mathml 0.8.1 → 0.10.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.
@@ -3,9 +3,11 @@
3
3
  # Copyright (C) 2005, KURODA Hiraku <hiraku@hinet.mydns.jp>
4
4
  # You can redistribute it and/or modify it under GPL2.
5
5
 
6
- unless __FILE__ == File.expand_path(__FILE__)
7
- require File.expand_path(File.dirname(__FILE__))+"/"+File.basename(__FILE__, ".rb")
8
- else
6
+ warn "*"*60 << "\n" << <<EOT << "*"*60
7
+ [DEPRECATION]
8
+ "mathml" gem is deprecated.
9
+ Please use "math_ml" gem instead.
10
+ EOT
9
11
 
10
12
  require "strscan"
11
13
  module MathML
@@ -18,1880 +20,12 @@ module MathML
18
20
  end
19
21
 
20
22
  def self.pcstring(s, encoded=false)
21
- EimXML::PCString.new(s, encoded)
23
+ s.is_a?(EimXML::PCString) ? s : EimXML::PCString.new(s, encoded)
22
24
  end
23
25
 
24
- PCString = EimXML::PCString
25
-
26
26
  class Error < StandardError; end
27
-
28
- class Element < XMLElement
29
- attr_reader :display_style
30
-
31
- def as_display_style
32
- @display_style = true
33
- self
34
- end
35
-
36
- def <<(s)
37
- s = MathML.pcstring(s) if String===s
38
- super(s)
39
- end
40
- end
41
-
42
- module Variant
43
- NORMAL = "normal"
44
- BOLD = "bold"
45
- BOLD_ITALIC = "bold-italic"
46
- def variant=(v)
47
- self["mathvariant"] = v
48
- end
49
- end
50
-
51
- module Align
52
- CENTER = "center"
53
- LEFT = "left"
54
- RIGHT = "right"
55
- end
56
-
57
- module Line
58
- SOLID = "solid"
59
- NONE = "none"
60
- end
61
-
62
- class Math < XMLElement
63
- def initialize(display_style)
64
- super("math", "xmlns"=>"http://www.w3.org/1998/Math/MathML")
65
- self[:display] = display_style ? "block" : "inline"
66
- end
67
- end
68
-
69
- class Row < Element
70
- def initialize
71
- super("mrow")
72
- end
73
- end
74
-
75
- class None < Element
76
- def initialize
77
- super("none")
78
- end
79
- end
80
-
81
- class Space < Element
82
- def initialize(width)
83
- super("mspace", "width"=>width)
84
- end
85
- end
86
-
87
- class Fenced < Element
88
- attr_reader :open, :close
89
-
90
- def initialize
91
- super("mfenced")
92
- end
93
-
94
- def open=(o)
95
- o = "" if o.to_s=="." || !o
96
- o = "{" if o.to_s=="\\{"
97
- self[:open] = MathML.pcstring(o, true)
98
- end
99
-
100
- def close=(c)
101
- c = "" if c.to_s=="." || !c
102
- c = "}" if c.to_s=="\\}"
103
- self[:close] = MathML.pcstring(c, true)
104
- end
105
- end
106
-
107
- class Frac < Element
108
- def initialize(numerator, denominator)
109
- super("mfrac")
110
- self << numerator
111
- self << denominator
112
- end
113
- end
114
-
115
- class SubSup < Element
116
- attr_reader :sub, :sup, :body
117
-
118
- def initialize(display_style, body)
119
- super("mrow")
120
- as_display_style if display_style
121
- @body = body
122
-
123
- update_name
124
- end
125
-
126
- def update_name
127
- if @sub || @sup
128
- name = "m"
129
- name << (@sub ? (@display_style ? "under" : "sub") : "")
130
- name << (@sup ? (@display_style ? "over" : "sup") : "")
131
- else
132
- name = "mrow"
133
- end
134
- self.name = name
135
- end
136
- protected :update_name
137
-
138
- def update_contents
139
- contents.clear
140
- contents << @body
141
- contents << @sub if @sub
142
- contents << @sup if @sup
143
- end
144
- protected :update_contents
145
-
146
- def sub=(sub)
147
- @sub = sub
148
- update_name
149
- end
150
-
151
- def sup=(sup)
152
- @sup = sup
153
- update_name
154
- end
155
-
156
- def to_xml_with_indent(dst=String.new, level=0, is_head=true)
157
- update_contents
158
- super
159
- end
160
- end
161
-
162
- class Over < Element
163
- def initialize(base, over)
164
- super("mover")
165
- self << base << over
166
- end
167
- end
168
-
169
- class Under < Element
170
- def initialize(base, under)
171
- super("munder")
172
- self << base << under
173
- end
174
- end
175
-
176
- class Number < Element
177
- def initialize
178
- super("mn")
179
- end
180
- end
181
-
182
- class Identifier < Element
183
- def initialize
184
- super("mi")
185
- end
186
- end
187
-
188
- class Operator < Element
189
- def initialize
190
- super("mo")
191
- end
192
- end
193
-
194
- class Text < Element
195
- def initialize
196
- super("mtext")
197
- end
198
- end
199
-
200
- class Sqrt < Element
201
- def initialize
202
- super("msqrt")
203
- end
204
- end
205
-
206
- class Root < Element
207
- def initialize(index, base)
208
- super("mroot")
209
- self << base
210
- self << index
211
- end
212
- end
213
-
214
- class Table < Element
215
- def initialize
216
- super("mtable")
217
- end
218
-
219
- def set_align_attribute(name, a, default)
220
- if a.is_a?(Array) && a.size>0
221
- value = ""
222
- a.each do |i|
223
- value << " "+i
224
- end
225
- if value =~ /^( #{default})*$/
226
- @attributes.delete(name)
227
- else
228
- @attributes[name] = value.strip
229
- end
230
- else
231
- @attributes.delete(name)
232
- end
233
- end
234
-
235
- def aligns=(a)
236
- set_align_attribute("columnalign", a, Align::CENTER)
237
- end
238
-
239
- def vlines=(a)
240
- set_align_attribute("columnlines", a, Line::NONE)
241
- end
242
-
243
- def hlines=(a)
244
- set_align_attribute("rowlines", a, Line::NONE)
245
- end
246
- end
247
-
248
- class Tr < Element
249
- def initialize
250
- super("mtr")
251
- end
252
- end
253
-
254
- class Td < Element
255
- def initialize
256
- super("mtd")
257
- end
258
- end
259
-
260
- module LaTeX
261
- MBEC = /\\.|[^\\]/m
262
-
263
- module RE
264
- SPACE = /(?:\s|%.*$)/
265
- NUMERICS = /(?:\.\d+)|(?:\d+(\.\d+)?)/
266
- OPERATORS = /[,\.\+\-\*=\/\(\)\[\]<>"|;:!]/
267
- ALPHABETS = /[a-zA-Z]/
268
- BLOCK = /\A\{(.*?)\}\z/m
269
- OPTION = /\A\[(.*)\]\z/m
270
- COMMANDS = /\\([a-zA-Z]+|[^a-zA-Z])/
271
- WBSLASH = /\\\\/
272
- BRACES = /\A([.|\[\]\(\)<>])\z/
273
- end
274
-
275
- module Font
276
- NORMAL = 0
277
- BOLD = 1
278
- BLACKBOLD = 2
279
- SCRIPT = 3
280
- FRAKTUR = 4
281
- ROMAN = 5
282
- BOLD_ITALIC = 6
283
- end
284
-
285
- class BlockNotClosed < StandardError; end
286
- class NotEnvironment < StandardError; end
287
- class EnvironmentNotEnd < StandardError; end
288
- class NeedParameter < StandardError; end
289
- class EndMismatchToBegin < StandardError; end
290
- class OptionNotClosed < StandardError; end
291
-
292
- class Scanner < StringScanner
293
- def done
294
- self.string[0, pos]
295
- end
296
-
297
- def scan_space
298
- _scan(/#{RE::SPACE}+/)
299
- end
300
-
301
- def skip_space_and(check_mode)
302
- opos = pos
303
- scan_space
304
- r = yield
305
- self.pos = opos if check_mode || !r
306
- r
307
- end
308
-
309
- alias :_check :check
310
- def check(re)
311
- skip_space_and(true){_check(re)}
312
- end
313
-
314
- alias :_scan :scan
315
- def scan(re)
316
- skip_space_and(false){_scan(re)}
317
- end
318
-
319
- alias :_eos? :eos?
320
- def eos?
321
- _eos? || _check(/#{RE::SPACE}+\z/)
322
- end
323
-
324
- def check_command
325
- check(RE::COMMANDS)
326
- end
327
-
328
- def scan_command
329
- scan(RE::COMMANDS)
330
- end
331
-
332
- def peek_command
333
- check_command ? self[1] : nil
334
- end
335
-
336
- def check_block
337
- skip_space_and(true){scan_block}
338
- end
339
-
340
- def scan_block
341
- return nil unless scan(/\{/)
342
- block = "{"
343
- bpos = pos-1
344
- nest = 1
345
- while _scan(/(#{MBEC}*?)([\{\}])/)
346
- block << matched
347
- case self[2]
348
- when "{"
349
- nest+=1
350
- when "}"
351
- nest-=1
352
- break if nest==0
353
- end
354
- end
355
- if nest>0
356
- self.pos = bpos
357
- raise BlockNotClosed
358
- end
359
- self.pos = bpos
360
- _scan(/\A\{(#{Regexp.escape(block[RE::BLOCK, 1].to_s)})\}/)
361
- end
362
-
363
- def check_any(remain_space=false)
364
- skip_space_and(true){scan_any(remain_space)}
365
- end
366
-
367
- def scan_any(remain_space=false)
368
- p = pos
369
- scan_space
370
- r = remain_space ? matched.to_s : ""
371
- case
372
- when s = scan_block
373
- when s = scan_command
374
- else
375
- unless _scan(/./) || remain_space
376
- self.pos = p
377
- return nil
378
- end
379
- s = matched.to_s
380
- end
381
- r << s
382
- end
383
-
384
- def scan_option
385
- return nil unless scan(/\[/)
386
- opt = "["
387
- p = pos-1
388
- until (s=scan_any(true)) =~ /\A#{RE::SPACE}*\]\z/
389
- opt << s
390
- if eos?
391
- self.pos = p
392
- raise OptionNotClosed
393
- end
394
- end
395
- opt << s
396
- self.pos = p
397
- _scan(/\A\[(#{Regexp.escape(opt[RE::OPTION, 1].to_s)})\]/)
398
- end
399
-
400
- def check_option
401
- skip_space_and(true){scan_option}
402
- end
403
- end
404
-
405
- class ParseError < StandardError
406
- attr_accessor :rest, :done
407
- def initialize(message, rest = "", done = "")
408
- @done = done
409
- @rest = rest
410
- super(message)
411
- end
412
-
413
- def inspect
414
- "#{message} : '#{@done}' / '#{@rest}'\n"+backtrace[0..5].join("\n")
415
- end
416
- end
417
-
418
- class Macro
419
- class Command
420
- attr_reader :num, :body, :option
421
- def initialize(n, b, o)
422
- @num = n
423
- @body = b
424
- @option = o
425
- end
426
- end
427
-
428
- class Environment
429
- attr_reader :num, :beginning, :ending, :option
430
- def initialize(n, b, e, o)
431
- @num = n
432
- @beginning = b
433
- @ending = e
434
- @option = o
435
- end
436
- end
437
-
438
- def initialize
439
- @commands = Hash.new
440
- @environments = Hash.new
441
- end
442
-
443
- def parse_error(message, rest="", whole=nil)
444
- rest = whole[/\A.*?(#{Regexp.escape(rest)}.*\z)/, 1] if whole
445
- rest << @scanner.rest
446
- done = @scanner.string[0, @scanner.string.size-rest.size]
447
- ParseError.new(message, rest, done)
448
- end
449
-
450
- def parse(src)
451
- @scanner = Scanner.new(src)
452
- until @scanner.eos?
453
- unless @scanner.scan_command
454
- @scanner.scan_space
455
- raise parse_error("Syntax error.")
456
- end
457
- case @scanner[1]
458
- when "newcommand"
459
- parse_newcommand
460
- when "newenvironment"
461
- parse_newenvironment
462
- else
463
- raise parse_error("Syntax error.", @scanner.matched)
464
- end
465
- end
466
- rescue BlockNotClosed => e
467
- raise parse_error("Block not closed.")
468
- rescue OptionNotClosed => e
469
- raise parse_error("Option not closed.")
470
- end
471
-
472
- def scan_num_of_parameter
473
- if @scanner.scan_option
474
- raise parse_error("Need positive number.", @scanner[1]+"]") unless @scanner[1]=~/\A#{RE::SPACE}*\d+#{RE::SPACE}*\z/
475
- @scanner[1].to_i
476
- else
477
- 0
478
- end
479
- end
480
-
481
- def check_parameter_numbers(src, opt, whole)
482
- s = Scanner.new(src)
483
- until s.eos?
484
- case
485
- when s.scan(/#{MBEC}*?\#(\d+|.)/)
486
- raise parse_error("Need positive number.") unless s[1]=~/\d+/
487
- raise parse_error("Parameter \# too large.", s[1]+s.rest, whole) if s[1].to_i>opt
488
- else
489
- return nil
490
- end
491
- end
492
- end
493
-
494
- def parse_newcommand
495
- case
496
- when @scanner.scan_block
497
- s = Scanner.new(@scanner[1])
498
- raise parse_error("Need newcommand.", s.rest+"}") unless s.scan_command
499
- com = s[1]
500
- raise parse_error("Syntax error." ,s.rest+"}") unless s.eos?
501
- when @scanner.scan_command
502
- s = Scanner.new(@scanner[1])
503
- com = s.scan_command
504
- else
505
- raise parse_error("Need newcommand.")
506
- end
507
-
508
- optnum = scan_num_of_parameter
509
- opt = @scanner.scan_option ? @scanner[1] : nil
510
-
511
- case
512
- when @scanner.scan_block
513
- body = @scanner[1]
514
- when @scanner.scan_command
515
- body = @scanner.matched
516
- else
517
- body = @scanner.scan(/./)
518
- end
519
-
520
- raise parse_error("Need parameter.") unless body
521
-
522
- check_parameter_numbers(body, optnum, @scanner.matched)
523
-
524
- optnum-=1 if opt
525
- @commands[com] = Command.new(optnum, body, opt)
526
- end
527
-
528
- def parse_newenvironment
529
- case
530
- when @scanner.scan_block
531
- env = @scanner[1]
532
- when @scanner.scan_command
533
- raise ParseError.new
534
- when @scanner.scan(/./)
535
- env = @scanner.matched
536
- end
537
- raise parse_error("Syntax error.", env[/\A.*?(\\.*\z)/, 1], @scanner.matched) if env=~/\\/
538
-
539
- optnum = scan_num_of_parameter
540
- opt = @scanner.scan_option ? @scanner[1] : nil
541
-
542
- b = @scanner.scan_block ? @scanner[1] : @scanner.scan_any
543
- raise parse_error("Need begin block.") unless b
544
- check_parameter_numbers(b, optnum, @scanner.matched)
545
- e = @scanner.scan_block ? @scanner[1] : @scanner.scan_any
546
- raise parse_error("Need end block.") unless e
547
- check_parameter_numbers(e, optnum, @scanner.matched)
548
-
549
- optnum -= 1 if opt
550
- @environments[env] = Environment.new(optnum, b, e, opt)
551
- end
552
-
553
- def commands(com)
554
- @commands[com]
555
- end
556
-
557
- def expand_command(com, params, opt=nil)
558
- return nil unless @commands.has_key?(com)
559
- c = @commands[com]
560
- opt = c.option if c.option && !opt
561
- params.unshift(opt) if c.option
562
- raise ParseError.new("Need more parameter.") if params.size < c.num
563
-
564
- c.body.gsub(/(#{MBEC}*?)\#(\d+)/) do
565
- $1.to_s << params[$2.to_i-1]
566
- end
567
- end
568
-
569
- def environments(env)
570
- @environments[env]
571
- end
572
-
573
- def expand_environment(env, body, params, opt=nil)
574
- return nil unless @environments.has_key?(env)
575
- e = @environments[env]
576
- opt = e.option if e.option && !opt
577
- params.unshift(opt) if e.option
578
- raise ParseError.new("Need more parameter.") if params.size < e.num
579
-
580
- bg = e.beginning.gsub(/(#{MBEC}*?)\#(\d+)/) do
581
- $1.to_s << params[$2.to_i-1]
582
- end
583
-
584
- en = e.ending.gsub(/(#{MBEC}*?)\#(\d+)/) do
585
- $1.to_s << params[$2.to_i-1]
586
- end
587
-
588
- " #{bg} #{body} #{en} "
589
- end
590
- end
591
-
592
- module BuiltinCommands; end
593
- module BuiltinGroups; end
594
- module BuiltinEnvironments; end
595
-
596
- class Parser
597
- class CircularReferenceCommand < StandardError; end
598
-
599
- include LaTeX
600
-
601
- include BuiltinEnvironments
602
- include BuiltinGroups
603
- include BuiltinCommands
604
-
605
- BUILTIN_MACRO = <<'EOS'
606
- \newenvironment{smallmatrix}{\begin{matrix}}{\end{matrix}}
607
- \newenvironment{pmatrix}{\left(\begin{matrix}}{\end{matrix}\right)}
608
- \newenvironment{bmatrix}{\left[\begin{matrix}}{\end{matrix}\right]}
609
- \newenvironment{Bmatrix}{\left\{\begin{matrix}}{\end{matrix}\right\}}
610
- \newenvironment{vmatrix}{\left|\begin{matrix}}{\end{matrix}\right|}
611
- \newenvironment{Vmatrix}{\left\|\begin{matrix}}{\end{matrix}\right\|}
612
- EOS
613
-
614
- attr_accessor :unsecure_entity
615
- attr_reader :macro
616
- def initialize
617
- @unsecure_entity = false
618
- @entities = Hash.new
619
- @commands = Hash.new
620
- @symbols = Hash.new
621
- @delimiters = Array.new
622
- @group_begins = Hash.new
623
- @group_ends = Hash.new
624
- @macro = Macro.new
625
- @macro.parse(BUILTIN_MACRO)
626
- @expanded_command = Array.new
627
- @expanded_environment = Array.new
628
-
629
- super
630
- end
631
-
632
- def add_entity(list)
633
- list.each do |i|
634
- @entities[i] = true
635
- end
636
- end
637
-
638
- def parse(src, displaystyle=false)
639
- @ds = displaystyle
640
- begin
641
- parse_into(src, Math.new(@ds), Font::NORMAL)
642
- rescue ParseError => e
643
- e.done = src[0...(src.size - e.rest.size)]
644
- raise
645
- end
646
- end
647
-
648
- def push_container(container, scanner=@scanner, font=@font)
649
- data = [@container, @scanner, @font]
650
- @container, @scanner, @font = [container, scanner, font]
651
- begin
652
- yield container
653
- container
654
- ensure
655
- @container, @scanner, @font = data
656
- end
657
- end
658
-
659
- def add_plugin(plugin)
660
- self.extend(plugin)
661
- end
662
-
663
- def add_commands(*a)
664
- if a.size==1 && Hash===a[0]
665
- @commands.merge!(a[0])
666
- else
667
- a.each{|i| @commands[i] = false}
668
- end
669
- end
670
-
671
- def add_multi_command(m, *a)
672
- a.each{|i| @commands[i] = m}
673
- end
674
-
675
- def add_sym_cmd(hash)
676
- @symbols.merge!(hash)
677
- end
678
-
679
- def add_delimiter(list)
680
- @delimiters.concat(list)
681
- end
682
-
683
- def add_group(begin_name, end_name, method=nil)
684
- @group_begins[begin_name] = method
685
- @group_ends[end_name] = begin_name
686
- end
687
-
688
- private
689
- def parse_into(src, parent, font=nil)
690
- orig = [@scanner, @container, @font, @ds]
691
- @scanner = Scanner.new(src)
692
- @container = parent
693
- @font = font if font
694
- begin
695
- until @scanner.eos?
696
- @container << parse_to_element(true)
697
- end
698
- @container
699
- rescue BlockNotClosed => e
700
- raise ParseError.new("Block not closed.", @scanner.rest)
701
- rescue NotEnvironment => e
702
- raise ParseError.new("Not environment.", @scanner.rest)
703
- rescue EnvironmentNotEnd => e
704
- raise ParseError.new("Environment not end.", @scanner.rest)
705
- rescue OptionNotClosed => e
706
- raise ParseError.new("Option not closed.", @scanner.rest)
707
- rescue ParseError => e
708
- e.rest << @scanner.rest.to_s
709
- raise
710
- ensure
711
- @scanner, @container, @font, @ds = orig
712
- end
713
- end
714
-
715
- def parse_any(message = "Syntax error.")
716
- raise ParseError.new(message) unless @scanner.scan_any
717
- s = @scanner
718
- @scanner = Scanner.new(@scanner.matched)
719
- begin
720
- parse_to_element
721
- ensure
722
- @scanner = s
723
- end
724
- end
725
-
726
- def parse_to_element(whole_group = false)
727
- if whole_group && @group_begins.has_key?(@scanner.peek_command)
728
- @scanner.scan_command
729
- parse_group
730
- else
731
- case
732
- when @scanner.scan(RE::NUMERICS)
733
- parse_num
734
- when @scanner.scan(RE::ALPHABETS)
735
- parse_char
736
- when @scanner.scan(RE::OPERATORS)
737
- parse_operator
738
- when @scanner.scan_block
739
- parse_block
740
- when @scanner.scan(/_/)
741
- parse_sub
742
- when @scanner.scan(/'+|\^/)
743
- parse_sup
744
- when @scanner.scan_command
745
- parse_command
746
- else
747
- raise ParseError.new('Syntax error.')
748
- end
749
- end
750
- end
751
-
752
- def parse_num
753
- n = Number.new
754
- n.extend(Variant).variant = Variant::BOLD if @font==Font::BOLD
755
- n << @scanner.matched
756
- end
757
-
758
- def parse_char
759
- c = @scanner.matched
760
- i = Identifier.new
761
- case @font
762
- when Font::ROMAN
763
- i.extend(Variant).variant = Variant::NORMAL
764
- when Font::BOLD
765
- i.extend(Variant).variant = Variant::BOLD
766
- when Font::BOLD_ITALIC
767
- i.extend(Variant).variant = Variant::BOLD_ITALIC
768
- when Font::BLACKBOLD
769
- c = MathML.pcstring(%Q[&#{c}opf;], true)
770
- when Font::SCRIPT
771
- c = MathML.pcstring(%Q[&#{c}scr;], true)
772
- when Font::FRAKTUR
773
- c = MathML.pcstring(%Q[&#{c}fr;], true)
774
- end
775
- i << c
776
- end
777
-
778
- def parse_operator
779
- o = @scanner.matched
780
- Operator.new << o
781
- end
782
-
783
- def parse_block
784
- os = @scanner
785
- @scanner = Scanner.new(@scanner[1])
786
- begin
787
- push_container(Row.new) do |r|
788
- r << parse_to_element(true) until @scanner.eos?
789
- end
790
- rescue ParseError => e
791
- e.rest << '}'
792
- raise
793
- ensure
794
- @scanner = os
795
- end
796
- end
797
-
798
- def parse_sub
799
- e = @container.pop
800
- e = None.new unless e
801
- e = SubSup.new(@ds && e.display_style, e) unless e.is_a?(SubSup)
802
- raise ParseError.new("Double subscript.", "_") if e.sub
803
- e.sub = parse_any("Subscript not exist.")
804
- e
805
- end
806
-
807
- def parse_sup
808
- e = @container.pop
809
- e = None.new unless e
810
- e = SubSup.new(@ds && e.display_style, e) unless e.is_a?(SubSup)
811
- raise ParseError.new("Double superscript.", @scanner[0]) if e.sup
812
- if /'+/=~@scanner[0]
813
- prime = Operator.new
814
- prime << MathML.pcstring('&prime;'*@scanner[0].size, true)
815
- unless @scanner.scan(/\^/)
816
- e.sup = prime
817
- return e
818
- end
819
- end
820
- sup = parse_any("Superscript not exist.")
821
-
822
- if prime
823
- unless sup.is_a?(Row)
824
- r = Row.new
825
- r << sup
826
- sup = r
827
- end
828
- sup.contents.insert(0, prime)
829
- end
830
-
831
- e.sup = sup
832
- e
833
- end
834
-
835
- def entitize(str)
836
- MathML.pcstring(str.sub(/^(.*)$/){"&#{$1};"}, true)
837
- end
838
-
839
- def parse_symbol_command(com, plain=false)
840
- unless @symbols.include?(com)
841
- @scanner.pos = @scanner.pos-(com.size+1)
842
- raise ParseError.new("Undefined command.")
843
- end
844
- data = @symbols[com]
845
- return nil unless data
846
-
847
- su = data[0]
848
- el = data[1]
849
- el = :o unless el
850
- s = data[2]
851
- s = com.dup.untaint.to_sym unless s
852
- s = com if s.is_a?(String) && s.length==0
853
-
854
- case el
855
- when :I
856
- el = Identifier.new
857
- when :i
858
- el = Identifier.new
859
- el.extend(Variant).variant = Variant::NORMAL unless s.is_a?(String)&&s.length>1
860
- when :o
861
- el = Operator.new
862
- when :n
863
- el = Number.new
864
- else
865
- raise ParseError.new("Inner data broken.")
866
- end
867
-
868
- case s
869
- when String
870
- when Fixnum
871
- s = "&\#x#{s.to_s(16)};"
872
- when Symbol
873
- s = "&#{s.to_s};"
874
- end
875
-
876
- return s if plain
877
- el << MathML.pcstring(s, true)
878
- el.as_display_style if su==:u
879
- el
880
- end
881
-
882
- def parse_command
883
- com = @scanner[1]
884
- matched = @scanner.matched
885
- pos = @scanner.pos-matched.size
886
- macro = @macro.commands(com)
887
- if macro
888
- begin
889
- flg = @expanded_command.include?(com)
890
- @expanded_command.push(com)
891
- raise CircularReferenceCommand if flg
892
- option = (macro.option && @scanner.scan_option) ? @scanner[1] : nil
893
- params = Array.new
894
- (1..macro.num).each do
895
- params << (@scanner.scan_block ? @scanner[1] : @scanner.scan_any)
896
- raise ParseError.new("Need more parameter.") unless params.last
897
- end
898
- r = parse_into(@macro.expand_command(com, params, option), Array.new)
899
- return r
900
- rescue CircularReferenceCommand
901
- if @expanded_command.size>1
902
- raise
903
- else
904
- @scanner.pos = pos
905
- raise ParseError.new("Circular reference.")
906
- end
907
- rescue ParseError => e
908
- if @expanded_command.size>1
909
- raise
910
- else
911
- @scanner.pos = pos
912
- raise ParseError.new(%[Error in macro(#{e.message} "#{e.rest.strip}").])
913
- end
914
- ensure
915
- @expanded_command.pop
916
- end
917
- elsif @commands.key?(com)
918
- m = @commands[com]
919
- m = com unless m
920
- return __send__("cmd_#{m.to_s}")
921
- end
922
- parse_symbol_command(com)
923
- end
924
-
925
- def parse_mathfont(font)
926
- f = @font
927
- @font = font
928
- begin
929
- push_container(Row.new){|r| r << parse_any}
930
- ensure
931
- @font = f
932
- end
933
- end
934
-
935
- def parse_group
936
- font = @font
937
- begin
938
- g = @group_begins[@scanner[1]]
939
- g = @scanner[1] unless g
940
- __send__("grp_#{g.to_s}")
941
- ensure
942
- @font = font
943
- end
944
- end
945
- end
946
-
947
- module BuiltinCommands
948
- OVERS = {'hat'=>'circ', 'breve'=>'smile', 'grave'=>'grave',
949
- 'acute'=>'acute', 'dot'=>'sdot', 'ddot'=>'nldr', 'tilde'=>'tilde',
950
- 'bar'=>'macr', 'vec'=>'rightarrow', 'check'=>'vee', 'widehat'=>'circ',
951
- 'overline'=>'macr', 'widetilde'=>'tilde', 'overbrace'=>'OverBrace'}
952
- UNDERS = {'underbrace'=>'UnderBrace', 'underline'=>'macr'}
953
-
954
- def initialize
955
- add_commands("\\"=>:backslash)
956
- add_commands("entity", "stackrel", "frac", "sqrt", "mbox")
957
- add_multi_command(:hat_etc, 'hat', 'breve', 'grave', 'acute', 'dot', 'ddot', 'tilde', 'bar', 'vec', 'check', 'widehat', 'overline', 'widetilde', 'overbrace')
958
- add_multi_command(:underbrace_etc, 'underbrace', 'underline')
959
- add_multi_command(:quad_etc, "quad", "qquad", ",", ":", ";")
960
- add_multi_command(:it_etc, "it", "rm", "bf")
961
- add_multi_command(:mathit_etc, "mathit", "mathrm", "mathbf", "bm", "mathbb", "mathscr", "mathfrak")
962
- add_sym_cmd(SymbolCommands)
963
- add_delimiter(Delimiters)
964
-
965
- super
966
- end
967
-
968
- def cmd_backslash
969
- @ds ? nil : XMLElement.new("br", "xmlns"=>"http://www.w3.org/1999/xhtml")
970
- end
971
-
972
- def cmd_hat_etc
973
- com = @scanner[1]
974
- Over.new(parse_any, Operator.new << entitize(OVERS[com]))
975
- end
976
-
977
- def cmd_underbrace_etc
978
- com = @scanner[1]
979
- Under.new(parse_any, Operator.new << entitize(UNDERS[com]))
980
- end
981
-
982
- def cmd_entity
983
- param = @scanner.scan_block ? @scanner[1] : @scanner.scan(/./)
984
- raise ParseError.new("Need parameter.") unless param
985
- unless @unsecure_entity || @entities[param]
986
- param =@scanner.matched[/\A\{#{RE::SPACE}*(.*\})\z/, 1] if @scanner.matched=~RE::BLOCK
987
- @scanner.pos = @scanner.pos-(param.size)
988
- raise ParseError.new("Unregistered entity.")
989
- end
990
- Operator.new << entitize(param)
991
- end
992
-
993
- def cmd_stackrel
994
- o = parse_any; b = parse_any
995
- Over.new(b, o)
996
- end
997
-
998
- def cmd_quad_etc
999
- case @scanner[1]
1000
- when 'quad'
1001
- Space.new("1em")
1002
- when 'qquad'
1003
- Space.new("2em")
1004
- when ','
1005
- Space.new("0.167em")
1006
- when ':'
1007
- Space.new("0.222em")
1008
- when ';'
1009
- Space.new("0.278em")
1010
- end
1011
- end
1012
-
1013
- def cmd_it_etc
1014
- case @scanner[1]
1015
- when 'it'
1016
- @font = Font::NORMAL
1017
- when 'rm'
1018
- @font = Font::ROMAN
1019
- when 'bf'
1020
- @font = Font::BOLD
1021
- end
1022
- nil
1023
- end
1024
-
1025
- def cmd_mathit_etc
1026
- case @scanner[1]
1027
- when 'mathit'
1028
- parse_mathfont(Font::NORMAL)
1029
- when 'mathrm'
1030
- parse_mathfont(Font::ROMAN)
1031
- when 'mathbf'
1032
- parse_mathfont(Font::BOLD)
1033
- when 'bm'
1034
- parse_mathfont(Font::BOLD_ITALIC)
1035
- when 'mathbb'
1036
- parse_mathfont(Font::BLACKBOLD)
1037
- when 'mathscr'
1038
- parse_mathfont(Font::SCRIPT)
1039
- when 'mathfrak'
1040
- parse_mathfont(Font::FRAKTUR)
1041
- end
1042
- end
1043
-
1044
- def cmd_frac
1045
- n = parse_any; d = parse_any
1046
- Frac.new(n, d)
1047
- end
1048
-
1049
- def cmd_sqrt
1050
- if @scanner.scan_option
1051
- i = parse_into(@scanner[1], Array.new)
1052
- i = i.size==1 ? i[0] : (Row.new << i)
1053
- b = parse_any
1054
- Root.new(i, b)
1055
- else
1056
- Sqrt.new << parse_any
1057
- end
1058
- end
1059
-
1060
- def cmd_mbox
1061
- @scanner.scan_any
1062
- Text.new << (@scanner.matched =~ RE::BLOCK ? @scanner[1] : @scanner.matched)
1063
- end
1064
- end
1065
-
1066
- module BuiltinGroups
1067
- class CircularReferenceEnvironment < StandardError; end
1068
-
1069
- def initialize
1070
- add_group("begin", "end")
1071
- add_group("left", "right", :left_etc)
1072
- add_group("bigg", "bigg", :left_etc)
1073
- @environments = Hash.new
1074
-
1075
- super
1076
- end
1077
-
1078
- def add_environment(*a)
1079
- @environments = Hash.new unless @environments
1080
- if a.size==1 && Hash===a[0]
1081
- @environments.merge!(hash)
1082
- else
1083
- a.each{|i| @environments[i] = false}
1084
- end
1085
- end
1086
-
1087
- def grp_begin
1088
- matched = @scanner.matched
1089
- begin_pos = @scanner.pos-matched.size
1090
- en = @scanner.scan_block ? @scanner[1] : @scanner.scan_any
1091
- raise ParseError.new('Environment name not exist.') unless en
1092
-
1093
- macro = @macro.environments(en)
1094
- if macro
1095
- begin
1096
- flg = @expanded_environment.include?(en)
1097
- @expanded_environment.push(en)
1098
- raise CircularReferenceEnvironment if flg
1099
-
1100
- pos = @scanner.pos
1101
- option = (macro.option && @scanner.scan_option) ? @scanner[1] : nil
1102
- params = Array.new
1103
- (1..macro.num).each do
1104
- params << (@scanner.scan_block ? @scanner[1] : @scanner.scan_any)
1105
- raise ParseError.new("Need more parameter.") unless params.last
1106
- end
1107
- body = ""
1108
- grpnest = 0
1109
- until @scanner.peek_command=="end" && grpnest==0
1110
- if @scanner.eos?
1111
- @scanner.pos = pos
1112
- raise ParseError.new('Matching \end not exist.')
1113
- end
1114
- com = @scanner.peek_command
1115
- grpnest += 1 if @group_begins.has_key?(com)
1116
- grpnest -=1 if @group_ends.has_key?(com) && @group_begins[com]
1117
- raise ParseError.new("Syntax error.") if grpnest<0
1118
-
1119
- body << @scanner.scan_any(true)
1120
- end
1121
- @scanner.scan_command
1122
- raise ParseError.new("Environment mismatched.", @scanner.matched) unless en==(@scanner.scan_block ? @scanner[1] : @scanner.scan_any)
1123
- begin
1124
- return parse_into(@macro.expand_environment(en, body, params, option), Array.new)
1125
- rescue CircularReferenceEnvironment
1126
- if @expanded_environment.size>1
1127
- raise
1128
- else
1129
- @scanner.pos = begin_pos
1130
- raise ParseError.new("Circular reference.")
1131
- end
1132
- rescue ParseError => e
1133
- if @expanded_environment.size>1
1134
- raise
1135
- else
1136
- @scanner.pos = begin_pos
1137
- raise ParseError.new(%[Error in macro(#{e.message} "#{e.rest.strip}").])
1138
- end
1139
- end
1140
- ensure
1141
- @expanded_environment.pop
1142
- end
1143
- end
1144
-
1145
- raise ParseError.new("Undefined environment.") unless @environments.has_key?(en)
1146
- e = @environments[en]
1147
- e = en unless e # default method name
1148
- __send__("env_#{e.to_s}")
1149
- end
1150
-
1151
- def grp_left_etc
1152
- right =
1153
- case @scanner[1]
1154
- when "left"
1155
- "right"
1156
- when "bigg"
1157
- "bigg"
1158
- end
1159
-
1160
- f = Fenced.new
1161
- p = @scanner.pos
1162
- o = @scanner.scan_any
1163
- raise ParseError.new('Need brace here.') unless o && (o=~RE::BRACES || @delimiters.include?(o[RE::COMMANDS, 1]))
1164
-
1165
- f.open = (o=~RE::BRACES ? o : parse_symbol_command(o[RE::COMMANDS, 1], true))
1166
- f << push_container(Row.new) do |r|
1167
- until @scanner.peek_command==right
1168
- if @scanner.eos?
1169
- @scanner.pos = p
1170
- raise ParseError.new('Brace not closed.')
1171
- end
1172
- r << parse_to_element(true)
1173
- end
1174
- end
1175
- @scanner.scan_command # skip right
1176
- c = @scanner.scan_any
1177
- raise ParseError.new('Need brace here.') unless c=~RE::BRACES || @delimiters.include?(c[RE::COMMANDS, 1])
1178
- f.close = (c=~RE::BRACES ? c : parse_symbol_command(c[RE::COMMANDS, 1], true))
1179
- f
1180
- end
1181
- end
1182
-
1183
- module BuiltinEnvironments
1184
- def initialize
1185
- add_environment("array", "matrix")
1186
-
1187
- super
1188
- end
1189
-
1190
- def env_array
1191
- layout = @scanner.scan_block ? @scanner.matched : @scanner.scan(/./)
1192
- l = Scanner.new(layout=~RE::BLOCK ? layout[RE::BLOCK, 1] : layout)
1193
- t = Table.new
1194
- aligns = Array.new
1195
- vlines = Array.new
1196
- vlined = l.check(/\|/)
1197
- columned = false
1198
- until l.eos?
1199
- c = l.scan_any
1200
- raise ParseError.new("Syntax error.", layout[/\A.*(#{Regexp.escape(c+l.rest)}.*\z)/m, 1]) unless c=~/[clr\|@]/
1201
-
1202
- if c=='|'
1203
- aligns << Align::CENTER if vlined
1204
- vlines << Line::SOLID
1205
- vlined = true
1206
- columned = false
1207
- else
1208
- vlines << Line::NONE if columned
1209
- vlined = false
1210
- columned = true
1211
- case c
1212
- when 'l'
1213
- aligns << Align::LEFT
1214
- when 'c'
1215
- aligns << Align::CENTER
1216
- when 'r'
1217
- aligns << Align::RIGHT
1218
- when '@'
1219
- aligns << Align::CENTER
1220
- l.scan_any
1221
- end
1222
- end
1223
- end
1224
- t.aligns = aligns
1225
- t.vlines = vlines
1226
-
1227
- layout = layout[RE::BLOCK, 1] if layout=~RE::BLOCK
1228
- raise ParseError.new('Need parameter here.') if layout==""
1229
-
1230
- hlines = Array.new
1231
- row_parsed = false
1232
- hlined = false
1233
- until @scanner.peek_command=="end"
1234
- raise ParseError.new('Matching \end not exist.') if @scanner.eos?
1235
- if @scanner.peek_command=="hline"
1236
- @scanner.scan_command
1237
- t << Tr.new unless row_parsed
1238
- hlines << Line::SOLID
1239
- row_parsed = false
1240
- hlined = true
1241
- else
1242
- hlines << Line::NONE if row_parsed
1243
- t << env_array_row(l.string)
1244
- @scanner.scan(RE::WBSLASH)
1245
- row_parsed = true
1246
- hlined = false
1247
- end
1248
- end
1249
- t.hlines = hlines
1250
-
1251
- if hlined
1252
- tr = Tr.new
1253
- (0..vlines.size).each {|i| tr << Td.new}
1254
- t << tr
1255
- end
1256
-
1257
- @scanner.scan_command
1258
- raise ParseError.new("Environment mismatched.") unless @scanner.check_block && @scanner[1]=="array"
1259
- @scanner.scan_block
1260
- t
1261
- end
1262
-
1263
- def env_array_row(layout)
1264
- l = Scanner.new(layout)
1265
- r = Tr.new
1266
- first_column = true
1267
- vlined = l.check(/\|/)
1268
- until l.eos?
1269
- c = l.scan(/./)
1270
- if c=='|'
1271
- r << Td.new if vlined
1272
- vlined = true
1273
- next
1274
- else
1275
- vlined = false
1276
- case c
1277
- when 'r', 'l', 'c'
1278
- when '@'
1279
- r << parse_into(l.scan_any, Td.new)
1280
- next
1281
- end
1282
- if first_column
1283
- first_column = false
1284
- else
1285
- raise ParseError.new("Need more column.", @scanner.matched.to_s) unless @scanner.scan(/&/)
1286
- end
1287
- r << push_container(Td.new) do |td|
1288
- td << parse_to_element(true) until @scanner.peek_command=="end" || @scanner.check(/(&|\\\\)/) || @scanner.eos?
1289
- end
1290
- end
1291
- end
1292
- r << Td.new if vlined
1293
- raise ParseError.new("Too many column.") if @scanner.check(/&/)
1294
- r
1295
- end
1296
-
1297
- def env_matrix
1298
- t = Table.new
1299
- hlines = Array.new
1300
- hlined = false
1301
- row_parsed = false
1302
- until @scanner.peek_command=="end"
1303
- raise ParseError.new('Matching \end not exist.') if @scanner.eos?
1304
- if @scanner.peek_command=="hline"
1305
- @scanner.scan_command
1306
- t << Tr.new unless row_parsed
1307
- hlines << Line::SOLID
1308
- row_parsed = false
1309
- hlined = true
1310
- else
1311
- hlines << Line::NONE if row_parsed
1312
- t << (r = Tr.new)
1313
- r << (td=Td.new)
1314
- until @scanner.check(RE::WBSLASH) || @scanner.peek_command=="end" || @scanner.eos?
1315
- push_container(td) do |e|
1316
- e << parse_to_element(true) until @scanner.peek_command=="end" || @scanner.check(/(&|\\\\)/) || @scanner.eos?
1317
- end
1318
- r << (td=Td.new) if @scanner.scan(/&/)
1319
- end
1320
- @scanner.scan(RE::WBSLASH)
1321
- row_parsed = true
1322
- hlined = false
1323
- end
1324
- end
1325
- t.hlines = hlines
1326
-
1327
- t << Tr.new if hlined
1328
-
1329
- raise ParseError.new("Need \\end{array}.") unless @scanner.peek_command=="end"
1330
- @scanner.scan_command
1331
- raise ParseError.new("Environment mismatched.") unless @scanner.check_block && @scanner[1]=="matrix"
1332
- @scanner.scan_block
1333
- t
1334
- end
1335
-
1336
- def env_matrix_row
1337
- r = Tr.new
1338
- until @scanner.check(RE::WBSLASH) || @scanner.peek_command=="end"
1339
- r << push_container(Td.new) do |td|
1340
- td << parse_to_element(true) until @scanner.peek_command=="end" || @scanner.check(/(&|\\\\)/) || @scanner.eos?
1341
- end
1342
- end
1343
-
1344
- end
1345
- end
1346
- end
1347
27
  end
1348
28
 
1349
- # Automatically generated constants
1350
- module MathML::LaTeX::BuiltinCommands
1351
- SymbolCommands={
1352
- "{"=>[:s,:o,""],
1353
- "}"=>[:s,:o,""],
1354
- "#"=>[:s,:o,""],
1355
- "$"=>[:s,:o,""],
1356
- "&"=>[:s,:o,:amp],
1357
- "_"=>[:s,:o,""],
1358
- "%"=>[:s,:o,""],
1359
- ","=>nil,
1360
- "varepsilon"=>[:s,:I],
1361
- "mathdollar"=>[:s,:o,"$"],
1362
- "lbrace"=>[:s],
1363
- "rbrace"=>[:s],
1364
- "P"=>[:s,:o,:para],
1365
- "mathparagraph"=>[:s,:o,:para],
1366
- "S"=>[:s,:o,:sect],
1367
- "mathsection"=>[:s,:o,:sect],
1368
- "dag"=>[:s,:o,:dagger],
1369
- "dagger"=>[:s],
1370
- "ddag"=>[:s,:o,:ddagger],
1371
- "ddagger"=>[:s],
1372
- "copyright"=>[:s,:o,:copy],
1373
- "pounds"=>[:s,:o,:pound],
1374
- "mathsterling"=>[:s,:o,:pound],
1375
- "dots"=>[:s,:o,:mldr],
1376
- "mathellipsis"=>[:s,:o,:mldr],
1377
- "ldots"=>[:s,:o,:mldr],
1378
- "ensuremath"=>nil,
1379
- "|"=>[:s,:o,:DoubleVerticalBar],
1380
- "mho"=>[:s],
1381
- "Join"=>[:s,:o,:bowtie],
1382
- "Box"=>[:s,:o,:square],
1383
- "Diamond"=>[:s],
1384
- "leadsto"=>[:s,:o,:zigrarr],
1385
- "sqsubset"=>[:s],
1386
- "sqsupset"=>[:s],
1387
- "lhd"=>[:s,:o,:vltri],
1388
- "unlhd"=>[:s,:o,:ltrie],
1389
- "rhd"=>[:s,:o,:vrtri],
1390
- "unrhd"=>[:s,:o,:rtrie],
1391
- "log"=>[:s,:i,""],
1392
- "lg"=>[:s,:i,""],
1393
- "ln"=>[:s,:i,""],
1394
- "lim"=>[:u,:i,""],
1395
- "limsup"=>[:u,:i,"lim sup"],
1396
- "liminf"=>[:u,:i,"lim inf"],
1397
- "sin"=>[:s,:i,""],
1398
- "arcsin"=>[:s,:i,""],
1399
- "sinh"=>[:s,:i,""],
1400
- "cos"=>[:s,:i,""],
1401
- "arccos"=>[:s,:i,""],
1402
- "cosh"=>[:s,:i,""],
1403
- "tan"=>[:s,:i,""],
1404
- "arctan"=>[:s,:i,""],
1405
- "tanh"=>[:s,:i,""],
1406
- "cot"=>[:s,:i,""],
1407
- "coth"=>[:s,:i,""],
1408
- "sec"=>[:s,:i,""],
1409
- "csc"=>[:s,:i,""],
1410
- "max"=>[:u,:i,""],
1411
- "min"=>[:u,:i,""],
1412
- "sup"=>[:u,:i,""],
1413
- "inf"=>[:u,:i,""],
1414
- "arg"=>[:s,:i,""],
1415
- "ker"=>[:s,:i,""],
1416
- "dim"=>[:s,:i,""],
1417
- "hom"=>[:s,:i,""],
1418
- "det"=>[:u,:i,""],
1419
- "exp"=>[:s,:i,""],
1420
- "Pr"=>[:u,:i,""],
1421
- "gcd"=>[:u,:i,""],
1422
- "deg"=>[:s,:i,""],
1423
- "prime"=>[:s],
1424
- "alpha"=>[:s,:I],
1425
- "beta"=>[:s,:I],
1426
- "gamma"=>[:s,:I],
1427
- "delta"=>[:s,:I],
1428
- "epsilon"=>[:s,:I],
1429
- "zeta"=>[:s,:I],
1430
- "eta"=>[:s,:I],
1431
- "theta"=>[:s,:I],
1432
- "iota"=>[:s,:I],
1433
- "kappa"=>[:s,:I],
1434
- "lambda"=>[:s,:I],
1435
- "mu"=>[:s,:I],
1436
- "nu"=>[:s,:I],
1437
- "xi"=>[:s,:I],
1438
- "pi"=>[:s,:I],
1439
- "rho"=>[:s,:I],
1440
- "sigma"=>[:s,:I],
1441
- "tau"=>[:s,:I],
1442
- "upsilon"=>[:s,:I],
1443
- "phi"=>[:s,:I],
1444
- "chi"=>[:s,:I],
1445
- "psi"=>[:s,:I],
1446
- "omega"=>[:s,:I],
1447
- "vartheta"=>[:s,:I],
1448
- "varpi"=>[:s,:I],
1449
- "varrho"=>[:s,:I],
1450
- "varsigma"=>[:s,:I],
1451
- "varphi"=>[:s,:I],
1452
- "Gamma"=>[:s,:i],
1453
- "Delta"=>[:s,:i],
1454
- "Theta"=>[:s,:i],
1455
- "Lambda"=>[:s,:i],
1456
- "Xi"=>[:s,:i],
1457
- "Pi"=>[:s,:i],
1458
- "Sigma"=>[:s,:i],
1459
- "Upsilon"=>[:s,:i,:Upsi],
1460
- "Phi"=>[:s,:i],
1461
- "Psi"=>[:s,:i],
1462
- "Omega"=>[:s,:i],
1463
- "aleph"=>[:s,:i],
1464
- "hbar"=>[:s,:i,:hslash],
1465
- "imath"=>[:s,:i],
1466
- "jmath"=>[:s,:i],
1467
- "ell"=>[:s],
1468
- "wp"=>[:s],
1469
- "Re"=>[:s,:i],
1470
- "Im"=>[:s,:i],
1471
- "partial"=>[:s,:o,:part],
1472
- "infty"=>[:s,:n,:infin],
1473
- "emptyset"=>[:s,:i,:empty],
1474
- "nabla"=>[:s,:i],
1475
- "surd"=>[:s,:o,:Sqrt],
1476
- "top"=>[:s],
1477
- "bot"=>[:s],
1478
- "angle"=>[:s],
1479
- "not"=>[:s],
1480
- "triangle"=>[:s],
1481
- "forall"=>[:s],
1482
- "exists"=>[:s,:o,:exist],
1483
- "neg"=>[:s,:o,:not],
1484
- "lnot"=>[:s,:o,:not],
1485
- "flat"=>[:s],
1486
- "natural"=>[:s],
1487
- "sharp"=>[:s],
1488
- "clubsuit"=>[:s],
1489
- "diamondsuit"=>[:s],
1490
- "heartsuit"=>[:s],
1491
- "spadesuit"=>[:s],
1492
- "coprod"=>[:u],
1493
- "bigvee"=>[:u],
1494
- "bigwedge"=>[:u],
1495
- "biguplus"=>[:u],
1496
- "bigcap"=>[:u],
1497
- "bigcup"=>[:u],
1498
- "intop"=>[:u,:o,:int],
1499
- "int"=>[:s,:o],
1500
- "prod"=>[:u],
1501
- "sum"=>[:u],
1502
- "bigotimes"=>[:u],
1503
- "bigoplus"=>[:u],
1504
- "bigodot"=>[:u],
1505
- "ointop"=>[:u,:o,:oint],
1506
- "oint"=>[:s],
1507
- "bigsqcup"=>[:u],
1508
- "smallint"=>[:u,:o,:int],
1509
- "triangleleft"=>[:s],
1510
- "triangleright"=>[:s],
1511
- "bigtriangleup"=>[:s],
1512
- "bigtriangledown"=>[:s],
1513
- "wedge"=>[:s],
1514
- "land"=>[:s,:o,:wedge],
1515
- "vee"=>[:s],
1516
- "lor"=>[:s,:o,:vee],
1517
- "cap"=>[:s],
1518
- "cup"=>[:s],
1519
- "sqcap"=>[:s],
1520
- "sqcup"=>[:s],
1521
- "uplus"=>[:s],
1522
- "amalg"=>[:s],
1523
- "diamond"=>[:s],
1524
- "bullet"=>[:s],
1525
- "wr"=>[:s],
1526
- "div"=>[:s],
1527
- "odot"=>[:s],
1528
- "oslash"=>[:s],
1529
- "otimes"=>[:s],
1530
- "ominus"=>[:s],
1531
- "oplus"=>[:s],
1532
- "mp"=>[:s],
1533
- "pm"=>[:s],
1534
- "circ"=>[:s,:o,:cir],
1535
- "bigcirc"=>[:s],
1536
- "setminus"=>[:s],
1537
- "cdot"=>[:s,:o,:sdot],
1538
- "ast"=>[:s],
1539
- "times"=>[:s],
1540
- "star"=>[:s],
1541
- "propto"=>[:s],
1542
- "sqsubseteq"=>[:s],
1543
- "sqsupseteq"=>[:s],
1544
- "parallel"=>[:s],
1545
- "mid"=>[:s],
1546
- "dashv"=>[:s],
1547
- "vdash"=>[:s],
1548
- "nearrow"=>[:s],
1549
- "searrow"=>[:s],
1550
- "nwarrow"=>[:s],
1551
- "swarrow"=>[:s],
1552
- "Leftrightarrow"=>[:s],
1553
- "Leftarrow"=>[:s],
1554
- "Rightarrow"=>[:s],
1555
- "neq"=>[:s,:o,:ne],
1556
- "ne"=>[:s],
1557
- "leq"=>[:s],
1558
- "le"=>[:s],
1559
- "geq"=>[:s],
1560
- "ge"=>[:s],
1561
- "succ"=>[:s],
1562
- "prec"=>[:s],
1563
- "approx"=>[:s],
1564
- "succeq"=>[:s,:o,:sccue],
1565
- "preceq"=>[:s,:o,:prcue],
1566
- "supset"=>[:s],
1567
- "subset"=>[:s],
1568
- "supseteq"=>[:s],
1569
- "subseteq"=>[:s],
1570
- "in"=>[:s],
1571
- "ni"=>[:s],
1572
- "owns"=>[:s,:o,:ni],
1573
- "gg"=>[:s],
1574
- "ll"=>[:s],
1575
- "leftrightarrow"=>[:s],
1576
- "leftarrow"=>[:s],
1577
- "gets"=>[:s,:o,:leftarrow],
1578
- "rightarrow"=>[:s],
1579
- "to"=>[:s,:o,:rightarrow],
1580
- "mapstochar"=>[:s,:o,:vdash],
1581
- "mapsto"=>[:s],
1582
- "sim"=>[:s],
1583
- "simeq"=>[:s],
1584
- "perp"=>[:s],
1585
- "equiv"=>[:s],
1586
- "asymp"=>[:s],
1587
- "smile"=>[:s],
1588
- "frown"=>[:s],
1589
- "leftharpoonup"=>[:s],
1590
- "leftharpoondown"=>[:s],
1591
- "rightharpoonup"=>[:s],
1592
- "rightharpoondown"=>[:s],
1593
- "cong"=>[:s],
1594
- "notin"=>[:s],
1595
- "rightleftharpoons"=>[:s],
1596
- "doteq"=>[:s],
1597
- "joinrel"=>nil,
1598
- "relbar"=>[:s,:o,"-"],
1599
- "Relbar"=>[:s,:o,"="],
1600
- "lhook"=>[:s,:o,:sub],
1601
- "hookrightarrow"=>[:s],
1602
- "rhook"=>[:s,:o,:sup],
1603
- "hookleftarrow"=>[:s],
1604
- "bowtie"=>[:s],
1605
- "models"=>[:s],
1606
- "Longrightarrow"=>[:s],
1607
- "longrightarrow"=>[:s],
1608
- "longleftarrow"=>[:s],
1609
- "Longleftarrow"=>[:s],
1610
- "longmapsto"=>[:s,:o,:mapsto],
1611
- "longleftrightarrow"=>[:s],
1612
- "Longleftrightarrow"=>[:s],
1613
- "iff"=>[:s],
1614
- "ldotp"=>[:s,:o,"."],
1615
- "cdotp"=>[:s,:o,:cdot],
1616
- "colon"=>[:s],
1617
- "cdots"=>[:s,:o,:ctdot],
1618
- "vdots"=>[:s,:o,:vellip],
1619
- "ddots"=>[:s,:o,:dtdot],
1620
- "braceld"=>[:s,:o,0x25dc],
1621
- "bracerd"=>[:s,:o,0x25dd],
1622
- "bracelu"=>[:s,:o,0x25df],
1623
- "braceru"=>[:s,:o,0x25de],
1624
- "lmoustache"=>[:s],
1625
- "rmoustache"=>[:s],
1626
- "arrowvert"=>[:s,:o,:vert],
1627
- "Arrowvert"=>[:s,:o,:DoubleVerticalBar],
1628
- "Vert"=>[:s,:o,:DoubleVerticalBar],
1629
- "vert"=>[:s],
1630
- "uparrow"=>[:s],
1631
- "downarrow"=>[:s],
1632
- "updownarrow"=>[:s],
1633
- "Uparrow"=>[:s],
1634
- "Downarrow"=>[:s],
1635
- "Updownarrow"=>[:s],
1636
- "backslash"=>[:s,:o,"\\"],
1637
- "rangle"=>[:s],
1638
- "langle"=>[:s],
1639
- "rceil"=>[:s],
1640
- "lceil"=>[:s],
1641
- "rfloor"=>[:s],
1642
- "lfloor"=>[:s],
1643
- "lgroup"=>[:s,:o,0x2570],
1644
- "rgroup"=>[:s,:o,0x256f],
1645
- "bracevert"=>[:s,:o,:vert],
1646
- "mathunderscore"=>[:s,:o,"_"],
1647
- "square"=>[:s],
1648
- "rightsquigarrow"=>[:s],
1649
- "lozenge"=>[:s],
1650
- "vartriangleright"=>[:s],
1651
- "vartriangleleft"=>[:s],
1652
- "trianglerighteq"=>[:s],
1653
- "trianglelefteq"=>[:s],
1654
- "boxdot"=>[:s,:o,:dotsquare],
1655
- "boxplus"=>[:s],
1656
- "boxtimes"=>[:s],
1657
- "blacksquare"=>[:s],
1658
- "centerdot"=>[:s],
1659
- "blacklozenge"=>[:s],
1660
- "circlearrowright"=>[:s],
1661
- "circlearrowleft"=>[:s],
1662
- "leftrightharpoons"=>[:s],
1663
- "boxminus"=>[:s],
1664
- "Vdash"=>[:s],
1665
- "Vvdash"=>[:s],
1666
- "vDash"=>[:s],
1667
- "twoheadrightarrow"=>[:s],
1668
- "twoheadleftarrow"=>[:s],
1669
- "leftleftarrows"=>[:s],
1670
- "rightrightarrows"=>[:s],
1671
- "upuparrows"=>[:s],
1672
- "downdownarrows"=>[:s],
1673
- "upharpoonright"=>[:s],
1674
- "restriction"=>[:s,:o,:upharpoonright],
1675
- "downharpoonright"=>[:s],
1676
- "upharpoonleft"=>[:s],
1677
- "downharpoonleft"=>[:s],
1678
- "rightarrowtail"=>[:s],
1679
- "leftarrowtail"=>[:s],
1680
- "leftrightarrows"=>[:s],
1681
- "rightleftarrows"=>[:s],
1682
- "Lsh"=>[:s],
1683
- "Rsh"=>[:s],
1684
- "leftrightsquigarrow"=>[:s],
1685
- "looparrowleft"=>[:s],
1686
- "looparrowright"=>[:s],
1687
- "circeq"=>[:s],
1688
- "succsim"=>[:s],
1689
- "gtrsim"=>[:s],
1690
- "gtrapprox"=>[:s],
1691
- "multimap"=>[:s],
1692
- "therefore"=>[:s],
1693
- "because"=>[:s],
1694
- "doteqdot"=>[:s],
1695
- "Doteq"=>[:s,:o,:doteqdot],
1696
- "triangleq"=>[:s],
1697
- "precsim"=>[:s],
1698
- "lesssim"=>[:s],
1699
- "lessapprox"=>[:s],
1700
- "eqslantless"=>[:s],
1701
- "eqslantgtr"=>[:s],
1702
- "curlyeqprec"=>[:s],
1703
- "curlyeqsucc"=>[:s],
1704
- "preccurlyeq"=>[:s],
1705
- "leqq"=>[:s],
1706
- "leqslant"=>[:s,:o,:leq],
1707
- "lessgtr"=>[:s],
1708
- "backprime"=>[:s],
1709
- "risingdotseq"=>[:s],
1710
- "fallingdotseq"=>[:s],
1711
- "succcurlyeq"=>[:s],
1712
- "geqq"=>[:s],
1713
- "geqslant"=>[:s,:o,:geq],
1714
- "gtrless"=>[:s],
1715
- "bigstar"=>[:s],
1716
- "between"=>[:s],
1717
- "blacktriangledown"=>[:s],
1718
- "blacktriangleright"=>[:s],
1719
- "blacktriangleleft"=>[:s],
1720
- "vartriangle"=>[:s,:o,:triangle],
1721
- "blacktriangle"=>[:s],
1722
- "triangledown"=>[:s],
1723
- "eqcirc"=>[:s],
1724
- "lesseqgtr"=>[:s],
1725
- "gtreqless"=>[:s],
1726
- "lesseqqgtr"=>[:s],
1727
- "gtreqqless"=>[:s],
1728
- "Rrightarrow"=>[:s],
1729
- "Lleftarrow"=>[:s],
1730
- "veebar"=>[:s],
1731
- "barwedge"=>[:s],
1732
- "doublebarwedge"=>[:s],
1733
- "measuredangle"=>[:s],
1734
- "sphericalangle"=>[:s,:o,:angsph],
1735
- "varpropto"=>[:s],
1736
- "smallsmile"=>[:s,:o,:smile],
1737
- "smallfrown"=>[:s,:o,:frown],
1738
- "Subset"=>[:s],
1739
- "Supset"=>[:s],
1740
- "Cup"=>[:s],
1741
- "doublecup"=>[:s,:o,:Cup],
1742
- "Cap"=>[:s],
1743
- "doublecap"=>[:s,:o,:Cap],
1744
- "curlywedge"=>[:s],
1745
- "curlyvee"=>[:s],
1746
- "leftthreetimes"=>[:s],
1747
- "rightthreetimes"=>[:s],
1748
- "subseteqq"=>[:s],
1749
- "supseteqq"=>[:s],
1750
- "bumpeq"=>[:s],
1751
- "Bumpeq"=>[:s],
1752
- "lll"=>[:s,:o,:Ll],
1753
- "llless"=>[:s,:o,:Ll],
1754
- "ggg"=>[:s],
1755
- "gggtr"=>[:s,:o,:ggg],
1756
- "circledS"=>[:s],
1757
- "pitchfork"=>[:s],
1758
- "dotplus"=>[:s],
1759
- "backsim"=>[:s],
1760
- "backsimeq"=>[:s],
1761
- "complement"=>[:s],
1762
- "intercal"=>[:s],
1763
- "circledcirc"=>[:s],
1764
- "circledast"=>[:s],
1765
- "circleddash"=>[:s],
1766
- "lvertneqq"=>[:s,:o,:lneqq],
1767
- "gvertneqq"=>[:s,:o,:gneqq],
1768
- "nleq"=>[:s,:o,0x2270],
1769
- "ngeq"=>[:s,:o,0x2271],
1770
- "nless"=>[:s],
1771
- "ngtr"=>[:s],
1772
- "nprec"=>[:s],
1773
- "nsucc"=>[:s],
1774
- "lneqq"=>[:s],
1775
- "gneqq"=>[:s],
1776
- "nleqslant"=>[:s],
1777
- "ngeqslant"=>[:s],
1778
- "lneq"=>[:s],
1779
- "gneq"=>[:s],
1780
- "npreceq"=>[:s,:o,:nprcue],
1781
- "nsucceq"=>[:s,:o,:nsccue],
1782
- "precnsim"=>[:s],
1783
- "succnsim"=>[:s],
1784
- "lnsim"=>[:s],
1785
- "gnsim"=>[:s],
1786
- "nleqq"=>[:s],
1787
- "ngeqq"=>[:s],
1788
- "precneqq"=>[:s,:o,"<mfrac linethickness='0' mathsize='1%'><mo>&prec;</mo><mo>&ne;</mo></mfrac>"],
1789
- "succneqq"=>[:s,:o,"<mfrac linethickness='0' mathsize='1%'><mo>&succ;</mo><mo>&ne;</mo></mfrac>"],
1790
- "precnapprox"=>[:s],
1791
- "succnapprox"=>[:s],
1792
- "lnapprox"=>[:s,:o,"<mfrac linethickness='0' mathsize='1%'><mo>&lt;</mo><mo>&nap;</mo></mfrac>"],
1793
- "gnapprox"=>[:s,:o,"<mfrac linethickness='0' mathsize='1%'><mo>&gt;</mo><mo>&nap;</mo></mfrac>"],
1794
- "nsim"=>[:s],
1795
- "ncong"=>[:s],
1796
- "diagup"=>[:s,:o,0x2571],
1797
- "diagdown"=>[:s,:o,0x2572],
1798
- "varsubsetneq"=>[:s,:o,:subsetneq],
1799
- "varsupsetneq"=>[:s,:o,:supsetneq],
1800
- "nsubseteqq"=>[:s],
1801
- "nsupseteqq"=>[:s],
1802
- "subsetneqq"=>[:s],
1803
- "supsetneqq"=>[:s],
1804
- "varsubsetneqq"=>[:s,:o,:subsetneqq],
1805
- "varsupsetneqq"=>[:s,:o,:supsetneqq],
1806
- "subsetneq"=>[:s],
1807
- "supsetneq"=>[:s],
1808
- "nsubseteq"=>[:s],
1809
- "nsupseteq"=>[:s],
1810
- "nparallel"=>[:s],
1811
- "nmid"=>[:s],
1812
- "nshortmid"=>[:s,:o,:nmid],
1813
- "nshortparallel"=>[:s,:o,:nparallel],
1814
- "nvdash"=>[:s],
1815
- "nVdash"=>[:s],
1816
- "nvDash"=>[:s],
1817
- "nVDash"=>[:s],
1818
- "ntrianglerighteq"=>[:s],
1819
- "ntrianglelefteq"=>[:s],
1820
- "ntriangleleft"=>[:s],
1821
- "ntriangleright"=>[:s],
1822
- "nleftarrow"=>[:s],
1823
- "nrightarrow"=>[:s],
1824
- "nLeftarrow"=>[:s],
1825
- "nRightarrow"=>[:s],
1826
- "nLeftrightarrow"=>[:s],
1827
- "nleftrightarrow"=>[:s],
1828
- "divideontimes"=>[:s],
1829
- "varnothing"=>[:s],
1830
- "nexists"=>[:s],
1831
- "Finv"=>[:s,:o,0x2132],
1832
- "Game"=>[:s,:o,"G"],
1833
- "eth"=>[:s],
1834
- "eqsim"=>[:s],
1835
- "beth"=>[:s],
1836
- "gimel"=>[:s],
1837
- "daleth"=>[:s],
1838
- "lessdot"=>[:s],
1839
- "gtrdot"=>[:s],
1840
- "ltimes"=>[:s],
1841
- "rtimes"=>[:s],
1842
- "shortmid"=>[:s,:o,:mid],
1843
- "shortparallel"=>[:s],
1844
- "smallsetminus"=>[:s,:o,:setminus],
1845
- "thicksim"=>[:s,:o,:sim],
1846
- "thickapprox"=>[:s,:o,:approx],
1847
- "approxeq"=>[:s],
1848
- "succapprox"=>[:s],
1849
- "precapprox"=>[:s],
1850
- "curvearrowleft"=>[:s],
1851
- "curvearrowright"=>[:s],
1852
- "digamma"=>[:s],
1853
- "varkappa"=>[:s],
1854
- "Bbbk"=>[:s,:i,:kopf],
1855
- "hslash"=>[:s],
1856
- "backepsilon"=>[:s],
1857
- "ulcorner"=>[:s,:o,:boxdr],
1858
- "urcorner"=>[:s,:o,:boxdl],
1859
- "llcorner"=>[:s,:o,:boxur],
1860
- "lrcorner"=>[:s,:o,:boxul],
1861
- }
1862
- Delimiters=[
1863
- "lmoustache",
1864
- "rmoustache",
1865
- "arrowvert",
1866
- "Arrowvert",
1867
- "Vert",
1868
- "vert",
1869
- "uparrow",
1870
- "downarrow",
1871
- "updownarrow",
1872
- "Uparrow",
1873
- "Downarrow",
1874
- "Updownarrow",
1875
- "backslash",
1876
- "rangle",
1877
- "langle",
1878
- "rbrace",
1879
- "lbrace",
1880
- "rceil",
1881
- "lceil",
1882
- "rfloor",
1883
- "lfloor",
1884
- "lgroup",
1885
- "rgroup",
1886
- "bracevert",
1887
- "ulcorner",
1888
- "urcorner",
1889
- "llcorner",
1890
- "lrcorner",
1891
- "{",
1892
- "|",
1893
- "}",
1894
- ]
1895
- end
1896
-
1897
- end
29
+ require "math_ml/element"
30
+ require "math_ml/symbol/entity_reference"
31
+ require "math_ml/latex"