plurimath 0.10.4 → 0.10.7
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/Gemfile +2 -2
- data/lib/plurimath/mathml/formula_transformation.rb +24 -9
- data/lib/plurimath/mathml/translator.rb +1 -4
- data/lib/plurimath/version.rb +1 -1
- metadata +2 -32
- data/TODO.bad_symbols.md +0 -45
- data/TODO.bugs/01-unitsml-enoent.md +0 -28
- data/TODO.bugs/02-system-stack-error-cloned-objects.md +0 -34
- data/TODO.bugs/03-omml-underover-displaystyle.md +0 -23
- data/TODO.bugs/04-unitsml-spec-diffs.md +0 -20
- data/TODO.bugs/05-omml-greek-entity-encoding.md +0 -50
- data/TODO.bugs/mml_custom_model_child_order.md +0 -149
- data/TODO.fix-fails/01-phantom-whitespace.md +0 -63
- data/TODO.fix-fails/02-table-parentheses-latex.md +0 -17
- data/TODO.fix-fails/03-longidv-tag-mathml.md +0 -17
- data/TODO.fix-fails/04-mmultiscript-none-mathml.md +0 -17
- data/TODO.fix-fails/05-mstyle-nary-oint-mathml.md +0 -17
- data/TODO.fix-fails/06-issue-238-mathml.md +0 -17
- data/TODO.fix-fails/07-metanorma-bipm-latex.md +0 -19
- data/TODO.fix-fails/08-metanorma-itu-latex.md +0 -17
- data/TODO.fix-fails/09-omml-greek-encoding.md +0 -24
- data/TODO.fix-fails/10-omml-underover-greek.md +0 -19
- data/TODO.fix-fails/11-omml-multiscripts-zwsp.md +0 -19
- data/TODO.fix-fails/12-omml-oint-integral.md +0 -19
- data/TODO.fix-fails/13-omml-nary-prod.md +0 -19
- data/TODO.fix-fails/14-omml-empty-mo.md +0 -19
- data/TODO.fix-fails/REMAINING_FAILURES.md +0 -168
- data/TODO.fix-tests/00-overview.md +0 -102
- data/TODO.fix-tests/01-zero-width-space.md +0 -34
- data/TODO.fix-tests/02-html-linebreak.md +0 -41
- data/TODO.fix-tests/03-phantom-whitespace.md +0 -34
- data/TODO.fix-tests/04-mathml-structure.md +0 -33
- data/TODO.fix-tests/05-omml-rendering.md +0 -27
- data/TODO.mml-plurimath-model.md +0 -86
- data/lib/plurimath/mathml/utility/formula_transformation.rb +0 -143
data/TODO.mml-plurimath-model.md
DELETED
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
# TODO: Translation Layer for MathML to Plurimath Model
|
|
2
|
-
|
|
3
|
-
## Status: Translation Complete ✅
|
|
4
|
-
|
|
5
|
-
The translation layer in `lib/plurimath/mathml/translator.rb` is **complete and working**.
|
|
6
|
-
|
|
7
|
-
## What Was Fixed
|
|
8
|
-
|
|
9
|
-
### 1. Function Classes (cos, sin, tan, etc.)
|
|
10
|
-
Added comprehensive `MATHML_FUNCTION_CLASSES` lookup mapping 45 function names to their Plurimath Function classes:
|
|
11
|
-
- Trigonometric: sin, cos, tan, cot, sec, csc
|
|
12
|
-
- Hyperbolic: sinh, cosh, tanh, coth, sech, csch
|
|
13
|
-
- Inverse trigonometric: arcsin, arccos, arctan, arccot, arcsec, arccsc
|
|
14
|
-
- Inverse hyperbolic: arsinh, arcosh, artanh, arcoth, arsech, arcsch
|
|
15
|
-
- Exponential/logarithmic: exp, log, ln, lg
|
|
16
|
-
- Limits/extremum: lim, liminf, limsup, inf, sup, max, min
|
|
17
|
-
- Other: det, gcd, dim, hom, ker, deg, mod, arg, abs, norm, floor, ceil, sgn, sum, prod, int, oint
|
|
18
|
-
|
|
19
|
-
### 2. Function + Parenthesis Heuristic
|
|
20
|
-
When `<mi>cos</mi><mo>(</mo>` is encountered in an `<mrow>`, they are combined into `Cos.new(Symbol.new("("))` to produce `\cos{(}` in LaTeX - matching old parser behavior.
|
|
21
|
-
|
|
22
|
-
### 3. Mtext Array Handling
|
|
23
|
-
Fixed issue where `<mtext>` with mixed content would pass an Array to `Text.new` instead of a String.
|
|
24
|
-
|
|
25
|
-
### 4. Mover Bug (Previously Fixed)
|
|
26
|
-
`ordered_children` using `each_mixed_content` ensures correct child order for binary operators.
|
|
27
|
-
|
|
28
|
-
## Test Status
|
|
29
|
-
|
|
30
|
-
```
|
|
31
|
-
41 examples total
|
|
32
|
-
36 failures (due to output format differences, NOT translation bugs)
|
|
33
|
-
5 passing (verified correct)
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
## What Still Fails (36 Tests)
|
|
37
|
-
|
|
38
|
-
The failures are **NOT translation bugs** - they are **output format differences** caused by:
|
|
39
|
-
|
|
40
|
-
### 1. Structural Differences in MathML/OMML Output
|
|
41
|
-
- Extra `<mrow>` wrappers in some places
|
|
42
|
-
- Missing `<mrow>` wrappers in other places
|
|
43
|
-
- The `Mstyle` or `Formula` rendering adds wrappers differently than old parser
|
|
44
|
-
|
|
45
|
-
### 2. Missing Model Attribute Support
|
|
46
|
-
- `Scarries` class doesn't support `crossout` attribute
|
|
47
|
-
- `Msline` class doesn't support `length` attribute
|
|
48
|
-
- `Mglyph` class doesn't support all attributes properly
|
|
49
|
-
|
|
50
|
-
### 3. Format Differences
|
|
51
|
-
- `<=` vs `le` in ASCIIMath output
|
|
52
|
-
- `θ` vs `θ` in OMML output (semantically equivalent)
|
|
53
|
-
- Various whitespace differences
|
|
54
|
-
|
|
55
|
-
### 4. Model Structure Differences
|
|
56
|
-
- The new translator creates objects differently than old `custom_models` approach
|
|
57
|
-
- When these objects render to MathML/OMML/HTML, structure differs
|
|
58
|
-
|
|
59
|
-
## Why These Cannot Be Fixed in Translator
|
|
60
|
-
|
|
61
|
-
The translator correctly creates Plurimath model objects. The failures occur when:
|
|
62
|
-
1. `formula.to_mathml` renders the model to MathML - structure differs from expected
|
|
63
|
-
2. `formula.to_omml` renders the model to OMML - structure differs from expected
|
|
64
|
-
3. `formula.to_asciimath` renders the model to ASCIIMath - format differs from expected
|
|
65
|
-
|
|
66
|
-
These are **model rendering issues**, not **translation issues**.
|
|
67
|
-
|
|
68
|
-
## What Would Fix the Remaining Failures
|
|
69
|
-
|
|
70
|
-
1. **Change Plurimath model classes** to support missing attributes (crossout, length, etc.)
|
|
71
|
-
2. **Change Formula/Mstyle rendering** to match old parser's mrow wrapping behavior
|
|
72
|
-
3. **Update test expectations** to match correct output (not allowed per user constraint)
|
|
73
|
-
|
|
74
|
-
## Files
|
|
75
|
-
|
|
76
|
-
### Created/Modified
|
|
77
|
-
- `lib/plurimath/mathml/translator.rb` - 550+ line translation layer
|
|
78
|
-
- `lib/plurimath/mathml/parser.rb` - uses Translator
|
|
79
|
-
|
|
80
|
-
## Passing Tests (Verified Correct)
|
|
81
|
-
1. Basic MathML parsing
|
|
82
|
-
2. mover children order (critical fix!)
|
|
83
|
-
3. Greek letters → Symbol subclasses
|
|
84
|
-
4. Parentheses → `(` / `)` not `\lparen`/`\rparen`
|
|
85
|
-
5. Linebreak handling
|
|
86
|
-
6. LaTeX output (to_latex assertions now passing)
|
|
@@ -1,143 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Plurimath
|
|
4
|
-
class Mathml
|
|
5
|
-
module Utility
|
|
6
|
-
module FormulaTransformation
|
|
7
|
-
private
|
|
8
|
-
|
|
9
|
-
def filter_values(value, array_to_instance: false,
|
|
10
|
-
replacing_order: true)
|
|
11
|
-
return value unless value.is_a?(Array)
|
|
12
|
-
return array_to_instance ? nil : value if value.empty?
|
|
13
|
-
|
|
14
|
-
if is_a?(Math::Formula) && value.length == 1 && value.first.is_mstyle?
|
|
15
|
-
@displaystyle = value.first.displaystyle
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
if value.length == 1 && value.all?(Math::Formula)
|
|
19
|
-
if array_to_instance
|
|
20
|
-
filter_values(value.first.value, array_to_instance: true)
|
|
21
|
-
else
|
|
22
|
-
value.first
|
|
23
|
-
end
|
|
24
|
-
elsif value.is_a?(Array) && value.any?(Math::Formula::Mrow)
|
|
25
|
-
value.each_with_index do |element, index|
|
|
26
|
-
next unless element.is_a?(Math::Formula::Mrow)
|
|
27
|
-
|
|
28
|
-
value[index] = filter_values(
|
|
29
|
-
Array(element),
|
|
30
|
-
array_to_instance: true,
|
|
31
|
-
replacing_order: replacing_order,
|
|
32
|
-
)
|
|
33
|
-
end
|
|
34
|
-
value
|
|
35
|
-
elsif value_is_ternary_or_nary?(value)
|
|
36
|
-
value.first.parameter_three = value.delete_at(1)
|
|
37
|
-
filter_values(
|
|
38
|
-
Array(value),
|
|
39
|
-
array_to_instance: array_to_instance,
|
|
40
|
-
replacing_order: replacing_order,
|
|
41
|
-
)
|
|
42
|
-
elsif ternary_naryable?(value)
|
|
43
|
-
[
|
|
44
|
-
Math::Function::Nary.new(
|
|
45
|
-
value.first.parameter_one,
|
|
46
|
-
value.first.parameter_two,
|
|
47
|
-
value.first.parameter_three,
|
|
48
|
-
value.last,
|
|
49
|
-
),
|
|
50
|
-
]
|
|
51
|
-
elsif overset_naryable?(value)
|
|
52
|
-
[
|
|
53
|
-
Math::Function::Nary.new(
|
|
54
|
-
value.first.parameter_two,
|
|
55
|
-
nil,
|
|
56
|
-
value.first.parameter_one,
|
|
57
|
-
value.last,
|
|
58
|
-
{ type: "undOvr" },
|
|
59
|
-
),
|
|
60
|
-
]
|
|
61
|
-
elsif power_naryable?(value)
|
|
62
|
-
[
|
|
63
|
-
Math::Function::Nary.new(
|
|
64
|
-
value.first.parameter_one,
|
|
65
|
-
nil,
|
|
66
|
-
value.first.parameter_two,
|
|
67
|
-
value.last,
|
|
68
|
-
{ type: "subSup" },
|
|
69
|
-
),
|
|
70
|
-
]
|
|
71
|
-
elsif array_to_instance && replacing_order
|
|
72
|
-
value.length > 1 ? Math::Formula.new(value) : value.first
|
|
73
|
-
else
|
|
74
|
-
value
|
|
75
|
-
end
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
def validate_symbols(value)
|
|
79
|
-
case value
|
|
80
|
-
when Array
|
|
81
|
-
array_validations(value)
|
|
82
|
-
when Math::Symbols::Symbol
|
|
83
|
-
return value if value.value.nil?
|
|
84
|
-
|
|
85
|
-
instance = mathml_symbol_to_class(value.value)
|
|
86
|
-
if value&.options&.any? && instance.is_a?(Math::Symbols::Symbol)
|
|
87
|
-
instance.options = value.options
|
|
88
|
-
end
|
|
89
|
-
instance
|
|
90
|
-
when String
|
|
91
|
-
mathml_symbol_to_class(value)
|
|
92
|
-
end
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
def array_validations(value)
|
|
96
|
-
value.each_with_index do |val, index|
|
|
97
|
-
next unless val.is_a?(Math::Symbols::Symbol)
|
|
98
|
-
|
|
99
|
-
unless val.value.nil?
|
|
100
|
-
value[index] =
|
|
101
|
-
mathml_symbol_to_class(val.value)
|
|
102
|
-
end
|
|
103
|
-
end
|
|
104
|
-
value
|
|
105
|
-
end
|
|
106
|
-
|
|
107
|
-
def mathml_symbol_to_class(symbol)
|
|
108
|
-
Plurimath::Utility.mathml_unary_classes(
|
|
109
|
-
Array(symbol),
|
|
110
|
-
lang: :mathml,
|
|
111
|
-
)
|
|
112
|
-
end
|
|
113
|
-
|
|
114
|
-
def value_is_ternary_or_nary?(value)
|
|
115
|
-
return false if value.any?(String)
|
|
116
|
-
|
|
117
|
-
value.length >= 2 &&
|
|
118
|
-
value.first.is_ternary_function? &&
|
|
119
|
-
value.first.parameter_three.nil? &&
|
|
120
|
-
(!value.first.parameter_one.nil? || !value.first.parameter_two.nil?)
|
|
121
|
-
end
|
|
122
|
-
|
|
123
|
-
def ternary_naryable?(value)
|
|
124
|
-
value.length == 2 &&
|
|
125
|
-
value.first.is_a?(Math::Function::PowerBase) &&
|
|
126
|
-
value.first.parameter_one.is_nary_symbol?
|
|
127
|
-
end
|
|
128
|
-
|
|
129
|
-
def overset_naryable?(value)
|
|
130
|
-
value.length == 2 &&
|
|
131
|
-
value.first.is_a?(Math::Function::Overset) &&
|
|
132
|
-
value.first.parameter_two.is_nary_symbol?
|
|
133
|
-
end
|
|
134
|
-
|
|
135
|
-
def power_naryable?(value)
|
|
136
|
-
value.length == 2 &&
|
|
137
|
-
value.first.is_a?(Math::Function::Power) &&
|
|
138
|
-
value.first.parameter_one.is_nary_symbol?
|
|
139
|
-
end
|
|
140
|
-
end
|
|
141
|
-
end
|
|
142
|
-
end
|
|
143
|
-
end
|