mirror of
https://github.com/go-gitea/gitea
synced 2024-12-29 15:14:38 +01:00
parent
b32f0cdfa0
commit
3c4a06273f
5 changed files with 101 additions and 32 deletions
|
@ -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…
Reference in a new issue