metanorma 2.0.4 → 2.0.6

Sign up to get free protection for your applications and to get access to all the features.
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