Skip to content

Commit 09ddd4b

Browse files
authored
Merge pull request #149 from manuelbb-upb/delimiters
additional delimiters / delimiter commands
2 parents 82fc6a3 + efdbaab commit 09ddd4b

File tree

5 files changed

+116
-7
lines changed

5 files changed

+116
-7
lines changed

src/parser/commands_data.jl

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,43 @@ combining_accents = [
107107
]
108108

109109
punctuation_symbols = split(raw", ; . !")
110-
delimiter_symbols = split(raw"| / ( ) [ ] < >")
110+
delimiter_symbols = split(raw"| / \ ( ) [ ] ⟨ ⟩ ‖ ⌈ ⌉ ⌊ ⌋ ⌜ ⌝ ⌞ ⌟")
111+
## NOTE `<` and `>` not included in `delimiter_symbols` because
112+
## they should not be used as such. In math mode, they are relation symbols and
113+
## we don't want to change that by overwriting the `symbol_to_canonical` entries.
114+
## **However**, `\left<` and `\right>` should work to produce `\left\langle` and
115+
## `\right\rangle`, respectively, due to intercepting `delimiter(...)`.
116+
## NOTE `{` and `}` not included because they are group delimiters that the tokenizer
117+
## should recognize as `lcurly` and `rcurly`.
118+
## The symbols have to be typed by command.
119+
120+
## some delimiter symbols can also be typed with commands;
121+
### instead of relying on `get_symbol_char` (like with `space_commands` in `commands_registration.jl`)
122+
### we define them explicitly, because `latex_symbols` misses some
123+
delimiter_commands = Dict(
124+
raw"\vert" => '|',
125+
raw"\slash" => '/', # NOTE seems to work with LaTeX, but not MathJax
126+
raw"\backslash" => '\\',
127+
raw"\lbrack" => '[',
128+
raw"\rbrack" => ']',
129+
raw"\langle" => '',
130+
raw"\rangle" => '',
131+
raw"\|" => '',
132+
raw"\Vert" => '',
133+
raw"\lceil" => '',
134+
raw"\rceil" => '',
135+
raw"\lfloor" => '',
136+
raw"\lfloor" => '',
137+
raw"\ulcorner" => '',
138+
raw"\urcorner" => '',
139+
raw"\llcorner" => '',
140+
raw"\lrcorner" => '',
141+
raw"\{" => '{',
142+
raw"\}" => '}',
143+
raw"\lbrace" => '{',
144+
raw"\rbrace" => '}',
145+
)
146+
111147
font_names = split(raw"rm cal it tt sf bf default bb frak scr regular")
112148

113149
# TODO Add to the parser what come below, if needed

src/parser/commands_registration.jl

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,6 @@ const command_definitions = Dict(
5858
raw"\frac" => (TeXExpr(:frac), 2),
5959
raw"\sqrt" => (TeXExpr(:sqrt), 1),
6060
raw"\overline" => (TeXExpr(:overline), 1),
61-
raw"\{" => (TeXExpr(:delimiter, '{'), 0),
62-
raw"\}" => (TeXExpr(:delimiter, '}'), 0),
6361
raw"\_" => (TeXExpr(:symbol, '_'), 0),
6462
raw"\%" => (TeXExpr(:symbol, '%'), 0),
6563
raw"\$" => (TeXExpr(:symbol, '$'), 0),
@@ -150,11 +148,20 @@ for symbol in punctuation_symbols
150148
symbol_to_canonical[symbol] = TeXExpr(:punctuation, symbol)
151149
end
152150

151+
# Delimiters
153152
for symbol in delimiter_symbols
154153
symbol = first(symbol)
155154
symbol_to_canonical[symbol] = TeXExpr(:delimiter, symbol)
156155
end
157156

157+
for (com_str, symbol) in pairs(delimiter_commands)
158+
delim_expr = TeXExpr(:delimiter, symbol)
159+
if !haskey(symbol_to_canonical, symbol)
160+
symbol_to_canonical[symbol] = delim_expr
161+
end
162+
command_definitions[com_str] = (delim_expr, 0)
163+
end
164+
158165
##
159166
## Default behavior
160167
##

src/parser/parser.jl

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,13 @@ end
106106
function delimiter(com_str, str)
107107
str = str[length(com_str)+1:end]
108108
if length(str) == 1
109-
return TeXExpr(:delimiter, only(str))
109+
char = only(str)
110+
if char == '<'
111+
char = ''
112+
elseif char == '>'
113+
char = ''
114+
end
115+
return TeXExpr(:delimiter, char)
110116
else
111117
return only(texparse(str).args)
112118
end

src/parser/tokenizer.jl

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
1+
const token_command = re"\\[a-zA-Z]+" | re"\\."
12
tex_tokens = [
23
:char => re".",
34
:primes => re"'+",
45
:caret => re"\^",
56
:underscore => re"_",
67
:rcurly => re"}",
78
:lcurly => re"{",
8-
:command => re"\\[a-zA-Z]+" | re"\\.",
9-
:right => re"\\right.",
10-
:left => re"\\left.",
9+
:command => token_command,
10+
:right => re"\\right." | re"\\right" * token_command,
11+
:left => re"\\left." | re"\\left" * token_command,
1112
:newline => (re"\\" * re"\\") | re"\\n",
1213
:dollar => re"$"
1314
]

test/parser.jl

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,65 @@ end
5555

5656
@test_throws TeXParseError texparse(raw"\left( x")
5757
@test_throws TeXParseError texparse(raw"x \right)")
58+
59+
## all `delimiter_symbols`
60+
test_parse(raw"|", (:delimiter, '|'))
61+
test_parse(raw"/", (:delimiter, '/'))
62+
test_parse(raw"\\", (:delimiter, '\\'))
63+
test_parse(raw"(", (:delimiter, '('))
64+
test_parse(raw")", (:delimiter, ')'))
65+
test_parse(raw"[", (:delimiter, '['))
66+
test_parse(raw"]", (:delimiter, ']'))
67+
test_parse(raw"", (:delimiter, ''))
68+
test_parse(raw"", (:delimiter, ''))
69+
test_parse(raw"", (:delimiter, ''))
70+
test_parse(raw"", (:delimiter, ''))
71+
test_parse(raw"", (:delimiter, ''))
72+
test_parse(raw"", (:delimiter, ''))
73+
test_parse(raw"", (:delimiter, ''))
74+
test_parse(raw"", (:delimiter, ''))
75+
test_parse(raw"", (:delimiter, ''))
76+
test_parse(raw"", (:delimiter, ''))
77+
test_parse(raw"", (:delimiter, ''))
78+
79+
test_parse(raw"<", (:space, '<')) # formerly, this was a delimiter
80+
test_parse(raw">", (:space, '>'))
81+
82+
## all `delimiter_commands`
83+
test_parse(raw"\vert", (:delimiter, '|'))
84+
test_parse(raw"\slash", (:delimiter, '/'))
85+
test_parse(raw"\backslash", (:delimiter, '\\'))
86+
test_parse(raw"\lbrack", (:delimiter, '['))
87+
test_parse(raw"\rbrack", (:delimiter, ']'))
88+
test_parse(raw"\langle", (:delimiter, ''))
89+
test_parse(raw"\rangle", (:delimiter, ''))
90+
test_parse(raw"\|", (:delimiter, ''))
91+
test_parse(raw"\Vert", (:delimiter, ''))
92+
test_parse(raw"\lceil", (:delimiter, ''))
93+
test_parse(raw"\rceil", (:delimiter, ''))
94+
test_parse(raw"\lfloor", (:delimiter, ''))
95+
test_parse(raw"\lfloor", (:delimiter, ''))
96+
test_parse(raw"\ulcorner", (:delimiter, ''))
97+
test_parse(raw"\urcorner", (:delimiter, ''))
98+
test_parse(raw"\llcorner", (:delimiter, ''))
99+
test_parse(raw"\lrcorner", (:delimiter, ''))
100+
test_parse(raw"\{", (:delimiter, '{'))
101+
test_parse(raw"\}", (:delimiter, '}'))
102+
test_parse(raw"\lbrace", (:delimiter, '{'))
103+
test_parse(raw"\rbrace", (:delimiter, '}'))
104+
105+
### test commands as arguments to a delimited group
106+
for (cmd_str, delim_symb) in pairs(MathTeXEngine.delimiter_commands)
107+
## NOTE this does not check for "correct" left right pairs like `\lbrack` and `\rbrack`
108+
test_parse(
109+
"\\left$(cmd_str)\\right$(cmd_str)",
110+
(:delimited,
111+
(:delimiter, delim_symb),
112+
(:group,),
113+
(:delimiter, delim_symb)
114+
)
115+
)
116+
end
58117
end
59118

60119
@testset "Fonts" begin

0 commit comments

Comments
 (0)