diff --git a/services/web/frontend/js/features/outline/outline-parser.js b/services/web/frontend/js/features/outline/outline-parser.js index 9b7af66b37..4e5f9d7762 100644 --- a/services/web/frontend/js/features/outline/outline-parser.js +++ b/services/web/frontend/js/features/outline/outline-parser.js @@ -50,6 +50,7 @@ function matchOutline(content) { } const DISPLAY_TITLE_REGEX = new RegExp('([^\\\\]*)\\\\([^{]+){([^}]+)}(.*)') +const END_OF_TITLE_REGEX = new RegExp('^([^{}]*?({[^{}]*?}[^{}]*?)*)}') /* * Attempt to improve the display of the outline title for titles with commands. * Either skip the command (for labels) or display the command's content instead @@ -61,11 +62,19 @@ const DISPLAY_TITLE_REGEX = new RegExp('([^\\\\]*)\\\\([^{]+){([^}]+)}(.*)') */ function matchDisplayTitle(title) { const closingBracketPosition = title.indexOf('}') + if (closingBracketPosition < 0) { // simple title (no commands) return title } + // if there is anything outside the title def on the line, remove it + // before proceeding + const titleOnlyMatch = title.match(END_OF_TITLE_REGEX) + if (titleOnlyMatch) { + title = titleOnlyMatch[1] + } + const titleMatch = title.match(DISPLAY_TITLE_REGEX) if (!titleMatch) { // no contained commands; strip everything after the first closing bracket diff --git a/services/web/test/frontend/features/outline/outline-parser.test.js b/services/web/test/frontend/features/outline/outline-parser.test.js index da220d6baa..7af793d31a 100644 --- a/services/web/test/frontend/features/outline/outline-parser.test.js +++ b/services/web/test/frontend/features/outline/outline-parser.test.js @@ -47,13 +47,27 @@ describe('OutlineParser', function() { \\section{Label after \\label{foo}} \\section{Label \\label{foo} between} \\section{TT \\texttt{Bar}} - ` + \\section{plain title} + ` const outline = matchOutline(content) expect(outline).to.deep.equal([ { line: 2, title: ' Label before', level: 40 }, { line: 3, title: 'Label after ', level: 40 }, { line: 4, title: 'Label between', level: 40 }, - { line: 5, title: 'TT Bar', level: 40 } + { line: 5, title: 'TT Bar', level: 40 }, + { line: 6, title: 'plain title', level: 40 } + ]) + }) + + it('removes spurious commands after title definition', function() { + const content = ` + \\section{Plain title} more text \\href{link}{link} + \\section{\\label{foo} Label before} more text \\href{link}{link} + ` + const outline = matchOutline(content) + expect(outline).to.deep.equal([ + { line: 2, title: 'Plain title', level: 40 }, + { line: 3, title: ' Label before', level: 40 } ]) })