isodoc 1.3.1 → 1.5.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 29fb94d37c013e802491e2c1266e8b39d607ea3050f272f1a7bcd398e57c0283
4
- data.tar.gz: 85ea530071d54477f462d34a5b18dbf9ba500b71a4d5ea858b62530757a6b795
3
+ metadata.gz: 691e16d8f19de5c4008d22686af0f70594dea57d039e7d4e265763a02cc8eea3
4
+ data.tar.gz: 4aca2f6a4b06fa9c6dd3235ee8581e94060f47eb3fe8dc9de9a6b6aa5ee356f2
5
5
  SHA512:
6
- metadata.gz: 9539cdc3d0fac50a04aa3cdf93581016306b660f1d0681a8a1e06255ed839ac9362c887b9a6f0ef7480711122c5275e0936fab640efff76c84aaa5ad84831f84
7
- data.tar.gz: b05012f1f7189becfa14871de424ae5713a8791a9c0b520cdcca591d3f733d996c776d2f37d2c1ff23fdff6b2c146b6e09d2f9c5b97dcbeec43edafd9785dfcb
6
+ metadata.gz: 1ac28f83694610bab479de1bed5921c3d5807ab337dd2926555b66a7e5c1f5912c320a335089a4c7a617e816f1d8957bf923c986813e3374316ef472f825f7c2
7
+ data.tar.gz: d472986686451eab5674ce530a2a8fb2a82660d345280ae4ce57425c8920f135a789536ae4d0b05b952a8ea44efcaaf5122bc266cb6f17aee2fb6b4d79d1ca79
@@ -16,17 +16,17 @@ jobs:
16
16
  strategy:
17
17
  fail-fast: false
18
18
  matrix:
19
- ruby: [ '2.6', '2.5', '2.4' ]
19
+ ruby: [ '2.7', '2.6', '2.5', '2.4' ]
20
20
  os: [ ubuntu-latest, windows-latest, macos-latest ]
21
21
  experimental: [ false ]
22
22
  include:
23
- - ruby: '2.7'
23
+ - ruby: '3.0'
24
24
  os: 'ubuntu-latest'
25
25
  experimental: true
26
- - ruby: '2.7'
26
+ - ruby: '3.0'
27
27
  os: 'windows-latest'
28
28
  experimental: true
29
- - ruby: '2.7'
29
+ - ruby: '3.0'
30
30
  os: 'macos-latest'
31
31
  experimental: true
32
32
  steps:
@@ -35,35 +35,19 @@ jobs:
35
35
  - uses: ruby/setup-ruby@v1
36
36
  with:
37
37
  ruby-version: ${{ matrix.ruby }}
38
+ bundler-cache: true
38
39
 
39
- - uses: actions/cache@v2
40
- with:
41
- path: vendor/bundle
42
- key: bundle-${{ matrix.os }}-${{ matrix.ruby }}-${{ hashFiles('**/*.gemspec') }}
43
- restore-keys: bundle-${{ matrix.os }}-${{ matrix.ruby }}
44
-
45
- - run: bundle config set path 'vendor/bundle'
46
-
47
- - run: bundle install --jobs 4 --retry 3
48
-
49
- - name: Install Inkscape macOS
50
- if: matrix.os == 'macos-latest'
51
- run: |
52
- brew cask install inkscape
53
- inkscape --version
54
-
55
- - name: Install Inkscape Ubuntu
56
- if: matrix.os == 'ubuntu-latest'
57
- run: |
58
- sudo add-apt-repository ppa:inkscape.dev/stable
59
- sudo apt update
60
- sudo apt install inkscape
61
- inkscape --version
62
-
63
- - name: Install Inkscape Windows
64
- if: matrix.os == 'windows-latest'
65
- run: |
66
- choco install --no-progress -y inkscape
67
- inkscape --version
40
+ - uses: metanorma/metanorma-build-scripts/inkscape-setup-action@master
68
41
 
69
42
  - run: bundle exec rake
43
+
44
+ tests-passed:
45
+ needs: rake
46
+ runs-on: ubuntu-latest
47
+ steps:
48
+ - uses: peter-evans/repository-dispatch@v1
49
+ with:
50
+ token: ${{ secrets.METANORMA_CI_PAT_TOKEN || secrets.GITHUB_TOKEN }}
51
+ repository: ${{ github.repository }}
52
+ event-type: notify
53
+ client-payload: '{"ref": "${{ github.ref }}", "sha": "${{ github.sha }}"}'
data/isodoc.gemspec CHANGED
@@ -30,11 +30,11 @@ Gem::Specification.new do |spec|
30
30
 
31
31
  spec.add_dependency "asciimath"
32
32
  spec.add_dependency "htmlentities", "~> 4.3.4"
33
- spec.add_dependency "nokogiri", ">= 1.10.4"
33
+ spec.add_dependency "nokogiri", "~> 1.10.4"
34
34
  spec.add_dependency "thread_safe"
35
35
  spec.add_dependency "uuidtools"
36
36
  spec.add_dependency "html2doc", "~> 1.0.0"
37
- spec.add_dependency "liquid"
37
+ spec.add_dependency "liquid", "~> 4"
38
38
  spec.add_dependency "twitter_cldr"
39
39
  spec.add_dependency "roman-numerals"
40
40
  spec.add_dependency "metanorma", "~> 1.2.0"
@@ -50,4 +50,5 @@ Gem::Specification.new do |spec|
50
50
  spec.add_development_dependency "rubocop", "= 0.54.0"
51
51
  spec.add_development_dependency "simplecov", "~> 0.15"
52
52
  spec.add_development_dependency "timecop", "~> 0.9"
53
+ spec.add_development_dependency "rexml"
53
54
  end
@@ -97,3 +97,58 @@ locality: {
97
97
  note: Note,
98
98
  formula: Formula
99
99
  }
100
+ inflection:
101
+ Clause:
102
+ sg: Clause
103
+ pl: Clauses
104
+ Annex:
105
+ sg: Annex
106
+ pl: Annexes
107
+ Appendix:
108
+ sg: Appendix
109
+ pl: Appendixes
110
+ Note:
111
+ sg: Note
112
+ pl: Notes
113
+ "Note % to entry":
114
+ sg: Note % to entry
115
+ pl: Notes % to entry
116
+ List:
117
+ sg: List
118
+ pl: Lists
119
+ Figure:
120
+ sg: Figure
121
+ pl: Figures
122
+ Formula:
123
+ sg: Formula
124
+ pl: Formulas
125
+ Table:
126
+ sg: Table
127
+ pl: Tables
128
+ Requirement:
129
+ sg: Requirement
130
+ pl: Requirements
131
+ Recommendation:
132
+ sg: Recommendation
133
+ pl: Recommendations
134
+ Permission:
135
+ sg: Permission
136
+ pl: Permissions
137
+ Example:
138
+ sg: Example
139
+ pl: Examples
140
+ Part:
141
+ sg: Part
142
+ pl: Parts
143
+ Section:
144
+ sg: Section
145
+ pl: Sections
146
+ Paragraph:
147
+ sg: Paragraph
148
+ pl: Paragraphs
149
+ Chapter:
150
+ sg: Chapter
151
+ pl: Chapters
152
+ Page:
153
+ sg: Page
154
+ pl: Pages
@@ -90,3 +90,59 @@ locality: {
90
90
  note: Note,
91
91
  formula: Formule
92
92
  }
93
+ inflection:
94
+ Clause:
95
+ sg: Article
96
+ pl: Articles
97
+ Annex:
98
+ sg: Annexe
99
+ pl: Annexes
100
+ Appendix:
101
+ sg: Appendice
102
+ pl: Appendices
103
+ Note:
104
+ sg: Note
105
+ pl: Notes
106
+ "Note % à l’article":
107
+ sg: Note % à l’article
108
+ pl: Notes % à l’article
109
+ List:
110
+ sg: Liste
111
+ pl: Listes
112
+ Figure:
113
+ sg: Figure
114
+ pl: Figures
115
+ Formula:
116
+ sg: Formule
117
+ pl: Formules
118
+ Table:
119
+ sg: Tableau
120
+ pl: Tableaux
121
+ Requirement:
122
+ sg: Exigence
123
+ pl: Exigences
124
+ Recommendation:
125
+ sg: Recommandation
126
+ pl: Recommandations
127
+ Permission:
128
+ sg: Autorisation
129
+ pl: Autorisations
130
+ Example:
131
+ sg: Exemple
132
+ pl: Exemples
133
+ Part:
134
+ sg: Partie
135
+ pl: Parties
136
+ Section:
137
+ sg: Section
138
+ pl: Sections
139
+ Paragraph:
140
+ sg: Alinéa
141
+ pl: Alinéas
142
+ Chapter:
143
+ sg: Chapitre
144
+ pl: Chapitres
145
+ Page:
146
+ sg: Page
147
+ pl: Pages
148
+
@@ -9,6 +9,7 @@ module IsoDoc
9
9
  class Convert < ::IsoDoc::Common
10
10
  attr_accessor :options
11
11
  attr_accessor :i18n
12
+ attr_accessor :meta
12
13
 
13
14
  # htmlstylesheet: Generic stylesheet for HTML
14
15
  # wordstylesheet: Generic stylesheet for Word
@@ -157,7 +158,7 @@ module IsoDoc
157
158
  FileUtils.rm_rf dir
158
159
  end
159
160
 
160
- def middle_clause
161
+ def middle_clause(docxml = nil)
161
162
  "//clause[parent::sections][not(@type = 'scope')]"\
162
163
  '[not(descendant::terms)]'
163
164
  end
@@ -39,7 +39,7 @@ module IsoDoc::Function
39
39
  "uri[@type = 'citation']"))
40
40
  return href unless url
41
41
  href = suffix_url(url.text)
42
- anchor = node&.at(ns(".//locality[@type = 'anchor']"))&.text
42
+ anchor = node&.at(ns(".//locality[@type = 'anchor']"))&.text&.strip
43
43
  anchor and href += "##{anchor}"
44
44
  href
45
45
  end
@@ -71,5 +71,11 @@ module IsoDoc::Function
71
71
  node.children.each { |n| parse(n, e) }
72
72
  end
73
73
  end
74
+
75
+ def underline_parse(node, out)
76
+ out.u do |e|
77
+ node.children.each { |n| parse(n, e) }
78
+ end
79
+ end
74
80
  end
75
81
  end
@@ -56,7 +56,7 @@ module IsoDoc::Function
56
56
  end
57
57
 
58
58
  def clause(isoxml, out)
59
- isoxml.xpath(ns(middle_clause)).each do |c|
59
+ isoxml.xpath(ns(middle_clause(isoxml))).each do |c|
60
60
  out.div **attr_code(clause_attrs(c)) do |s|
61
61
  clause_name(nil, c&.at(ns("./title")), s, nil)
62
62
  c.elements.reject { |c1| c1.name == "title" }.each do |c1|
@@ -109,7 +109,7 @@ module IsoDoc::Function
109
109
  @meta.get
110
110
  end
111
111
 
112
- def middle_title(out)
112
+ def middle_title(_isoxml, out)
113
113
  out.p(**{ class: "zzSTDTitle1" }) { |p| p << @meta.get[:doctitle] }
114
114
  end
115
115
 
@@ -120,7 +120,7 @@ module IsoDoc::Function
120
120
  end
121
121
 
122
122
  def middle(isoxml, out)
123
- middle_title(out)
123
+ middle_title(isoxml, out)
124
124
  middle_admonitions(isoxml, out)
125
125
  i = scope isoxml, out, 0
126
126
  i = norm_ref isoxml, out, i
@@ -157,6 +157,7 @@ module IsoDoc::Function
157
157
  when "sub" then sub_parse(node, out)
158
158
  when "tt" then tt_parse(node, out)
159
159
  when "strike" then strike_parse(node, out)
160
+ when "underline" then underline_parse(node, out)
160
161
  when "keyword" then keyword_parse(node, out)
161
162
  when "smallcap" then smallcap_parse(node, out)
162
163
  when "br" then br_parse(node, out)
@@ -152,8 +152,8 @@ module IsoDoc::Function
152
152
  def populate_template(docxml, _format = nil)
153
153
  meta = @meta
154
154
  .get
155
- .merge(@labels || {})
156
- .merge(@meta.labels || {})
155
+ .merge(@labels ? {labels: @labels} : {})
156
+ .merge(@meta.labels ? {labels: @meta.labels} : {})
157
157
  .merge(fonts_options || {})
158
158
  template = liquid(docxml)
159
159
  template.render(meta.map { |k, v| [k.to_s, empty2nil(v)] }.to_h)
@@ -161,7 +161,7 @@ module IsoDoc::Function
161
161
  end
162
162
 
163
163
  def save_dataimage(uri, _relative_dir = true)
164
- %r{^data:image/(?<imgtype>[^;]+);base64,(?<imgdata>.+)$} =~ uri
164
+ %r{^data:(image|application)/(?<imgtype>[^;]+);base64,(?<imgdata>.+)$} =~ uri
165
165
  imgtype.sub!(/\+[a-z0-9]+$/, '') # svg+xml
166
166
  imgtype = 'png' unless /^[a-z0-9]+$/.match imgtype
167
167
  Tempfile.open(['image', ".#{imgtype}"]) do |f|
@@ -173,7 +173,7 @@ module IsoDoc::Function
173
173
  end
174
174
 
175
175
  def image_localfile(i)
176
- if /^data:image/.match? i['src']
176
+ if /^data:/.match? i['src']
177
177
  save_dataimage(i['src'], false)
178
178
  elsif %r{^([A-Z]:)?/}.match? i['src']
179
179
  i['src']
@@ -111,6 +111,12 @@ module IsoDoc::HtmlFunction
111
111
  sourcecode_name_parse(node, out, name)
112
112
  end
113
113
 
114
+ def underline_parse(node, out)
115
+ out.span **{ style: "text-decoration: underline;" } do |e|
116
+ node.children.each { |n| parse(n, e) }
117
+ end
118
+ end
119
+
114
120
  def table_long_strings_cleanup(docxml)
115
121
  end
116
122
  end
@@ -0,0 +1,82 @@
1
+ module IsoDoc
2
+ module HtmlFunction
3
+ # Class for recursively converting mathvariant text into plain text symbols
4
+ class MathvariantToPlain
5
+ MATHML = { "m" => "http://www.w3.org/1998/Math/MathML" }.freeze
6
+ MATHVARIANT_SPECIAL_CASE_MAPPINGS_1 = %w[bold italic sans-serif]
7
+ .permutation
8
+ .each_with_object(:sansbolditalic)
9
+ .map { |n, y| [n, y] }
10
+ .to_h
11
+ .freeze
12
+ MATHVARIANT_SPECIAL_CASE_MAPPINGS_2 = {
13
+ %w[bold fraktur] => :frakturbold,
14
+ %w[bold script] => :scriptbold,
15
+ %w[sans-serif bold] => :sansbold,
16
+ %w[sans-serif italic] => :sansitalic,
17
+ %w[sans-serif bold-italic] => :sansbolditalic,
18
+ %w[bold-sans-serif italic] => :sansbolditalic,
19
+ %w[sans-serif-italic bold] => :sansbolditalic,
20
+ }.freeze
21
+ MATHVARIANT_TO_PLANE_MAPPINGS = {
22
+ %w[double-struck] => :doublestruck,
23
+ %w[bold-fraktur] => :frakturbold,
24
+ %w[script] => :script,
25
+ %w[bold-script] => :scriptbold,
26
+ %w[fraktur] => :fraktur,
27
+ %w[sans-serif] => :sans,
28
+ %w[bold-sans-serif] => :sansbold,
29
+ %w[sans-serif-italic] => :sansitalic,
30
+ %w[sans-serif-bold-italic] => :sansbolditalic,
31
+ %w[monospace] => :monospace,
32
+ }.freeze
33
+
34
+ attr_reader :docxml
35
+
36
+ # @param [Nokogiri::Document] docxml
37
+ def initialize(docxml)
38
+ @docxml = docxml
39
+ end
40
+
41
+ def convert
42
+ docxml.xpath("//m:math", MATHML).each do |elem|
43
+ next if nothing_to_style(elem)
44
+ mathml1(elem)
45
+ end
46
+ docxml
47
+ end
48
+
49
+ private
50
+
51
+ def nothing_to_style(elem)
52
+ !elem.at("./*[@mathvariant][not(@mathvariant = 'normal')][not(@mathvariant = 'italic')]")
53
+ end
54
+
55
+ def mathml1(base_elem)
56
+ MATHVARIANT_SPECIAL_CASE_MAPPINGS_1
57
+ .merge(MATHVARIANT_SPECIAL_CASE_MAPPINGS_2)
58
+ .merge(MATHVARIANT_TO_PLANE_MAPPINGS)
59
+ .each_pair do |mathvariant_list, plain_font|
60
+ base_elem.xpath(mathvariant_xpath(mathvariant_list)).each do |elem|
61
+ toPlane(elem, plain_font)
62
+ end
63
+ end
64
+ end
65
+
66
+ def mathvariant_xpath(list)
67
+ list
68
+ .map { |variant| "//*[@mathvariant = '#{variant}']" }
69
+ .join
70
+ end
71
+
72
+ def toPlane(elem, font)
73
+ elem.traverse do |n|
74
+ next unless n.text?
75
+
76
+ n.replace(Plane1Converter.conv(HTMLEntities.new.decode(n.text), font))
77
+ end
78
+ elem
79
+ end
80
+ end
81
+ end
82
+ end
@@ -1,35 +1,47 @@
1
+ require "isodoc/html_function/mathvariant_to_plain"
2
+
1
3
  module IsoDoc::HtmlFunction
2
4
  module Html
3
- def postprocess(result, filename, dir)
5
+ def postprocess(result, filename, _dir)
4
6
  result = from_xhtml(cleanup(to_xhtml(textcleanup(result))))
5
7
  toHTML(result, filename)
6
8
  @files_to_delete.each { |f| FileUtils.rm_rf f }
7
9
  end
8
10
 
9
11
  def script_cdata(result)
10
- result.gsub(%r{<script([^>]*)>\s*<!\[CDATA\[}m, "<script\\1>").
11
- gsub(%r{\]\]>\s*</script>}, "</script>").
12
- gsub(%r{<!\[CDATA\[\s*<script([^>]*)>}m, "<script\\1>").
13
- gsub(%r{</script>\s*\]\]>}, "</script>")
12
+ result.gsub(%r{<script([^>]*)>\s*<!\[CDATA\[}m, "<script\\1>")
13
+ .gsub(%r{\]\]>\s*</script>}, "</script>")
14
+ .gsub(%r{<!\[CDATA\[\s*<script([^>]*)>}m, "<script\\1>")
15
+ .gsub(%r{</script>\s*\]\]>}, "</script>")
14
16
  end
15
17
 
16
18
  def toHTML(result, filename)
17
- result = (from_xhtml(html_cleanup(to_xhtml(result))))
18
- #result = populate_template(result, :html)
19
+ result = from_xhtml(html_cleanup(to_xhtml(result)))
20
+ # result = populate_template(result, :html)
19
21
  result = from_xhtml(move_images(to_xhtml(result)))
20
22
  result = html5(script_cdata(inject_script(result)))
21
23
  File.open(filename, "w:UTF-8") { |f| f.write(result) }
22
24
  end
23
25
 
24
26
  def html5(doc)
25
- doc.sub(%r{<!DOCTYPE html [^>]+>}, "<!DOCTYPE html>").
26
- sub(%r{<\?xml[^>]+>}, "")
27
+ doc.sub(%r{<!DOCTYPE html [^>]+>}, "<!DOCTYPE html>")
28
+ .sub(%r{<\?xml[^>]+>}, "")
27
29
  end
28
30
 
29
31
  def html_cleanup(x)
30
- footnote_format(footnote_backlinks(html_toc(
31
- term_header((html_footnote_filter(html_preface(htmlstyle(x))))))
32
- ))
32
+ mathml(
33
+ footnote_format(
34
+ footnote_backlinks(
35
+ html_toc(
36
+ term_header(html_footnote_filter(html_preface(htmlstyle(x))))
37
+ )
38
+ )
39
+ )
40
+ )
41
+ end
42
+
43
+ def mathml(docxml)
44
+ IsoDoc::HtmlFunction::MathvariantToPlain.new(docxml).convert
33
45
  end
34
46
 
35
47
  def htmlstylesheet
@@ -76,14 +88,14 @@ module IsoDoc::HtmlFunction
76
88
  def html_cover(docxml)
77
89
  doc = to_xhtml_fragment(File.read(@htmlcoverpage, encoding: "UTF-8"))
78
90
  d = docxml.at('//div[@class="title-section"]')
79
- #d.children.first.add_previous_sibling doc.to_xml(encoding: "US-ASCII")
91
+ # d.children.first.add_previous_sibling doc.to_xml(encoding: "US-ASCII")
80
92
  d.children.first.add_previous_sibling populate_template(doc.to_xml(encoding: "US-ASCII"), :html)
81
93
  end
82
94
 
83
95
  def html_intro(docxml)
84
96
  doc = to_xhtml_fragment(File.read(@htmlintropage, encoding: "UTF-8"))
85
97
  d = docxml.at('//div[@class="prefatory-section"]')
86
- #d.children.first.add_previous_sibling doc.to_xml(encoding: "US-ASCII")
98
+ # d.children.first.add_previous_sibling doc.to_xml(encoding: "US-ASCII")
87
99
  d.children.first.add_previous_sibling populate_template(doc.to_xml(encoding: "US-ASCII"), :html)
88
100
  end
89
101
 
@@ -93,19 +105,19 @@ module IsoDoc::HtmlFunction
93
105
  end
94
106
 
95
107
  def toclevel_classes
96
- (1..@htmlToClevels).inject([]) { |m, i| m << "h#{i}" }
108
+ (1..@htmlToClevels).reduce([]) { |m, i| m << "h#{i}" }
97
109
  end
98
110
 
99
111
  def toclevel
100
112
  ret = toclevel_classes.map { |l| "#{l}:not(:empty):not(.TermNum):not(.noTOC)" }
101
113
  <<~HEAD.freeze
102
- function toclevel() { return "#{ret.join(',')}";}
114
+ function toclevel() { return "#{ret.join(',')}";}
103
115
  HEAD
104
116
  end
105
117
 
106
118
  # needs to be same output as toclevel
107
119
  def html_toc(docxml)
108
- idx = docxml.at("//div[@id = 'toc']") or return docxml
120
+ (idx = docxml.at("//div[@id = 'toc']")) or (return docxml)
109
121
  toc = "<ul>"
110
122
  path = toclevel_classes.map do |l|
111
123
  "//main//#{l}[not(@class = 'TermNum')][not(@class = 'noTOC')][text()]"
@@ -125,7 +137,7 @@ module IsoDoc::HtmlFunction
125
137
  docxml.xpath("//*[local-name() = 'img']").each do |i|
126
138
  i["width"], i["height"] = Html2Doc.image_resize(i, image_localfile(i),
127
139
  @maxheight, @maxwidth)
128
- next if /^data:image/.match i["src"]
140
+ next if /^data:/.match i["src"]
129
141
  @datauriimage ? datauri(i) : move_image1(i)
130
142
  end
131
143
  docxml
@@ -133,9 +145,10 @@ module IsoDoc::HtmlFunction
133
145
 
134
146
  def datauri(i)
135
147
  type = i["src"].split(".")[-1]
148
+ supertype = type == "xml" ? "application" : "image"
136
149
  bin = IO.binread(image_localfile(i))
137
150
  data = Base64.strict_encode64(bin)
138
- i["src"] = "data:image/#{type};base64,#{data}"
151
+ i["src"] = "data:#{supertype}/#{type};base64,#{data}"
139
152
  end
140
153
 
141
154
  def image_suffix(i)