asciimath 2.0.0 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9854257261efca821e14c559add910c54fe4902cac3b5670f9af6c2fde09f168
4
- data.tar.gz: a92201a108b0ebafb364e5b619a9edfcdde7c9bbea1facc58d5302d9d4d44c36
3
+ metadata.gz: d4492ccf2978a02b79bf6d5a70a23871fd33db6893e4a90b1b159db3b4d7b8b3
4
+ data.tar.gz: 43fbc1d2bba388ca359e0e908e0118b22189479cc05bf4a9882cb6459b4c6488
5
5
  SHA512:
6
- metadata.gz: d20e388ca4ecdf4823361833276033b7b8c003a3b8324515e0d5c36457c790996f3b344380cee5b7d61f259ccf893eb176bc944481a3f4d254055edf35ef0d4f
7
- data.tar.gz: f38c5f8c4fa8af496e6aabdf147afe29b4de39eedab4266ba33392284b4ec6dc588ece0ca3fa6cd9c743174fdd66c10cdf376e8949b2498146046877a10957d7
6
+ metadata.gz: 60c01de3ce18dd8eec2ff1a1fa559da2e0de840e08b59686ab3d1ff913a02f2656f2d8ceee1106657ae99bf9de2fdb2f80eeef1f71cc604845541d9d503f7bed
7
+ data.tar.gz: 62e0c29f76f709c53b040260dee1e36dce9af4c8737822297ea9d1908b2c72ade763d236c36266c411ce8f7330fbf397d4f0877ac2d5fc80d9064c40920bcbee
@@ -0,0 +1,16 @@
1
+ /.idea/
2
+ /.bundle/
3
+ /.yardoc
4
+ /Gemfile.lock
5
+ /_yardoc/
6
+ /coverage/
7
+ /doc/
8
+ /pkg/
9
+ /spec/reports/
10
+ /tmp/
11
+ *.bundle
12
+ *.so
13
+ *.o
14
+ *.a
15
+ *.iml
16
+ mkmf.log
@@ -0,0 +1,16 @@
1
+ language: ruby
2
+ cache:
3
+ apt: true
4
+ directories:
5
+ - vendor/bundle
6
+ - $HOME/.cache/pip
7
+ rvm:
8
+ - 2.3
9
+ - 2.4
10
+ - 2.5
11
+ - jruby
12
+ - truffleruby
13
+ before_install:
14
+ - type bundle || gem install bundler --version '~> 1.0'
15
+ install:
16
+ - bundle install --path vendor/bundle --jobs=3 --retry=3
@@ -1,5 +1,16 @@
1
1
  = Asciimath Changelog
2
2
 
3
+ == 2.0.1
4
+
5
+ Enhancements::
6
+
7
+ * Issue #40: add `ker` as standard symbol (@GarkGarcia)
8
+ * Issue #46: allow customisation of the parsing and rendering symbol tables (@GarkGarcia)
9
+
10
+ Bug fixes::
11
+
12
+ * Issue #48: fix parsing of single column matrices (@ronaldtse)
13
+
3
14
  == 2.0.0
4
15
 
5
16
  Enhancements::
@@ -72,4 +83,4 @@ Enhancements::
72
83
 
73
84
  Initial release::
74
85
 
75
- * An AsciiMath parser and MathML converter written in Ruby
86
+ * An AsciiMath parser and MathML converter written in Ruby
@@ -87,6 +87,45 @@ asciimath latex "an asciimath string"
87
87
 
88
88
  This command will print out the generated code on stdout.
89
89
 
90
+ ## Extentions and Customization
91
+
92
+ The parser can be extended by passing a custum tokenization table:
93
+
94
+ [source, ruby]
95
+ ----
96
+ my_tokens_table = AsciiMath::SymbolTableBuilder.new
97
+ AsciiMath::Parser.add_default_parser_symbols(my_tokens_table)
98
+ my_tokens_table.add('mysymbol', :mysymbol, :symbol)
99
+
100
+ AsciiMath::parse("a + mysymbol + b", my_tokens_table.build)
101
+ ----
102
+
103
+ Furthermore, the behaviour of the tokenizer be customized by altering the value
104
+ associated with a token in `AsciiMath::Tokenizer::DEFAULT_PARSE_SYMBOL_TABLE`:
105
+
106
+ [source, ruby]
107
+ ----
108
+ my_tokens_table = AsciiMath::SymbolTableBuilder.new
109
+ AsciiMath::Parser.add_default_parser_symbols(my_tokens_table)
110
+ my_tokens_table.add('alpha', :beta, :symbol)
111
+
112
+ # Now "alpha + beta" is equivalent to "beta + beta"
113
+ AsciiMath::parse("alpha + beta", my_tokens_table.build)
114
+ ----
115
+
116
+ The same behaviour applies to each individual render (`MathMLBuilder`,
117
+ `HTMLBuilder` and `LatexBuilder`). By adding entries to a rendere's rendering
118
+ table (or modifying exisisting entries), users can customize it's output:
119
+
120
+ [source, ruby]
121
+ ----
122
+ my_rendering_table = AsciiMath::SymbolTableBuilder.new
123
+ AsciiMath::MarkupBuilder.add_default_display_symbols(my_rendering_table)
124
+ my_rendering_table.add('alpha', '\u03b2', :identifier)
125
+
126
+ # Now "alpha + beta" is equivalent to "beta + beta"
127
+ AsciiMath::parse("alpha + beta").to_mathml(my_rendering_table.build)
128
+ ----
90
129
 
91
130
  ## Notes on the HTML Output
92
131
 
@@ -3,7 +3,6 @@ lib = File.expand_path('../lib', __FILE__)
3
3
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
4
 
5
5
  require 'asciimath/version'
6
- require 'rake/file_list'
7
6
 
8
7
  Gem::Specification.new do |spec|
9
8
  spec.name = "asciimath"
@@ -15,8 +14,7 @@ Gem::Specification.new do |spec|
15
14
  spec.homepage = ""
16
15
  spec.license = "MIT"
17
16
 
18
- spec.files = Rake::FileList['**/*'].exclude(*File.read('.gitignore').split)
19
- .exclude('dump_symbol_table.rb')
17
+ spec.files = `git ls-files -z`.split("\x0")
20
18
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
21
19
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
22
20
  spec.require_paths = ["lib"]
@@ -0,0 +1,46 @@
1
+ require_relative 'lib/asciimath'
2
+
3
+ def escape_adoc(adoc)
4
+ case adoc
5
+ when nil
6
+ ''
7
+ when '+'
8
+ adoc
9
+ else
10
+ "++#{adoc.gsub('|', '\\|')}++"
11
+ end
12
+ end
13
+
14
+ puts "|==="
15
+ puts '|AsciiMath |Symbol |MathML Value |LaTeX Value'
16
+ puts
17
+
18
+ AsciiMath::Parser::DEFAULT_PARSER_SYMBOL_TABLE.each_pair do |asciimath, value|
19
+ sym = value[:value]
20
+ unless sym.is_a?(Symbol)
21
+ next
22
+ end
23
+
24
+ mathml = AsciiMath::MathMLBuilder::DEFAULT_DISPLAY_SYMBOL_TABLE[sym]
25
+
26
+ if mathml
27
+ val = mathml[:value]
28
+ else
29
+ val = "Missing!!!!!"
30
+ end
31
+
32
+ latex = AsciiMath::LatexBuilder::SYMBOLS[sym] || "\\#{sym.to_s}"
33
+
34
+ codepoint = ""
35
+ if val.is_a?(String)
36
+ codepoint = val.codepoints.map do |cp|
37
+ cpstr = sprintf('U+%04X', cp)
38
+ "https://codepoints.net/#{cpstr}[#{cpstr}]"
39
+ end.join(' ')
40
+ end
41
+
42
+ puts "|#{escape_adoc(asciimath)} |:#{sym.to_s} |#{escape_adoc(val.to_s)} (#{codepoint}) |#{escape_adoc(latex)}"
43
+ end
44
+
45
+ puts "|==="
46
+ puts
@@ -2,8 +2,11 @@ require_relative 'ast'
2
2
 
3
3
  module AsciiMath
4
4
  class LatexBuilder
5
- def initialize
5
+ attr_reader :symbol_table
6
+
7
+ def initialize(symbol_table = nil)
6
8
  @latex = ''
9
+ @symbol_table = symbol_table.nil? ? DEFAULT_DISPLAY_SYMBOL_TABLE : symbol_table
7
10
  end
8
11
 
9
12
  def to_s
@@ -14,12 +17,8 @@ module AsciiMath
14
17
  append(expression)
15
18
  self
16
19
  end
17
-
18
- private
19
-
20
- SPECIAL_CHARACTERS = [?&, ?%, ?$, ?#, ?_, ?{, ?}, ?~, ?^, ?[, ?]].map(&:ord)
21
-
22
- SYMBOLS = {
20
+
21
+ DEFAULT_DISPLAY_SYMBOL_TABLE = {
23
22
  :plus => ?+,
24
23
  :minus => ?-,
25
24
  :ast => ?*,
@@ -97,7 +96,11 @@ module AsciiMath
97
96
  :bold_sans_serif => "\\mathsf",
98
97
  :sans_serif_italic => "\\mathsf",
99
98
  :sans_serif_bold_italic => "\\mathsf",
100
- }
99
+ }.freeze
100
+
101
+ private
102
+
103
+ SPECIAL_CHARACTERS = [?&, ?%, ?$, ?#, ?_, ?{, ?}, ?~, ?^, ?[, ?]].map(&:ord)
101
104
 
102
105
  COLOURS = {
103
106
  [0xFF, 0xFF, 0xFF] => "white",
@@ -138,7 +141,7 @@ module AsciiMath
138
141
  end
139
142
 
140
143
  when AsciiMath::AST::Symbol
141
- @latex << symbol(expression.value)
144
+ @latex << resolve_symbol(expression.value)
142
145
 
143
146
  when AsciiMath::AST::Identifier
144
147
  append_escaped(expression.value)
@@ -229,7 +232,7 @@ module AsciiMath
229
232
  end
230
233
 
231
234
  else
232
- @latex << symbol(op)
235
+ @latex << resolve_symbol(op)
233
236
 
234
237
  curly do
235
238
  append(expression.operand1)
@@ -259,7 +262,7 @@ module AsciiMath
259
262
  end
260
263
 
261
264
  def macro(macro, *args)
262
- @latex << symbol(macro)
265
+ @latex << resolve_symbol(macro)
263
266
 
264
267
  if args.length != 0
265
268
  @latex << "["
@@ -284,9 +287,9 @@ module AsciiMath
284
287
 
285
288
  if block_given?
286
289
  if l || r
287
- @latex << "\\left " << symbol(l) << " "
290
+ @latex << "\\left " << resolve_symbol(l) << " "
288
291
  yield self
289
- @latex << " \\right " << symbol(r)
292
+ @latex << " \\right " << resolve_symbol(r)
290
293
  else
291
294
  yield self
292
295
  end
@@ -294,12 +297,12 @@ module AsciiMath
294
297
  needs_left_right = !is_small(content)
295
298
 
296
299
  @latex << "\\left " if needs_left_right
297
- @latex << symbol(l) << " " if l or needs_left_right
300
+ @latex << resolve_symbol(l) << " " if l or needs_left_right
298
301
 
299
302
  append(content)
300
303
 
301
304
  @latex << " \\right" if needs_left_right
302
- @latex << " " << symbol(r) if r or needs_left_right
305
+ @latex << " " << resolve_symbol(r) if r or needs_left_right
303
306
  end
304
307
  end
305
308
 
@@ -333,8 +336,19 @@ module AsciiMath
333
336
  end
334
337
  end
335
338
 
336
- def symbol(s)
337
- SYMBOLS[s] || "\\#{s.to_s}"
339
+ def resolve_symbol(s)
340
+ symbol = @symbol_table[s]
341
+
342
+ case symbol
343
+ when String
344
+ return symbol
345
+ when Hash
346
+ return symbol[:value]
347
+ when nil
348
+ return "\\#{s.to_s}"
349
+ else
350
+ raise "Invalid entry in symbol table"
351
+ end
338
352
  end
339
353
 
340
354
  def is_small(e)
@@ -379,8 +393,8 @@ module AsciiMath
379
393
  end
380
394
 
381
395
  class Expression
382
- def to_latex
383
- LatexBuilder.new().append_expression(ast).to_s
396
+ def to_latex(symbol_table = nil)
397
+ LatexBuilder.new(symbol_table).append_expression(ast).to_s
384
398
  end
385
399
  end
386
400
  end
@@ -163,6 +163,7 @@ module AsciiMath
163
163
  b.add(:Ln, 'Ln', :identifier)
164
164
  b.add(:det, 'det', :identifier)
165
165
  b.add(:dim, 'dim', :identifier)
166
+ b.add(:ker, 'ker', :identifier)
166
167
  b.add(:mod, 'mod', :identifier)
167
168
  b.add(:gcd, 'gcd', :identifier)
168
169
  b.add(:lcm, 'lcm', :identifier)
@@ -475,4 +476,4 @@ module AsciiMath
475
476
  end
476
477
  end
477
478
  end
478
- end
479
+ end
@@ -385,6 +385,7 @@ module AsciiMath
385
385
  b.add('Ln', :Ln, :symbol)
386
386
  b.add('det', :det, :symbol)
387
387
  b.add('dim', :dim, :symbol)
388
+ b.add('ker', :ker, :symbol)
388
389
  b.add('mod', :mod, :symbol)
389
390
  b.add('gcd', :gcd, :symbol)
390
391
  b.add('lcm', :lcm, :symbol)
@@ -663,21 +664,21 @@ module AsciiMath
663
664
 
664
665
  row_content = row.expression
665
666
  unless row_content.is_a?(::AsciiMath::AST::Sequence)
666
- row_content = expression(row_content)
667
- end
668
-
669
- row_content.each do |item|
670
- if is_matrix_separator(item)
671
- chunks << current_chunk
672
- current_chunk = []
673
- else
674
- current_chunk << item
667
+ [expression(row_content)]
668
+ else
669
+ row_content.each do |item|
670
+ if is_matrix_separator(item)
671
+ chunks << current_chunk
672
+ current_chunk = []
673
+ else
674
+ current_chunk << item
675
+ end
675
676
  end
676
- end
677
677
 
678
- chunks << current_chunk
678
+ chunks << current_chunk
679
679
 
680
- chunks.map { |c| c.length == 1 ? c[0] : expression(*c) }.to_a
680
+ chunks.map { |c| c.length == 1 ? c[0] : expression(*c) }.to_a
681
+ end
681
682
  end
682
683
 
683
684
  return node unless rows.all? { |row| row.length == rows[0].length }
@@ -1,3 +1,3 @@
1
1
  module AsciiMath
2
- VERSION = "2.0.0"
2
+ VERSION = "2.0.1"
3
3
  end
@@ -141,4 +141,4 @@ module AsciiMath
141
141
  end
142
142
  end
143
143
  end
144
- end
144
+ end
@@ -0,0 +1,28 @@
1
+ #encoding: utf-8
2
+ require 'rspec'
3
+ require 'asciimath'
4
+ require_relative 'ast'
5
+
6
+ RSpec.configure do |c|
7
+ c.include ::AsciiMath::ASTHelper
8
+ end
9
+
10
+ describe 'AsciiMath::Parser', :variant => :ast do
11
+ it "should support custom symbols" do
12
+ my_tokens_table = AsciiMath::SymbolTableBuilder.new
13
+ AsciiMath::Parser.add_default_parser_symbols(my_tokens_table)
14
+ my_tokens_table.add('mysymbol', :mysymbol, :symbol)
15
+
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')))
18
+ end
19
+
20
+ it "should support replacing standard symbols" do
21
+ my_tokens_table = AsciiMath::SymbolTableBuilder.new
22
+ AsciiMath::Parser.add_default_parser_symbols(my_tokens_table)
23
+ my_tokens_table.add('+', :foo, :symbol)
24
+
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')))
27
+ end
28
+ end
@@ -1,7 +1,7 @@
1
1
  #encoding: utf-8
2
2
  require 'rspec'
3
3
  require 'asciimath'
4
- require 'ast'
4
+ require_relative 'ast'
5
5
  require 'nokogiri'
6
6
 
7
7
 
@@ -319,6 +319,13 @@ RSpec.shared_examples 'AsciiMath Examples' do
319
319
  :latex => '\\sum_{n = 0}^\\infty a_n',
320
320
  ))
321
321
 
322
+ example('((1),(42))', &should_generate(
323
+ :ast => matrix([%w[1], %w[42]]),
324
+ :mathml => '<math><mrow><mo>(</mo><mtable><mtr><mtd><mn>1</mn></mtd></mtr><mtr><mtd><mn>42</mn></mtd></mtr></mtable><mo>)</mo></mrow></math>',
325
+ :html => '<span class="math-inline"><span class="math-row"><span class="math-brace" style="font-size: 200%;">(</span><span class="math-matrix" style="grid-template-columns:repeat(1,1fr);grid-template-rows:repeat(2,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: 200%;">)</span></span></span>',
326
+ :latex => '\\left ( \\begin{matrix} 1 \\\\ 42 \\end{matrix} \\right )',
327
+ ))
328
+
322
329
  example('((1,2,3),(4,5,6),(7,8,9))', &should_generate(
323
330
  :ast => matrix([%w[1 2 3], %w[4 5 6], %w[7 8 9]]),
324
331
  :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>',
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.0
4
+ version: 2.0.1
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: 2020-05-13 00:00:00.000000000 Z
12
+ date: 2020-06-29 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -76,15 +76,17 @@ executables:
76
76
  extensions: []
77
77
  extra_rdoc_files: []
78
78
  files:
79
+ - ".gitignore"
80
+ - ".travis.yml"
79
81
  - AST.adoc
80
82
  - CHANGELOG.adoc
81
83
  - Gemfile
82
- - Gemfile.lock
83
84
  - LICENSE.txt
84
85
  - README.adoc
85
86
  - Rakefile
86
87
  - asciimath.gemspec
87
88
  - bin/asciimath
89
+ - dump_symbol_table.rb
88
90
  - lib/asciimath.rb
89
91
  - lib/asciimath/ast.rb
90
92
  - lib/asciimath/cli.rb
@@ -97,6 +99,7 @@ files:
97
99
  - lib/asciimath/symbol_table.rb
98
100
  - lib/asciimath/version.rb
99
101
  - spec/ast.rb
102
+ - spec/customisation_spec.rb
100
103
  - spec/parser_spec.rb
101
104
  - spec/schema/mathml2/common/common-attribs.xsd
102
105
  - spec/schema/mathml2/common/math.xsd
@@ -153,12 +156,14 @@ required_rubygems_version: !ruby/object:Gem::Requirement
153
156
  - !ruby/object:Gem::Version
154
157
  version: '0'
155
158
  requirements: []
156
- rubygems_version: 3.0.3
159
+ rubyforge_project:
160
+ rubygems_version: 2.7.6
157
161
  signing_key:
158
162
  specification_version: 4
159
163
  summary: AsciiMath parser and converter
160
164
  test_files:
161
165
  - spec/ast.rb
166
+ - spec/customisation_spec.rb
162
167
  - spec/parser_spec.rb
163
168
  - spec/schema/mathml2/common/common-attribs.xsd
164
169
  - spec/schema/mathml2/common/math.xsd
@@ -1,39 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- asciimath (2.0.0.next1)
5
-
6
- GEM
7
- remote: https://rubygems.org/
8
- specs:
9
- diff-lcs (1.3)
10
- mini_portile2 (2.4.0)
11
- nokogiri (1.10.9)
12
- mini_portile2 (~> 2.4.0)
13
- rake (13.0.1)
14
- rspec (3.9.0)
15
- rspec-core (~> 3.9.0)
16
- rspec-expectations (~> 3.9.0)
17
- rspec-mocks (~> 3.9.0)
18
- rspec-core (3.9.2)
19
- rspec-support (~> 3.9.3)
20
- rspec-expectations (3.9.1)
21
- diff-lcs (>= 1.2.0, < 2.0)
22
- rspec-support (~> 3.9.0)
23
- rspec-mocks (3.9.1)
24
- diff-lcs (>= 1.2.0, < 2.0)
25
- rspec-support (~> 3.9.0)
26
- rspec-support (3.9.3)
27
-
28
- PLATFORMS
29
- ruby
30
-
31
- DEPENDENCIES
32
- asciimath!
33
- bundler (> 0)
34
- nokogiri (~> 1.10.9)
35
- rake (~> 13.0.0)
36
- rspec (~> 3.9.0)
37
-
38
- BUNDLED WITH
39
- 1.17.2