mathml2asciimath 0.0.6 → 0.0.11

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ed8645a43df0081966f9dfeb7adab874692f88744694c662b756b4422c49ce4d
4
- data.tar.gz: 2313a305a66a017c5dde637f3d2577530933b0619182a9edbe80328e604d5cf8
3
+ metadata.gz: aebdecff67a553ed83034b2f6fc90d1e1ec5b6be2225b2b74ae7bd951d1e313e
4
+ data.tar.gz: 8aea5d20406c5feab2d8a1713bd3928ecf6a4db264a2a1dbe6a3a87118db4f45
5
5
  SHA512:
6
- metadata.gz: df23f1866231c211cab0bd7fea974d792f15069b6286fcab8fca7a0121043807e21c41b52aa0fd23bbd6e906f7e67246533b7d66af47a5f4690ddfd93d3cb32d
7
- data.tar.gz: 074b6b0c7582313f40725e87d7ecb0a6a0866bd4a198eb9ba963b8d4a3d79712dfa9a7537c03bccae53321fc1a0cf083b9573c424329ea5a3208f41425e3bec8
6
+ metadata.gz: 27e09923df99f422a42ed234d4a9f0d2504f18f667bba3c45547d76d2852019399bfea08cae791e9bc27e1a946fe71b2ec6dd82492d436116f741f8c3e7b8ab2
7
+ data.tar.gz: 0b92d2dc4d0a5239a2487c80c27a812214c21de7164539ed4877fa140e9bb903dab8aec608e66bdb17e989c97f5d74385f4fa59de0016df878c3cff5d84d8679
@@ -0,0 +1,32 @@
1
+ # Auto-generated by Cimas: Do not edit it manually!
2
+ # See https://github.com/metanorma/cimas
3
+ name: rake
4
+
5
+ on:
6
+ push:
7
+ branches: [ master, main ]
8
+ tags: [ v* ]
9
+ pull_request:
10
+
11
+ jobs:
12
+ rake:
13
+ name: Test on Ruby ${{ matrix.ruby }} ${{ matrix.os }}
14
+ runs-on: ${{ matrix.os }}
15
+ continue-on-error: ${{ matrix.experimental }}
16
+ strategy:
17
+ fail-fast: false
18
+ matrix:
19
+ ruby: [ '3.0', '2.7', '2.6', '2.5', '2.4' ]
20
+ os: [ ubuntu-latest, windows-latest, macos-latest ]
21
+ experimental: [ false ]
22
+ steps:
23
+ - uses: actions/checkout@v2
24
+ with:
25
+ submodules: true
26
+
27
+ - uses: ruby/setup-ruby@v1
28
+ with:
29
+ ruby-version: ${{ matrix.ruby }}
30
+ bundler-cache: true
31
+
32
+ - run: bundle exec rake
data/.gitignore ADDED
@@ -0,0 +1 @@
1
+ .rubocop-https--*
data/.hound.yml CHANGED
@@ -1,3 +1,5 @@
1
+ # Auto-generated by Cimas: Do not edit it manually!
2
+ # See https://github.com/metanorma/cimas
1
3
  ruby:
2
- Enabled: true
4
+ enabled: true
3
5
  config_file: .rubocop.yml
data/.rubocop.yml CHANGED
@@ -1,10 +1,10 @@
1
- # This project follows the Ribose OSS style guide.
2
- # https://github.com/riboseinc/oss-guides
3
- # All project-specific additions and overrides should be specified in this file.
4
-
1
+ # Auto-generated by Cimas: Do not edit it manually!
2
+ # See https://github.com/metanorma/cimas
5
3
  inherit_from:
6
4
  - https://raw.githubusercontent.com/riboseinc/oss-guides/master/ci/rubocop.yml
5
+
6
+ # local repo-specific modifications
7
+ # ...
8
+
7
9
  AllCops:
8
- TargetRubyVersion: 2.3
9
- Rails:
10
- Enabled: true
10
+ TargetRubyVersion: 2.4
data/Gemfile CHANGED
@@ -1,5 +1,4 @@
1
1
  source "https://rubygems.org"
2
-
2
+
3
3
  # Specify your gem's dependencies in ruby-vobject.gemspec
4
4
  gemspec
5
-
data/README.adoc CHANGED
@@ -1,10 +1,12 @@
1
1
  = mathml2asciimath
2
2
 
3
3
  image:https://img.shields.io/gem/v/mathml2asciimath.svg["Gem Version", link="https://rubygems.org/gems/mathml2asciimath"]
4
- image:https://img.shields.io/travis/metanorma/mathml2asciimath/master.svg["Travis Build Status", link="https://travis-ci.org/metanorma/mathml2asciimath"]
5
- image:https://ci.appveyor.com/api/projects/status/qvd7fsh8m2aiua4c?svg=true["Appveyor Build Status", link="https://ci.appveyor.com/project/ribose/mathml2asciimath"]
6
- image:https://codeclimate.com/github/metanorma/mathml2asciimath/badges/gpa.svg["Code Climate", link="https://codeclimate.com/github/metanorma/mathml2asciimath"]
7
- image:https://ci.appveyor.com/api/projects/status/qvd7fsh8m2aiua4c?svg=true["Appveyor Build Status", link="https://ci.appveyor.com/project/ribose/mathml2asciimath"]
4
+ image:https://github.com/plurimath/mathml2asciimath/workflows/ubuntu/badge.svg["Ubuntu Build Status", link="https://github.com/plurimath/mathml2asciimath/actions?query=workflow%3Aubuntu"]
5
+ image:https://github.com/plurimath/mathml2asciimath/workflows/macos/badge.svg["OSX Build Status", link="https://github.com/plurimath/mathml2asciimath/actions?query=workflow%3Amacos"]
6
+ image:https://github.com/plurimath/mathml2asciimath/workflows/windows/badge.svg["Windows Build Status", link="https://github.com/plurimath/mathml2asciimath/actions?query=workflow%3Awindows"]
7
+ image:https://codeclimate.com/github/plurimath/mathml2asciimath/badges/gpa.svg["Code Climate", link="https://codeclimate.com/github/plurimath/mathml2asciimath"]
8
+ image:https://img.shields.io/github/issues-pr-raw/plurimath/mathml2asciimath.svg["Pull Requests", link="https://github.com/plurimath/mathml2asciimath/pulls"]
9
+ image:https://img.shields.io/github/commits-since/plurimath/mathml2asciimath/latest.svg["Commits since latest",link="https://github.com/plurimath/mathml2asciimath/releases"]
8
10
 
9
11
  Ruby gem to convert MathML into AsciiMath
10
12
 
data/Rakefile CHANGED
@@ -3,4 +3,4 @@ require "rspec/core/rake_task"
3
3
 
4
4
  RSpec::Core::RakeTask.new(:spec)
5
5
 
6
- task :default => :spec
6
+ task default: :spec
data/bin/m2a.rb CHANGED
@@ -5,13 +5,11 @@ while a = gets
5
5
  matches = a.split(%r{(<math.*?</math>)})
6
6
  out = ""
7
7
  matches.each do |x|
8
- if /<math/.match x
9
- out += MathML2AsciiMath.m2a(x)
10
- else
11
- out += x
12
- end
8
+ out += if /<math/.match? x
9
+ MathML2AsciiMath.m2a(x)
10
+ else
11
+ x
12
+ end
13
13
  end
14
14
  print out
15
15
  end
16
-
17
-
data/bin/rspec CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
-
2
+
3
3
  # This file was generated by Bundler.
4
4
  #
5
5
  # The application 'rspec' is installed as part of a gem, and
@@ -3,267 +3,301 @@ require "htmlentities"
3
3
  require "pp"
4
4
 
5
5
  module MathML2AsciiMath
6
+ def self.m2a(xml)
7
+ normalized = xml
6
8
 
7
- def self.m2a(x)
8
- docxml = Nokogiri::XML(x)
9
- parse(docxml.root).gsub(/ /, " ").
10
- sub(/^\s+/, "").
11
- sub(/\s+$/, "")
9
+ # &:noblanks skips non-significant whitespaces in MathML
10
+ docxml = Nokogiri::XML.parse(normalized, &:noblanks)
11
+
12
+ # Get rid of things like
13
+ # <mtext>&#x2009;</mtext>
14
+ parse(docxml.root).gsub(/[[:blank:]]/, " ").unicode_normalize.squeeze(" ")
15
+ end
16
+
17
+ def self.encodechars(xml)
18
+ xml.gsub(/\u03b1/, "alpha")
19
+ .gsub(/\u03b2/, "beta")
20
+ .gsub(/\u03b3/, "gamma")
21
+ .gsub(/\u0393/, "Gamma")
22
+ .gsub(/\u03b4/, "delta")
23
+ .gsub(/\u0394/, "Delta")
24
+ .gsub(/\u2206/, "Delta")
25
+ .gsub(/\u03b5/, "epsilon")
26
+ .gsub(/\u025b/, "varepsilon")
27
+ .gsub(/\u03b6/, "zeta")
28
+ .gsub(/\u03b7/, "eta")
29
+ .gsub(/\u03b8/, "theta")
30
+ .gsub(/\u0398/, "Theta")
31
+ .gsub(/\u03d1/, "vartheta")
32
+ .gsub(/\u03b9/, "iota")
33
+ .gsub(/\u03ba/, "kappa")
34
+ .gsub(/\u03bb/, "lambda")
35
+ .gsub(/\u039b/, "Lambda")
36
+ .gsub(/\u03bc/, "mu")
37
+ .gsub(/\u03bd/, "nu")
38
+ .gsub(/\u03be/, "xi")
39
+ .gsub(/\u039e/, "Xi")
40
+ .gsub(/\u03c0/, "pi")
41
+ .gsub(/\u03a0/, "Pi")
42
+ .gsub(/\u03c1/, "rho")
43
+ .gsub(/\u03c2/, "beta")
44
+ .gsub(/\u03c3/, "sigma")
45
+ .gsub(/\u03a3/, "Sigma")
46
+ .gsub(/\u03c4/, "tau")
47
+ .gsub(/\u03c5/, "upsilon")
48
+ .gsub(/\u03c6/, "phi")
49
+ .gsub(/\u03a6/, "Phi")
50
+ .gsub(/\u03d5/, "varphi")
51
+ .gsub(/\u03c7/, "chi")
52
+ .gsub(/\u03c8/, "psi")
53
+ .gsub(/\u03a8/, "Psi")
54
+ .gsub(/\u03c9/, "omega")
55
+ .gsub(/\u03a9/, "omega")
56
+ .gsub(/\u22c5/, "*")
57
+ .gsub(/\u2219/, "*")
58
+ .gsub(/\u00b7/, "*")
59
+ .gsub(/\u2217/, "**")
60
+ .gsub(/\u22c6/, "***")
61
+ .gsub(/\//, "//")
62
+ .gsub(/\\/, "\\\\")
63
+ .gsub(/\u00d7/, "xx")
64
+ .gsub(/\u22c9/, "|><")
65
+ .gsub(/\u22ca/, "><|")
66
+ .gsub(/\u22c8/, "|><|")
67
+ .gsub(/\u00f7/, "-:")
68
+ .gsub(/\u2218/, "@")
69
+ .gsub(/\u2295/, "o+")
70
+ .gsub(/\u2a01/, "o+")
71
+ .gsub(/\u2297/, "ox")
72
+ .gsub(/\u2299/, "o.")
73
+ .gsub(/\u2211/, "sum")
74
+ .gsub(/\u220f/, "prod")
75
+ .gsub(/\u2227/, "^^")
76
+ .gsub(/\u22c0/, "^^^")
77
+ .gsub(/\u2228/, "vv")
78
+ .gsub(/\u22c1/, "vvv")
79
+ .gsub(/\u2229/, "nn")
80
+ .gsub(/\u22c2/, "nnn")
81
+ .gsub(/\u222a/, "uu")
82
+ .gsub(/\u22c3/, "uuu")
83
+ .gsub(/\u2260/, "!=")
84
+ .gsub(/\u2264/, "<=")
85
+ .gsub(/\u2265/, ">=")
86
+ .gsub(/\u227a/, "-<")
87
+ .gsub(/\u227b/, ">-")
88
+ .gsub(/\u2aaf/, "-<=")
89
+ .gsub(/\u2ab0/, ">-=")
90
+ .gsub(/\u2208/, "in")
91
+ .gsub(/\u2209/, "!in")
92
+ .gsub(/\u2282/, "sub")
93
+ .gsub(/\u2283/, "sup")
94
+ .gsub(/\u2286/, "sube")
95
+ .gsub(/\u2287/, "supe")
96
+ .gsub(/\u2261/, "-=")
97
+ .gsub(/\u2245/, "~=")
98
+ .gsub(/\u2248/, "~~")
99
+ .gsub(/\u221d/, "prop")
100
+ .gsub(/\u00ac/, "not")
101
+ .gsub(/\u21d2/, "=>")
102
+ .gsub(/\u21d4/, "<=>")
103
+ .gsub(/\u2200/, "AA")
104
+ .gsub(/\u2203/, "EE")
105
+ .gsub(/\u22a5/, "_|_")
106
+ .gsub(/\u22a4/, "TT")
107
+ .gsub(/\u22a2/, "|--")
108
+ .gsub(/\u22a8/, "|==")
109
+ .gsub(/\u22a8/, "|==")
110
+ .gsub(/\u2329/, "(:")
111
+ .gsub(/\u232a/, ":)")
112
+ .gsub(/\u2329/, "<<")
113
+ .gsub(/\u27e8/, "<<")
114
+ .gsub(/\u232a/, ">>")
115
+ .gsub(/\u27e9/, ">>")
116
+ .gsub(/\u222b/, "int")
117
+ .gsub(/\u222e/, "oint")
118
+ .gsub(/\u2202/, "del")
119
+ .gsub(/\u2207/, "grad")
120
+ .gsub(/\u00b1/, "+-")
121
+ .gsub(/\u2205/, "O/")
122
+ .gsub(/\u221e/, "oo")
123
+ .gsub(/\u2135/, "aleph")
124
+ .gsub(/\u2234/, ":.")
125
+ .gsub(/\u2235/, ":'")
126
+ .gsub(/\u2220/, "/_")
127
+ .gsub(/\u25b3/, "/_\\")
128
+ .gsub(/\u2032/, "'")
129
+ .gsub(/~/, "tilde")
130
+ .gsub(/\u00a0\u00a0\u00a0\u00a0/, "qquad")
131
+ .gsub(/\u00a0\u00a0/, "quad")
132
+ .gsub(/\u00a0/, "\\ ")
133
+ .gsub(/\u2322/, "frown")
134
+ .gsub(/\u00a0/, "quad")
135
+ .gsub(/\u22ef/, "cdots")
136
+ .gsub(/\u22ee/, "vdots")
137
+ .gsub(/\u22f1/, "ddots")
138
+ .gsub(/\u22c4/, "diamond")
139
+ .gsub(/\u25a1/, "square")
140
+ .gsub(/\u230a/, "|__")
141
+ .gsub(/\u230b/, "__|")
142
+ .gsub(/\u2308/, "|~")
143
+ .gsub(/\u2309/, "~|")
144
+ .gsub(/\u2102/, "CC")
145
+ .gsub(/\u2115/, "NN")
146
+ .gsub(/\u211a/, "QQ")
147
+ .gsub(/\u211d/, "RR")
148
+ .gsub(/\u2124/, "ZZ")
149
+ .gsub(/\u2191/, "uarr")
150
+ .gsub(/\u2193/, "darr")
151
+ .gsub(/\u2190/, "larr")
152
+ .gsub(/\u2194/, "harr")
153
+ .gsub(/\u21d2/, "rArr")
154
+ .gsub(/\u21d0/, "lArr")
155
+ .gsub(/\u21d4/, "hArr")
156
+ .gsub(/\u2192/, "->")
157
+ .gsub(/\u21a3/, ">->")
158
+ .gsub(/\u21a0/, "->>")
159
+ .gsub(/\u2916/, ">->>")
160
+ .gsub(/\u21a6/, "|->")
161
+ .gsub(/\u2026/, "...")
162
+ .gsub(/\u2212/, "-")
163
+ .gsub(/\u2061/, "") # function application
164
+ .gsub(/\u2751/, "square")
165
+ .gsub(/[\u2028\u2029]/, " ") # normalize thin spaces like \u2009, \u2008
12
166
  end
13
167
 
14
- def self.encodechars(x)
15
- x.gsub(/\u03b1/, "\\alpha").
16
- gsub(/\u03b2/, "\\beta").
17
- gsub(/\u03b3/, "\\gamma").
18
- gsub(/\u0393/, "\\Gamma").
19
- gsub(/\u03b4/, "\\delta").
20
- gsub(/\u0394/, "\\Delta").
21
- gsub(/\u2206/, "\\Delta").
22
- gsub(/\u03b5/, "\\epsilon").
23
- gsub(/\u025b/, "\\varepsilon").
24
- gsub(/\u03b6/, "\\zeta").
25
- gsub(/\u03b7/, "\\eta").
26
- gsub(/\u03b8/, "\\theta").
27
- gsub(/\u0398/, "\\Theta").
28
- gsub(/\u03d1/, "\\vartheta").
29
- gsub(/\u03b9/, "\\iota").
30
- gsub(/\u03ba/, "\\kappa").
31
- gsub(/\u03bb/, "\\lambda").
32
- gsub(/\u039b/, "\\Lambda").
33
- gsub(/\u03bc/, "\\mu").
34
- gsub(/\u03bd/, "\\nu").
35
- gsub(/\u03be/, "\\xi").
36
- gsub(/\u039e/, "\\Xi").
37
- gsub(/\u03c0/, "\\pi").
38
- gsub(/\u03a0/, "\\Pi").
39
- gsub(/\u03c1/, "\\rho").
40
- gsub(/\u03c2/, "\\beta").
41
- gsub(/\u03c3/, "\\sigma").
42
- gsub(/\u03a3/, "\\Sigma").
43
- gsub(/\u03c4/, "\\tau").
44
- gsub(/\u03c5/, "\\upsilon").
45
- gsub(/\u03c6/, "\\phi").
46
- gsub(/\u03a6/, "\\Phi").
47
- gsub(/\u03d5/, "\\varphi").
48
- gsub(/\u03c7/, "\\chi").
49
- gsub(/\u03c8/, "\\psi").
50
- gsub(/\u03a8/, "\\Psi").
51
- gsub(/\u03c9/, "\\omega").
52
- gsub(/\u22c5/, "*").
53
- gsub(/\u2219/, "*").
54
- gsub(/\u00b7/, "*").
55
- gsub(/\u2217/, "**").
56
- gsub(/\u22c6/, "***").
57
- gsub(/\//, "//").
58
- gsub(/\\/, "\\\\").
59
- gsub(/\u00d7/, "xx").
60
- gsub(/\u22c9/, "|><").
61
- gsub(/\u22ca/, "><|").
62
- gsub(/\u22c8/, "|><|").
63
- gsub(/\u00f7/, "-:").
64
- gsub(/\u2218/, "@").
65
- gsub(/\u2295/, "o+").
66
- gsub(/\u2a01/, "o+").
67
- gsub(/\u2297/, "ox").
68
- gsub(/\u2299/, "o.").
69
- gsub(/\u2211/, "sum").
70
- gsub(/\u220f/, "prod").
71
- gsub(/\u2227/, "^^").
72
- gsub(/\u22c0/, "^^^").
73
- gsub(/\u2228/, "vv").
74
- gsub(/\u22c1/, "vvv").
75
- gsub(/\u2229/, "nn").
76
- gsub(/\u22c2/, "nnn").
77
- gsub(/\u222a/, "uu").
78
- gsub(/\u22c3/, "uuu").
79
- gsub(/\u2260/, "!=").
80
- gsub(/\u2264/, "<=").
81
- gsub(/\u2265/, ">=").
82
- gsub(/\u227a/, "-<").
83
- gsub(/\u227b/, ">-").
84
- gsub(/\u2aaf/, "-<=").
85
- gsub(/\u2ab0/, ">-=").
86
- gsub(/\u2208/, "in").
87
- gsub(/\u2209/, "!in").
88
- gsub(/\u2282/, "sub").
89
- gsub(/\u2283/, "sup").
90
- gsub(/\u2286/, "sube").
91
- gsub(/\u2287/, "supe").
92
- gsub(/\u2261/, "-=").
93
- gsub(/\u2245/, "~=").
94
- gsub(/\u2248/, "~~").
95
- gsub(/\u221d/, "prop").
96
- gsub(/\u00ac/, "not").
97
- gsub(/\u21d2/, "=>").
98
- gsub(/\u21d4/, "<=>").
99
- gsub(/\u2200/, "AA").
100
- gsub(/\u2203/, "EE").
101
- gsub(/\u22a5/, "_|_").
102
- gsub(/\u22a4/, "TT").
103
- gsub(/\u22a2/, "|--").
104
- gsub(/\u22a8/, "|==").
105
- gsub(/\u22a8/, "|==").
106
- gsub(/\u2329/, "(:").
107
- gsub(/\u232a/, ":)").
108
- gsub(/\u2329/, "<<").
109
- gsub(/\u27e8/, "<<").
110
- gsub(/\u232a/, ">>").
111
- gsub(/\u27e9/, ">>").
112
- gsub(/\u222e/, "oint").
113
- gsub(/\u2202/, "del").
114
- gsub(/\u2207/, "grad").
115
- gsub(/\u00b1/, "+-").
116
- gsub(/\u2205/, "O/").
117
- gsub(/\u221e/, "oo").
118
- gsub(/\u2135/, "aleph").
119
- gsub(/\u2234/, ":.").
120
- gsub(/\u2235/, ":'").
121
- gsub(/\u2220/, "/_").
122
- gsub(/\u25b3/, "/_\\").
123
- gsub(/\u2032/, "'").
124
- gsub(/~/, "tilde").
125
- gsub(/\u00a0\u00a0\u00a0\u00a0/, "qquad").
126
- gsub(/\u00a0\u00a0/, "quad").
127
- gsub(/\u00a0/, "\\ ").
128
- gsub(/\u2322/, "frown").
129
- gsub(/\u00a0/, "quad").
130
- gsub(/\u22ef/, "cdots").
131
- gsub(/\u22ee/, "vdots").
132
- gsub(/\u22f1/, "ddots").
133
- gsub(/\u22c4/, "diamond").
134
- gsub(/\u25a1/, "square").
135
- gsub(/\u230a/, "|__").
136
- gsub(/\u230b/, "__|").
137
- gsub(/\u2308/, "|~").
138
- gsub(/\u2309/, "~|").
139
- gsub(/\u2102/, "CC").
140
- gsub(/\u2115/, "NN").
141
- gsub(/\u211a/, "QQ").
142
- gsub(/\u211d/, "RR").
143
- gsub(/\u2124/, "ZZ").
144
- gsub(/\u2191/, "uarr").
145
- gsub(/\u2193/, "darr").
146
- gsub(/\u2190/, "larr").
147
- gsub(/\u2194/, "harr").
148
- gsub(/\u21d2/, "rArr").
149
- gsub(/\u21d0/, "lArr").
150
- gsub(/\u21d4/, "hArr").
151
- gsub(/\u2192/, "->").
152
- gsub(/\u21a3/, ">->").
153
- gsub(/\u21a0/, "->>").
154
- gsub(/\u2916/, ">->>").
155
- gsub(/\u21a6/, "|->").
156
- gsub(/\u2026/, "...").
157
- gsub(/\u2212/, "-").
158
- gsub(/\u2061/, ""). # function application
159
- gsub(/\u2751/, "square")
168
+ def self.join_parsed_children(children, delimiter = " ")
169
+ children.map do |n|
170
+ parse(n).strip
171
+ end.join(delimiter)
160
172
  end
161
173
 
162
174
  def self.parse(node)
163
175
  out = ""
164
176
  if node.text?
165
177
  return encodechars(HTMLEntities.new.decode(node.text))
166
- else
167
- case node.name
168
- when "math"
169
- node.elements.each { |n| out << parse(n) }
170
- return out
171
- when "mrow"
172
- outarr = []
173
- node.children.each { |n| outarr << parse(n) }
174
- out = outarr.join("")
175
- if %w{mfrac msub munder munderover}.include? node.parent.name
176
- out = "(#{out})"
177
- end
178
- return out
179
- when "mfenced"
180
- outarr = []
181
- open = node["open"] || "("
182
- close = node["close"] || ")"
183
- separator = "," # TODO currently ignore the supplied separators
184
- node.elements.each { |n| outarr << parse(n) }
185
- out = outarr.join(separator)
186
- return "#{open}#{out}#{close}"
187
- when "msqrt"
188
- node.children.each { |n| out << parse(n) }
189
- return "sqrt(#{out})"
190
- when "mfrac"
191
- return "(#{parse(node.elements[0])})/(#{parse(node.elements[1])})"
192
- when "msup"
193
- sup = parse(node.elements[1])
194
- sup = "(#{sup})" unless sup.length == 1
195
- op = parse(node.elements[0]).gsub(/ $/, "")
196
- return "#{op}^#{sup}"
197
- when "msub"
198
- sub = parse(node.elements[1])
199
- sub = "(#{sub})" unless sub.length == 1
200
- op = parse(node.elements[0]).gsub(/ $/, "")
201
- return "#{op}_#{sub}"
202
- when "munderover", "msubsup"
203
- sub = parse(node.elements[1])
204
- sub = "(#{sub})" unless sub.length == 1
205
- sup = parse(node.elements[2])
206
- sup = "(#{sup})" unless sup.length == 1
207
- op = parse(node.elements[0]).gsub(/ $/, "")
208
- return "#{op}_#{sub}^#{sup}"
209
- when "munder"
210
- elem1 = parse(node.elements[1]).sub(/^\s+/, "").sub(/\s+$/, "")
211
- accent = case elem1
212
- when "\u0332" then "ul"
213
- when "\u23df" then "ubrace"
214
- else
215
- "underset"
216
- end
217
- if accent == "underset"
218
- return "underset(#{elem1})(#{parse(node.elements[0])})"
219
- else
220
- return "#{accent} #{parse(node.elements[0])}"
221
- end
222
- when "mover"
223
- elem1 = parse(node.elements[1]).sub(/^\s+/, "").sub(/\s+$/, "")
224
- accent = case elem1
225
- when "\u005e" then "hat"
226
- when "\u00af" then "bar"
227
- #when "\u2192" then "vec"
228
- when "->" then "vec"
229
- when "." then "dot"
230
- when ".." then "ddot"
231
- when "\u23de" then "obrace"
232
- else
233
- "overset"
234
- end
235
- if accent == "overset"
236
- return "overset(#{elem1})(#{parse(node.elements[0])})"
237
- else
238
- return "#{accent} #{parse(node.elements[0])}"
239
- end
240
- when "mtable"
241
- rows = []
242
- node.elements.each { |n| rows << parse(n) }
243
- return "[#{rows.join(",")}]"
244
- when "mtr"
245
- cols = []
246
- node.elements.each { |n| cols << parse(n) }
247
- return "[#{cols.join(",")}]"
248
- when "mtd"
249
- node.elements.each { |n| out << parse(n) }
250
- return "#{out}"
251
- when "mn", "mtext"
252
- node.children.each { |n| out << parse(n) }
253
- return "#{out}"
254
- when "mi"
255
- # mi is not meant to have space around it, but Word is conflating operators and operands
256
- node.children.each { |n| out << parse(n) }
257
- out = " #{out} " if /[^a-zA-Z0-9',]|[a-z][a-z]/.match out
258
- return out
259
- when "mo"
260
- node.children.each { |n| out << parse(n) }
261
- out = " #{out} " unless node["fence"]
262
- return out
178
+ end
179
+
180
+ case node.name.sub(/^[^:]*:/, "")
181
+ when "math"
182
+ join_parsed_children(node.elements)
183
+
184
+ when "annotation"
185
+ ""
186
+
187
+ when "semantics"
188
+ join_parsed_children(node.elements)
189
+
190
+ when "mrow"
191
+ out = join_parsed_children(node.elements)
192
+ if %w[mfrac msub munder munderover]
193
+ .include? node.parent.name.sub(/^[^:]*:/, "")
194
+ out = "(#{out})"
195
+ end
196
+ out
197
+
198
+ when "mfenced"
199
+ sym_open = node["open"] || "("
200
+ sym_close = node["close"] || ")"
201
+
202
+ separator = "," # TODO currently ignore the supplied separators
203
+ out = join_parsed_children(node.elements, separator)
204
+ "#{sym_open}#{out}#{sym_close}"
205
+
206
+ when "msqrt"
207
+ "sqrt(#{join_parsed_children(node.elements)})"
208
+
209
+ when "mfrac"
210
+ "(#{parse(node.elements[0])})/(#{parse(node.elements[1])})"
211
+
212
+ when "msup"
213
+ sup = parse(node.elements[1])
214
+ sup = "(#{sup})" unless sup.length == 1
215
+ op = parse(node.elements[0]).gsub(/ $/, "")
216
+ "#{op}^#{sup}"
217
+
218
+ when "msub"
219
+ sub = parse(node.elements[1])
220
+ sub = "(#{sub})" unless sub.length == 1
221
+ op = parse(node.elements[0]).gsub(/ $/, "")
222
+ "#{op}_#{sub}"
223
+
224
+ when "munderover", "msubsup"
225
+ sub = parse(node.elements[1])
226
+ sub = "(#{sub})" unless sub.length == 1
227
+ sup = parse(node.elements[2])
228
+ sup = "(#{sup})" unless sup.length == 1
229
+ op = parse(node.elements[0]).gsub(/ $/, "")
230
+ "#{op}_#{sub}^#{sup}"
231
+
232
+ when "munder"
233
+ elem1 = parse(node.elements[1]).strip
234
+ accent = case elem1
235
+ when "\u0332" then "ul"
236
+ when "\u23df" then "ubrace"
237
+ else
238
+ "underset"
239
+ end
240
+
241
+ if accent == "underset"
242
+ "underset(#{elem1})(#{parse(node.elements[0])})"
243
+ else
244
+ "#{accent} #{parse(node.elements[0])}"
245
+ end
246
+
247
+ when "mover"
248
+ elem1 = parse(node.elements[1]).strip
249
+ accent = case elem1
250
+ when "\u005e" then "hat"
251
+ when "\u00af" then "bar"
252
+ # when "\u2192" then "vec"
253
+ when "->" then "vec"
254
+ when "." then "dot"
255
+ when ".." then "ddot"
256
+ when "\u23de" then "obrace"
257
+ else
258
+ "overset"
259
+ end
260
+
261
+ if accent == "overset"
262
+ "overset(#{elem1})(#{parse(node.elements[0])})"
263
263
  else
264
- node.to_xml
264
+ "#{accent} #{parse(node.elements[0])}"
265
265
  end
266
+
267
+ when "mtable"
268
+ "[#{join_parsed_children(node.elements, ',')}]"
269
+
270
+ when "mtr"
271
+ "[#{join_parsed_children(node.elements, ',')}]"
272
+
273
+ when "mtd"
274
+ join_parsed_children(node.elements, ",")
275
+
276
+ when "mn", "mtext"
277
+ join_parsed_children(node.children, "")
278
+
279
+ when "mi"
280
+ # FIXME: What does this comment have to do with Word?
281
+ # mi is not meant to have space around it,
282
+ # but Word is conflating operators and operands
283
+ join_parsed_children(node.children)
284
+
285
+ # FIXME: Why do we need to add extra spaces?
286
+ # out = " #{out} " if /[^a-zA-Z0-9',]|[a-z][a-z]/.match out
287
+
288
+ when "mo"
289
+ out = join_parsed_children(node.children)
290
+ out = " #{out} " unless node["fence"]
291
+ out
292
+
293
+ when "mstyle"
294
+ join_parsed_children(node.children)
295
+
296
+ else
297
+ "<math xmlns=\"http://www.w3.org/1998/Math/MathML\">" +
298
+ node.to_xml +
299
+ "</math>"
300
+
266
301
  end
267
302
  end
268
-
269
303
  end