asciimath 1.0.9 → 2.0.3

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 (59) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/ci.yml +20 -0
  3. data/AST.adoc +457 -0
  4. data/CHANGELOG.adoc +47 -1
  5. data/Gemfile +5 -0
  6. data/README.adoc +68 -4
  7. data/asciimath.gemspec +3 -6
  8. data/dump_symbol_table.rb +46 -0
  9. data/lib/asciimath.rb +5 -4
  10. data/lib/asciimath/ast.rb +456 -0
  11. data/lib/asciimath/cli.rb +4 -1
  12. data/lib/asciimath/color_table.rb +21 -0
  13. data/lib/asciimath/html.rb +128 -112
  14. data/lib/asciimath/latex.rb +399 -0
  15. data/lib/asciimath/markup.rb +509 -0
  16. data/lib/asciimath/mathml.rb +206 -87
  17. data/lib/asciimath/parser.rb +510 -350
  18. data/lib/asciimath/symbol_table.rb +25 -0
  19. data/lib/asciimath/version.rb +1 -1
  20. data/spec/ast.rb +144 -0
  21. data/spec/customisation_spec.rb +28 -0
  22. data/spec/parser_spec.rb +623 -165
  23. data/spec/schema/mathml2/common/common-attribs.xsd +41 -0
  24. data/spec/schema/mathml2/common/math.xsd +126 -0
  25. data/spec/schema/mathml2/common/xlink-href.xsd +20 -0
  26. data/spec/schema/mathml2/content/arith.xsd +90 -0
  27. data/spec/schema/mathml2/content/calculus.xsd +146 -0
  28. data/spec/schema/mathml2/content/common-attrib.xsd +30 -0
  29. data/spec/schema/mathml2/content/constants.xsd +83 -0
  30. data/spec/schema/mathml2/content/constructs.xsd +260 -0
  31. data/spec/schema/mathml2/content/elementary-functions.xsd +117 -0
  32. data/spec/schema/mathml2/content/functions.xsd +73 -0
  33. data/spec/schema/mathml2/content/linear-algebra.xsd +173 -0
  34. data/spec/schema/mathml2/content/logic.xsd +53 -0
  35. data/spec/schema/mathml2/content/relations.xsd +55 -0
  36. data/spec/schema/mathml2/content/semantics.xsd +85 -0
  37. data/spec/schema/mathml2/content/sets.xsd +236 -0
  38. data/spec/schema/mathml2/content/statistics.xsd +136 -0
  39. data/spec/schema/mathml2/content/tokens.xsd +120 -0
  40. data/spec/schema/mathml2/content/vector-calculus.xsd +88 -0
  41. data/spec/schema/mathml2/mathml2.xsd +59 -0
  42. data/spec/schema/mathml2/presentation/action.xsd +44 -0
  43. data/spec/schema/mathml2/presentation/characters.xsd +37 -0
  44. data/spec/schema/mathml2/presentation/common-attribs.xsd +113 -0
  45. data/spec/schema/mathml2/presentation/common-types.xsd +103 -0
  46. data/spec/schema/mathml2/presentation/error.xsd +40 -0
  47. data/spec/schema/mathml2/presentation/layout.xsd +195 -0
  48. data/spec/schema/mathml2/presentation/scripts.xsd +186 -0
  49. data/spec/schema/mathml2/presentation/space.xsd +52 -0
  50. data/spec/schema/mathml2/presentation/style.xsd +69 -0
  51. data/spec/schema/mathml2/presentation/table.xsd +216 -0
  52. data/spec/schema/mathml2/presentation/tokens.xsd +124 -0
  53. data/spec/schema/mathml3/mathml3-common.xsd +99 -0
  54. data/spec/schema/mathml3/mathml3-content.xsd +684 -0
  55. data/spec/schema/mathml3/mathml3-presentation.xsd +2151 -0
  56. data/spec/schema/mathml3/mathml3-strict-content.xsd +186 -0
  57. data/spec/schema/mathml3/mathml3.xsd +9 -0
  58. metadata +88 -48
  59. data/.travis.yml +0 -18
@@ -0,0 +1,509 @@
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, fix_phi: true)
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(:ker, 'ker', :identifier)
167
+ b.add(:mod, 'mod', :identifier)
168
+ b.add(:gcd, 'gcd', :identifier)
169
+ b.add(:lcm, 'lcm', :identifier)
170
+ b.add(:lub, 'lub', :identifier)
171
+ b.add(:glb, 'glb', :identifier)
172
+
173
+ # Arrows
174
+ b.add(:uparrow, "\u2191", :operator)
175
+ b.add(:downarrow, "\u2193", :operator)
176
+ b.add(:rightarrow, "\u2192", :operator)
177
+ b.add(:to, "\u2192", :operator)
178
+ b.add(:rightarrowtail, "\u21A3", :operator)
179
+ b.add(:twoheadrightarrow, "\u21A0", :operator)
180
+ b.add(:twoheadrightarrowtail, "\u2916", :operator)
181
+ b.add(:mapsto, "\u21A6", :operator)
182
+ b.add(:leftarrow, "\u2190", :operator)
183
+ b.add(:leftrightarrow, "\u2194", :operator)
184
+ b.add(:Rightarrow, "\u21D2", :operator)
185
+ b.add(:Leftarrow, "\u21D0", :operator)
186
+ b.add(:Leftrightarrow, "\u21D4", :operator)
187
+
188
+ # Unary tags
189
+ b.add(:sqrt, :sqrt, :sqrt)
190
+ b.add(:cancel, :cancel, :cancel)
191
+
192
+ # Binary tags
193
+ b.add(:root, :root, :root)
194
+ b.add(:frac, :frac, :frac)
195
+ b.add(:stackrel, :stackrel, :over)
196
+ b.add(:overset, :overset, :over)
197
+ b.add(:underset, :underset, :under)
198
+ b.add(:color, :color, :color)
199
+
200
+ b.add(:sub, "_", :operator)
201
+ b.add(:sup, "^", :operator)
202
+ b.add(:hat, "\u005E", :accent, :position => :over)
203
+ b.add(:overline, "\u00AF", :accent, :position => :over)
204
+ b.add(:vec, "\u2192", :accent, :position => :over)
205
+ b.add(:dot, '.', :accent, :position => :over)
206
+ b.add(:ddot, '..', :accent, :position => :over)
207
+ b.add(:overarc, "\u23DC", :accent, :position => :over)
208
+ b.add(:underline, '_', :accent, :position => :under)
209
+ b.add(:underbrace, "\u23DF", :accent, :position => :under)
210
+ b.add(:overbrace, "\u23DE", :accent, :position => :over)
211
+ b.add(:bold, :bold, :font)
212
+ b.add(:double_struck, :double_struck, :font)
213
+ b.add(:italic, :italic, :font)
214
+ b.add(:bold_italic, :bold_italic, :font)
215
+ b.add(:script, :script, :font)
216
+ b.add(:bold_script, :bold_script, :font)
217
+ b.add(:monospace, :monospace, :font)
218
+ b.add(:fraktur, :fraktur, :font)
219
+ b.add(:bold_fraktur, :bold_fraktur, :font)
220
+ b.add(:sans_serif, :sans_serif, :font)
221
+ b.add(:bold_sans_serif, :bold_sans_serif, :font)
222
+ b.add(:sans_serif_italic, :sans_serif_italic, :font)
223
+ b.add(:sans_serif_bold_italic, :sans_serif_bold_italic, :font)
224
+ b.add(:roman, :normal, :font)
225
+
226
+ # Greek letters
227
+ b.add(:alpha, "\u03b1", :identifier)
228
+ b.add(:Alpha, "\u0391", :identifier)
229
+ b.add(:beta, "\u03b2", :identifier)
230
+ b.add(:Beta, "\u0392", :identifier)
231
+ b.add(:gamma, "\u03b3", :identifier)
232
+ b.add(:Gamma, "\u0393", :operator)
233
+ b.add(:delta, "\u03b4", :identifier)
234
+ b.add(:Delta, "\u0394", :operator)
235
+ b.add(:epsilon, "\u03b5", :identifier)
236
+ b.add(:Epsilon, "\u0395", :identifier)
237
+ b.add(:varepsilon, "\u025b", :identifier)
238
+ b.add(:zeta, "\u03b6", :identifier)
239
+ b.add(:Zeta, "\u0396", :identifier)
240
+ b.add(:eta, "\u03b7", :identifier)
241
+ b.add(:Eta, "\u0397", :identifier)
242
+ b.add(:theta, "\u03b8", :identifier)
243
+ b.add(:Theta, "\u0398", :operator)
244
+ b.add(:vartheta, "\u03d1", :identifier)
245
+ b.add(:iota, "\u03b9", :identifier)
246
+ b.add(:Iota, "\u0399", :identifier)
247
+ b.add(:kappa, "\u03ba", :identifier)
248
+ b.add(:Kappa, "\u039a", :identifier)
249
+ b.add(:lambda, "\u03bb", :identifier)
250
+ b.add(:Lambda, "\u039b", :operator)
251
+ b.add(:mu, "\u03bc", :identifier)
252
+ b.add(:Mu, "\u039c", :identifier)
253
+ b.add(:nu, "\u03bd", :identifier)
254
+ b.add(:Nu, "\u039d", :identifier)
255
+ b.add(:xi, "\u03be", :identifier)
256
+ b.add(:Xi, "\u039e", :operator)
257
+ b.add(:omicron, "\u03bf", :identifier)
258
+ b.add(:Omicron, "\u039f", :identifier)
259
+ b.add(:pi, "\u03c0", :identifier)
260
+ b.add(:Pi, "\u03a0", :operator)
261
+ b.add(:rho, "\u03c1", :identifier)
262
+ b.add(:Rho, "\u03a1", :identifier)
263
+ b.add(:sigma, "\u03c3", :identifier)
264
+ b.add(:Sigma, "\u03a3", :operator)
265
+ b.add(:tau, "\u03c4", :identifier)
266
+ b.add(:Tau, "\u03a4", :identifier)
267
+ b.add(:upsilon, "\u03c5", :identifier)
268
+ b.add(:Upsilon, "\u03a5", :identifier)
269
+ if fix_phi
270
+ b.add(:phi, "\u03d5", :identifier)
271
+ b.add(:varphi, "\u03c6", :identifier)
272
+ else
273
+ b.add(:phi, "\u03c6", :identifier)
274
+ b.add(:varphi, "\u03d5", :identifier)
275
+ end
276
+ b.add(:Phi, "\u03a6", :identifier)
277
+ b.add(:chi, "\u03c7", :identifier)
278
+ b.add(:Chi, "\u03a7", :identifier)
279
+ b.add(:psi, "\u03c8", :identifier)
280
+ b.add(:Psi, "\u03a8", :identifier)
281
+ b.add(:omega, "\u03c9", :identifier)
282
+ b.add(:Omega, "\u03a9", :operator)
283
+
284
+ b
285
+ end
286
+
287
+ private
288
+ DEFAULT_SYMBOL_TABLE = ::AsciiMath::MarkupBuilder.add_default_display_symbols(AsciiMath::SymbolTableBuilder.new, fix_phi: false).build
289
+ DEFAULT_SYMBOL_TABLE_FIX_PHI = ::AsciiMath::MarkupBuilder.add_default_display_symbols(AsciiMath::SymbolTableBuilder.new, fix_phi: true).build
290
+
291
+ public
292
+ def self.default_display_symbol_table(fix_phi: true)
293
+ if fix_phi
294
+ DEFAULT_SYMBOL_TABLE_FIX_PHI
295
+ else
296
+ DEFAULT_SYMBOL_TABLE
297
+ end
298
+ end
299
+
300
+ def initialize(symbol_table)
301
+ @symbol_table = symbol_table
302
+ end
303
+
304
+ private
305
+
306
+ def append(node, opts = {})
307
+ row_mode = opts[:row] || :avoid
308
+ if row_mode == :force
309
+ case node
310
+ when ::AsciiMath::AST::Sequence
311
+ append_row(node)
312
+ else
313
+ append_row([node])
314
+ end
315
+ return
316
+ end
317
+
318
+ case node
319
+ when ::AsciiMath::AST::Sequence
320
+ if (node.length <= 1 && row_mode == :avoid) || row_mode == :omit
321
+ node.each { |e| append(e) }
322
+ else
323
+ append_row(node)
324
+ end
325
+ when ::AsciiMath::AST::Group
326
+ append(node.expression)
327
+ when ::AsciiMath::AST::Text
328
+ append_text(node.value)
329
+ when ::AsciiMath::AST::Number
330
+ append_number(node.value)
331
+ when ::AsciiMath::AST::Identifier
332
+ append_identifier_or_operator(node.value)
333
+ when ::AsciiMath::AST::Symbol
334
+ if (symbol = resolve_symbol(node))
335
+ case symbol[:type]
336
+ when :operator, :accent, :lparen, :rparen, :lrparen
337
+ append_operator(symbol[:value])
338
+ else
339
+ append_identifier(symbol[:value])
340
+ end
341
+ else
342
+ append_identifier_or_operator(node[:value])
343
+ end
344
+ when ::AsciiMath::AST::Paren
345
+ append_paren(resolve_paren(node.lparen), node.expression, resolve_paren(node.rparen), opts)
346
+ when ::AsciiMath::AST::SubSup
347
+ if (resolve_symbol(node.base_expression) || {})[:underover]
348
+ append_underover(node.base_expression, node.sub_expression, node.sup_expression)
349
+ else
350
+ append_subsup(node.base_expression, node.sub_expression, node.sup_expression)
351
+ end
352
+ when ::AsciiMath::AST::UnaryOp
353
+ if (symbol = resolve_symbol(node.operator))
354
+ case symbol[:type]
355
+ when :identifier
356
+ append_identifier_unary(symbol[:value], node.operand)
357
+ when :operator
358
+ append_operator_unary(symbol[:value], node.operand)
359
+ when :wrap
360
+ append_paren(resolve_paren(symbol[:lparen]), node.operand, resolve_paren(symbol[:rparen]), opts)
361
+ when :accent
362
+ if symbol[:position] == :over
363
+ append_underover(node.operand, nil, node.operator)
364
+ else
365
+ append_underover(node.operand, node.operator, nil)
366
+ end
367
+ when :font
368
+ append_font(symbol[:value], node.operand)
369
+ when :cancel
370
+ append_cancel(node.operand)
371
+ when :sqrt
372
+ append_sqrt(node.operand)
373
+ end
374
+ end
375
+ when ::AsciiMath::AST::BinaryOp
376
+ if (symbol = resolve_symbol(node.operator))
377
+ case symbol[:type]
378
+ when :over
379
+ append_underover(node.operand2, nil, node.operand1)
380
+ when :under
381
+ append_underover(node.operand2, node.operand1, nil)
382
+ when :root
383
+ append_root(node.operand2, node.operand1)
384
+ when :color
385
+ append_color(node.operand1.to_hex_rgb, node.operand2)
386
+ end
387
+ end
388
+ when ::AsciiMath::AST::InfixOp
389
+ if (symbol = resolve_symbol(node.operator))
390
+ case symbol[:type]
391
+ when :frac
392
+ append_fraction(node.operand1, node.operand2)
393
+ end
394
+ end
395
+ when ::AsciiMath::AST::Matrix
396
+ append_matrix(resolve_paren(node.lparen), node, resolve_paren(node.rparen))
397
+ end
398
+ end
399
+
400
+ def append_row(expressions)
401
+ raise NotImplementedError.new __method__.to_s
402
+ end
403
+
404
+ def append_operator(operator)
405
+ raise NotImplementedError.new __method__.to_s
406
+ end
407
+
408
+ def append_identifier_or_operator(value)
409
+ if value.empty? || value =~ /[[:alnum:]].*/
410
+ append_identifier(value)
411
+ else
412
+ append_operator(value)
413
+ end
414
+ end
415
+
416
+ def append_identifier(identifier)
417
+ raise NotImplementedError.new __method__.to_s
418
+ end
419
+
420
+ def append_text(text_string)
421
+ raise NotImplementedError.new __method__.to_s
422
+ end
423
+
424
+ def append_number(number)
425
+ raise NotImplementedError.new __method__.to_s
426
+ end
427
+
428
+ def append_sqrt(expression)
429
+ raise NotImplementedError.new __method__.to_s
430
+ end
431
+
432
+ def append_cancel(expression)
433
+ raise NotImplementedError.new __method__.to_s
434
+ end
435
+
436
+ def append_root(base, index)
437
+ raise NotImplementedError.new __method__.to_s
438
+ end
439
+
440
+ def append_color(color, expression)
441
+ raise NotImplementedError.new __method__.to_s
442
+ end
443
+
444
+ def append_fraction(numerator, denominator)
445
+ raise NotImplementedError.new __method__.to_s
446
+ end
447
+
448
+ def append_font(style, expression)
449
+ raise NotImplementedError.new __method__.to_s
450
+ end
451
+
452
+ def append_matrix(lparen, rows, rparen)
453
+ raise NotImplementedError.new __method__.to_s
454
+ end
455
+
456
+ def append_operator_unary(operator, expression)
457
+ raise NotImplementedError.new __method__.to_s
458
+ end
459
+
460
+ def append_identifier_unary(identifier, expression)
461
+ raise NotImplementedError.new __method__.to_s
462
+ end
463
+
464
+ def append_paren(lparen, expression, rparen, opts)
465
+ raise NotImplementedError.new __method__.to_s
466
+ end
467
+
468
+ def append_subsup(base, sub, sup)
469
+ raise NotImplementedError.new __method__.to_s
470
+ end
471
+
472
+ def append_underover(base, under, over)
473
+ raise NotImplementedError.new __method__.to_s
474
+ end
475
+
476
+ def resolve_paren(paren_symbol)
477
+ if paren_symbol.nil?
478
+ return nil
479
+ end
480
+
481
+ if (resolved = resolve_symbol(paren_symbol))
482
+ resolved[:value]
483
+ else
484
+ case paren_symbol
485
+ when ::AsciiMath::AST::Symbol
486
+ paren_symbol.value
487
+ else
488
+ paren_symbol
489
+ end
490
+ end
491
+ end
492
+
493
+ def resolve_symbol(node)
494
+ case node
495
+ when ::AsciiMath::AST::Symbol
496
+ @symbol_table[node.value]
497
+ when ::Symbol
498
+ @symbol_table[node]
499
+ else
500
+ nil
501
+ end
502
+ end
503
+
504
+ def is_accent(node)
505
+ resolved = resolve_symbol(node)
506
+ !resolved.nil? && resolved[:type] == :accent
507
+ end
508
+ end
509
+ end