metanorma 1.3.4 → 1.3.5

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