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