mathtype 0.0.8 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (110) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -0
  3. data/.travis.yml +7 -0
  4. data/Rakefile +8 -0
  5. data/lib/file_parser/ole.rb +15 -0
  6. data/lib/file_parser/parser.rb +19 -0
  7. data/lib/file_parser/wmf.rb +28 -0
  8. data/lib/mathtype.rb +30 -7
  9. data/lib/mathtype/version.rb +1 -1
  10. data/lib/records/bintypes.rb +18 -0
  11. data/lib/records/mtef.rb +8 -114
  12. data/lib/records/nudge.rb +9 -5
  13. data/lib/records/ruler.rb +1 -1
  14. data/lib/records/typesizes.rb +5 -10
  15. data/lib/records3/char.rb +53 -0
  16. data/lib/records3/embell.rb +109 -0
  17. data/lib/records3/font.rb +27 -0
  18. data/lib/records3/line.rb +47 -0
  19. data/lib/records3/matrix.rb +80 -0
  20. data/lib/records3/mtef.rb +97 -0
  21. data/lib/records3/options.rb +5 -0
  22. data/lib/records3/pile.rb +43 -0
  23. data/lib/records3/size.rb +75 -0
  24. data/lib/records3/snapshot.rb +19 -0
  25. data/lib/records3/tmpl.rb +751 -0
  26. data/lib/{records → records5}/char.rb +6 -12
  27. data/lib/{records → records5}/color.rb +1 -1
  28. data/lib/{records → records5}/color_def.rb +8 -8
  29. data/lib/{records → records5}/embell.rb +2 -2
  30. data/lib/{records → records5}/encoding_def.rb +1 -1
  31. data/lib/{records → records5}/eqn_prefs.rb +2 -2
  32. data/lib/{records → records5}/font_def.rb +1 -1
  33. data/lib/{records → records5}/font_style_def.rb +1 -1
  34. data/lib/{records → records5}/future.rb +1 -1
  35. data/lib/{records → records5}/line.rb +3 -3
  36. data/lib/{records → records5}/matrix.rb +11 -3
  37. data/lib/records5/mtef.rb +129 -0
  38. data/lib/{records → records5}/pile.rb +2 -2
  39. data/lib/{records → records5}/size.rb +9 -7
  40. data/lib/records5/snapshot.rb +19 -0
  41. data/lib/{records → records5}/tmpl.rb +2 -2
  42. data/spec/fixtures/expected/mathtype3/ceil.xml +38 -0
  43. data/spec/fixtures/expected/mathtype3/fence.xml +77 -0
  44. data/spec/fixtures/expected/mathtype3/floor.xml +38 -0
  45. data/spec/fixtures/expected/mathtype3/frac.xml +136 -0
  46. data/spec/fixtures/expected/mathtype3/large_nudge.xml +135 -0
  47. data/spec/fixtures/expected/mathtype3/lim_embell.xml +247 -0
  48. data/spec/fixtures/expected/mathtype3/matrix_2x1.xml +500 -0
  49. data/spec/fixtures/expected/mathtype3/pile.xml +188 -0
  50. data/spec/fixtures/expected/mathtype3/sigma_subsup.xml +46 -0
  51. data/spec/fixtures/expected/mathtype3/small_nudge.xml +90 -0
  52. data/spec/fixtures/expected/mathtype3/sqrt.xml +132 -0
  53. data/spec/fixtures/expected/{299.xml → mathtype5/299.xml} +30 -15
  54. data/spec/fixtures/expected/{arrows.xml → mathtype5/arrows.xml} +30 -15
  55. data/spec/fixtures/expected/{embedded.xml → mathtype5/embedded.xml} +29 -14
  56. data/spec/fixtures/expected/{embellishments.xml → mathtype5/embellishments.xml} +30 -15
  57. data/spec/fixtures/expected/{equation1.xml → mathtype5/equation1.xml} +30 -15
  58. data/spec/fixtures/expected/{equation10.xml → mathtype5/equation10.xml} +30 -15
  59. data/spec/fixtures/expected/{equation11.xml → mathtype5/equation11.xml} +30 -15
  60. data/spec/fixtures/expected/{equation12.xml → mathtype5/equation12.xml} +30 -15
  61. data/spec/fixtures/expected/{equation13.xml → mathtype5/equation13.xml} +30 -15
  62. data/spec/fixtures/expected/{equation2.xml → mathtype5/equation2.xml} +30 -15
  63. data/spec/fixtures/expected/{equation3.xml → mathtype5/equation3.xml} +30 -15
  64. data/spec/fixtures/expected/{equation4.xml → mathtype5/equation4.xml} +30 -15
  65. data/spec/fixtures/expected/{equation5.xml → mathtype5/equation5.xml} +30 -15
  66. data/spec/fixtures/expected/{equation6.xml → mathtype5/equation6.xml} +30 -15
  67. data/spec/fixtures/expected/{equation7.xml → mathtype5/equation7.xml} +30 -15
  68. data/spec/fixtures/expected/{equation8.xml → mathtype5/equation8.xml} +30 -15
  69. data/spec/fixtures/expected/{equation9.xml → mathtype5/equation9.xml} +30 -15
  70. data/spec/fixtures/expected/{fences.xml → mathtype5/fences.xml} +30 -15
  71. data/spec/fixtures/expected/{integrals.xml → mathtype5/integrals.xml} +30 -15
  72. data/spec/fixtures/expected/mathtype5/matrix-border.xml +365 -0
  73. data/spec/fixtures/expected/mathtype5/matrix.xml +382 -0
  74. data/spec/fixtures/expected/{sizes.xml → mathtype5/sizes.xml} +30 -15
  75. data/spec/fixtures/input/mathtype3/ceil.bin +0 -0
  76. data/spec/fixtures/input/mathtype3/fence.bin +0 -0
  77. data/spec/fixtures/input/mathtype3/floor.bin +0 -0
  78. data/spec/fixtures/input/mathtype3/frac.bin +0 -0
  79. data/spec/fixtures/input/mathtype3/large_nudge.bin +0 -0
  80. data/spec/fixtures/input/mathtype3/lim_embell.bin +0 -0
  81. data/spec/fixtures/input/mathtype3/matrix_2x1.bin +0 -0
  82. data/spec/fixtures/input/mathtype3/pile.bin +0 -0
  83. data/spec/fixtures/input/mathtype3/sigma_subsup.bin +0 -0
  84. data/spec/fixtures/input/mathtype3/small_nudge.bin +0 -0
  85. data/spec/fixtures/input/mathtype3/sqrt.bin +0 -0
  86. data/spec/fixtures/input/{299.bin → mathtype5/299.bin} +0 -0
  87. data/spec/fixtures/input/{arrows.bin → mathtype5/arrows.bin} +0 -0
  88. data/spec/fixtures/input/{embedded.bin → mathtype5/embedded.bin} +0 -0
  89. data/spec/fixtures/input/{embellishments.bin → mathtype5/embellishments.bin} +0 -0
  90. data/spec/fixtures/input/{equation1.bin → mathtype5/equation1.bin} +0 -0
  91. data/spec/fixtures/input/{equation10.bin → mathtype5/equation10.bin} +0 -0
  92. data/spec/fixtures/input/{equation11.bin → mathtype5/equation11.bin} +0 -0
  93. data/spec/fixtures/input/{equation12.bin → mathtype5/equation12.bin} +0 -0
  94. data/spec/fixtures/input/{equation13.bin → mathtype5/equation13.bin} +0 -0
  95. data/spec/fixtures/input/{equation2.bin → mathtype5/equation2.bin} +0 -0
  96. data/spec/fixtures/input/{equation3.bin → mathtype5/equation3.bin} +0 -0
  97. data/spec/fixtures/input/{equation4.bin → mathtype5/equation4.bin} +0 -0
  98. data/spec/fixtures/input/{equation5.bin → mathtype5/equation5.bin} +0 -0
  99. data/spec/fixtures/input/{equation6.bin → mathtype5/equation6.bin} +0 -0
  100. data/spec/fixtures/input/{equation7.bin → mathtype5/equation7.bin} +0 -0
  101. data/spec/fixtures/input/{equation8.bin → mathtype5/equation8.bin} +0 -0
  102. data/spec/fixtures/input/{equation9.bin → mathtype5/equation9.bin} +0 -0
  103. data/spec/fixtures/input/{fences.bin → mathtype5/fences.bin} +0 -0
  104. data/spec/fixtures/input/{integrals.bin → mathtype5/integrals.bin} +0 -0
  105. data/spec/fixtures/input/mathtype5/matrix-border.bin +0 -0
  106. data/spec/fixtures/input/mathtype5/matrix.bin +0 -0
  107. data/spec/fixtures/input/{sizes.bin → mathtype5/sizes.bin} +0 -0
  108. data/spec/mathtype_spec.rb +11 -9
  109. data/test-mathtype.rb +2 -0
  110. metadata +168 -97
@@ -0,0 +1,19 @@
1
+ require "bindata"
2
+
3
+ module Mathtype3
4
+ module Snapshot
5
+ def snapshot
6
+ snapshot = BinData::Record::Snapshot.new
7
+ exposed = self.class.const_get(:EXPOSED_IN_SNAPSHOT)
8
+ exposed.each do |name|
9
+ obj = find_obj_for_name(name)
10
+ if obj
11
+ snapshot[name] = obj.snapshot if include_obj?(obj)
12
+ else
13
+ snapshot[name] = self.send(name)
14
+ end
15
+ end
16
+ snapshot
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,751 @@
1
+ require_relative "snapshot"
2
+
3
+ # TMPL record (3):
4
+
5
+ # Consists of:
6
+ # record type (3)
7
+ # options
8
+ # [nudge] if mtefOPT_NUDGE is set
9
+ # [selector] template selector code
10
+ # [variation] template variation code (1 or 2 bytes; see below)
11
+ # [options] template-specific options
12
+ # [subobject list] either a single character (e.g. sigma in a summation) and/or lines
13
+ # The template selector and variation codes determine the class of the
14
+ # template and various properties of the template, such as which subobjects
15
+ # can be deleted by the user (see Templates). The class of a template
16
+ # determines the order and meaning of each of its subobjects (see Template
17
+ # subobject order).
18
+
19
+ # The variation code may be 1 or 2 bytes long. If the first byte value has the
20
+ # high bit set (0x80), the next byte is read and combined with the first
21
+ # according to this formula:
22
+
23
+ # variation code = (byte1 & 0x7F) | (byte2 << 8)
24
+
25
+ # Template-specific options field only used for integrals & fence templates:
26
+ # Fence template option field values (fence alignment):
27
+ # 0 center fence on math axis, place math axis of contents on math axis of
28
+ # containing line (default);
29
+ # 1 center fence on contents, place math axis of contents on math axis of
30
+ # containing line;
31
+ # 2 center fence on contents, center contents on math axis of containing line.
32
+ # Warning: the expanding integral property is duplicated in the integral
33
+ # templates variation codes (see Limit variations). On reading, MathType only
34
+ # looks at the variation code.
35
+
36
+ # Integral template option field values:
37
+ # 0 fixed-size integral;
38
+ # 1 the integral expands vertically to fit its contents.
39
+
40
+ # Limit variations:
41
+
42
+ # The following variation codes apply to all templates whose class is BigOpBoxClass or LimBoxClass:
43
+
44
+ # variation bits symbol description
45
+ # 0x0001 tvBO_LOWER lower limit is present
46
+ # 0x0002 tvBO_UPPER upper limit is present
47
+ # 0x0040 tvBO_SUM summation-style limit positions, else integral-style
48
+
49
+ # Template selectors and variations:
50
+ # Fences (parentheses, etc.):
51
+ # selector symbol description class
52
+ # 0 tmANGLE angle brackets ParBoxClass
53
+ # 1 tmPAREN parentheses ParBoxClass
54
+ # 2 tmBRACE braces (curly brackets) ParBoxClass
55
+ # 3 tmBRACK square brackets ParBoxClass
56
+ # 4 tmBAR vertical bars ParBoxClass
57
+ # 5 tmDBAR double vertical bars ParBoxClass
58
+ # 6 tmFLOOR floor brackets ParBoxClass
59
+ # 7 tmCEILING ceiling brackets ParBoxClass
60
+ # 8 tmOBRACK open (white) brackets ParBoxClass
61
+ # variations variation bits symbol description
62
+ # 0x0001 tvFENCE_L left fence is present
63
+ # 0x0002 tvFENCE_R right fence is present
64
+ # Intervals:
65
+ # selector symbol description class
66
+ # 9 tmINTERVAL unmatched brackets and parentheses ParBoxClass
67
+ # variations variation bits symbol description
68
+ # 0x0000 tvINTV_LEFT_LP left fence is left parenthesis
69
+ # 0x0001 tvINTV_LEFT_RP left fence is right parenthesis
70
+ # 0x0002 tvINTV_LEFT_LB left fence is left bracket
71
+ # 0x0003 tvINTV_LEFT_RB left fence is right bracket
72
+ # 0x0000 tvINTV_RIGHT_LP right fence is left parenthesis
73
+ # 0x0010 tvINTV_RIGHT_RP right fence is right parenthesis
74
+ # 0x0020 tvINTV_RIGHT_LB right fence is left bracket
75
+ # 0x0030 tvINTV_RIGHT_RB right fence is right bracket
76
+ # Radicals (square and nth roots):
77
+ # selector symbol description class
78
+ # 10 tmROOT radical RootBoxClass
79
+ # variations variation symbol description
80
+ # 0 tvROOT_SQ square root
81
+ # 1 tvROOT_NTH nth root
82
+ # Fractions:
83
+ # selector symbol description class
84
+ # 11 tmFRACT fractions FracBoxClass
85
+ # variations variation bits symbol description
86
+ # 0x0001 tvFR_SMALL subscript-size slots (piece fraction)
87
+ # 0x0002 tvFR_SLASH fraction bar is a slash
88
+ # 0x0004 tvFR_BASE num. and denom. are baseline aligned
89
+ # Over and Underbars:
90
+ # selector symbol description class
91
+ # 12 tmUBAR underbar BarBoxClass
92
+ # 13 tmOBAR overbar BarBoxClass
93
+ # variations variation bits symbol description
94
+ # 0x0001 tvBAR_DOUBLE bar is doubled, else single
95
+ # Arrows:
96
+ # selector symbol description class
97
+ # 14 tmARROW arrow ArroBoxClass
98
+ # variations variation symbol description
99
+ # 0x0000 tvAR_SINGLE single arrow
100
+ # 0x0001 tvAR_DOUBLE double arrow
101
+ # 0x0002 tvAR_HARPOON harpoon
102
+ # 0x0004 tvAR_TOP top slot is present
103
+ # 0x0008 tvAR_BOTTOM bottom slot is present
104
+ # 0x0010 tvAR_LEFT if single, arrow points left
105
+ # 0x0020 tvAR_RIGHT if single, arrow points right
106
+ # 0x0010 tvAR_LOS if double or harpoon, large over small
107
+ # 0x0020 tvAR_SOL if double or harpoon, small over large
108
+ # Integrals (see Limit Variations):
109
+ # selector symbol description class
110
+ # 15 tmINTEG integral BigOpBoxClass
111
+ # variations variation symbol description
112
+ # 0x0001 tvINT_1 single integral sign
113
+ # 0x0002 tvINT_2 double integral sign
114
+ # 0x0003 tvINT_3 triple integral sign
115
+ # 0x0004 tvINT_LOOP has loop w/o arrows
116
+ # 0x0008 tvINT_CW_LOOP has clockwise loop
117
+ # 0x000C tvINT_CCW_LOOP has counter-clockwise loop
118
+ # 0x0100 tvINT_EXPAND integral signs expand
119
+ # Sums, products, coproducts, unions, intersections, etc. (see Limit Variations):
120
+ # selector symbol description class
121
+ # 16 tmSUM sum BigOpBoxClass
122
+ # 17 tmPROD product BigOpBoxClass
123
+ # 18 tmCOPROD coproduct BigOpBoxClass
124
+ # 19 tmUNION union BigOpBoxClass
125
+ # 20 tmINTER intersection BigOpBoxClass
126
+ # 21 tmINTOP integral-style big operator BigOpBoxClass
127
+ # 22 tmSUMOP summation-style big operator BigOpBoxClass
128
+ # Limits (see Limit Variations):
129
+ # selector symbol description class
130
+ # 23 tmLIM limits LimBoxClass
131
+ # variations variation symbol description
132
+ # 0 tvSUBAR single underbar
133
+ # 1 tvDUBAR double underbar
134
+ # Horizontal braces and brackets:
135
+ # selector symbol description class
136
+ # 24 tmHBRACE horizontal brace HFenceBoxClass
137
+ # 25 tmHBRACK horizontal bracket HFenceBoxClass
138
+ # variation symbol description
139
+ # 0x0001 tvHB_TOP slot is on the top, else on the bottom
140
+ # Long division:
141
+ # selector symbol description class
142
+ # 26 tmLDIV long division LDivBoxClass
143
+ # variation symbol description
144
+ # 0x0001 tvLD_UPPER upper slot is present
145
+ # Subscripts and superscripts:
146
+ # selector symbol description class
147
+ # 27 tmSUB subscript ScrBoxClass
148
+ # 28 tmSUP superscript ScrBoxClass
149
+ # 29 tmSUBSUP subscript and superscript ScrBoxClass
150
+ # variation symbol description
151
+ # 0x0001 tvSU_PRECEDES script precedes scripted item,
152
+ # else follows
153
+ # Dirac bra-ket notation:
154
+ # selector symbol description class
155
+ # 30 tmDIRAC bra-ket notation DiracBoxClass
156
+ # variation symbol description
157
+ # 0x0001 tvDI_LEFT left part is present
158
+ # 0x0002 tvDI_RIGHT right part is present
159
+ # Vectors:
160
+ # selector symbol description class
161
+ # 31 tmVEC vector HatBoxClass
162
+ # variation symbol description
163
+ # 0x0001 tvVE_LEFT arrow points left
164
+ # 0x0002 tvVE_RIGHT arrow points right
165
+ # 0x0004 tvVE_UNDER arrow under slot, else over slot
166
+ # 0x0008 tvVE_HARPOON harpoon
167
+ # Hats, arcs, tilde, joint status:
168
+ # selector symbol description class
169
+ # 32 tmTILDE tilde over characters HatBoxClass
170
+ # 33 tmHAT hat over characters HatBoxClass
171
+ # 34 tmARC arc over characters HatBoxClass
172
+ # 35 tmJSTATUS joint status construct HatBoxClass
173
+ # Overstrikes (cross-outs):
174
+ # selector symbol description class
175
+ # 36 tmSTRIKE overstrike (cross-out) StrikeBoxClass
176
+ # variation symbol description
177
+ # 0x0001 tvST_HORIZ line is horizontal, else slashes
178
+ # 0x0002 tvST_UP if slashes, slash from lower-left to upper-right is present
179
+ # 0x0004 tvST_DOWN if slashes, slash from upper-left to lower-right is present
180
+ # Boxes:
181
+ # selector symbol description class
182
+ # 37 tmBOX box TBoxBoxClass
183
+ # variation symbol description
184
+ # 0x0001 tvBX_ROUND corners are round, else square
185
+ # 0x0002 tvBX_LEFT left side is present
186
+ # 0x0004 tvBX_RIGHT right side is present
187
+ # 0x0008 tvBX_TOP top side is present
188
+ # 0x0010 tvBX_BOTTOM bottom side is present
189
+
190
+ module Mathtype3
191
+ class RecordTmpl < BinData::Record
192
+ include Snapshot
193
+ EXPOSED_IN_SNAPSHOT = %i(options selector variation template_specific_options nudge
194
+ subobject_list)
195
+
196
+ SCRIPT_SELECTOR = {
197
+ 0 => "tmSUP",
198
+ 1 => "tmSUB",
199
+ 2 => "tmSUBSUP"
200
+ }
201
+
202
+ SELECTORS = {
203
+ 0 => "tmANGLE",
204
+ 1 => "tmPAREN",
205
+ 2 => "tmBRACE",
206
+ 3 => "tmBRACK",
207
+ 4 => "tmBAR",
208
+ 5 => "tmDBAR",
209
+ 6 => "tmFLOOR",
210
+ 7 => "tmCEILING",
211
+ 8 => "tmINTERVAL",
212
+ 9 => "tmINTERVAL",
213
+ 10 => "tmINTERVAL",
214
+ 11 => "tmINTERVAL",
215
+ 12 => "tmINTERVAL",
216
+ 13 => "tmROOT",
217
+ 14 => "tmFRACT",
218
+ 15 => "tmSCRIPT",
219
+ 16 => "tmUBAR",
220
+ 17 => "tmOBAR",
221
+ 18 => "tmARROW",
222
+ 19 => "tmARROW",
223
+ 20 => "tmARROW",
224
+ 21 => "tmINTEG",
225
+ 22 => "tmINTEG",
226
+ 23 => "tmINTEG",
227
+ 24 => "tmINTEG",
228
+ 25 => "tmINTEG",
229
+ 26 => "tmINTEG",
230
+ 27 => "tmHBRACE",
231
+ 28 => "tmHBRACE",
232
+ 29 => "tmSUM",
233
+ 30 => "tmSUM",
234
+ 31 => "tmPROD",
235
+ 32 => "tmPROD",
236
+ 33 => "tmCOPROD",
237
+ 34 => "tmCOPROD",
238
+ 35 => "tmUNION",
239
+ 36 => "tmUNION",
240
+ 37 => "tmINTER",
241
+ 38 => "tmINTER",
242
+ 39 => "tmLIM",
243
+ 40 => "tmLDIV",
244
+ 41 => "tmFRACT",
245
+ 42 => "tmINTOP",
246
+ 43 => "tmSUMOP",
247
+ 44 => "tmSCRIPT",
248
+ 45 => "tmDIRAC",
249
+ 46 => "tmVEC",
250
+ 47 => "tmVEC",
251
+ 48 => "tmBOX"
252
+ }
253
+ FENCE_BOTH = [
254
+ "tvFENCE_L",
255
+ "tvFENCE_R"
256
+ ]
257
+
258
+ FENCE_VARIATIONS = {
259
+ 0 => FENCE_BOTH,
260
+ 1 => ["tvFENCE_L"], # left fence is present
261
+ 2 => ["tvFENCE_R"] # right fence is present
262
+ }
263
+
264
+ BAR_VARIATIONS = {
265
+ 0 => ["tvBAR_SINGLE"],
266
+ 1 => ["tvBAR_DOUBLE"] # bar is doubled, else single
267
+ }
268
+
269
+
270
+ VARIATIONS = {
271
+ # Fences (parentheses, etc.):
272
+ 0 => FENCE_VARIATIONS,
273
+ 1 => FENCE_VARIATIONS,
274
+ 2 => FENCE_VARIATIONS,
275
+ 3 => FENCE_VARIATIONS,
276
+ 4 => FENCE_VARIATIONS,
277
+ 5 => FENCE_VARIATIONS,
278
+ 6 => {
279
+ 0 => FENCE_BOTH
280
+ },
281
+ 7 => {
282
+ 0 => FENCE_BOTH
283
+ },
284
+ # Intervals:
285
+ # 0x0000 => "tvINTV_LEFT_LP", # left fence is left parenthesis
286
+ # 0x0001 => "tvINTV_LEFT_RP", # left fence is right parenthesis
287
+ # 0x0002 => "tvINTV_LEFT_LB", # left fence is left bracket
288
+ # 0x0003 => "tvINTV_LEFT_RB", # left fence is right bracket
289
+ # 0x0004 => "tvINTV_RIGHT_LP", # right fence is left parenthesis # WARNING: DOCUMENTATION SAYS 0x0000?
290
+ # 0x0010 => "tvINTV_RIGHT_RP", # right fence is right parenthesis
291
+ # 0x0020 => "tvINTV_RIGHT_LB", # right fence is left bracket
292
+ # 0x0030 => "tvINTV_RIGHT_RB", # right fence is right bracket
293
+ # Replaced above to match MathML translator
294
+ 8 => {
295
+ 0 => FENCE_BOTH
296
+ },
297
+ 9 => {
298
+ 0 => FENCE_BOTH
299
+ },
300
+ 10 => {
301
+ 0 => FENCE_BOTH
302
+ },
303
+ 11 => {
304
+ 0 => FENCE_BOTH
305
+ },
306
+ 12 => {
307
+ 0 => FENCE_BOTH
308
+ },
309
+
310
+ # Radicals (square and nth roots):
311
+ 13 => {
312
+ 0 => ["tvROOT_SQ"], # square root
313
+ 1 => ["tvROOT_NTH"] # nth root
314
+ },
315
+
316
+ # Fractions:
317
+ 14 => {
318
+ #TODO: full-size slots?
319
+ 0 => ["tvFR_FULL"],
320
+ 1 => ["tvFR_SMALL"] # subscript-size slots (piece fraction)
321
+ },
322
+
323
+ # Over and Underbars:
324
+ 16 => BAR_VARIATIONS,
325
+ 17 => BAR_VARIATIONS,
326
+
327
+ # Arrows:
328
+ 18 => {
329
+ 0 => [
330
+ "tvAR_SINGLE",
331
+ "tvAR_LEFT",
332
+ "tvAR_TOP",
333
+ ], # single arrow
334
+ 1 => [
335
+ "tvAR_SINGLE",
336
+ "tvAR_LEFT",
337
+ "tvAR_BOTTOM"
338
+ ]
339
+ },
340
+
341
+ 19 => {
342
+ 0 => [
343
+ "tvAR_SINGLE",
344
+ "tvAR_RIGHT",
345
+ "tvAR_TOP"
346
+ ],
347
+ 1 => [
348
+ "tvAR_SINGLE",
349
+ "tvAR_RIGHT",
350
+ "tvAR_TOP"
351
+ ]
352
+ },
353
+
354
+ 20 => {
355
+ 0 => [
356
+ "tvAR_SINGLE",
357
+ "tvAR_RIGHT",
358
+ "tvAR_LEFT",
359
+ "tvAR_TOP"
360
+ ],
361
+ 1 => [
362
+ "tvAR_SINGLE",
363
+ "tvAR_RIGHT",
364
+ "tvAR_LEFT",
365
+ "tvAR_TOP"
366
+ ]
367
+ },
368
+
369
+ # Integrals (see Limit Variations):
370
+ 21 => {
371
+ 0 => [
372
+ "tvINT_1" # single integral sign
373
+ ],
374
+ 1 => [
375
+ "tvINT_1",
376
+ "tvBO_LOWER"
377
+ ],
378
+ 2 => [
379
+ "tvINT_1",
380
+ "tvBO_LOWER",
381
+ "tvBO_UPPER"
382
+ ],
383
+ 3 => [
384
+ "tvINT_1",
385
+ ],
386
+ 4 => [
387
+ "tvINT_1",
388
+ "tvBO_LOWER"
389
+ ]
390
+ },
391
+
392
+ 22 => {
393
+ 0 => [
394
+ "tvINT_2" # double integral sign
395
+ ],
396
+ 1 => [
397
+ "tvINT_2",
398
+ "tvBO_LOWER"
399
+ ],
400
+ 2 => [
401
+ "tvINT_2",
402
+ "tvBO_LOWER",
403
+ "tvBO_UPPER"
404
+ ],
405
+ 3 => [
406
+ "tvINT_2",
407
+ ],
408
+ 4 => [
409
+ "tvINT_2",
410
+ "tvBO_LOWER"
411
+ ]
412
+ },
413
+
414
+ 23 => {
415
+ 0 => [
416
+ "tvINT_3" # triple integral sign
417
+ ],
418
+ 1 => [
419
+ "tvINT_3",
420
+ "tvBO_LOWER"
421
+ ],
422
+ 2 => [
423
+ "tvINT_3",
424
+ "tvBO_LOWER",
425
+ "tvBO_UPPER"
426
+ ],
427
+ 3 => ["tvINT_3"],
428
+ 4 => [
429
+ "tvINT_3",
430
+ "tvBO_LOWER"
431
+ ]
432
+ },
433
+
434
+ 24 => {
435
+ 0 => [
436
+ "tvINT_1", # single integral sign
437
+ "tvBO_SUM",
438
+ "tvBO_LOWER",
439
+ "tvBO_UPPER"
440
+ ],
441
+ 1 => [
442
+ "tvINT_1",
443
+ "tvBO_SUM",
444
+ "tvBO_LOWER"
445
+ ],
446
+ 2 => [
447
+ "tvINT_1",
448
+ "tvBO_SUM",
449
+ "tvBO_LOWER",
450
+ ]
451
+ },
452
+
453
+ 25 => {
454
+ 0 => [
455
+ "tvINT_2", # double integral sign
456
+ "tvBO_SUM",
457
+ "tvBO_LOWER",
458
+ ],
459
+ 1 => [
460
+ "tvINT_2",
461
+ "tvBO_SUM",
462
+ "tvBO_LOWER"
463
+ ]
464
+ },
465
+
466
+ 26 => {
467
+ 0 => [
468
+ "tvINT_3", # triple integral sign
469
+ "tvBO_SUM",
470
+ "tvBO_LOWER"
471
+ ],
472
+ 1 => [
473
+ "tvINT_3",
474
+ "tvBO_SUM",
475
+ "tvBO_LOWER"
476
+ ]
477
+ },
478
+
479
+ # Horizontal braces and brackets:
480
+ 27 => {
481
+ 0 => ["tvHB_TOP"] # slot is on the top
482
+ },
483
+
484
+ 28 => {
485
+ # default on the bottom
486
+ 0 => ["tvHB_BOT"]
487
+ },
488
+
489
+ # Sums, products, coproducts, unions, intersections, etc.:
490
+ 29 => {
491
+ 0 => [
492
+ "tvBO_LOWER", # lower limit is present
493
+ "tvBO_SUM" # summation-style limit positions,
494
+ ],
495
+ 1 => [
496
+ "tvBO_LOWER", # lower limit is present
497
+ "tvBO_UPPER", # upper limit is present
498
+ "tvBO_SUM"
499
+ ],
500
+ 2 => ["tvBO_SUM"]
501
+ },
502
+
503
+ 30 => {
504
+ 0 => [
505
+ "tvBO_LOWER" # lower limit is present
506
+ ],
507
+ 1 => [
508
+ "tvBO_LOWER", # lower limit is present
509
+ "tvBO_UPPER" # upper limit is present
510
+ ]
511
+ },
512
+
513
+ 31 => {
514
+ 0 => [
515
+ "tvBO_LOWER", # lower limit is present
516
+ "tvBO_SUM" # summation-style limit positions,
517
+ ],
518
+ 1 => [
519
+ "tvBO_LOWER", # lower limit is present
520
+ "tvBO_UPPER", # upper limit is present
521
+ "tvBO_SUM"
522
+ ],
523
+ 2 => ["tvBO_SUM"]
524
+ },
525
+
526
+ 32 => {
527
+ 0 => [
528
+ "tvBO_LOWER" # lower limit is present
529
+ ],
530
+ 1 => [
531
+ "tvBO_LOWER", # lower limit is present
532
+ "tvBO_UPPER" # upper limit is present
533
+ ]
534
+ },
535
+
536
+ 33 => {
537
+ 0 => [
538
+ "tvBO_LOWER", # lower limit is present
539
+ "tvBO_SUM" # summation-style limit positions,
540
+ ],
541
+ 1 => [
542
+ "tvBO_LOWER", # lower limit is present
543
+ "tvBO_UPPER", # upper limit is present
544
+ "tvBO_SUM"
545
+ ],
546
+ 2 => ["tvBO_SUM"]
547
+ },
548
+
549
+ 34 => {
550
+ 0 => [
551
+ "tvBO_LOWER" # lower limit is present
552
+ ],
553
+ 1 => [
554
+ "tvBO_LOWER", # lower limit is present
555
+ "tvBO_UPPER" # upper limit is present
556
+ ]
557
+ },
558
+
559
+ 35 => {
560
+ 0 => [
561
+ "tvBO_LOWER", # lower limit is present
562
+ "tvBO_SUM" # summation-style limit positions,
563
+ ],
564
+ 1 => [
565
+ "tvBO_LOWER", # lower limit is present
566
+ "tvBO_UPPER", # upper limit is present
567
+ "tvBO_SUM"
568
+ ],
569
+ 2 => ["tvBO_SUM"]
570
+ },
571
+
572
+ 36 => {
573
+ 0 => [
574
+ "tvBO_LOWER" # lower limit is present
575
+ ],
576
+ 1 => [
577
+ "tvBO_LOWER", # lower limit is present
578
+ "tvBO_UPPER" # upper limit is present
579
+ ]
580
+ },
581
+
582
+ 37 => {
583
+ 0 => [
584
+ "tvBO_LOWER", # lower limit is present
585
+ "tvBO_SUM" # summation-style limit positions,
586
+ ],
587
+ 1 => [
588
+ "tvBO_LOWER", # lower limit is present
589
+ "tvBO_UPPER", # upper limit is present
590
+ "tvBO_SUM"
591
+ ],
592
+ 2 => ["tvBO_SUM"]
593
+ },
594
+
595
+ 38 => {
596
+ 0 => [
597
+ "tvBO_LOWER" # lower limit is present
598
+ ],
599
+ 1 => [
600
+ "tvBO_LOWER", # lower limit is present
601
+ "tvBO_UPPER" # upper limit is present
602
+ ]
603
+ },
604
+
605
+ 39 => {
606
+ 0 => [
607
+ "tvBO_UPPER" # upper limit is present
608
+ ],
609
+ 1 => [
610
+ "tvBO_LOWER" # lower limit is present
611
+ ],
612
+ 2 => [
613
+ "tvBO_LOWER", # lower limit is present
614
+ "tvBO_UPPER" # upper limit is present
615
+ ]
616
+ },
617
+
618
+ # Long division:
619
+ 40 => {
620
+ 0 => ["tvLD_UPPER"]
621
+ },
622
+
623
+ # Frac with Slash:
624
+ 41 => {
625
+ 0 => ["tvFR_SLASH"],
626
+ 1 => [
627
+ "tvFR_SLASH",
628
+ "tvFR_BASE"
629
+ ],
630
+ 2 => [
631
+ "tvFR_SLASH",
632
+ "tvFR_SMALL"
633
+ ]
634
+ },
635
+
636
+ # Big integral-style operators:
637
+ 42 => {
638
+ 0 => ["tvBO_LOWER"],
639
+ 1 => ["tvBO_UPPER"],
640
+ 2 => [
641
+ "tvBO_LOWER",
642
+ "tvBO_UPPER"
643
+ ]
644
+ },
645
+
646
+ # Big summation-style operators:
647
+ 43 => {
648
+ 0 => [
649
+ "tvBO_SUM",
650
+ "tvBO_LOWER"
651
+ ],
652
+ 1 => [
653
+ "tvBO_SUM",
654
+ "tvBO_UPPER"
655
+ ],
656
+ 2 => [
657
+ "tvBO_SUM",
658
+ "tvBO_LOWER",
659
+ "tvBO_UPPER"
660
+ ]
661
+ },
662
+
663
+ 44 => {
664
+ 0 => ["tvSU_PRECEDES"],
665
+ 1 => ["tvSU_PRECEDES"],
666
+ 2 => ["tvSU_PRECEDES"],
667
+ 3 => ["tvSU_PRECEDES"]
668
+ },
669
+
670
+ 45 => {
671
+ 0 => [
672
+ "tvDI_LEFT",
673
+ "tvDI_RIGHT"
674
+ ],
675
+ 1 => ["tvDI_LEFT"],
676
+ 2 => ["tvDI_RIGHT"]
677
+ },
678
+
679
+ 46 => {
680
+ 0 => [
681
+ "tvVE_UNDER",
682
+ "tvVE_LEFT"
683
+ ],
684
+ 1 => [
685
+ "tvVE_UNDER",
686
+ "tvVE_RIGHT"
687
+ ],
688
+ 2 => [
689
+ "tvVE_UNDER",
690
+ "tvVE_LEFT",
691
+ "tvVE_RIGHT"
692
+ ],
693
+ },
694
+
695
+ 47 => {
696
+ 0 => ["tvVE_LEFT"],
697
+ 1 => ["tvVE_RIGHT"],
698
+ 2 => [
699
+ "tvVE_LEFT",
700
+ "tvVE_RIGHT"
701
+ ],
702
+ },
703
+
704
+ # Selectors with empty variation:
705
+ 15 => {0=>nil,1=>nil,2=>nil,3=>nil,4=>nil},
706
+ 48 => {0=>nil,1=>nil,2=>nil,3=>nil,4=>nil}
707
+ }
708
+
709
+
710
+ # When options overlap in the binary space, ordinary bitmasks
711
+ # are not the correct tool to use for detection. We use digit
712
+ # position and presence instead.
713
+
714
+ DIGIT_MODE_VARIATIONS = [9]
715
+
716
+ # Top-level keys are template identifiers, defined in TEMPLATES.
717
+ # Second-level keys are bits for certain variations, negative keys mean
718
+ # that the variation is present if the bit is absent.
719
+
720
+ mandatory_parameter :_options
721
+
722
+ virtual :options, :value => lambda{ _options }
723
+
724
+ record_nudge :nudge, onlyif: lambda { _options & OPTIONS["xfLMOVE"] > 0 }
725
+
726
+ int8 :_selector
727
+
728
+ int8 :_variation
729
+
730
+ int8 :template_specific_options
731
+
732
+ array :subobject_list, read_until: lambda { element.record_type == 0 } do
733
+ named_record
734
+ end
735
+
736
+ def selector
737
+ if is_script _selector
738
+ #SCRIPT has to be handled separate
739
+ SCRIPT_SELECTOR[_variation]
740
+ else
741
+ SELECTORS[_selector]
742
+ end
743
+ end
744
+ def is_script(sel)
745
+ return sel == 44 || sel == 15
746
+ end
747
+ def variation
748
+ VARIATIONS[_selector][_variation]
749
+ end
750
+ end
751
+ end