metanorma 1.3.2 → 1.3.3

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: 6da8527ed559d4b6833977c169022db5dfec3a9d93926257586d9e676a11e578
4
- data.tar.gz: cf9cc8d31d2ae7cbd08787dcb3f4a79747e85fad5c142bc02fd377df91e467e0
3
+ metadata.gz: fec4f760c22a19793bca3f3cb2c5abc0b355a8554d5ac0720fe8e679a26db842
4
+ data.tar.gz: ffa03687166474e66611a2fa0f5841281ae5b1127e078dd7cbf2993ec1a15f65
5
5
  SHA512:
6
- metadata.gz: 07f86288c180813daf6ceed810dec2bfecc1cdb2605bf45de5f363cf0a7187babffa37095f208679fd1d1a3cdc6aeebfc879a5293f51c4f49ecc9c473a077295
7
- data.tar.gz: bc111d4ca32a5b3135cf518c748370654b9f99803b4123de42b2603965bba4a1e6164e6b3307f7f9afa8b53b7b721b1b01941eee22fd3dd5d63d95a8597cb71e
6
+ metadata.gz: 9721c89fe96d4bfb1bf6458fc79d824fa16887a349b2bdcd9618d6528ec0b32abf86158bc7658de8288bcf130ce3008427fcc06fe036179c652b70a2a3edd9f6
7
+ data.tar.gz: 74993bec3d7dca356699d821dadb55f35f7f7c20d6a8270e2c3fc9e224225504fe4fe3dee77cdf9cbc0a55eeee033df0253a17307fac8fec76772dc02c5c2f2f
@@ -51,16 +51,21 @@ module Metanorma
51
51
 
52
52
  # @return [String] XML
53
53
  def to_xml
54
- Nokogiri::XML::Builder.new do |xml|
54
+ b = Nokogiri::XML::Builder.new do |xml|
55
55
  xml.send("metanorma-collection",
56
56
  "xmlns" => "http://metanorma.org") do |mc|
57
- mc << @bibdata.to_xml(bibdata: true, date_format: :full)
58
- @manifest.to_xml mc
59
- content_to_xml "prefatory", mc
60
- doccontainer mc
61
- content_to_xml "final", mc
57
+ collection_body(mc)
62
58
  end
63
- end.to_xml
59
+ end
60
+ b.to_xml
61
+ end
62
+
63
+ def collection_body(coll)
64
+ coll << @bibdata.to_xml(bibdata: true, date_format: :full)
65
+ @manifest.to_xml coll
66
+ content_to_xml "prefatory", coll
67
+ doccontainer coll
68
+ content_to_xml "final", coll
64
69
  end
65
70
 
66
71
  def render(opts)
@@ -128,7 +133,7 @@ module Metanorma
128
133
  <<~CONT
129
134
 
130
135
  == #{xml.at('title')&.text}
131
- #{xml.at('p')&.text}
136
+ #{xml.at('p')&.text}
132
137
  CONT
133
138
  end
134
139
  end
@@ -153,7 +158,7 @@ module Metanorma
153
158
  return unless (cnt = send(elm))
154
159
 
155
160
  require "metanorma-#{doctype}"
156
- out = sections(dummy_header + cnt)
161
+ out = sections(dummy_header + cnt.strip)
157
162
  builder.send("#{elm}-content") { |b| b << out }
158
163
  end
159
164
 
@@ -169,13 +174,17 @@ module Metanorma
169
174
  return unless Array(@directives).include? "documents-inline"
170
175
 
171
176
  documents.each_with_index do |(_, d), i|
172
- id = format("doc%<index>09d", index: i)
173
- builder.send("doc-container", id: id) do |b|
174
- if d.attachment
175
- d.bibitem and b << d.bibitem.root.to_xml
176
- b.attachment Metanorma::Utils::datauri(d.file)
177
- else d.to_xml b
178
- end
177
+ doccontainer1(builder, d, i)
178
+ end
179
+ end
180
+
181
+ def doccontainer1(builder, doc, idx)
182
+ id = format("doc%<index>09d", index: idx)
183
+ builder.send("doc-container", id: id) do |b|
184
+ if doc.attachment
185
+ doc.bibitem and b << doc.bibitem.root.to_xml
186
+ b.attachment Metanorma::Utils::datauri(doc.file)
187
+ else doc.to_xml b
179
188
  end
180
189
  end
181
190
  end
@@ -8,19 +8,16 @@ module Metanorma
8
8
  # UUIDs, so that their IDs can at least be registered to be tracked
9
9
  # as existing.
10
10
  def read_anchors(xml)
11
- ret = {}
12
11
  xrefs = @isodoc.xref_init(@lang, @script, @isodoc, @isodoc.i18n, {})
13
12
  xrefs.parse xml
14
- xrefs.get.each do |k, v|
13
+ xrefs.get.each_with_object({}) do |(k, v), ret|
15
14
  ret[v[:type]] ||= {}
16
15
  index = if v[:container] || v[:label].nil? || v[:label].empty?
17
16
  UUIDTools::UUID.random_create.to_s
18
- else
19
- v[:label]
17
+ else v[:label]
20
18
  end
21
19
  ret[v[:type]][index] = k
22
20
  end
23
- ret
24
21
  end
25
22
 
26
23
  # @param id [String]
@@ -72,7 +69,8 @@ module Metanorma
72
69
  add_document_suffix(identifier, docxml)
73
70
  update_direct_refs_to_docs(docxml, identifier)
74
71
  svgmap_resolve(datauri_encode(docxml))
75
- docxml.xpath(ns("//references[not(./bibitem[not(@hidden) or @hidden = 'false'])]")).each do |f|
72
+ docxml.xpath(ns("//references[not(./bibitem[not(@hidden) or "\
73
+ "@hidden = 'false'])]")).each do |f|
76
74
  f["hidden"] = "true"
77
75
  end
78
76
  docxml.to_xml
@@ -89,33 +87,8 @@ module Metanorma
89
87
  isodoc = IsoDoc::Convert.new({})
90
88
  docxml.xpath(ns("//svgmap//eref")).each do |e|
91
89
  href = isodoc.eref_target(e)
92
- next if href == "##{e['bibitemid']}"
93
-
94
- # XML collection renderer
95
- # map locality type and label (e.g. "clause" "1") to id = anchor for
96
- # a document
97
- # Note: will only key clauses, which have unambiguous reference label in
98
- # locality. Notes, examples etc with containers are just plunked against
99
- # UUIDs, so that their IDs can at least be registered to be tracked
100
- # as existing.
101
- # @param id [String]
102
- # @param read [Boolean]
103
- # @return [Array<String, nil>]
104
- # @param bib [Nokogiri::XML::Element]
105
- # @param identifier [String]
106
- # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
107
- # Resolves direct links to other files in collection
108
- # (repo(current-metanorma-collection/x),
109
- # and indirect links to other files in collection
110
- # (bibitem[@type = 'internal'] pointing to a file anchor
111
- # in another file in the collection)
112
- # @param file [String] XML content
113
- # @param identifier [String] docid
114
- # @param internal_refs [Hash{String=>Hash{String=>String}] schema name to anchor to filename
115
- # @return [String] XML content
116
- if href =~ /^#/ && !docxml.at("//*[@id = '#{href.sub(/^#/, '')}']")
117
- next
118
- end
90
+ next if href == "##{e['bibitemid']}" ||
91
+ href =~ /^#/ && !docxml.at("//*[@id = '#{href.sub(/^#/, '')}']")
119
92
 
120
93
  e["target"] = href.strip
121
94
  e.name = "link"
@@ -159,14 +132,16 @@ module Metanorma
159
132
  docid.previous = "<docidentifier type='X'>#{file}</docidentifier>"
160
133
  end
161
134
 
162
- # update crossrefences to other documents, to include disambiguating document suffix on id
135
+ # update crossrefences to other documents, to include
136
+ # disambiguating document suffix on id
163
137
  def update_anchors(bib, docxml, _id) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
164
138
  docid = bib&.at(ns("./docidentifier"))&.text
165
139
  docxml.xpath("//xmlns:eref[@citeas = '#{docid}']").each do |e|
166
140
  if @files[docid]
167
141
  update_anchor_loc(bib, e, docid)
168
142
  else
169
- e << "<strong>** Unresolved reference to document #{docid}, id #{e['bibitemid']}</strong>"
143
+ e << "<strong>** Unresolved reference to document #{docid}, "\
144
+ "id #{e['bibitemid']}</strong>"
170
145
  end
171
146
  end
172
147
  end
@@ -219,18 +194,8 @@ module Metanorma
219
194
  # resolve file location for the target of each internal reference
220
195
  def locate_internal_refs
221
196
  refs = gather_internal_refs
222
- @files.each do |identifier, x|
223
- next if x[:attachment]
224
-
225
- file, _filename = targetfile(x, read: true)
226
- docxml = Nokogiri::XML(file)
227
- refs.each do |schema, ids|
228
- ids.each_key do |id|
229
- n = docxml.at("//*[@id = '#{id}']") and
230
- n.at("./ancestor-or-self::*[@type = '#{schema}']") and
231
- refs[schema][id] = identifier
232
- end
233
- end
197
+ @files.keys.reject { |k| @files[k][:attachment] }.each do |identifier|
198
+ locate_internal_refs1(refs, identifier, @files[identifier])
234
199
  end
235
200
  refs.each do |schema, ids|
236
201
  ids.each do |id, key|
@@ -239,5 +204,17 @@ module Metanorma
239
204
  end
240
205
  refs
241
206
  end
207
+
208
+ def locate_internal_refs1(refs, identifier, filedesc)
209
+ file, _filename = targetfile(filedesc, read: true)
210
+ docxml = Nokogiri::XML(file)
211
+ refs.each do |schema, ids|
212
+ ids.each_key do |id|
213
+ n = docxml.at("//*[@id = '#{id}']") and
214
+ n.at("./ancestor-or-self::*[@type = '#{schema}']") and
215
+ refs[schema][id] = identifier
216
+ end
217
+ end
218
+ end
242
219
  end
243
220
  end
@@ -16,7 +16,7 @@ module Metanorma
16
16
  files = {}
17
17
  @xml.xpath(ns("//docref")).each do |d|
18
18
  identifier = d.at(ns("./identifier")).text
19
- files[identifier] = file_entry(d, path)
19
+ files[identifier] = file_entry(d, identifier, path)
20
20
  if files[identifier][:attachment]
21
21
  files[identifier][:bibdata] = Metanorma::Document
22
22
  .attachment_bibitem(identifier).root
@@ -31,10 +31,14 @@ module Metanorma
31
31
  files
32
32
  end
33
33
 
34
- def file_entry(docref, path)
34
+ # rel_path is the source file address, determined relative to the YAML.
35
+ # out_path is the destination file address, with any references outside
36
+ # the working directory (../../...) truncated
37
+ def file_entry(docref, identifier, _path)
35
38
  ret = if docref["fileref"]
36
- { type: "fileref", ref: File.join(path, docref["fileref"]),
37
- rel_path: docref["fileref"] }
39
+ { type: "fileref", ref: @documents[identifier].file,
40
+ rel_path: docref["fileref"],
41
+ out_path: Util::source2dest_filename(docref["fileref"]) }
38
42
  else
39
43
  { type: "id", ref: docref["id"] }
40
44
  end
@@ -65,12 +69,12 @@ module Metanorma
65
69
  # @param read [Boolean] read the file in and return it
66
70
  # @param doc [Boolean] I am a Metanorma document,
67
71
  # so my URL should end with html or pdf or whatever
68
- # @param relative [Boolean] Return path relative to YAML file,
69
- # not relative to calling function
72
+ # @param relative [Boolean] Return output path,
73
+ # formed relative to YAML file, not input path, relative to calling function
70
74
  # @return [Array<String, nil>]
71
75
  def targetfile(data, options)
72
76
  options = { read: false, doc: true, relative: false }.merge(options)
73
- path = options[:relative] ? data[:rel_path] : data[:ref]
77
+ path = options[:relative] ? data[:out_path] : data[:ref]
74
78
  if data[:type] == "fileref"
75
79
  ref_file path, options[:read], options[:doc]
76
80
  else
@@ -90,23 +94,23 @@ module Metanorma
90
94
  end
91
95
 
92
96
  # compile and output individual file in collection
93
- def file_compile(f, filename, identifier)
97
+ def file_compile(file, filename, identifier)
94
98
  # warn "metanorma compile -x html #{f.path}"
95
99
  c = Compile.new
96
- c.compile f.path, { format: :asciidoc,
97
- extension_keys: @format }.merge(@compile_options)
100
+ c.compile file.path, { format: :asciidoc,
101
+ extension_keys: @format }.merge(@compile_options)
98
102
  @files[identifier][:outputs] = {}
99
103
  @format.each do |e|
100
104
  ext = c.processor.output_formats[e]
101
105
  fn = File.basename(filename).sub(/(?<=\.)[^\.]+$/, ext.to_s)
102
- FileUtils.mv f.path.sub(/\.xml$/, ".#{ext}"), File.join(@outdir, fn)
106
+ FileUtils.mv file.path.sub(/\.xml$/, ".#{ext}"), File.join(@outdir, fn)
103
107
  @files[identifier][:outputs][e] = File.join(@outdir, fn)
104
108
  end
105
109
  end
106
110
 
107
111
  def copy_file_to_dest(fileref)
108
112
  _file, filename = targetfile(fileref, read: true, doc: false)
109
- dest = File.join(@outdir, fileref[:rel_path])
113
+ dest = File.join(@outdir, fileref[:out_path])
110
114
  FileUtils.mkdir_p(File.dirname(dest))
111
115
  FileUtils.cp filename, dest
112
116
  end
@@ -44,7 +44,7 @@ module Metanorma
44
44
  def parse_docref(mnf)
45
45
  mnf.xpath("xmlns:docref").map do |dr|
46
46
  h = { "identifier" => dr.at("identifier").text }
47
- h["fileref"] = dr[:fileref] if dr[:fileref]
47
+ dr[:fileref] and h["fileref"] = dr[:fileref]
48
48
  h["attachment"] = dr[:attachment] if dr[:attachment]
49
49
  h
50
50
  end
@@ -102,7 +102,7 @@ module Metanorma
102
102
  def docref_to_xml(builder)
103
103
  @docref.each do |dr|
104
104
  drf = builder.docref { |b| b.identifier dr["identifier"] }
105
- drf[:fileref] = dr["fileref"]
105
+ drf[:fileref] = Util::source2dest_filename(dr["fileref"])
106
106
  drf[:attachment] = dr["attachment"] if dr["attachment"]
107
107
  if collection.directives.include?("documents-inline")
108
108
  id = collection.documents.find_index { |k, _| k == dr["identifier"] }
@@ -21,9 +21,9 @@ module Metanorma
21
21
  # the collection, and that the flavour gem can sensibly process it. We may
22
22
  # need to enhance metadata in the flavour gems isodoc/metadata.rb with
23
23
  # collection metadata
24
- def initialize(xml, folder, options = {}) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
24
+ def initialize(collection, folder, options = {}) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
25
25
  check_options options
26
- @xml = Nokogiri::XML xml # @xml is the collection manifest
26
+ @xml = Nokogiri::XML collection.to_xml # @xml is the collection manifest
27
27
  @lang = @xml&.at(ns("//bibdata/language"))&.text || "en"
28
28
  @script = @xml&.at(ns("//bibdata/script"))&.text || "Latn"
29
29
  @doctype = doctype
@@ -37,6 +37,7 @@ module Metanorma
37
37
  @format = options[:format]
38
38
  @compile_options = options[:compile] || {}
39
39
  @log = options[:log]
40
+ @documents = collection.documents
40
41
 
41
42
  # list of files in the collection
42
43
  @files = read_files folder
@@ -51,7 +52,7 @@ module Metanorma
51
52
  # @option options [Strong] :ourput_folder output directory
52
53
  def self.render(col, options = {})
53
54
  folder = File.dirname col.file
54
- cr = new(col.to_xml, folder, options)
55
+ cr = new(col, folder, options)
55
56
  cr.files
56
57
  cr.concatenate(col, options)
57
58
  cr.coverpage if options[:format]&.include?(:html)
@@ -61,11 +62,13 @@ module Metanorma
61
62
  options[:format] << :presentation if options[:format].include?(:pdf)
62
63
  options[:format].uniq.each do |e|
63
64
  next unless %i(presentation xml).include?(e)
65
+
64
66
  ext = e == :presentation ? "presentation.xml" : e.to_s
65
67
  out = col.clone
66
68
  out.directives << "documents-inline"
67
69
  out.documents.keys.each do |id|
68
70
  next if @files[id][:attachment]
71
+
69
72
  filename = @files[id][:outputs][e]
70
73
  out.documents[id] = Metanorma::Document.raw_file(filename)
71
74
  end
@@ -135,6 +138,8 @@ module Metanorma
135
138
  # populate liquid template of ARGV[1] with metadata extracted from
136
139
  # collection manifest
137
140
  def coverpage
141
+ return unless @coverpage
142
+
138
143
  File.open(File.join(@outdir, "index.html"), "w:UTF-8") do |f|
139
144
  f.write @isodoc.populate_template(File.read(@coverpage))
140
145
  end
@@ -199,8 +204,6 @@ module Metanorma
199
204
  unless options[:format].is_a?(Array) && (FORMATS & options[:format]).any?
200
205
  raise ArgumentError, "Need to specify formats (xml,html,pdf,doc)"
201
206
  end
202
- return if !options[:format].include?(:html) || options[:coverpage]
203
- raise ArgumentError, "Need to specify a coverpage to render HTML"
204
207
  end
205
208
  end
206
209
  end
@@ -20,7 +20,7 @@ module Metanorma
20
20
  def compile(filename, options = {})
21
21
  require_libraries(options)
22
22
  options = options_extract(filename, options)
23
- validate_type(options) && validate_format(options) || (return nil)
23
+ validate_options(options)
24
24
  @processor = @registry.find_processor(options[:type].to_sym)
25
25
  extensions = get_extensions(options) or return nil
26
26
  (file, isodoc = process_input(filename, options)) or return nil
@@ -1,45 +1,51 @@
1
1
  module Metanorma
2
2
  class Compile
3
+ def validate_options(options)
4
+ validate_type(options)
5
+ validate_format(options)
6
+ end
7
+
3
8
  def validate_type(options)
4
9
  unless options[:type]
5
10
  Util.log("[metanorma] Error: Please specify a standard type: "\
6
- "#{@registry.supported_backends}.", :error)
7
- return nil
11
+ "#{@registry.supported_backends}.", :fatal)
8
12
  end
9
13
  stdtype = options[:type].to_sym
10
- metanorma_flavor = "metanorma-#{stdtype}"
14
+ load_flavor(stdtype)
15
+ end
16
+
17
+ def validate_format(options)
18
+ unless options[:format] == :asciidoc
19
+ Util.log("[metanorma] Error: Only source file format currently "\
20
+ "supported is 'asciidoc'.", :fatal)
21
+ end
22
+ end
23
+
24
+ private
25
+
26
+ def load_flavor(stdtype)
27
+ flavor = "metanorma-#{stdtype}"
11
28
  unless @registry.supported_backends.include? stdtype
12
- Util.log("[metanorma] Info: Loading `#{metanorma_flavor}` gem "\
29
+ Util.log("[metanorma] Info: Loading `#{flavor}` gem "\
13
30
  "for standard type `#{stdtype}`.", :info)
14
31
  end
15
- begin
16
- require "metanorma-#{stdtype}"
17
- Util.log("[metanorma] Info: gem `#{metanorma_flavor}` loaded.", :info)
18
- rescue Gem::ConflictError
19
- Util.log("[metanorma] Error: Couldn't resolve dependencies for "\
20
- "`metanorma-#{stdtype}`, Please add it to your Gemfile "\
21
- "and run bundle install first", :error)
22
- return false
23
- rescue LoadError
24
- Util.log("[metanorma] Error: loading gem `#{metanorma_flavor}` "\
25
- "failed. Exiting.", :error)
26
- return false
27
- end
32
+ require_flavor(flavor, stdtype)
28
33
  unless @registry.supported_backends.include? stdtype
29
- Util.log("[metanorma] Error: The `#{metanorma_flavor}` gem "\
30
- "still doesn't support `#{stdtype}`. Exiting.", :error)
31
- return false
34
+ Util.log("[metanorma] Error: The `#{flavor}` gem "\
35
+ "still doesn't support `#{stdtype}`. Exiting.", :fatal)
32
36
  end
33
- true
34
37
  end
35
38
 
36
- def validate_format(options)
37
- unless options[:format] == :asciidoc
38
- Util.log("[metanorma] Error: Only source file format currently "\
39
- "supported is 'asciidoc'.", :error)
40
- return false
41
- end
42
- true
39
+ def require_flavor(flavor, stdtype)
40
+ require flavor
41
+ Util.log("[metanorma] Info: gem `#{flavor}` loaded.", :info)
42
+ rescue Gem::ConflictError
43
+ Util.log("[metanorma] Error: Couldn't resolve dependencies for "\
44
+ "`metanorma-#{stdtype}`, Please add it to your Gemfile "\
45
+ "and run bundle install first", :fatal)
46
+ rescue LoadError
47
+ Util.log("[metanorma] Error: loading gem `#{flavor}` "\
48
+ "failed. Exiting.", :fatal)
43
49
  end
44
50
  end
45
51
  end
@@ -11,5 +11,9 @@ module Metanorma
11
11
  exit(1)
12
12
  end
13
13
  end
14
+
15
+ def self.source2dest_filename(name)
16
+ name.sub(%r{^(\./)?(\.\./)+}, "")
17
+ end
14
18
  end
15
19
  end
@@ -1,3 +1,3 @@
1
1
  module Metanorma
2
- VERSION = "1.3.2".freeze
2
+ VERSION = "1.3.3".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: 1.3.2
4
+ version: 1.3.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-05-10 00:00:00.000000000 Z
11
+ date: 2021-05-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: asciidoctor