mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-31 07:21:36 +01:00 
			
		
		
		
	
							parent
							
								
									b32f0cdfa0
								
							
						
					
					
						commit
						3c4a06273f
					
				| @ -68,7 +68,7 @@ func TestMathRender(t *testing.T) { | ||||
| 		}, | ||||
| 		{ | ||||
| 			"$$a$$", | ||||
| 			`<pre class="code-block is-loading"><code class="chroma language-math display">a</code></pre>` + nl, | ||||
| 			`<code class="chroma language-math display">a</code>` + nl, | ||||
| 		}, | ||||
| 		{ | ||||
| 			"$$a$$ test", | ||||
| @ -79,9 +79,13 @@ func TestMathRender(t *testing.T) { | ||||
| 			`<p>test <code class="language-math display is-loading">a</code></p>` + nl, | ||||
| 		}, | ||||
| 		{ | ||||
| 			"foo $x=\\$$ bar", | ||||
| 			`foo $x=\$$ bar`, | ||||
| 			`<p>foo <code class="language-math is-loading">x=\$</code> bar</p>` + nl, | ||||
| 		}, | ||||
| 		{ | ||||
| 			`$\text{$b$}$`, | ||||
| 			`<p><code class="language-math is-loading">\text{$b$}</code></p>` + nl, | ||||
| 		}, | ||||
| 	} | ||||
| 
 | ||||
| 	for _, test := range testcases { | ||||
| @ -124,14 +128,36 @@ func TestMathRenderBlockIndent(t *testing.T) { | ||||
| `, | ||||
| 		}, | ||||
| 		{ | ||||
| 			"indent-2", | ||||
| 			"indent-2-mismatch", | ||||
| 			` | ||||
|   \[ | ||||
|   \alpha | ||||
| a | ||||
|  b | ||||
|   c | ||||
|    d | ||||
|   \] | ||||
| `, | ||||
| 			`<pre class="code-block is-loading"><code class="chroma language-math display"> | ||||
| \alpha | ||||
| a | ||||
| b | ||||
| c | ||||
|  d | ||||
| </code></pre> | ||||
| `, | ||||
| 		}, | ||||
| 		{ | ||||
| 			"indent-2", | ||||
| 			` | ||||
|   \[ | ||||
|   a | ||||
|    b | ||||
|   c | ||||
|   \] | ||||
| `, | ||||
| 			`<pre class="code-block is-loading"><code class="chroma language-math display"> | ||||
| a | ||||
|  b | ||||
| c | ||||
| </code></pre> | ||||
| `, | ||||
| 		}, | ||||
| @ -139,7 +165,7 @@ func TestMathRenderBlockIndent(t *testing.T) { | ||||
| 			"indent-0-oneline", | ||||
| 			`$$ x $$ | ||||
| foo`, | ||||
| 			`<pre class="code-block is-loading"><code class="chroma language-math display"> x </code></pre> | ||||
| 			`<code class="chroma language-math display"> x </code> | ||||
| <p>foo</p> | ||||
| `, | ||||
| 		}, | ||||
| @ -147,8 +173,46 @@ foo`, | ||||
| 			"indent-3-oneline", | ||||
| 			`   $$ x $$<SPACE> | ||||
| foo`, | ||||
| 			`<pre class="code-block is-loading"><code class="chroma language-math display"> x </code></pre> | ||||
| 			`<code class="chroma language-math display"> x </code> | ||||
| <p>foo</p> | ||||
| `, | ||||
| 		}, | ||||
| 		{ | ||||
| 			"quote-block", | ||||
| 			` | ||||
| > \[ | ||||
| > a | ||||
| > \] | ||||
| > \[ | ||||
| > b | ||||
| > \] | ||||
| `, | ||||
| 			`<blockquote> | ||||
| <pre class="code-block is-loading"><code class="chroma language-math display"> | ||||
| a | ||||
| </code></pre> | ||||
| <pre class="code-block is-loading"><code class="chroma language-math display"> | ||||
| b | ||||
| </code></pre> | ||||
| </blockquote> | ||||
| `, | ||||
| 		}, | ||||
| 		{ | ||||
| 			"list-block", | ||||
| 			` | ||||
| 1. a | ||||
|    \[ | ||||
|    x | ||||
|    \] | ||||
| 2. b`, | ||||
| 			`<ol> | ||||
| <li>a | ||||
| <pre class="code-block is-loading"><code class="chroma language-math display"> | ||||
| x | ||||
| </code></pre> | ||||
| </li> | ||||
| <li>b</li> | ||||
| </ol> | ||||
| `, | ||||
| 		}, | ||||
| 	} | ||||
|  | ||||
| @ -11,6 +11,7 @@ type Block struct { | ||||
| 	Dollars bool | ||||
| 	Indent  int | ||||
| 	Closed  bool | ||||
| 	Inline  bool | ||||
| } | ||||
| 
 | ||||
| // KindBlock is the node kind for math blocks | ||||
|  | ||||
| @ -6,6 +6,8 @@ package math | ||||
| import ( | ||||
| 	"bytes" | ||||
| 
 | ||||
| 	giteaUtil "code.gitea.io/gitea/modules/util" | ||||
| 
 | ||||
| 	"github.com/yuin/goldmark/ast" | ||||
| 	"github.com/yuin/goldmark/parser" | ||||
| 	"github.com/yuin/goldmark/text" | ||||
| @ -13,13 +15,17 @@ import ( | ||||
| ) | ||||
| 
 | ||||
| type blockParser struct { | ||||
| 	parseDollars bool | ||||
| 	parseDollars    bool | ||||
| 	endBytesDollars []byte | ||||
| 	endBytesBracket []byte | ||||
| } | ||||
| 
 | ||||
| // NewBlockParser creates a new math BlockParser | ||||
| func NewBlockParser(parseDollarBlocks bool) parser.BlockParser { | ||||
| 	return &blockParser{ | ||||
| 		parseDollars: parseDollarBlocks, | ||||
| 		parseDollars:    parseDollarBlocks, | ||||
| 		endBytesDollars: []byte{'$', '$'}, | ||||
| 		endBytesBracket: []byte{'\\', ']'}, | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| @ -47,10 +53,7 @@ func (b *blockParser) Open(parent ast.Node, reader text.Reader, pc parser.Contex | ||||
| 	node := NewBlock(dollars, pos) | ||||
| 
 | ||||
| 	// Now we need to check if the ending block is on the segment... | ||||
| 	endBytes := []byte{'\\', ']'} | ||||
| 	if dollars { | ||||
| 		endBytes = []byte{'$', '$'} | ||||
| 	} | ||||
| 	endBytes := giteaUtil.Iif(dollars, b.endBytesDollars, b.endBytesBracket) | ||||
| 	idx := bytes.Index(line[pos+2:], endBytes) | ||||
| 	if idx >= 0 { | ||||
| 		// for case $$ ... $$ any other text | ||||
| @ -63,6 +66,7 @@ func (b *blockParser) Open(parent ast.Node, reader text.Reader, pc parser.Contex | ||||
| 		segment.Stop = segment.Start + idx | ||||
| 		node.Lines().Append(segment) | ||||
| 		node.Closed = true | ||||
| 		node.Inline = true | ||||
| 		return node, parser.Close | parser.NoChildren | ||||
| 	} | ||||
| 
 | ||||
| @ -79,27 +83,19 @@ func (b *blockParser) Continue(node ast.Node, reader text.Reader, pc parser.Cont | ||||
| 	} | ||||
| 
 | ||||
| 	line, segment := reader.PeekLine() | ||||
| 	w, pos := util.IndentWidth(line, 0) | ||||
| 	w, pos := util.IndentWidth(line, reader.LineOffset()) | ||||
| 	if w < 4 { | ||||
| 		if block.Dollars { | ||||
| 			i := pos | ||||
| 			for ; i < len(line) && line[i] == '$'; i++ { | ||||
| 			} | ||||
| 			length := i - pos | ||||
| 			if length >= 2 && util.IsBlank(line[i:]) { | ||||
| 				reader.Advance(segment.Stop - segment.Start - segment.Padding) | ||||
| 				block.Closed = true | ||||
| 		endBytes := giteaUtil.Iif(block.Dollars, b.endBytesDollars, b.endBytesBracket) | ||||
| 		if bytes.HasPrefix(line[pos:], endBytes) && util.IsBlank(line[pos+len(endBytes):]) { | ||||
| 			if util.IsBlank(line[pos+len(endBytes):]) { | ||||
| 				newline := giteaUtil.Iif(line[len(line)-1] != '\n', 0, 1) | ||||
| 				reader.Advance(segment.Stop - segment.Start - newline + segment.Padding) | ||||
| 				return parser.Close | ||||
| 			} | ||||
| 		} else if len(line[pos:]) > 1 && line[pos] == '\\' && line[pos+1] == ']' && util.IsBlank(line[pos+2:]) { | ||||
| 			reader.Advance(segment.Stop - segment.Start - segment.Padding) | ||||
| 			block.Closed = true | ||||
| 			return parser.Close | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	pos, padding := util.IndentPosition(line, 0, block.Indent) | ||||
| 	seg := text.NewSegmentPadding(segment.Start+pos, segment.Stop, padding) | ||||
| 	start := segment.Start + giteaUtil.Iif(pos > block.Indent, block.Indent, pos) | ||||
| 	seg := text.NewSegmentPadding(start, segment.Stop, segment.Padding) | ||||
| 	node.Lines().Append(seg) | ||||
| 	return parser.Continue | parser.NoChildren | ||||
| } | ||||
|  | ||||
| @ -5,6 +5,7 @@ package math | ||||
| 
 | ||||
| import ( | ||||
| 	"code.gitea.io/gitea/modules/markup/internal" | ||||
| 	giteaUtil "code.gitea.io/gitea/modules/util" | ||||
| 
 | ||||
| 	gast "github.com/yuin/goldmark/ast" | ||||
| 	"github.com/yuin/goldmark/renderer" | ||||
| @ -37,10 +38,11 @@ func (r *BlockRenderer) writeLines(w util.BufWriter, source []byte, n gast.Node) | ||||
| func (r *BlockRenderer) renderBlock(w util.BufWriter, source []byte, node gast.Node, entering bool) (gast.WalkStatus, error) { | ||||
| 	n := node.(*Block) | ||||
| 	if entering { | ||||
| 		_ = r.renderInternal.FormatWithSafeAttrs(w, `<pre class="code-block is-loading"><code class="chroma language-math display">`) | ||||
| 		code := giteaUtil.Iif(n.Inline, "", `<pre class="code-block is-loading">`) + `<code class="chroma language-math display">` | ||||
| 		_ = r.renderInternal.FormatWithSafeAttrs(w, code) | ||||
| 		r.writeLines(w, source, n) | ||||
| 	} else { | ||||
| 		_, _ = w.WriteString(`</code></pre>` + "\n") | ||||
| 		_, _ = w.WriteString(`</code>` + giteaUtil.Iif(n.Inline, "", `</pre>`) + "\n") | ||||
| 	} | ||||
| 	return gast.WalkContinue, nil | ||||
| } | ||||
|  | ||||
| @ -79,9 +79,10 @@ func (parser *inlineParser) Parse(parent ast.Node, block text.Reader, pc parser. | ||||
| 	opener := len(parser.start) | ||||
| 
 | ||||
| 	// Now look for an ending line | ||||
| 	depth := 0 | ||||
| 	ender := -1 | ||||
| 	for i := opener; i < len(line); i++ { | ||||
| 		if bytes.HasPrefix(line[i:], parser.end) { | ||||
| 		if depth == 0 && bytes.HasPrefix(line[i:], parser.end) { | ||||
| 			succeedingCharacter := byte(0) | ||||
| 			if i+len(parser.end) < len(line) { | ||||
| 				succeedingCharacter = line[i+len(parser.end)] | ||||
| @ -99,6 +100,11 @@ func (parser *inlineParser) Parse(parent ast.Node, block text.Reader, pc parser. | ||||
| 			i++ | ||||
| 			continue | ||||
| 		} | ||||
| 		if line[i] == '{' { | ||||
| 			depth++ | ||||
| 		} else if line[i] == '}' { | ||||
| 			depth-- | ||||
| 		} | ||||
| 	} | ||||
| 	if ender == -1 { | ||||
| 		return nil | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user