metanorma 1.3.1 → 1.3.6

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