metanorma 2.0.5 → 2.0.7

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: e6416bb8205d8f155d6affc6566e882a0cc161b16e6753e0df39be3818fb369b
4
- data.tar.gz: ecfc71eb0cecda61acd433a6a2a1512415375f69a38a9bb2c4f5f779d7ca38f4
3
+ metadata.gz: 6cf068df8203ed463672bcbef38ca1f5f1483ac2e08c9c37ee2236777dc86fad
4
+ data.tar.gz: 67c17ad923912cdf66f69b539691525a60751725e8f3d918fca5030d858661c7
5
5
  SHA512:
6
- metadata.gz: '0989d2e8fe2373f3e10733fca8e562839e6e264e3e45abc58782ab0d7ec5de8965fefc5a944154acab16968ed6292a42c000454791e782333b8cd47c5b51fce5'
7
- data.tar.gz: 9004900c903b5cd1fe081cb4ca663a8caf0c0f2a4e016024accce10873261ccd3dacac953a1686a49d647cbe0d4f1914327304df9366ad3530a42078869cda84
6
+ metadata.gz: b33588bb9dbd2f0e63c7438bf3739e3c46698be76566d4430658f12284c8221bd0c2532ae86318dcae0a4b1df90e7e270b12405e120bdd076ee18e4f85933820
7
+ data.tar.gz: 186204d57aa31ab72ea3454ea5e20b9d7b3506bcbe501c6e0c44312e22d26e83cfd1fd7b355ac3358b15cba24d234c55cbd2af369343974a34ac7cfef262c3a6
@@ -28,11 +28,16 @@ module Metanorma
28
28
  def initialize(**args)
29
29
  @file = args[:file]
30
30
  @dirname = File.expand_path(File.dirname(@file)) # feeds @manifest
31
- @documents = args[:documents] || {} # feeds initialize_directives
31
+ @documents = args[:documents] || {} # feeds initialize_directives, initialize_docs
32
32
  @bibdatas = args[:documents] || {}
33
33
  initialize_vars
34
34
  initialize_config(args[:config])
35
35
  initialize_directives
36
+ initialize_docs
37
+ validate_flavor(flavor)
38
+ end
39
+
40
+ def initialize_docs
36
41
  @documents.merge! @manifest.documents
37
42
  @bibdatas.merge! @manifest.documents
38
43
  @documents.transform_keys { |k| Util::key(k) }
@@ -53,12 +58,15 @@ module Metanorma
53
58
  @final = config.final_content
54
59
  @manifest = ::Metanorma::Collection::Manifest
55
60
  .new(config.manifest, self, @dirname) # feeds initialize_directives
61
+ @format = config.format.map(&:to_sym)
62
+ @format&.empty? and @format = nil
56
63
  end
57
64
 
58
65
  def initialize_directives
59
66
  d = @directives.each_with_object({}) { |x, m| m[x.key] = x.value }
60
67
  @coverpage = d["coverpage"]
61
68
  @coverpage_style = d["coverpage-style"]
69
+ @flavor = d["flavor"]
62
70
  if (@documents.any? || @manifest) && !d.key?("documents-inline") &&
63
71
  !d.key?("documents-external")
64
72
  @directives << ::Metanorma::Collection::Config::Directive
@@ -66,6 +74,10 @@ module Metanorma
66
74
  end
67
75
  end
68
76
 
77
+ def validate_flavor(flavor)
78
+ ::Metanorma::Compile.new.load_flavor(flavor)
79
+ end
80
+
69
81
  def clean_exit
70
82
  @log.write(File.join(@dirname,
71
83
  "#{File.basename(@file, '.*')}.err.html"))
@@ -82,8 +94,12 @@ module Metanorma
82
94
  end
83
95
 
84
96
  def render(opts)
85
- opts[:format].nil? || opts[:format].empty? and opts[:format] = [:html]
86
- ::Metanorma::Collection::Renderer.render self, opts.merge(log: @log)
97
+ if opts[:format].nil? || opts[:format].empty?
98
+ opts[:format] = @format || [:html]
99
+ end
100
+ opts[:log] = @log
101
+ opts[:flavor] = @flavor
102
+ ::Metanorma::Collection::Renderer.render self, opts
87
103
  clean_exit
88
104
  end
89
105
 
@@ -103,7 +119,7 @@ module Metanorma
103
119
  # @param builder [Nokogiri::XML::Builder]
104
120
  def content_to_xml(elm, builder)
105
121
  (cnt = send(elm)) or return
106
- @compile.load_flavor(doctype)
122
+ @compile.load_flavor(flavor)
107
123
  out = sections(dummy_header + cnt.strip)
108
124
  builder.send("#{elm}-content") { |b| b << out }
109
125
  end
@@ -111,13 +127,12 @@ module Metanorma
111
127
  # @param cnt [String] prefatory/final content
112
128
  # @return [String] XML
113
129
  def sections(cnt)
114
- c = Asciidoctor.convert(cnt, backend: doctype.to_sym, header_footer: true)
130
+ c = Asciidoctor.convert(cnt, backend: flavor.to_sym, header_footer: true)
115
131
  Nokogiri::XML(c, &:huge).at("//xmlns:sections").children.to_xml
116
132
  end
117
133
 
118
134
  # @param builder [Nokogiri::XML::Builder]
119
135
  def doccontainer(builder)
120
- # Array(@directives).include? "documents-inline" or return
121
136
  @directives.detect { |d| d.key == "documents-inline" } or return
122
137
  documents.each_with_index do |(_, d), i|
123
138
  doccontainer1(builder, d, i)
@@ -136,14 +151,19 @@ module Metanorma
136
151
  end
137
152
  end
138
153
 
139
- def doctype
140
- @doctype ||= fetch_doctype || "standoc"
154
+ def flavor
155
+ @flavor ||= fetch_flavor || "standoc"
141
156
  end
142
157
 
143
- def fetch_doctype
144
- docid = @bibdata.docidentifier.first
145
- docid or return
146
- docid.type&.downcase || docid.id&.sub(/\s.*$/, "")&.downcase
158
+ # TODO: retrieve flavor based on @bibdata publisher when lookup implemented
159
+ # Will still infer based on docid, but will validate it before proceeding
160
+ def fetch_flavor
161
+ docid = @bibdata.docidentifier.first or return
162
+ f = docid.type.downcase || docid.id.sub(/\s.*$/, "").downcase or return
163
+ require ::Metanorma::Compile.new.stdtype2flavor(f)
164
+ f
165
+ rescue LoadError
166
+ nil
147
167
  end
148
168
 
149
169
  class << self
@@ -44,7 +44,7 @@ module Metanorma
44
44
 
45
45
  xml do
46
46
  root "entry"
47
- map_attribute "id", to: :id
47
+ map_attribute "target", to: :id
48
48
  map_attribute "attachment", to: :attachment
49
49
  map_attribute "sectionsplit", to: :sectionsplit
50
50
  map_attribute "index", to: :index
@@ -55,7 +55,7 @@ module Metanorma
55
55
  map_element "title", to: :title
56
56
  map_element "bibdata", using: { from: :bibdata_from_xml,
57
57
  to: :bibdata_to_xml }
58
- map_element "entry", to: :entry # using: { from: :entry_from_xml, to: :entry_to_xml }
58
+ map_element "entry", to: :entry
59
59
  end
60
60
 
61
61
  def entry_from_xml(model, node)
@@ -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
 
@@ -62,12 +62,24 @@ module Metanorma
62
62
  file, _filename = targetfile(entry, read: true)
63
63
  xml = Nokogiri::XML(file, &:huge)
64
64
  add_document_suffix(ident, xml)
65
- entry.merge!(anchors: read_anchors(xml), ids: read_ids(xml),
66
- bibdata: xml.at(ns("//bibdata")),
67
- document_suffix: xml.root["document_suffix"])
65
+ entry.merge!(bibdata_extract(xml))
68
66
  end
69
67
  end
70
68
 
69
+ def anchors_lookup(anchors)
70
+ anchors.values.each_with_object({}) do |v, m|
71
+ v.each_value { |v1| m[v1] = true }
72
+ end
73
+ end
74
+
75
+ def bibdata_extract(xml)
76
+ anchors = read_anchors(xml)
77
+ { anchors: anchors, anchors_lookup: anchors_lookup(anchors),
78
+ ids: read_ids(xml),
79
+ bibdata: xml.at(ns("//bibdata")),
80
+ document_suffix: xml.root["document_suffix"] }
81
+ end
82
+
71
83
  def bibitem_process(entry)
72
84
  entry[:bibitem] = entry[:bibdata].dup
73
85
  entry[:bibitem].name = "bibitem"
@@ -76,7 +88,7 @@ module Metanorma
76
88
  end
77
89
 
78
90
  # ref is the absolute source file address
79
- # rel_path is the relative source file address, relative to the YAML locaton
91
+ # rel_path is the relative source file address, relative to the YAML location
80
92
  # out_path is the destination file address, with any references outside
81
93
  # the working directory (../../...) truncated, and based on relative path
82
94
  # identifier is the id with only spaces, no nbsp
@@ -110,9 +122,9 @@ module Metanorma
110
122
 
111
123
  def add_document_suffix(identifier, doc)
112
124
  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)
125
+ Metanorma::Utils::anchor_attributes.each do |(tag_name, attr_name)|
126
+ Util::add_suffix_to_attrs(doc, document_suffix, tag_name, attr_name,
127
+ @isodoc)
116
128
  end
117
129
  url_in_css_styles(doc, document_suffix)
118
130
  doc.root["document_suffix"] ||= ""
@@ -1,4 +1,5 @@
1
1
  require_relative "../sectionsplit/sectionsplit"
2
+ # require "concurrent-ruby"
2
3
 
3
4
  module Metanorma
4
5
  class Collection
@@ -16,13 +17,25 @@ module Metanorma
16
17
 
17
18
  def process_section_split_instance(key, manifest)
18
19
  s, sectionsplit_manifest = sectionsplit(key)
20
+ # section_split_instance_threads(s, manifest, key)
19
21
  s.each_with_index do |f1, i|
20
22
  add_section_split_instance(f1, manifest, key, i)
21
23
  end
22
24
  a = add_section_split_attachments(sectionsplit_manifest, key) and
23
25
  manifest["#{key}:attachments"] = a
24
- manifest["#{key}:index.html"] =
25
- add_section_split_cover(sectionsplit_manifest, key)
26
+ add_section_split_cover(manifest, sectionsplit_manifest, key)
27
+ end
28
+
29
+ def section_split_instance_threads(s, manifest, key)
30
+ @mutex = Mutex.new
31
+ pool = Concurrent::FixedThreadPool.new(4)
32
+ s.each_with_index do |f1, i|
33
+ pool.post do
34
+ add_section_split_instance(f1, manifest, key, i)
35
+ end
36
+ end
37
+ pool.shutdown
38
+ pool.wait_for_termination
26
39
  end
27
40
 
28
41
  def cleanup_section_split_instance(key, manifest)
@@ -31,24 +44,34 @@ module Metanorma
31
44
  @files[key][:indirect_key] = @sectionsplit.key
32
45
  end
33
46
 
34
- def add_section_split_cover(manifest, ident)
47
+ def add_section_split_cover(manifest, sectionsplit_manifest, ident)
35
48
  cover = @sectionsplit
36
- .section_split_cover(manifest, @parent.dir_name_cleanse(ident),
49
+ .section_split_cover(sectionsplit_manifest,
50
+ @parent.dir_name_cleanse(ident),
37
51
  one_doc_collection?)
38
52
  @files[ident][:out_path] = cover
39
- { attachment: true, index: false, out_path: cover,
40
- ref: File.join(File.dirname(manifest.file), cover) }
53
+ src = File.join(File.dirname(sectionsplit_manifest.file), cover)
54
+ m = { attachment: true, index: false, out_path: cover, ref: src }
55
+ manifest["#{ident}:index.html"] = m
56
+ one_doc_collection? and
57
+ add_cover_one_doc_coll(manifest, sectionsplit_manifest, ident, m)
58
+ end
59
+
60
+ def add_cover_one_doc_coll(manifest, sectionsplit_manifest, key, entry)
61
+ idx = File.join(File.dirname(sectionsplit_manifest.file), "index.html")
62
+ FileUtils.cp entry[:ref], idx
63
+ manifest["#{key}:index1.html"] =
64
+ entry.merge(out_path: "index.html", ref: idx)
41
65
  end
42
66
 
43
67
  def one_doc_collection?
44
- return false
45
68
  docs = 0
46
69
  @files.each_value do |v|
47
70
  v[:attachment] and next
48
71
  v[:presentationxml] and next
49
72
  docs += 1
50
73
  end
51
- docs > 1
74
+ docs <= 1
52
75
  end
53
76
 
54
77
  def add_section_split_attachments(manifest, ident)
@@ -61,16 +84,17 @@ module Metanorma
61
84
  end
62
85
 
63
86
  def add_section_split_instance(file, manifest, key, idx)
64
- presfile, newkey, xml =
65
- add_section_split_instance_prep(file, key)
66
- manifest[newkey] =
67
- { parentid: key, presentationxml: true, type: "fileref",
68
- rel_path: file[:url], out_path: File.basename(file[:url]),
69
- anchors: read_anchors(xml), ids: read_ids(xml),
70
- sectionsplit_output: true,
71
- bibdata: @files[key][:bibdata], ref: presfile }
87
+ presfile, newkey, xml = add_section_split_instance_prep(file, key)
88
+ anchors = read_anchors(xml)
89
+ m = { parentid: key, presentationxml: true, type: "fileref",
90
+ rel_path: file[:url], out_path: File.basename(file[:url]),
91
+ anchors: anchors, anchors_lookup: anchors_lookup(anchors),
92
+ ids: read_ids(xml),
93
+ sectionsplit_output: true, indirect_key: @sectionsplit.key,
94
+ bibdata: @files[key][:bibdata], ref: presfile }
95
+ m[:bare] = true unless idx.zero?
96
+ manifest[newkey] = m
72
97
  @files_to_delete << file[:url]
73
- manifest[newkey][:bare] = true unless idx.zero?
74
98
  end
75
99
 
76
100
  def add_section_split_instance_prep(file, key)
@@ -84,9 +108,11 @@ module Metanorma
84
108
  def sectionsplit(ident)
85
109
  file = @files[ident][:ref]
86
110
  @sectionsplit = ::Metanorma::Collection::Sectionsplit
87
- .new(input: file, base: @files[ident][:out_path], dir: File.dirname(file),
88
- output: @files[ident][:out_path], compile_opts: @parent.compile_options,
89
- fileslookup: self, ident: ident, isodoc: @isodoc)
111
+ .new(input: file, base: @files[ident][:out_path],
112
+ dir: File.dirname(file), output: @files[ident][:out_path],
113
+ compile_opts: @parent.compile_options,
114
+ fileslookup: self, ident: ident, isodoc: @isodoc,
115
+ document_suffix: @files[ident][:document_suffix])
90
116
  coll = @sectionsplit.sectionsplit.sort_by { |f| f[:order] }
91
117
  xml = Nokogiri::XML(File.read(file, encoding: "UTF-8"), &:huge)
92
118
  [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