##// END OF EJS Templates
FIX, don't use regex
Jonathan Frederic -
Show More
@@ -1,115 +1,114
1 1 """Latex filters.
2 2
3 3 Module of useful filters for processing Latex within Jinja latex templates.
4 4 """
5 5 #-----------------------------------------------------------------------------
6 6 # Copyright (c) 2013, the IPython Development Team.
7 7 #
8 8 # Distributed under the terms of the Modified BSD License.
9 9 #
10 10 # The full license is in the file COPYING.txt, distributed with this software.
11 11 #-----------------------------------------------------------------------------
12 12
13 13 #-----------------------------------------------------------------------------
14 14 # Imports
15 15 #-----------------------------------------------------------------------------
16 16 import re
17 17
18 18 #-----------------------------------------------------------------------------
19 19 # Globals and constants
20 20 #-----------------------------------------------------------------------------
21 21
22 #Latex substitutions for escaping latex.
23 LATEX_SUBS = (
24 (re.compile('\033\[[0-9;]+m'),''), # handle console escapes
25 (re.compile(r'\\'), r'{\\textbackslash}'),
26 (re.compile(r'([{}_#%&$])'), r'\\\1'),
27 (re.compile(r'~'), r'\~{}'),
28 (re.compile(r'\^'), r'\^{}'),
29 (re.compile(r'"'), r"''"),
30 (re.compile(r'\.\.\.+'), r'\\ldots'),
31 )
22 # Latex substitutions for escaping latex.
23 # see: http://stackoverflow.com/questions/16259923/how-can-i-escape-latex-special-characters-inside-django-templates
24 LATEX_SUBS = {
25 '&': r'\&',
26 '%': r'\%',
27 '$': r'\$',
28 '#': r'\#',
29 '_': r'\letterunderscore{}',
30 '{': r'\letteropenbrace{}',
31 '}': r'\letterclosebrace{}',
32 '~': r'\lettertilde{}',
33 '^': r'\letterhat{}',
34 '\\': r'\letterbackslash{}'}
35
32 36
33 37 #-----------------------------------------------------------------------------
34 38 # Functions
35 39 #-----------------------------------------------------------------------------
36 40
37 __all__ = [
38 'escape_latex',
39 'strip_math_space'
40 ]
41
41 __all__ = ['escape_latex',
42 'strip_math_space']
42 43
43 44 def escape_latex(text):
44 45 """
45 46 Escape characters that may conflict with latex.
46
47
47 48 Parameters
48 49 ----------
49 50 text : str
50 51 Text containing characters that may conflict with Latex
51 52 """
52 return_text = text
53 for pattern, replacement in LATEX_SUBS:
54 return_text = pattern.sub(replacement, return_text)
55 return return_text
53
54 return ''.join([LATEX_SUBS.get(c, c) for c in text])
56 55
57 56
58 57 def strip_math_space(text):
59 58 """
60 59 Remove the space between latex math commands and enclosing $ symbols.
61 60 This filter is important because latex isn't as flexible as the notebook
62 61 front end when it comes to flagging math using ampersand symbols.
63 62
64 63 Parameters
65 64 ----------
66 65 text : str
67 66 Text to filter.
68 67 """
69 68
70 69 # First, scan through the markdown looking for $. If
71 70 # a $ symbol is found, without a preceding \, assume
72 71 # it is the start of a math block. UNLESS that $ is
73 72 # not followed by another within two math_lines.
74 73 math_regions = []
75 74 math_lines = 0
76 75 within_math = False
77 76 math_start_index = 0
78 77 ptext = ''
79 78 last_character = ""
80 79 skip = False
81 80 for index, char in enumerate(text):
82 81
83 82 #Make sure the character isn't preceeded by a backslash
84 83 if (char == "$" and last_character != "\\"):
85 84
86 85 # Close the math region if this is an ending $
87 86 if within_math:
88 87 within_math = False
89 88 skip = True
90 89 ptext = ptext+'$'+text[math_start_index+1:index].strip()+'$'
91 90 math_regions.append([math_start_index, index+1])
92 91 else:
93 92
94 93 # Start a new math region
95 94 within_math = True
96 95 math_start_index = index
97 96 math_lines = 0
98 97
99 98 # If we are in a math region, count the number of lines parsed.
100 99 # Cancel the math region if we find two line breaks!
101 100 elif char == "\n":
102 101 if within_math:
103 102 math_lines += 1
104 103 if math_lines > 1:
105 104 within_math = False
106 105 ptext = ptext+text[math_start_index:index]
107 106
108 107 # Remember the last character so we can easily watch
109 108 # for backslashes
110 109 last_character = char
111 110 if not within_math and not skip:
112 111 ptext = ptext+char
113 112 if skip:
114 113 skip = False
115 114 return ptext
@@ -1,65 +1,65
1 1 """
2 2 Module with tests for Latex
3 3 """
4 4
5 5 #-----------------------------------------------------------------------------
6 6 # Copyright (c) 2013, the IPython Development Team.
7 7 #
8 8 # Distributed under the terms of the Modified BSD License.
9 9 #
10 10 # The full license is in the file COPYING.txt, distributed with this software.
11 11 #-----------------------------------------------------------------------------
12 12
13 13 #-----------------------------------------------------------------------------
14 14 # Imports
15 15 #-----------------------------------------------------------------------------
16 16
17 17 from ...tests.base import TestsBase
18 18 from ..latex import escape_latex, strip_math_space
19 19
20 20
21 21 #-----------------------------------------------------------------------------
22 22 # Class
23 23 #-----------------------------------------------------------------------------
24 24
25 25 class TestLatex(TestsBase):
26 26
27 27
28 28 def test_escape_latex(self):
29 29 """escape_latex test"""
30 30 tests = [
31 (r'How are \you doing today?', r'How are \textbackslashyou doing today?'),
32 (r'\escapechar=`\A\catcode`\|=0 |string|foo', r'\textbackslashescapechar=`\textbackslashA\textbackslashcatcode`\textbackslash|=0 |string|foo'),
33 (r'# $ % & ~ _ ^ \ { }',r'\# \$ \% \& \~{} \_ \^{} \textbackslash \{ \}'),
31 (r'How are \you doing today?', r'How are \letterbackslash{}you doing today?'),
32 (r'\escapechar=`\A\catcode`\|=0 |string|foo', r'\letterbackslash{}escapechar=`\letterbackslash{}A\letterbackslash{}catcode`\letterbackslash{}|=0 |string|foo'),
33 (r'# $ % & ~ _ ^ \ { }', r'\# \$ \% \& \lettertilde{} \letterunderscore{} \letterhat{} \letterbackslash{} \letteropenbrace{} \letterclosebrace{}'),
34 34 ('','')]
35 35
36 36 for test in tests:
37 37 yield self._try_escape_latex(test[0], test[1])
38 38
39 39
40 40 def _try_escape_latex(self, test, result):
41 41 """Try to remove latex from string"""
42 42 self.assertEqual(escape_latex(test), result)
43 43
44 44
45 45 def test_strip_math_space(self):
46 46 """strip_math_space test"""
47 47 tests = [
48 48 ('$e$','$e$'),
49 49 ('$ e $','$e$'),
50 50 ('xxx$e^i$yyy','xxx$e^i$yyy'),
51 51 ('xxx$ e^i $yyy','xxx$e^i$yyy'),
52 52 ('xxx$e^i $yyy','xxx$e^i$yyy'),
53 53 ('xxx$ e^i$yyy','xxx$e^i$yyy'),
54 54 ('\$ e $ e $','\$ e $e$'),
55 55 ('','')]
56 56
57 57 for test in tests:
58 58 yield self._try_strip_math_space(test[0], test[1])
59 59
60 60
61 61 def _try_strip_math_space(self, test, result):
62 62 """
63 63 Try to remove spaces between dollar symbols and contents correctly
64 64 """
65 65 self.assertEqual(strip_math_space(test), result)
General Comments 0
You need to be logged in to leave comments. Login now