From e42a3d1dc506b0c6ed0c2177cad120fe3bc41101 Mon Sep 17 00:00:00 2001 From: Brian Gough Date: Mon, 10 Dec 2018 09:39:58 +0000 Subject: [PATCH] Merge pull request #1227 from sharelatex/spd-better-project-name-parsing Handle embedded commands when parsing project name from title GitOrigin-RevId: 09c1720897056a40d38b4f2f80f9d48caad4258b --- .../Features/Documents/DocumentHelper.coffee | 19 +++++-- .../Documents/DocumentHelperTests.coffee | 51 +++++++++++++++++++ 2 files changed, 65 insertions(+), 5 deletions(-) diff --git a/services/web/app/coffee/Features/Documents/DocumentHelper.coffee b/services/web/app/coffee/Features/Documents/DocumentHelper.coffee index 26c1d8d7a9..39cf812823 100644 --- a/services/web/app/coffee/Features/Documents/DocumentHelper.coffee +++ b/services/web/app/coffee/Features/Documents/DocumentHelper.coffee @@ -2,12 +2,9 @@ module.exports = DocumentHelper = getTitleFromTexContent: (content, maxContentToScan = 30000) -> TITLE_WITH_CURLY_BRACES = /\\[tT]itle\*?\s*{([^}]+)}/ TITLE_WITH_SQUARE_BRACES = /\\[tT]itle\s*\[([^\]]+)\]/ - ESCAPED_BRACES = /\\([{}\[\]])/g - for line in DocumentHelper._getLinesFromContent(content, maxContentToScan) - match = line.match(TITLE_WITH_SQUARE_BRACES) || line.match(TITLE_WITH_CURLY_BRACES) - if match? - return match[1].replace(ESCAPED_BRACES, (br)->br[1]) + if match = line.match(TITLE_WITH_CURLY_BRACES) || line.match(TITLE_WITH_SQUARE_BRACES) + return DocumentHelper.detex(match[1]) return null @@ -21,5 +18,17 @@ module.exports = DocumentHelper = return false + detex: (string) -> + return string.replace(/\\LaTeX/g, 'LaTeX') + .replace(/\\TeX/g, 'TeX') + .replace(/\\TikZ/g, 'TikZ') + .replace(/\\BibTeX/g, 'BibTeX') + .replace(/\\\[[A-Za-z0-9. ]*\]/g, ' ') # line spacing + .replace(/\\(?:[a-zA-Z]+|.|)/g, '') + .replace(/{}|~/g, ' ') + .replace(/[${}]/g, '') + .replace(/ +/g, ' ') + .trim() + _getLinesFromContent: (content, maxContentToScan) -> return if typeof content is 'string' then content.substring(0, maxContentToScan).split("\n") else content diff --git a/services/web/test/unit/coffee/Documents/DocumentHelperTests.coffee b/services/web/test/unit/coffee/Documents/DocumentHelperTests.coffee index 16a9f2bb2e..28bcbe5439 100644 --- a/services/web/test/unit/coffee/Documents/DocumentHelperTests.coffee +++ b/services/web/test/unit/coffee/Documents/DocumentHelperTests.coffee @@ -27,6 +27,57 @@ describe "DocumentHelper", -> document = ["\\begin{document}","\\title{foo}","\\end{document}"] expect(@DocumentHelper.getTitleFromTexContent(document)).to.equal "foo" + it "should parse out formatting elements from the title", -> + document = "\\title{\\textbf{\\large{Second Year LaTeX Exercise}}}" + expect(@DocumentHelper.getTitleFromTexContent(document)).to.equal "Second Year LaTeX Exercise" + + it "should ignore junk after the title", -> + document = "\\title{wombat} potato" + expect(@DocumentHelper.getTitleFromTexContent(document)).to.equal "wombat" + + it "should ignore junk before the title", -> + document = "% this is something that v1 relied on, even though it seems odd \\title{wombat}" + expect(@DocumentHelper.getTitleFromTexContent(document)).to.equal "wombat" + + # NICETOHAVE: Current implementation doesn't do this + #it "should keep content that surrounds formatting elements", -> + # document = "\\title{Second Year \\large{LaTeX} Exercise}" + # expect(@DocumentHelper.getTitleFromTexContent(document)).to.equal "Second Year LaTeX Exercise" + + it "should collapse whitespace", -> + document = "\\title{Second Year LaTeX Exercise}" + expect(@DocumentHelper.getTitleFromTexContent(document)).to.equal "Second Year LaTeX Exercise" + + describe "detex", -> + # note, there are a number of tests for getTitleFromTexContent that also test cases here + it 'leaves a non-TeX string unchanged', -> + expect(@DocumentHelper.detex('')).to.equal '' + expect(@DocumentHelper.detex('a')).to.equal 'a' + expect(@DocumentHelper.detex('a a')).to.equal 'a a' + + it 'collapses spaces', -> + expect(@DocumentHelper.detex('a a')).to.equal 'a a' + expect(@DocumentHelper.detex('a \n a')).to.equal 'a \n a' + + it 'replaces named commands', -> + expect(@DocumentHelper.detex('\\LaTeX')).to.equal 'LaTeX' + expect(@DocumentHelper.detex('\\TikZ')).to.equal 'TikZ' + expect(@DocumentHelper.detex('\\TeX')).to.equal 'TeX' + expect(@DocumentHelper.detex('\\BibTeX')).to.equal 'BibTeX' + + it 'removes general commands', -> + expect(@DocumentHelper.detex('\\foo')).to.equal '' + expect(@DocumentHelper.detex('\\foo{}')).to.equal '' + expect(@DocumentHelper.detex('\\foo~Test')).to.equal 'Test' + expect(@DocumentHelper.detex('\\"e')).to.equal 'e' + expect(@DocumentHelper.detex('\\textit{e}')).to.equal 'e' + + it 'leaves basic math', -> + expect(@DocumentHelper.detex('$\\cal{O}(n^2)$')).to.equal 'O(n^2)' + + it 'removes line spacing commands', -> + expect(@DocumentHelper.detex('a \\\\[1.50cm] b')).to.equal 'a b' + describe "contentHasDocumentclass", -> it "should return true if the content has a documentclass", -> document = ["% line", "% line", "% line", "\\documentclass"]