asciimath 1.0.9 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. checksums.yaml +5 -5
  2. data/AST.adoc +457 -0
  3. data/CHANGELOG.adoc +12 -0
  4. data/Gemfile.lock +39 -0
  5. data/README.adoc +27 -3
  6. data/asciimath.gemspec +9 -5
  7. data/lib/asciimath.rb +5 -4
  8. data/lib/asciimath/ast.rb +456 -0
  9. data/lib/asciimath/cli.rb +4 -1
  10. data/lib/asciimath/color_table.rb +21 -0
  11. data/lib/asciimath/html.rb +126 -111
  12. data/lib/asciimath/latex.rb +386 -0
  13. data/lib/asciimath/markup.rb +478 -0
  14. data/lib/asciimath/mathml.rb +189 -87
  15. data/lib/asciimath/parser.rb +498 -343
  16. data/lib/asciimath/symbol_table.rb +25 -0
  17. data/lib/asciimath/version.rb +1 -1
  18. data/spec/ast.rb +144 -0
  19. data/spec/parser_spec.rb +592 -165
  20. data/spec/schema/mathml2/common/common-attribs.xsd +41 -0
  21. data/spec/schema/mathml2/common/math.xsd +126 -0
  22. data/spec/schema/mathml2/common/xlink-href.xsd +20 -0
  23. data/spec/schema/mathml2/content/arith.xsd +90 -0
  24. data/spec/schema/mathml2/content/calculus.xsd +146 -0
  25. data/spec/schema/mathml2/content/common-attrib.xsd +30 -0
  26. data/spec/schema/mathml2/content/constants.xsd +83 -0
  27. data/spec/schema/mathml2/content/constructs.xsd +260 -0
  28. data/spec/schema/mathml2/content/elementary-functions.xsd +117 -0
  29. data/spec/schema/mathml2/content/functions.xsd +73 -0
  30. data/spec/schema/mathml2/content/linear-algebra.xsd +173 -0
  31. data/spec/schema/mathml2/content/logic.xsd +53 -0
  32. data/spec/schema/mathml2/content/relations.xsd +55 -0
  33. data/spec/schema/mathml2/content/semantics.xsd +85 -0
  34. data/spec/schema/mathml2/content/sets.xsd +236 -0
  35. data/spec/schema/mathml2/content/statistics.xsd +136 -0
  36. data/spec/schema/mathml2/content/tokens.xsd +120 -0
  37. data/spec/schema/mathml2/content/vector-calculus.xsd +88 -0
  38. data/spec/schema/mathml2/mathml2.xsd +59 -0
  39. data/spec/schema/mathml2/presentation/action.xsd +44 -0
  40. data/spec/schema/mathml2/presentation/characters.xsd +37 -0
  41. data/spec/schema/mathml2/presentation/common-attribs.xsd +113 -0
  42. data/spec/schema/mathml2/presentation/common-types.xsd +103 -0
  43. data/spec/schema/mathml2/presentation/error.xsd +40 -0
  44. data/spec/schema/mathml2/presentation/layout.xsd +195 -0
  45. data/spec/schema/mathml2/presentation/scripts.xsd +186 -0
  46. data/spec/schema/mathml2/presentation/space.xsd +52 -0
  47. data/spec/schema/mathml2/presentation/style.xsd +69 -0
  48. data/spec/schema/mathml2/presentation/table.xsd +216 -0
  49. data/spec/schema/mathml2/presentation/tokens.xsd +124 -0
  50. data/spec/schema/mathml3/mathml3-common.xsd +99 -0
  51. data/spec/schema/mathml3/mathml3-content.xsd +684 -0
  52. data/spec/schema/mathml3/mathml3-presentation.xsd +2151 -0
  53. data/spec/schema/mathml3/mathml3-strict-content.xsd +186 -0
  54. data/spec/schema/mathml3/mathml3.xsd +9 -0
  55. metadata +102 -10
  56. data/.gitignore +0 -16
  57. data/.travis.yml +0 -18
@@ -0,0 +1,478 @@
1
+ require_relative 'ast'
2
+ require_relative 'symbol_table'
3
+
4
+ module AsciiMath
5
+ class MarkupBuilder
6
+ # Operation symbols
7
+ def self.add_default_display_symbols(b)
8
+ b.add(:plus, '+', :operator)
9
+ b.add(:minus, "\u2212", :operator)
10
+ b.add(:cdot, "\u22C5", :operator)
11
+ b.add(:ast, "\u002A", :operator)
12
+ b.add(:star, "\u22C6", :operator)
13
+ b.add(:slash, '/', :operator)
14
+ b.add(:backslash, '\\', :operator)
15
+ b.add(:setminus, '\\', :operator)
16
+ b.add(:times, "\u00D7", :operator)
17
+ b.add(:ltimes, "\u22C9", :operator)
18
+ b.add(:rtimes, "\u22CA", :operator)
19
+ b.add(:bowtie, "\u22C8", :operator)
20
+ b.add(:div, "\u00F7", :operator)
21
+ b.add(:circ, "\u26AC", :operator)
22
+ b.add(:oplus, "\u2295", :operator)
23
+ b.add(:otimes, "\u2297", :operator)
24
+ b.add(:odot, "\u2299", :operator)
25
+ b.add(:sum, "\u2211", :operator, :underover => true)
26
+ b.add(:prod, "\u220F", :operator, :underover => true)
27
+ b.add(:wedge, "\u2227", :operator)
28
+ b.add(:bigwedge, "\u22C0", :operator, :underover => true)
29
+ b.add(:vee, "\u2228", :operator)
30
+ b.add(:bigvee, "\u22C1", :operator, :underover => true)
31
+ b.add(:cap, "\u2229", :operator)
32
+ b.add(:bigcap, "\u22C2", :operator, :underover => true)
33
+ b.add(:cup, "\u222A", :operator)
34
+ b.add(:bigcup, "\u22C3", :operator, :underover => true)
35
+
36
+ # Relation symbols
37
+ b.add(:eq, '=', :operator)
38
+ b.add(:ne, "\u2260", :operator)
39
+ b.add(:assign, "\u2254", :operator)
40
+ b.add(:lt, "\u003C", :operator)
41
+ b.add(:gt, "\u003E", :operator)
42
+ b.add(:le, "\u2264", :operator)
43
+ b.add(:ge, "\u2265", :operator)
44
+ b.add(:prec, "\u227A", :operator)
45
+ b.add(:succ, "\u227B", :operator)
46
+ b.add(:preceq, "\u2AAF", :operator)
47
+ b.add(:succeq, "\u2AB0", :operator)
48
+ b.add(:in, "\u2208", :operator)
49
+ b.add(:notin, "\u2209", :operator)
50
+ b.add(:subset, "\u2282", :operator)
51
+ b.add(:supset, "\u2283", :operator)
52
+ b.add(:subseteq, "\u2286", :operator)
53
+ b.add(:supseteq, "\u2287", :operator)
54
+ b.add(:equiv, "\u2261", :operator)
55
+ b.add(:cong, "\u2245", :operator)
56
+ b.add(:approx, "\u2248", :operator)
57
+ b.add(:propto, "\u221D", :operator)
58
+
59
+ # Logical symbols
60
+ b.add(:and, 'and', :text)
61
+ b.add(:or, 'or', :text)
62
+ b.add(:not, "\u00AC", :operator)
63
+ b.add(:implies, "\u21D2", :operator)
64
+ b.add(:if, 'if', :operator)
65
+ b.add(:iff, "\u21D4", :operator)
66
+ b.add(:forall, "\u2200", :operator)
67
+ b.add(:exists, "\u2203", :operator)
68
+ b.add(:bot, "\u22A5", :operator)
69
+ b.add(:top, "\u22A4", :operator)
70
+ b.add(:vdash, "\u22A2", :operator)
71
+ b.add(:models, "\u22A8", :operator)
72
+
73
+ # Grouping brackets
74
+ b.add(:lparen, '(', :lparen)
75
+ b.add(:rparen, ')', :rparen)
76
+ b.add(:lbracket, '[', :lparen)
77
+ b.add(:rbracket, ']', :rparen)
78
+ b.add(:lbrace, '{', :lparen)
79
+ b.add(:rbrace, '}', :rparen)
80
+ b.add(:vbar, '|', :lrparen)
81
+ b.add(:langle, "\u2329", :lparen)
82
+ b.add(:rangle, "\u232A", :rparen)
83
+ b.add(:parallel, "\u2225", :lrparen)
84
+
85
+ # Miscellaneous symbols
86
+ b.add(:integral, "\u222B", :operator)
87
+ b.add(:dx, 'dx', :identifier)
88
+ b.add(:dy, 'dy', :identifier)
89
+ b.add(:dz, 'dz', :identifier)
90
+ b.add(:dt, 'dt', :identifier)
91
+ b.add(:contourintegral, "\u222E", :operator)
92
+ b.add(:partial, "\u2202", :operator)
93
+ b.add(:nabla, "\u2207", :operator)
94
+ b.add(:pm, "\u00B1", :operator)
95
+ b.add(:emptyset, "\u2205", :operator)
96
+ b.add(:infty, "\u221E", :operator)
97
+ b.add(:aleph, "\u2135", :operator)
98
+ b.add(:ellipsis, "\u2026", :operator)
99
+ b.add(:therefore, "\u2234", :operator)
100
+ b.add(:because, "\u2235", :operator)
101
+ b.add(:angle, "\u2220", :operator)
102
+ b.add(:triangle, "\u25B3", :operator)
103
+ b.add(:prime, "\u2032", :operator)
104
+ b.add(:tilde, "~", :accent, :position => :over)
105
+ b.add(:nbsp, "\u00A0", :operator)
106
+ b.add(:frown, "\u2322", :operator)
107
+ b.add(:quad, "\u00A0\u00A0", :operator)
108
+ b.add(:qquad, "\u00A0\u00A0\u00A0\u00A0", :operator)
109
+ b.add(:cdots, "\u22EF", :operator)
110
+ b.add(:vdots, "\u22EE", :operator)
111
+ b.add(:ddots, "\u22F1", :operator)
112
+ b.add(:diamond, "\u22C4", :operator)
113
+ b.add(:square, "\u25A1", :operator)
114
+ b.add(:lfloor, "\u230A", :operator)
115
+ b.add(:rfloor, "\u230B", :operator)
116
+ b.add(:lceiling, "\u2308", :operator)
117
+ b.add(:rceiling, "\u2309", :operator)
118
+ b.add(:dstruck_captial_c, "\u2102", :operator)
119
+ b.add(:dstruck_captial_n, "\u2115", :operator)
120
+ b.add(:dstruck_captial_q, "\u211A", :operator)
121
+ b.add(:dstruck_captial_r, "\u211D", :operator)
122
+ b.add(:dstruck_captial_z, "\u2124", :operator)
123
+ b.add(:f, 'f', :identifier)
124
+ b.add(:g, 'g', :identifier)
125
+
126
+ # Standard functions
127
+ b.add(:lim, 'lim', :operator, :underover => true)
128
+ b.add(:Lim, 'Lim', :operator, :underover => true)
129
+ b.add(:min, 'min', :operator, :underover => true)
130
+ b.add(:max, 'max', :operator, :underover => true)
131
+ b.add(:sin, 'sin', :identifier)
132
+ b.add(:Sin, 'Sin', :identifier)
133
+ b.add(:cos, 'cos', :identifier)
134
+ b.add(:Cos, 'Cos', :identifier)
135
+ b.add(:tan, 'tan', :identifier)
136
+ b.add(:Tan, 'Tan', :identifier)
137
+ b.add(:sinh, 'sinh', :identifier)
138
+ b.add(:Sinh, 'Sinh', :identifier)
139
+ b.add(:cosh, 'cosh', :identifier)
140
+ b.add(:Cosh, 'Cosh', :identifier)
141
+ b.add(:tanh, 'tanh', :identifier)
142
+ b.add(:Tanh, 'Tanh', :identifier)
143
+ b.add(:cot, 'cot', :identifier)
144
+ b.add(:Cot, 'Cot', :identifier)
145
+ b.add(:sec, 'sec', :identifier)
146
+ b.add(:Sec, 'Sec', :identifier)
147
+ b.add(:csc, 'csc', :identifier)
148
+ b.add(:Csc, 'Csc', :identifier)
149
+ b.add(:arcsin, 'arcsin', :identifier)
150
+ b.add(:arccos, 'arccos', :identifier)
151
+ b.add(:arctan, 'arctan', :identifier)
152
+ b.add(:coth, 'coth', :identifier)
153
+ b.add(:sech, 'sech', :identifier)
154
+ b.add(:csch, 'csch', :identifier)
155
+ b.add(:exp, 'exp', :identifier)
156
+ b.add(:abs, 'abs', :wrap, :lparen => '|', :rparen => '|')
157
+ b.add(:norm, 'norm', :wrap, :lparen => "\u2225", :rparen => "\u2225")
158
+ b.add(:floor, 'floor', :wrap, :lparen => "\u230A", :rparen => "\u230B")
159
+ b.add(:ceil, 'ceil', :wrap, :lparen => "\u2308", :rparen => "\u2309")
160
+ b.add(:log, 'log', :identifier)
161
+ b.add(:Log, 'Log', :identifier)
162
+ b.add(:ln, 'ln', :identifier)
163
+ b.add(:Ln, 'Ln', :identifier)
164
+ b.add(:det, 'det', :identifier)
165
+ b.add(:dim, 'dim', :identifier)
166
+ b.add(:mod, 'mod', :identifier)
167
+ b.add(:gcd, 'gcd', :identifier)
168
+ b.add(:lcm, 'lcm', :identifier)
169
+ b.add(:lub, 'lub', :identifier)
170
+ b.add(:glb, 'glb', :identifier)
171
+
172
+ # Arrows
173
+ b.add(:uparrow, "\u2191", :operator)
174
+ b.add(:downarrow, "\u2193", :operator)
175
+ b.add(:rightarrow, "\u2192", :operator)
176
+ b.add(:to, "\u2192", :operator)
177
+ b.add(:rightarrowtail, "\u21A3", :operator)
178
+ b.add(:twoheadrightarrow, "\u21A0", :operator)
179
+ b.add(:twoheadrightarrowtail, "\u2916", :operator)
180
+ b.add(:mapsto, "\u21A6", :operator)
181
+ b.add(:leftarrow, "\u2190", :operator)
182
+ b.add(:leftrightarrow, "\u2194", :operator)
183
+ b.add(:Rightarrow, "\u21D2", :operator)
184
+ b.add(:Leftarrow, "\u21D0", :operator)
185
+ b.add(:Leftrightarrow, "\u21D4", :operator)
186
+
187
+ # Unary tags
188
+ b.add(:sqrt, :sqrt, :sqrt)
189
+ b.add(:cancel, :cancel, :cancel)
190
+
191
+ # Binary tags
192
+ b.add(:root, :root, :root)
193
+ b.add(:frac, :frac, :frac)
194
+ b.add(:stackrel, :stackrel, :over)
195
+ b.add(:overset, :overset, :over)
196
+ b.add(:underset, :underset, :under)
197
+ b.add(:color, :color, :color)
198
+
199
+ b.add(:sub, "_", :operator)
200
+ b.add(:sup, "^", :operator)
201
+ b.add(:hat, "\u005E", :accent, :position => :over)
202
+ b.add(:overline, "\u00AF", :accent, :position => :over)
203
+ b.add(:vec, "\u2192", :accent, :position => :over)
204
+ b.add(:dot, '.', :accent, :position => :over)
205
+ b.add(:ddot, '..', :accent, :position => :over)
206
+ b.add(:overarc, "\u23DC", :accent, :position => :over)
207
+ b.add(:underline, '_', :accent, :position => :under)
208
+ b.add(:underbrace, "\u23DF", :accent, :position => :under)
209
+ b.add(:overbrace, "\u23DE", :accent, :position => :over)
210
+ b.add(:bold, :bold, :font)
211
+ b.add(:double_struck, :double_struck, :font)
212
+ b.add(:italic, :italic, :font)
213
+ b.add(:bold_italic, :bold_italic, :font)
214
+ b.add(:script, :script, :font)
215
+ b.add(:bold_script, :bold_script, :font)
216
+ b.add(:monospace, :monospace, :font)
217
+ b.add(:fraktur, :fraktur, :font)
218
+ b.add(:bold_fraktur, :bold_fraktur, :font)
219
+ b.add(:sans_serif, :sans_serif, :font)
220
+ b.add(:bold_sans_serif, :bold_sans_serif, :font)
221
+ b.add(:sans_serif_italic, :sans_serif_italic, :font)
222
+ b.add(:sans_serif_bold_italic, :sans_serif_bold_italic, :font)
223
+
224
+ # Greek letters
225
+ b.add(:alpha, "\u03b1", :identifier)
226
+ b.add(:Alpha, "\u0391", :identifier)
227
+ b.add(:beta, "\u03b2", :identifier)
228
+ b.add(:Beta, "\u0392", :identifier)
229
+ b.add(:gamma, "\u03b3", :identifier)
230
+ b.add(:Gamma, "\u0393", :operator)
231
+ b.add(:delta, "\u03b4", :identifier)
232
+ b.add(:Delta, "\u0394", :operator)
233
+ b.add(:epsilon, "\u03b5", :identifier)
234
+ b.add(:Epsilon, "\u0395", :identifier)
235
+ b.add(:varepsilon, "\u025b", :identifier)
236
+ b.add(:zeta, "\u03b6", :identifier)
237
+ b.add(:Zeta, "\u0396", :identifier)
238
+ b.add(:eta, "\u03b7", :identifier)
239
+ b.add(:Eta, "\u0397", :identifier)
240
+ b.add(:theta, "\u03b8", :identifier)
241
+ b.add(:Theta, "\u0398", :operator)
242
+ b.add(:vartheta, "\u03d1", :identifier)
243
+ b.add(:iota, "\u03b9", :identifier)
244
+ b.add(:Iota, "\u0399", :identifier)
245
+ b.add(:kappa, "\u03ba", :identifier)
246
+ b.add(:Kappa, "\u039a", :identifier)
247
+ b.add(:lambda, "\u03bb", :identifier)
248
+ b.add(:Lambda, "\u039b", :operator)
249
+ b.add(:mu, "\u03bc", :identifier)
250
+ b.add(:Mu, "\u039c", :identifier)
251
+ b.add(:nu, "\u03bd", :identifier)
252
+ b.add(:Nu, "\u039d", :identifier)
253
+ b.add(:xi, "\u03be", :identifier)
254
+ b.add(:Xi, "\u039e", :operator)
255
+ b.add(:omicron, "\u03bf", :identifier)
256
+ b.add(:Omicron, "\u039f", :identifier)
257
+ b.add(:pi, "\u03c0", :identifier)
258
+ b.add(:Pi, "\u03a0", :operator)
259
+ b.add(:rho, "\u03c1", :identifier)
260
+ b.add(:Rho, "\u03a1", :identifier)
261
+ b.add(:sigma, "\u03c3", :identifier)
262
+ b.add(:Sigma, "\u03a3", :operator)
263
+ b.add(:tau, "\u03c4", :identifier)
264
+ b.add(:Tau, "\u03a4", :identifier)
265
+ b.add(:upsilon, "\u03c5", :identifier)
266
+ b.add(:Upsilon, "\u03a5", :identifier)
267
+ b.add(:phi, "\u03c6", :identifier)
268
+ b.add(:Phi, "\u03a6", :identifier)
269
+ b.add(:varphi, "\u03d5", :identifier)
270
+ b.add(:chi, "\u03c7", :identifier)
271
+ b.add(:Chi, "\u03a7", :identifier)
272
+ b.add(:psi, "\u03c8", :identifier)
273
+ b.add(:Psi, "\u03a8", :identifier)
274
+ b.add(:omega, "\u03c9", :identifier)
275
+ b.add(:Omega, "\u03a9", :operator)
276
+
277
+ b
278
+ end
279
+
280
+ DEFAULT_DISPLAY_SYMBOL_TABLE = ::AsciiMath::MarkupBuilder.add_default_display_symbols(AsciiMath::SymbolTableBuilder.new).build
281
+
282
+ def initialize(symbol_table)
283
+ @symbol_table = symbol_table
284
+ end
285
+
286
+ private
287
+
288
+ def append(node, opts = {})
289
+ row_mode = opts[:row] || :avoid
290
+ if row_mode == :force
291
+ case node
292
+ when ::AsciiMath::AST::Sequence
293
+ append_row(node)
294
+ else
295
+ append_row([node])
296
+ end
297
+ return
298
+ end
299
+
300
+ case node
301
+ when ::AsciiMath::AST::Sequence
302
+ if (node.length <= 1 && row_mode == :avoid) || row_mode == :omit
303
+ node.each { |e| append(e) }
304
+ else
305
+ append_row(node)
306
+ end
307
+ when ::AsciiMath::AST::Group
308
+ append(node.expression)
309
+ when ::AsciiMath::AST::Text
310
+ append_text(node.value)
311
+ when ::AsciiMath::AST::Number
312
+ append_number(node.value)
313
+ when ::AsciiMath::AST::Identifier
314
+ append_identifier(node.value)
315
+ when ::AsciiMath::AST::Symbol
316
+ if (symbol = resolve_symbol(node))
317
+ case symbol[:type]
318
+ when :operator, :accent, :lparen, :rparen, :lrparen
319
+ append_operator(symbol[:value])
320
+ else
321
+ append_identifier(symbol[:value])
322
+ end
323
+ else
324
+ append_identifier(node[:value])
325
+ end
326
+ when ::AsciiMath::AST::Paren
327
+ append_paren(resolve_paren(node.lparen), node.expression, resolve_paren(node.rparen), opts)
328
+ when ::AsciiMath::AST::SubSup
329
+ if (resolve_symbol(node.base_expression) || {})[:underover]
330
+ append_underover(node.base_expression, node.sub_expression, node.sup_expression)
331
+ else
332
+ append_subsup(node.base_expression, node.sub_expression, node.sup_expression)
333
+ end
334
+ when ::AsciiMath::AST::UnaryOp
335
+ if (symbol = resolve_symbol(node.operator))
336
+ case symbol[:type]
337
+ when :identifier
338
+ append_identifier_unary(symbol[:value], node.operand)
339
+ when :operator
340
+ append_operator_unary(symbol[:value], node.operand)
341
+ when :wrap
342
+ append_paren(resolve_paren(symbol[:lparen]), node.operand, resolve_paren(symbol[:rparen]), opts)
343
+ when :accent
344
+ if symbol[:position] == :over
345
+ append_underover(node.operand, nil, node.operator)
346
+ else
347
+ append_underover(node.operand, node.operator, nil)
348
+ end
349
+ when :font
350
+ append_font(symbol[:value], node.operand)
351
+ when :cancel
352
+ append_cancel(node.operand)
353
+ when :sqrt
354
+ append_sqrt(node.operand)
355
+ end
356
+ end
357
+ when ::AsciiMath::AST::BinaryOp
358
+ if (symbol = resolve_symbol(node.operator))
359
+ case symbol[:type]
360
+ when :over
361
+ append_underover(node.operand2, nil, node.operand1)
362
+ when :under
363
+ append_underover(node.operand2, node.operand1, nil)
364
+ when :root
365
+ append_root(node.operand2, node.operand1)
366
+ when :color
367
+ append_color(node.operand1.to_hex_rgb, node.operand2)
368
+ end
369
+ end
370
+ when ::AsciiMath::AST::InfixOp
371
+ if (symbol = resolve_symbol(node.operator))
372
+ case symbol[:type]
373
+ when :frac
374
+ append_fraction(node.operand1, node.operand2)
375
+ end
376
+ end
377
+ when ::AsciiMath::AST::Matrix
378
+ append_matrix(resolve_paren(node.lparen), node, resolve_paren(node.rparen))
379
+ end
380
+ end
381
+
382
+ def append_row(expressions)
383
+ raise NotImplementedError.new __method__.to_s
384
+ end
385
+
386
+ def append_operator(operator)
387
+ raise NotImplementedError.new __method__.to_s
388
+ end
389
+
390
+ def append_identifier(identifier)
391
+ raise NotImplementedError.new __method__.to_s
392
+ end
393
+
394
+ def append_text(text_string)
395
+ raise NotImplementedError.new __method__.to_s
396
+ end
397
+
398
+ def append_number(number)
399
+ raise NotImplementedError.new __method__.to_s
400
+ end
401
+
402
+ def append_sqrt(expression)
403
+ raise NotImplementedError.new __method__.to_s
404
+ end
405
+
406
+ def append_cancel(expression)
407
+ raise NotImplementedError.new __method__.to_s
408
+ end
409
+
410
+ def append_root(base, index)
411
+ raise NotImplementedError.new __method__.to_s
412
+ end
413
+
414
+ def append_color(color, expression)
415
+ raise NotImplementedError.new __method__.to_s
416
+ end
417
+
418
+ def append_fraction(numerator, denominator)
419
+ raise NotImplementedError.new __method__.to_s
420
+ end
421
+
422
+ def append_font(style, expression)
423
+ raise NotImplementedError.new __method__.to_s
424
+ end
425
+
426
+ def append_matrix(lparen, rows, rparen)
427
+ raise NotImplementedError.new __method__.to_s
428
+ end
429
+
430
+ def append_operator_unary(operator, expression)
431
+ raise NotImplementedError.new __method__.to_s
432
+ end
433
+
434
+ def append_identifier_unary(identifier, expression)
435
+ raise NotImplementedError.new __method__.to_s
436
+ end
437
+
438
+ def append_paren(lparen, expression, rparen, opts)
439
+ raise NotImplementedError.new __method__.to_s
440
+ end
441
+
442
+ def append_subsup(base, sub, sup)
443
+ raise NotImplementedError.new __method__.to_s
444
+ end
445
+
446
+ def append_underover(base, under, over)
447
+ raise NotImplementedError.new __method__.to_s
448
+ end
449
+
450
+ def resolve_paren(paren_symbol)
451
+ if paren_symbol.nil?
452
+ return nil
453
+ end
454
+
455
+ if (resolved = resolve_symbol(paren_symbol))
456
+ resolved[:value]
457
+ else
458
+ case paren_symbol
459
+ when ::AsciiMath::AST::Symbol
460
+ paren_symbol.value
461
+ else
462
+ paren_symbol
463
+ end
464
+ end
465
+ end
466
+
467
+ def resolve_symbol(node)
468
+ case node
469
+ when ::AsciiMath::AST::Symbol
470
+ @symbol_table[node.value]
471
+ when ::Symbol
472
+ @symbol_table[node]
473
+ else
474
+ nil
475
+ end
476
+ end
477
+ end
478
+ end