metanorma 1.3.1 → 1.3.6

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: e823c389c083ead32851781abb9fa3e28d7744d7fcd3ebacb60b051c118157ed
4
- data.tar.gz: 6a3ef75f087f322c0fcf317f72cf5d91c52576b3f322c0935c368e9c74fb7e6d
3
+ metadata.gz: 1858cecb1db05debaa3cb36f970a2bcb76b403508067ea2fa8569720fd294a98
4
+ data.tar.gz: 90f6e4bca7bd431a9d40a989c77837e6cfa47a12e436e0934624592bac0707f0
5
5
  SHA512:
6
- metadata.gz: b942d2fadf478c4aa4e8f27437a29a75c37d9515541bc1c13aec1fece10c8d81b07ad8d60cdce455341fc8f65b35d1a53b3d20bf6005281753774e21e1130354
7
- data.tar.gz: f744d5316edcd92e46fcfff79128a20353849b8a5d7037cc808afbc39aeb5c1feecb503d3e47fffad4f5fd175129f152be83c5208dc3f8ca771d748d4deb5736
6
+ metadata.gz: 8aec70e8a44751d4ab8557b793718c0bd02be3d90715a0048864257a8faf4bf23a5f4b60b780cf6d24658179eb2ecb572bf8b870ca9313b5d6f70839d2df03a5
7
+ data.tar.gz: 58814116504a8ec8c80961e836adf50b7e50bc049d2a259031e7dc92b9a8f8909ddd8bbc26219197057a6e4a9dfec4ee05cb16144f1b69fdfdc66d46d9408e9b
@@ -16,19 +16,9 @@ jobs:
16
16
  strategy:
17
17
  fail-fast: false
18
18
  matrix:
19
- ruby: [ '2.7', '2.6', '2.5', '2.4' ]
19
+ ruby: [ '3.0', '2.7', '2.6', '2.5' ]
20
20
  os: [ ubuntu-latest, windows-latest, macos-latest ]
21
21
  experimental: [ false ]
22
- include:
23
- - ruby: '3.0'
24
- os: 'ubuntu-latest'
25
- experimental: true
26
- - ruby: '3.0'
27
- os: 'windows-latest'
28
- experimental: true
29
- - ruby: '3.0'
30
- os: 'macos-latest'
31
- experimental: true
32
22
  steps:
33
23
  - uses: actions/checkout@v2
34
24
  with:
@@ -49,5 +39,5 @@ jobs:
49
39
  with:
50
40
  token: ${{ secrets.METANORMA_CI_PAT_TOKEN || secrets.GITHUB_TOKEN }}
51
41
  repository: ${{ github.repository }}
52
- event-type: notify
42
+ event-type: tests-passed
53
43
  client-payload: '{"ref": "${{ github.ref }}", "sha": "${{ github.sha }}"}'
data/.hound.yml CHANGED
@@ -1,3 +1,5 @@
1
+ # Auto-generated by Cimas: Do not edit it manually!
2
+ # See https://github.com/metanorma/cimas
1
3
  ruby:
2
- Enabled: true
4
+ enabled: true
3
5
  config_file: .rubocop.yml
data/.rubocop.yml CHANGED
@@ -1,14 +1,10 @@
1
- # This project follows the Ribose OSS style guide.
2
- # https://github.com/riboseinc/oss-guides
3
- # All project-specific additions and overrides should be specified in this file.
1
+ # Auto-generated by Cimas: Do not edit it manually!
2
+ # See https://github.com/metanorma/cimas
4
3
  inherit_from:
5
4
  - https://raw.githubusercontent.com/riboseinc/oss-guides/master/ci/rubocop.yml
6
5
 
7
6
  # local repo-specific modifications
7
+ # ...
8
8
 
9
9
  AllCops:
10
- DisplayCopNames: false
11
- StyleGuideCopsOnly: false
12
- TargetRubyVersion: 2.4
13
- Rails:
14
- Enabled: true
10
+ TargetRubyVersion: 2.5
data/Gemfile CHANGED
@@ -6,6 +6,6 @@ git_source(:github) { |repo| "https://github.com/#{repo}" }
6
6
 
7
7
  gemspec
8
8
 
9
- if File.exist? 'Gemfile.devel'
10
- eval File.read('Gemfile.devel'), nil, 'Gemfile.devel' # rubocop:disable Security/Eval
9
+ if File.exist? "Gemfile.devel"
10
+ eval File.read("Gemfile.devel"), nil, "Gemfile.devel" # rubocop:disable Security/Eval
11
11
  end
data/Rakefile CHANGED
@@ -3,4 +3,4 @@ require "rspec/core/rake_task"
3
3
 
4
4
  RSpec::Core::RakeTask.new(:spec)
5
5
 
6
- task :default => :spec
6
+ task default: :spec
@@ -1,20 +1,18 @@
1
1
  module Metanorma::AsciidoctorExtensions
2
-
3
2
  class GlobIncludeProcessor < ::Asciidoctor::Extensions::IncludeProcessor
4
- def process doc, reader, target_glob, attributes
3
+ def process(_doc, reader, target_glob, attributes)
5
4
  Dir[File.join reader.dir, target_glob].sort.reverse_each do |target|
6
5
  content = IO.readlines target
7
- content.unshift '' unless attributes['adjoin-option']
6
+ content.unshift "" unless attributes["adjoin-option"]
8
7
  reader.push_include content, target, target, 1, attributes
9
8
  end
10
9
  reader
11
10
  end
12
11
 
13
- def handles? target
14
- target.include? '*'
12
+ def handles?(target)
13
+ target.include? "*"
15
14
  end
16
15
  end
17
-
18
16
  end
19
17
 
20
18
  Asciidoctor::Extensions.register do
@@ -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,25 +44,32 @@ 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
47
- def clean_exit
48
- @log.write(File.join(File.dirname(@file), File.basename(@file, ".*") + ".err"))
49
- end
51
+ def clean_exit
52
+ @log.write(File.join(File.dirname(@file),
53
+ "#{File.basename(@file, '.*')}.err"))
54
+ end
50
55
 
51
56
  # @return [String] XML
52
57
  def to_xml
53
- Nokogiri::XML::Builder.new do |xml|
58
+ b = Nokogiri::XML::Builder.new do |xml|
54
59
  xml.send("metanorma-collection",
55
60
  "xmlns" => "http://metanorma.org") do |mc|
56
- mc << @bibdata.to_xml(bibdata: true, date_format: :full)
57
- @manifest.to_xml mc
58
- content_to_xml "prefatory", mc
59
- doccontainer mc
60
- content_to_xml "final", mc
61
+ collection_body(mc)
61
62
  end
62
- end.to_xml
63
+ end
64
+ b.to_xml
65
+ end
66
+
67
+ def collection_body(coll)
68
+ coll << @bibdata.to_xml(bibdata: true, date_format: :full)
69
+ @manifest.to_xml coll
70
+ content_to_xml "prefatory", coll
71
+ doccontainer coll
72
+ content_to_xml "final", coll
63
73
  end
64
74
 
65
75
  def render(opts)
@@ -81,7 +91,9 @@ module Metanorma
81
91
  private
82
92
 
83
93
  def parse_xml(file)
84
- xml = Nokogiri::XML File.read(file, encoding: "UTF-8")
94
+ xml = Nokogiri::XML File.read(file, encoding: "UTF-8") do |config|
95
+ config.huge
96
+ end
85
97
  if (b = xml.at("/xmlns:metanorma-collection/xmlns:bibdata"))
86
98
  bd = Relaton::Cli.parse_xml b
87
99
  end
@@ -110,7 +122,7 @@ module Metanorma
110
122
  # @parma mnf [Metanorma::CollectionManifest]
111
123
  # @return [Hash{String=>Metanorma::Document}]
112
124
  def docs_from_xml(xml, mnf)
113
- xml.xpath("//xmlns:doc-container/*/xmlns:bibdata")
125
+ xml.xpath("//xmlns:doc-container//xmlns:bibdata")
114
126
  .each_with_object({}) do |b, m|
115
127
  bd = Relaton::Cli.parse_xml b
116
128
  docref = mnf.docref_by_id bd.docidentifier.first.id
@@ -127,7 +139,7 @@ module Metanorma
127
139
  <<~CONT
128
140
 
129
141
  == #{xml.at('title')&.text}
130
- #{xml.at('p')&.text}
142
+ #{xml.at('p')&.text}
131
143
  CONT
132
144
  end
133
145
  end
@@ -152,8 +164,8 @@ module Metanorma
152
164
  return unless (cnt = send(elm))
153
165
 
154
166
  require "metanorma-#{doctype}"
155
- out = sections(dummy_header + cnt)
156
- builder.send(elm + "-content") { |b| b << out }
167
+ out = sections(dummy_header + cnt.strip)
168
+ builder.send("#{elm}-content") { |b| b << out }
157
169
  end
158
170
 
159
171
  # @param cnt [String] prefatory/final content
@@ -168,9 +180,18 @@ module Metanorma
168
180
  return unless Array(@directives).include? "documents-inline"
169
181
 
170
182
  documents.each_with_index do |(_, d), i|
171
- next if d.attachment
172
- id = format("doc%<index>09d", index: i)
173
- builder.send("doc-container", id: id) { |b| d.to_xml b }
183
+ doccontainer1(builder, d, i)
184
+ end
185
+ end
186
+
187
+ def doccontainer1(builder, doc, idx)
188
+ id = format("doc%<index>09d", index: idx)
189
+ builder.send("doc-container", id: id) do |b|
190
+ if doc.attachment
191
+ doc.bibitem and b << doc.bibitem.root.to_xml
192
+ b.attachment Metanorma::Utils::datauri(doc.file)
193
+ else doc.to_xml b
194
+ end
174
195
  end
175
196
  end
176
197
 
@@ -8,16 +8,22 @@ 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|
15
- ret[v[:type]] ||= {}
16
- index = v[:container] || v[:label].nil? || v[:label].empty? ?
17
- UUIDTools::UUID.random_create.to_s : v[:label]
18
- ret[v[:type]][index] = k
13
+ xrefs.get.each_with_object({}) do |(k, v), ret|
14
+ read_anchors1(k, v, ret)
19
15
  end
20
- ret
16
+ end
17
+
18
+ def read_anchors1(key, val, ret)
19
+ val[:type] ||= "clause"
20
+ ret[val[:type]] ||= {}
21
+ index = if val[:container] || val[:label].nil? || val[:label].empty?
22
+ UUIDTools::UUID.random_create.to_s
23
+ else val[:label]
24
+ end
25
+ ret[val[:type]][index] = key
26
+ ret[val[:type]][val[:value]] = key if val[:value]
21
27
  end
22
28
 
23
29
  # @param id [String]
@@ -31,28 +37,36 @@ module Metanorma
31
37
 
32
38
  # @param bib [Nokogiri::XML::Element]
33
39
  # @param identifier [String]
34
- def update_bibitem(bib, identifier) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
35
- docid = bib&.at(ns("./docidentifier"))&.text
36
- unless @files[docid]
37
- error = "[metanorma] Cannot find crossreference to document #{docid} "\
38
- "in document #{identifier}."
39
- @log.add("Cross-References", nil, error)
40
- Util.log(error, :warning)
41
- return
42
- end
43
- id = bib["id"]
44
- newbib = bib.replace(@files[docid][:bibdata])
45
- newbib.name = "bibitem"
46
- newbib["id"] = id
47
- newbib["hidden"] = "true"
48
- newbib&.at(ns("./ext"))&.remove
49
- _file, url = targetfile(@files[docid], false, !@files[docid][:attachment])
40
+ def update_bibitem(bib, identifier) # rubocop:disable Metrics/AbcSize
41
+ docid = bib&.at(ns("./docidentifier"))&.children&.to_xml
42
+ return fail_update_bibitem(docid, identifier) unless @files[docid]
43
+
44
+ newbib = dup_bibitem(docid, bib)
45
+ bib.replace(newbib)
46
+ _file, url = targetfile(@files[docid], relative: true, read: false,
47
+ doc: !@files[docid][:attachment])
50
48
  uri_node = Nokogiri::XML::Node.new "uri", newbib
51
49
  uri_node[:type] = "citation"
52
50
  uri_node.content = url
53
51
  newbib.at(ns("./docidentifier")).previous = uri_node
54
52
  end
55
53
 
54
+ def fail_update_bibitem(docid, identifier)
55
+ error = "[metanorma] Cannot find crossreference to document #{docid} "\
56
+ "in document #{identifier}."
57
+ @log.add("Cross-References", nil, error)
58
+ Util.log(error, :warning)
59
+ end
60
+
61
+ def dup_bibitem(docid, bib)
62
+ newbib = @files[docid][:bibdata].dup
63
+ newbib.name = "bibitem"
64
+ newbib["hidden"] = "true"
65
+ newbib&.at("./*[local-name() = 'ext']")&.remove
66
+ newbib["id"] = bib["id"]
67
+ newbib
68
+ end
69
+
56
70
  # Resolves direct links to other files in collection
57
71
  # (repo(current-metanorma-collection/x),
58
72
  # and indirect links to other files in collection
@@ -63,12 +77,13 @@ module Metanorma
63
77
  # @param internal_refs [Hash{String=>Hash{String=>String}] schema name to anchor to filename
64
78
  # @return [String] XML content
65
79
  def update_xrefs(file, identifier, internal_refs)
66
- docxml = Nokogiri::XML(file)
80
+ docxml = Nokogiri::XML(file) { |config| config.huge }
67
81
  update_indirect_refs_to_docs(docxml, internal_refs)
68
82
  add_document_suffix(identifier, docxml)
69
83
  update_direct_refs_to_docs(docxml, identifier)
70
84
  svgmap_resolve(datauri_encode(docxml))
71
- docxml.xpath(ns("//references[not(./bibitem[not(@hidden) or @hidden = 'false'])]")).each do |f|
85
+ docxml.xpath(ns("//references[bibitem][not(./bibitem[not(@hidden) or "\
86
+ "@hidden = 'false'])]")).each do |f|
72
87
  f["hidden"] = "true"
73
88
  end
74
89
  docxml.to_xml
@@ -85,11 +100,9 @@ module Metanorma
85
100
  isodoc = IsoDoc::Convert.new({})
86
101
  docxml.xpath(ns("//svgmap//eref")).each do |e|
87
102
  href = isodoc.eref_target(e)
88
- next if href == "##{e['bibitemid']}"
103
+ next if href == "##{e['bibitemid']}" ||
104
+ href =~ /^#/ && !docxml.at("//*[@id = '#{href.sub(/^#/, '')}']")
89
105
 
90
- if href.match(/^#/)
91
- next unless docxml.at("//*[@id = '#{href.sub(/^#/, '')}']")
92
- end
93
106
  e["target"] = href.strip
94
107
  e.name = "link"
95
108
  e&.elements&.remove
@@ -103,11 +116,18 @@ module Metanorma
103
116
  # Preferably with anchor, and is a job to realise dynamic lookup
104
117
  # of localities.
105
118
  def update_direct_refs_to_docs(docxml, identifier)
119
+ erefs = docxml.xpath(ns("//eref"))
120
+ .each_with_object({ citeas: {}, bibitemid: {} }) do |i, m|
121
+ m[:citeas][i["citeas"]] = true
122
+ m[:bibitemid][i["bibitemid"]] = true
123
+ end
106
124
  docxml.xpath(ns("//bibitem[not(ancestor::bibitem)]")).each do |b|
107
125
  docid = b&.at(ns("./docidentifier[@type = 'repository']"))&.text
108
126
  next unless docid && %r{^current-metanorma-collection/}.match(docid)
127
+
109
128
  update_bibitem(b, identifier)
110
- update_anchors(b, docxml, docid)
129
+ docid = b&.at(ns("./docidentifier"))&.children&.to_xml or next
130
+ erefs[:citeas][docid] and update_anchors(b, docxml, docid)
111
131
  end
112
132
  end
113
133
 
@@ -124,6 +144,9 @@ module Metanorma
124
144
  def update_indirect_refs_to_docs1(docxml, schema, id, file)
125
145
  docxml.xpath(ns("//eref[@bibitemid = '#{schema}_#{id}']")).each do |e|
126
146
  e["citeas"] = file
147
+ if a = e.at(ns(".//locality[@type = 'anchor']/referenceFrom"))
148
+ a.children = "#{a.text}_#{Metanorma::Utils::to_ncname(file)}"
149
+ end
127
150
  end
128
151
  docid = docxml.at(ns("//bibitem[@id = '#{schema}_#{id}']/"\
129
152
  "docidentifier[@type = 'repository']")) or return
@@ -131,53 +154,52 @@ module Metanorma
131
154
  docid.previous = "<docidentifier type='X'>#{file}</docidentifier>"
132
155
  end
133
156
 
134
- # update crossrefences to other documents, to include disambiguating document suffix on id
135
- def update_anchors(bib, docxml, _id) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
136
- docid = bib&.at(ns("./docidentifier"))&.text
157
+ # update crossrefences to other documents, to include
158
+ # disambiguating document suffix on id
159
+ def update_anchors(bib, docxml, docid) # rubocop:disable Metrics/AbcSize
137
160
  docxml.xpath("//xmlns:eref[@citeas = '#{docid}']").each do |e|
138
- if @files[docid]
139
- update_anchor_loc(bib, e, docid)
161
+ if @files[docid] then update_anchor_loc(bib, e, docid)
140
162
  else
141
- e << "<strong>** Unresolved reference to document #{docid}, id #{e['bibitemid']}</strong>"
163
+ e << "<strong>** Unresolved reference to document #{docid} "\
164
+ "from eref</strong>"
142
165
  end
143
166
  end
144
167
  end
145
168
 
146
- def update_anchor_loc(bib, e, docid)
147
- loc = e.at(ns(".//locality[@type = 'anchor']")) or
148
- return update_anchor_create_loc(bib, e, docid)
169
+ def update_anchor_loc(bib, eref, docid)
170
+ loc = eref.at(ns(".//locality[@type = 'anchor']")) or
171
+ return update_anchor_create_loc(bib, eref, docid)
149
172
  document_suffix = Metanorma::Utils::to_ncname(docid)
150
173
  ref = loc.at(ns("./referenceFrom")) || return
151
174
  anchor = "#{ref.text}_#{document_suffix}"
152
175
  return unless @files[docid][:anchors].inject([]) do |m, (_, x)|
153
- m+= x.values
176
+ m += x.values
154
177
  end.include?(anchor)
178
+
155
179
  ref.content = anchor
156
180
  end
157
181
 
158
182
  # if there is a crossref to another document, with no anchor, retrieve the
159
183
  # anchor given the locality, and insert it into the crossref
160
- def update_anchor_create_loc(bib, e, docid)
161
- ins = e.at(ns("./localityStack")) || return
184
+ def update_anchor_create_loc(_bib, eref, docid)
185
+ ins = eref.at(ns("./localityStack")) or return
162
186
  type = ins&.at(ns("./locality/@type"))&.text
187
+ type = "clause" if type == "annex"
163
188
  ref = ins&.at(ns("./locality/referenceFrom"))&.text
164
- (anchor = @files[docid][:anchors][type][ref]) || return
165
- ref_from = Nokogiri::XML::Node.new "referenceFrom", bib
166
- ref_from.content = anchor.sub(/^_/, "")
167
- locality = Nokogiri::XML::Node.new "locality", bib
168
- locality[:type] = "anchor"
169
- locality.add_child ref_from
170
- ins << locality
189
+ anchor = @files[docid][:anchors].dig(type, ref) or return
190
+ ins << "<locality type='anchor'><referenceFrom>#{anchor.sub(/^_/, '')}"\
191
+ "</referenceFrom></locality>"
171
192
  end
172
193
 
173
194
  # gather internal bibitem references
174
195
  def gather_internal_refs
175
196
  @files.each_with_object({}) do |(_, x), refs|
176
197
  next if x[:attachment]
177
- file, _ = targetfile(x, true)
198
+
199
+ file, = targetfile(x, read: true)
178
200
  Nokogiri::XML(file)
179
201
  .xpath(ns("//bibitem[@type = 'internal']/"\
180
- "docidentifier[@type = 'repository']")).each do |d|
202
+ "docidentifier[@type = 'repository']")).each do |d|
181
203
  a = d.text.split(%r{/}, 2)
182
204
  a.size > 1 or next
183
205
  refs[a[0]] ||= {}
@@ -189,18 +211,8 @@ module Metanorma
189
211
  # resolve file location for the target of each internal reference
190
212
  def locate_internal_refs
191
213
  refs = gather_internal_refs
192
- @files.each do |identifier, x|
193
- next if x[:attachment]
194
-
195
- file, _filename = targetfile(x, true)
196
- docxml = Nokogiri::XML(file)
197
- refs.each do |schema, ids|
198
- ids.each_key do |id|
199
- n = docxml.at("//*[@id = '#{id}']") and
200
- n.at("./ancestor-or-self::*[@type = '#{schema}']") and
201
- refs[schema][id] = identifier
202
- end
203
- end
214
+ @files.keys.reject { |k| @files[k][:attachment] }.each do |identifier|
215
+ locate_internal_refs1(refs, identifier, @files[identifier])
204
216
  end
205
217
  refs.each do |schema, ids|
206
218
  ids.each do |id, key|
@@ -209,5 +221,18 @@ module Metanorma
209
221
  end
210
222
  refs
211
223
  end
224
+
225
+ def locate_internal_refs1(refs, identifier, filedesc)
226
+ file, _filename = targetfile(filedesc, read: true)
227
+ xml = Nokogiri::XML(file) { |config| config.huge }
228
+ t = xml.xpath("//*/@id").each_with_object({}) { |i, x| x[i.text] = true }
229
+ refs.each do |schema, ids|
230
+ ids.keys.select { |id| t[id] }.each do |id|
231
+ n = xml.at("//*[@id = '#{id}']") and
232
+ n.at("./ancestor-or-self::*[@type = '#{schema}']") and
233
+ refs[schema][id] = identifier
234
+ end
235
+ end
236
+ end
212
237
  end
213
238
  end