metanorma 2.1.7 → 2.1.9

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: b9a70c61c914359e1637bfdf33edb5e2e560b92d2dd3922db64cec7fecaa5e32
4
- data.tar.gz: fd5c55fe248e1a36e2ec0f25689aeb4b149ba94200daea52edea4a73065db69f
3
+ metadata.gz: b6f662b6213511d30fb8f16f0bc51bb4209959a4f17ac385d81bdd02f1135088
4
+ data.tar.gz: 4021db66267ad5cbc213058d7b2252d6a2f9572e6efd686df2f84ba1f1965cbb
5
5
  SHA512:
6
- metadata.gz: 237cff4f2cb22825906017cd7286b7a3578603f0816b3b4c699117eb212b384fef8fac5d8d68a31ba6261b6b525db7375d2a796b4f0d4b689563026fecfa9381
7
- data.tar.gz: 9a72304008e8e4c5d5571210d6a704389b88dbf85223f16709ace9c878fb761161f1aca7549642dd91a4a5030fa648d7203b43b3a2983f6a445bd1dfcd82a761
6
+ metadata.gz: 6ba138f8fd28e6e4ee1d0fcc786f49b17b816483c39a6d2dda89643b9611bed93068ac8f3e700ba199a01f0f0446ce2c46be97d4a7e705a67df04e6b1d898432
7
+ data.tar.gz: 45a50ed06452ff4e598bc95ce07412eeca39b33afe7158a48f17080381417cda79ba4ed4286901652a6e4f6311d0ad70e083388aba4e3150c22f543f56825dde
@@ -172,7 +172,7 @@ module Metanorma
172
172
  def fetch_flavor
173
173
  docid = @bibdata.docidentifier.first or return
174
174
  f = docid.type.downcase || docid.id.sub(/\s.*$/, "").downcase or return
175
- require ::Metanorma::Compile.new.stdtype2flavor(f)
175
+ require ::Metanorma::Compile.new.stdtype2flavor_gem(f)
176
176
  f
177
177
  rescue LoadError
178
178
  nil
@@ -68,6 +68,8 @@ module Metanorma
68
68
  def from_xml(xml)
69
69
  b = xml.at("//xmlns:bibitem|//xmlns:bibdata")
70
70
  r = mn2relaton_parser(xml.root.name)
71
+ # Relaton doesn't understand Pres XML tags
72
+ b.xpath("//xmlns:fmt-identifier").each(&:remove)
71
73
  r.from_xml(b.to_xml)
72
74
  end
73
75
 
@@ -18,6 +18,7 @@ module Metanorma
18
18
  @parent = parent
19
19
  @xml = parent.xml
20
20
  @isodoc = parent.isodoc
21
+ @isodoc_presxml = parent.isodoc_presxml
21
22
  @path = path
22
23
  @compile = parent.compile
23
24
  @documents = parent.documents
@@ -131,7 +132,7 @@ module Metanorma
131
132
 
132
133
  def add_document_suffix(identifier, doc)
133
134
  document_suffix = Metanorma::Utils::to_ncname(identifier)
134
- Metanorma::Utils::anchor_attributes.each do |(tag_name, attr_name)|
135
+ Util::anchor_id_attributes.each do |(tag_name, attr_name)|
135
136
  Util::add_suffix_to_attrs(doc, document_suffix, tag_name, attr_name,
136
137
  @isodoc)
137
138
  end
@@ -230,7 +231,6 @@ module Metanorma
230
231
  ret = {}
231
232
  xml.traverse do |x|
232
233
  x.text? and next
233
- /^semantic__/.match?(x.name) and next
234
234
  x["id"] and ret[x["id"]] = true
235
235
  end
236
236
  ret
@@ -110,8 +110,9 @@ module Metanorma
110
110
  @sectionsplit = ::Metanorma::Collection::Sectionsplit
111
111
  .new(input: file, base: @files[ident][:out_path],
112
112
  dir: File.dirname(file), output: @files[ident][:out_path],
113
- compile_opts: @parent.compile_options,
114
- fileslookup: self, ident: ident, isodoc: @isodoc,
113
+ compile_opts: @parent.compile_options, ident: ident,
114
+ fileslookup: self, isodoc: @isodoc,
115
+ isodoc_presxml: @isodoc_presxml,
115
116
  document_suffix: @files[ident][:document_suffix])
116
117
  coll = @sectionsplit.sectionsplit.sort_by { |f| f[:order] }
117
118
  xml = Nokogiri::XML(File.read(file, encoding: "UTF-8"), &:huge)
@@ -16,8 +16,6 @@ module Metanorma
16
16
  # @return [String] XML content
17
17
  def update_xrefs(file, docid, internal_refs)
18
18
  xml, sso = update_xrefs_prep(file, docid)
19
- #require "debug"; binding.b if /This document is also unrelated/.match?(xml.to_xml)
20
- #warn (/fmt-title/.match?(xml.to_xml) ? "*** PRESENTATION" : "*** SEMANTIC")
21
19
  @nested || sso or
22
20
  Metanorma::Collection::XrefProcess::xref_process(xml, xml, nil, docid,
23
21
  @isodoc, sso)
@@ -26,7 +24,7 @@ module Metanorma
26
24
  @files.add_document_suffix(docid, xml)
27
25
  @nested or update_sectionsplit_refs_to_docs(xml, internal_refs, sso)
28
26
  update_direct_refs_to_docs(xml, docid, sso)
29
- hide_refs(xml)
27
+ ::Metanorma::Collection::Util::hide_refs(xml)
30
28
  sso and eref2link(xml, sso)
31
29
  @nested or svgmap_resolve(xml, docid, sso)
32
30
  xml.to_xml
@@ -109,7 +107,6 @@ module Metanorma
109
107
  else no_anchor[k] << e end
110
108
  end
111
109
  end
112
- #require "debug"; binding.b
113
110
  [erefs, no_anchor, anchors, Util::gather_bibitemids(docxml, presxml)]
114
111
  end
115
112
 
@@ -128,8 +125,9 @@ module Metanorma
128
125
 
129
126
  # Resolve erefs to a container of ids in another doc,
130
127
  # to an anchor eref (direct link)
131
- def update_indirect_refs_to_docs(docxml, _docidentifier, internal_refs, presxml)
132
- bib, erefs, doc_suffix, doc_type, f = update_indirect_refs_prep(docxml, presxml)
128
+ def update_indirect_refs_to_docs(docxml, _docid, internal_refs, presxml)
129
+ bib, erefs, doc_suffix, doc_type, f = update_indirect_refs_prep(docxml,
130
+ presxml)
133
131
  internal_refs.each do |schema, ids|
134
132
  add_suffix = doc_suffix && doc_type && doc_type != schema
135
133
  ids.each do |id, file|
@@ -149,37 +147,15 @@ module Metanorma
149
147
  docxml.root["document_suffix"], docxml.root["type"], {}]
150
148
  end
151
149
 
152
- # KILL
153
- def indirect_ref_key(schema, id, doc_suffix, doc_type)
154
- /^#{schema}_/.match?(id) and return id
155
- key = [schema, id, doc_suffix, doc_type].join("::")
156
- x = @indirect_keys[key] and return x
157
- ret = "#{schema}_#{id}"
158
- doc_suffix && doc_type && doc_type != schema and
159
- ret = "#{ret}_#{doc_suffix}"
160
- @indirect_keys[key] = ret
161
- ret
162
- end
163
-
164
150
  def indirect_ref_key(schema, id, doc_suffix, add_suffix)
165
151
  /^#{schema}_/.match?(id) and return id
166
- #key = "#{schema}_#{id}"
167
152
  x = @indirect_keys.dig(schema, id) and return x
168
153
  @indirect_keys[schema] ||= {}
169
154
  @indirect_keys[schema][id] = if add_suffix
170
- "#{schema}_#{id}_#{doc_suffix}"
171
- else
172
- "#{schema}_#{id}"
173
- end
174
- end
175
-
176
- # KILL
177
- def indirect_ref_keyx(schema, id, doc_suffix, doc_type)
178
- /^#{schema}_/.match?(id) and return id
179
- ret = "#{schema}_#{id}"
180
- doc_suffix && doc_type && doc_type != schema and
181
- ret = "#{ret}_#{doc_suffix}"
182
- ret
155
+ "#{schema}_#{id}_#{doc_suffix}"
156
+ else
157
+ "#{schema}_#{id}"
158
+ end
183
159
  end
184
160
 
185
161
  def update_indirect_refs_to_docs1(filec, key, file, bibitems, erefs)
@@ -196,13 +172,10 @@ module Metanorma
196
172
  parentid and file = "#{parentid}_#{file}"
197
173
  existing = a.text
198
174
  anchor = if url then existing
199
- else
200
- #suffix_anchor_indirect(existing, suffix)
201
- #k = "#{existing}_#{file}"
202
- #@ncnames[k] ||= Metanorma::Utils::to_ncname(k)
203
- @indirect_keys[existing] ||= {}
204
- @indirect_keys[existing][file] ||= Metanorma::Utils::to_ncname("#{existing}_#{file}")
205
- end
175
+ else
176
+ @indirect_keys[existing] ||= {}
177
+ @indirect_keys[existing][file] ||= Metanorma::Utils::to_ncname("#{existing}_#{file}")
178
+ end
206
179
  @updated_anchors[existing] or a.children = anchor
207
180
  @updated_anchors[anchor] = true
208
181
  end
@@ -15,7 +15,7 @@ module Metanorma
15
15
  class Renderer
16
16
  FORMATS = %i[html xml doc pdf].freeze
17
17
 
18
- attr_accessor :isodoc, :nested
18
+ attr_accessor :isodoc, :isodoc_presxml, :nested
19
19
  attr_reader :xml, :compile, :compile_options, :documents, :outdir,
20
20
  :manifest
21
21
 
@@ -45,6 +45,8 @@ module Metanorma
45
45
 
46
46
  # output processor for flavour
47
47
  @isodoc = Util::isodoc_create(@flavor, @lang, @script, @xml)
48
+ @isodoc_presxml = Util::isodoc_create(@flavor, @lang, @script, @xml,
49
+ presxml: true)
48
50
  @outdir = dir_name_cleanse(options[:output_folder])
49
51
  @coverpage = options[:coverpage] || collection.coverpage
50
52
  @format = ::Metanorma::Util.sort_extensions_execution(options[:format])
@@ -17,6 +17,7 @@ module Metanorma
17
17
  newbib["hidden"] = "true"
18
18
  newbib&.at("./*[local-name() = 'ext']")&.remove
19
19
  newbib["id"] = bib["id"]
20
+ bib["anchor"] and newbib["anchor"] = bib["anchor"]
20
21
  newbib
21
22
  end
22
23
 
@@ -37,17 +38,10 @@ module Metanorma
37
38
  end
38
39
  end
39
40
 
40
- def hide_refs(docxml)
41
- docxml.xpath(ns("//references[bibitem][not(./bibitem[not(@hidden) or " \
42
- "@hidden = 'false'])]")).each do |f|
43
- f["hidden"] = "true"
44
- end
45
- end
46
-
47
41
  def new_hidden_ref(xmldoc)
48
42
  ins = xmldoc.at(ns("bibliography")) or
49
43
  xmldoc.root << "<bibliography/>" and ins = xmldoc.at(ns("bibliography"))
50
- ins.at(ns("./referenced[@hidden = 'true']")) or
44
+ ins.at(ns("./references[@hidden = 'true']")) or
51
45
  ins.add_child("<references hidden='true' normative='false'/>").first
52
46
  end
53
47
 
@@ -81,7 +75,7 @@ module Metanorma
81
75
  refs.each do |k, v|
82
76
  url = @files.url(v, {})
83
77
  ins << <<~XML
84
- <bibitem id="#{k}">#{docid_xml(v)}<uri type='citation'>#{url}</uri></bibitem>
78
+ <bibitem id="#{k}" anchor="#{k}">#{docid_xml(v)}<uri type='citation'>#{url}</uri></bibitem>
85
79
  XML
86
80
  end
87
81
  end
@@ -39,6 +39,7 @@ module Metanorma
39
39
  end
40
40
 
41
41
  def collectionyaml(files, xml)
42
+ #warn xml.to_xml
42
43
  ret = {
43
44
  directives: ["presentation-xml", "bare-after-first"],
44
45
  bibdata: {
@@ -19,6 +19,7 @@ module Metanorma
19
19
  @fileslookup = opts[:fileslookup]
20
20
  @ident = opts[:ident]
21
21
  @isodoc = opts[:isodoc]
22
+ @isodoc_presxml = opts[:isodoc_presxml]
22
23
  @document_suffix = opts[:document_suffix]
23
24
  end
24
25
 
@@ -32,18 +33,19 @@ module Metanorma
32
33
  ["//bibliography/*[not(@hidden = 'true')]", "bibliography"],
33
34
  ["//indexsect", nil], ["//colophon", nil]].freeze
34
35
 
35
- # Input XML is Semantic
36
+ # Input XML is Semantic XML
36
37
  def sectionsplit
37
38
  xml = sectionsplit_prep(File.read(@input_filename), @base, @dir)
38
39
  @key = Metanorma::Collection::XrefProcess::xref_preprocess(xml, @isodoc)
39
40
  empty = empty_doc(xml)
40
41
  empty1 = empty_attachments(empty)
41
42
  @mutex = Mutex.new
42
- #@pool = Concurrent::FixedThreadPool.new(4)
43
+ # @pool = Concurrent::FixedThreadPool.new(4)
43
44
  @pool = Concurrent::FixedThreadPool.new(1)
44
45
  sectionsplit1(xml, empty, empty1, 0)
45
46
  end
46
47
 
48
+ # xml is Presentation XML
47
49
  def sectionsplit1(xml, empty, empty1, idx)
48
50
  ret = SPLITSECTIONS.each_with_object([]) do |n, m|
49
51
  conflate_floatingtitles(xml.xpath(ns(n[0]))).each do |s|
@@ -59,12 +61,14 @@ module Metanorma
59
61
 
60
62
  def sectionsplit2(xml, empty, chunks, parentnode, opt)
61
63
  @pool.post do
64
+ warn "#{@base}.#{opt[:idx]}"
62
65
  a = sectionfile(xml, empty, "#{@base}.#{opt[:idx]}", chunks,
63
66
  parentnode)
64
67
  @mutex.synchronize { opt[:acc] << a }
65
68
  end
66
69
  end
67
70
 
71
+ # TODO move to metanorma-utils
68
72
  def block?(node)
69
73
  %w(p table formula admonition ol ul dl figure quote sourcecode example
70
74
  pre note pagebreak hr bookmark requirement recommendation permission
@@ -86,7 +90,6 @@ module Metanorma
86
90
  xml, type = sectionsplit_preprocess_semxml(file, filename)
87
91
  flags = { format: :asciidoc, extension_keys: [:presentation],
88
92
  type: type }.merge(@compile_opts)
89
- #require "debug"; binding.b
90
93
  Compile.new.compile(xml, flags)
91
94
  f = File.open(xml.sub(/\.xml$/, ".presentation.xml"), encoding: "utf-8")
92
95
  r = Nokogiri::XML(f, &:huge)
@@ -109,7 +112,6 @@ module Metanorma
109
112
  if c = @fileslookup&.parent
110
113
  n = c.nested
111
114
  c.nested = true # so unresolved erefs are not deleted
112
- #require "debug"; binding.b
113
115
  c.update_xrefs(xml, @ident, {})
114
116
  c.nested = n
115
117
  xml.xpath("//xmlns:svgmap").each { |x| x.name = "svgmap1" }
@@ -125,35 +127,19 @@ module Metanorma
125
127
  outname
126
128
  end
127
129
 
128
- def emptydoc(xml, ordinal)
129
- out = xml.dup
130
- out.xpath(
131
- ns("//preface | //sections | //annex | //bibliography/clause | " \
132
- "//bibliography/references[not(@hidden = 'true')] | " \
133
- "//indexsect | //colophon"),
134
- ).each(&:remove)
135
- ordinal.zero? or out.xpath(ns("//metanorma-ext//attachment | " \
136
- "//semantic__metanorma-ext//semantic__attachment"))
137
- .each(&:remove) # keep only one copy of attachments
138
- out
139
- end
140
-
141
130
  def empty_doc(xml)
142
131
  out = xml.dup
143
132
  out.xpath(
144
- ns("//preface | //sections | //annex | //bibliography/clause | " \
145
- "//bibliography/references[not(@hidden = 'true')] | " \
146
- "//indexsect | //colophon"),
133
+ ns("//preface | //sections | //annex | " \
134
+ "//references/bibitem[not(@hidden = 'true')] | " \
135
+ "//indexsect | //colophon"),
147
136
  ).each(&:remove)
137
+ ::Metanorma::Collection::Util::hide_refs(out)
148
138
  out
149
139
  end
150
140
 
151
141
  def empty_attachments(xml)
152
- out = xml.dup
153
- out.xpath(ns("//metanorma-ext//attachment | " \
154
- "//semantic__metanorma-ext//semantic__attachment"))
155
- .each(&:remove) # keep only one copy of attachments
156
- out
142
+ xml.dup
157
143
  end
158
144
 
159
145
  def sectionfile(fulldoc, xml, file, chunks, parentnode)
@@ -164,11 +150,10 @@ module Metanorma
164
150
 
165
151
  def create_sectionfile(xml, out, file, chunks, parentnode)
166
152
  ins = out.at(ns("//metanorma-extension")) || out.at(ns("//bibdata"))
167
- #require "debug"; binding.b
168
153
  sectionfile_insert(ins, chunks, parentnode)
154
+ sectionfile_fn_filter(sectionfile_review_filter(out))
169
155
  Metanorma::Collection::XrefProcess::xref_process(out, xml, @key,
170
156
  @ident, @isodoc, true)
171
- #truncate_semxml(out, chunks)
172
157
  outname = "#{file}.xml"
173
158
  File.open(File.join(@splitdir, outname), "w:UTF-8") do |f|
174
159
  f.write(out)
@@ -176,36 +161,86 @@ module Metanorma
176
161
  outname
177
162
  end
178
163
 
179
- # KILL
180
- def semantic_xml_ids_gather(out)
181
- out.at(ns("//semantic__bibdata")) or return
182
- SPLITSECTIONS.each_with_object({}) do |s, m|
183
- out.xpath(ns(s[0].sub("//", "//semantic__"))).each do |x|
184
- x["id"] or next
185
- m[x["id"].sub(/^semantic__/, "")] = x
164
+ def sectionfile_insert(ins, chunks, parentnode)
165
+ if parentnode
166
+ ins.next = "<#{parentnode}/>"
167
+ chunks.each { |c| ins.next.add_child(c.dup) }
168
+ else chunks.each { |c| ins.next = c.dup }
169
+ end
170
+ end
171
+
172
+ def sectionfile_fn_filter(xml)
173
+ ids = sectionfile_fn_filter_prep(xml)
174
+ xml.root.xpath(ns("./fmt-footnote-container/fmt-fn-body")).each do |f|
175
+ ids.has_key?(f["id"]) or f.remove
176
+ end
177
+ seen = {}
178
+ xml.root.xpath(ns("/fmt-footnote-container/fmt-fn-body"))
179
+ .each_with_index do |fnbody, i|
180
+ sectionfile_fn_filter_renumber(fnbody, i, ids, seen)
186
181
  end
182
+ xml
183
+ end
184
+
185
+ # map fmt-fn-body/@id = fn/@target to fn
186
+ def sectionfile_fn_filter_prep(xml)
187
+ xml.xpath(ns("//fn")).each_with_object({}) do |f, m|
188
+ m[f["target"]] ||= []
189
+ m[f["target"]] << f
187
190
  end
188
191
  end
189
192
 
190
- # KILL
191
- def semxml_presxml_nodes_match(nodes, chunks)
192
- chunks.each do |x|
193
- nodes[x["id"]] and nodes.delete(x["id"])
193
+ FN_CAPTIONS = ".//fmt-fn-label/span[@class = 'fmt-caption-label']".freeze
194
+
195
+ def sectionfile_fn_filter_renumber(fnbody, idx, ids, seen)
196
+ sectionfile_fn_filter_fn_renumber(fnbody, idx, ids, seen)
197
+ sectionfile_fn_filter_fnbody_renumber(fnbody, idx, ids)
198
+ end
199
+
200
+ def sectionfile_fn_filter_fn_renumber(fnbody, idx, ids, seen)
201
+ ids[fnbody["id"]].each do |f|
202
+ @isodoc_presxml.renumber_document_footnote(f, idx, seen)
203
+ fnlabel = f.at(ns(FN_CAPTIONS)) and
204
+ fnlabel.children = @isodoc_presxml.fn_ref_label(f)
194
205
  end
195
206
  end
196
207
 
197
- # KILL
198
- def truncate_semxml(out, chunks)
199
- nodes = semantic_xml_ids_gather(out) or return
200
- semxml_presxml_nodes_match(nodes, chunks)
201
- nodes.each_value(&:remove)
208
+ def sectionfile_fn_filter_fnbody_renumber(fnbody, _idx, ids)
209
+ fnlabel = fnbody.at(ns(FN_CAPTIONS)) or return
210
+ fnbody["reference"] = ids[fnbody["id"]].first["reference"]
211
+ fnlabel.children = @isodoc_presxml.fn_body_label(fnbody)
202
212
  end
203
213
 
204
- def sectionfile_insert(ins, chunks, parentnode)
205
- if parentnode
206
- ins.next = "<#{parentnode}/>"
207
- chunks.each { |c| ins.next.add_child(c.dup) }
208
- else chunks.each { |c| ins.next = c.dup }
214
+ # map fmt-review-body/@id = fmt-review-{start/end}/@target
215
+ # to fmt-review-{stary/end}
216
+ def sectionfile_review_filter_prep(xml)
217
+ xml.xpath(ns("//fmt-review-start | //fmt-review-end"))
218
+ .each_with_object({}) do |f, m|
219
+ m[f["target"]] ||= []
220
+ m[f["target"]] << f
221
+ end
222
+ end
223
+
224
+ def sectionfile_review_filter(xml)
225
+ ids = sectionfile_review_filter_prep(xml)
226
+ xml.root.xpath(ns("./review-container/fmt-review-body")).each do |f|
227
+ ids.has_key?(f["id"]) or f.remove
228
+ end
229
+ xml.root.xpath(ns("./review-container/fmt-review-body"))
230
+ .each_with_index do |fnbody, i|
231
+ sectionfile_review_filter_renumber(fnbody, i, ids)
232
+ end
233
+ xml
234
+ end
235
+
236
+ def sectionfile_review_filter_renumber(fnbody, _idx, ids)
237
+ ids[fnbody["id"]].each do |f|
238
+ case f.name
239
+ when "fmt-review-start"
240
+ f.children = @isodoc_presxml.comment_bookmark_start_label(f)
241
+ when "fmt-review-end"
242
+ f.children = @isodoc_presxml.comment_bookmark_end_label(f)
243
+ end
209
244
  end
210
245
  end
211
246
 
@@ -214,7 +249,7 @@ module Metanorma
214
249
  t = title.dup
215
250
  t.xpath(ns(".//tab | .//br")).each { |x| x.replace(" ") }
216
251
  t.xpath(ns(".//bookmark")).each(&:remove)
217
- t.xpath('.//text()').map(&:text).join
252
+ t.xpath(".//text()").map(&:text).join
218
253
  end
219
254
  end
220
255
  end
@@ -2,6 +2,11 @@ module Metanorma
2
2
  class Collection
3
3
  module Util
4
4
  class << self
5
+ def anchor_id_attributes
6
+ Metanorma::Utils::anchor_attributes(presxml: true) +
7
+ [%w(* id), %w(* anchor), %w(link bibitemid), %w(fmt-link bibitemid)]
8
+ end
9
+
5
10
  def gather_bibitems(xml)
6
11
  xml.xpath("//xmlns:bibitem[@id]").each_with_object({}) do |b, m|
7
12
  if m[b["id"]]
@@ -16,7 +21,6 @@ module Metanorma
16
21
 
17
22
  def gather_bibitemids(xml, presxml)
18
23
  xml.xpath("//*[@bibitemid]").each_with_object({}) do |e, m|
19
- #/^semantic__/.match?(e.name) and next
20
24
  presxml && %w(xref eref link).include?(e.name) and next
21
25
  m[e["bibitemid"]] ||= []
22
26
  m[e["bibitemid"]] << e
@@ -25,7 +29,6 @@ module Metanorma
25
29
 
26
30
  def gather_citeases(xml, presxml)
27
31
  xml.xpath("//*[@citeas]").each_with_object({}) do |e, m|
28
- #/^semantic__/.match?(e.name) and next
29
32
  presxml && %w(xref eref link).include?(e.name) and next
30
33
  k = key(e["citeas"])
31
34
  m[k] ||= []
@@ -36,6 +39,8 @@ module Metanorma
36
39
  def add_suffix_to_attrs(doc, suffix, tag_name, attr_name, isodoc)
37
40
  (suffix.nil? || suffix.empty?) and return
38
41
  doc.xpath(isodoc.ns("//#{tag_name}[@#{attr_name}]")).each do |elem|
42
+ #warn "#{tag_name} : #{elem.name}" if attr_name == "bibitemid"
43
+ #require 'debug'; binding.b if attr_name == "bibitemid" && #!%w(eref fmt-eref link fmt-link).include?(elem.name)
39
44
  a = elem.attributes[attr_name].value
40
45
  /_#{suffix}$/.match?(a) or
41
46
  elem.attributes[attr_name].value = "#{a}_#{suffix}"
@@ -55,6 +60,14 @@ module Metanorma
55
60
  p.absolute? ? path : File.join(dir, path)
56
61
  end
57
62
 
63
+ def hide_refs(docxml)
64
+ p = "//xmlns:references[xmlns:bibitem]"\
65
+ "[not(./xmlns:bibitem[not(@hidden) or @hidden = 'false'])]"
66
+ docxml.xpath(p).each do |f|
67
+ f["hidden"] = "true"
68
+ end
69
+ end
70
+
58
71
  def key(ident)
59
72
  @c ||= HTMLEntities.new
60
73
  @c.decode(ident).gsub(/(\p{Zs})+/, " ")
@@ -67,20 +80,20 @@ module Metanorma
67
80
  def load_isodoc(flavor, presxml: false)
68
81
  x = Asciidoctor.load nil, backend: flavor.to_sym
69
82
  if presxml
70
- x.converter.presentation_xml_converter(Dummy.new)
83
+ x.converter.presentation_xml_converter(Dummy.new)
71
84
  else
72
- x.converter.html_converter(Dummy.new) # to obtain Isodoc class
85
+ x.converter.html_converter(Dummy.new) # to obtain Isodoc class
73
86
  end
74
87
  end
75
88
 
76
89
  def isodoc_create(flavor, lang, script, xml, presxml: false)
77
- isodoc = Util::load_isodoc(flavor, presxml: presxml)
78
- isodoc.i18n_init(lang, script, nil) # read in internationalisation
79
- # TODO locale?
80
- isodoc.metadata_init(lang, script, nil, isodoc.i18n)
81
- isodoc.info(xml, nil)
82
- isodoc
83
- end
90
+ isodoc = Util::load_isodoc(flavor, presxml: presxml)
91
+ isodoc.i18n_init(lang, script, nil) # read in internationalisation
92
+ # TODO locale?
93
+ isodoc.metadata_init(lang, script, nil, isodoc.i18n)
94
+ isodoc.info(xml, nil)
95
+ isodoc
96
+ end
84
97
  end
85
98
  end
86
99
  end
@@ -10,8 +10,7 @@ module Metanorma
10
10
  @isodoc = isodoc
11
11
  key = (0...8).map { rand(65..90).chr }.join # random string
12
12
  xml.root["type"] = key
13
- Metanorma::Utils::anchor_attributes
14
- .each do |(tag_name, attr_name)|
13
+ Util::anchor_id_attributes.each do |(tag_name, attr_name)|
15
14
  #tag_name == "xref" and tag_name = "fmt-xref"
16
15
  ::Metanorma::Collection::Util::add_suffix_to_attrs(
17
16
  xml, xml.root["document_suffix"], tag_name, attr_name, isodoc
@@ -225,7 +224,7 @@ module Metanorma
225
224
 
226
225
  def new_indirect_bibitem(ident, prefix)
227
226
  <<~BIBENTRY
228
- <bibitem id="#{ident}" type="internal">
227
+ <bibitem id="#{ident}" anchor="#{ident}" type="internal">
229
228
  <docidentifier type="repository">#{ident.sub(/^#{prefix}_/, "#{prefix}/")}</docidentifier>
230
229
  </bibitem>
231
230
  BIBENTRY
@@ -0,0 +1,41 @@
1
+ == copyright-statement
2
+ === Copyright notice
3
+
4
+ Copyright © 1994-{{docyear}} International Color Consortium®
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
7
+ the Specification and associated documentation files (the “Specification”) to
8
+ deal in the Specification without restriction, including without limitation the
9
+ rights to use, copy, modify, merge, publish, distribute, and/or sublicense
10
+ copies of the Specification, and to permit persons to whom the Specification is
11
+ furnished to do so, subject to the following conditions.
12
+
13
+ The above copyright notice and this permission notice shall be included in all
14
+ copies or substantial portions of the Specification.
15
+
16
+ The Specification is provided "as is", without warranty of any kind, express,
17
+ implied, or otherwise, including but not limited to the warranties of
18
+ merchantability, fitness for a particular purpose and noninfringement. In no
19
+ event shall the International Color Consortium be liable for any claim, damages
20
+ or other liability, whether in an action of contract, tort or otherwise, arising
21
+ from, out of, or in connection with the Specification or the use or other
22
+ dealings in the Specification.
23
+
24
+ Except as contained in this notice, the name of the International Color
25
+ Consortium shall not be used in advertising or otherwise to promote the use or
26
+ other dealings in this Specification without prior written authorization from
27
+ the International Color Consortium.
28
+
29
+ == license-statement
30
+ === Licenses and trademarks
31
+
32
+ International Color Consortium and the ICC logo are registered trademarks of the
33
+ International Color Consortium. Rather than put a trademark symbol in every
34
+ occurrence of other trademarked names, we state that we are using the names only
35
+ in an editorial fashion, and to the benefit of the trademark owner, with no
36
+ intention of infringement of the trademark.
37
+
38
+ == feedback-statement
39
+ === For additional information on the ICC
40
+
41
+ Visit the ICC Web site: http://www.color.org
@@ -18,6 +18,7 @@ require_relative "output_filename"
18
18
  require_relative "output_filename_config"
19
19
  require_relative "flavor"
20
20
  require_relative "relaton_drop"
21
+ require_relative "render"
21
22
 
22
23
  module Metanorma
23
24
  class Compile
@@ -114,20 +115,18 @@ module Metanorma
114
115
  # @param options [Hash] compilation options
115
116
  # @return [Hash] paths for different output formats
116
117
  def prepare_output_paths(filename, bibdata, options)
117
- basename = if !options[:filename_template].nil?
118
+ basename = if options[:filename_template].nil?
119
+ filename.sub(/\.[^.]+$/, "")
120
+ else
118
121
  drop = RelatonDrop.new(bibdata)
119
122
  config = OutputFilenameConfig.new(options[:filename_template])
120
123
  config.generate_filename(drop)
121
- else
122
- filename.sub(/\.[^.]+$/, "")
123
124
  end
124
-
125
125
  @output_filename = OutputFilename.new(
126
126
  basename,
127
127
  options[:output_dir],
128
128
  @processor,
129
129
  )
130
-
131
130
  {
132
131
  xml: @output_filename.semantic_xml,
133
132
  orig_filename: filename,
@@ -175,53 +174,40 @@ module Metanorma
175
174
  end
176
175
  end
177
176
 
178
- # Generate presentation XML from semantic XML
179
- def generate_presentation_xml(
180
- source_file, semantic_xml, bibdata, output_paths, options
181
- )
182
- process_ext(
183
- :presentation, source_file, semantic_xml, bibdata, output_paths, options
184
- )
185
- end
186
-
187
- # Generate multiple output formats with parallel processing
188
- def generate_outputs_parallel(
189
- source_file, semantic_xml, bibdata, extensions, output_paths, options
190
- )
191
- @queue = ::Metanorma::Util::WorkersPool.new(
192
- ENV["METANORMA_PARALLEL"]&.to_i || DEFAULT_NUM_WORKERS,
193
- )
194
-
195
- # Install required fonts for all extensions
196
- gather_and_install_fonts(source_file, options.dup, extensions)
197
-
198
- # Process each extension in order
199
- process_extensions_in_order(
200
- source_file, semantic_xml, bibdata, extensions, output_paths, options
201
- )
202
-
203
- @queue.shutdown
177
+ def process_input_adoc_hdr(file, options)
178
+ hdr, rest = Metanorma::Input::Asciidoc.new.header(file)
179
+ attrs = hdr.split("\n")
180
+ options[:asciimath] and attrs << ":mn-keep-asciimath:"
181
+ process_input_adoc_overrides(attrs, options)
182
+ "#{attrs.join("\n")}\n\n#{rest}"
204
183
  end
205
184
 
206
- def process_extensions_in_order(
207
- source_file, semantic_xml, bibdata, extensions, output_paths, options
208
- )
209
- Util.sort_extensions_execution(extensions).each do |ext|
210
- process_ext(
211
- ext, source_file, semantic_xml, bibdata, output_paths, options
212
- ) or break
185
+ # TODO: to config
186
+ def process_input_adoc_overrides(attrs, options)
187
+ case options[:supplied_type]
188
+ when :icc
189
+ f = File.join(File.dirname(__FILE__), "assets", "icc-boilerplate.adoc")
190
+ [":boilerplate-authority: #{f}",
191
+ ":publisher: International Color Consortium",
192
+ ":publisher_abbr: ICC"].each { |a| attrs << a }
193
+ options[":boilerplate-authority:"] = f
213
194
  end
195
+ attrs
214
196
  end
215
197
 
216
- def process_input_adoc(filename, options)
217
- Util.log("[metanorma] Processing: AsciiDoc input.", :info)
218
- file = read_file(filename)
219
- options[:asciimath] and
220
- file.sub!(/^(=[^\n]+\n)/, "\\1:mn-keep-asciimath:\n")
198
+ def process_input_adoc_includes(file, filename)
221
199
  dir = File.dirname(filename)
222
200
  dir != "." and
223
201
  file = file.gsub(/^include::/, "include::#{dir}/")
224
202
  .gsub(/^embed::/, "embed::#{dir}/")
203
+ file
204
+ end
205
+
206
+ def process_input_adoc(filename, options)
207
+ Util.log("[metanorma] Processing: AsciiDoc input.", :info)
208
+ file = read_file(filename)
209
+ file = process_input_adoc_hdr(file, options)
210
+ file = process_input_adoc_includes(file, filename)
225
211
  [file, @processor.input_to_isodoc(file, filename, options)]
226
212
  end
227
213
 
@@ -235,166 +221,5 @@ module Metanorma
235
221
  def read_file(filename)
236
222
  File.read(filename, encoding: "utf-8").gsub("\r\n", "\n")
237
223
  end
238
-
239
- # Export given bibliographic data to Relaton XML on disk
240
- # @param bibdata [Nokogiri::XML::Element] the bibliographic data element
241
- # @param options [Hash] compilation options
242
- def export_relaton_from_bibdata(bibdata, options)
243
- return unless options[:relaton]
244
-
245
- # docid = bibdata&.at("./xmlns:docidentifier")&.text || options[:filename]
246
- # outname = docid.sub(/^\s+/, "").sub(/\s+$/, "").gsub(/\s+/, "-") + ".xml"
247
- export_output(options[:relaton], bibdata.to_xml)
248
- end
249
-
250
- # @param xml [Nokogiri::XML::Document] the XML document
251
- # @return [Nokogiri::XML::Element] the bibliographic data element
252
- def extract_relaton_metadata(xml)
253
- xml.at("//bibdata") || xml.at("//xmlns:bibdata")
254
- end
255
-
256
- def wrap_html(options, file_extension, outfilename)
257
- if options[:wrapper] && /html$/.match(file_extension)
258
- outfilename = outfilename.sub(/\.html$/, "")
259
- FileUtils.mkdir_p outfilename
260
- FileUtils.mv "#{outfilename}.html", outfilename
261
- FileUtils.mv "#{outfilename}_images", outfilename, force: true
262
- end
263
- end
264
-
265
- # isodoc is Raw Metanorma XML
266
-
267
- def gather_and_install_fonts(source_file, options, extensions)
268
- Util.sort_extensions_execution(extensions).each do |ext|
269
- isodoc_options = get_isodoc_options(source_file, options, ext)
270
- font_install(isodoc_options.merge(options))
271
- end
272
- end
273
-
274
- # Process a single extension (output format)
275
- def process_ext(ext, source_file, semantic_xml, bibdata, output_paths,
276
- options)
277
- output_paths[:ext] = @processor.output_formats[ext]
278
- output_paths[:out] = @output_filename.for_format(ext) ||
279
- output_paths[:xml].sub(/\.[^.]+$/, ".#{output_paths[:ext]}")
280
- isodoc_options = get_isodoc_options(source_file, options, ext)
281
-
282
- # Handle special cases first
283
- return true if process_ext_special(
284
- ext, semantic_xml, bibdata, output_paths, options, isodoc_options
285
- )
286
-
287
- # Otherwise, determine if it uses presentation XML
288
- if @processor.use_presentation_xml(ext)
289
- # Format requires presentation XML first, then convert to final format
290
- process_via_presentation_xml(ext, output_paths, options, isodoc_options)
291
- else
292
- # Format can be generated directly from semantic XML
293
- process_from_semantic_xml(
294
- ext, output_paths, semantic_xml, isodoc_options
295
- )
296
- end
297
- end
298
-
299
- # Process special extensions with custom handling
300
- def process_ext_special(
301
- ext, semantic_xml, bibdata, output_paths, options, isodoc_options
302
- )
303
- if ext == :rxl
304
-
305
- # Special case: Relaton export
306
- export_relaton_from_bibdata(
307
- bibdata,
308
- options.merge(relaton: output_paths[:out]),
309
- )
310
- true
311
-
312
- elsif ext == :presentation && options[:passthrough_presentation_xml]
313
-
314
- # Special case: Pass through presentation XML
315
- f = if File.exist?(output_paths[:orig_filename])
316
- output_paths[:orig_filename]
317
- else
318
- output_paths[:xml]
319
- end
320
-
321
- FileUtils.cp f, output_paths[:presentationxml]
322
- true
323
-
324
- elsif ext == :html && options[:sectionsplit]
325
-
326
- # Special case: Split HTML into sections
327
- sectionsplit_convert(
328
- output_paths[:xml], semantic_xml, output_paths[:out], isodoc_options
329
- )
330
- true
331
- else
332
- false
333
- end
334
- end
335
-
336
- # Process format that requires presentation XML
337
- def process_via_presentation_xml(ext, output_paths, options, isodoc_options)
338
- @queue.schedule(ext, output_paths.dup, options.dup,
339
- isodoc_options.dup) do |a, b, c, d|
340
- process_output_from_presentation_xml(a, b, c, d)
341
- end
342
- end
343
-
344
- # Generate output format from presentation XML
345
- def process_output_from_presentation_xml(ext, output_paths, options,
346
- isodoc_options)
347
- @processor.output(nil, output_paths[:presentationxml],
348
- output_paths[:out], ext, isodoc_options)
349
- wrap_html(options, output_paths[:ext], output_paths[:out])
350
- rescue StandardError => e
351
- strict = ext == :presentation || isodoc_options[:strict] == true
352
- isodoc_error_process(e, strict, false)
353
- end
354
-
355
- # Process format directly from semantic XML
356
- def process_from_semantic_xml(ext, output_paths, semantic_xml,
357
- isodoc_options)
358
- @processor.output(semantic_xml, output_paths[:xml], output_paths[:out],
359
- ext, isodoc_options)
360
- true # Return as Thread equivalent
361
- rescue StandardError => e
362
- strict = ext == :presentation || isodoc_options[:strict] == "true"
363
- isodoc_error_process(e, strict, true)
364
- ext != :presentation
365
- end
366
-
367
- # assume we pass in Presentation XML, but we want to recover Semantic XML
368
- def sectionsplit_convert(input_filename, file, output_filename = nil,
369
- opts = {})
370
- @isodoc ||= IsoDoc::PresentationXMLConvert.new({})
371
- input_filename += ".xml" unless input_filename.match?(/\.xml$/)
372
- File.exist?(input_filename) or
373
- export_output(input_filename, file)
374
- presxml = File.read(input_filename, encoding: "utf-8")
375
- _xml, filename, dir = @isodoc.convert_init(presxml, input_filename, false)
376
-
377
- ::Metanorma::Collection::Sectionsplit.new(
378
- input: input_filename,
379
- isodoc: @isodoc,
380
- xml: presxml,
381
- base: File.basename(output_filename || filename),
382
- output: output_filename || filename,
383
- dir: dir,
384
- compile_opts: opts,
385
- ).build_collection
386
- end
387
-
388
- private
389
-
390
- def isodoc_error_process(err, strict, must_abort)
391
- if strict || err.message.include?("Fatal:")
392
- @errors << err.message
393
- else
394
- puts err.message
395
- end
396
- puts err.backtrace.join("\n")
397
- must_abort and 1
398
- end
399
224
  end
400
225
  end
@@ -18,17 +18,9 @@ module Metanorma
18
18
  end
19
19
 
20
20
  def extract_options(filename, options)
21
- content = read_file(filename)
22
- o = Metanorma::Input::Asciidoc.new.extract_metanorma_options(content)
23
- .merge(extract_xml_options(content))
24
- options[:type] ||= o[:type]&.to_sym
25
- t = @registry.alias(options[:type]) and options[:type] = t
26
- dir = filename.sub(%r(/[^/]+$), "/")
27
- options[:relaton] ||= File.join(dir, o[:relaton]) if o[:relaton]
28
- if o[:sourcecode]
29
- options[:sourcecode] ||= File.join(dir,
30
- o[:sourcecode])
31
- end
21
+ o = options_in_file(filename)
22
+ extract_flavor_options(options, o)
23
+ extract_dir_options(options, o, filename)
32
24
  options[:extension_keys] ||= o[:extensions]&.split(/, */)&.map(&:to_sym)
33
25
  options[:extension_keys] = nil if options[:extension_keys] == [:all]
34
26
  options[:format] ||= :asciidoc
@@ -38,6 +30,29 @@ module Metanorma
38
30
  options
39
31
  end
40
32
 
33
+ def options_in_file(filename)
34
+ content = read_file(filename)
35
+ Metanorma::Input::Asciidoc.new.extract_metanorma_options(content)
36
+ .merge(extract_xml_options(content))
37
+ end
38
+
39
+ def extract_flavor_options(options, options_in_file)
40
+ options[:type] ||= options_in_file[:type]
41
+ options[:type] = options[:type]&.to_sym
42
+ options[:supplied_type] = options[:type]
43
+ t = @registry.alias(options[:type]) and options[:type] = t
44
+ end
45
+
46
+ def extract_dir_options(options, options_in_file, filename)
47
+ dir = filename.sub(%r(/[^/]+$), "/")
48
+ options_in_file[:relaton] and
49
+ options[:relaton] ||= File.join(dir,
50
+ options_in_file[:relaton])
51
+ options_in_file[:sourcecode] and
52
+ options[:sourcecode] ||= File.join(dir,
53
+ options_in_file[:sourcecode])
54
+ end
55
+
41
56
  def get_extensions(options)
42
57
  ext = extract_extensions(options)
43
58
  !ext.include?(:presentation) && ext.any? do |e|
@@ -70,7 +85,7 @@ module Metanorma
70
85
 
71
86
  def unsupported_format_error(ext)
72
87
  message = "[metanorma] Error: #{ext} format is not supported " \
73
- "for this standard."
88
+ "for this standard."
74
89
  @errors << message
75
90
  Util.log(message, :error)
76
91
  end
@@ -8,7 +8,7 @@ module Metanorma
8
8
  # @return [void]
9
9
  def load_flavor(stdtype)
10
10
  stdtype = stdtype.to_sym
11
- flavor = stdtype2flavor(stdtype)
11
+ flavor = stdtype2flavor_gem(stdtype)
12
12
  @registry.supported_backends.include? stdtype or
13
13
  Util.log("[metanorma] Info: Loading `#{flavor}` gem "\
14
14
  "for standard type `#{stdtype}`.", :info)
@@ -21,15 +21,12 @@ module Metanorma
21
21
  # Convert the standard type to the flavor gem name
22
22
  # @param stdtype [Symbol] the standard type
23
23
  # @return [String] the flavor gem name
24
- def stdtype2flavor(stdtype)
25
- flavor = STDTYPE2FLAVOR[stdtype] || stdtype
26
- "metanorma-#{flavor}"
24
+ def stdtype2flavor_gem(stdtype)
25
+ "metanorma-#{stdtype}"
27
26
  end
28
27
 
29
28
  private
30
29
 
31
- STDTYPE2FLAVOR = {}.freeze
32
-
33
30
  def require_flavor(flavor)
34
31
  require flavor
35
32
  Util.log("[metanorma] Info: gem `#{flavor}` loaded.", :info)
@@ -0,0 +1,178 @@
1
+ module Metanorma
2
+ class Compile
3
+ # Generate presentation XML from semantic XML
4
+ def generate_presentation_xml(source_file, xml, bibdata, output_paths, opt)
5
+ process_ext(:presentation, source_file, xml, bibdata, output_paths, opt)
6
+ end
7
+
8
+ # Generate multiple output formats with parallel processing
9
+ def generate_outputs_parallel(
10
+ source_file, semantic_xml, bibdata, extensions, output_paths, options
11
+ )
12
+ @queue = ::Metanorma::Util::WorkersPool.new(
13
+ ENV["METANORMA_PARALLEL"]&.to_i || DEFAULT_NUM_WORKERS,
14
+ )
15
+ # Install required fonts for all extensions
16
+ gather_and_install_fonts(source_file, options.dup, extensions)
17
+ # Process each extension in order
18
+ process_extensions_in_order(
19
+ source_file, semantic_xml, bibdata, extensions, output_paths, options
20
+ )
21
+ @queue.shutdown
22
+ end
23
+
24
+ def process_extensions_in_order(
25
+ source_file, semantic_xml, bibdata, extensions, output_paths, options
26
+ )
27
+ Util.sort_extensions_execution(extensions).each do |ext|
28
+ process_ext(
29
+ ext, source_file, semantic_xml, bibdata, output_paths, options
30
+ ) or break
31
+ end
32
+ end
33
+
34
+ # Export given bibliographic data to Relaton XML on disk
35
+ # @param bibdata [Nokogiri::XML::Element] the bibliographic data element
36
+ # @param options [Hash] compilation options
37
+ def export_relaton_from_bibdata(bibdata, options)
38
+ options[:relaton] or return
39
+ export_output(options[:relaton], bibdata.to_xml)
40
+ end
41
+
42
+ # @param xml [Nokogiri::XML::Document] the XML document
43
+ # @return [Nokogiri::XML::Element] the bibliographic data element
44
+ def extract_relaton_metadata(xml)
45
+ xml.at("//bibdata") || xml.at("//xmlns:bibdata")
46
+ end
47
+
48
+ def wrap_html(options, file_extension, outfilename)
49
+ if options[:wrapper] && /html$/.match(file_extension)
50
+ outfilename = outfilename.sub(/\.html$/, "")
51
+ FileUtils.mkdir_p outfilename
52
+ FileUtils.mv "#{outfilename}.html", outfilename
53
+ FileUtils.mv "#{outfilename}_images", outfilename, force: true
54
+ end
55
+ end
56
+
57
+ # isodoc is Raw Metanorma XML
58
+ def gather_and_install_fonts(source_file, options, extensions)
59
+ Util.sort_extensions_execution(extensions).each do |ext|
60
+ isodoc_options = get_isodoc_options(source_file, options, ext)
61
+ font_install(isodoc_options.merge(options))
62
+ end
63
+ end
64
+
65
+ # Process a single extension (output format)
66
+ def process_ext(ext, source_file, semantic_xml, bibdata, output_paths,
67
+ options)
68
+ output_paths[:ext] = @processor.output_formats[ext]
69
+ output_paths[:out] = @output_filename.for_format(ext) ||
70
+ output_paths[:xml].sub(/\.[^.]+$/, ".#{output_paths[:ext]}")
71
+ isodoc_options = get_isodoc_options(source_file, options, ext)
72
+
73
+ # Handle special cases first
74
+ return true if process_ext_special(
75
+ ext, semantic_xml, bibdata, output_paths, options, isodoc_options
76
+ )
77
+
78
+ # Otherwise, determine if it uses presentation XML
79
+ if @processor.use_presentation_xml(ext)
80
+ # Format requires presentation XML first, then convert to final format
81
+ process_via_presentation_xml(ext, output_paths, options, isodoc_options)
82
+ else
83
+ # Format can be generated directly from semantic XML
84
+ process_from_semantic_xml(
85
+ ext, output_paths, semantic_xml, isodoc_options
86
+ )
87
+ end
88
+ end
89
+
90
+ # Process special extensions with custom handling
91
+ def process_ext_special(
92
+ ext, sem_xml, bibdata, output_paths, options, isodoc_options
93
+ )
94
+ if ext == :rxl
95
+ # Special case: Relaton export
96
+ export_relaton_from_bibdata(
97
+ bibdata,
98
+ options.merge(relaton: output_paths[:out]),
99
+ )
100
+ true
101
+ elsif ext == :presentation && options[:passthrough_presentation_xml]
102
+ # Special case: Pass through presentation XML
103
+ f = if File.exist?(output_paths[:orig_filename])
104
+ output_paths[:orig_filename]
105
+ else
106
+ output_paths[:xml]
107
+ end
108
+ FileUtils.cp f, output_paths[:presentationxml]
109
+ true
110
+ elsif ext == :html && options[:sectionsplit]
111
+ # Special case: Split HTML into sections
112
+ sectionsplit_convert(
113
+ output_paths[:xml], sem_xml, output_paths[:out], isodoc_options
114
+ )
115
+ true
116
+ else
117
+ false
118
+ end
119
+ end
120
+
121
+ # Process format that requires presentation XML
122
+ def process_via_presentation_xml(ext, output_paths, options, isodoc_options)
123
+ @queue.schedule(ext, output_paths.dup, options.dup,
124
+ isodoc_options.dup) do |a, b, c, d|
125
+ process_output_from_presentation_xml(a, b, c, d)
126
+ end
127
+ end
128
+
129
+ # Generate output format from presentation XML
130
+ def process_output_from_presentation_xml(ext, output_paths, options,
131
+ isodoc_options)
132
+ @processor.output(nil, output_paths[:presentationxml],
133
+ output_paths[:out], ext, isodoc_options)
134
+ wrap_html(options, output_paths[:ext], output_paths[:out])
135
+ rescue StandardError => e
136
+ strict = ext == :presentation || isodoc_options[:strict] == true
137
+ isodoc_error_process(e, strict, false)
138
+ end
139
+
140
+ # Process format directly from semantic XML
141
+ def process_from_semantic_xml(ext, output_paths, sem_xml, isodoc_options)
142
+ @processor.output(sem_xml, output_paths[:xml], output_paths[:out],
143
+ ext, isodoc_options)
144
+ true # Return as Thread equivalent
145
+ rescue StandardError => e
146
+ strict = ext == :presentation || isodoc_options[:strict] == "true"
147
+ isodoc_error_process(e, strict, true)
148
+ ext != :presentation
149
+ end
150
+
151
+ # assume we pass in Presentation XML, but we want to recover Semantic XML
152
+ def sectionsplit_convert(input_filename, file, output_filename = nil,
153
+ opts = {})
154
+ @isodoc ||= IsoDoc::PresentationXMLConvert.new({})
155
+ input_filename += ".xml" unless input_filename.match?(/\.xml$/)
156
+ File.exist?(input_filename) or export_output(input_filename, file)
157
+ presxml = File.read(input_filename, encoding: "utf-8")
158
+ _xml, filename, dir = @isodoc.convert_init(presxml, input_filename, false)
159
+ ::Metanorma::Collection::Sectionsplit.new(
160
+ input: input_filename, isodoc: @isodoc, xml: presxml,
161
+ base: File.basename(output_filename || filename),
162
+ output: output_filename || filename, dir: dir, compile_opts: opts
163
+ ).build_collection
164
+ end
165
+
166
+ private
167
+
168
+ def isodoc_error_process(err, strict, must_abort)
169
+ if strict || err.message.include?("Fatal:")
170
+ @errors << err.message
171
+ else
172
+ puts err.message
173
+ end
174
+ puts err.backtrace.join("\n")
175
+ must_abort and 1
176
+ end
177
+ end
178
+ end
@@ -9,19 +9,17 @@ module Metanorma
9
9
  end
10
10
 
11
11
  def validate_type!(options)
12
- unless options[:type]
12
+ options[:type] or
13
13
  Util.log("[metanorma] Error: Please specify a standard type: "\
14
14
  "#{@registry.supported_backends}.", :fatal)
15
- end
16
15
  stdtype = options[:type].to_sym
17
16
  load_flavor(stdtype)
18
17
  end
19
18
 
20
19
  def validate_format!(options)
21
- unless options[:format] == :asciidoc
20
+ options[:format] == :asciidoc or
22
21
  Util.log("[metanorma] Error: Only source file format currently "\
23
22
  "supported is 'asciidoc'.", :fatal)
24
- end
25
23
  end
26
24
  end
27
25
  end
@@ -13,8 +13,14 @@ module Metanorma
13
13
  ::Asciidoctor.convert(file, out_opts)
14
14
  end
15
15
 
16
+ def header(file)
17
+ ret = file.split("\n\n", 2) or return [nil, nil]
18
+ ret[0] and ret[0] += "\n"
19
+ [ret[0], ret[1]]
20
+ end
21
+
16
22
  def extract_metanorma_options(file)
17
- hdr = file.sub(/\n\n.*$/m, "\n")
23
+ hdr, = header(file)
18
24
  /\n:(?:mn-)?(?:document-class|flavor):\s+(?<type>\S[^\n]*)\n/ =~ hdr
19
25
  /\n:(?:mn-)?output-extensions:\s+(?<extensions>\S[^\n]*)\n/ =~ hdr
20
26
  /\n:(?:mn-)?relaton-output-file:\s+(?<relaton>\S[^\n]*)\n/ =~ hdr
@@ -22,7 +28,7 @@ module Metanorma
22
28
  /\n(?<novalid>:novalid:[^\n]*)\n/ =~ hdr
23
29
  if defined?(asciimath)
24
30
  asciimath =
25
- !asciimath.nil? && !/keep-asciimath: false/.match?(asciimath)
31
+ !asciimath.nil? && !/keep-asciimath:\s*false/.match?(asciimath)
26
32
  end
27
33
  asciimath = nil if asciimath == false
28
34
  {
@@ -68,17 +74,17 @@ module Metanorma
68
74
  end
69
75
 
70
76
  def extract_options(file)
71
- header = file.sub(/\n\n.*$/m, "\n")
77
+ hdr, = header(file)
72
78
  ret = ADOC_OPTIONS.each_with_object({}) do |w, acc|
73
- m = /\n:#{w}:\s+([^\n]+)\n/.match(header) or next
79
+ m = /\n:#{w}:\s+([^\n]+)\n/.match(hdr) or next
74
80
  acc[attr_name_normalise(w)] = m[1]&.strip
75
81
  end
76
82
  ret2 = EMPTY_ADOC_OPTIONS_DEFAULT_TRUE.each_with_object({}) do |w, acc|
77
- m = /\n:#{w}:([^\n]*)\n/.match(header) || [nil, "true"]
83
+ m = /\n:#{w}:([^\n]*)\n/.match(hdr) || [nil, "true"]
78
84
  acc[attr_name_normalise(w)] = (m[1].strip != "false")
79
85
  end
80
86
  ret3 = EMPTY_ADOC_OPTIONS_DEFAULT_FALSE.each_with_object({}) do |w, acc|
81
- m = /\n:#{w}:([^\n]*)\n/.match(header) || [nil, "false"]
87
+ m = /\n:#{w}:([^\n]*)\n/.match(hdr) || [nil, "false"]
82
88
  acc[attr_name_normalise(w)] = !["false"].include?(m[1].strip)
83
89
  end
84
90
  ret.merge(ret2).merge(ret3).compact
@@ -11,9 +11,11 @@ module Metanorma
11
11
 
12
12
  attr_reader :processors
13
13
 
14
+ # TODO: make aliases configurable
14
15
  def initialize
15
16
  @processors = {}
16
- @aliases = { csd: :cc, m3d: :m3aawg, mpfd: :mpfa, csand: :csa }
17
+ @aliases = { csd: :cc, m3d: :m3aawg, mpfd: :mpfa, csand: :csa,
18
+ icc: :iso }
17
19
  end
18
20
 
19
21
  def alias(flavour)
@@ -21,18 +23,14 @@ module Metanorma
21
23
  end
22
24
 
23
25
  def register(processor)
24
- raise Error unless processor < ::Metanorma::Processor
25
-
26
+ processor < ::Metanorma::Processor or raise Error
26
27
  p = processor.new
27
28
  # p.short[-1] is the canonical name
28
29
  short = Array(p.short)
29
30
  @processors[short[-1]] = p
30
- short.each do |s|
31
- @aliases[s] = short[-1]
32
- end
31
+ short.each { |s| @aliases[s] = short[-1] }
33
32
  Array(p.short)
34
- Util.log("[metanorma] processor \"#{Array(p.short)[0]}\" registered",
35
- :info)
33
+ Util.log("[metanorma] processor \"#{Array(p.short)[0]}\" registered", :info)
36
34
  end
37
35
 
38
36
  def find_processor(short)
@@ -1,3 +1,3 @@
1
1
  module Metanorma
2
- VERSION = "2.1.7".freeze
2
+ VERSION = "2.1.9".freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: metanorma
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.7
4
+ version: 2.1.9
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-04-14 00:00:00.000000000 Z
11
+ date: 2025-05-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: asciidoctor
@@ -338,6 +338,7 @@ files:
338
338
  - lib/metanorma/collection/util/disambig_files.rb
339
339
  - lib/metanorma/collection/util/util.rb
340
340
  - lib/metanorma/collection/xrefprocess/xrefprocess.rb
341
+ - lib/metanorma/compile/assets/icc-boilerplate.adoc
341
342
  - lib/metanorma/compile/compile.rb
342
343
  - lib/metanorma/compile/compile_options.rb
343
344
  - lib/metanorma/compile/extract.rb
@@ -345,6 +346,7 @@ files:
345
346
  - lib/metanorma/compile/output_filename.rb
346
347
  - lib/metanorma/compile/output_filename_config.rb
347
348
  - lib/metanorma/compile/relaton_drop.rb
349
+ - lib/metanorma/compile/render.rb
348
350
  - lib/metanorma/compile/validator.rb
349
351
  - lib/metanorma/compile/writeable.rb
350
352
  - lib/metanorma/config/config.rb