diff --git a/modules/markup/markdown/markdown_math_test.go b/modules/markup/markdown/markdown_math_test.go
index 0e5adeeac8..e371b1c74a 100644
--- a/modules/markup/markdown/markdown_math_test.go
+++ b/modules/markup/markdown/markdown_math_test.go
@@ -68,7 +68,7 @@ func TestMathRender(t *testing.T) {
},
{
"$$a$$",
- `
a
` + nl,
+ `a
` + nl,
},
{
"$$a$$ test",
@@ -79,9 +79,13 @@ func TestMathRender(t *testing.T) {
`test a
` + nl,
},
{
- "foo $x=\\$$ bar",
+ `foo $x=\$$ bar`,
`foo x=\$
bar
` + nl,
},
+ {
+ `$\text{$b$}$`,
+ `\text{$b$}
` + nl,
+ },
}
for _, test := range testcases {
@@ -124,14 +128,36 @@ func TestMathRenderBlockIndent(t *testing.T) {
`,
},
{
- "indent-2",
+ "indent-2-mismatch",
`
\[
- \alpha
+a
+ b
+ c
+ d
\]
`,
`
-\alpha
+a
+b
+c
+ d
+
+`,
+ },
+ {
+ "indent-2",
+ `
+ \[
+ a
+ b
+ c
+ \]
+`,
+ `
+a
+ b
+c
`,
},
@@ -139,7 +165,7 @@ func TestMathRenderBlockIndent(t *testing.T) {
"indent-0-oneline",
`$$ x $$
foo`,
- ` x
+ ` x
foo
`,
},
@@ -147,8 +173,46 @@ foo`,
"indent-3-oneline",
` $$ x $$
foo`,
- ` x
+ ` x
foo
+`,
+ },
+ {
+ "quote-block",
+ `
+> \[
+> a
+> \]
+> \[
+> b
+> \]
+`,
+ `
+
+a
+
+
+b
+
+
+`,
+ },
+ {
+ "list-block",
+ `
+1. a
+ \[
+ x
+ \]
+2. b`,
+ `
+- a
+
+x
+
+
+- b
+
`,
},
}
diff --git a/modules/markup/markdown/math/block_node.go b/modules/markup/markdown/math/block_node.go
index 10d17ff8d3..d2293133cd 100644
--- a/modules/markup/markdown/math/block_node.go
+++ b/modules/markup/markdown/math/block_node.go
@@ -11,6 +11,7 @@ type Block struct {
Dollars bool
Indent int
Closed bool
+ Inline bool
}
// KindBlock is the node kind for math blocks
diff --git a/modules/markup/markdown/math/block_parser.go b/modules/markup/markdown/math/block_parser.go
index f31cfb09ad..3f37ce8333 100644
--- a/modules/markup/markdown/math/block_parser.go
+++ b/modules/markup/markdown/math/block_parser.go
@@ -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
}
diff --git a/modules/markup/markdown/math/block_renderer.go b/modules/markup/markdown/math/block_renderer.go
index 0d2a966102..a770efa01c 100644
--- a/modules/markup/markdown/math/block_renderer.go
+++ b/modules/markup/markdown/math/block_renderer.go
@@ -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, ``)
+ code := giteaUtil.Iif(n.Inline, "", ``) + ``
+ _ = r.renderInternal.FormatWithSafeAttrs(w, code)
r.writeLines(w, source, n)
} else {
- _, _ = w.WriteString(`
` + "\n")
+ _, _ = w.WriteString(`
` + giteaUtil.Iif(n.Inline, "", `
`) + "\n")
}
return gast.WalkContinue, nil
}
diff --git a/modules/markup/markdown/math/inline_parser.go b/modules/markup/markdown/math/inline_parser.go
index 56ae3d57eb..191d1e5a31 100644
--- a/modules/markup/markdown/math/inline_parser.go
+++ b/modules/markup/markdown/math/inline_parser.go
@@ -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