Эх сурвалжийг харах

Merge pull request #1227 from sharelatex/spd-better-project-name-parsing

Handle embedded commands when parsing project name from title

GitOrigin-RevId: 09c1720897056a40d38b4f2f80f9d48caad4258b
Brian Gough 7 жил өмнө
parent
commit
e42a3d1dc5

+ 14 - 5
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

+ 51 - 0
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"]