From ad0192e8e10641af4ec0d1f2b0b3eadbbeeba2ed Mon Sep 17 00:00:00 2001 From: Sorunome Date: Sat, 24 Oct 2020 11:50:16 +0200 Subject: [PATCH] fix: Greatly improve latex markdown --- lib/src/utils/markdown.dart | 25 +++++++++++++++++-------- test/markdown_test.dart | 10 ++++++++++ 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/lib/src/utils/markdown.dart b/lib/src/utils/markdown.dart index 81a882c..dea262c 100644 --- a/lib/src/utils/markdown.dart +++ b/lib/src/utils/markdown.dart @@ -76,12 +76,13 @@ class EmoteSyntax extends InlineSyntax { } } -class InlineLatexSyntax extends InlineSyntax { - InlineLatexSyntax() : super(r'(?<=\s|^)\$(?=\S)([^\n$]+)(?<=\S)\$(?=\s|$)'); +class InlineLatexSyntax extends TagSyntax { + InlineLatexSyntax() : super(r'\$', requiresDelimiterRun: true); @override - bool onMatch(InlineParser parser, Match match) { - final latex = htmlEscape.convert(match[1]); + bool onMatchEnd(InlineParser parser, Match match, TagState state) { + final latex = + htmlEscape.convert(parser.source.substring(state.endPos, match.start)); final element = Element('span', [Element.text('code', latex)]); element.attributes['data-mx-maths'] = latex; parser.addNode(element); @@ -89,22 +90,28 @@ class InlineLatexSyntax extends InlineSyntax { } } +// We also want to allow single-lines of like "$$latex$$" class BlockLatexSyntax extends BlockSyntax { @override - RegExp get pattern => RegExp(r'^[ ]{0,3}\${2}\s*$'); + RegExp get pattern => RegExp(r'^[ ]{0,3}\$\$(.*)$'); + + final endPattern = RegExp(r'^(.*)\$\$\s*$'); @override List parseChildLines(BlockParser parser) { var childLines = []; - parser.advance(); + var first = true; while (!parser.isDone) { - if (!pattern.hasMatch(parser.current)) { + final match = endPattern.firstMatch(parser.current); + if (match == null || (first && match.group(1).trim().isEmpty)) { childLines.add(parser.current); parser.advance(); } else { + childLines.add(match.group(1)); parser.advance(); break; } + first = false; } return childLines; } @@ -112,7 +119,9 @@ class BlockLatexSyntax extends BlockSyntax { @override Node parse(BlockParser parser) { final childLines = parseChildLines(parser); - final latex = htmlEscape.convert(childLines.join('\n')); + // we use .substring(2) as childLines will *always* contain the first two '$$' + final latex = + htmlEscape.convert(childLines.join('\n').trim().substring(2).trim()); final element = Element('div', [ Element('pre', [Element.text('code', latex)]) ]); diff --git a/test/markdown_test.dart b/test/markdown_test.dart index 0b172d6..b2aecff 100644 --- a/test/markdown_test.dart +++ b/test/markdown_test.dart @@ -73,6 +73,16 @@ void main() { test('latex', () { expect(markdown('meep \$\\frac{2}{3}\$'), 'meep \\frac{2}{3}'); + expect(markdown('meep \$hmm *yay*\$'), + 'meep hmm *yay*'); + expect(markdown('you have \$somevar and \$someothervar'), + 'you have \$somevar and \$someothervar'); + expect(markdown('meep ||\$\\frac{2}{3}\$||'), + 'meep \\frac{2}{3}'); + expect(markdown('meep `\$\\frac{2}{3}\$`'), + 'meep \$\\frac{2}{3}\$'); + expect(markdown('hey\n\$\$beep\$\$\nmeow'), + '

hey

\n
\n
beep
\n
\n

meow

'); expect(markdown('hey\n\$\$\nbeep\nboop\n\$\$\nmeow'), '

hey

\n
\n
beep\nboop
\n
\n

meow

'); });