mml 2.2.0 → 2.2.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.
- checksums.yaml +4 -4
- data/.rubocop_todo.yml +1 -1
- data/README.adoc +74 -54
- data/lib/mml/version.rb +1 -1
- data/lib/mml.rb +3 -23
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b681a8e9ba48bcb41372e146fa0f16c95eae47303df8db3eb48a9561e959ce6d
|
|
4
|
+
data.tar.gz: d0d046fceba746e66519e9c6c44b395b22d0078d06140e1db04bb0aadb29f37d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5e21cda0df4bada88b50899cb98b58d78ec46f3edca237ae54f064a33038fef2b7b0f5a6ce053709c2113adc0d01ffdea6efb436ca40debb85a6c54c21dbde26
|
|
7
|
+
data.tar.gz: 9544c69937ff05d4df59cd16943c9f393df5bd8a8f3a8a9cd24ba84d3bf9cb457bf6681e24e824faa6bb72c06a30729ef42963741c4034cffbb86a65925a689e
|
data/.rubocop_todo.yml
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# This configuration was generated by
|
|
2
2
|
# `rubocop --auto-gen-config`
|
|
3
|
-
# on 2026-03-31
|
|
3
|
+
# on 2026-03-31 12:25:08 UTC using RuboCop version 1.86.0.
|
|
4
4
|
# The point is for the user to remove these configuration records
|
|
5
5
|
# one by one as the offenses are removed from the code base.
|
|
6
6
|
# Note that changes in the inspected code, or installation of new
|
data/README.adoc
CHANGED
|
@@ -39,15 +39,16 @@ $ gem install mml
|
|
|
39
39
|
----
|
|
40
40
|
require "mml"
|
|
41
41
|
|
|
42
|
-
# Parse MathML
|
|
43
|
-
math = Mml.parse('<math xmlns="http://www.w3.org/1998/Math/MathML"><mi>x</mi></math>')
|
|
42
|
+
# Parse MathML with explicit version
|
|
43
|
+
math = Mml.parse('<math xmlns="http://www.w3.org/1998/Math/MathML"><mi>x</mi></math>', version: 3)
|
|
44
|
+
math4 = Mml.parse(input, version: 4)
|
|
44
45
|
|
|
45
46
|
# Serialize back to XML
|
|
46
47
|
math.to_xml
|
|
47
|
-
# => "<math xmlns=\"http://www.w3.org/1998/Math/MathML\"><mi>x</mi></math>"
|
|
48
48
|
|
|
49
|
-
#
|
|
50
|
-
|
|
49
|
+
# Or use versioned modules directly
|
|
50
|
+
Mml::V3::Math.from_xml(input)
|
|
51
|
+
Mml::V4::Math.from_xml(input)
|
|
51
52
|
----
|
|
52
53
|
|
|
53
54
|
== MathML version architecture
|
|
@@ -60,7 +61,7 @@ for backward compatibility.
|
|
|
60
61
|
----
|
|
61
62
|
┌───────────────────────────────────────────┐
|
|
62
63
|
│ Mml │
|
|
63
|
-
│ (
|
|
64
|
+
│ parse() delegates to V3 or V4 │
|
|
64
65
|
└────────────────────┬──────────────────────┘
|
|
65
66
|
│
|
|
66
67
|
┌───────────────────┴────────────────────┐
|
|
@@ -97,7 +98,8 @@ for backward compatibility.
|
|
|
97
98
|
Mml.parse(input) # Default: MathML 3 (Mml::V3)
|
|
98
99
|
Mml.parse(input, version: 3) # Explicit MathML 3
|
|
99
100
|
Mml.parse(input, version: 4) # MathML 4 with intent/arg attributes
|
|
100
|
-
Mml::
|
|
101
|
+
Mml::V3.parse(input) # Direct v3 parsing
|
|
102
|
+
Mml::V4.parse(input) # Direct v4 parsing
|
|
101
103
|
----
|
|
102
104
|
|
|
103
105
|
=== Key differences between MathML 3 and MathML 4
|
|
@@ -114,49 +116,60 @@ Mml::V4.parse(input) # Direct v4 parsing (no default fallback)
|
|
|
114
116
|
|Deprecated (recognized but hidden) |`<mlabeledtr>`, `<none>` removed from `CommonAttributes` but classes still exist
|
|
115
117
|
|===
|
|
116
118
|
|
|
117
|
-
=== Migration from
|
|
119
|
+
=== Migration from previous versions
|
|
118
120
|
|
|
119
|
-
====
|
|
121
|
+
==== require and configuration
|
|
120
122
|
|
|
121
|
-
|
|
123
|
+
The `Mml` module no longer aliases versioned constants. Use the explicit version
|
|
124
|
+
namespace:
|
|
122
125
|
|
|
123
126
|
[source,ruby]
|
|
124
127
|
----
|
|
125
|
-
#
|
|
126
|
-
|
|
128
|
+
# Before (no longer supported)
|
|
129
|
+
require "mml/configuration"
|
|
130
|
+
Mml::Configuration.adapter = :nokogiri
|
|
131
|
+
Mml::Configuration.custom_models = { Mi => MyCustomMi }
|
|
132
|
+
Mml::Math.new(...)
|
|
133
|
+
|
|
134
|
+
# After — explicit version
|
|
135
|
+
require "mml"
|
|
136
|
+
Mml::V3::Configuration.adapter = :nokogiri
|
|
137
|
+
Mml::V3::Configuration.custom_models = { Mi => MyCustomMi }
|
|
138
|
+
Mml::V3::Math.new(...)
|
|
127
139
|
|
|
128
|
-
#
|
|
129
|
-
|
|
140
|
+
# Or for MathML 4
|
|
141
|
+
Mml::V4::Configuration.adapter = :nokogiri
|
|
142
|
+
Mml::V4::Configuration.custom_models = { Mi => MyCustomMi }
|
|
143
|
+
Mml::V4::Math.new(...)
|
|
130
144
|
----
|
|
131
145
|
|
|
132
|
-
====
|
|
146
|
+
==== Element class references
|
|
133
147
|
|
|
134
|
-
|
|
148
|
+
All element classes live under their version namespace:
|
|
135
149
|
|
|
136
150
|
[source,ruby]
|
|
137
151
|
----
|
|
138
|
-
#
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
----
|
|
142
|
-
|
|
143
|
-
==== For gem extenders (adding custom elements)
|
|
152
|
+
# Before (no longer supported)
|
|
153
|
+
Mml::Mi.new(value: "x")
|
|
154
|
+
Mml::Mrow.new(mi_value: [...])
|
|
144
155
|
|
|
145
|
-
|
|
156
|
+
# After
|
|
157
|
+
Mml::V3::Mi.new(value: "x")
|
|
158
|
+
Mml::V3::Mrow.new(mi_value: [...])
|
|
146
159
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
Mml::V4::Configuration.custom_models = { Mi => MyCustomMiV4 }
|
|
160
|
+
# Or for MathML 4
|
|
161
|
+
Mml::V4::Mi.new(value: "x", intent: "$x")
|
|
162
|
+
Mml::V4::Mrow.new(mi_value: [...])
|
|
151
163
|
----
|
|
152
164
|
|
|
153
|
-
|
|
154
|
-
|
|
165
|
+
==== Parsing
|
|
166
|
+
|
|
167
|
+
`Mml.parse` still works with a `version:` keyword, defaulting to version 3:
|
|
155
168
|
|
|
156
169
|
[source,ruby]
|
|
157
170
|
----
|
|
158
|
-
#
|
|
159
|
-
Mml
|
|
171
|
+
Mml.parse(input) # unchanged — defaults to MathML 3
|
|
172
|
+
Mml.parse(input, version: 4) # use MathML 4
|
|
160
173
|
----
|
|
161
174
|
|
|
162
175
|
== Parsing and serialization
|
|
@@ -166,13 +179,16 @@ Mml::V4::Mrow.new(a_value: [Mml::V4::A.new(href: "https://...")])
|
|
|
166
179
|
[source,ruby]
|
|
167
180
|
----
|
|
168
181
|
# Default namespace
|
|
169
|
-
Mml.parse('<math xmlns="http://www.w3.org/1998/Math/MathML"><mi>x</mi></math>')
|
|
182
|
+
Mml::V3.parse('<math xmlns="http://www.w3.org/1998/Math/MathML"><mi>x</mi></math>')
|
|
170
183
|
|
|
171
184
|
# Prefixed namespace
|
|
172
|
-
Mml.parse('<mml:math xmlns:mml="http://www.w3.org/1998/Math/MathML"><mml:mi>x</mml:mi></mml:math>')
|
|
185
|
+
Mml::V3.parse('<mml:math xmlns:mml="http://www.w3.org/1998/Math/MathML"><mml:mi>x</mml:mi></mml:math>')
|
|
173
186
|
|
|
174
187
|
# No namespace (namespace injected internally)
|
|
175
|
-
Mml.parse("<math><mi>x</mi></math>", namespace_exist: false)
|
|
188
|
+
Mml::V3.parse("<math><mi>x</mi></math>", namespace_exist: false)
|
|
189
|
+
|
|
190
|
+
# MathML 4
|
|
191
|
+
Mml::V4.parse(input)
|
|
176
192
|
----
|
|
177
193
|
|
|
178
194
|
=== Serialization
|
|
@@ -225,13 +241,13 @@ Token elements hold text content in the `value` attribute:
|
|
|
225
241
|
|
|
226
242
|
[source,ruby]
|
|
227
243
|
----
|
|
228
|
-
Mml::Mi.new(value: "x")
|
|
229
|
-
Mml::Mn.new(value: "42")
|
|
230
|
-
Mml::Mo.new(value: "+")
|
|
231
|
-
Mml::Ms.new(value: "text")
|
|
232
|
-
Mml::Mtext.new(value: "label")
|
|
233
|
-
Mml::Mspace.new(width: "1em")
|
|
234
|
-
Mml::Mglyph.new(alt: "symbol")
|
|
244
|
+
Mml::V3::Mi.new(value: "x")
|
|
245
|
+
Mml::V3::Mn.new(value: "42")
|
|
246
|
+
Mml::V3::Mo.new(value: "+")
|
|
247
|
+
Mml::V3::Ms.new(value: "text")
|
|
248
|
+
Mml::V3::Mtext.new(value: "label")
|
|
249
|
+
Mml::V3::Mspace.new(width: "1em")
|
|
250
|
+
Mml::V3::Mglyph.new(alt: "symbol")
|
|
235
251
|
----
|
|
236
252
|
|
|
237
253
|
=== Container elements
|
|
@@ -240,10 +256,10 @@ Container elements hold child elements via `#{tag}_value` collection attributes:
|
|
|
240
256
|
|
|
241
257
|
[source,ruby]
|
|
242
258
|
----
|
|
243
|
-
Mml::Mrow.new(
|
|
244
|
-
mi_value: [Mml::Mi.new(value: "x")],
|
|
245
|
-
mo_value: [Mml::Mo.new(value: "+")],
|
|
246
|
-
mn_value: [Mml::Mn.new(value: "1")],
|
|
259
|
+
Mml::V3::Mrow.new(
|
|
260
|
+
mi_value: [Mml::V3::Mi.new(value: "x")],
|
|
261
|
+
mo_value: [Mml::V3::Mo.new(value: "+")],
|
|
262
|
+
mn_value: [Mml::V3::Mn.new(value: "1")],
|
|
247
263
|
)
|
|
248
264
|
# => <mrow><mi>x</mi><mo>+</mo><mn>1</mn></mrow>
|
|
249
265
|
----
|
|
@@ -254,10 +270,10 @@ Build an expression tree by nesting elements:
|
|
|
254
270
|
|
|
255
271
|
[source,ruby]
|
|
256
272
|
----
|
|
257
|
-
Mml::Math.new(
|
|
273
|
+
Mml::V3::Math.new(
|
|
258
274
|
mfrac_value: [
|
|
259
|
-
Mml::Mfrac.new(
|
|
260
|
-
mi_value: [Mml::Mi.new(value: "a"), Mml::Mi.new(value: "b")],
|
|
275
|
+
Mml::V3::Mfrac.new(
|
|
276
|
+
mi_value: [Mml::V3::Mi.new(value: "a"), Mml::V3::Mi.new(value: "b")],
|
|
261
277
|
),
|
|
262
278
|
],
|
|
263
279
|
)
|
|
@@ -268,12 +284,12 @@ Mml::Math.new(
|
|
|
268
284
|
|
|
269
285
|
[source,ruby]
|
|
270
286
|
----
|
|
271
|
-
Mml::Mtable.new(
|
|
287
|
+
Mml::V3::Mtable.new(
|
|
272
288
|
mtr_value: [
|
|
273
|
-
Mml::Mtr.new(
|
|
289
|
+
Mml::V3::Mtr.new(
|
|
274
290
|
mtd_value: [
|
|
275
|
-
Mml::Mtd.new(mi_value: [Mml::Mi.new(value: "a")]),
|
|
276
|
-
Mml::Mtd.new(mi_value: [Mml::Mi.new(value: "b")]),
|
|
291
|
+
Mml::V3::Mtd.new(mi_value: [Mml::V3::Mi.new(value: "a")]),
|
|
292
|
+
Mml::V3::Mtd.new(mi_value: [Mml::V3::Mi.new(value: "b")]),
|
|
277
293
|
],
|
|
278
294
|
),
|
|
279
295
|
],
|
|
@@ -339,13 +355,17 @@ Three input forms are supported:
|
|
|
339
355
|
|
|
340
356
|
== Configuration
|
|
341
357
|
|
|
358
|
+
Configuration is version-specific. Use the namespace matching your target version:
|
|
359
|
+
|
|
342
360
|
[source,ruby]
|
|
343
361
|
----
|
|
344
362
|
# Switch XML adapter (default: :ox, also supports :nokogiri)
|
|
345
|
-
Mml::Configuration.adapter = :nokogiri
|
|
363
|
+
Mml::V3::Configuration.adapter = :nokogiri
|
|
364
|
+
Mml::V4::Configuration.adapter = :nokogiri
|
|
346
365
|
|
|
347
366
|
# Register custom model replacements
|
|
348
|
-
Mml::Configuration.custom_models = { Mi => MyCustomMi }
|
|
367
|
+
Mml::V3::Configuration.custom_models = { Mi => MyCustomMi }
|
|
368
|
+
Mml::V4::Configuration.custom_models = { Mi => MyCustomMi }
|
|
349
369
|
----
|
|
350
370
|
|
|
351
371
|
== Development
|
data/lib/mml/version.rb
CHANGED
data/lib/mml.rb
CHANGED
|
@@ -1,38 +1,18 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require "mml/v3"
|
|
4
|
-
|
|
5
3
|
module Mml
|
|
6
4
|
class Error < StandardError; end
|
|
7
5
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
def self.const_missing(name)
|
|
11
|
-
if name == :V4
|
|
12
|
-
require "mml/v4"
|
|
13
|
-
Mml::V4
|
|
14
|
-
elsif Mml::V3.const_defined?(name)
|
|
15
|
-
Mml::V3.const_get(name)
|
|
16
|
-
else
|
|
17
|
-
raise NameError, "uninitialized constant Mml::#{name}"
|
|
18
|
-
end
|
|
19
|
-
end
|
|
6
|
+
autoload :V3, "mml/v3"
|
|
7
|
+
autoload :V4, "mml/v4"
|
|
20
8
|
|
|
21
9
|
module_function
|
|
22
10
|
|
|
23
11
|
def parse(input, namespace_exist: true, version: 3)
|
|
24
12
|
case version
|
|
25
13
|
when 3 then Mml::V3.parse(input, namespace_exist: namespace_exist)
|
|
26
|
-
when 4
|
|
27
|
-
require "mml/v4"
|
|
28
|
-
Mml::V4.parse(input, namespace_exist: namespace_exist)
|
|
14
|
+
when 4 then Mml::V4.parse(input, namespace_exist: namespace_exist)
|
|
29
15
|
else raise Error, "Unsupported MathML version: #{version}"
|
|
30
16
|
end
|
|
31
17
|
end
|
|
32
|
-
|
|
33
|
-
# Backward compatibility: Mml aliases Mml::V3
|
|
34
|
-
Configuration = Mml::V3::Configuration
|
|
35
|
-
|
|
36
|
-
# Explicitly define Math to avoid collision with Ruby built-in Math module
|
|
37
|
-
Math = Mml::V3::Math
|
|
38
18
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: mml
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.2.
|
|
4
|
+
version: 2.2.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose Inc.
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-04-01 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: lutaml-model
|