isodoc 3.1.10 → 3.1.11

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.
Files changed (33) hide show
  1. checksums.yaml +4 -4
  2. data/lib/isodoc/function/blocks.rb +6 -6
  3. data/lib/isodoc/function/blocks_example_note.rb +1 -1
  4. data/lib/isodoc/function/form.rb +2 -6
  5. data/lib/isodoc/function/inline.rb +9 -10
  6. data/lib/isodoc/function/inline_simple.rb +8 -8
  7. data/lib/isodoc/function/reqt.rb +2 -4
  8. data/lib/isodoc/function/section.rb +4 -4
  9. data/lib/isodoc/function/section_titles.rb +1 -1
  10. data/lib/isodoc/function/setup.rb +2 -2
  11. data/lib/isodoc/function/terms.rb +3 -3
  12. data/lib/isodoc/function/utils.rb +4 -0
  13. data/lib/isodoc/html_function/form.rb +4 -12
  14. data/lib/isodoc/metadata_contributor.rb +40 -18
  15. data/lib/isodoc/presentation_function/autonum.rb +5 -3
  16. data/lib/isodoc/presentation_function/footnotes.rb +5 -5
  17. data/lib/isodoc/presentation_function/ids.rb +81 -10
  18. data/lib/isodoc/presentation_function/image.rb +0 -4
  19. data/lib/isodoc/presentation_function/index.rb +6 -8
  20. data/lib/isodoc/presentation_function/metadata.rb +1 -1
  21. data/lib/isodoc/presentation_function/refs.rb +1 -0
  22. data/lib/isodoc/presentation_function/section.rb +2 -2
  23. data/lib/isodoc/presentation_function/terms.rb +4 -4
  24. data/lib/isodoc/presentation_function/title.rb +1 -2
  25. data/lib/isodoc/version.rb +1 -1
  26. data/lib/isodoc/word_function/body.rb +25 -6
  27. data/lib/isodoc/word_function/comments.rb +1 -1
  28. data/lib/isodoc/word_function/footnotes.rb +3 -2
  29. data/lib/isodoc/word_function/inline.rb +3 -3
  30. data/lib/isodoc/xref/xref_gen.rb +1 -1
  31. data/lib/isodoc/xref/xref_sect_gen.rb +3 -3
  32. data/lib/isodoc/xslfo_convert.rb +24 -7
  33. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 99e69024aaaf44cd4e14adf54c3a7ae462ca5400306a9ccc20c74834ad101418
4
- data.tar.gz: 39060f4e2b83d5211610b75d39474449191b0ef8f8d543672fc6a40eba55f7bd
3
+ metadata.gz: 8160c3e32a52cffb4ec08452c22872631c0a55dfd3ae81b3bb5dfdf6269769c6
4
+ data.tar.gz: bb0f4a1a46099a5315d97991b6bff04a4f08a5364f8b5d4a3ae74bc4c2a2ea6c
5
5
  SHA512:
6
- metadata.gz: 2eeb99cfc5aebc17b5e07b2496467cc822a547c61d08e5b572b6575da8402b3beee4c6b854e8ee7feefaaa215e6aecd055670f9653e1d9c38538928ab6d06a85
7
- data.tar.gz: 6a185f46948895262590d32bf58d311f53938a0f122d84e26d722a661d1a48fdf63aa043f5d8f094928d1441eb6b00f844182376300b3cf5c44311e35dea2849
6
+ metadata.gz: 221dafa4fa11246d7b0e61c5553c6199e2a4a58bc409d6389a889a5cb4bee761c6e5a7a8d2936acefd41083cb86436845a6719519d50a675774149fd5a2c92ad
7
+ data.tar.gz: de02f2a399990422f41dd6380bd337462b3a90609e1e6caefb7266d117a24b29b17a1b69015188cd087373eeb00ba097678aeed669d8bf7b2a1c73037c7e306b
@@ -137,13 +137,13 @@ module IsoDoc
137
137
 
138
138
  def para_parse(node, out)
139
139
  out.p **attr_code(para_attrs(node)) do |p|
140
- node.children.each { |n| parse(n, p) }
140
+ children_parse(node, p)
141
141
  end
142
142
  end
143
143
 
144
144
  def attribution_parse(node, out)
145
- out.div class: "QuoteAttribution" do |d|
146
- node.children.each { |n| parse(n, d) }
145
+ out.div class: "QuoteAttribution" do |div|
146
+ children_parse(node, div)
147
147
  end
148
148
  end
149
149
 
@@ -167,14 +167,14 @@ module IsoDoc
167
167
 
168
168
  def toc_parse(node, out)
169
169
  out.div class: "toc" do |div|
170
- node.children.each { |n| parse(n, div) }
170
+ children_parse(node, div)
171
171
  end
172
172
  end
173
173
 
174
174
  def source_parse(node, out)
175
175
  out.div class: "BlockSource" do |d|
176
176
  d.p do |p|
177
- node.children.each { |n| parse(n, p) }
177
+ children_parse(node, p)
178
178
  end
179
179
  end
180
180
  end
@@ -201,7 +201,7 @@ module IsoDoc
201
201
  tag = node.parent.name == "fmt-footnote-container" ? "aside" : "div"
202
202
  id = node["is_table"] ? node["reference"] : node["id"]
203
203
  out.send tag, id: "fn:#{id}", class: "footnote" do |div|
204
- node.children.each { |n| parse(n, div) }
204
+ children_parse(node, div)
205
205
  end
206
206
  end
207
207
  end
@@ -4,7 +4,7 @@ module IsoDoc
4
4
  def example_label(_node, div, name)
5
5
  name.nil? and return
6
6
  div.p class: "example-title" do |_p|
7
- name.children.each { |n| parse(n, div) }
7
+ children_parse(name, div)
8
8
  end
9
9
  end
10
10
 
@@ -4,9 +4,7 @@ module IsoDoc
4
4
  def form_parse(node, out)
5
5
  out.div **attr_code(class: node["class"],
6
6
  id: node["id"]) do |div|
7
- node.children.each do |n|
8
- parse(n, div)
9
- end
7
+ children_parse(node, div)
10
8
  end
11
9
  end
12
10
 
@@ -34,9 +32,7 @@ module IsoDoc
34
32
  end
35
33
 
36
34
  def label_parse(node, out)
37
- node.children.each do |n|
38
- parse(n, out)
39
- end
35
+ children_parse(node, out)
40
36
  end
41
37
 
42
38
  def option_parse(node, out); end
@@ -10,7 +10,7 @@ module IsoDoc
10
10
  if node.elements.empty? && node.text.strip.empty?
11
11
  l << @c.encode(node["target"].sub(/^mailto:/, ""), :basic,
12
12
  :hexadecimal)
13
- else node.children.each { |n| parse(n, l) }
13
+ else children_parse(node, l)
14
14
  end
15
15
  end
16
16
  end
@@ -74,8 +74,7 @@ module IsoDoc
74
74
  def termrefelem_parse(node, out)
75
75
  if node.text.strip.empty?
76
76
  out << "Termbase #{node['base']}, term ID #{node['target']}"
77
- else
78
- node.children.each { |n| parse(n, out) }
77
+ else children_parse(node, out)
79
78
  end
80
79
  end
81
80
 
@@ -142,7 +141,7 @@ module IsoDoc
142
141
 
143
142
  def smallcap_parse(node, xml)
144
143
  xml.span style: "font-variant:small-caps;" do |s|
145
- node.children.each { |n| parse(n, s) }
144
+ children_parse(node, s)
146
145
  end
147
146
  end
148
147
 
@@ -158,13 +157,13 @@ module IsoDoc
158
157
 
159
158
  def add_parse(node, out)
160
159
  out.span class: "addition" do |e|
161
- node.children.each { |n| parse(n, e) }
160
+ children_parse(node, e)
162
161
  end
163
162
  end
164
163
 
165
164
  def del_parse(node, out)
166
165
  out.span class: "deletion" do |e|
167
- node.children.each { |n| parse(n, e) }
166
+ children_parse(node, e)
168
167
  end
169
168
  end
170
169
 
@@ -177,19 +176,19 @@ module IsoDoc
177
176
 
178
177
  def ruby_parse(node, out)
179
178
  out.ruby do |e|
180
- node.children.each { |n| parse(n, e) }
179
+ children_parse(node, e)
181
180
  end
182
181
  end
183
182
 
184
183
  def rt_parse(node, out)
185
184
  out.rt do |e|
186
- node.children.each { |n| parse(n, e) }
185
+ children_parse(node, e)
187
186
  end
188
187
  end
189
188
 
190
189
  def rb_parse(node, out)
191
190
  out.rb do |e|
192
- node.children.each { |n| parse(n, e) }
191
+ children_parse(node, e)
193
192
  end
194
193
  end
195
194
 
@@ -198,7 +197,7 @@ module IsoDoc
198
197
  end
199
198
 
200
199
  def children_parse(node, out)
201
- node.children.each { |n| parse(n, out) }
200
+ node&.children&.each { |n| parse(n, out) }
202
201
  end
203
202
 
204
203
  def location_parse(node, out); end
@@ -31,50 +31,50 @@ module IsoDoc
31
31
 
32
32
  def keyword_parse(node, out)
33
33
  out.span class: "keyword" do |s|
34
- node.children.each { |n| parse(n, s) }
34
+ children_parse(node, s)
35
35
  end
36
36
  end
37
37
 
38
38
  def em_parse(node, out)
39
39
  out.i do |e|
40
- node.children.each { |n| parse(n, e) }
40
+ children_parse(node, e)
41
41
  end
42
42
  end
43
43
 
44
44
  def strong_parse(node, out)
45
45
  out.b do |e|
46
- node.children.each { |n| parse(n, e) }
46
+ children_parse(node, e)
47
47
  end
48
48
  end
49
49
 
50
50
  def sup_parse(node, out)
51
51
  out.sup do |e|
52
- node.children.each { |n| parse(n, e) }
52
+ children_parse(node, e)
53
53
  end
54
54
  end
55
55
 
56
56
  def sub_parse(node, out)
57
57
  out.sub do |e|
58
- node.children.each { |n| parse(n, e) }
58
+ children_parse(node, e)
59
59
  end
60
60
  end
61
61
 
62
62
  def tt_parse(node, out)
63
63
  out.tt do |e|
64
- node.children.each { |n| parse(n, e) }
64
+ children_parse(node, e)
65
65
  end
66
66
  end
67
67
 
68
68
  def strike_parse(node, out)
69
69
  out.s do |e|
70
- node.children.each { |n| parse(n, e) }
70
+ children_parse(node, e)
71
71
  end
72
72
  end
73
73
 
74
74
  def underline_parse(node, out)
75
75
  node["style"] and style = "text-decoration: #{node['style']}"
76
76
  out.u **attr_code(style: style) do |e|
77
- node.children.each { |n| parse(n, e) }
77
+ children_parse(node, e)
78
78
  end
79
79
  end
80
80
  end
@@ -40,10 +40,8 @@ module IsoDoc
40
40
  end
41
41
 
42
42
  def div_parse(node, out)
43
- out.div **reqt_attrs(node, node["type"]) do |t|
44
- node.children.each do |n|
45
- parse(n, t)
46
- end
43
+ out.div **reqt_attrs(node, node["type"]) do |div|
44
+ children_parse(node, div)
47
45
  end
48
46
  end
49
47
  end
@@ -199,28 +199,28 @@ module IsoDoc
199
199
  def copyright_parse(node, out)
200
200
  @bare and return
201
201
  out.div class: "boilerplate-copyright" do |div|
202
- node.children.each { |n| parse(n, div) }
202
+ children_parse(node, div)
203
203
  end
204
204
  end
205
205
 
206
206
  def license_parse(node, out)
207
207
  @bare and return
208
208
  out.div class: "boilerplate-license" do |div|
209
- node.children.each { |n| parse(n, div) }
209
+ children_parse(node, div)
210
210
  end
211
211
  end
212
212
 
213
213
  def legal_parse(node, out)
214
214
  @bare and return
215
215
  out.div class: "boilerplate-legal" do |div|
216
- node.children.each { |n| parse(n, div) }
216
+ children_parse(node, div)
217
217
  end
218
218
  end
219
219
 
220
220
  def feedback_parse(node, out)
221
221
  @bare and return
222
222
  out.div class: "boilerplate-feedback" do |div|
223
- node.children.each { |n| parse(n, div) }
223
+ children_parse(node, div)
224
224
  end
225
225
  end
226
226
 
@@ -90,7 +90,7 @@ module IsoDoc
90
90
  def variant_title(node, out)
91
91
  out.p **attr_code(style: "display:none;",
92
92
  class: "variant-title-#{node['type']}") do |p|
93
- node.children.each { |c| parse(c, p) }
93
+ children_parse(node, p)
94
94
  end
95
95
  end
96
96
  end
@@ -13,8 +13,8 @@ module IsoDoc
13
13
  filename = filepath.sub_ext("").sub(/\.presentation$/, "").to_s
14
14
  dir = init_dir(filename, debug)
15
15
  @filename = filename
16
- @localdir = @baseassetpath || filepath.parent.to_s
17
- @localdir += "/"
16
+ @output_dir = File.dirname(filename)
17
+ @localdir = (@baseassetpath || filepath.parent.to_s) + "/"
18
18
  @sourcedir = @localdir
19
19
  @sourcefilename and
20
20
  @sourcedir = "#{Pathname.new(@sourcefilename).parent}/"
@@ -2,7 +2,7 @@ module IsoDoc
2
2
  module Function
3
3
  module Terms
4
4
  def definition_parse(node, out)
5
- node.children.each { |n| parse(n, out) }
5
+ children_parse(node, out)
6
6
  end
7
7
 
8
8
  def modification_parse(node, out)
@@ -78,7 +78,7 @@ module IsoDoc
78
78
 
79
79
  def termref_parse(node, out)
80
80
  out.p do |p|
81
- node.children.each { |n| parse(n, p) }
81
+ children_parse(node, p)
82
82
  end
83
83
  end
84
84
 
@@ -89,7 +89,7 @@ module IsoDoc
89
89
  out.p class: "TermNum", id: node["id"] do |p|
90
90
  name&.children&.each { |n| parse(n, p) }
91
91
  end
92
- node.children.each { |n| parse(n, out) }
92
+ children_parse(node, out)
93
93
  end
94
94
 
95
95
  def termdocsource_parse(_node, _out); end
@@ -236,6 +236,10 @@ module IsoDoc
236
236
  path.tr!(%{/}, "\\")
237
237
  path[/\s/] ? "\"#{path}\"" : path
238
238
  end
239
+
240
+ def imgfile_suffix(uri, suffix)
241
+ "#{File.join(File.dirname(uri), File.basename(uri, '.*'))}.#{suffix}"
242
+ end
239
243
  end
240
244
  end
241
245
  end
@@ -5,9 +5,7 @@ module IsoDoc
5
5
  out.form **attr_code(id: node["id"], name: node["name"],
6
6
  class: node["class"],
7
7
  action: node["action"]) do |div|
8
- node.children.each do |n|
9
- parse(n, div)
10
- end
8
+ children_parse(node, div)
11
9
  end
12
10
  end
13
11
 
@@ -27,17 +25,13 @@ module IsoDoc
27
25
  id: node["id"], name: node["name"], size: node["size"],
28
26
  disabled: node["disabled"], multiple: node["multiple"]
29
27
  ) do |div|
30
- node.children.each do |n|
31
- parse(n, div)
32
- end
28
+ children_parse(node, div)
33
29
  end
34
30
  end
35
31
 
36
32
  def label_parse(node, out)
37
33
  out.label **attr_code(for: node["for"]) do |div|
38
- node.children.each do |n|
39
- parse(n, div)
40
- end
34
+ children_parse(node, div)
41
35
  end
42
36
  end
43
37
 
@@ -46,9 +40,7 @@ module IsoDoc
46
40
  disabled: node["disabled"], selected: node["selected"],
47
41
  value: node["value"]
48
42
  ) do |o|
49
- node.children.each do |n|
50
- parse(n, o)
51
- end
43
+ children_parse(node, o)
52
44
  end
53
45
  end
54
46
 
@@ -56,41 +56,63 @@ module IsoDoc
56
56
  end
57
57
 
58
58
  def iso?(org)
59
- name = org&.at(ns("./name"))&.text
60
- abbrev = org&.at(ns("./abbreviation"))&.text
61
- abbrev == "ISO" ||
62
- name == "International Organization for Standardization"
59
+ org[:abbr] == "ISO" ||
60
+ org[:name] == "International Organization for Standardization"
63
61
  end
64
62
 
65
63
  def agency1(xml)
66
64
  agency = ""
67
65
  publisher = []
68
- xml.xpath(ns("//bibdata/contributor[xmlns:role/@type = 'publisher']/" \
69
- "organization")).each do |org|
70
- name = org.at(ns("./name[@language = '#{@lang}']")) ||
71
- org.at(ns("./name"))
72
- agency1 = org.at(ns("./abbreviation"))&.text || name&.text
73
- publisher << name.text if name
66
+ logos = []
67
+ agency_data(xml).each do |org|
68
+ agency1 = org[:abbr] || org[:name]
69
+ org[:name] and publisher << org[:name]
70
+ org[:logo] and logos << org[:logo]
74
71
  agency = iso?(org) ? "ISO/#{agency}" : "#{agency}#{agency1}/"
75
72
  end
76
- [agency, publisher]
73
+ [agency.sub(%r{/$}, ""), publisher, logos]
74
+ end
75
+
76
+ AGENCY_DATA = { subdivision: "./subdivision",
77
+ pub_phone: "./phone[not(@type = 'fax')]",
78
+ abbr: "./abbreviation",
79
+ logo: "./logo/image/@src",
80
+ pub_fax: "./phone[@type = 'fax']", pub_email: "./email",
81
+ pub_uri: "./uri" }.freeze
82
+
83
+ def agency_data(xml)
84
+ xml.xpath(ns("//bibdata/contributor[xmlns:role/@type = 'publisher']/" \
85
+ "organization")).each_with_object([]) do |org, m|
86
+ m << agency_data1(org)
87
+ end
88
+ end
89
+
90
+ def agency_data1(org)
91
+ ret = {}
92
+ n = org.at(ns("./name[@language = '#{@lang}']")) ||
93
+ org.at(ns("./name")) and ret[:name] = n.text
94
+ AGENCY_DATA.each do |k, v|
95
+ n = org.at(ns(v)) and ret[k] = n.text
96
+ end
97
+ ret
77
98
  end
78
99
 
79
100
  def agency(xml)
80
- agency, publisher = agency1(xml)
81
- set(:agency, agency.sub(%r{/$}, ""))
101
+ agency, publisher, logos = agency1(xml)
102
+ set(:agency, agency)
82
103
  set(:publisher, connectives_strip(@i18n.boolean_conj(publisher, "and")))
104
+ set(:copublisher_logos, logos)
83
105
  agency_addr(xml)
84
106
  end
85
107
 
86
108
  def agency_addr(xml)
87
109
  a = xml.at(ns("//bibdata/contributor[xmlns:role/@type = 'publisher'][1]/" \
88
110
  "organization")) or return
89
- { subdivision: "./subdivision", pub_phone: "./phone[not(@type = 'fax')]",
90
- pub_fax: "./phone[@type = 'fax']", pub_email: "./email",
91
- pub_uri: "./uri" }.each do |k, v|
92
- n = a.at(ns(v)) and set(k, n.text)
93
- end
111
+ data = agency_data1(a)
112
+ data.compact.each do |k, v|
113
+ %i(name abbr logo).include?(k) and next
114
+ set(k, v)
115
+ end
94
116
  n = a.at(ns("./address/formattedAddress")) and
95
117
  set(:pub_address, n.children.to_xml)
96
118
  end
@@ -27,8 +27,10 @@ module IsoDoc
27
27
  end
28
28
 
29
29
  def prefix_name_labels(node)
30
- { elem: node["id"],
31
- name: "_#{UUIDTools::UUID.random_create}" }
30
+ @new_ids ||= {}
31
+ id = "_#{UUIDTools::UUID.random_create}"
32
+ @new_ids[id] = nil
33
+ { elem: node["id"], name: id }
32
34
  end
33
35
 
34
36
  def prefix_name_postprocess(node, elem)
@@ -45,7 +47,7 @@ module IsoDoc
45
47
  end
46
48
 
47
49
  def semx_fmt_dup(elem)
48
- elem["id"] ||= "_#{UUIDTools::UUID.random_create}"
50
+ add_id(elem)
49
51
  new = Nokogiri::XML(<<~XML).root
50
52
  <semx xmlns='#{elem.namespace.href}' element='#{elem.name}' source='#{elem['original-id'] || elem['id']}'>#{to_xml(elem.children)}</semx>
51
53
  XML
@@ -22,7 +22,7 @@ module IsoDoc
22
22
 
23
23
  def fnbody(fnote, seen)
24
24
  body = Nokogiri::XML::Node.new("fmt-fn-body", fnote.document)
25
- body["id"] = "_#{UUIDTools::UUID.random_create}"
25
+ add_id(body)
26
26
  body["target"] = fnote["id"]
27
27
  body["reference"] = fnote["reference"]
28
28
  body << semx_fmt_dup(fnote)
@@ -147,8 +147,8 @@ module IsoDoc
147
147
 
148
148
  def comment_body(elem)
149
149
  c1 = elem.after("<fmt-review-body/>").next
150
- elem.attributes.each_key { |k| c1[k] = elem[k] }
151
- c1["id"] = "_#{UUIDTools::UUID.random_create}"
150
+ elem.attributes.each_key { |k| k == "id" or c1[k] = elem[k] }
151
+ add_id(c1)
152
152
  c1 << semx_fmt_dup(elem)
153
153
  end
154
154
 
@@ -182,7 +182,7 @@ module IsoDoc
182
182
 
183
183
  def comment_bookmark_start(from, elem)
184
184
  ret = from.before("<fmt-review-start/>").previous
185
- ret["id"] = "_#{UUIDTools::UUID.random_create}"
185
+ add_id(ret)
186
186
  ret["source"] = elem["from"]
187
187
  comment_to_bookmark_attrs(elem, ret, start: true)
188
188
  ret << comment_bookmark_start_label(elem)
@@ -191,7 +191,7 @@ module IsoDoc
191
191
 
192
192
  def comment_bookmark_end(to, elem)
193
193
  ret = to.after("<fmt-review-end/>").next
194
- ret["id"] = "_#{UUIDTools::UUID.random_create}"
194
+ add_id(ret)
195
195
  ret["source"] = elem["to"]
196
196
  comment_to_bookmark_attrs(elem, ret, start: false)
197
197
  ret << comment_bookmark_end_label(elem)
@@ -1,32 +1,65 @@
1
1
  module IsoDoc
2
2
  class PresentationXMLConvert < ::IsoDoc::Convert
3
+ def add_id_text
4
+ id = "_#{UUIDTools::UUID.random_create}"
5
+ @new_ids[id] = nil
6
+ %(id="#{id}")
7
+ end
8
+
9
+ def add_id(elem)
10
+ elem["id"] and return
11
+ id = "_#{UUIDTools::UUID.random_create}"
12
+ elem["id"] = id
13
+ @new_ids[id] = nil
14
+ end
15
+
3
16
  def id_validate(docxml)
4
- repeat_id_validate(docxml)
17
+ add_missing_presxml_id(docxml)
18
+ repeat_id_validate(docxml) # feeds orig_id_cleanup
19
+ orig_id_cleanup(docxml)
5
20
  idref_validate(docxml)
21
+ contenthash_id_cleanup(docxml)
22
+ end
23
+
24
+ def add_missing_presxml_id(docxml)
25
+ docxml.xpath(ns("//fmt-name | //fmt-title | //fmt-definition | " \
26
+ "//fmt-sourcecode | //fmt-provision")).each do |x|
27
+ add_id(x)
28
+ end
6
29
  end
7
30
 
8
31
  def repeat_id_validate1(elem)
9
32
  if @doc_ids[elem["id"]]
10
- @log.add("Anchors", elem,
11
- "Anchor #{elem['id']} has already been " \
12
- "used at line #{@doc_ids[elem['id']]}", severity: 0)
33
+ @log&.add("Anchors", elem,
34
+ "Anchor #{elem['id']} has already been " \
35
+ "used at line #{@doc_ids[elem['id']]}", severity: 0)
13
36
  end
14
37
  @doc_ids[elem["id"]] = elem.line
15
38
  end
16
39
 
17
40
  def repeat_id_validate(doc)
18
- @log or return
19
41
  @doc_ids = {}
20
42
  doc.xpath("//*[@id]").each do |x|
21
43
  repeat_id_validate1(x)
22
44
  end
23
45
  end
24
46
 
47
+ # if have moved a new GUID id to original-id in copying, move it back to id
48
+ def orig_id_cleanup(docxml)
49
+ @doc_orig_ids = {}
50
+ docxml.xpath("//*[@original-id]").each do |x|
51
+ if !@doc_ids[x["original-id"]] && !x["id"]
52
+ x["id"] = x["original-id"]
53
+ x.delete("original-id")
54
+ @doc_ids[x["id"]] = x.line
55
+ else
56
+ @doc_orig_ids[x["original-id"]] = x.line
57
+ end
58
+ end
59
+ end
60
+
25
61
  def idref_validate(doc)
26
62
  @log or return
27
- doc.xpath("//*[@original-id]").each do |x|
28
- @doc_ids[x["original-id"]] = x.line
29
- end
30
63
  Metanorma::Utils::anchor_attributes(presxml: true).each do |e|
31
64
  doc.xpath("//xmlns:#{e[0]}[@#{e[1]}]").each do |x|
32
65
  idref_validate1(x, e[1])
@@ -37,12 +70,14 @@ module IsoDoc
37
70
  def idref_validate1(node, attr)
38
71
  node[attr].strip.empty? and return
39
72
  @doc_ids[node[attr]] and return
73
+ @doc_orig_ids[node[attr]] and return
40
74
  @log.add("Anchors", node,
41
75
  "Anchor #{node[attr]} pointed to by #{node.name} " \
42
76
  "is not defined in the document", severity: 1)
43
77
  end
44
78
 
45
79
  def provide_ids(docxml)
80
+ @new_ids = {} # guids assigned within Presentation XML
46
81
  anchor_sanitise(docxml)
47
82
  populate_id(docxml)
48
83
  add_missing_id(docxml)
@@ -65,8 +100,11 @@ module IsoDoc
65
100
 
66
101
  def add_missing_id(docxml)
67
102
  docxml.xpath(ns("//source | //modification | //erefstack | //fn | " \
68
- "//review | //floating-title")).each do |s|
69
- s["id"] ||= "_#{UUIDTools::UUID.random_create}"
103
+ "//review | //floating-title | //li | //executivesummary | " \
104
+ "//preface/abstract | //foreword | //introduction | //annex | " \
105
+ "//acknowledgements | //clause | //references | //terms | " \
106
+ "//preferred | //deprecates | //admitted | //related")).each do |s|
107
+ add_id(s)
70
108
  end
71
109
  end
72
110
 
@@ -75,5 +113,38 @@ module IsoDoc
75
113
  ret = ident.split("#", 2)
76
114
  ret.map { |x| Metanorma::Utils::to_ncname(x) }.join("#")
77
115
  end
116
+
117
+ def contenthash_id_cleanup(docxml)
118
+ add_new_contenthash_id(docxml, @new_ids)
119
+ xref_new_contenthash_id(docxml, @new_ids)
120
+ end
121
+
122
+ def add_new_contenthash_id(docxml, ids)
123
+ %w(original-id id).each do |k|
124
+ docxml.xpath("//*[@#{k}]").each do |x|
125
+ ids.has_key?(x[k]) or next
126
+ new_id = contenthash(x)
127
+ ids[x[k]] = new_id
128
+ x[k] = new_id
129
+ end
130
+ end
131
+ end
132
+
133
+ def xref_new_contenthash_id(docxml, ids)
134
+ Metanorma::Utils::anchor_attributes(presxml: true).each do |e|
135
+ docxml.xpath("//xmlns:#{e[0]}[@#{e[1]}]").each do |x|
136
+ ids.has_key?(x[e[1]]) or next
137
+ #require "debug"; binding.b unless ids[x[e[1]]]
138
+ ids[x[e[1]]] or next
139
+ x[e[1]] = ids[x[e[1]]]
140
+ end
141
+ end
142
+ end
143
+
144
+ # TODO duplicate of standoc
145
+ def contenthash(elem)
146
+ Digest::MD5.hexdigest("#{elem.path}////#{elem.text}")
147
+ .sub(/^(.{8})(.{4})(.{4})(.{4})(.{12})$/, "_\\1-\\2-\\3-\\4-\\5")
148
+ end
78
149
  end
79
150
  end
@@ -180,9 +180,5 @@ module IsoDoc
180
180
  node["height"] = e["height"]
181
181
  node["width"] = e["width"]
182
182
  end
183
-
184
- def imgfile_suffix(uri, suffix)
185
- "#{File.join(File.dirname(uri), File.basename(uri, '.*'))}.#{suffix}"
186
- end
187
183
  end
188
184
  end
@@ -4,10 +4,6 @@ module IsoDoc
4
4
  false
5
5
  end
6
6
 
7
- def add_id
8
- %(id="_#{UUIDTools::UUID.random_create}")
9
- end
10
-
11
7
  def strip_index(docxml)
12
8
  docxml.xpath(ns("//index | //index-xref | //indexsect")).each(&:remove)
13
9
  end
@@ -15,8 +11,10 @@ module IsoDoc
15
11
  def index(xml)
16
12
  if enable_indexsect && xml.at(ns("//index"))
17
13
  i = xml.at(ns("//indexsect")) ||
18
- xml.root.add_child("<indexsect #{add_id}><title>#{@i18n.index}" \
19
- "</title></indexsect>").first
14
+ xml.root.add_child(
15
+ "<indexsect #{add_id_text}>" \
16
+ "<fmt-title #{add_id_text}>#{@i18n.index}</fmt-title></indexsect>",
17
+ ).first
20
18
  index = sort_indexterms(xml.xpath(ns("//index")),
21
19
  xml.xpath(ns("//index-xref[@also = 'false']")),
22
20
  xml.xpath(ns("//index-xref[@also = 'true']")))
@@ -89,7 +87,7 @@ module IsoDoc
89
87
  end
90
88
 
91
89
  def index_entries_head(head, entries, opt)
92
- ret = "<li>#{head}"
90
+ ret = "<li #{add_id_text}>#{head}"
93
91
  xref = entries&.dig(:xref)&.join(", ")
94
92
  see = index_entries_see(entries, :see)
95
93
  also = index_entries_see(entries, :also)
@@ -173,7 +171,7 @@ module IsoDoc
173
171
  def index2bookmark(node)
174
172
  node.name = "bookmark"
175
173
  node.children.each(&:remove)
176
- node["id"] = "_#{UUIDTools::UUID.random_create}"
174
+ add_id(node)
177
175
  node.delete("to")
178
176
  end
179
177
  end
@@ -18,7 +18,7 @@ module IsoDoc
18
18
 
19
19
  def attachments_extract(docxml)
20
20
  docxml.at(ns("//metanorma-extension/attachment")) or return
21
- dir = File.join(@localdir, "_#{@outputfile}_attachments")
21
+ dir = File.join(@output_dir, "_#{@outputfile}_attachments")
22
22
  FileUtils.rm_rf(dir)
23
23
  FileUtils.mkdir_p(dir)
24
24
  docxml.xpath(ns("//metanorma-extension/attachment")).each do |a|
@@ -211,6 +211,7 @@ module IsoDoc
211
211
  date_note = bib.at(ns("./note[@type = 'Unpublished-Status']"))
212
212
  date_note.nil? and return ret
213
213
  id = "_#{UUIDTools::UUID.random_create}"
214
+ @new_ids[id] = nil
214
215
  "#{ret}<fn id='#{id}' reference='#{id}'><p>#{date_note.content}</p></fn>"
215
216
  end
216
217
 
@@ -44,7 +44,7 @@ module IsoDoc
44
44
  level = @xrefs.anchor(elem["id"], :level, false) ||
45
45
  (elem.ancestors("clause, annex").size + 1)
46
46
  is_unnumbered = unnumbered_clause?(elem)
47
- lbl = @xrefs.anchor(elem["id"], :label, !is_unnumbered)
47
+ lbl = @xrefs.anchor(elem["id"], :label, false)
48
48
  if is_unnumbered || !lbl
49
49
  prefix_name(elem, {}, nil, "title")
50
50
  else
@@ -179,7 +179,7 @@ module IsoDoc
179
179
 
180
180
  def toc_refs(docxml)
181
181
  docxml.xpath(ns("//toc//xref[text()]")).each do |x|
182
- lbl = @xrefs.anchor(x["target"], :label) or next
182
+ lbl = @xrefs.anchor(x["target"], :label, false) or next
183
183
  x.add_first_child "#{lbl}<span class='fmt-caption-delim'><tab/></span>"
184
184
  end
185
185
  end
@@ -47,7 +47,7 @@ module IsoDoc
47
47
  end
48
48
 
49
49
  def termnote_label(elem)
50
- @xrefs.anchor(elem["id"], :label) || "???"
50
+ @xrefs.anchor(elem["id"], :label, false) || "???"
51
51
  end
52
52
 
53
53
  def termdefinition(docxml)
@@ -71,9 +71,9 @@ module IsoDoc
71
71
 
72
72
  def multidef(_elem, defn, fmt_defn)
73
73
  ret = defn.each_with_object([]) do |f, m|
74
- m << "<li>#{to_xml(semx_fmt_dup(f))}</li>"
74
+ m << "<li #{add_id_text}>#{to_xml(semx_fmt_dup(f))}</li>"
75
75
  end
76
- fmt_defn << "<ol>#{ret.join("\n")}</ol>"
76
+ fmt_defn << "<ol #{add_id_text}>#{ret.join("\n")}</ol>"
77
77
  end
78
78
 
79
79
  def singledef(_elem, defn, fmt_defn)
@@ -191,7 +191,7 @@ module IsoDoc
191
191
  end
192
192
 
193
193
  def term1(elem)
194
- lbl = @xrefs.anchor(elem["id"], :label) or return
194
+ lbl = @xrefs.anchor(elem["id"], :label, false) or return
195
195
  prefix_name(elem, {}, "#{lbl}#{clausedelim}", "name")
196
196
  end
197
197
  end
@@ -87,9 +87,8 @@ module IsoDoc
87
87
  def toc_title(docxml)
88
88
  docxml.at(ns("//preface/clause[@type = 'toc']")) and return
89
89
  ins = toc_title_insert_pt(docxml) or return
90
- id = UUIDTools::UUID.random_create.to_s
91
90
  ins.previous = <<~CLAUSE
92
- <clause type = 'toc' id='_#{id}'><fmt-title depth='1'>#{@i18n.table_of_contents}</fmt-title></clause>
91
+ <clause type = 'toc' #{add_id_text}><fmt-title depth='1'>#{@i18n.table_of_contents}</fmt-title></clause>
93
92
  CLAUSE
94
93
  end
95
94
 
@@ -1,3 +1,3 @@
1
1
  module IsoDoc
2
- VERSION = "3.1.10".freeze
2
+ VERSION = "3.1.11".freeze
3
3
  end
@@ -120,14 +120,33 @@ module IsoDoc
120
120
  end
121
121
  end
122
122
 
123
+ def datauri_word(uri)
124
+ ret = %r{^data:}.match?(uri) ? save_dataimage(uri) : uri
125
+ if ret.end_with?(".svg")
126
+ v = Vectory::Svg.from_node(Nokogiri::XML(File.read(ret))).to_emf
127
+ target_path = imgfile_suffix(ret, "emf")
128
+ v.write(target_path).to_uri.content
129
+ ret = target_path
130
+ end
131
+ ret
132
+ end
133
+
123
134
  def info(xml, out)
124
- @tocfigurestitle =
125
- xml.at(ns("//metanorma-extension/toc[@type = 'figure']/title"))&.text
126
- @toctablestitle =
127
- xml.at(ns("//metanorma-extension/toc[@type = 'table']/title"))&.text
128
- @tocrecommendationstitle = xml
129
- .at(ns("//metanorma-extension/toc[@type = 'recommendation']/title"))&.text
135
+ toc_info(xml)
130
136
  super
137
+ if logos = @meta.get[:copublisher_logos] # may be DataURI
138
+ logos.map! { |l| datauri_word(l) }
139
+ @meta.set(:copublisher_logos, logos)
140
+ end
141
+ @meta.get
142
+ end
143
+
144
+ def toc_info(xml)
145
+ toc = "metanorma-extension/toc"
146
+ @tocfigurestitle = xml.at(ns("//#{toc}[@type = 'figure']/title"))&.text
147
+ @toctablestitle = xml.at(ns("//#{toc}[@type = 'table']/title"))&.text
148
+ @tocrecommendationstitle =
149
+ xml.at(ns("//#{toc}[@type = 'recommendation']/title"))&.text
131
150
  end
132
151
 
133
152
  def table_of_contents(clause, out)
@@ -46,7 +46,7 @@ module IsoDoc
46
46
  out.div style: "mso-element:comment", id: node["id"] do |div|
47
47
  div.span style: %{mso-comment-author:"#{node['reviewer']}"}
48
48
  make_comment_target(div)
49
- node.children.each { |n| parse(n, div) }
49
+ children_parse(node, div)
50
50
  end
51
51
  end
52
52
 
@@ -16,7 +16,7 @@ module IsoDoc
16
16
  tag = aside ? "aside" : "div"
17
17
  id = node["is_table"] ? node["reference"] : node["id"]
18
18
  out.send tag, id: "ftn#{id}" do |div|
19
- node.children.each { |n| parse(n, div) }
19
+ children_parse(node, div)
20
20
  end
21
21
  end
22
22
 
@@ -36,7 +36,8 @@ module IsoDoc
36
36
  def footnote_parse(node, out)
37
37
  table_footnote?(node) and return table_footnote_parse(node, out)
38
38
  fn = node["reference"] # || UUIDTools::UUID.random_create.to_s
39
- @seen_footnote.include?(fn) and return seen_footnote_parse(node, out, fn)
39
+ @seen_footnote.include?(fn) and return seen_footnote_parse(node, out,
40
+ fn)
40
41
  @fn_bookmarks[fn] = bookmarkid
41
42
  f = footnote_label_process(node)
42
43
  out.span style: "mso-bookmark:_Ref#{@fn_bookmarks[fn]}",
@@ -67,7 +67,7 @@ module IsoDoc
67
67
  "##{node['target']}"
68
68
  end
69
69
  out.a(href: target) do |l|
70
- node.children.each { |n| parse(n, l) }
70
+ children_parse(node, l)
71
71
  end
72
72
  end
73
73
 
@@ -84,14 +84,14 @@ module IsoDoc
84
84
  r.replace(r.at(ns("./ruby/rb")))
85
85
  end
86
86
  out.ruby do |e|
87
- node.children.each { |n| parse(n, e) }
87
+ children_parse(node, e)
88
88
  end
89
89
  double_ruby and out << "(#{double_ruby.text})"
90
90
  end
91
91
 
92
92
  def rt_parse(node, out)
93
93
  out.rt **{ style: "font-size: 6pt;" } do |e|
94
- node.children.each { |n| parse(n, e) }
94
+ children_parse(node, e)
95
95
  end
96
96
  end
97
97
  end
@@ -147,7 +147,7 @@ refer_list)
147
147
  list_item_value(li, c, depth,
148
148
  { list_anchor:, prev_label:,
149
149
  refer_list: depth == 1 ? refer_list : nil })
150
- li["id"] ||= "_#{UUIDTools::UUID.random_create}"
150
+ #li["id"] ||= "_#{UUIDTools::UUID.random_create}"
151
151
  @anchors[li["id"]] =
152
152
  { label: bare_label, bare_xref: "#{label})", type: "listitem",
153
153
  xref: %[#{label}#{delim_wrap(list_item_delim)}], refer_list:,
@@ -106,7 +106,7 @@ module IsoDoc
106
106
 
107
107
  def preface_name_anchors(clause, level, title)
108
108
  xref = semx(clause, title, clause.name)
109
- clause["id"] ||= "_#{UUIDTools::UUID.random_create}"
109
+ #clause["id"] ||= "_#{UUIDTools::UUID.random_create}"
110
110
  @anchors[clause["id"]] =
111
111
  { label: nil, level:,
112
112
  xref:, title: nil,
@@ -162,7 +162,7 @@ module IsoDoc
162
162
  xref = labelled_autonum(@labels["clause"], num)
163
163
  label = num
164
164
  c = clause_title(clause) and title = semx(clause, c, "title")
165
- clause["id"] ||= "_#{UUIDTools::UUID.random_create}"
165
+ #clause["id"] ||= "_#{UUIDTools::UUID.random_create}"
166
166
  @anchors[clause["id"]] =
167
167
  { label:, xref:, title:, level:, type: "clause",
168
168
  elem: @labels["clause"] }
@@ -184,7 +184,7 @@ module IsoDoc
184
184
  level == 1 && clause.name == "annex" and
185
185
  label = annex_name_lbl(clause, label)
186
186
  c = clause_title(clause) and title = semx(clause, c, "title")
187
- clause["id"] ||= "_#{UUIDTools::UUID.random_create}"
187
+ #clause["id"] ||= "_#{UUIDTools::UUID.random_create}"
188
188
  @anchors[clause["id"]] =
189
189
  { label:, xref: labelled_autonum(@labels["annex"], num), title:,
190
190
  elem: @labels["annex"], type: "clause",
@@ -13,6 +13,8 @@ module IsoDoc
13
13
  pdfallowaccesscontent: "--allow-access-content",
14
14
  pdfallowassembledocument: "--allow-assemble-document",
15
15
  pdfallowprinthq: "--allow-print-hq",
16
+ pdfstylesheet: "--xsl-file",
17
+ pdfstylesheet_override: "--xsl-file-override",
16
18
  pdfencryptmetadata: "--encrypt-metadata" }.freeze
17
19
  MN2PDF_DEFAULT_ARGS = { "--syntax-highlight": nil }.freeze
18
20
 
@@ -54,23 +56,38 @@ module IsoDoc
54
56
  @aligncrosselements.tr(",", " ")
55
57
  @baseassetpath and
56
58
  ret["--param baseassetpath="] = @baseassetpath
57
- ret.merge(@pdf_cmd_options)
59
+ ret = ret.merge(@pdf_cmd_options)
60
+ %w(--xsl-file --xsl-file-override).each do |x|
61
+ ret[x] &&= Pathname.new(File.expand_path(ret[x])).to_s
62
+ #.relative_path_from(File.dirname(@xsl)).to_s
63
+ end
64
+ if ret["--xsl-file"]
65
+ @xsl = ret["--xsl-file"]
66
+ ret.delete("--xsl-file")
67
+ end
68
+ ret
58
69
  end
59
70
 
60
71
  # input_file: keep-alive tempfile
61
72
  def convert(input_fname, file = nil, debug = false,
62
73
  output_fname = nil)
63
- file ||= File.read(input_fname, encoding: "utf-8")
64
- _, docxml, filename = input_xml_path(input_fname, file, debug)
65
- xsl = pdf_stylesheet(docxml) or return
66
- Pathname.new(xsl).absolute? or xsl = File.join(@libdir, xsl)
67
- @doctype = Nokogiri::XML(file).at(ns("//bibdata/ext/doctype"))&.text
74
+ _, docxml, filename = convert_prep(input_fname, file, debug)
75
+ opts = pdf_options(docxml, input_fname)
68
76
  ::Metanorma::Output::XslfoPdf.new.convert(
69
77
  filename, output_fname || output_filename(input_fname),
70
- xsl, pdf_options(docxml, input_fname)
78
+ @xsl, opts
71
79
  )
72
80
  end
73
81
 
82
+ def convert_prep(input_fname, file, debug)
83
+ file ||= File.read(input_fname, encoding: "utf-8")
84
+ _, docxml, filename = input_xml_path(input_fname, file, debug)
85
+ @xsl = pdf_stylesheet(docxml) or return
86
+ Pathname.new(@xsl).absolute? or @xsl = File.join(@libdir, @xsl)
87
+ @doctype = docxml.at(ns("//bibdata/ext/doctype"))&.text
88
+ [file, docxml, filename]
89
+ end
90
+
74
91
  def output_filename(input_fname)
75
92
  out = input_fname.sub(/\.presentation\.xml$/, ".xml")
76
93
  File.join(File.dirname(input_fname),
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: 3.1.10
4
+ version: 3.1.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-05-26 00:00:00.000000000 Z
11
+ date: 2025-06-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: base64