isodoc 1.5.3 → 1.5.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '084d4f07e708055ffd6bdd9b3a7aef78e9b437b5938cb3a0594f9a5f44dae6bd'
4
- data.tar.gz: 046f4c2c521c1a3a13a502369229df28e3aa64eb4319eb2dc8761127d473f918
3
+ metadata.gz: 8da1e26ad7132ffa08da0fcea2d5690591d195fed192f9de480f142045526f00
4
+ data.tar.gz: 6f7790baee1639e89aa09f8234a17dd024cac0a9d47ad95039f2caa273264d94
5
5
  SHA512:
6
- metadata.gz: b7d440fc7f367c502b4b9fe61faa41b1c2ed3f189edaae426777f849217f98a81fb27fbd7facdbf5051b50a7bea6c23d88b5adcbecb48ea92502b6bb81c0672f
7
- data.tar.gz: 27cfead9b111414f1dd384869707cd6e55db06680574d6035c203019272e435ee0c6c616114867531384715be89024e1647faf6743d053c196d5e447b7d1b29e
6
+ metadata.gz: 5f72f7cbc23636918dade5e52ceb6e1115cdd018b4a051ffd965162d11c081b6e7dfcafe04cf583373e55d5f2262d4393823497b7a5ed4a0a8d248dc5c1574a6
7
+ data.tar.gz: 249e6bb5247039595870c52969c49bc4acbb40a1dcae798a4f925ab6fa5ea4640a22a8defdd60ad64134159a21f26088268324ce2381f00aa79db673ffcb3695
@@ -50,4 +50,4 @@ jobs:
50
50
  token: ${{ secrets.METANORMA_CI_PAT_TOKEN || secrets.GITHUB_TOKEN }}
51
51
  repository: ${{ github.repository }}
52
52
  event-type: notify
53
- client-payload: '{"ref": "${{ github.ref }}", "sha": "${{ github.sha }}"}'
53
+ client-payload: '{"ref": "${{ github.ref }}", "sha": "${{ github.sha }}"}'
@@ -205,5 +205,9 @@ module IsoDoc::Function
205
205
  !(node["format"].split(/,/).include? @format.to_s)
206
206
  out.passthrough node.text
207
207
  end
208
+
209
+ def svg_parse(node, out)
210
+ out << node.to_xml
211
+ end
208
212
  end
209
213
  end
@@ -225,6 +225,7 @@ module IsoDoc::Function
225
225
  when "passthrough" then passthrough_parse(node, out)
226
226
  when "amend" then amend_parse(node, out)
227
227
  when "tab" then clausedelimspace(out) # in Presentation XML only
228
+ when "svg" then svg_parse(node, out) # introduced in Presentation XML only
228
229
  else
229
230
  error_parse(node, out)
230
231
  end
@@ -1,3 +1,5 @@
1
+ require "base64"
2
+
1
3
  module IsoDoc
2
4
  class PresentationXMLConvert < ::IsoDoc::Convert
3
5
  def lower2cap(s)
@@ -6,9 +8,8 @@ module IsoDoc
6
8
  end
7
9
 
8
10
  def figure(docxml)
9
- docxml.xpath(ns("//figure")).each do |f|
10
- figure1(f)
11
- end
11
+ docxml.xpath(ns("//image")).each { |f| svg_extract(f) }
12
+ docxml.xpath(ns("//figure")).each { |f| figure1(f) }
12
13
  docxml.xpath(ns("//svgmap")).each do |s|
13
14
  if f = s.at(ns("./figure")) then s.replace(f)
14
15
  else
@@ -17,9 +18,14 @@ module IsoDoc
17
18
  end
18
19
  end
19
20
 
21
+ def svg_extract(f)
22
+ return unless %r{^data:image/svg\+xml;base64,}.match(f["src"])
23
+ svg = Base64.strict_decode64(f["src"].sub(%r{^data:image/svg\+xml;base64,}, ""))
24
+ f.replace(svg.sub(/<\?xml[^>]*>/, ""))
25
+ end
26
+
20
27
  def figure1(f)
21
- return sourcecode1(f) if f["class"] == "pseudocode" ||
22
- f["type"] == "pseudocode"
28
+ return sourcecode1(f) if f["class"] == "pseudocode" || f["type"] == "pseudocode"
23
29
  return if labelled_ancestor(f) && f.ancestors("figure").empty?
24
30
  return if f.at(ns("./figure")) and !f.at(ns("./name"))
25
31
  lbl = @xrefs.anchor(f['id'], :label, false) or return
@@ -1,4 +1,6 @@
1
1
  require "twitter_cldr"
2
+ require "bigdecimal"
3
+ require_relative "../../twitter-cldr/patch"
2
4
 
3
5
  module IsoDoc
4
6
  class PresentationXMLConvert < ::IsoDoc::Convert
@@ -10,8 +12,7 @@ module IsoDoc
10
12
  if node["citeas"].nil? && node["bibitemid"]
11
13
  return @xrefs.anchor(node["bibitemid"] ,:xref) || "???"
12
14
  elsif node["target"] && node["droploc"]
13
- return @xrefs.anchor(node["target"], :value) ||
14
- @xrefs.anchor(node["target"], :label) ||
15
+ return @xrefs.anchor(node["target"], :value) || @xrefs.anchor(node["target"], :label) ||
15
16
  @xrefs.anchor(node["target"], :xref) || "???"
16
17
  elsif node["target"] && !/.#./.match(node["target"])
17
18
  linkend = anchor_linkend1(node)
@@ -22,9 +23,8 @@ module IsoDoc
22
23
  def anchor_linkend1(node)
23
24
  linkend = @xrefs.anchor(node["target"], :xref)
24
25
  container = @xrefs.anchor(node["target"], :container, false)
25
- (container && get_note_container_id(node) != container &&
26
- @xrefs.get[node["target"]]) &&
27
- linkend = prefix_container(container, linkend, node["target"])
26
+ (container && get_note_container_id(node) != container && @xrefs.get[node["target"]]) &&
27
+ linkend = prefix_container(container, linkend, node["target"])
28
28
  capitalise_xref(node, linkend)
29
29
  end
30
30
 
@@ -35,13 +35,11 @@ module IsoDoc
35
35
  return linkend if linkend[0,1].match(/\p{Upper}/)
36
36
  prec = nearest_block_parent(node).xpath("./descendant-or-self::text()") &
37
37
  node.xpath("./preceding::text()")
38
- (prec.empty? || /(?!<[^.].)\.\s+$/.match(prec.map { |p| p.text }.join)) ?
39
- linkend&.capitalize : linkend
38
+ (prec.empty? || /(?!<[^.].)\.\s+$/.match(prec.map { |p| p.text }.join)) ? linkend&.capitalize : linkend
40
39
  end
41
40
 
42
41
  def nearest_block_parent(node)
43
- until %w(p title td th name formula
44
- li dt dd sourcecode pre).include?(node.name)
42
+ until %w(p title td th name formula li dt dd sourcecode pre).include?(node.name)
45
43
  node = node.parent
46
44
  end
47
45
  node
@@ -89,8 +87,7 @@ module IsoDoc
89
87
  def eref_localities0(r, i, target, delim)
90
88
  if r["type"] == "whole" then l10n("#{delim} #{@i18n.wholeoftext}")
91
89
  else
92
- eref_localities1(target, r["type"], r.at(ns("./referenceFrom")),
93
- r.at(ns("./referenceTo")), delim, @lang)
90
+ eref_localities1(target, r["type"], r.at(ns("./referenceFrom")), r.at(ns("./referenceTo")), delim, @lang)
94
91
  end
95
92
  end
96
93
 
@@ -106,8 +103,7 @@ module IsoDoc
106
103
  # TODO: move to localization file
107
104
  def eref_localities1(target, type, from, to, delim, lang = "en")
108
105
  return "" if type == "anchor"
109
- lang == "zh" and
110
- return l10n(eref_localities1_zh(target, type, from, to, delim))
106
+ lang == "zh" and return l10n(eref_localities1_zh(target, type, from, to, delim))
111
107
  ret = delim
112
108
  loc = @i18n.locality[type] || type.sub(/^locality:/, "").capitalize
113
109
  ret += " #{loc}"
@@ -163,23 +159,23 @@ module IsoDoc
163
159
  # TwitterCldr::DataReaders::NumberDataReader.new(locale).symbols
164
160
  def localize_maths(f, locale)
165
161
  f.xpath(".//m:mn", MATHML).each do |x|
166
- num = /\./.match(x.text) ? x.text.to_f : x.text.to_i
162
+ num = BigDecimal(x.text)
167
163
  precision = /\./.match(x.text) ? x.text.sub(/^.*\./, "").size : 0
168
164
  x.children = localized_number(num, locale, precision)
169
165
  end
170
166
  end
171
167
 
172
- # By itself twiiter cldr does not support fraction part digits grouping
168
+ # By itself twitter-cldr does not support fraction part digits grouping
173
169
  # and custom delimeter, will decorate fraction part manually
174
170
  def localized_number(num, locale, precision)
175
- localized = precision == 0 ? num.localize(locale).to_s :
171
+ TwitterCldr::Localized::LocalizedNumber.localize(BigDecimal)
172
+ localized = (precision == 0) ? num.localize(locale).to_s :
176
173
  num.localize(locale).to_decimal.to_s(:precision => precision)
177
174
  twitter_cldr_reader_symbols = twitter_cldr_reader(locale)
178
175
  return localized unless twitter_cldr_reader_symbols[:decimal]
179
176
  integer, fraction = localized.split(twitter_cldr_reader_symbols[:decimal])
180
177
  return localized if fraction.nil? || fraction.length.zero?
181
- [integer, decorate_fraction_part(fraction, locale)].
182
- join(twitter_cldr_reader_symbols[:decimal])
178
+ [integer, decorate_fraction_part(fraction, locale)].join(twitter_cldr_reader_symbols[:decimal])
183
179
  end
184
180
 
185
181
  def decorate_fraction_part(fract, locale)
@@ -229,8 +225,7 @@ module IsoDoc
229
225
  end
230
226
 
231
227
  def variant1(node)
232
- if (!node["lang"] || node["lang"] == @lang) &&
233
- (!node["script"] || node["script"] == @script)
228
+ if (!node["lang"] || node["lang"] == @lang) && (!node["script"] || node["script"] == @script)
234
229
  elsif found_matching_variant_sibling(node)
235
230
  node["remove"] = "true"
236
231
  else
@@ -243,8 +238,7 @@ module IsoDoc
243
238
  foll = node.xpath("./following-sibling::xmlns:variant")
244
239
  found = false
245
240
  (prev + foll).each do |n|
246
- found = true if n["lang"] == @lang &&
247
- (!n["script"] || n["script"] == @script)
241
+ found = true if n["lang"] == @lang && (!n["script"] || n["script"] == @script)
248
242
  end
249
243
  found
250
244
  end
@@ -1,3 +1,3 @@
1
1
  module IsoDoc
2
- VERSION = "1.5.3".freeze
2
+ VERSION = "1.5.4".freeze
3
3
  end
@@ -22,6 +22,12 @@ module IsoDoc::WordFunction
22
22
  end
23
23
  end
24
24
 
25
+ def svg_parse(node, out)
26
+ svg = Base64.strict_encode64(node.to_xml)
27
+ r = node.replace("<img src='data:image/svg+xml;base64,#{svg}' mimetype='image/svg+xml'/>").first
28
+ image_parse(r, out, nil)
29
+ end
30
+
25
31
  def imgsrc(node)
26
32
  ret = svg_to_emf(node) and return ret
27
33
  return node["src"] unless %r{^data:}.match node["src"]
@@ -0,0 +1,39 @@
1
+ module ::TwitterCldr
2
+ module Formatters
3
+ class NumberFormatter
4
+ def parse_number(number, options = {})
5
+ precision = options[:precision] || precision_from(number)
6
+ rounding = options[:rounding] || 0
7
+ if number.is_a? BigDecimal
8
+ number = precision == 0 ?
9
+ round_to(number, precision, rounding).abs.fix.to_s("F") :
10
+ round_to(number, precision, rounding).abs.round(precision).to_s("F")
11
+ else
12
+ number = "%.#{precision}f" % round_to(number, precision, rounding).abs
13
+ end
14
+ number.split(".")
15
+ end
16
+
17
+ def round_to(number, precision, rounding = 0)
18
+ factor = 10 ** precision
19
+ result = number.is_a?(BigDecimal) ?
20
+ ((number * factor).fix / factor) :
21
+ ((number * factor).round.to_f / factor)
22
+ if rounding > 0
23
+ rounding = rounding.to_f / factor
24
+ result = number.is_a?(BigDecimal) ?
25
+ ((result * (1.0 / rounding)).fix / (1.0 / rounding)) :
26
+ ((result * (1.0 / rounding)).round.to_f / (1.0 / rounding))
27
+ end
28
+ result
29
+ end
30
+
31
+ def precision_from(num)
32
+ return 0 if num.is_a?(BigDecimal) && num.fix == num
33
+ parts = (num.is_a?(BigDecimal) ? num.to_s("F") : num.to_s ).split(".")
34
+ parts.size == 2 ? parts[1].size : 0
35
+ end
36
+ end
37
+ end
38
+ end
39
+
@@ -768,6 +768,93 @@ B</pre>
768
768
  expect(xmlpp(strip_guid(IsoDoc::WordConvert.new({}).convert("test", presxml, true).gsub(/['"][^'".]+\.(gif|xml)['"]/, "'_.\\1'").gsub(/mso-bookmark:_Ref\d+/, "mso-bookmark:_Ref")))).to be_equivalent_to xmlpp(word)
769
769
  end
770
770
 
771
+ it "processes SVG" do
772
+ input = <<~INPUT
773
+ <iso-standard xmlns="http://riboseinc.com/isoxml">
774
+ <preface><foreword>
775
+ <figure id="figureA-1">
776
+ <image src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMDAgMTAwIj4KICA8Y2lyY2xlIGZpbGw9IiMwMDkiIHI9IjQ1IiBjeD0iNTAiIGN5PSI1MCIvPgogIDxwYXRoIGQ9Ik0zMywyNkg3OEEzNywzNywwLDAsMSwzMyw4M1Y1N0g1OVY0M0gzM1oiIGZpbGw9IiNGRkYiLz4KPC9zdmc+Cg==" id="_d3731866-1a07-435a-a6c2-1acd41023a4e" mimetype="image/svg+xml" height="auto" width="auto"/>
777
+ </figure>
778
+ </foreword></preface>
779
+ </iso-standard>
780
+ INPUT
781
+
782
+ presxml = <<~OUTPUT
783
+ <iso-standard xmlns='http://riboseinc.com/isoxml' type='presentation'>
784
+ <preface>
785
+ <foreword>
786
+ <figure id='figureA-1'>
787
+ <name>Figure 1</name>
788
+ <svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'>
789
+ <circle fill='#009' r='45' cx='50' cy='50'/>
790
+ <path d='M33,26H78A37,37,0,0,1,33,83V57H59V43H33Z' fill='#FFF'/>
791
+ </svg>
792
+ </figure>
793
+ </foreword>
794
+ </preface>
795
+ </iso-standard>
796
+ OUTPUT
797
+
798
+ html = <<~HTML
799
+ #{HTML_HDR}
800
+ <br/>
801
+ <div>
802
+ <h1 class='ForewordTitle'>Foreword</h1>
803
+ <div id='figureA-1' class='figure'>
804
+ <svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'>
805
+ <circle fill='#009' r='45' cx='50' cy='50'/>
806
+ <path d='M33,26H78A37,37,0,0,1,33,83V57H59V43H33Z' fill='#FFF'/>
807
+ </svg>
808
+ <p class='FigureTitle' style='text-align:center;'>Figure 1</p>
809
+ </div>
810
+ </div>
811
+ <p class='zzSTDTitle1'/>
812
+ </div>
813
+ </body>
814
+ </html>
815
+ HTML
816
+
817
+ doc = <<~DOC
818
+ <html xmlns:epub='http://www.idpf.org/2007/ops' lang='en'>
819
+ <head>
820
+ <style>
821
+ </style>
822
+ </head>
823
+ <body lang='EN-US' link='blue' vlink='#954F72'>
824
+ <div class='WordSection1'>
825
+ <p>&#160;</p>
826
+ </div>
827
+ <p>
828
+ <br clear='all' class='section'/>
829
+ </p>
830
+ <div class='WordSection2'>
831
+ <p>
832
+ <br clear='all' style='mso-special-character:line-break;page-break-before:always'/>
833
+ </p>
834
+ <div>
835
+ <h1 class='ForewordTitle'>Foreword</h1>
836
+ <div id='figureA-1' class='figure'>
837
+ <img src='_.emf'/>
838
+ <p class='FigureTitle' style='text-align:center;'>Figure 1</p>
839
+ </div>
840
+ </div>
841
+ <p>&#160;</p>
842
+ </div>
843
+ <p>
844
+ <br clear='all' class='section'/>
845
+ </p>
846
+ <div class='WordSection3'>
847
+ <p class='zzSTDTitle1'/>
848
+ </div>
849
+ </body>
850
+ </html>
851
+ DOC
852
+
853
+ expect(xmlpp(IsoDoc::PresentationXMLConvert.new({}).convert("test", input, true).gsub(/\&lt;/, "&#x3c;"))).to be_equivalent_to xmlpp(presxml)
854
+ expect(xmlpp(strip_guid(IsoDoc::HtmlConvert.new({}).convert("test", presxml, true)))).to be_equivalent_to xmlpp(html)
855
+ expect(xmlpp(strip_guid(IsoDoc::WordConvert.new({}).convert("test", presxml, true).gsub(/['"][^'".]+(?<!odf1)(?<!odf)\.emf['"]/, "'_.emf'").gsub(/['"][^'".]+\.(gif|xml)['"]/, "'_.\\1'")))).to be_equivalent_to xmlpp(doc)
856
+ end
857
+
771
858
  it "converts SVG (Word)" do
772
859
  FileUtils.rm_rf "spec/assets/odf1.emf"
773
860
  expect(xmlpp(strip_guid(IsoDoc::WordConvert.new({}).convert("test", <<~"INPUT", true).gsub(/['"][^'".]+(?<!odf1)(?<!odf)\.emf['"]/, "'_.emf'").gsub(/['"][^'".]+\.(gif|xml)['"]/, "'_.\\1'").gsub(/mso-bookmark:_Ref\d+/, "mso-bookmark:_Ref")))).to be_equivalent_to xmlpp(<<~"OUTPUT")
@@ -25,7 +25,10 @@ it "localises numbers in MathML" do
25
25
  <title language="en">test</title>
26
26
  </bibdata>
27
27
  <preface>
28
- <p><stem type="MathML"><math xmlns="http://www.w3.org/1998/Math/MathML"><mn>30000</mn></math></stem>
28
+ <p>
29
+ <stem type="MathML"><math xmlns="http://www.w3.org/1998/Math/MathML"><mn>64212149677264515</mn></math></stem>
30
+ <stem type="MathML"><math xmlns="http://www.w3.org/1998/Math/MathML"><mn>642121496772645.15</mn></math></stem>
31
+ <stem type="MathML"><math xmlns="http://www.w3.org/1998/Math/MathML"><mn>30000</mn></math></stem>
29
32
  <stem type="MathML"><math xmlns="http://www.w3.org/1998/Math/MathML"><mi>P</mi><mfenced open="(" close=")"><mrow><mi>X</mi><mo>≥</mo><msub><mrow><mi>X</mi></mrow><mrow><mo>max</mo></mrow></msub></mrow></mfenced><mo>=</mo><munderover><mrow><mo>∑</mo></mrow><mrow><mrow><mi>j</mi><mo>=</mo><msub><mrow><mi>X</mi></mrow><mrow><mo>max</mo></mrow></msub></mrow></mrow><mrow><mn>1000</mn></mrow></munderover><mfenced open="(" close=")"><mtable><mtr><mtd><mn>1000</mn></mtd></mtr><mtr><mtd><mi>j</mi></mtd></mtr></mtable></mfenced><msup><mrow><mi>p</mi></mrow><mrow><mi>j</mi></mrow></msup><msup><mrow><mfenced open="(" close=")"><mrow><mn>1</mn><mo>−</mo><mi>p</mi></mrow></mfenced></mrow><mrow><mrow><mn>1.003</mn><mo>−</mo><mi>j</mi></mrow></mrow></msup></math></stem></p>
30
33
  </preface>
31
34
  </iso-standard>
@@ -37,7 +40,8 @@ it "localises numbers in MathML" do
37
40
 
38
41
  <preface>
39
42
  <p>
40
- 30,000
43
+ 64,212,149,677,264,515
44
+ 642,121,496,772,645.15 30,000
41
45
  <stem type='MathML'>
42
46
  <math xmlns='http://www.w3.org/1998/Math/MathML'>
43
47
  <mi>P</mi>
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: isodoc
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.3
4
+ version: 1.5.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-02-22 00:00:00.000000000 Z
11
+ date: 2021-03-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: asciimath
@@ -418,6 +418,7 @@ files:
418
418
  - lib/isodoc/xref/xref_gen_seq.rb
419
419
  - lib/isodoc/xref/xref_sect_gen.rb
420
420
  - lib/isodoc/xslfo_convert.rb
421
+ - lib/twitter-cldr/patch.rb
421
422
  - spec/assets/header.html
422
423
  - spec/assets/html.scss
423
424
  - spec/assets/htmlcover.html