asciimath 1.0.9 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
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