mirror of
https://github.com/go-gitea/gitea.git
synced 2025-04-23 02:28:23 +02:00
* Fix #27645 * Add config options `MATH_CODE_BLOCK_DETECTION`, problematic syntaxes are disabled by default * Fix #33639 * Add config options `RENDER_OPTIONS_*`, old behaviors are kept
311 lines
5.7 KiB
Go
311 lines
5.7 KiB
Go
// Copyright 2024 The Gitea Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package markdown
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
|
|
"code.gitea.io/gitea/modules/markup"
|
|
"code.gitea.io/gitea/modules/setting"
|
|
"code.gitea.io/gitea/modules/test"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
const nl = "\n"
|
|
|
|
func TestMathRender(t *testing.T) {
|
|
setting.Markdown.MathCodeBlockOptions = setting.MarkdownMathCodeBlockOptions{ParseInlineDollar: true, ParseInlineParentheses: true}
|
|
testcases := []struct {
|
|
testcase string
|
|
expected string
|
|
}{
|
|
{
|
|
"$a$",
|
|
`<p><code class="language-math">a</code></p>` + nl,
|
|
},
|
|
{
|
|
"$ a $",
|
|
`<p><code class="language-math">a</code></p>` + nl,
|
|
},
|
|
{
|
|
"$a$ $b$",
|
|
`<p><code class="language-math">a</code> <code class="language-math">b</code></p>` + nl,
|
|
},
|
|
{
|
|
`\(a\) \(b\)`,
|
|
`<p><code class="language-math">a</code> <code class="language-math">b</code></p>` + nl,
|
|
},
|
|
{
|
|
`$a$.`,
|
|
`<p><code class="language-math">a</code>.</p>` + nl,
|
|
},
|
|
{
|
|
`.$a$`,
|
|
`<p>.$a$</p>` + nl,
|
|
},
|
|
{
|
|
`$a a$b b$`,
|
|
`<p>$a a$b b$</p>` + nl,
|
|
},
|
|
{
|
|
`a a$b b`,
|
|
`<p>a a$b b</p>` + nl,
|
|
},
|
|
{
|
|
`a$b $a a$b b$`,
|
|
`<p>a$b $a a$b b$</p>` + nl,
|
|
},
|
|
{
|
|
"a$x$",
|
|
`<p>a$x$</p>` + nl,
|
|
},
|
|
{
|
|
"$x$a",
|
|
`<p>$x$a</p>` + nl,
|
|
},
|
|
{
|
|
"$a$ ($b$) [$c$] {$d$}",
|
|
`<p><code class="language-math">a</code> (<code class="language-math">b</code>) [$c$] {$d$}</p>` + nl,
|
|
},
|
|
{
|
|
"$$a$$",
|
|
`<p><code class="language-math">a</code></p>` + nl,
|
|
},
|
|
{
|
|
"$$a$$ test",
|
|
`<p><code class="language-math">a</code> test</p>` + nl,
|
|
},
|
|
{
|
|
"test $$a$$",
|
|
`<p>test <code class="language-math">a</code></p>` + nl,
|
|
},
|
|
{
|
|
`foo $x=\$$ bar`,
|
|
`<p>foo <code class="language-math">x=\$</code> bar</p>` + nl,
|
|
},
|
|
{
|
|
`$\text{$b$}$`,
|
|
`<p><code class="language-math">\text{$b$}</code></p>` + nl,
|
|
},
|
|
{
|
|
"a$`b`$c",
|
|
`<p>a<code class="language-math">b</code>c</p>` + nl,
|
|
},
|
|
{
|
|
"a $`b`$ c",
|
|
`<p>a <code class="language-math">b</code> c</p>` + nl,
|
|
},
|
|
{
|
|
"a$``b``$c x$```y```$z",
|
|
`<p>a<code class="language-math">b</code>c x<code class="language-math">y</code>z</p>` + nl,
|
|
},
|
|
}
|
|
|
|
for _, test := range testcases {
|
|
t.Run(test.testcase, func(t *testing.T) {
|
|
res, err := RenderString(markup.NewTestRenderContext(), test.testcase)
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, test.expected, string(res))
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestMathRenderBlockIndent(t *testing.T) {
|
|
setting.Markdown.MathCodeBlockOptions = setting.MarkdownMathCodeBlockOptions{ParseBlockDollar: true, ParseBlockSquareBrackets: true}
|
|
testcases := []struct {
|
|
name string
|
|
testcase string
|
|
expected string
|
|
}{
|
|
{
|
|
"indent-0",
|
|
`
|
|
\[
|
|
\alpha
|
|
\]
|
|
`,
|
|
`<pre class="code-block is-loading"><code class="language-math display">
|
|
\alpha
|
|
</code></pre>
|
|
`,
|
|
},
|
|
{
|
|
"indent-1",
|
|
`
|
|
\[
|
|
\alpha
|
|
\]
|
|
`,
|
|
`<pre class="code-block is-loading"><code class="language-math display">
|
|
\alpha
|
|
</code></pre>
|
|
`,
|
|
},
|
|
{
|
|
"indent-2-mismatch",
|
|
`
|
|
\[
|
|
a
|
|
b
|
|
c
|
|
d
|
|
\]
|
|
`,
|
|
`<pre class="code-block is-loading"><code class="language-math display">
|
|
a
|
|
b
|
|
c
|
|
d
|
|
</code></pre>
|
|
`,
|
|
},
|
|
{
|
|
"indent-2",
|
|
`
|
|
\[
|
|
a
|
|
b
|
|
c
|
|
\]
|
|
`,
|
|
`<pre class="code-block is-loading"><code class="language-math display">
|
|
a
|
|
b
|
|
c
|
|
</code></pre>
|
|
`,
|
|
},
|
|
{
|
|
"indent-0-oneline",
|
|
`$$ x $$
|
|
foo`,
|
|
`<code class="language-math display"> x </code>
|
|
<p>foo</p>
|
|
`,
|
|
},
|
|
{
|
|
"indent-3-oneline",
|
|
` $$ x $$<SPACE>
|
|
foo`,
|
|
`<code class="language-math display"> x </code>
|
|
<p>foo</p>
|
|
`,
|
|
},
|
|
{
|
|
"quote-block",
|
|
`
|
|
> \[
|
|
> a
|
|
> \]
|
|
> \[
|
|
> b
|
|
> \]
|
|
`,
|
|
`<blockquote>
|
|
<pre class="code-block is-loading"><code class="language-math display">
|
|
a
|
|
</code></pre>
|
|
<pre class="code-block is-loading"><code class="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="language-math display">
|
|
x
|
|
</code></pre>
|
|
</li>
|
|
<li>b</li>
|
|
</ol>
|
|
`,
|
|
},
|
|
{
|
|
"inline-non-math",
|
|
`\[x]`,
|
|
`<p>[x]</p>` + nl,
|
|
},
|
|
}
|
|
|
|
for _, test := range testcases {
|
|
t.Run(test.name, func(t *testing.T) {
|
|
res, err := RenderString(markup.NewTestRenderContext(), strings.ReplaceAll(test.testcase, "<SPACE>", " "))
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, test.expected, string(res), "unexpected result for test case:\n%s", test.testcase)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestMathRenderOptions(t *testing.T) {
|
|
setting.Markdown.MathCodeBlockOptions = setting.MarkdownMathCodeBlockOptions{}
|
|
defer test.MockVariableValue(&setting.Markdown.MathCodeBlockOptions)
|
|
test := func(t *testing.T, expected, input string) {
|
|
res, err := RenderString(markup.NewTestRenderContext(), input)
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(string(res)), "input: %s", input)
|
|
}
|
|
|
|
// default (non-conflict) inline syntax
|
|
test(t, `<p><code class="language-math">a</code></p>`, "$`a`$")
|
|
|
|
// ParseInlineDollar
|
|
test(t, `<p>$a$</p>`, `$a$`)
|
|
setting.Markdown.MathCodeBlockOptions.ParseInlineDollar = true
|
|
test(t, `<p><code class="language-math">a</code></p>`, `$a$`)
|
|
|
|
// ParseInlineParentheses
|
|
test(t, `<p>(a)</p>`, `\(a\)`)
|
|
setting.Markdown.MathCodeBlockOptions.ParseInlineParentheses = true
|
|
test(t, `<p><code class="language-math">a</code></p>`, `\(a\)`)
|
|
|
|
// ParseBlockDollar
|
|
test(t, `<p>$$
|
|
a
|
|
$$</p>
|
|
`, `
|
|
$$
|
|
a
|
|
$$
|
|
`)
|
|
setting.Markdown.MathCodeBlockOptions.ParseBlockDollar = true
|
|
test(t, `<pre class="code-block is-loading"><code class="language-math display">
|
|
a
|
|
</code></pre>
|
|
`, `
|
|
$$
|
|
a
|
|
$$
|
|
`)
|
|
|
|
// ParseBlockSquareBrackets
|
|
test(t, `<p>[
|
|
a
|
|
]</p>
|
|
`, `
|
|
\[
|
|
a
|
|
\]
|
|
`)
|
|
setting.Markdown.MathCodeBlockOptions.ParseBlockSquareBrackets = true
|
|
test(t, `<pre class="code-block is-loading"><code class="language-math display">
|
|
a
|
|
</code></pre>
|
|
`, `
|
|
\[
|
|
a
|
|
\]
|
|
`)
|
|
}
|