mathtype_to_mathml 0.0.1

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 (58) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +14 -0
  3. data/.rspec +2 -0
  4. data/.ruby-version +1 -0
  5. data/.travis.yml +3 -0
  6. data/Gemfile +6 -0
  7. data/LICENSE.txt +22 -0
  8. data/README.md +45 -0
  9. data/Rakefile +7 -0
  10. data/lib/mathtype_to_mathml.rb +28 -0
  11. data/lib/mathtype_to_mathml/char_replacer.rb +311 -0
  12. data/lib/mathtype_to_mathml/mover.rb +151 -0
  13. data/lib/mathtype_to_mathml/version.rb +3 -0
  14. data/lib/transform.xsl +104 -0
  15. data/lib/xsl/arrow.xsl +319 -0
  16. data/lib/xsl/brace.xsl +55 -0
  17. data/lib/xsl/char.xsl +35 -0
  18. data/lib/xsl/embellishment.xsl +389 -0
  19. data/lib/xsl/matrix.xsl +116 -0
  20. data/lib/xsl/pile.xsl +54 -0
  21. data/lib/xsl/subsup.xsl +55 -0
  22. data/lib/xsl/sum.xsl +57 -0
  23. data/lib/xsl/union_intersection.xsl +104 -0
  24. data/mathtype_to_mathml.gemspec +28 -0
  25. data/spec/fixtures/expected/arrows.xml +389 -0
  26. data/spec/fixtures/expected/embellishments.xml +178 -0
  27. data/spec/fixtures/expected/equation1.xml +52 -0
  28. data/spec/fixtures/expected/equation10.xml +19 -0
  29. data/spec/fixtures/expected/equation11.xml +17 -0
  30. data/spec/fixtures/expected/equation12.xml +34 -0
  31. data/spec/fixtures/expected/equation13.xml +113 -0
  32. data/spec/fixtures/expected/equation2.xml +33 -0
  33. data/spec/fixtures/expected/equation3.xml +324 -0
  34. data/spec/fixtures/expected/equation4.xml +14 -0
  35. data/spec/fixtures/expected/equation5.xml +23 -0
  36. data/spec/fixtures/expected/equation6.xml +13 -0
  37. data/spec/fixtures/expected/equation7.xml +19 -0
  38. data/spec/fixtures/expected/equation8.xml +17 -0
  39. data/spec/fixtures/expected/equation9.xml +15 -0
  40. data/spec/fixtures/input/arrows.bin +0 -0
  41. data/spec/fixtures/input/embellishments.bin +0 -0
  42. data/spec/fixtures/input/equation1.bin +0 -0
  43. data/spec/fixtures/input/equation10.bin +0 -0
  44. data/spec/fixtures/input/equation11.bin +0 -0
  45. data/spec/fixtures/input/equation12.bin +0 -0
  46. data/spec/fixtures/input/equation13.bin +0 -0
  47. data/spec/fixtures/input/equation2.bin +0 -0
  48. data/spec/fixtures/input/equation3.bin +0 -0
  49. data/spec/fixtures/input/equation4.bin +0 -0
  50. data/spec/fixtures/input/equation5.bin +0 -0
  51. data/spec/fixtures/input/equation6.bin +0 -0
  52. data/spec/fixtures/input/equation7.bin +0 -0
  53. data/spec/fixtures/input/equation8.bin +0 -0
  54. data/spec/fixtures/input/equation9.bin +0 -0
  55. data/spec/html_output.rb +28 -0
  56. data/spec/mathtype_to_mathml_spec.rb +19 -0
  57. data/spec/spec_helper.rb +2 -0
  58. metadata +220 -0
@@ -0,0 +1,151 @@
1
+ require "nokogiri"
2
+
3
+ # We're moving elements around to avoid "scanning" for characters when
4
+ # using the /scan translator mode. The original issue is that MathType
5
+ # considers subscripts and superscripts to be stand-alone, while MathML
6
+ # considers them subscripts and superscripts of an object, and the object
7
+ # is then included in the sub/superscript element.
8
+
9
+ # MathType's translator has a scan mode, which does the following:
10
+ # 1. Scanning goes to the right for commands with the "pre" option,
11
+ # otherwise left;
12
+ # 2. If we are scanning right and the object next to the template is an
13
+ # opening "fence" character (parenthesis, bracket, brace, etc.),
14
+ # the slot is scanned for the corresponding closing fence character;
15
+ # 3. If we are scanning left and the object next to the template is an closing
16
+ # "fence" character (parenthesis, bracket, brace, etc.), the slot is scanned
17
+ # for the corresponding opening fence character;
18
+ # 4. If the fenced expression is found, it is used as #1 in the template translation.
19
+
20
+ # Additionally, Mover inverts <emb>ellishments from <char><emb></emb></char> to
21
+ # <emb><char></char></emb>.
22
+
23
+ module MathTypeToMathML
24
+ class Mover
25
+ attr_reader :mathtype
26
+ attr_accessor :last_preceding_siblings
27
+
28
+ PARENS_SELECTOR = "selector='tmPARENS' or "\
29
+ "selector='tmBRACK' or " \
30
+ "selector='tmBRACE' or " \
31
+ "selector='tmOBRACK' or " \
32
+ "selector='tmOBRACE' or " \
33
+ "selector='tmHBRACK' or " \
34
+ "selector='tmHBRACE'"
35
+
36
+ SUBSUP_SELECTOR = "selector='tmSUP' or " \
37
+ "selector='tmSUB' or " \
38
+ "selector='tmSUBSUP'"
39
+
40
+ PRE = "variation='tvSU_PRECEDES'"
41
+
42
+ OPEN_PAREN = "mt_code_value = '0x0028' or " \
43
+ "mt_code_value = '0x005B' or " \
44
+ "mt_code_value = '0x007B'"
45
+
46
+ CLOSE_PAREN = "mt_code_value = '0x0029' or " \
47
+ "mt_code_value = '0x005D' or " \
48
+ "mt_code_value = '0x007D'"
49
+
50
+ OPEN_CLOSE_PAIRS = {
51
+ "0x0028" => "0x0029", # ( )
52
+ "0x005B" => "0x005D", # [ ]
53
+ "0x007B" => "0x007D", # { }
54
+ }
55
+
56
+ def initialize(mathtype)
57
+ @mathtype = mathtype
58
+ @last_preceding_siblings = Nokogiri::XML::NodeSet.new(@mathtype)
59
+ end
60
+
61
+ def move_until_mt_code(elements, mt_code_value, parent)
62
+ elements.each do |element|
63
+ element.parent = parent
64
+ break if element.xpath("mt_code_value = '#{mt_code_value}'")
65
+ end
66
+ end
67
+
68
+ def move_paren(siblings, node)
69
+ OPEN_CLOSE_PAIRS.each do |open, close|
70
+ if siblings[0].xpath("mt_code_value = '#{open}'") # ( )
71
+ move_until_mt_code(siblings, close, node)
72
+ end
73
+ end
74
+ end
75
+
76
+ def new_preceding_siblings(el)
77
+ all_siblings = el.xpath("preceding-sibling::tmpl | preceding-sibling::char")
78
+ siblings = all_siblings - last_preceding_siblings
79
+ self.last_preceding_siblings = all_siblings
80
+ siblings
81
+ end
82
+
83
+ def new_following_siblings(el)
84
+ el.xpath("following-sibling::tmpl | following-sibling::char")
85
+ end
86
+
87
+ def move_following_subsup
88
+ mathtype.xpath("//tmpl[(#{SUBSUP_SELECTOR}) and not(#{PRE})]").each do |el|
89
+ siblings = new_preceding_siblings(el)
90
+
91
+ node = Nokogiri::XML::Node.new "slot", mathtype
92
+
93
+ if siblings.last.xpath(CLOSE_PAREN)
94
+ siblings = siblings.reverse.take_while do |sibling|
95
+ !sibling.next_element.xpath(OPEN_PAREN)
96
+ end.reverse
97
+
98
+ move_paren(siblings, node)
99
+ elsif siblings.last.xpath("self::tmpl[#{PARENS_SELECTOR}]")
100
+ siblings.last.parent = node
101
+ else
102
+ siblings.last.parent = node
103
+ end
104
+
105
+ el.at_css("slot").add_previous_sibling node
106
+ end
107
+ end
108
+
109
+ def move_preceding_subsup
110
+ mathtype.xpath("//tmpl[(#{SUBSUP_SELECTOR}) and #{PRE}]").each do |el|
111
+ siblings = new_following_siblings(el)
112
+
113
+ node = Nokogiri::XML::Node.new "slot", mathtype
114
+
115
+ if siblings.first.xpath(OPEN_PAREN)
116
+ siblings = siblings.reverse.take_while do |sibling|
117
+ !sibling.next_element.xpath(CLOSE_PAREN)
118
+ end.reverse
119
+
120
+ move_paren(siblings, node)
121
+ elsif siblings.first.xpath("self::tmpl[#{PARENS_SELECTOR}]")
122
+ siblings.first.parent = node
123
+ else
124
+ siblings.first.parent = node
125
+ end
126
+
127
+ el.at_css("slot").add_previous_sibling node
128
+ end
129
+ end
130
+
131
+ def invert_char_embell
132
+ # Invert char -> embell to embell -> char.
133
+ mathtype.xpath("//char[embell]").each do |el|
134
+ embell = el.xpath("embell").first.remove
135
+ char = el.clone
136
+ char.parent = embell
137
+ el.replace(embell)
138
+ end
139
+ end
140
+
141
+ def move
142
+ move_following_subsup
143
+ move_preceding_subsup
144
+ invert_char_embell
145
+ end
146
+ end
147
+ end
148
+
149
+
150
+
151
+
@@ -0,0 +1,3 @@
1
+ module MathTypeToMathML
2
+ VERSION = "0.0.1"
3
+ end
data/lib/transform.xsl ADDED
@@ -0,0 +1,104 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
3
+ xmlns:xs="http://www.w3.org/2001/XMLSchema"
4
+ exclude-result-prefixes="xs"
5
+ version="1.0">
6
+ <xsl:template match="/">
7
+ <xsl:apply-templates select=".//mtef" />
8
+ </xsl:template>
9
+
10
+ <xsl:template match="mtef">
11
+ <math display="block">
12
+ <xsl:apply-templates select="pile | slot"/>
13
+ </math>
14
+ </xsl:template>
15
+
16
+ <xsl:template match="tmpl[selector = 'tmFRACT']">
17
+ <mfrac>
18
+ <xsl:apply-templates select="slot[1]"/>
19
+ <xsl:apply-templates select="slot[2]"/>
20
+ </mfrac>
21
+ </xsl:template>
22
+
23
+ <xsl:template match="slot">
24
+ <mrow>
25
+ <xsl:apply-templates/>
26
+ </mrow>
27
+ </xsl:template>
28
+
29
+ <xsl:template match="tmpl[selector = 'tmROOT']">
30
+ <msqrt>
31
+ <xsl:apply-templates/>
32
+ </msqrt>
33
+ </xsl:template>
34
+
35
+ <xsl:template match="char[typeface = '2']">
36
+ <mn>
37
+ <xsl:text disable-output-escaping="yes">&amp;#</xsl:text>
38
+ <xsl:value-of select="substring(mt_code_value/text(), 2)"/>
39
+ <xsl:text>;</xsl:text>
40
+ </mn>
41
+ </xsl:template>
42
+
43
+ <xsl:template match="char[typeface = '8']">
44
+ <mn>
45
+ <xsl:text disable-output-escaping="yes">&amp;#</xsl:text>
46
+ <xsl:value-of select="substring(mt_code_value/text(), 2)"/>
47
+ <xsl:text>;</xsl:text>
48
+ </mn>
49
+ </xsl:template>
50
+
51
+ <xsl:template match="char[typeface = '3']">
52
+ <mi>
53
+ <xsl:text disable-output-escaping="yes">&amp;#</xsl:text>
54
+ <xsl:value-of select="substring(mt_code_value/text(), 2)"/>
55
+ <xsl:text>;</xsl:text>
56
+ </mi>
57
+ </xsl:template>
58
+
59
+ <xsl:template match="char[typeface = '6']">
60
+ <mo>
61
+ <xsl:text disable-output-escaping="yes">&amp;#</xsl:text>
62
+ <xsl:value-of select="substring(mt_code_value/text(), 2)"/>
63
+ <xsl:text>;</xsl:text>
64
+ </mo>
65
+ </xsl:template>
66
+
67
+ <xsl:template match="*" />
68
+
69
+ <xsl:template match="tmpl[selector='tmROOT' and variation='tvROOT_NTH']">
70
+ <mroot>
71
+ <xsl:apply-templates select="slot[1]" />
72
+ <xsl:apply-templates select="slot[2]" />
73
+ </mroot>
74
+ </xsl:template>
75
+
76
+ <xsl:template match="tmpl[selector='tmARROW']">
77
+ <munderover accentunder="true">
78
+ <mstyle scriptlevel="-1"><mo>&#x21C0;</mo></mstyle>
79
+ <munder>
80
+ <mstyle scriptlevel="+1"><mo>&#x21BD;</mo></mstyle>
81
+ <xsl:apply-templates select="slot[1]" />
82
+ <xsl:apply-templates select="slot[2]" />
83
+ </munder>
84
+ </munderover>
85
+ </xsl:template>
86
+
87
+ <xsl:template match="tmpl[selector='tmPAREN']">
88
+ <mrow><mo>(</mo>
89
+ <xsl:apply-templates select="slot[1]"/>
90
+ <mo>)</mo></mrow>
91
+ </xsl:template>
92
+
93
+ <xsl:include href="lib/xsl/pile.xsl" />
94
+ <xsl:include href="lib/xsl/char.xsl" />
95
+ <xsl:include href="lib/xsl/embellishment.xsl" />
96
+ <xsl:include href="lib/xsl/subsup.xsl"/>
97
+ <xsl:include href="lib/xsl/sum.xsl"/>
98
+ <xsl:include href="lib/xsl/union_intersection.xsl"/>
99
+ <xsl:include href="lib/xsl/arrow.xsl"/>
100
+ <xsl:include href="lib/xsl/matrix.xsl"/>
101
+ <xsl:include href="lib/xsl/brace.xsl"/>
102
+
103
+
104
+ </xsl:stylesheet>
data/lib/xsl/arrow.xsl ADDED
@@ -0,0 +1,319 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
3
+ xmlns:xs="http://www.w3.org/2001/XMLSchema"
4
+ exclude-result-prefixes="xs"
5
+ version="1.0">
6
+
7
+ <!-- Arrows -->
8
+ <xsl:template match="tmpl[selector='tmARROW']">
9
+ <mover>
10
+ <mo>&#x2192;</mo>
11
+ <xsl:apply-templates select="slot[1]"/>
12
+ </mover>
13
+ </xsl:template>
14
+
15
+ <xsl:template match="tmpl[selector='tmARROW' and variation='tvAR_LEFT']">
16
+ <mover>
17
+ <mo>&#x2190;</mo>
18
+ <xsl:apply-templates select="slot[1]"/>
19
+ </mover>
20
+ </xsl:template>
21
+
22
+ <xsl:template match="tmpl[selector='tmARROW' and variation='tvAR_BOTTOM']">
23
+ <munder>
24
+ <mo>&#x2192;</mo>
25
+ <xsl:apply-templates select="slot[2]"/>
26
+ </munder>
27
+ </xsl:template>
28
+
29
+ <xsl:template match="tmpl[selector='tmARROW' and variation='tvAR_TOPBOTTOM']">
30
+ <munderover>
31
+ <mo>&#x2192;</mo>
32
+ <xsl:apply-templates select="slot[2]"/>
33
+ <xsl:apply-templates select="slot[1]"/>
34
+ </munderover>
35
+ </xsl:template>
36
+
37
+ <xsl:template match="tmpl[selector='tmARROW' and variation='tvAR_DOUBLE']">
38
+ <mover>
39
+ <mo>&#x21C4;</mo>
40
+ <xsl:apply-templates select="slot[1]"/>
41
+ </mover>
42
+ </xsl:template>
43
+
44
+ <xsl:template match="tmpl[selector='tmARROW' and (variation='tvAR_LEFT' and variation='tvAR_RIGHT' )]">
45
+ <mover>
46
+ <mo>&#x2194;</mo>
47
+ <xsl:apply-templates select="slot[1]"/>
48
+ </mover>
49
+ </xsl:template>
50
+
51
+ <xsl:template match="tmpl[selector='tmARROW' and variation='tvAR_LEFT' and variation='tvAR_TOPBOTTOM']">
52
+ <munderover>
53
+ <mo>&#x2190;</mo>
54
+ <xsl:apply-templates select="slot[2]"/>
55
+ <xsl:apply-templates select="slot[1]"/>
56
+ </munderover>
57
+ </xsl:template>
58
+
59
+
60
+ <xsl:template match="tmpl[selector='tmARROW' and variation='tvAR_DOUBLE' and variation='tvAR_TOPBOTTOM']">
61
+ <munderover>
62
+ <mo>&#x21C4;</mo>
63
+ <xsl:apply-templates select="slot[2]"/>
64
+ <xsl:apply-templates select="slot[1]"/>
65
+ </munderover>
66
+ </xsl:template>
67
+
68
+ <xsl:template match="tmpl[selector='tmARROW' and variation='tvAR_DOUBLE' and variation='tvAR_LOS']">
69
+ <mover>
70
+ <munder accentunder="true">
71
+ <mstyle scriptlevel="-1"><mo>&#x2192;</mo></mstyle>
72
+ <mstyle scriptlevel="+1"><mo>&#x2190;</mo></mstyle>
73
+ </munder>
74
+ <xsl:apply-templates select="slot[1]"/>
75
+ </mover>
76
+ </xsl:template>
77
+
78
+ <xsl:template match="tmpl[selector='tmARROW' and variation='tvAR_DOUBLE' and variation='tvAR_SOL']">
79
+ <mover>
80
+ <munder accentunder="true">
81
+ <mstyle scriptlevel="+1"><mo>&#x2192;</mo></mstyle>
82
+ <mstyle scriptlevel="-1"><mo>&#x2190;</mo></mstyle>
83
+ </munder>
84
+ <xsl:apply-templates select="slot[1]"/>
85
+ </mover>
86
+ </xsl:template>
87
+
88
+ <xsl:template match="tmpl[selector='tmARROW' and (variation='tvAR_DOUBLE' or variation='tvAR_HARPOON') and variation='tvAR_HARPOON']">
89
+ <mover>
90
+ <mo>&#x21CC;</mo>
91
+ <xsl:apply-templates select="slot[1]"/>
92
+ </mover>
93
+ </xsl:template>
94
+
95
+ <xsl:template match="tmpl[selector='tmARROW' and (variation='tvAR_LEFT' and variation='tvAR_RIGHT' ) and variation='tvAR_TOPBOTTOM']">
96
+ <munderover>
97
+ <mo>&#x2194;</mo>
98
+ <xsl:apply-templates select="slot[2]"/>
99
+ <xsl:apply-templates select="slot[1]"/>
100
+ </munderover>
101
+ </xsl:template>
102
+
103
+
104
+ <xsl:template match="tmpl[selector='tmARROW' and (variation='tvAR_DOUBLE' or variation='tvAR_HARPOON') and variation='tvAR_HARPOON']">
105
+ <mover>
106
+ <mo>&#x21CC;</mo>
107
+ <xsl:apply-templates select="slot[1]"/>
108
+ </mover>
109
+ </xsl:template>
110
+
111
+ <xsl:template match="tmpl[selector='tmARROW' and variation='tvAR_DOUBLE' and variation='tvAR_LOS' and variation='tvAR_TOPBOTTOM']">
112
+ <munderover accentunder="true">
113
+ <mstyle scriptlevel="-1"><mo>&#x2192;</mo></mstyle>
114
+ <munder>
115
+ <mstyle scriptlevel="+1"><mo>&#x2190;</mo></mstyle>
116
+ <xsl:apply-templates select="slot[2]"/>
117
+ </munder>
118
+ <xsl:apply-templates select="slot[1]"/>
119
+ </munderover>
120
+ </xsl:template>
121
+
122
+ <xsl:template match="tmpl[selector='tmARROW' and variation='tvAR_DOUBLE' and variation='tvAR_SOL' and variation='tvAR_TOPBOTTOM']">
123
+ <munderover accentunder="true">
124
+ <mstyle scriptlevel="+1"><mo>&#x2192;</mo></mstyle>
125
+ <munder>
126
+ <mstyle scriptlevel="-1"><mo>&#x2190;</mo></mstyle>
127
+ <xsl:apply-templates select="slot[2]"/>
128
+ </munder>
129
+ <xsl:apply-templates select="slot[1]"/>
130
+ </munderover>
131
+ </xsl:template>
132
+
133
+ <xsl:template match="tmpl[selector='tmARROW' and (variation='tvAR_DOUBLE' or variation='tvAR_HARPOON') and variation='tvAR_HARPOON' and variation='tvAR_SOL']">
134
+ <mover>
135
+ <munder accentunder="true">
136
+ <mstyle scriptlevel="+1"><mo>&#x21C0;</mo></mstyle>
137
+ <mstyle scriptlevel="-1"><mo>&#x21BD;</mo></mstyle>
138
+ </munder>
139
+ <xsl:apply-templates select="slot[1]"/>
140
+ </mover>
141
+ </xsl:template>
142
+
143
+ <xsl:template match="tmpl[selector='tmARROW' and (variation='tvAR_DOUBLE' or variation='tvAR_HARPOON') and variation='tvAR_HARPOON' and variation='tvAR_LOS']">
144
+ <mover>
145
+ <munder accentunder="true">
146
+ <mstyle scriptlevel="-1"><mo>&#x21C0;</mo></mstyle>
147
+ <mstyle scriptlevel="+1"><mo>&#x21BD;</mo></mstyle>
148
+ </munder>
149
+ <xsl:apply-templates select="slot[1]"/>
150
+ </mover>
151
+ </xsl:template>
152
+
153
+ <xsl:template match="tmpl[selector='tmARROW' and (variation='tvAR_DOUBLE' or variation='tvAR_HARPOON') and variation='tvAR_HARPOON' and variation='tvAR_TOPBOTTOM']">
154
+ <munderover>
155
+ <mo>&#x21CC;</mo>
156
+ <xsl:apply-templates select="slot[2]"/>
157
+ <xsl:apply-templates select="slot[1]"/>
158
+ </munderover>
159
+ </xsl:template>
160
+
161
+ <xsl:template match="tmpl[selector='tmARROW' and (variation='tvAR_DOUBLE' or variation='tvAR_HARPOON') and variation='tvAR_HARPOON' and variation='tvAR_LOS' and variation='tvAR_TOPBOTTOM']">
162
+ <munderover accentunder="true">
163
+ <mstyle scriptlevel="-1"><mo>&#x21C0;</mo></mstyle>
164
+ <munder>
165
+ <mstyle scriptlevel="+1"><mo>&#x21BD;</mo></mstyle>
166
+ <xsl:apply-templates select="slot[2]"/>
167
+ </munder>
168
+ <xsl:apply-templates select="slot[1]"/>
169
+ </munderover>
170
+ </xsl:template>
171
+
172
+ <xsl:template match="tmpl[selector='tmARROW' and (variation='tvAR_DOUBLE' or variation='tvAR_HARPOON') and variation='tvAR_HARPOON' and variation='tvAR_SOL' and variation='tvAR_TOPBOTTOM']">
173
+ <munderover accentunder="true">
174
+ <mstyle scriptlevel="+1"><mo>&#x21C0;</mo></mstyle>
175
+ <munder>
176
+ <mstyle scriptlevel="-1"><mo>&#x21BD;</mo></mstyle>
177
+ <xsl:apply-templates select="slot[2]"/>
178
+ </munder>
179
+ <xsl:apply-templates select="slot[1]"/>
180
+ </munderover>
181
+ </xsl:template>
182
+
183
+ <xsl:template match="tmpl[selector='tmARROW' and variation='tvAR_LEFT' and variation='tvAR_BOTTOM']">
184
+ <munder>
185
+ <mo>&#x2190;</mo>
186
+ <xsl:apply-templates select="slot[2]"/>
187
+ </munder>
188
+ </xsl:template>
189
+
190
+ <xsl:template match="tmpl[selector='tmARROW' and (variation='tvAR_LEFT' and variation='tvAR_RIGHT' ) and variation='tvAR_BOTTOM']">
191
+ <munder>
192
+ <mo>&#x2194;</mo>
193
+ <xsl:apply-templates select="slot[2]"/>
194
+ </munder>
195
+ </xsl:template>
196
+
197
+ <xsl:template match="tmpl[selector='tmARROW' and variation='tvAR_DOUBLE' and variation='tvAR_BOTTOM']">
198
+ <munder>
199
+ <mo>&#x21C4;</mo>
200
+ <xsl:apply-templates select="slot[2]"/>
201
+ </munder>
202
+ </xsl:template>
203
+
204
+ <xsl:template match="tmpl[selector='tmARROW' and variation='tvAR_DOUBLE' and variation='tvAR_LOS' and variation='tvAR_BOTTOM']">
205
+ <munder>
206
+ <munder accentunder="true">
207
+ <mstyle scriptlevel="-1"><mo>&#x2192;</mo></mstyle>
208
+ <mstyle scriptlevel="+1"><mo>&#x2190;</mo></mstyle>
209
+ </munder>
210
+ <xsl:apply-templates select="slot[2]"/>
211
+ </munder>
212
+ </xsl:template>
213
+
214
+ <xsl:template match="tmpl[selector='tmARROW' and variation='tvAR_DOUBLE' and variation='tvAR_SOL' and variation='tvAR_BOTTOM']">
215
+ <munder>
216
+ <munder accentunder="true">
217
+ <mstyle scriptlevel="+1"><mo>&#x2192;</mo></mstyle>
218
+ <mstyle scriptlevel="-1"><mo>&#x2190;</mo></mstyle>
219
+ </munder>
220
+ <xsl:apply-templates select="slot[2]"/>
221
+ </munder>
222
+ </xsl:template>
223
+
224
+ <xsl:template match="tmpl[selector='tmARROW' and (variation='tvAR_DOUBLE' or variation='tvAR_HARPOON') and variation='tvAR_HARPOON' and variation='tvAR_BOTTOM']">
225
+ <munder>
226
+ <mo>&#x21CC;</mo>
227
+ <xsl:apply-templates select="slot[2]"/>
228
+ </munder>
229
+ </xsl:template>
230
+
231
+ <xsl:template match="tmpl[selector='tmARROW' and (variation='tvAR_DOUBLE' or variation='tvAR_HARPOON') and variation='tvAR_HARPOON' and variation='tvAR_LOS' and variation='tvAR_BOTTOM']">
232
+ <munder>
233
+ <munder accentunder="true">
234
+ <mstyle scriptlevel="-1"><mo>&#x21C0;</mo></mstyle>
235
+ <mstyle scriptlevel="+1"><mo>&#x21BD;</mo></mstyle>
236
+ </munder>
237
+ <xsl:apply-templates select="slot[2]"/>
238
+ </munder>
239
+ </xsl:template>
240
+
241
+ <xsl:template match="tmpl[selector='tmARROW' and (variation='tvAR_DOUBLE' or variation='tvAR_HARPOON') and variation='tvAR_HARPOON' and variation='tvAR_SOL' and variation='tvAR_BOTTOM']">
242
+ <munder>
243
+ <munder accentunder="true">
244
+ <mstyle scriptlevel="+1"><mo>&#x21C0;</mo></mstyle>
245
+ <mstyle scriptlevel="-1"><mo>&#x21BD;</mo></mstyle>
246
+ </munder>
247
+ <xsl:apply-templates select="slot[2]"/>
248
+ </munder>
249
+ </xsl:template>
250
+
251
+ <xsl:template match="tmpl[selector='tmARROW' and variation='tvAR_LEFT' and variation='tvAR_BOTTOM']">
252
+ <munder>
253
+ <mo>&#x2190;</mo>
254
+ <xsl:apply-templates select="slot[2]"/>
255
+ </munder>
256
+ </xsl:template>
257
+
258
+ <xsl:template match="tmpl[selector='tmARROW' and (variation='tvAR_LEFT' and variation='tvAR_RIGHT' ) and variation='tvAR_BOTTOM']">
259
+ <munder>
260
+ <mo>&#x2194;</mo>
261
+ <xsl:apply-templates select="slot[2]"/>
262
+ </munder>
263
+ </xsl:template>
264
+
265
+ <xsl:template match="tmpl[selector='tmARROW' and variation='tvAR_DOUBLE' and variation='tvAR_BOTTOM']">
266
+ <munder>
267
+ <mo>&#x21C4;</mo>
268
+ <xsl:apply-templates select="slot[2]"/>
269
+ </munder>
270
+ </xsl:template>
271
+
272
+ <xsl:template match="tmpl[selector='tmARROW' and variation='tvAR_DOUBLE' and variation='tvAR_LOS' and variation='tvAR_BOTTOM']">
273
+ <munder>
274
+ <munder accentunder="true">
275
+ <mstyle scriptlevel="-1"><mo>&#x2192;</mo></mstyle>
276
+ <mstyle scriptlevel="+1"><mo>&#x2190;</mo></mstyle>
277
+ </munder>
278
+ <xsl:apply-templates select="slot[2]"/>
279
+ </munder>
280
+ </xsl:template>
281
+
282
+ <xsl:template match="tmpl[selector='tmARROW' and variation='tvAR_DOUBLE' and variation='tvAR_SOL' and variation='tvAR_BOTTOM']">
283
+ <munder>
284
+ <munder accentunder="true">
285
+ <mstyle scriptlevel="+1"><mo>&#x2192;</mo></mstyle>
286
+ <mstyle scriptlevel="-1"><mo>&#x2190;</mo></mstyle>
287
+ </munder>
288
+ <xsl:apply-templates select="slot[2]"/>
289
+ </munder>
290
+ </xsl:template>
291
+
292
+ <xsl:template match="tmpl[selector='tmARROW' and (variation='tvAR_DOUBLE' or variation='tvAR_HARPOON') and variation='tvAR_HARPOON' and variation='tvAR_BOTTOM']">
293
+ <munder>
294
+ <mo>&#x21CC;</mo>
295
+ <xsl:apply-templates select="slot[2]"/>
296
+ </munder>
297
+ </xsl:template>
298
+
299
+ <xsl:template match="tmpl[selector='tmARROW' and (variation='tvAR_DOUBLE' or variation='tvAR_HARPOON') and variation='tvAR_HARPOON' and variation='tvAR_LOS' and variation='tvAR_BOTTOM']">
300
+ <munder>
301
+ <munder accentunder="true">
302
+ <mstyle scriptlevel="-1"><mo>&#x21C0;</mo></mstyle>
303
+ <mstyle scriptlevel="+1"><mo>&#x21BD;</mo></mstyle>
304
+ </munder>
305
+ <xsl:apply-templates select="slot[2]"/>
306
+ </munder>
307
+ </xsl:template>
308
+
309
+ <xsl:template match="tmpl[selector='tmARROW' and (variation='tvAR_DOUBLE' or variation='tvAR_HARPOON') and variation='tvAR_HARPOON' and variation='tvAR_SOL' and variation='tvAR_BOTTOM']">
310
+ <munder>
311
+ <munder accentunder="true">
312
+ <mstyle scriptlevel="+1"><mo>&#x21C0;</mo></mstyle>
313
+ <mstyle scriptlevel="-1"><mo>&#x21BD;</mo></mstyle>
314
+ </munder>
315
+ <xsl:apply-templates select="slot[2]"/>
316
+ </munder>
317
+ </xsl:template>
318
+
319
+ </xsl:stylesheet>