metanorma 1.3.4 → 1.3.5

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: c92210eec85835a4e8be4a85a1c1dbe84cc1b88163e0f3c9c9be136f0019cb6e
4
- data.tar.gz: 066d89b3df0a8865f52e3e70b257a1a4ce3c71eb9f8b6840a87b9046743536d1
3
+ metadata.gz: d4ccf8d6a09fd9345faa44ae7201b4f7ee8816a6f36245c26b2482abd3f7afa9
4
+ data.tar.gz: 7997e0bea6b752e07f7db96f19b6d136b7a9740c046a0850022b477a2223a85b
5
5
  SHA512:
6
- metadata.gz: d23d488ab60995b4745184cc5a22aaaf1c9b24694186b8cfb0d7359ecaea1a999fef99dcc71c15944d5e9fbdd377f0739b35f79528f46071a7a701b512fd3108
7
- data.tar.gz: 70dd774b5b69a08661cacf0d2601b0a92cb45624848f23f6f3a397df02ef9c496ff44a64f1c1fc083d07bbfa8754921dafe6168d0472ab776cb1453b064313ce
6
+ metadata.gz: 162c6e5e79ff9f7f4f41b17444c68ec23168ee593173b72c251c8623f9a16916f6ae557bc581f39d220c2c6d68d6350c2e4f4de7c000a87e90f39bed7e825609
7
+ data.tar.gz: a92a8a6ddd41e404cb6a1e00e0a0aaa2ecd645723486769b8656bb09e10f9e595a9df81231713224f6f9781d17c1c6943135d978b5865d0c02842b5e0ccbb84c
data/.rubocop.yml CHANGED
@@ -7,4 +7,4 @@ inherit_from:
7
7
  # ...
8
8
 
9
9
  AllCops:
10
- TargetRubyVersion: 2.4
10
+ TargetRubyVersion: 2.5
@@ -4,6 +4,7 @@ require "relaton"
4
4
  require "relaton/cli"
5
5
  require "metanorma/collection_manifest"
6
6
  require "metanorma-utils"
7
+ require_relative "util"
7
8
 
8
9
  module Metanorma
9
10
  # Metanorma collection of documents
@@ -18,6 +19,8 @@ module Metanorma
18
19
  # @return [Hash<String, Metanorma::Document>]
19
20
  attr_accessor :documents
20
21
 
22
+ attr_accessor :disambig
23
+
21
24
  # @param file [String] path to source file
22
25
  # @param directives [Array<String>] documents-inline to inject the XML into
23
26
  # the collection manifest; documents-external to keeps them outside
@@ -41,6 +44,7 @@ module Metanorma
41
44
  @prefatory = args[:prefatory]
42
45
  @final = args[:final]
43
46
  @log = Metanorma::Utils::Log.new
47
+ @disambig = Util::DisambigFiles.new
44
48
  end
45
49
 
46
50
  # rubocop:enable Metrics/AbcSize,Metrics/MethodLength
@@ -11,12 +11,14 @@ module Metanorma
11
11
  xrefs = @isodoc.xref_init(@lang, @script, @isodoc, @isodoc.i18n, {})
12
12
  xrefs.parse xml
13
13
  xrefs.get.each_with_object({}) do |(k, v), ret|
14
+ v[:type] ||= "clause"
14
15
  ret[v[:type]] ||= {}
15
16
  index = if v[:container] || v[:label].nil? || v[:label].empty?
16
17
  UUIDTools::UUID.random_create.to_s
17
18
  else v[:label]
18
19
  end
19
20
  ret[v[:type]][index] = k
21
+ ret[v[:type]][v[:value]] = k if v[:value]
20
22
  end
21
23
  end
22
24
 
@@ -32,7 +34,7 @@ module Metanorma
32
34
  # @param bib [Nokogiri::XML::Element]
33
35
  # @param identifier [String]
34
36
  def update_bibitem(bib, identifier) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
35
- docid = bib&.at(ns("./docidentifier"))&.text
37
+ docid = bib&.at(ns("./docidentifier"))&.children&.to_xml
36
38
  unless @files[docid]
37
39
  error = "[metanorma] Cannot find crossreference to document #{docid} "\
38
40
  "in document #{identifier}."
@@ -41,11 +43,12 @@ module Metanorma
41
43
  return
42
44
  end
43
45
  id = bib["id"]
44
- newbib = bib.replace(@files[docid][:bibdata])
46
+ newbib = @files[docid][:bibdata].dup
45
47
  newbib.name = "bibitem"
46
48
  newbib["id"] = id
47
49
  newbib["hidden"] = "true"
48
- newbib&.at(ns("./ext"))&.remove
50
+ newbib&.at("./*[local-name() = 'ext']")&.remove
51
+ bib.replace(newbib)
49
52
  _file, url = targetfile(@files[docid], relative: true, read: false,
50
53
  doc: !@files[docid][:attachment])
51
54
  uri_node = Nokogiri::XML::Node.new "uri", newbib
@@ -69,7 +72,7 @@ module Metanorma
69
72
  add_document_suffix(identifier, docxml)
70
73
  update_direct_refs_to_docs(docxml, identifier)
71
74
  svgmap_resolve(datauri_encode(docxml))
72
- docxml.xpath(ns("//references[not(./bibitem[not(@hidden) or "\
75
+ docxml.xpath(ns("//references[bibitem][not(./bibitem[not(@hidden) or "\
73
76
  "@hidden = 'false'])]")).each do |f|
74
77
  f["hidden"] = "true"
75
78
  end
@@ -135,7 +138,7 @@ module Metanorma
135
138
  # update crossrefences to other documents, to include
136
139
  # disambiguating document suffix on id
137
140
  def update_anchors(bib, docxml, _id) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
138
- docid = bib&.at(ns("./docidentifier"))&.text
141
+ docid = bib&.at(ns("./docidentifier"))&.children.to_xml
139
142
  docxml.xpath("//xmlns:eref[@citeas = '#{docid}']").each do |e|
140
143
  if @files[docid]
141
144
  update_anchor_loc(bib, e, docid)
@@ -161,11 +164,12 @@ module Metanorma
161
164
 
162
165
  # if there is a crossref to another document, with no anchor, retrieve the
163
166
  # anchor given the locality, and insert it into the crossref
164
- def update_anchor_create_loc(bib, e, docid)
165
- ins = e.at(ns("./localityStack")) || return
167
+ def update_anchor_create_loc(bib, eref, docid)
168
+ ins = eref.at(ns("./localityStack")) or return
166
169
  type = ins&.at(ns("./locality/@type"))&.text
170
+ type = "clause" if type == "annex"
167
171
  ref = ins&.at(ns("./locality/referenceFrom"))&.text
168
- (anchor = @files[docid][:anchors][type][ref]) || return
172
+ anchor = @files[docid][:anchors].dig(type, ref) or return
169
173
  ref_from = Nokogiri::XML::Node.new "referenceFrom", bib
170
174
  ref_from.content = anchor.sub(/^_/, "")
171
175
  locality = Nokogiri::XML::Node.new "locality", bib
@@ -15,7 +15,7 @@ module Metanorma
15
15
  def read_files(path) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
16
16
  files = {}
17
17
  @xml.xpath(ns("//docref")).each do |d|
18
- identifier = d.at(ns("./identifier")).text
18
+ identifier = d.at(ns("./identifier")).children.to_xml
19
19
  files[identifier] = file_entry(d, identifier, path)
20
20
  if files[identifier][:attachment]
21
21
  files[identifier][:bibdata] = Metanorma::Document
@@ -34,15 +34,16 @@ module Metanorma
34
34
  # rel_path is the source file address, determined relative to the YAML.
35
35
  # out_path is the destination file address, with any references outside
36
36
  # the working directory (../../...) truncated
37
- def file_entry(docref, identifier, _path)
38
- ret = if docref["fileref"]
37
+ def file_entry(ref, identifier, _path)
38
+ out = ref["attachment"] ? ref["fileref"] : File.basename(ref["fileref"])
39
+ ret = if ref["fileref"]
39
40
  { type: "fileref", ref: @documents[identifier].file,
40
- rel_path: docref["fileref"],
41
- out_path: Util::source2dest_filename(docref["fileref"]) }
41
+ rel_path: ref["fileref"],
42
+ out_path: out }
42
43
  else
43
- { type: "id", ref: docref["id"] }
44
+ { type: "id", ref: ref["id"] }
44
45
  end
45
- ret[:attachment] = docref["attachment"] if docref["attachment"]
46
+ ret[:attachment] = ref["attachment"] if ref["attachment"]
46
47
  ret
47
48
  end
48
49
 
@@ -74,9 +75,9 @@ module Metanorma
74
75
  # @return [Array<String, nil>]
75
76
  def targetfile(data, options)
76
77
  options = { read: false, doc: true, relative: false }.merge(options)
77
- path = options[:relative] ? data[:out_path] : data[:ref]
78
+ path = options[:relative] ? data[:rel_path] : data[:ref]
78
79
  if data[:type] == "fileref"
79
- ref_file path, options[:read], options[:doc]
80
+ ref_file path, data[:out_path], options[:read], options[:doc]
80
81
  else
81
82
  xml_file data[:id], options[:read]
82
83
  end
@@ -86,9 +87,9 @@ module Metanorma
86
87
  # @param read [Boolean]
87
88
  # @param doc [Boolean]
88
89
  # @return [Array<String, nil>]
89
- def ref_file(ref, read, doc)
90
+ def ref_file(ref, out, read, doc)
90
91
  file = File.read(ref, encoding: "utf-8") if read
91
- filename = ref.dup
92
+ filename = out.dup
92
93
  filename.sub!(/\.xml$/, ".html") if doc
93
94
  [file, filename]
94
95
  end
@@ -96,6 +97,8 @@ module Metanorma
96
97
  # compile and output individual file in collection
97
98
  def file_compile(file, filename, identifier)
98
99
  # warn "metanorma compile -x html #{f.path}"
100
+ Array(@directives).include?("presentation-xml") and
101
+ @compile_options.merge!(passthrough_presentation_xml: true)
99
102
  c = Compile.new
100
103
  c.compile file.path, { format: :asciidoc,
101
104
  extension_keys: @format }.merge(@compile_options)
@@ -103,23 +106,24 @@ module Metanorma
103
106
  @format.each do |e|
104
107
  ext = c.processor.output_formats[e]
105
108
  fn = File.basename(filename).sub(/(?<=\.)[^\.]+$/, ext.to_s)
106
- FileUtils.mv file.path.sub(/\.xml$/, ".#{ext}"), File.join(@outdir, fn)
109
+ FileUtils.cp file.path.sub(/\.xml$/, ".#{ext}"), File.join(@outdir, fn)
107
110
  @files[identifier][:outputs][e] = File.join(@outdir, fn)
108
111
  end
109
112
  end
110
113
 
111
114
  def copy_file_to_dest(fileref)
112
- _file, filename = targetfile(fileref, read: true, doc: false)
113
115
  dest = File.join(@outdir, fileref[:out_path])
114
116
  FileUtils.mkdir_p(File.dirname(dest))
115
- FileUtils.cp filename, dest
117
+ FileUtils.cp fileref[:ref], dest
116
118
  end
117
119
 
118
120
  # process each file in the collection
119
121
  # files are held in memory, and altered as postprocessing
120
122
  def files # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
121
123
  internal_refs = locate_internal_refs
122
- @files.each do |identifier, x|
124
+ @files.each_with_index do |(identifier, x), i|
125
+ i.positive? && Array(@directives).include?("bare-after-first") and
126
+ @compile_options.merge!(bare: true)
123
127
  if x[:attachment] then copy_file_to_dest(x)
124
128
  else
125
129
  file, filename = targetfile(x, read: true)
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+ require_relative "util"
2
3
 
3
4
  module Metanorma
4
5
  # Metanorma collection's manifest
@@ -15,6 +16,7 @@ module Metanorma
15
16
  @title = title
16
17
  @docref = docref
17
18
  @manifest = manifest
19
+ @disambig = Util::DisambigFiles.new
18
20
  end
19
21
 
20
22
  class << self
@@ -43,7 +45,7 @@ module Metanorma
43
45
  # @return [Hash{String=>String}]
44
46
  def parse_docref(mnf)
45
47
  mnf.xpath("xmlns:docref").map do |dr|
46
- h = { "identifier" => dr.at("identifier").text }
48
+ h = { "identifier" => dr.at("identifier").children.to_xml }
47
49
  dr[:fileref] and h["fileref"] = dr[:fileref]
48
50
  h["attachment"] = dr[:attachment] if dr[:attachment]
49
51
  h
@@ -100,14 +102,25 @@ module Metanorma
100
102
 
101
103
  # @param builder [Nokogiri::XML::Builder]
102
104
  def docref_to_xml(builder)
105
+ @disambig = Util::DisambigFiles.new
103
106
  @docref.each do |dr|
104
- drf = builder.docref { |b| b.identifier dr["identifier"] }
105
- drf[:fileref] = Util::source2dest_filename(dr["fileref"])
106
- drf[:attachment] = dr["attachment"] if dr["attachment"]
107
- if collection.directives.include?("documents-inline")
108
- id = collection.documents.find_index { |k, _| k == dr["identifier"] }
109
- drf[:id] = format("doc%<index>09d", index: id)
107
+ drf = builder.docref do |b|
108
+ b.identifier do |i|
109
+ i << dr["identifier"]
110
+ end
110
111
  end
112
+ docref_to_xml_attrs(drf, dr)
113
+ end
114
+ end
115
+
116
+ def docref_to_xml_attrs(elem, docref)
117
+ elem[:fileref] = @disambig.source2dest_filename(docref["fileref"])
118
+ elem[:attachment] = docref["attachment"] if docref["attachment"]
119
+ if collection.directives.include?("documents-inline")
120
+ id = collection.documents.find_index do |k, _|
121
+ k == docref["identifier"]
122
+ end
123
+ elem[:id] = format("doc%<index>09d", index: id)
111
124
  end
112
125
  end
113
126
  end
@@ -3,6 +3,7 @@
3
3
  require "isodoc"
4
4
  require_relative "collection_fileprocess"
5
5
  require_relative "fontist_utils"
6
+ require_relative "util"
6
7
 
7
8
  module Metanorma
8
9
  # XML collection renderer
@@ -38,9 +39,12 @@ module Metanorma
38
39
  @compile_options = options[:compile] || {}
39
40
  @log = options[:log]
40
41
  @documents = collection.documents
42
+ @directives = collection.directives
43
+ @disambig = Util::DisambigFiles.new
41
44
 
42
45
  # list of files in the collection
43
46
  @files = read_files folder
47
+ isodoc_populate(@isodoc)
44
48
  FileUtils.rm_rf @outdir
45
49
  FileUtils.mkdir_p @outdir
46
50
  end
@@ -103,15 +107,21 @@ module Metanorma
103
107
  end
104
108
 
105
109
  # The isodoc class for the metanorma flavour we are using
106
- def isodoc # rubocop:disable Metrics/MethodLength
110
+ def isodoc
107
111
  x = Asciidoctor.load nil, backend: @doctype.to_sym
108
112
  isodoc = x.converter.html_converter(Dummy.new)
109
113
  isodoc.i18n_init(@lang, @script) # read in internationalisation
114
+ isodoc.metadata_init(@lang, @script, isodoc.i18n)
115
+ isodoc.info(@xml, nil)
116
+ isodoc
117
+ end
118
+
119
+ def isodoc_populate(isodoc)
110
120
  # create the @meta class of isodoc, with "navigation" set to the index bar
111
121
  # extracted from the manifest
112
122
  nav = indexfile(@xml.at(ns("//manifest")))
113
123
  i18n = isodoc.i18n
114
- i18n.set(:navigation, nav)
124
+ i18n.set("navigation", nav)
115
125
  isodoc.metadata_init(@lang, @script, i18n)
116
126
  # populate the @meta class of isodoc with the various metadata fields
117
127
  # native to the flavour; used to populate Liquid
@@ -168,11 +178,19 @@ module Metanorma
168
178
  # @param builder [Nokogiri::XML::Builder]
169
179
  def docrefs(elm, builder)
170
180
  elm.xpath(ns("./docref")).each do |d|
171
- identifier = d.at(ns("./identifier")).text
172
- link = if d["fileref"] then d["fileref"].sub(/\.xml$/, ".html")
173
- else d["id"] + ".html"
174
- end
175
- builder.li { builder.a identifier, href: link }
181
+ ident = d.at(ns("./identifier")).children.to_xml
182
+ builder.li do |li|
183
+ li.a **{ href: index_link(d, ident) } do |a|
184
+ a << ident
185
+ end
186
+ end
187
+ end
188
+ end
189
+
190
+ def index_link(docref, ident)
191
+ if docref["fileref"]
192
+ @files[ident][:out_path].sub(/\.xml$/, ".html")
193
+ else "#{docref['id']}.html"
176
194
  end
177
195
  end
178
196
 
@@ -74,7 +74,9 @@ module Metanorma
74
74
  memo
75
75
  end
76
76
  end
77
- if !extensions.include?(:presentation) and extensions.any? { |e| @processor.use_presentation_xml(e) }
77
+ if !extensions.include?(:presentation) && extensions.any? do |e|
78
+ @processor.use_presentation_xml(e)
79
+ end
78
80
  extensions << :presentation
79
81
  end
80
82
  extensions
@@ -88,7 +90,7 @@ module Metanorma
88
90
  options[:asciimath] and
89
91
  file.sub!(/^(=[^\n]+\n)/, "\\1:mn-keep-asciimath:\n")
90
92
  dir = File.dirname(filename)
91
- dir != '.' and
93
+ dir != "." and
92
94
  file.gsub!(/^include::/, "include::#{dir}/")
93
95
  [file, @processor.input_to_isodoc(file, filename, options)]
94
96
  when ".xml"
@@ -108,15 +110,17 @@ module Metanorma
108
110
 
109
111
  def relaton_export(isodoc, options)
110
112
  return unless options[:relaton]
113
+
111
114
  xml = Nokogiri::XML(isodoc)
112
115
  bibdata = xml.at("//bibdata") || xml.at("//xmlns:bibdata")
113
- #docid = bibdata&.at("./xmlns:docidentifier")&.text || options[:filename]
114
- #outname = docid.sub(/^\s+/, "").sub(/\s+$/, "").gsub(/\s+/, "-") + ".xml"
116
+ # docid = bibdata&.at("./xmlns:docidentifier")&.text || options[:filename]
117
+ # outname = docid.sub(/^\s+/, "").sub(/\s+$/, "").gsub(/\s+/, "-") + ".xml"
115
118
  File.open(options[:relaton], "w:UTF-8") { |f| f.write bibdata.to_xml }
116
119
  end
117
120
 
118
121
  def clean_sourcecode(xml)
119
- xml.xpath(".//callout | .//annotation | .//xmlns:callout | .//xmlns:annotation").each do |x|
122
+ xml.xpath(".//callout | .//annotation | .//xmlns:callout | "\
123
+ ".//xmlns:annotation").each do |x|
120
124
  x.remove
121
125
  end
122
126
  xml.xpath(".//br | .//xmlns:br").each { |x| x.replace("\n") }
@@ -125,6 +129,7 @@ module Metanorma
125
129
 
126
130
  def extract(isodoc, dirname, extract_types)
127
131
  return unless dirname
132
+
128
133
  if extract_types.nil? || extract_types.empty?
129
134
  extract_types = [:sourcecode, :image, :requirement]
130
135
  end
@@ -207,6 +212,7 @@ module Metanorma
207
212
  isodoc_options = @processor.extract_options(file)
208
213
  isodoc_options[:datauriimage] = true if options[:datauriimage]
209
214
  isodoc_options[:sourcefilename] = options[:filename]
215
+ isodoc_options[:bare] = options[:bare]
210
216
  file_extension = @processor.output_formats[ext]
211
217
  outfilename = f.sub(/\.[^.]+$/, ".#{file_extension}")
212
218
  if ext == :pdf
@@ -217,6 +223,8 @@ module Metanorma
217
223
  if ext == :rxl
218
224
  options[:relaton] = outfilename
219
225
  relaton_export(isodoc, options)
226
+ elsif options[:passthrough_presentation_xml] && ext == :presentation
227
+ FileUtils.cp f, presentationxml_name
220
228
  else
221
229
  begin
222
230
  @processor.use_presentation_xml(ext) ?
@@ -12,8 +12,32 @@ module Metanorma
12
12
  end
13
13
  end
14
14
 
15
- def self.source2dest_filename(name)
16
- name.sub(%r{^(\./)?(\.\./)+}, "")
15
+ class DisambigFiles
16
+ def initialize
17
+ @seen_filenames = []
18
+ end
19
+
20
+ def source2dest_filename(name, disambig = true)
21
+ n = name.sub(%r{^(\./)?(\.\./)+}, "")
22
+ dir = File.dirname(n)
23
+ base = File.basename(n)
24
+ if disambig && @seen_filenames.include?(base)
25
+ base = disambiguate_filename(base)
26
+ end
27
+ @seen_filenames << base
28
+ dir == "." ? base : File.join(dir, base)
29
+ end
30
+
31
+ def disambiguate_filename(base)
32
+ m = /^(?<start>.+\.)(?!0)(?<num>\d+)\.(?<suff>[^.]*)$/.match(base) ||
33
+ /^(?<start>.+\.)(?<suff>[^.]*)/.match(base) ||
34
+ /^(?<start>.+)$/.match(base)
35
+ i = m.names.include?("num") ? m["num"].to_i + 1 : 1
36
+ while @seen_filenames.include? base = "#{m['start']}#{i}.#{m['suff']}"
37
+ i += 1
38
+ end
39
+ base
40
+ end
17
41
  end
18
42
  end
19
43
  end
@@ -1,3 +1,3 @@
1
1
  module Metanorma
2
- VERSION = "1.3.4".freeze
2
+ VERSION = "1.3.5".freeze
3
3
  end
data/metanorma.gemspec CHANGED
@@ -20,7 +20,7 @@ Gem::Specification.new do |spec|
20
20
  spec.bindir = "bin"
21
21
  # spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
22
22
  spec.require_paths = ["lib"]
23
- spec.required_ruby_version = ">= 2.4.0"
23
+ spec.required_ruby_version = ">= 2.5.0"
24
24
 
25
25
  spec.add_runtime_dependency "asciidoctor"
26
26
  spec.add_runtime_dependency "fontist", "~> 1.8"
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.4
4
+ version: 1.3.5
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-06-07 00:00:00.000000000 Z
11
+ date: 2021-06-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: asciidoctor
@@ -286,7 +286,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
286
286
  requirements:
287
287
  - - ">="
288
288
  - !ruby/object:Gem::Version
289
- version: 2.4.0
289
+ version: 2.5.0
290
290
  required_rubygems_version: !ruby/object:Gem::Requirement
291
291
  requirements:
292
292
  - - ">="