asciimath 2.0.3 → 2.0.5
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/AST.adoc +2 -2
- data/CHANGELOG.adoc +14 -0
- data/lib/asciimath/ast.rb +6 -4
- data/lib/asciimath/latex.rb +10 -2
- data/lib/asciimath/markup.rb +20 -3
- data/lib/asciimath/parser.rb +97 -51
- data/lib/asciimath/symbol_table.rb +7 -2
- data/lib/asciimath/version.rb +1 -1
- data/spec/ast.rb +1 -1
- data/spec/customisation_spec.rb +8 -2
- data/spec/parser_spec.rb +60 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 86018ef6bb3e96fddebb125bf2d246b847378dd686cfa720398c09970ad00696
|
4
|
+
data.tar.gz: 6347a679a01a6fbfa1b56cfa366e43f80bf195a763efe9150f69067dbaf0c227
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9886f869eafa972e926c0103fc13c56a67203d2a71eaa607489169d7695225cfe3cdbf216ef325153e9d24f7ea8f57c26482a71752a9713992d866826b08a879
|
7
|
+
data.tar.gz: 985c445a620542eb3d6f851ce1c832b2c8b89c9aa1d3a2258c64d23456cddb7b36b7953de5f954c3fbbfd9769f113edc499881b88206b4bfc67137ea3cfbaf03
|
data/AST.adoc
CHANGED
@@ -257,8 +257,8 @@ Empty matrix cells are represented as `AsciiMath::AST::Empty`.
|
|
257
257
|
|++oo++ |:infty |++∞++ (https://codepoints.net/U+221E[U+221E]) |++\infty++
|
258
258
|
|++infty++ |:infty |++∞++ (https://codepoints.net/U+221E[U+221E]) |++\infty++
|
259
259
|
|++aleph++ |:aleph |++ℵ++ (https://codepoints.net/U+2135[U+2135]) |++\aleph++
|
260
|
-
|++...++ |:ellipsis |++…++ (https://codepoints.net/U+2026[U+2026]) |++\
|
261
|
-
|++ldots++ |:ellipsis |++…++ (https://codepoints.net/U+2026[U+2026]) |++\
|
260
|
+
|++...++ |:ellipsis |++…++ (https://codepoints.net/U+2026[U+2026]) |++\ldots++
|
261
|
+
|++ldots++ |:ellipsis |++…++ (https://codepoints.net/U+2026[U+2026]) |++\ldots++
|
262
262
|
|++:.++ |:therefore |++∴++ (https://codepoints.net/U+2234[U+2234]) |++\therefore++
|
263
263
|
|++therefore++ |:therefore |++∴++ (https://codepoints.net/U+2234[U+2234]) |++\therefore++
|
264
264
|
|++:'++ |:because |++∵++ (https://codepoints.net/U+2235[U+2235]) |++\because++
|
data/CHANGELOG.adoc
CHANGED
@@ -1,5 +1,19 @@
|
|
1
1
|
= Asciimath Changelog
|
2
2
|
|
3
|
+
== 2.0.5
|
4
|
+
|
5
|
+
Bug fixes::
|
6
|
+
|
7
|
+
* Issue #75: render `tilde x` as `\tilde{x}` instead of `\~{x}` in LaTeX output.
|
8
|
+
|
9
|
+
== 2.0.4
|
10
|
+
|
11
|
+
Bug fixes::
|
12
|
+
|
13
|
+
* Issue #69: correctly render sub and superscripts as following `obrace` and `ubrace`.
|
14
|
+
* Issue #70: fix MathML output for `frac`.
|
15
|
+
* Issue #71: correctly parse row vectors.
|
16
|
+
|
3
17
|
== 2.0.3
|
4
18
|
|
5
19
|
Enhancements::
|
data/lib/asciimath/ast.rb
CHANGED
@@ -51,8 +51,8 @@ module AsciiMath
|
|
51
51
|
Number.new(value)
|
52
52
|
end
|
53
53
|
|
54
|
-
def symbol(symbol, text)
|
55
|
-
Symbol.new(symbol, text)
|
54
|
+
def symbol(symbol, text, type)
|
55
|
+
Symbol.new(symbol, text, type)
|
56
56
|
end
|
57
57
|
|
58
58
|
def identifier(value)
|
@@ -340,14 +340,16 @@ module AsciiMath
|
|
340
340
|
|
341
341
|
class Symbol < ValueNode
|
342
342
|
attr_reader :text
|
343
|
+
attr_reader :type
|
343
344
|
|
344
|
-
def initialize(value, text)
|
345
|
+
def initialize(value, text, type)
|
345
346
|
super(value)
|
346
347
|
@text = text.dup.freeze
|
348
|
+
@type = type
|
347
349
|
end
|
348
350
|
|
349
351
|
def ==(o)
|
350
|
-
super && o.text == text
|
352
|
+
super && o.text == text && o.type == type
|
351
353
|
end
|
352
354
|
|
353
355
|
def to_s
|
data/lib/asciimath/latex.rb
CHANGED
@@ -27,7 +27,9 @@ module AsciiMath
|
|
27
27
|
:ne => "\\neq",
|
28
28
|
:assign => ":=",
|
29
29
|
:lt => ?<,
|
30
|
+
:mlt => "\\ll",
|
30
31
|
:gt => ?>,
|
32
|
+
:mgt => "\\gg",
|
31
33
|
:sub => "\\text{–}",
|
32
34
|
:sup => "\\text{^}",
|
33
35
|
:implies => "\\Rightarrow",
|
@@ -71,7 +73,7 @@ module AsciiMath
|
|
71
73
|
:glb => "\\operatorname{glb}",
|
72
74
|
:partial => "\\del",
|
73
75
|
:prime => ?',
|
74
|
-
:tilde => "
|
76
|
+
:tilde => "\\tilde",
|
75
77
|
:nbsp => "\\;",
|
76
78
|
:lceiling => "\\lceil",
|
77
79
|
:rceiling => "\\rceil",
|
@@ -83,6 +85,7 @@ module AsciiMath
|
|
83
85
|
:f => "f",
|
84
86
|
:g => "g",
|
85
87
|
:to => "\\rightarrow",
|
88
|
+
:ellipsis => "\\ldots",
|
86
89
|
:bold => "\\mathbf",
|
87
90
|
:double_struck => "\\mathbb",
|
88
91
|
:italic => "\\mathit",
|
@@ -166,7 +169,12 @@ module AsciiMath
|
|
166
169
|
sup = expression.sup_expression
|
167
170
|
e = expression.base_expression
|
168
171
|
|
169
|
-
|
172
|
+
if e.is_a?(AsciiMath::AST::UnaryOp) &&
|
173
|
+
%i[underbrace overbrace].include?(e.operator.value)
|
174
|
+
append(e)
|
175
|
+
else
|
176
|
+
curly(e)
|
177
|
+
end
|
170
178
|
|
171
179
|
if sub
|
172
180
|
@latex << "_"
|
data/lib/asciimath/markup.rb
CHANGED
@@ -38,7 +38,9 @@ module AsciiMath
|
|
38
38
|
b.add(:ne, "\u2260", :operator)
|
39
39
|
b.add(:assign, "\u2254", :operator)
|
40
40
|
b.add(:lt, "\u003C", :operator)
|
41
|
+
b.add(:mlt, "\u226A", :operator)
|
41
42
|
b.add(:gt, "\u003E", :operator)
|
43
|
+
b.add(:mgt, "\u226B", :operator)
|
42
44
|
b.add(:le, "\u2264", :operator)
|
43
45
|
b.add(:ge, "\u2265", :operator)
|
44
46
|
b.add(:prec, "\u227A", :operator)
|
@@ -52,6 +54,7 @@ module AsciiMath
|
|
52
54
|
b.add(:subseteq, "\u2286", :operator)
|
53
55
|
b.add(:supseteq, "\u2287", :operator)
|
54
56
|
b.add(:equiv, "\u2261", :operator)
|
57
|
+
b.add(:sim, "\u223C", :operator)
|
55
58
|
b.add(:cong, "\u2245", :operator)
|
56
59
|
b.add(:approx, "\u2248", :operator)
|
57
60
|
b.add(:propto, "\u221D", :operator)
|
@@ -92,6 +95,7 @@ module AsciiMath
|
|
92
95
|
b.add(:partial, "\u2202", :operator)
|
93
96
|
b.add(:nabla, "\u2207", :operator)
|
94
97
|
b.add(:pm, "\u00B1", :operator)
|
98
|
+
b.add(:mp, "\u2213", :operator)
|
95
99
|
b.add(:emptyset, "\u2205", :operator)
|
96
100
|
b.add(:infty, "\u221E", :operator)
|
97
101
|
b.add(:aleph, "\u2135", :operator)
|
@@ -206,8 +210,8 @@ module AsciiMath
|
|
206
210
|
b.add(:ddot, '..', :accent, :position => :over)
|
207
211
|
b.add(:overarc, "\u23DC", :accent, :position => :over)
|
208
212
|
b.add(:underline, '_', :accent, :position => :under)
|
209
|
-
b.add(:underbrace, "\u23DF", :accent, :position => :under)
|
210
|
-
b.add(:overbrace, "\u23DE", :accent, :position => :over)
|
213
|
+
b.add(:underbrace, "\u23DF", :accent, :position => :under, :underover => true)
|
214
|
+
b.add(:overbrace, "\u23DE", :accent, :position => :over, :underover => true)
|
211
215
|
b.add(:bold, :bold, :font)
|
212
216
|
b.add(:double_struck, :double_struck, :font)
|
213
217
|
b.add(:italic, :italic, :font)
|
@@ -344,7 +348,7 @@ module AsciiMath
|
|
344
348
|
when ::AsciiMath::AST::Paren
|
345
349
|
append_paren(resolve_paren(node.lparen), node.expression, resolve_paren(node.rparen), opts)
|
346
350
|
when ::AsciiMath::AST::SubSup
|
347
|
-
if (
|
351
|
+
if is_underover(node.base_expression)
|
348
352
|
append_underover(node.base_expression, node.sub_expression, node.sup_expression)
|
349
353
|
else
|
350
354
|
append_subsup(node.base_expression, node.sub_expression, node.sup_expression)
|
@@ -383,6 +387,8 @@ module AsciiMath
|
|
383
387
|
append_root(node.operand2, node.operand1)
|
384
388
|
when :color
|
385
389
|
append_color(node.operand1.to_hex_rgb, node.operand2)
|
390
|
+
when :frac
|
391
|
+
append_fraction(node.operand1, node.operand2)
|
386
392
|
end
|
387
393
|
end
|
388
394
|
when ::AsciiMath::AST::InfixOp
|
@@ -505,5 +511,16 @@ module AsciiMath
|
|
505
511
|
resolved = resolve_symbol(node)
|
506
512
|
!resolved.nil? && resolved[:type] == :accent
|
507
513
|
end
|
514
|
+
|
515
|
+
def is_underover(node)
|
516
|
+
case node
|
517
|
+
when AsciiMath::AST::UnaryOp
|
518
|
+
symbol = node.operator
|
519
|
+
else
|
520
|
+
symbol = node
|
521
|
+
end
|
522
|
+
|
523
|
+
(resolve_symbol(symbol) || {})[:underover]
|
524
|
+
end
|
508
525
|
end
|
509
526
|
end
|
data/lib/asciimath/parser.rb
CHANGED
@@ -253,7 +253,9 @@ module AsciiMath
|
|
253
253
|
b.add('!=', 'ne', :ne, :symbol)
|
254
254
|
b.add(':=', :assign, :symbol)
|
255
255
|
b.add('<', 'lt', :lt, :symbol)
|
256
|
+
b.add('mlt', 'll', :mlt, :symbol)
|
256
257
|
b.add('>', 'gt', :gt, :symbol)
|
258
|
+
b.add('mgt', 'gg', :mgt, :symbol)
|
257
259
|
b.add('<=', 'le', :le, :symbol)
|
258
260
|
b.add('>=', 'ge', :ge, :symbol)
|
259
261
|
b.add('-<', '-lt', 'prec', :prec, :symbol)
|
@@ -267,6 +269,7 @@ module AsciiMath
|
|
267
269
|
b.add('sube', 'subseteq', :subseteq, :symbol)
|
268
270
|
b.add('supe', 'supseteq', :supseteq, :symbol)
|
269
271
|
b.add('-=', 'equiv', :equiv, :symbol)
|
272
|
+
b.add('~', 'sim', :sim, :symbol)
|
270
273
|
b.add('~=', 'cong', :cong, :symbol)
|
271
274
|
b.add('~~', 'approx', :approx, :symbol)
|
272
275
|
b.add('prop', 'propto', :propto, :symbol)
|
@@ -312,6 +315,7 @@ module AsciiMath
|
|
312
315
|
b.add('del', 'partial', :partial, :symbol)
|
313
316
|
b.add('grad', 'nabla', :nabla, :symbol)
|
314
317
|
b.add('+-', 'pm', :pm, :symbol)
|
318
|
+
b.add('-+', 'mp', :mp, :symbol)
|
315
319
|
b.add('O/', 'emptyset', :emptyset, :symbol)
|
316
320
|
b.add('oo', 'infty', :infty, :symbol)
|
317
321
|
b.add('aleph', :aleph, :symbol)
|
@@ -428,16 +432,16 @@ module AsciiMath
|
|
428
432
|
b.add('ubrace', 'underbrace', :underbrace, :unary)
|
429
433
|
b.add('obrace', 'overbrace', :overbrace, :unary)
|
430
434
|
b.add('cancel', :cancel, :unary)
|
431
|
-
b.add('bb', :bold, :unary)
|
432
|
-
b.add('bbb', :double_struck, :unary)
|
435
|
+
b.add('bb', 'mathbf', :bold, :unary)
|
436
|
+
b.add('bbb', 'mathbb', :double_struck, :unary)
|
433
437
|
b.add('ii', :italic, :unary)
|
434
438
|
b.add('bii', :bold_italic, :unary)
|
435
|
-
b.add('cc', :script, :unary)
|
439
|
+
b.add('cc', 'mathcal', :script, :unary)
|
436
440
|
b.add('bcc', :bold_script, :unary)
|
437
|
-
b.add('tt', :monospace, :unary)
|
438
|
-
b.add('fr', :fraktur, :unary)
|
441
|
+
b.add('tt', 'mathtt', :monospace, :unary)
|
442
|
+
b.add('fr', 'mathfrak', :fraktur, :unary)
|
439
443
|
b.add('bfr', :bold_fraktur, :unary)
|
440
|
-
b.add('sf', :sans_serif, :unary)
|
444
|
+
b.add('sf', 'mathsf', :sans_serif, :unary)
|
441
445
|
b.add('bsf', :bold_sans_serif, :unary)
|
442
446
|
b.add('sfi', :sans_serif_italic, :unary)
|
443
447
|
b.add('sfbi', :sans_serif_bold_italic, :unary)
|
@@ -507,7 +511,7 @@ module AsciiMath
|
|
507
511
|
def parse(input)
|
508
512
|
Expression.new(
|
509
513
|
input,
|
510
|
-
parse_expression(Tokenizer.new(input, @symbol_table),
|
514
|
+
parse_expression(Tokenizer.new(input, @symbol_table), nil)
|
511
515
|
)
|
512
516
|
end
|
513
517
|
|
@@ -515,36 +519,36 @@ module AsciiMath
|
|
515
519
|
|
516
520
|
include AsciiMath::AST
|
517
521
|
|
518
|
-
def parse_expression(tok,
|
519
|
-
e =
|
522
|
+
def parse_expression(tok, close_paren_type)
|
523
|
+
e = nil
|
520
524
|
|
521
|
-
while (
|
525
|
+
while (i1 = parse_intermediate_expression(tok, close_paren_type))
|
522
526
|
t1 = tok.next_token
|
523
527
|
|
524
528
|
if t1[:type] == :infix && t1[:value] == :frac
|
525
|
-
|
526
|
-
if
|
527
|
-
e
|
529
|
+
i2 = parse_intermediate_expression(tok, close_paren_type)
|
530
|
+
if i2
|
531
|
+
e = concat_expressions(e, infix(unwrap_paren(i1), token_to_symbol(t1), unwrap_paren(i2)))
|
528
532
|
else
|
529
|
-
e
|
533
|
+
e = concat_expressions(e, i1)
|
530
534
|
end
|
531
535
|
elsif t1[:type] == :eof
|
532
|
-
e
|
536
|
+
e = concat_expressions(e, i1)
|
533
537
|
break
|
534
538
|
else
|
535
|
-
e
|
539
|
+
e = concat_expressions(e, i1)
|
536
540
|
tok.push_back(t1)
|
537
|
-
if
|
541
|
+
if t1[:type] == close_paren_type
|
538
542
|
break
|
539
543
|
end
|
540
544
|
end
|
541
545
|
end
|
542
546
|
|
543
|
-
|
547
|
+
e
|
544
548
|
end
|
545
549
|
|
546
|
-
def parse_intermediate_expression(tok,
|
547
|
-
s = parse_simple_expression(tok,
|
550
|
+
def parse_intermediate_expression(tok, close_paren_type)
|
551
|
+
s = parse_simple_expression(tok, close_paren_type)
|
548
552
|
sub = nil
|
549
553
|
sup = nil
|
550
554
|
|
@@ -553,17 +557,17 @@ module AsciiMath
|
|
553
557
|
when :infix
|
554
558
|
case t1[:value]
|
555
559
|
when :sub
|
556
|
-
sub = parse_simple_expression(tok,
|
560
|
+
sub = parse_simple_expression(tok, close_paren_type)
|
557
561
|
if sub
|
558
562
|
t2 = tok.next_token
|
559
563
|
if t2[:type] == :infix && t2[:value] == :sup
|
560
|
-
sup = parse_simple_expression(tok,
|
564
|
+
sup = parse_simple_expression(tok, close_paren_type)
|
561
565
|
else
|
562
566
|
tok.push_back(t2)
|
563
567
|
end
|
564
568
|
end
|
565
569
|
when :sup
|
566
|
-
sup = parse_simple_expression(tok,
|
570
|
+
sup = parse_simple_expression(tok, close_paren_type)
|
567
571
|
else
|
568
572
|
tok.push_back(t1)
|
569
573
|
end
|
@@ -582,46 +586,54 @@ module AsciiMath
|
|
582
586
|
end
|
583
587
|
end
|
584
588
|
|
585
|
-
def parse_simple_expression(tok,
|
589
|
+
def parse_simple_expression(tok, close_paren_type)
|
586
590
|
t1 = tok.next_token
|
587
591
|
|
588
592
|
case t1[:type]
|
589
593
|
when :lparen, :lrparen
|
594
|
+
if t1[:type] == :lparen
|
595
|
+
close_with = :rparen
|
596
|
+
else
|
597
|
+
close_with = :lrparen
|
598
|
+
end
|
599
|
+
|
590
600
|
t2 = tok.next_token
|
591
|
-
|
592
|
-
|
593
|
-
|
594
|
-
|
595
|
-
tok.push_back(t2)
|
601
|
+
if t2[:type] == close_with
|
602
|
+
paren(token_to_symbol(t1), nil, token_to_symbol(t2))
|
603
|
+
else
|
604
|
+
tok.push_back(t2)
|
596
605
|
|
597
|
-
|
606
|
+
e = parse_expression(tok, close_with)
|
598
607
|
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
|
608
|
+
t2 = tok.next_token
|
609
|
+
if t2[:type] == close_with
|
610
|
+
convert_to_matrix(paren(token_to_symbol(t1), e, token_to_symbol(t2)))
|
611
|
+
else
|
612
|
+
tok.push_back(t2)
|
613
|
+
if t1[:type] == :lrparen
|
614
|
+
concat_expressions(token_to_symbol(t1), e)
|
615
|
+
else
|
616
|
+
paren(token_to_symbol(t1), e, nil)
|
606
617
|
end
|
618
|
+
end
|
607
619
|
end
|
608
620
|
when :rparen
|
609
|
-
if
|
621
|
+
if close_paren_type.nil?
|
622
|
+
token_to_symbol(t1)
|
623
|
+
else
|
610
624
|
tok.push_back(t1)
|
611
625
|
nil
|
612
|
-
else
|
613
|
-
token_to_symbol(t1)
|
614
626
|
end
|
615
627
|
when :unary
|
616
|
-
parse_simple_expression = parse_simple_expression(tok,
|
628
|
+
parse_simple_expression = parse_simple_expression(tok, close_paren_type)
|
617
629
|
s = unwrap_paren(parse_simple_expression)
|
618
630
|
s = identifier('') if s.nil?
|
619
631
|
s = convert_node(s, t1[:convert_operand])
|
620
632
|
unary(token_to_symbol(t1), s)
|
621
633
|
when :binary
|
622
|
-
s1 = unwrap_paren(parse_simple_expression(tok,
|
634
|
+
s1 = unwrap_paren(parse_simple_expression(tok, close_paren_type))
|
623
635
|
s1 = identifier('') if s1.nil?
|
624
|
-
s2 = unwrap_paren(parse_simple_expression(tok,
|
636
|
+
s2 = unwrap_paren(parse_simple_expression(tok, close_paren_type))
|
625
637
|
s2 = identifier('') if s2.nil?
|
626
638
|
|
627
639
|
s1 = convert_node(s1, t1[:convert_operand1])
|
@@ -641,12 +653,37 @@ module AsciiMath
|
|
641
653
|
end
|
642
654
|
end
|
643
655
|
|
656
|
+
def concat_expressions(e1, e2)
|
657
|
+
case e1
|
658
|
+
when Sequence
|
659
|
+
case e2
|
660
|
+
when Sequence
|
661
|
+
expression(*(e1.to_a), *(e2.to_a))
|
662
|
+
when nil
|
663
|
+
e1
|
664
|
+
else
|
665
|
+
expression(*(e1.to_a), e2)
|
666
|
+
end
|
667
|
+
when nil
|
668
|
+
e2
|
669
|
+
else
|
670
|
+
case e2
|
671
|
+
when Sequence
|
672
|
+
expression(e1, *(e2.to_a))
|
673
|
+
when nil
|
674
|
+
e1
|
675
|
+
else
|
676
|
+
expression(e1, e2)
|
677
|
+
end
|
678
|
+
end
|
679
|
+
end
|
680
|
+
|
644
681
|
def token_to_symbol(t1)
|
645
|
-
symbol(t1[:value], t1[:text])
|
682
|
+
symbol(t1[:value], t1[:text], t1[:type])
|
646
683
|
end
|
647
684
|
|
648
685
|
def unwrap_paren(node)
|
649
|
-
if node.is_a?(::AsciiMath::AST::Paren)
|
686
|
+
if node.is_a?(::AsciiMath::AST::Paren) && (node.lparen.nil? || node.lparen.type == :lparen) && (node.rparen.nil? || node.rparen.type == :rparen)
|
650
687
|
group(node.lparen, node.expression, node.rparen)
|
651
688
|
else
|
652
689
|
node
|
@@ -654,14 +691,23 @@ module AsciiMath
|
|
654
691
|
end
|
655
692
|
|
656
693
|
def convert_to_matrix(node)
|
657
|
-
return node unless node.is_a?(::AsciiMath::AST::Paren)
|
694
|
+
return node unless node.is_a?(::AsciiMath::AST::Paren)
|
695
|
+
|
696
|
+
case node.expression
|
697
|
+
when ::AsciiMath::AST::Sequence
|
698
|
+
rows, separators = node.expression.partition.with_index { |obj, i| i.even? }
|
699
|
+
when ::AsciiMath::AST::Paren
|
700
|
+
rows = [node.expression]
|
701
|
+
separators = []
|
702
|
+
else
|
703
|
+
return node
|
704
|
+
end
|
658
705
|
|
659
|
-
|
660
|
-
return node unless rows.length > 1 &&
|
706
|
+
return node unless rows.length >= 1 &&
|
661
707
|
rows.length > separators.length &&
|
662
708
|
separators.all? { |item| is_matrix_separator(item) } &&
|
663
|
-
(rows.all? { |item| item.is_a?(::AsciiMath::AST::Paren) && item.lparen == symbol(:lparen, '(') && item.rparen == symbol(:rparen, ')') } ||
|
664
|
-
rows.all? { |item| item.is_a?(::AsciiMath::AST::Paren) && item.lparen == symbol(:lbracket, '[') && item.rparen == symbol(:rbracket, ']') })
|
709
|
+
(rows.all? { |item| item.is_a?(::AsciiMath::AST::Paren) && item.lparen == symbol(:lparen, '(', :lparen) && item.rparen == symbol(:rparen, ')', :rparen) } ||
|
710
|
+
rows.all? { |item| item.is_a?(::AsciiMath::AST::Paren) && item.lparen == symbol(:lbracket, '[', :lparen) && item.rparen == symbol(:rbracket, ']', :rparen) })
|
665
711
|
|
666
712
|
rows = rows.map do |row|
|
667
713
|
chunks = []
|
@@ -755,7 +801,7 @@ module AsciiMath
|
|
755
801
|
end
|
756
802
|
|
757
803
|
DEFAULT_COLOR_TABLE = ::AsciiMath::Parser.add_default_colors(AsciiMath::ColorTableBuilder.new).build
|
758
|
-
DEFAULT_PARSER_SYMBOL_TABLE = ::AsciiMath::Parser.add_default_parser_symbols(AsciiMath::SymbolTableBuilder.new).build
|
804
|
+
DEFAULT_PARSER_SYMBOL_TABLE = ::AsciiMath::Parser.add_default_parser_symbols(AsciiMath::SymbolTableBuilder.new(allow_symbol_overwrites: false)).build
|
759
805
|
end
|
760
806
|
|
761
807
|
class Expression
|
@@ -1,7 +1,8 @@
|
|
1
1
|
module AsciiMath
|
2
2
|
class SymbolTableBuilder
|
3
|
-
def initialize()
|
3
|
+
def initialize(allow_symbol_overwrites: true)
|
4
4
|
@table = {}
|
5
|
+
@allow_symbol_overwrites = allow_symbol_overwrites
|
5
6
|
end
|
6
7
|
|
7
8
|
def add(*args)
|
@@ -15,7 +16,11 @@ module AsciiMath
|
|
15
16
|
entry[:value] = args.pop
|
16
17
|
|
17
18
|
entry.freeze
|
18
|
-
args.each
|
19
|
+
args.map(&:freeze).each do |name|
|
20
|
+
raise "Symbol overwrites are disallowed, but were attempted for #{name}" if !@allow_symbol_overwrites && !@table[name].nil?
|
21
|
+
|
22
|
+
@table[name] = entry
|
23
|
+
end
|
19
24
|
end
|
20
25
|
|
21
26
|
def build
|
data/lib/asciimath/version.rb
CHANGED
data/spec/ast.rb
CHANGED
data/spec/customisation_spec.rb
CHANGED
@@ -14,7 +14,7 @@ describe 'AsciiMath::Parser', :variant => :ast do
|
|
14
14
|
my_tokens_table.add('mysymbol', :mysymbol, :symbol)
|
15
15
|
|
16
16
|
parsed = AsciiMath::parse("a + mysymbol + b", my_tokens_table.build)
|
17
|
-
expect(parsed.ast).to eq(seq(identifier('a'), symbol('+'), ::AsciiMath::AST::Symbol.new(:mysymbol, 'mysymbol'), symbol('+'), identifier('b')))
|
17
|
+
expect(parsed.ast).to eq(seq(identifier('a'), symbol('+'), ::AsciiMath::AST::Symbol.new(:mysymbol, 'mysymbol', :symbol), symbol('+'), identifier('b')))
|
18
18
|
end
|
19
19
|
|
20
20
|
it "should support replacing standard symbols" do
|
@@ -23,6 +23,12 @@ describe 'AsciiMath::Parser', :variant => :ast do
|
|
23
23
|
my_tokens_table.add('+', :foo, :symbol)
|
24
24
|
|
25
25
|
parsed = AsciiMath::parse("a + b", my_tokens_table.build)
|
26
|
-
expect(parsed.ast).to eq(seq(identifier('a'), ::AsciiMath::AST::Symbol.new(:foo, '+'), identifier('b')))
|
26
|
+
expect(parsed.ast).to eq(seq(identifier('a'), ::AsciiMath::AST::Symbol.new(:foo, '+', :symbol), identifier('b')))
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should support disallowing symbol overwrites" do
|
30
|
+
my_tokens_table = AsciiMath::SymbolTableBuilder.new(allow_symbol_overwrites: false)
|
31
|
+
AsciiMath::Parser.add_default_parser_symbols(my_tokens_table)
|
32
|
+
expect{my_tokens_table.add('+', :foo, :symbol)}.to raise_error 'Symbol overwrites are disallowed, but were attempted for +'
|
27
33
|
end
|
28
34
|
end
|
data/spec/parser_spec.rb
CHANGED
@@ -328,6 +328,13 @@ RSpec.shared_examples 'AsciiMath Examples' do
|
|
328
328
|
:latex => '\\left ( \\begin{matrix} 1 \\\\ 42 \\end{matrix} \\right )',
|
329
329
|
))
|
330
330
|
|
331
|
+
example('((1,42))', &should_generate(
|
332
|
+
:ast => matrix([%w[1 42]]),
|
333
|
+
:mathml => '<math><mrow><mo>(</mo><mtable><mtr><mtd><mn>1</mn></mtd><mtd><mn>42</mn></mtd></mtr></mtable><mo>)</mo></mrow></math>',
|
334
|
+
:html => '<span class="math-inline"><span class="math-row"><span class="math-brace" style="font-size: 100%;">(</span><span class="math-matrix" style="grid-template-columns:repeat(2,1fr);grid-template-rows:repeat(1,1fr);"><span class="math-row"><span class="math-number">1</span></span><span class="math-row"><span class="math-number">42</span></span></span><span class="math-brace" style="font-size: 100%;">)</span></span></span>',
|
335
|
+
:latex => '\\left ( \\begin{matrix} 1 & 42 \\end{matrix} \\right )',
|
336
|
+
))
|
337
|
+
|
331
338
|
example('((1,2,3),(4,5,6),(7,8,9))', &should_generate(
|
332
339
|
:ast => matrix([%w[1 2 3], %w[4 5 6], %w[7 8 9]]),
|
333
340
|
:mathml => '<math><mrow><mo>(</mo><mtable><mtr><mtd><mn>1</mn></mtd><mtd><mn>2</mn></mtd><mtd><mn>3</mn></mtd></mtr><mtr><mtd><mn>4</mn></mtd><mtd><mn>5</mn></mtd><mtd><mn>6</mn></mtd></mtr><mtr><mtd><mn>7</mn></mtd><mtd><mn>8</mn></mtd><mtd><mn>9</mn></mtd></mtr></mtable><mo>)</mo></mrow></math>',
|
@@ -337,7 +344,7 @@ RSpec.shared_examples 'AsciiMath Examples' do
|
|
337
344
|
|
338
345
|
example('|(a,b),(c,d)|=ad-bc', &should_generate(
|
339
346
|
:ast => seq(
|
340
|
-
matrix(symbol('|'), [%w(a b), %w(c d)], symbol('|')
|
347
|
+
matrix(symbol('|'), [%w(a b), %w(c d)], symbol('|')),
|
341
348
|
symbol('='),
|
342
349
|
'a', 'd',
|
343
350
|
symbol('-'),
|
@@ -596,6 +603,58 @@ RSpec.shared_examples 'AsciiMath Examples' do
|
|
596
603
|
:latex => '40 \% \cdot 3 !'
|
597
604
|
))
|
598
605
|
|
606
|
+
example('R(alpha_(K+1)|x)', &should_generate(
|
607
|
+
:ast => seq('R', paren(symbol('('), seq(sub('alpha', grseq('K', symbol('+'), '1')), symbol('|'), 'x'), symbol(')'))),
|
608
|
+
:mathml => '<math><mi>R</mi><mrow><mo>(</mo><mrow><msub><mi>α</mi><mrow><mi>K</mi><mo>+</mo><mn>1</mn></mrow></msub><mo>|</mo><mi>x</mi></mrow><mo>)</mo></mrow></math>',
|
609
|
+
:latex => 'R \\left ( \\alpha_{K + 1} | x \\right )'
|
610
|
+
))
|
611
|
+
|
612
|
+
example('|(a),(b)|', &should_generate(
|
613
|
+
:ast => matrix(symbol('|'), [%w(a), %w(b)], symbol('|')),
|
614
|
+
))
|
615
|
+
|
616
|
+
example('|a+b|', &should_generate(
|
617
|
+
:ast => paren(symbol('|'), seq('a', '+', 'b'), symbol('|')),
|
618
|
+
))
|
619
|
+
|
620
|
+
example('|a+b|/c', &should_generate(
|
621
|
+
:ast => infix(paren(symbol('|'), seq('a', '+', 'b'), symbol('|')), '/', 'c'),
|
622
|
+
))
|
623
|
+
|
624
|
+
example('[[a,b,|,c],[d,e,|,f]]', &should_generate(
|
625
|
+
:ast => matrix(symbol('['), [['a', 'b', symbol('|'), 'c'], ['d', 'e', symbol('|'), 'f']], symbol(']')),
|
626
|
+
))
|
627
|
+
|
628
|
+
example('~a mlt b mgt -+c', &should_generate(
|
629
|
+
:ast => seq(symbol('~'), 'a', symbol('mlt'), 'b', symbol('mgt'), symbol('-+'), 'c'),
|
630
|
+
:latex => '\\sim a \\ll b \\gg \\mp c',
|
631
|
+
:mathml => '<math><mo>∼</mo><mi>a</mi><mo>≪</mo><mi>b</mi><mo>≫</mo><mo>∓</mo><mi>c</mi></math>'
|
632
|
+
))
|
633
|
+
|
634
|
+
example('a+b+...+c', &should_generate(
|
635
|
+
:ast => seq('a', symbol('+'), 'b', symbol('+'), symbol('...'), symbol('+'), 'c'),
|
636
|
+
:latex => 'a + b + \ldots + c',
|
637
|
+
:mathml => '<math><mi>a</mi><mo>+</mo><mi>b</mi><mo>+</mo><mo>…</mo><mo>+</mo><mi>c</mi></math>'
|
638
|
+
))
|
639
|
+
|
640
|
+
example('frac{a}{b}', &should_generate(
|
641
|
+
:ast => binary('frac', group(symbol('{'), 'a', symbol('}')), group(symbol('{'), 'b', symbol('}'))),
|
642
|
+
:latex => '\frac{a}{b}',
|
643
|
+
:mathml => '<math><mfrac><mi>a</mi><mi>b</mi></mfrac></math>'
|
644
|
+
))
|
645
|
+
|
646
|
+
example('ubrace(((1, 0),(0, 1)))_("Adjustment to texture space")', &should_generate(
|
647
|
+
:ast => subsup(unary(symbol('ubrace'), group(matrix([%w[1 0], %w[0 1]]))), group("Adjustment to texture space"), []),
|
648
|
+
:latex => '\underbrace{\left ( \begin{matrix} 1 & 0 \\\\ 0 & 1 \end{matrix} \right )}_{\text{Adjustment to texture space}}',
|
649
|
+
:mathml => '<math><munder><munder accentunder="true"><mrow><mo>(</mo><mtable><mtr><mtd><mn>1</mn></mtd><mtd><mn>0</mn></mtd></mtr><mtr><mtd><mn>0</mn></mtd><mtd><mn>1</mn></mtd></mtr></mtable><mo>)</mo></mrow><mo>⏟</mo></munder><mtext>Adjustment to texture space</mtext></munder></math>'
|
650
|
+
))
|
651
|
+
|
652
|
+
example('tilde x', &should_generate(
|
653
|
+
:ast => unary(symbol('tilde'), 'x'),
|
654
|
+
:latex => '\\tilde{x}'
|
655
|
+
))
|
656
|
+
|
657
|
+
|
599
658
|
version = RUBY_VERSION.split('.').map { |s| s.to_i }
|
600
659
|
|
601
660
|
if version[0] > 1 || version[1] > 8
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: asciimath
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
4
|
+
version: 2.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Pepijn Van Eeckhoudt
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2023-04-09 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: A pure Ruby AsciiMath parsing and conversion library.
|
15
15
|
email:
|
@@ -100,7 +100,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
100
100
|
- !ruby/object:Gem::Version
|
101
101
|
version: '0'
|
102
102
|
requirements: []
|
103
|
-
rubygems_version: 3.1
|
103
|
+
rubygems_version: 3.0.3.1
|
104
104
|
signing_key:
|
105
105
|
specification_version: 4
|
106
106
|
summary: AsciiMath parser and converter
|