isodoc 2.9.4 → 2.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fa1b06e38f973ba312a0f2d90d306c7ffb34e377f2fcc4a59c42775ba9f2a927
4
- data.tar.gz: b74dcbe6b71b90da2ec4f205754bb08028d5bd1d45f085f7e35d6c3c47dc55cc
3
+ metadata.gz: 6867b3f44bce43fcfbd4c65115b8b71b6eb38cb7b1e39c20215addc7af8ad086
4
+ data.tar.gz: f335e4aecc20758c7c9810083d7da486ec73e0db4c377b9528841b46166085de
5
5
  SHA512:
6
- metadata.gz: 9cbe711521cc25e29f1879fa47ca42347a5ecfc0f94526166a4acb73f5787d5a5d577d68e3fe756cedce0c862b4aebfb54022fea51f296cbbeeff173e2ad5521
7
- data.tar.gz: a07f6c1bdd5457be3cad8fececa4974de6bc95a952c73e31b718e22606a6d4c6807293729a784d55655a4419e10486c7de171dd1630ceb2f275605b263955e5d
6
+ metadata.gz: 0bda93db557ef73dc1c5999bbd88d9ba06ac9977f48b93f4adca7aaac7e762d5b4fed0d62d8934151ce3ecf1becea0060d3fab65c92e2150a8a00a0c49895ee6
7
+ data.tar.gz: 1b0d780a2e450e8a22e8f6d4dcbcaa991e73bdcf1343ca3675c2e81b5f52688be7882f58762c18820fd2e99c4c37ea6043af8efc7f454ec44b553e00c3d356e3
@@ -10,7 +10,8 @@ require "mn-requirements"
10
10
  module IsoDoc
11
11
  class Convert < ::IsoDoc::Common
12
12
  attr_accessor :options, :i18n, :meta, :xrefs, :reqt_models,
13
- :requirements_processor, :doctype, :bibrender
13
+ :requirements_processor, :doctype, :bibrender,
14
+ :tempfile_cache, :wordcoverpage, :wordintropage
14
15
 
15
16
  # htmlstylesheet: Generic stylesheet for HTML
16
17
  # htmlstylesheet_override: Override stylesheet for HTML
@@ -89,11 +90,15 @@ module IsoDoc
89
90
  i18nhash: @i18n.get))
90
91
  end
91
92
 
93
+ def convert1_namespaces(html)
94
+ html.add_namespace("epub", "http://www.idpf.org/2007/ops")
95
+ end
96
+
92
97
  def convert1(docxml, filename, dir)
93
98
  @xrefs.parse docxml
94
99
  noko do |xml|
95
100
  xml.html lang: @lang.to_s do |html|
96
- html.parent.add_namespace("epub", "http://www.idpf.org/2007/ops")
101
+ convert1_namespaces(html.parent)
97
102
  info docxml, nil
98
103
  populate_css
99
104
  html.head { |head| define_head head, filename, dir }
@@ -177,5 +182,19 @@ module IsoDoc
177
182
  else "##{node['target']}"
178
183
  end
179
184
  end
185
+
186
+ # use a different class than self for rendering, as a result
187
+ # of document-specific criteria
188
+ # but pass on any singleton methods defined on top of the self instance
189
+ def swap_renderer(oldklass, newklass, file, input_filename, debug)
190
+ ref = oldklass # avoid oldklass == self for indirection of methods
191
+ oldklass.singleton_methods.each do |x|
192
+ newklass.define_singleton_method(x) do |*args|
193
+ ref.public_send(x, *args)
194
+ end
195
+ end
196
+ oldklass.singleton_methods.empty? or
197
+ newklass.convert_init(file, input_filename, debug)
198
+ end
180
199
  end
181
200
  end
@@ -8,7 +8,7 @@ module IsoDoc
8
8
  node["update-type"] == "true" and url = suffix_url(url)
9
9
  out.a **attr_code(href: url, title: node["alt"]) do |l|
10
10
  if node.elements.empty? && node.text.strip.empty?
11
- l << node["target"].sub(/^mailto:/, "")
11
+ l << @c.encode(node["target"].sub(/^mailto:/, ""), :basic, :hexadecimal)
12
12
  else node.children.each { |n| parse(n, l) }
13
13
  end
14
14
  end
@@ -152,6 +152,7 @@ module IsoDoc
152
152
  end
153
153
 
154
154
  def table_of_contents(clause, out)
155
+ @bare and return
155
156
  page_break(out)
156
157
  out.div **attr_code(preface_attrs(clause)) do |div|
157
158
  clause_name(clause, clause.at(ns("./title")), div,
@@ -194,32 +195,28 @@ module IsoDoc
194
195
  end
195
196
 
196
197
  def copyright_parse(node, out)
197
- return if @bare
198
-
198
+ @bare and return
199
199
  out.div class: "boilerplate-copyright" do |div|
200
200
  node.children.each { |n| parse(n, div) }
201
201
  end
202
202
  end
203
203
 
204
204
  def license_parse(node, out)
205
- return if @bare
206
-
205
+ @bare and return
207
206
  out.div class: "boilerplate-license" do |div|
208
207
  node.children.each { |n| parse(n, div) }
209
208
  end
210
209
  end
211
210
 
212
211
  def legal_parse(node, out)
213
- return if @bare
214
-
212
+ @bare and return
215
213
  out.div class: "boilerplate-legal" do |div|
216
214
  node.children.each { |n| parse(n, div) }
217
215
  end
218
216
  end
219
217
 
220
218
  def feedback_parse(node, out)
221
- return if @bare
222
-
219
+ @bare and return
223
220
  out.div class: "boilerplate-feedback" do |div|
224
221
  node.children.each { |n| parse(n, div) }
225
222
  end
@@ -40,8 +40,10 @@ module IsoDoc
40
40
  end
41
41
 
42
42
  def html_preface(docxml)
43
- html_cover(docxml) if @htmlcoverpage && !@bare
44
- html_intro(docxml) if @htmlintropage && !@bare
43
+ @htmlcoverpage && !@htmlcoverpage.empty? && !@bare and
44
+ html_cover(docxml)
45
+ @htmlintropage && !@htmlintropage.empty? && !@bare and
46
+ html_intro(docxml)
45
47
  docxml.at("//body") << mathjax(@openmathdelim, @closemathdelim)
46
48
  html_main(docxml)
47
49
  authority_cleanup(docxml)
@@ -100,7 +100,7 @@ module IsoDoc
100
100
  end
101
101
 
102
102
  def maths_just_numeral(node)
103
- mn = node.at("./m:mn", MATHML).children
103
+ mn = node.at(".//m:mn", MATHML).children
104
104
  if node.parent.name == "stem"
105
105
  node.parent.replace(mn)
106
106
  else
@@ -127,12 +127,22 @@ module IsoDoc
127
127
  end
128
128
 
129
129
  def mathml_number(node, locale)
130
- justnumeral = node.elements.size == 1 && node.elements.first.name == "mn"
130
+ justnumeral = numeric_mathml?(node)
131
131
  justnumeral or asciimath_dup(node)
132
132
  localize_maths(node, locale)
133
133
  justnumeral and maths_just_numeral(node)
134
134
  end
135
135
 
136
+ def numeric_mathml?(node)
137
+ m = {}
138
+ node.traverse do |x|
139
+ %w(mstyle mrow math text).include?(x.name) and next
140
+ m[x.name] ||= 0
141
+ m[x.name] += 1
142
+ end
143
+ m.keys.size == 1 && m["mn"] == 1
144
+ end
145
+
136
146
  def mathml_style_inherit(node)
137
147
  node.at("./ancestor::xmlns:strong") or return
138
148
  node.children =
@@ -102,9 +102,14 @@ module IsoDoc
102
102
  end
103
103
 
104
104
  def bibliography_bibitem_number_insert_pt(bibitem)
105
- unless ins = bibitem.at(ns(".//docidentifier")).previous_element
106
- bibitem.at(ns(".//docidentifier")).previous = " "
107
- ins = bibitem.at(ns(".//docidentifier")).previous
105
+ unless d = bibitem.at(ns(".//docidentifier"))
106
+ d = bibitem.children.first
107
+ d.previous = " "
108
+ return d.previous
109
+ end
110
+ unless ins = d.previous_element
111
+ d.previous = " "
112
+ ins = d.previous
108
113
  end
109
114
  ins
110
115
  end
@@ -1,3 +1,3 @@
1
1
  module IsoDoc
2
- VERSION = "2.9.4".freeze
2
+ VERSION = "2.10.1".freeze
3
3
  end
@@ -5,6 +5,14 @@ require_relative "lists"
5
5
  module IsoDoc
6
6
  module WordFunction
7
7
  module Body
8
+ def convert1_namespaces(html)
9
+ super
10
+ html.add_namespace("v", "urn:schemas-microsoft-com:vml")
11
+ html.add_namespace("o", "urn:schemas-microsoft-com:office:office")
12
+ html.add_namespace("w", "urn:schemas-microsoft-com:office:word")
13
+ html.add_namespace("m", "http://schemas.microsoft.com/office/2004/12/omml")
14
+ end
15
+
8
16
  def define_head(head, filename, _dir)
9
17
  head.style do |style|
10
18
  loc = File.join(File.dirname(__FILE__), "..", "base_style",
@@ -7,17 +7,21 @@ module IsoDoc
7
7
  module WordFunction
8
8
  module Postprocess
9
9
  def postprocess(result, filename, dir)
10
+ result = postprocess_cleanup(result)
10
11
  filename = filename.sub(/\.doc$/, "")
11
12
  header = generate_header(filename, dir)
12
- result = from_xhtml(cleanup(to_xhtml(textcleanup(result))))
13
+ @wordstylesheet = wordstylesheet_update
13
14
  toWord(result, filename, dir, header)
14
15
  @files_to_delete.each { |f| FileUtils.rm_f f }
15
16
  end
16
17
 
17
- def toWord(result, filename, dir, header)
18
- result = from_xhtml(word_cleanup(to_xhtml(result)))
18
+ def postprocess_cleanup(result)
19
+ result = cleanup(to_xhtml(textcleanup(result)))
20
+ from_xhtml(word_cleanup(result))
19
21
  .gsub("-DOUBLE_HYPHEN_ESCAPE-", "--")
20
- @wordstylesheet = wordstylesheet_update
22
+ end
23
+
24
+ def toWord(result, filename, dir, header)
21
25
  Html2Doc.new(
22
26
  filename: filename, imagedir: @localdir,
23
27
  stylesheet: @wordstylesheet&.path,
@@ -60,9 +64,16 @@ module IsoDoc
60
64
  word_tab_clean(docxml)
61
65
  authority_cleanup(docxml)
62
66
  word_footnote_format(docxml)
67
+ word_remove_empty_toc(docxml)
68
+ word_remove_empty_sections(docxml)
63
69
  docxml
64
70
  end
65
71
 
72
+ def word_remove_empty_toc(docxml)
73
+ docxml.at("//div[@class = 'TOC']//p[@class = 'MsoToc1']") and return
74
+ remove_toc_div(docxml)
75
+ end
76
+
66
77
  def word_sourcecode_annotations(html)
67
78
  ann = ".//div[@class = 'annotation']"
68
79
  html.xpath("//p[@class = '#{sourcecode_style}'][#{ann}]")
@@ -2,25 +2,36 @@ module IsoDoc
2
2
  module WordFunction
3
3
  module Postprocess
4
4
  def word_preface(docxml)
5
- word_cover(docxml) if @wordcoverpage
6
- word_intro(docxml, @wordToClevels) if @wordintropage
5
+ @wordcoverpage && !@wordcoverpage.empty? and
6
+ word_cover(docxml)
7
+ @wordintropage && !@wordintropage.empty? and
8
+ word_intro(docxml, @wordToClevels)
9
+ end
10
+
11
+ def word_remove_empty_sections(docxml)
12
+ %w(WordSection1 WordSection2).each do |x|
13
+ ins = docxml.at("//div[@class='#{x}']") or next
14
+ @c.decode(ins.text).gsub(/\p{Z}|\p{C}/, "").strip.empty? or next
15
+ ins.next_element.remove
16
+ ins.remove
17
+ end
7
18
  end
8
19
 
9
20
  def word_cover(docxml)
21
+ ins = docxml.at('//div[@class="WordSection1"]') or return
10
22
  cover = File.read(@wordcoverpage, encoding: "UTF-8")
11
23
  cover = populate_template(cover, :word)
12
24
  coverxml = to_word_xhtml_fragment(cover)
13
- docxml.at('//div[@class="WordSection1"]').children.first.previous =
14
- coverxml.to_xml(encoding: "US-ASCII")
25
+ ins.children.first.previous = coverxml.to_xml(encoding: "US-ASCII")
15
26
  end
16
27
 
17
28
  def word_intro(docxml, level)
29
+ ins = docxml.at('//div[@class="WordSection2"]') or return
18
30
  intro = insert_toc(File.read(@wordintropage, encoding: "UTF-8"),
19
31
  docxml, level)
20
32
  intro = populate_template(intro, :word)
21
33
  introxml = to_word_xhtml_fragment(intro)
22
- docxml.at('//div[@class="WordSection2"]').children.first.previous =
23
- introxml.to_xml(encoding: "US-ASCII")
34
+ ins.children.first.previous = introxml.to_xml(encoding: "US-ASCII")
24
35
  end
25
36
 
26
37
  # add namespaces for Word fragments
@@ -90,10 +101,7 @@ module IsoDoc
90
101
  def generate_header(filename, _dir)
91
102
  @header or return nil
92
103
  template = IsoDoc::Common.liquid(File.read(@header, encoding: "UTF-8"))
93
- meta = @meta.get.merge(@labels ? { labels: @labels } : {})
94
- .merge(@meta.labels ? { labels: @meta.labels } : {})
95
- meta[:filename] = filename
96
- params = meta.transform_keys(&:to_s)
104
+ params = header_params(filename)
97
105
  Tempfile.open(%w(header html),
98
106
  mode: File::BINARY | File::SHARE_DELETE,
99
107
  encoding: "utf-8") do |f|
@@ -102,6 +110,13 @@ module IsoDoc
102
110
  end
103
111
  end
104
112
 
113
+ def header_params(filename)
114
+ meta = @meta.get.merge(@labels ? { labels: @labels } : {})
115
+ .merge(@meta.labels ? { labels: @meta.labels } : {})
116
+ meta[:filename] = filename
117
+ meta.transform_keys(&:to_s)
118
+ end
119
+
105
120
  def word_section_breaks(docxml)
106
121
  @landscapestyle = ""
107
122
  word_section_breaks1(docxml, "WordSection2")
@@ -4,11 +4,7 @@ module IsoDoc
4
4
  def insert_toc(intro, docxml, level)
5
5
  toc = assemble_toc(docxml, level)
6
6
  if intro&.include?("WORDTOC")
7
- if s = docxml.at("//div[@class = 'TOC']")
8
- s&.previous_element&.elements&.first&.name == "br" and
9
- s&.previous_element&.remove # page break
10
- s.remove
11
- end
7
+ remove_toc_div(docxml)
12
8
  intro.sub("WORDTOC", toc)
13
9
  else
14
10
  source = docxml.at("//div[@class = 'TOC']") and
@@ -17,6 +13,14 @@ module IsoDoc
17
13
  end
18
14
  end
19
15
 
16
+ def remove_toc_div(docxml)
17
+ s = docxml.at("//div[@class = 'TOC']") or return
18
+ prev = s.previous_element
19
+ prev&.elements&.first&.name == "br" and
20
+ prev&.remove # page break
21
+ s.remove
22
+ end
23
+
20
24
  def assemble_toc(docxml, level)
21
25
  toc = ""
22
26
  toc += make_WordToC(docxml, level)
@@ -0,0 +1,41 @@
1
+ module IsoDoc
2
+ module XrefGen
3
+ module Sections
4
+ def clause_order(docxml)
5
+ { preface: clause_order_preface(docxml),
6
+ main: clause_order_main(docxml),
7
+ annex: clause_order_annex(docxml),
8
+ back: clause_order_back(docxml) }
9
+ end
10
+
11
+ def clause_order_preface(_docxml)
12
+ [{ path: "//preface/*", multi: true }]
13
+ end
14
+
15
+ def clause_order_main(docxml)
16
+ [
17
+ { path: "//sections/clause[@type = 'scope']" },
18
+ { path: @klass.norm_ref_xpath },
19
+ { path: "//sections/terms | " \
20
+ "//sections/clause[descendant::terms]" },
21
+ { path: "//sections/definitions | " \
22
+ "//sections/clause[descendant::definitions]" \
23
+ "[not(descendant::terms)]" },
24
+ { path: @klass.middle_clause(docxml), multi: true },
25
+ ]
26
+ end
27
+
28
+ def clause_order_annex(_docxml)
29
+ [{ path: "//annex", multi: true }]
30
+ end
31
+
32
+ def clause_order_back(_docxml)
33
+ [
34
+ { path: @klass.bibliography_xpath },
35
+ { path: "//indexsect", multi: true },
36
+ { path: "//colophon/*", multi: true },
37
+ ]
38
+ end
39
+ end
40
+ end
41
+ end
@@ -139,7 +139,7 @@ module IsoDoc
139
139
  end
140
140
 
141
141
  def increment(node)
142
- @unnumbered = (node["unnumbered"] || node["hidden"]) and return self
142
+ @unnumbered = node["unnumbered"] == "true" || node["hidden"] == "true" and return self
143
143
  reset_overrides
144
144
  if node["subsequence"] != @subseq &&
145
145
  !(blank?(node["subsequence"]) && blank?(@subseq))
@@ -88,6 +88,7 @@ module IsoDoc
88
88
 
89
89
  def admonition_anchor_names(sections)
90
90
  sections.each do |s|
91
+ s.at(ns(".//admonition[@type = 'box']")) or next
91
92
  notes = s.xpath(child_asset_path("admonition[@type = 'box']"))
92
93
  admonition_anchor_names1(notes, Counter.new)
93
94
  admonition_anchor_names(s.xpath(ns(CHILD_SECTIONS)))
@@ -132,20 +133,19 @@ module IsoDoc
132
133
  end
133
134
  end
134
135
 
135
- def list_item_anchor_names(list, list_anchor, depth, prev_label,
136
- refer_list)
136
+ def list_item_anchor_names(list, list_anchor, depth, prev_label, refer_list)
137
137
  c = Counter.new(list["start"] ? list["start"].to_i - 1 : 0)
138
138
  list.xpath(ns("./li")).each do |li|
139
139
  bare_label, label =
140
140
  list_item_value(li, c, depth, { list_anchor: list_anchor, prev_label: prev_label,
141
- refer_list: refer_list })
141
+ refer_list: depth == 1 ? refer_list : nil })
142
142
  li["id"] and @anchors[li["id"]] =
143
143
  { label: bare_label, bare_xref: "#{label})",
144
144
  xref: "#{label})",
145
145
  type: "listitem", refer_list: refer_list,
146
146
  container: list_anchor[:container] }
147
147
  (li.xpath(ns(".//ol")) - li.xpath(ns(".//ol//ol"))).each do |ol|
148
- list_item_anchor_names(ol, list_anchor, depth + 1, label, false)
148
+ list_item_anchor_names(ol, list_anchor, depth + 1, label, refer_list)
149
149
  end
150
150
  end
151
151
  end
@@ -1,42 +1,8 @@
1
+ require_relative "clause_order"
2
+
1
3
  module IsoDoc
2
4
  module XrefGen
3
5
  module Sections
4
- def clause_order(docxml)
5
- { preface: clause_order_preface(docxml),
6
- main: clause_order_main(docxml),
7
- annex: clause_order_annex(docxml),
8
- back: clause_order_back(docxml) }
9
- end
10
-
11
- def clause_order_preface(_docxml)
12
- [{ path: "//preface/*", multi: true }]
13
- end
14
-
15
- def clause_order_main(docxml)
16
- [
17
- { path: "//sections/clause[@type = 'scope']" },
18
- { path: @klass.norm_ref_xpath },
19
- { path: "//sections/terms | " \
20
- "//sections/clause[descendant::terms]" },
21
- { path: "//sections/definitions | " \
22
- "//sections/clause[descendant::definitions]" \
23
- "[not(descendant::terms)]" },
24
- { path: @klass.middle_clause(docxml), multi: true },
25
- ]
26
- end
27
-
28
- def clause_order_annex(_docxml)
29
- [{ path: "//annex", multi: true }]
30
- end
31
-
32
- def clause_order_back(_docxml)
33
- [
34
- { path: @klass.bibliography_xpath },
35
- { path: "//indexsect", multi: true },
36
- { path: "//colophon/*", multi: true },
37
- ]
38
- end
39
-
40
6
  def back_anchor_names(xml)
41
7
  if @parse_settings.empty? || @parse_settings[:clauses]
42
8
  annex_anchor_names(xml)
@@ -105,11 +71,12 @@ module IsoDoc
105
71
  termnote_anchor_names(doc)
106
72
  termexample_anchor_names(doc)
107
73
  note_anchor_names(doc.xpath(ns("//table | //figure")))
108
- note_anchor_names(doc.xpath(ns(sections_xpath)))
109
- admonition_anchor_names(doc.xpath(ns(sections_xpath)))
110
- example_anchor_names(doc.xpath(ns(sections_xpath)))
111
- list_anchor_names(doc.xpath(ns(sections_xpath)))
112
- deflist_anchor_names(doc.xpath(ns(sections_xpath)))
74
+ sections = doc.xpath(ns(sections_xpath))
75
+ note_anchor_names(sections)
76
+ admonition_anchor_names(sections)
77
+ example_anchor_names(sections)
78
+ list_anchor_names(sections)
79
+ deflist_anchor_names(sections)
113
80
  bookmark_anchor_names(doc)
114
81
  end
115
82
 
@@ -172,7 +139,7 @@ module IsoDoc
172
139
  end
173
140
 
174
141
  def section_names(clause, num, lvl)
175
- clause.nil? and return num
142
+ unnumbered_section_name?(clause) and return num
176
143
  num.increment(clause)
177
144
  section_name_anchors(clause, num.print, lvl)
178
145
  clause.xpath(ns(SUBCLAUSES))
@@ -183,6 +150,7 @@ module IsoDoc
183
150
  end
184
151
 
185
152
  def section_names1(clause, num, level)
153
+ unnumbered_section_name?(clause) and return num
186
154
  section_name_anchors(clause, num, level)
187
155
  i = Counter.new(0, prefix: "#{num}.")
188
156
  clause.xpath(ns(SUBCLAUSES)).each do |c|
@@ -190,6 +158,15 @@ module IsoDoc
190
158
  end
191
159
  end
192
160
 
161
+ def unnumbered_section_name?(clause)
162
+ clause.nil? and return true
163
+ if clause["unnumbered"] == "true"
164
+ unnumbered_names(clause)
165
+ return true
166
+ end
167
+ false
168
+ end
169
+
193
170
  def section_name_anchors(clause, num, level)
194
171
  @anchors[clause["id"]] =
195
172
  { label: num, xref: l10n("#{@labels['clause']} #{num}"),
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: 2.9.4
4
+ version: 2.10.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-03-25 00:00:00.000000000 Z
11
+ date: 2024-04-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: html2doc
@@ -392,6 +392,7 @@ files:
392
392
  - lib/isodoc/word_function/postprocess_toc.rb
393
393
  - lib/isodoc/word_function/table.rb
394
394
  - lib/isodoc/xref.rb
395
+ - lib/isodoc/xref/clause_order.rb
395
396
  - lib/isodoc/xref/xref_anchor.rb
396
397
  - lib/isodoc/xref/xref_counter.rb
397
398
  - lib/isodoc/xref/xref_gen.rb