metanorma 1.3.2 → 1.3.3

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: 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