metanorma 2.0.4 → 2.0.6

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: 77856427b06326b7de35ad6782ffc5dbfe5331d9596d6df53a6af4c2bb681c81
4
- data.tar.gz: d63ffb87f0abe973ed040f8567c986d504792433a9b3d46f4618752f9f254f59
3
+ metadata.gz: f27c1f604a729b827832e208b2ca5db54b8db3f5b3f69fe905e0f0ae87a08f53
4
+ data.tar.gz: 781c8396a4c325a34c456ba935e40aba94d4062b283b475cf1bc381aa4ead712
5
5
  SHA512:
6
- metadata.gz: 9b252f5a1c35eee2d8c6689bd2c7501964e557401cfc3ba129e962faf0f0c5631feacd6f46fcc606ba973a8e8ac43f4078488d4726f81a3dce087e921db5cd28
7
- data.tar.gz: 66cece76fb4ac1fca9f5795f002f15d7062e73aac558056a5b02fe98a8de45d4fbd68d3c30ae7883b74f6ef6247d84840db4c1a9bfe64a0dc57e37ab70f7f861
6
+ metadata.gz: 8305b0f43fec6a78fc64b2d79fde688d829bacb3e4ce772d14a6c68ceaa71141a6948c4d7c1d6a358f21c4e86e601f44c4e6411a0e5c7c2522a0a8fed71856f1
7
+ data.tar.gz: 6d9418c471d3966f00796dd0840cf33400188e93e61585b0b777cc31db70d020b92cd7f89f00754734a5331db29600ec4955b2b52bc86d62da3c11c98f71b45d
@@ -37,6 +37,7 @@ module Metanorma
37
37
  @bibdatas.merge! @manifest.documents
38
38
  @documents.transform_keys { |k| Util::key(k) }
39
39
  @bibdatas.transform_keys { |k| Util::key(k) }
40
+ validate_flavor(flavor)
40
41
  end
41
42
 
42
43
  def initialize_vars
@@ -59,6 +60,7 @@ module Metanorma
59
60
  d = @directives.each_with_object({}) { |x, m| m[x.key] = x.value }
60
61
  @coverpage = d["coverpage"]
61
62
  @coverpage_style = d["coverpage-style"]
63
+ @flavor = d["flavor"]
62
64
  if (@documents.any? || @manifest) && !d.key?("documents-inline") &&
63
65
  !d.key?("documents-external")
64
66
  @directives << ::Metanorma::Collection::Config::Directive
@@ -66,6 +68,10 @@ module Metanorma
66
68
  end
67
69
  end
68
70
 
71
+ def validate_flavor(flavor)
72
+ ::Metanorma::Compile.new.load_flavor(flavor)
73
+ end
74
+
69
75
  def clean_exit
70
76
  @log.write(File.join(@dirname,
71
77
  "#{File.basename(@file, '.*')}.err.html"))
@@ -83,7 +89,9 @@ module Metanorma
83
89
 
84
90
  def render(opts)
85
91
  opts[:format].nil? || opts[:format].empty? and opts[:format] = [:html]
86
- ::Metanorma::Collection::Renderer.render self, opts.merge(log: @log)
92
+ opts[:log] = @log
93
+ opts[:flavor] = @flavor
94
+ ::Metanorma::Collection::Renderer.render self, opts
87
95
  clean_exit
88
96
  end
89
97
 
@@ -103,7 +111,7 @@ module Metanorma
103
111
  # @param builder [Nokogiri::XML::Builder]
104
112
  def content_to_xml(elm, builder)
105
113
  (cnt = send(elm)) or return
106
- @compile.load_flavor(doctype)
114
+ @compile.load_flavor(flavor)
107
115
  out = sections(dummy_header + cnt.strip)
108
116
  builder.send("#{elm}-content") { |b| b << out }
109
117
  end
@@ -111,13 +119,12 @@ module Metanorma
111
119
  # @param cnt [String] prefatory/final content
112
120
  # @return [String] XML
113
121
  def sections(cnt)
114
- c = Asciidoctor.convert(cnt, backend: doctype.to_sym, header_footer: true)
122
+ c = Asciidoctor.convert(cnt, backend: flavor.to_sym, header_footer: true)
115
123
  Nokogiri::XML(c, &:huge).at("//xmlns:sections").children.to_xml
116
124
  end
117
125
 
118
126
  # @param builder [Nokogiri::XML::Builder]
119
127
  def doccontainer(builder)
120
- # Array(@directives).include? "documents-inline" or return
121
128
  @directives.detect { |d| d.key == "documents-inline" } or return
122
129
  documents.each_with_index do |(_, d), i|
123
130
  doccontainer1(builder, d, i)
@@ -136,14 +143,19 @@ module Metanorma
136
143
  end
137
144
  end
138
145
 
139
- def doctype
140
- @doctype ||= fetch_doctype || "standoc"
146
+ def flavor
147
+ @flavor ||= fetch_flavor || "standoc"
141
148
  end
142
149
 
143
- def fetch_doctype
144
- docid = @bibdata.docidentifier.first
145
- docid or return
146
- docid.type&.downcase || docid.id&.sub(/\s.*$/, "")&.downcase
150
+ # TODO: retrieve flavor based on @bibdata publisher when lookup implemented
151
+ # Will still infer based on docid, but will validate it before proceeding
152
+ def fetch_flavor
153
+ docid = @bibdata.docidentifier.first or return
154
+ f = docid.type.downcase || docid.id.sub(/\s.*$/, "").downcase or return
155
+ require ::Metanorma::Compile.new.stdtype2flavor(f)
156
+ f
157
+ rescue LoadError
158
+ nil
147
159
  end
148
160
 
149
161
  class << self
@@ -1,3 +1,5 @@
1
+ require "relaton-cli"
2
+
1
3
  module Metanorma
2
4
  class Collection
3
5
  class Document
@@ -48,16 +50,16 @@ module Metanorma
48
50
 
49
51
  def mn2relaton_parser(tag)
50
52
  case tag.sub(/-standard/, "")
51
- when "bipm" then RelatonBipm::XMLParser
52
- when "bsi" then RelatonBsi::XMLParser
53
- when "ietf" then RelatonIetf::XMLParser
54
- when "iho" then RelatonIho::XMLParser
55
- when "itu" then RelatonItu::XMLParser
56
- when "iec" then RelatonIec::XMLParser
57
- when "iso" then RelatonIsoBib::XMLParser
58
- when "nist" then RelatonNist::XMLParser
59
- when "ogc" then RelatonOgc::XMLParser
60
- else RelatonBib::XMLParser
53
+ when "bipm" then ::RelatonBipm::XMLParser
54
+ when "bsi" then ::RelatonBsi::XMLParser
55
+ when "ietf" then ::RelatonIetf::XMLParser
56
+ when "iho" then ::RelatonIho::XMLParser
57
+ when "itu" then ::RelatonItu::XMLParser
58
+ when "iec" then ::RelatonIec::XMLParser
59
+ when "iso" then ::RelatonIsoBib::XMLParser
60
+ when "nist" then ::RelatonNist::XMLParser
61
+ when "ogc" then ::RelatonOgc::XMLParser
62
+ else ::RelatonBib::XMLParser
61
63
  end
62
64
  end
63
65
 
@@ -104,15 +104,15 @@ module Metanorma
104
104
  %w(attachment sectionsplit index presentation-xml url
105
105
  bare-after-first).each do |s|
106
106
  ref.respond_to?(s.to_sym) and
107
- ret[s.gsub("-", "").to_sym] = ref.send(s)
107
+ ret[s.delete("-").to_sym] = ref.send(s)
108
108
  end
109
109
  end
110
110
 
111
111
  def add_document_suffix(identifier, doc)
112
112
  document_suffix = Metanorma::Utils::to_ncname(identifier)
113
- Metanorma::Utils::anchor_attributes.each do |(tag_name, attribute_name)|
114
- Util::add_suffix_to_attributes(doc, document_suffix, tag_name,
115
- attribute_name, @isodoc)
113
+ Metanorma::Utils::anchor_attributes.each do |(tag_name, attr_name)|
114
+ Util::add_suffix_to_attrs(doc, document_suffix, tag_name, attr_name,
115
+ @isodoc)
116
116
  end
117
117
  url_in_css_styles(doc, document_suffix)
118
118
  doc.root["document_suffix"] ||= ""
@@ -19,6 +19,8 @@ module Metanorma
19
19
  s.each_with_index do |f1, i|
20
20
  add_section_split_instance(f1, manifest, key, i)
21
21
  end
22
+ a = add_section_split_attachments(sectionsplit_manifest, key) and
23
+ manifest["#{key}:attachments"] = a
22
24
  manifest["#{key}:index.html"] =
23
25
  add_section_split_cover(sectionsplit_manifest, key)
24
26
  end
@@ -49,9 +51,17 @@ module Metanorma
49
51
  docs > 1
50
52
  end
51
53
 
54
+ def add_section_split_attachments(manifest, ident)
55
+ attachments = @sectionsplit
56
+ .section_split_attachments(out: File.dirname(manifest.file))
57
+ attachments or return
58
+ @files[ident][:out_path] = attachments
59
+ { attachment: true, index: false, out_path: attachments,
60
+ ref: File.join(File.dirname(manifest.file), attachments) }
61
+ end
62
+
52
63
  def add_section_split_instance(file, manifest, key, idx)
53
- presfile, newkey, xml =
54
- add_section_split_instance_prep(file, key)
64
+ presfile, newkey, xml = add_section_split_instance_prep(file, key)
55
65
  manifest[newkey] =
56
66
  { parentid: key, presentationxml: true, type: "fileref",
57
67
  rel_path: file[:url], out_path: File.basename(file[:url]),
@@ -59,6 +69,7 @@ module Metanorma
59
69
  sectionsplit_output: true,
60
70
  bibdata: @files[key][:bibdata], ref: presfile }
61
71
  @files_to_delete << file[:url]
72
+ manifest[newkey][:indirect_key] = @sectionsplit.key
62
73
  manifest[newkey][:bare] = true unless idx.zero?
63
74
  end
64
75
 
@@ -73,9 +84,11 @@ module Metanorma
73
84
  def sectionsplit(ident)
74
85
  file = @files[ident][:ref]
75
86
  @sectionsplit = ::Metanorma::Collection::Sectionsplit
76
- .new(input: file, base: @files[ident][:out_path], dir: File.dirname(file),
77
- output: @files[ident][:out_path], compile_opts: @parent.compile_options,
78
- fileslookup: self, ident: ident, isodoc: @isodoc)
87
+ .new(input: file, base: @files[ident][:out_path],
88
+ dir: File.dirname(file), output: @files[ident][:out_path],
89
+ compile_opts: @parent.compile_options,
90
+ fileslookup: self, ident: ident, isodoc: @isodoc,
91
+ document_suffix: @files[ident][:document_suffix])
79
92
  coll = @sectionsplit.sectionsplit.sort_by { |f| f[:order] }
80
93
  xml = Nokogiri::XML(File.read(file, encoding: "UTF-8"), &:huge)
81
94
  [coll, @sectionsplit
@@ -67,15 +67,15 @@ module Metanorma
67
67
  i = x.at("//xmlns:bibdata/xmlns:docidentifier[@primary = 'true']") ||
68
68
  x.at("//xmlns:bibdata/xmlns:docidentifier")
69
69
  i or return nil
70
- @doctype ||= i["type"]&.downcase || "standoc"
70
+ @flavor = @collection.flavor
71
71
  load_isodoc
72
72
  Util::key(@isodoc.docid_prefix(i["type"], i.text))
73
73
  end
74
74
 
75
75
  def load_isodoc
76
76
  @isodoc and return
77
- @collection.compile.load_flavor(@doctype)
78
- @isodoc = Util::load_isodoc(@doctype)
77
+ @collection.compile.load_flavor(@flavor)
78
+ @isodoc = Util::load_isodoc(@flavor)
79
79
  @isodoc.i18n_init(@lang, @script, nil) # for @i18n.all_parts in docid
80
80
  end
81
81
 
@@ -153,7 +153,7 @@ module Metanorma
153
153
  def set_adoc2xml(fileref)
154
154
  File.join(
155
155
  File.dirname(fileref),
156
- File.basename(fileref).gsub(/.adoc$/, ".xml"),
156
+ File.basename(fileref).gsub(/\.adoc$/, ".xml"),
157
157
  )
158
158
  end
159
159
 
@@ -161,10 +161,8 @@ module Metanorma
161
161
  # @raise [AdocFileNotFoundException]
162
162
  def compile_adoc_file(file)
163
163
  f = (Pathname.new file).absolute? ? file : File.join(@dir, file)
164
- unless File.exist? f
165
- raise AdocFileNotFoundException.new "#{f} not found!"
166
- end
167
-
164
+ File.exist?(f) or raise AdocFileNotFoundException.new "#{f} not found!"
165
+ compile_adoc_file?(file) or return
168
166
  ::Metanorma::Util.log("[metanorma] Info: Compiling #{f}...", :info)
169
167
  ::Metanorma::Compile.new
170
168
  .compile(f, agree_to_terms: true, install_fonts: false,
@@ -172,6 +170,13 @@ module Metanorma
172
170
  ::Metanorma::Util.log("[metanorma] Info: Compiling #{f}...done!", :info)
173
171
  end
174
172
 
173
+ def compile_adoc_file?(file)
174
+ @collection.directives.detect do |d|
175
+ d.key == "recompile-xml"
176
+ end and return true
177
+ !File.exist?(file.sub(/\.adoc$/, ".xml"))
178
+ end
179
+
175
180
  def documents(mnf = @config)
176
181
  Array(mnf.entry).each_with_object({}) do |dr, m|
177
182
  if dr.file
@@ -611,13 +611,13 @@ module Metanorma
611
611
  def initialize(options)
612
612
  options[:align_cross_elements] ||= %w(note p)
613
613
  @align_cross_elements = " #{options[:align_cross_elements].join(' ')} "
614
- @doctype = options[:doctype]
614
+ @flavor = options[:flavor]
615
615
  @outdir = options[:outdir]
616
616
  @converter_opt = options[:converter_options]
617
617
  end
618
618
 
619
619
  def htmlconv
620
- x = Asciidoctor.load nil, backend: @doctype
620
+ x = Asciidoctor.load nil, backend: @flavor
621
621
  x.converter.html_converter(@converter_opt)
622
622
  end
623
623
 
@@ -157,8 +157,9 @@ module Metanorma
157
157
  def update_indirect_refs_to_docs(docxml, _docidentifier, internal_refs)
158
158
  bibitems, erefs = update_indirect_refs_to_docs_prep(docxml)
159
159
  internal_refs.each do |schema, ids|
160
+ s = "#{schema}_"
160
161
  ids.each do |id, file|
161
- k = indirect_ref_key(schema, id, docxml)
162
+ k = indirect_ref_key(s, schema, id, docxml)
162
163
  update_indirect_refs_to_docs1(docxml, k, file, bibitems, erefs)
163
164
  end
164
165
  end
@@ -169,7 +170,16 @@ module Metanorma
169
170
  [Util::gather_bibitems(docxml), Util::gather_bibitemids(docxml)]
170
171
  end
171
172
 
172
- def indirect_ref_key(schema, id, docxml)
173
+ def indirect_ref_key(schema_, schema, id, docxml)
174
+ /^#{schema_}/.match?(id) and return id
175
+ ret = schema_ + id
176
+ suffix = docxml.root["document_suffix"] or return ret
177
+ (k = docxml.root["type"]) && k != schema or return ret
178
+ "#{ret}_#{suffix}"
179
+ end
180
+
181
+ #OLD
182
+ def indirect_ref_key1(schema, id, docxml)
173
183
  /^#{schema}_/.match?(id) and return id
174
184
  ret = "#{schema}_#{id}"
175
185
  suffix = docxml.root["document_suffix"]
@@ -222,6 +232,17 @@ module Metanorma
222
232
  end
223
233
 
224
234
  def update_anchor_loc(bib, eref, docid)
235
+ loc = eref.at(".//xmlns:locality[@type = 'anchor']") or
236
+ return update_anchor_create_loc(bib, eref, docid)
237
+ a = @files.get(docid, :anchors) or return
238
+ ref = loc.elements&.first or return
239
+ anchor = suffix_anchor(ref.text, docid)
240
+ a.values.detect { |x| x.value?(anchor) } or return
241
+ ref.content = anchor
242
+ end
243
+
244
+ #OLD
245
+ def update_anchor_loc1(bib, eref, docid)
225
246
  loc = eref.at(".//xmlns:locality[@type = 'anchor']") or
226
247
  return update_anchor_create_loc(bib, eref, docid)
227
248
  ref = loc.at("./xmlns:referenceFrom") or return
@@ -233,6 +254,13 @@ module Metanorma
233
254
  end
234
255
 
235
256
  def suffix_anchor(ref, docid)
257
+ @ncnames[docid] ||= "#{Metanorma::Utils::to_ncname(docid)}_"
258
+ @files.url?(docid) or return ref
259
+ @ncnames[docid] + ref
260
+ end
261
+
262
+ #OLD
263
+ def suffix_anchor1(ref, docid)
236
264
  @ncnames[docid] ||= Metanorma::Utils::to_ncname(docid)
237
265
  anchor = ref.text
238
266
  @files.url?(docid) or anchor = "#{@ncnames[docid]}_#{anchor}"
@@ -53,7 +53,7 @@ module Metanorma
53
53
  dest = File.join(@outdir, @disambig.source2dest_filename(out.to_s))
54
54
  FileUtils.mkdir_p(File.dirname(dest))
55
55
  source = @files.get(identifier, :ref)
56
- source != dest and FileUtils.cp source, dest
56
+ source != dest and FileUtils.cp_r source, dest, remove_destination: true
57
57
  end
58
58
 
59
59
  # process each file in the collection
@@ -85,6 +85,7 @@ module Metanorma
85
85
  def gather_internal_refs
86
86
  @files.keys.each_with_object({}) do |i, refs|
87
87
  @files.get(i, :attachment) and next
88
+ @files.get(i, :sectionsplit) and next
88
89
  file, = @files.targetfile_id(i, read: true)
89
90
  gather_internal_refs1(file, i, refs)
90
91
  end
@@ -3,8 +3,8 @@ module Metanorma
3
3
  class Renderer
4
4
  def docconv
5
5
  @tempfile_cache ||= []
6
- doctype = @doctype.to_sym
7
- x = Asciidoctor.load nil, backend: doctype
6
+ flavor = @flavor.to_sym
7
+ x = Asciidoctor.load nil, backend: flavor
8
8
  x.converter.doc_converter(DocOptionsNode.new(@directives, @dirname))
9
9
  end
10
10
 
@@ -34,7 +34,8 @@ module Metanorma
34
34
 
35
35
  def wrapping_doc_body(doc)
36
36
  doc.xpath(ns("//annex | //preface | //bibliography")).each(&:remove)
37
- s = doc.at(ns("//sections"))
37
+ s = doc.at(ns("//sections")) ||
38
+ doc.root.elements[-1].after("<sections/>").next
38
39
  repl = <<~BODY
39
40
  <sections><clause id='_collection_placeholder'><p>PLACEHOLDER</p></clause></sections>
40
41
  BODY
@@ -50,8 +51,8 @@ module Metanorma
50
51
  doc
51
52
  end
52
53
 
53
- SECTION_BREAK = '<p class="MsoNormal"><br clear="all" class="section"/></p>'
54
- .freeze
54
+ SECTION_BREAK =
55
+ '<p class="MsoNormal"><br clear="all" class="section"/></p>'.freeze
55
56
  DIV1 = '<div class="WordSection1">&#xa0;</div>'.freeze
56
57
  DIV2 = '<div class="WordSection2">&#xa0;</div>'.freeze
57
58
 
@@ -69,10 +70,10 @@ module Metanorma
69
70
  end
70
71
 
71
72
  def collection_coverpages(conv, docs)
72
- conv.wordintropage and [DIV2, SECTION_BREAK].reverse.each do |s|
73
+ conv.wordintropage and [DIV2, SECTION_BREAK].reverse_each do |s|
73
74
  docs.unshift(Nokogiri::XML(s).root)
74
75
  end
75
- conv.wordcoverpage and [DIV1, SECTION_BREAK].reverse.each do |s|
76
+ conv.wordcoverpage and [DIV1, SECTION_BREAK].reverse_each do |s|
76
77
  docs.unshift(Nokogiri::XML(s).root)
77
78
  end
78
79
  docs
@@ -38,9 +38,9 @@ module Metanorma
38
38
  @script = collection.bibdata.script.first || "Latn"
39
39
  @locale = @xml.at("//xmlns:bibdata/xmlns:locale")&.text
40
40
  @registry = Metanorma::Registry.instance
41
- @doctype = doctype
41
+ @flavor = options[:flavor] || flavor
42
42
  @compile = Compile.new
43
- @compile.load_flavor(@doctype)
43
+ @compile.load_flavor(@flavor)
44
44
 
45
45
  @isodoc = isodoc_create # output processor for flavour
46
46
  @outdir = dir_name_cleanse(options[:output_folder])
@@ -136,8 +136,8 @@ module Metanorma
136
136
  @directives.detect { |d| d.key == "bilingual" } &&
137
137
  options[:format].include?(:html) and
138
138
  Metanorma::Collection::Multilingual.new(
139
- { doctype: doctype.to_sym,
140
- converter_options: PdfOptionsNode.new(doctype, @compile_options),
139
+ { flavor: flavor.to_sym,
140
+ converter_options: PdfOptionsNode.new(flavor, @compile_options),
141
141
  outdir: @outdir },
142
142
  ).to_html(pres)
143
143
  end
@@ -155,14 +155,9 @@ module Metanorma
155
155
  out
156
156
  end
157
157
 
158
- # infer the flavour from the first document identifier; relaton does that
159
- def doctype
160
- if (docid = @xml.at("//bibdata/docidentifier/@type")&.text)
161
- dt = docid.downcase
162
- elsif (docid = @xml.at("//bibdata/docidentifier")&.text)
163
- dt = docid.sub(/\s.*$/, "").lowercase
164
- else return "standoc"
165
- end
158
+ # TODO: infer flavor from publisher when available
159
+ def flavor
160
+ dt = @xml.at("//bibdata/ext/flavor")&.text or return "standoc"
166
161
  @registry.alias(dt.to_sym)&.to_s || dt
167
162
  end
168
163
 
@@ -111,9 +111,9 @@ module Metanorma
111
111
  end
112
112
 
113
113
  def pdfconv
114
- doctype = @doctype.to_sym
115
- x = Asciidoctor.load nil, backend: doctype
116
- x.converter.pdf_converter(PdfOptionsNode.new(doctype,
114
+ flavor = @flavor.to_sym
115
+ x = Asciidoctor.load nil, backend: flavor
116
+ x.converter.pdf_converter(PdfOptionsNode.new(flavor,
117
117
  @compile_options))
118
118
  end
119
119
 
@@ -153,8 +153,8 @@ module Metanorma
153
153
  end
154
154
 
155
155
  class PdfOptionsNode
156
- def initialize(doctype, options)
157
- p = Metanorma::Registry.instance.find_processor(doctype)
156
+ def initialize(flavor, options)
157
+ p = Metanorma::Registry.instance.find_processor(flavor)
158
158
  if ::Metanorma::Util::FontistHelper.has_custom_fonts?(p, options, {})
159
159
  @fonts_manifest =
160
160
  ::Metanorma::Util::FontistHelper.location_manifest(p, options)
@@ -169,7 +169,7 @@ module Metanorma
169
169
  end
170
170
 
171
171
  def isodoc_create
172
- isodoc = Util::load_isodoc(@doctype)
172
+ isodoc = Util::load_isodoc(@flavor)
173
173
  isodoc.i18n_init(@lang, @script, @locale) # read in internationalisation
174
174
  isodoc.metadata_init(@lang, @script, @locale, isodoc.i18n)
175
175
  isodoc.info(@xml, nil)
@@ -0,0 +1,100 @@
1
+ module Metanorma
2
+ class Collection
3
+ class Sectionsplit
4
+ def build_collection
5
+ collection_setup(@base, @dir)
6
+ files = sectionsplit
7
+ input_xml = Nokogiri::XML(File.read(@input_filename,
8
+ encoding: "UTF-8"), &:huge)
9
+ collection_manifest(@base, files, input_xml, @xml, @dir).render(
10
+ { format: %i(html), output_folder: "#{@output_filename}_collection",
11
+ coverpage: File.join(@dir, "cover.html") }.merge(@compile_opts),
12
+ )
13
+ section_split_attachments(out: "#{@output_filename}_collection")
14
+ end
15
+
16
+ def collection_setup(filename, dir)
17
+ FileUtils.mkdir_p "#{filename}_collection" if filename
18
+ FileUtils.mkdir_p dir
19
+ File.open(File.join(dir, "cover.html"), "w:UTF-8") do |f|
20
+ f.write(coll_cover)
21
+ end
22
+ end
23
+
24
+ def coll_cover
25
+ <<~COVER
26
+ <html><head><meta charset="UTF-8"/></head><body>
27
+ <h1>{{ doctitle }}</h1>
28
+ <h2>{{ docnumber }}</h2>
29
+ <nav>{{ navigation }}</nav>
30
+ </body></html>
31
+ COVER
32
+ end
33
+
34
+ def collection_manifest(filename, files, origxml, _presxml, dir)
35
+ File.open(File.join(dir, "#{filename}.html.yaml"), "w:UTF-8") do |f|
36
+ f.write(collectionyaml(files, origxml))
37
+ end
38
+ Metanorma::Collection.parse File.join(dir, "#{filename}.html.yaml")
39
+ end
40
+
41
+ def collectionyaml(files, xml)
42
+ ret = {
43
+ directives: ["presentation-xml", "bare-after-first"],
44
+ bibdata: {
45
+ title: {
46
+ type: "title-main", language: @lang,
47
+ content: xml.at(ns("//bibdata/title")).text
48
+ },
49
+ type: "collection",
50
+ docid: {
51
+ type: xml.at(ns("//bibdata/docidentifier/@type")).text,
52
+ id: xml.at(ns("//bibdata/docidentifier")).text,
53
+ },
54
+ },
55
+ manifest: {
56
+ level: "collection", title: "Collection",
57
+ docref: files.sort_by { |f| f[:order] }.each.map do |f|
58
+ { fileref: f[:url], identifier: f[:title] }
59
+ end
60
+ },
61
+ }
62
+ ::Metanorma::Util::recursive_string_keys(ret).to_yaml
63
+ end
64
+
65
+ def att_dir(file)
66
+ "_#{File.basename(file, '.*')}_attachments"
67
+ end
68
+
69
+ def section_split_attachments(out: nil)
70
+ attachments = att_dir(@tmp_filename)
71
+ File.directory?(attachments) or return
72
+ dir = out || File.dirname(@input_filename)
73
+ ret = File.join(dir, att_dir(@output_filename))
74
+ FileUtils.rm_rf ret
75
+ FileUtils.mv attachments, ret
76
+ File.basename(ret)
77
+ end
78
+
79
+ def section_split_cover(col, ident, _one_doc_coll)
80
+ dir = File.dirname(col.file)
81
+ collection_setup(nil, dir)
82
+ r = ::Metanorma::Collection::Renderer
83
+ .new(col, dir, output_folder: "#{ident}_collection",
84
+ format: %i(html), coverpage: File.join(dir, "cover.html"))
85
+ r.coverpage
86
+ section_split_cover1(ident, r, dir, _one_doc_coll)
87
+ end
88
+
89
+ def section_split_cover1(ident, renderer, dir, _one_doc_coll)
90
+ # filename = one_doc_coll ? "#{ident}_index.html" : "index.html"
91
+ filename = File.basename("#{ident}_index.html")
92
+ # ident can be a directory with YAML indirection
93
+ FileUtils.mv File.join(renderer.outdir, "index.html"),
94
+ File.join(dir, filename)
95
+ FileUtils.rm_rf renderer.outdir
96
+ filename
97
+ end
98
+ end
99
+ end
100
+ end
@@ -1,6 +1,7 @@
1
1
  require "yaml"
2
2
  require_relative "../../util/util"
3
3
  require_relative "../xrefprocess/xrefprocess"
4
+ require_relative "collection"
4
5
 
5
6
  module Metanorma
6
7
  class Collection
@@ -17,48 +18,13 @@ module Metanorma
17
18
  @fileslookup = opts[:fileslookup]
18
19
  @ident = opts[:ident]
19
20
  @isodoc = opts[:isodoc]
21
+ @document_suffix = opts[:document_suffix]
20
22
  end
21
23
 
22
24
  def ns(xpath)
23
25
  @isodoc.ns(xpath)
24
26
  end
25
27
 
26
- def build_collection
27
- collection_setup(@base, @dir)
28
- files = sectionsplit # (@input_filename, @base, @dir, @compile_opts)
29
- input_xml = Nokogiri::XML(File.read(@input_filename,
30
- encoding: "UTF-8"), &:huge)
31
- collection_manifest(@base, files, input_xml, @xml, @dir).render(
32
- { format: %i(html), output_folder: "#{@output_filename}_collection",
33
- coverpage: File.join(@dir, "cover.html") }.merge(@compile_opts),
34
- )
35
- end
36
-
37
- def collection_manifest(filename, files, origxml, _presxml, dir)
38
- File.open(File.join(dir, "#{filename}.html.yaml"), "w:UTF-8") do |f|
39
- f.write(collectionyaml(files, origxml))
40
- end
41
- Metanorma::Collection.parse File.join(dir, "#{filename}.html.yaml")
42
- end
43
-
44
- def collection_setup(filename, dir)
45
- FileUtils.mkdir_p "#{filename}_collection" if filename
46
- FileUtils.mkdir_p dir
47
- File.open(File.join(dir, "cover.html"), "w:UTF-8") do |f|
48
- f.write(coll_cover)
49
- end
50
- end
51
-
52
- def coll_cover
53
- <<~COVER
54
- <html><head><meta charset="UTF-8"/></head><body>
55
- <h1>{{ doctitle }}</h1>
56
- <h2>{{ docnumber }}</h2>
57
- <nav>{{ navigation }}</nav>
58
- </body></html>
59
- COVER
60
- end
61
-
62
28
  SPLITSECTIONS =
63
29
  [["//preface/*", "preface"], ["//sections/*", "sections"],
64
30
  ["//annex", nil],
@@ -71,15 +37,15 @@ module Metanorma
71
37
  @key = Metanorma::Collection::XrefProcess::xref_preprocess(xml, @isodoc)
72
38
  SPLITSECTIONS.each_with_object([]) do |n, ret|
73
39
  conflate_floatingtitles(xml.xpath(ns(n[0]))).each do |s|
74
- ret << sectionfile(xml, emptydoc(xml), "#{@base}.#{ret.size}", s,
75
- n[1])
40
+ ret << sectionfile(xml, emptydoc(xml, ret.size),
41
+ "#{@base}.#{ret.size}", s, n[1])
76
42
  end
77
43
  end
78
44
  end
79
45
 
80
46
  def block?(node)
81
47
  %w(p table formula admonition ol ul dl figure quote sourcecode example
82
- pre note pagebrreak hr bookmark requirement recommendation permission
48
+ pre note pagebreak hr bookmark requirement recommendation permission
83
49
  svgmap inputform toc passthrough review imagemap).include?(node.name)
84
50
  end
85
51
 
@@ -111,6 +77,7 @@ module Metanorma
111
77
  type = xml.root.name.sub("-standard", "").to_sym
112
78
  sectionsplit_update_xrefs(xml)
113
79
  xml1 = sectionsplit_write_semxml(filename, xml)
80
+ @tmp_filename = xml1
114
81
  [xml1, type]
115
82
  end
116
83
 
@@ -133,13 +100,16 @@ module Metanorma
133
100
  outname
134
101
  end
135
102
 
136
- def emptydoc(xml)
103
+ def emptydoc(xml, ordinal)
137
104
  out = xml.dup
138
105
  out.xpath(
139
106
  ns("//preface | //sections | //annex | //bibliography/clause | " \
140
- "//bibliography/references[not(@hidden = 'true')] | //indexsect | " \
141
- "//colophon"),
107
+ "//bibliography/references[not(@hidden = 'true')] | " \
108
+ "//indexsect | //colophon"),
142
109
  ).each(&:remove)
110
+ ordinal.zero? or out.xpath(ns("//metanorma-ext//attachment | " \
111
+ "//semantic__metanorma-ext//semantic__attachment"))
112
+ .each(&:remove) # keep only one copy of attachments
143
113
  out
144
114
  end
145
115
 
@@ -154,13 +124,34 @@ module Metanorma
154
124
  sectionfile_insert(ins, chunks, parentnode)
155
125
  Metanorma::Collection::XrefProcess::xref_process(out, xml, @key,
156
126
  @ident, @isodoc)
127
+ truncate_semxml(out, chunks)
157
128
  outname = "#{file}.xml"
158
- File.open(File.join(@splitdir, outname), "w:UTF-8") do |f|
159
- f.write(out)
160
- end
129
+ File.open(File.join(@splitdir, outname), "w:UTF-8") { |f| f.write(out) }
161
130
  outname
162
131
  end
163
132
 
133
+ def semantic_xml_ids_gather(out)
134
+ out.at(ns("//semantic__bibdata")) or return
135
+ SPLITSECTIONS.each_with_object({}) do |s, m|
136
+ out.xpath(ns(s[0].sub("//", "//semantic__"))).each do |x|
137
+ x["id"] or next
138
+ m[x["id"].sub(/^semantic__/, "")] = x
139
+ end
140
+ end
141
+ end
142
+
143
+ def semxml_presxml_nodes_match(nodes, chunks)
144
+ chunks.each do |x|
145
+ nodes[x["id"]] and nodes.delete(x["id"])
146
+ end
147
+ end
148
+
149
+ def truncate_semxml(out, chunks)
150
+ nodes = semantic_xml_ids_gather(out) or return
151
+ semxml_presxml_nodes_match(nodes, chunks)
152
+ nodes.each_value(&:remove)
153
+ end
154
+
164
155
  def sectionfile_insert(ins, chunks, parentnode)
165
156
  if parentnode
166
157
  ins.next = "<#{parentnode}/>"
@@ -173,47 +164,11 @@ module Metanorma
173
164
  title = section.at(ns("./title")) or return "[Untitled]"
174
165
  t = title.dup
175
166
  t.xpath(ns(".//tab | .//br")).each { |x| x.replace(" ") }
176
- t.xpath(ns(".//strong")).each { |x| x.replace(x.children) }
167
+ t.xpath(ns(".//bookmark")).each(&:remove)
168
+ t.xpath(ns(".//strong | .//span"))
169
+ .each { |x| x.replace(x.children) }
177
170
  t.children.to_xml
178
171
  end
179
-
180
- def collectionyaml(files, xml)
181
- ret = {
182
- directives: ["presentation-xml", "bare-after-first"],
183
- bibdata: {
184
- title: {
185
- type: "title-main", language: @lang,
186
- content: xml.at(ns("//bibdata/title")).text
187
- },
188
- type: "collection",
189
- docid: {
190
- type: xml.at(ns("//bibdata/docidentifier/@type")).text,
191
- id: xml.at(ns("//bibdata/docidentifier")).text,
192
- },
193
- },
194
- manifest: {
195
- level: "collection", title: "Collection",
196
- docref: files.sort_by { |f| f[:order] }.each.map do |f|
197
- { fileref: f[:url], identifier: f[:title] }
198
- end
199
- },
200
- }
201
- ::Metanorma::Util::recursive_string_keys(ret).to_yaml
202
- end
203
-
204
- def section_split_cover(col, ident, _one_doc_coll)
205
- dir = File.dirname(col.file)
206
- collection_setup(nil, dir)
207
- r = ::Metanorma::Collection::Renderer
208
- .new(col, dir, output_folder: "#{ident}_collection",
209
- format: %i(html), coverpage: File.join(dir, "cover.html"))
210
- r.coverpage
211
- # filename = one_doc_coll ? "#{ident}_index.html" : "index.html"
212
- filename = File.basename("#{ident}_index.html") # ident can be a directory with YAML indirection
213
- FileUtils.mv File.join(r.outdir, "index.html"), File.join(dir, filename)
214
- FileUtils.rm_rf r.outdir
215
- filename
216
- end
217
172
  end
218
173
  end
219
174
  end
@@ -30,8 +30,7 @@ module Metanorma
30
30
  end
31
31
  end
32
32
 
33
- def add_suffix_to_attributes(doc, suffix, tag_name, attr_name,
34
- isodoc)
33
+ def add_suffix_to_attrs(doc, suffix, tag_name, attr_name, isodoc)
35
34
  (suffix.nil? || suffix.empty?) and return
36
35
  doc.xpath(isodoc.ns("//#{tag_name}[@#{attr_name}]")).each do |elem|
37
36
  a = elem.attributes[attr_name].value
@@ -62,8 +61,8 @@ isodoc)
62
61
  def attr(_key); end
63
62
  end
64
63
 
65
- def load_isodoc(doctype)
66
- x = Asciidoctor.load nil, backend: doctype.to_sym
64
+ def load_isodoc(flavor)
65
+ x = Asciidoctor.load nil, backend: flavor.to_sym
67
66
  x.converter.html_converter(Dummy.new) # to obtain Isodoc class
68
67
  end
69
68
  end
@@ -10,9 +10,9 @@ module Metanorma
10
10
  key = (0...8).map { rand(65..90).chr }.join # random string
11
11
  xml.root["type"] = key
12
12
  Metanorma::Utils::anchor_attributes
13
- .each do |(tag_name, attribute_name)|
14
- ::Metanorma::Collection::Util::add_suffix_to_attributes(
15
- xml, xml.root["document_suffix"], tag_name, attribute_name, isodoc
13
+ .each do |(tag_name, attr_name)|
14
+ ::Metanorma::Collection::Util::add_suffix_to_attrs(
15
+ xml, xml.root["document_suffix"], tag_name, attr_name, isodoc
16
16
  )
17
17
  end
18
18
  key
@@ -33,6 +33,7 @@ module Metanorma
33
33
  relaton_export(isodoc, options)
34
34
  extract(isodoc, options[:extract], options[:extract_type])
35
35
  process_exts(filename, extensions, file, isodoc, options)
36
+ ensure
36
37
  clean_exit(options)
37
38
  end
38
39
 
@@ -33,15 +33,15 @@ module Metanorma
33
33
  "support the standard type #{stdtype}. Exiting.", :fatal)
34
34
  end
35
35
 
36
- private
37
-
38
- STDTYPE2FLAVOR = {}.freeze
39
-
40
36
  def stdtype2flavor(stdtype)
41
37
  flavor = STDTYPE2FLAVOR[stdtype] || stdtype
42
38
  "metanorma-#{flavor}"
43
39
  end
44
40
 
41
+ private
42
+
43
+ STDTYPE2FLAVOR = {}.freeze
44
+
45
45
  def require_flavor(flavor)
46
46
  require flavor
47
47
  Util.log("[metanorma] Info: gem `#{flavor}` loaded.", :info)
@@ -10,29 +10,9 @@ module Metanorma
10
10
  novalid: options[:novalid],
11
11
  attributes: ["nodoc", "stem", "docfile=#{filename}",
12
12
  "output_dir=#{options[:output_dir]}"] }
13
- unless asciidoctor_validate(file, filename, out_opts)
14
- warn "Cannot continue compiling Asciidoctor document"
15
- abort
16
- end
17
13
  ::Asciidoctor.convert(file, out_opts)
18
14
  end
19
15
 
20
- def asciidoctor_validate(file, filename, options)
21
- err = nil
22
- begin
23
- previous_stderr = $stderr
24
- $stderr = StringIO.new
25
- ::Asciidoctor.load(file, options)
26
- %r{(\n|^)asciidoctor: ERROR: ['"]?#{Regexp.escape(filename ||
27
- '<empty>')}['"]?: line \d+: include file not found: }
28
- .match($stderr.string) and err = $stderr.string
29
- ensure
30
- $stderr = previous_stderr
31
- end
32
- warn err unless err.nil?
33
- err.nil?
34
- end
35
-
36
16
  def extract_metanorma_options(file)
37
17
  headerextract = file.sub(/\n\n.*$/m, "\n")
38
18
  /\n:mn-document-class:\s+(?<type>\S[^\n]*)\n/ =~ headerextract
@@ -1,3 +1,3 @@
1
1
  module Metanorma
2
- VERSION = "2.0.4".freeze
2
+ VERSION = "2.0.6".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.0.4
4
+ version: 2.0.6
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-09-02 00:00:00.000000000 Z
11
+ date: 2024-10-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: asciidoctor
@@ -317,6 +317,7 @@ files:
317
317
  - lib/metanorma/collection/renderer/render_word.rb
318
318
  - lib/metanorma/collection/renderer/renderer.rb
319
319
  - lib/metanorma/collection/renderer/utils.rb
320
+ - lib/metanorma/collection/sectionsplit/collection.rb
320
321
  - lib/metanorma/collection/sectionsplit/sectionsplit.rb
321
322
  - lib/metanorma/collection/util/disambig_files.rb
322
323
  - lib/metanorma/collection/util/util.rb