metanorma 1.2.1 → 1.2.6pre

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: 6a7eed0e26e4338f4485a309446b6d0c008dc76773d8672e7560fa672af77b70
4
- data.tar.gz: a5d36260967385bb27afb23cfc024802e08809212acdbfc369bffa5c46c37196
3
+ metadata.gz: 2f44605746ed08329b51fabc943ab3e0587e7e4cf07645fcd20505121a1f7544
4
+ data.tar.gz: 7531752fd6c7b2d1c3f7e13deee84d54276a2dc7ed7bd2e05cab02ce83ce6b9b
5
5
  SHA512:
6
- metadata.gz: 39e7761252dfc8467cd23fe1f5051c74a0c441b3cc8ff0d509793c8eaf04e7f135792ed34b12b1307a3cf85f593bb6b4f955feed831a3b0b1e156aa2a11a65de
7
- data.tar.gz: 7a94bd3e934c6255ecaa5a153eaf286aaf34ae49f03b326e4dbf12d03cbe51fca18bf971de3c7c68b399ea82f57671c4cbfc0d060b58e4e893cc0d7799fcad7c
6
+ metadata.gz: a1d8fc5ab61a03b0b2600bbf75f9d9945fefc463e0003f41b7534887c9c88826ed7dfa6cf264e852ac40493d4ced15fb639b3ee304bf0286328543ca119de296
7
+ data.tar.gz: 4ce326412a2248432450bd9fbe08c431bc5369bffa623e02895f8ce7d814ff000c50344bf7fa6653a55ac19deacebe31b9d07887ada84436a940db14a412712d
@@ -3,16 +3,16 @@
3
3
  name: notify
4
4
 
5
5
  on:
6
- push:
7
- branches: [ master ]
8
- tags:
9
- - '*'
6
+ repository_dispatch:
7
+ types: [ notify ]
10
8
 
11
9
  jobs:
12
10
  notify:
13
11
  name: Notify dependent repos
14
12
  runs-on: ubuntu-latest
15
13
  steps:
14
+ - uses: actions/checkout@v2
15
+
16
16
  - name: Trigger repositories
17
17
  env:
18
18
  GH_USERNAME: metanorma-ci
@@ -21,7 +21,7 @@ jobs:
21
21
  curl -LO --retry 3 https://raw.githubusercontent.com/metanorma/metanorma-build-scripts/master/trigger-gh-actions.sh
22
22
  [[ -f ".github/workflows/dependent_repos.env" ]] && source .github/workflows/dependent_repos.env
23
23
  CLIENT_PAYLOAD=$(cat <<EOF
24
- "{ "ref": "${GITHUB_REF}", "repo": "${GITHUB_REPOSITORY}" }"
24
+ "{ "ref": "${{ github.event.client_payload.ref }}", "repo": "${GITHUB_REPOSITORY}" }"
25
25
  EOF
26
26
  )
27
27
  for repo in $TEMPLATE_REPOS" $SAMPLES_REPOS"
@@ -30,7 +30,7 @@ jobs:
30
30
  done
31
31
 
32
32
  - name: Trigger release repositories
33
- if: github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags/v')
33
+ if: github.event.client_payload.ref == 'refs/heads/master' || startsWith(github.event.client_payload.ref, 'refs/tags/v')
34
34
  env:
35
35
  GH_USERNAME: metanorma-ci
36
36
  GH_ACCESS_TOKEN: ${{ secrets.METANORMA_CI_PAT_TOKEN }}
@@ -38,7 +38,7 @@ jobs:
38
38
  curl -LO --retry 3 https://raw.githubusercontent.com/metanorma/metanorma-build-scripts/master/trigger-gh-actions.sh
39
39
  [[ -f ".github/workflows/dependent_repos.env" ]] && source .github/workflows/dependent_repos.env
40
40
  CLIENT_PAYLOAD=$(cat <<EOF
41
- "{ "ref": "${GITHUB_REF}", "repo": "${GITHUB_REPOSITORY}" }"
41
+ "{ "ref": "${{ github.event.client_payload.ref }}", "repo": "${GITHUB_REPOSITORY}" }"
42
42
  EOF
43
43
  )
44
44
  for repo in $DEPENDENT_REPOS
@@ -4,7 +4,7 @@ name: rake
4
4
 
5
5
  on:
6
6
  push:
7
- branches: [ master ]
7
+ branches: [ master, main ]
8
8
  tags: [ v* ]
9
9
  pull_request:
10
10
 
@@ -32,28 +32,29 @@ jobs:
32
32
  steps:
33
33
  - uses: actions/checkout@master
34
34
 
35
- - name: Use Ruby
36
- uses: ruby/setup-ruby@v1
35
+ - uses: ruby/setup-ruby@v1
37
36
  with:
38
37
  ruby-version: ${{ matrix.ruby }}
39
- bundler-cache: true
40
38
 
41
- - name: Update gems
42
- run: bundle install --jobs 4 --retry 3
39
+ - uses: actions/cache@v2
40
+ with:
41
+ path: vendor/bundle
42
+ key: bundle-${{ matrix.os }}-${{ matrix.ruby }}-${{ hashFiles('**/*.gemspec') }}
43
+ restore-keys: bundle-${{ matrix.os }}-${{ matrix.ruby }}
44
+
45
+ - run: bundle config set path 'vendor/bundle'
46
+
47
+ - run: bundle install --jobs 4 --retry 3
43
48
 
44
- - name: Run specs
45
- run: bundle exec rake
49
+ - run: bundle exec rake
46
50
 
47
- notify:
48
- name: Trigger notify workflow
51
+ tests-passed:
49
52
  needs: rake
50
53
  runs-on: ubuntu-latest
51
54
  steps:
52
- - name: Trigger notify workflow
53
- uses: Sibz/github-status-action@v1
55
+ - uses: peter-evans/repository-dispatch@v1
54
56
  with:
55
- authToken: ${{ secrets.GITHUB_TOKEN }}
56
- context: 'tests-passed-successfully'
57
- description: 'Tests passed successfully'
58
- state: 'success'
59
- sha: ${{ github.event.pull_request.head.sha || github.sha }}
57
+ token: ${{ secrets.GITHUB_TOKEN }}
58
+ repository: ${{ github.repository }}
59
+ event-type: notify
60
+ client-payload: '{"ref": "${{ github.ref }}"}'
@@ -3,6 +3,7 @@
3
3
  require "relaton"
4
4
  require "relaton/cli"
5
5
  require "metanorma/collection_manifest"
6
+ require "metanorma-utils"
6
7
 
7
8
  module Metanorma
8
9
  # Metanorma collection of documents
@@ -39,8 +40,13 @@ module Metanorma
39
40
  @documents.merge! @manifest.documents(File.dirname(@file))
40
41
  @prefatory = args[:prefatory]
41
42
  @final = args[:final]
43
+ @log = Metanorma::Utils::Log.new
42
44
  end
45
+
43
46
  # rubocop:enable Metrics/AbcSize,Metrics/MethodLength
47
+ def clean_exit
48
+ @log.write(File.join(File.dirname(@file), File.basename(@file, ".*") + ".err"))
49
+ end
44
50
 
45
51
  # @return [String] XML
46
52
  def to_xml
@@ -57,7 +63,8 @@ module Metanorma
57
63
  end
58
64
 
59
65
  def render(opts)
60
- CollectionRenderer.render self, opts
66
+ CollectionRenderer.render self, opts.merge(log: @log)
67
+ clean_exit
61
68
  end
62
69
 
63
70
  class << self
@@ -0,0 +1,270 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "isodoc"
4
+
5
+ module Metanorma
6
+ # XML collection renderer
7
+ class CollectionRenderer
8
+ # hash for each document in collection of document identifier to:
9
+ # document reference (fileref or id), type of document reference,
10
+ # and bibdata entry for that file
11
+ # @param path [String] path to collection
12
+ # @return [Hash{String=>Hash}]
13
+ def read_files(path) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
14
+ files = {}
15
+ @xml.xpath(ns("//docref")).each do |d|
16
+ identifier = d.at(ns("./identifier")).text
17
+ files[identifier] = if d["fileref"]
18
+ { type: "fileref",
19
+ ref: File.join(path, d["fileref"]) }
20
+ else { type: "id", ref: d["id"] }
21
+ end
22
+ file, _filename = targetfile(files[identifier], true)
23
+ xml = Nokogiri::XML(file)
24
+ add_document_suffix(identifier, xml)
25
+ files[identifier][:anchors] = read_anchors(xml)
26
+ files[identifier][:bibdata] = xml.at(ns("//bibdata"))
27
+ end
28
+ files
29
+ end
30
+
31
+ def add_suffix_to_attributes(doc, suffix, tag_name, attribute_name)
32
+ doc.xpath(ns("//#{tag_name}[@#{attribute_name}]")).each do |elem|
33
+ elem.attributes[attribute_name].value =
34
+ "#{elem.attributes[attribute_name].value}_#{suffix}"
35
+ end
36
+ end
37
+
38
+ def add_document_suffix(identifier, doc)
39
+ document_suffix = Metanorma::Utils::to_ncname(identifier)
40
+ [%w[* id],
41
+ %w[* bibitemid],
42
+ %w[review from],
43
+ %w[review to],
44
+ %w[index to],
45
+ %w[xref target],
46
+ %w[callout target]]
47
+ .each do |(tag_name, attribute_name)|
48
+ add_suffix_to_attributes(doc, document_suffix, tag_name, attribute_name)
49
+ end
50
+ end
51
+
52
+ # map locality type and label (e.g. "clause" "1") to id = anchor for
53
+ # a document
54
+ def read_anchors(xml)
55
+ ret = {}
56
+ xrefs = @isodoc.xref_init(@lang, @script, @isodoc, @isodoc.i18n, {})
57
+ xrefs.parse xml
58
+ xrefs.get.each do |k, v|
59
+ ret[v[:type]] ||= {}
60
+ index = v[:container] || v[:label].nil? || v[:label].empty? ?
61
+ UUIDTools::UUID.random_create.to_s : v[:label]
62
+ # Note: will only key clauses, which have unambiguous reference label in locality.
63
+ # Notes, examples etc with containers are just plunked agaisnt UUIDs, so that their
64
+ # IDs can at least be registered to be tracked as existing.
65
+ ret[v[:type]][index] = k
66
+ end
67
+ ret
68
+ end
69
+
70
+ # return file contents + output filename for each file in the collection,
71
+ # given a docref entry
72
+ # @param data [Hash]
73
+ # @param read [Boolean]
74
+ # @return [Array<String, nil>]
75
+ def targetfile(data, read = false)
76
+ if data[:type] == "fileref" then ref_file data[:ref], read
77
+ else xml_file data[:id], read
78
+ end
79
+ end
80
+
81
+ # @param ref [String]
82
+ # @param read [Boolean]
83
+ # @return [Array<String, nil>]
84
+ def ref_file(ref, read)
85
+ file = File.read(ref, encoding: "utf-8") if read
86
+ filename = ref.sub(/\.xml$/, ".html")
87
+ [file, filename]
88
+ end
89
+
90
+ # @param id [String]
91
+ # @param read [Boolean]
92
+ # @return [Array<String, nil>]
93
+ def xml_file(id, read)
94
+ file = @xml.at(ns("//doc-container[@id = '#{id}']")).to_xml if read
95
+ filename = id + ".html"
96
+ [file, filename]
97
+ end
98
+
99
+ # @param bib [Nokogiri::XML::Element]
100
+ # @param identifier [String]
101
+ def update_bibitem(bib, identifier) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
102
+ docid = bib&.at(ns("./docidentifier"))&.text
103
+ unless @files[docid]
104
+ error = "[metanorma] Cannot find crossreference to document #{docid} in document #{identifier}."
105
+ @log.add("Cross-References", nil, error)
106
+ Util.log(error, :warning)
107
+ return
108
+ end
109
+ id = bib["id"]
110
+ newbib = bib.replace(@files[docid][:bibdata])
111
+ newbib.name = "bibitem"
112
+ newbib["id"] = id
113
+ newbib["hidden"] = "true"
114
+ newbib&.at(ns("./ext"))&.remove
115
+ _file, url = targetfile(@files[docid], false)
116
+ uri_node = Nokogiri::XML::Node.new "uri", newbib
117
+ uri_node[:type] = "citation"
118
+ uri_node.content = url
119
+ newbib.at(ns("./docidentifier")).previous = uri_node
120
+ end
121
+
122
+ # Resolves direct links to other files in collection (repo(current-metanorma-collection/x),
123
+ # and indirect links to other files in collection (bibitem[@type = 'internal'] pointing to a file anchor
124
+ # in another file in the collection)
125
+ # @param file [String] XML content
126
+ # @param identifier [String] docid
127
+ # @param internal_refs [Hash{String=>Hash{String=>String}] schema name to anchor to filename
128
+ # @return [String] XML content
129
+ def update_xrefs(file, identifier, internal_refs)
130
+ docxml = Nokogiri::XML(file)
131
+ update_indirect_refs_to_docs(docxml, internal_refs)
132
+ add_document_suffix(identifier, docxml)
133
+ update_direct_refs_to_docs(docxml, identifier)
134
+ docxml.xpath(ns("//references[not(./bibitem[not(@hidden) or @hidden = 'false'])]")).each do |f|
135
+ f["hidden"] = "true"
136
+ end
137
+ docxml.to_xml
138
+ end
139
+
140
+ # repo(current-metanorma-collection/ISO 17301-1:2016)
141
+ # replaced by bibdata of "ISO 17301-1:2016" in situ as bibitem.
142
+ # Any erefs to that bibitem id are replaced with relative URL
143
+ # Preferably with anchor, and is a job to realise dynamic lookup of localities.
144
+ def update_direct_refs_to_docs(docxml, identifier)
145
+ docxml.xpath(ns("//bibitem[not(ancestor::bibitem)]")).each do |b|
146
+ docid = b&.at(ns("./docidentifier[@type = 'repository']"))&.text
147
+ next unless docid && %r{^current-metanorma-collection/}.match(docid)
148
+ update_bibitem(b, identifier)
149
+ update_anchors(b, docxml, docid)
150
+ end
151
+ end
152
+
153
+ # Resolve erefs to a container of ids in another doc, to an anchor eref (direct link)
154
+ def update_indirect_refs_to_docs(docxml, internal_refs)
155
+ internal_refs.each do |schema, ids|
156
+ ids.each do |id, file|
157
+ update_indirect_refs_to_docs1(docxml, schema, id, file)
158
+ end
159
+ end
160
+ end
161
+
162
+ def update_indirect_refs_to_docs1(docxml, schema, id, file)
163
+ docxml.xpath(ns("//eref[@bibitemid = '#{schema}_#{id}']")).each do |e|
164
+ e["citeas"] = file
165
+ end
166
+ docid = docxml.at(ns("//bibitem[@id = '#{schema}_#{id}']/docidentifier[@type = 'repository']")) or return
167
+ docid.children = "current-metanorma-collection/#{file}"
168
+ docid.previous = "<docidentifier type='X'>#{file}</docidentifier>"
169
+ end
170
+
171
+ # update crossrefences to other documents, to include disambiguating document suffix on id
172
+ def update_anchors(bib, docxml, _id) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
173
+ docid = bib&.at(ns("./docidentifier"))&.text
174
+ docxml.xpath("//xmlns:eref[@citeas = '#{docid}']").each do |e|
175
+ if @files[docid]
176
+ update_anchor_loc(bib, e, docid)
177
+ else
178
+ e << "<strong>** Unresolved reference to document #{docid}, id #{e['bibitemid']}</strong>"
179
+ end
180
+ end
181
+ end
182
+
183
+ def update_anchor_loc(bib, e, docid)
184
+ loc = e.at(ns(".//locality[@type = 'anchor']")) or return update_anchor_create_loc(bib, e, docid)
185
+ document_suffix = Metanorma::Utils::to_ncname(docid)
186
+ ref = loc.at(ns("./referenceFrom")) || return
187
+ anchor = "#{ref.text}_#{document_suffix}"
188
+ return unless @files[docid][:anchors].inject([]) { |m, (_, x)| m+= x.values }.include?(anchor)
189
+ ref.content = anchor
190
+ end
191
+
192
+ # if there is a crossref to another document, with no anchor, retrieve the
193
+ # anchor given the locality, and insert it into the crossref
194
+ def update_anchor_create_loc(bib, e, docid)
195
+ ins = e.at(ns("./localityStack")) || return
196
+ type = ins&.at(ns("./locality/@type"))&.text
197
+ ref = ins&.at(ns("./locality/referenceFrom"))&.text
198
+ (anchor = @files[docid][:anchors][type][ref]) || return
199
+ ref_from = Nokogiri::XML::Node.new "referenceFrom", bib
200
+ ref_from.content = anchor.sub(/^_/, "")
201
+ locality = Nokogiri::XML::Node.new "locality", bib
202
+ locality[:type] = "anchor"
203
+ locality.add_child ref_from
204
+ ins << locality
205
+ end
206
+
207
+ # compile and output individual file in collection
208
+ def file_compile(f, filename, identifier)
209
+ # warn "metanorma compile -x html #{f.path}"
210
+ c = Compile.new
211
+ c.compile f.path, { format: :asciidoc, extension_keys: @format }.merge(@compile_options)
212
+ @files[identifier][:outputs] = {}
213
+ @format.each do |e|
214
+ ext = c.processor.output_formats[e]
215
+ fn = File.basename(filename).sub(/(?<=\.)[^\.]+$/, ext.to_s)
216
+ FileUtils.mv f.path.sub(/\.xml$/, ".#{ext}"), File.join(@outdir, fn)
217
+ @files[identifier][:outputs][e] = File.join(@outdir, fn)
218
+ end
219
+ end
220
+
221
+ # gather internal bibitem references
222
+ def gather_internal_refs
223
+ @files.each_with_object({}) do |(identifier, x), refs|
224
+ file, _ = targetfile(x, true)
225
+ Nokogiri::XML(file).xpath(ns("//bibitem[@type = 'internal']/docidentifier[@type = 'repository']")).each do |d|
226
+ a = d.text.split(%r{/}, 2)
227
+ a.size > 1 or next
228
+ refs[a[0]] ||= {}
229
+ refs[a[0]][a[1]] = true
230
+ end
231
+ end
232
+ end
233
+
234
+ # resolve file location for the target of each internal reference
235
+ def locate_internal_refs
236
+ refs = gather_internal_refs
237
+ @files.each do |identifier, x|
238
+ file, filename = targetfile(x, true)
239
+ docxml = Nokogiri::XML(file)
240
+ refs.each do |schema, ids|
241
+ ids.keys.each do |id|
242
+ docxml.at(ns("//*[@id = '#{id}'][@type = '#{schema}']")) and
243
+ refs[schema][id] = identifier
244
+ end
245
+ end
246
+ end
247
+ refs.each do |schema, ids|
248
+ ids.each do |id, key|
249
+ key == true and refs[schema][id] = "Missing:#{schema}:#{id}"
250
+ end
251
+ end
252
+ refs
253
+ end
254
+
255
+ # process each file in the collection
256
+ # files are held in memory, and altered as postprocessing
257
+ def files # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
258
+ internal_refs = locate_internal_refs
259
+ @files.each do |identifier, x|
260
+ file, filename = targetfile(x, true)
261
+ file = update_xrefs(file, identifier, internal_refs)
262
+ Tempfile.open(["collection", ".xml"], encoding: "utf-8") do |f|
263
+ f.write(file)
264
+ f.close
265
+ file_compile(f, filename, identifier)
266
+ end
267
+ end
268
+ end
269
+ end
270
+ end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "isodoc"
4
+ require_relative "./collection_fileprocess"
4
5
 
5
6
  module Metanorma
6
7
  # XML collection renderer
@@ -33,6 +34,8 @@ module Metanorma
33
34
  @outdir = options[:output_folder]
34
35
  @coverpage = options[:coverpage]
35
36
  @format = options[:format]
37
+ @compile_options = options[:compile] || {}
38
+ @log = options[:log]
36
39
 
37
40
  # list of files in the collection
38
41
  @files = read_files folder
@@ -113,42 +116,6 @@ module Metanorma
113
116
  IsoDoc::Convert.new({}).ns(xpath)
114
117
  end
115
118
 
116
- # hash for each document in collection of document identifier to:
117
- # document reference (fileref or id), type of document reference,
118
- # and bibdata entry for that file
119
- # @param path [String] path to collection
120
- # @return [Hash{String=>Hash}]
121
- def read_files(path) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
122
- files = {}
123
- @xml.xpath(ns("//docref")).each do |d|
124
- identifier = d.at(ns("./identifier")).text
125
- files[identifier] = if d["fileref"]
126
- { type: "fileref",
127
- ref: File.join(path, d["fileref"]) }
128
- else { type: "id", ref: d["id"] }
129
- end
130
- file, _filename = targetfile(files[identifier], true)
131
- xml = Nokogiri::XML(file)
132
- files[identifier][:anchors] = read_anchors(xml)
133
- files[identifier][:bibdata] = xml.at(ns("//bibdata"))
134
- end
135
- files
136
- end
137
-
138
- # map locality type and label (e.g. "clause" "1") to id = anchor for
139
- # a document
140
- def read_anchors(xml)
141
- ret = {}
142
- xrefs = @isodoc.xref_init(@lang, @script, @isodoc, @isodoc.i18n, {})
143
- xrefs.parse xml
144
- xrefs.get.each do |k, v|
145
- v[:label] && v[:type] || next
146
- ret[v[:type]] ||= {}
147
- ret[v[:type]][v[:label]] = k
148
- end
149
- ret
150
- end
151
-
152
119
  # populate liquid template of ARGV[1] with metadata extracted from
153
120
  # collection manifest
154
121
  def coverpage
@@ -208,124 +175,6 @@ module Metanorma
208
175
  end.doc.root.to_html
209
176
  end
210
177
 
211
- # return file contents + output filename for each file in the collection,
212
- # given a docref entry
213
- # @param data [Hash]
214
- # @param read [Boolean]
215
- # @return [Array<String, nil>]
216
- def targetfile(data, read = false)
217
- if data[:type] == "fileref" then ref_file data[:ref], read
218
- else xml_file data[:id], read
219
- end
220
- end
221
-
222
- # @param ref [String]
223
- # @param read [Boolean]
224
- # @return [Array<String, nil>]
225
- def ref_file(ref, read)
226
- file = File.read(ref, encoding: "utf-8") if read
227
- filename = ref.sub(/\.xml$/, ".html")
228
- [file, filename]
229
- end
230
-
231
- # @param id [String]
232
- # @param read [Boolean]
233
- # @return [Array<String, nil>]
234
- def xml_file(id, read)
235
- file = @xml.at(ns("//doc-container[@id = '#{id}']")).to_xml if read
236
- filename = id + ".html"
237
- [file, filename]
238
- end
239
-
240
- # @param bib [Nokogiri::XML::Element]
241
- # @param identifier [String]
242
- def update_bibitem(bib, identifier) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
243
- docid = bib&.at(ns("./docidentifier"))&.text
244
- unless @files[docid]
245
- warn "Cannot find crossreference to document #{docid} in document "\
246
- "#{identifier}!"
247
- abort
248
- end
249
- id = bib["id"]
250
- newbib = bib.replace(@files[docid][:bibdata])
251
- newbib.name = "bibitem"
252
- newbib["id"] = id
253
- newbib["hidden"] = "true"
254
- newbib&.at(ns("./ext"))&.remove
255
- _file, url = targetfile(@files[docid], false)
256
- uri_node = Nokogiri::XML::Node.new "uri", newbib
257
- uri_node[:type] = "citation"
258
- uri_node.content = url
259
- newbib.at(ns("./docidentifier")).previous = uri_node
260
- end
261
-
262
- # TODO: update crossreferences to other files in the selection
263
- # repo(current-metanorma-collection/ISO 17301-1:2016)
264
- # replaced by
265
- # bibdata of "ISO 17301-1:2016" in situ as bibitem
266
- # Any erefs to that bibitem id are replaced with relative URL
267
- # Preferably with anchor, and is a job to realise dynamic lookup of
268
- # localities
269
- # @param file [String] XML content
270
- # @param identifier [String] docid
271
- # @return [String] XML content
272
- def update_xrefs(file, identifier)
273
- docxml = Nokogiri::XML(file)
274
- docxml.xpath(ns("//bibitem[not(ancestor::bibitem)]")).each do |b|
275
- docid = b&.at(ns("./docidentifier[@type = 'repository']"))&.text
276
- next unless docid && %r{^current-metanorma-collection/}.match(docid)
277
-
278
- update_bibitem(b, identifier)
279
- update_anchors(b, docxml, docid)
280
- end
281
- docxml.xpath(ns("//references[not(./bibitem[not(@hidden) or @hidden = 'false'])]")).each do |f|
282
- f["hidden"] = "true"
283
- end
284
- docxml.to_xml
285
- end
286
-
287
- # if there is a crossref to another document, with no anchor, retrieve the
288
- # anchor given the locality, and insert it into the crossref
289
- def update_anchors(bib, docxml, _id) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
290
- docid = bib&.at(ns("./docidentifier"))&.text
291
- docxml.xpath("//xmlns:eref[@citeas = '#{docid}']").each do |e|
292
- e.at(ns(".//locality[@type = 'anchor']")).nil? || next
293
- ins = e.at(ns("./localityStack")) || next
294
- type = ins&.at(ns("./locality/@type"))&.text
295
- ref = ins&.at(ns("./locality/referenceFrom"))&.text
296
- (anchor = @files[docid][:anchors][type][ref]) || next
297
- ref_from = Nokogiri::XML::Node.new "referenceFrom", bib
298
- ref_from.content = anchor.sub(/^_/, "")
299
- locality = Nokogiri::XML::Node.new "locality", bib
300
- locality[:type] = "anchor"
301
- locality.add_child ref_from
302
- ins << locality
303
- end
304
- end
305
-
306
- # process each file in the collection
307
- # files are held in memory, and altered as postprocessing
308
- def files # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
309
- @files.each do |identifier, x|
310
- file, filename = targetfile(x, true)
311
- file = update_xrefs(file, identifier)
312
- Tempfile.open(["collection", ".xml"], encoding: "utf-8") do |f|
313
- f.write(file)
314
- f.close
315
- # warn "metanorma compile -x html #{f.path}"
316
- c = Compile.new
317
- c.compile f.path, format: :asciidoc, extension_keys: @format
318
- @files[identifier][:outputs] = {}
319
- @format.each do |e|
320
- ext = c.processor.output_formats[e]
321
- fn = File.basename(filename).sub(/(?<=\.)[^\.]+$/, ext.to_s)
322
- FileUtils.mv f.path.sub(/\.xml$/, ".#{ext}"), File.join(@outdir, fn)
323
- @files[identifier][:outputs][e] = File.join(@outdir, fn)
324
- end
325
- end
326
- end
327
- end
328
-
329
178
  private
330
179
 
331
180
  # @param options [Hash]
@@ -335,7 +184,6 @@ module Metanorma
335
184
  raise ArgumentError, "Need to specify formats (xml,html,pdf,doc)"
336
185
  end
337
186
  return if !options[:format].include?(:html) || options[:coverpage]
338
-
339
187
  raise ArgumentError, "Need to specify a coverpage to render HTML"
340
188
  end
341
189
  end
@@ -2,6 +2,9 @@ require "fileutils"
2
2
  require "nokogiri"
3
3
  require "htmlentities"
4
4
 
5
+ require "fontist"
6
+ require "fontist/manifest/install"
7
+
5
8
  module Metanorma
6
9
  class Compile
7
10
  # @return [Array<String>]
@@ -21,6 +24,7 @@ module Metanorma
21
24
  (file, isodoc = process_input(filename, options)) or return nil
22
25
  relaton_export(isodoc, options)
23
26
  extract(isodoc, options[:extract], options[:extract_type])
27
+ install_fonts(options)
24
28
  process_extensions(extensions, file, isodoc, options)
25
29
  end
26
30
 
@@ -63,21 +67,32 @@ module Metanorma
63
67
  Util.log("[metanorma] Error: Please specify a standard type: #{@registry.supported_backends}.", :error)
64
68
  return nil
65
69
  end
70
+
66
71
  stdtype = options[:type].to_sym
72
+ metanorma_flavor = "metanorma-#{stdtype}"
73
+
67
74
  unless @registry.supported_backends.include? stdtype
68
- Util.log("[metanorma] Info: Loading `metanorma-#{stdtype}` gem for standard type `#{stdtype}`.", :info)
75
+ Util.log("[metanorma] Info: Loading `#{metanorma_flavor}` gem for standard type `#{stdtype}`.", :info)
69
76
  end
77
+
70
78
  begin
71
79
  require "metanorma-#{stdtype}"
72
- Util.log("[metanorma] Info: gem `metanorma-#{stdtype}` loaded.", :info)
80
+ Util.log("[metanorma] Info: gem `#{metanorma_flavor}` loaded.", :info)
81
+
82
+ rescue Gem::ConflictError
83
+ Util.log("[metanorma] Error: Couldn't resolve dependencies for `metanorma-#{stdtype}`, Please add it to your Gemfile and run bundle install first", :error)
84
+ return false
85
+
73
86
  rescue LoadError
74
- Util.log("[metanorma] Error: loading gem `metanorma-#{stdtype}` failed. Exiting.", :error)
87
+ Util.log("[metanorma] Error: loading gem `#{metanorma_flavor}` failed. Exiting.", :error)
75
88
  return false
76
89
  end
90
+
77
91
  unless @registry.supported_backends.include? stdtype
78
- Util.log("[metanorma] Error: The `metanorma-#{stdtype}` gem still doesn't support `#{stdtype}`. Exiting.", :error)
92
+ Util.log("[metanorma] Error: The `#{metanorma_flavor}` gem still doesn't support `#{stdtype}`. Exiting.", :error)
79
93
  return false
80
94
  end
95
+
81
96
  true
82
97
  end
83
98
 
@@ -246,19 +261,70 @@ module Metanorma
246
261
  @processor.output(isodoc, xml_name, outfilename, ext, isodoc_options)
247
262
  rescue StandardError => e
248
263
  puts e.message
264
+ puts e.backtrace.join("\n")
249
265
  end
250
266
  end
251
267
  wrap_html(options, file_extension, outfilename)
252
268
  end
253
269
  end
254
270
 
271
+ def install_fonts(options)
272
+ if options[:no_install_fonts]
273
+ Util.log("[fontist] Skip font installation because" \
274
+ " --no-install-fonts argument passed", :debug)
275
+ return
276
+ end
277
+
278
+ if !@processor.respond_to?(:fonts_manifest) || @processor.fonts_manifest.nil?
279
+ Util.log("[fontist] Skip font installation because font_manifest is missing", :debug)
280
+ return
281
+ end
282
+
283
+ @updated_formulas_repo = false
284
+
285
+ manifest = @processor.fonts_manifest
286
+ agree_to_terms = options[:agree_to_terms] || false
287
+ continue_without_fonts = options[:continue_without_fonts] || false
288
+
289
+ install_fonts_safe(manifest, agree_to_terms, continue_without_fonts)
290
+ end
291
+
255
292
  private
256
293
 
294
+ def install_fonts_safe(manifest, agree, continue)
295
+ fontist_install(manifest, agree)
296
+ rescue Fontist::Errors::LicensingError
297
+ if continue
298
+ Util.log("[fontist] Processing will continue without fonts installed", :debug)
299
+ else
300
+ Util.log("[fontist] Aborting without proper fonts installed," \
301
+ " make sure that you have set option --agree-to-terms", :fatal)
302
+ end
303
+ rescue Fontist::Errors::FontError => e
304
+ log_level = continue ? :warning : :fatal
305
+ Util.log("[fontist] '#{e.font}' font is not supported. " \
306
+ "Please report this issue at github.com/metanorma/metanorma-#{@processor.short}/issues" \
307
+ " to report this issue.", log_level)
308
+ rescue Fontist::Errors::FormulaIndexNotFoundError
309
+ Util.log("[fontist] Bug: formula index not found after 'fontist update'", :fatal) if @updated_formulas_repo
310
+ Util.log("[fontist] Missing formula index. Fetching it...", :debug)
311
+ Fontist::Formula.update_formulas_repo
312
+ @updated_formulas_repo = true
313
+ install_fonts_safe(manifest, agree, continue)
314
+ end
315
+
316
+ def fontist_install(manifest, agree)
317
+ Fontist::Manifest::Install.from_hash(
318
+ manifest,
319
+ confirmation: agree ? "yes" : "no"
320
+ )
321
+ end
322
+
257
323
  # @param options [Hash]
258
324
  # @return [String]
259
325
  def change_output_dir(options)
260
- if options[:"output-dir"]
261
- File.join options[:"output-dir"], File.basename(options[:filename])
326
+ if options[:output_dir]
327
+ File.join options[:output_dir], File.basename(options[:filename])
262
328
  else options[:filename]
263
329
  end
264
330
  end
@@ -14,7 +14,7 @@ module Metanorma
14
14
  header_footer: true,
15
15
  attributes: [
16
16
  "nodoc", "stem", "xrefstyle=short", "docfile=#{filename}",
17
- "output_dir=#{options[:"output-dir"]}"
17
+ "output_dir=#{options[:output_dir]}"
18
18
  ]
19
19
  }
20
20
  unless asciidoctor_validate(file, filename, out_opts)
@@ -1,3 +1,3 @@
1
1
  module Metanorma
2
- VERSION = "1.2.1"
2
+ VERSION = "1.2.6pre"
3
3
  end
@@ -27,17 +27,19 @@ Gem::Specification.new do |spec|
27
27
  spec.add_runtime_dependency 'htmlentities'
28
28
  spec.add_runtime_dependency 'nokogiri'
29
29
  spec.add_runtime_dependency 'mn2pdf', "~> 1"
30
+ spec.add_runtime_dependency 'metanorma-utils', "~> 1"
30
31
  spec.add_runtime_dependency 'pry'
31
- # get relaton-cli to avoic circular reference with metanorma-standoc
32
+ spec.add_runtime_dependency 'fontist', '~> 1.8'
33
+
34
+ # get relaton-cli to avoid circular reference with metanorma-standoc
32
35
  #spec.add_dependency "relaton-cli"
33
- #spec.add_dependency "metanorma-standoc", "~> 1.5.3"
36
+ #spec.add_dependency "metanorma-standoc"
34
37
 
35
38
  spec.add_development_dependency "rake", "~> 12.0"
36
39
  spec.add_development_dependency "rspec", "~> 3.0"
37
40
  spec.add_development_dependency "byebug", "~> 10.0"
38
41
  spec.add_development_dependency "rspec-command", "~> 1.0"
39
42
  spec.add_development_dependency "equivalent-xml", "~> 0.6"
40
- spec.add_development_dependency "metanorma-iso", "~> 1.5.8"
43
+ spec.add_development_dependency "metanorma-iso", "~> 1.7.0"
41
44
  spec.add_development_dependency "sassc", "~> 2.4.0"
42
- #spec.add_development_dependency "isodoc", "~> 1.2.1"
43
45
  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.2.1
4
+ version: 1.2.6pre
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-11-30 00:00:00.000000000 Z
11
+ date: 2021-01-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: asciidoctor
@@ -66,6 +66,20 @@ dependencies:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: '1'
69
+ - !ruby/object:Gem::Dependency
70
+ name: metanorma-utils
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '1'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '1'
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: pry
71
85
  requirement: !ruby/object:Gem::Requirement
@@ -80,6 +94,20 @@ dependencies:
80
94
  - - ">="
81
95
  - !ruby/object:Gem::Version
82
96
  version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: fontist
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '1.8'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '1.8'
83
111
  - !ruby/object:Gem::Dependency
84
112
  name: rake
85
113
  requirement: !ruby/object:Gem::Requirement
@@ -156,14 +184,14 @@ dependencies:
156
184
  requirements:
157
185
  - - "~>"
158
186
  - !ruby/object:Gem::Version
159
- version: 1.5.8
187
+ version: 1.7.0
160
188
  type: :development
161
189
  prerelease: false
162
190
  version_requirements: !ruby/object:Gem::Requirement
163
191
  requirements:
164
192
  - - "~>"
165
193
  - !ruby/object:Gem::Version
166
- version: 1.5.8
194
+ version: 1.7.0
167
195
  - !ruby/object:Gem::Dependency
168
196
  name: sassc
169
197
  requirement: !ruby/object:Gem::Requirement
@@ -210,6 +238,7 @@ files:
210
238
  - lib/metanorma/asciidoctor_extensions.rb
211
239
  - lib/metanorma/asciidoctor_extensions/glob_include_processor.rb
212
240
  - lib/metanorma/collection.rb
241
+ - lib/metanorma/collection_fileprocess.rb
213
242
  - lib/metanorma/collection_manifest.rb
214
243
  - lib/metanorma/collection_renderer.rb
215
244
  - lib/metanorma/compile.rb
@@ -243,9 +272,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
243
272
  version: 2.4.0
244
273
  required_rubygems_version: !ruby/object:Gem::Requirement
245
274
  requirements:
246
- - - ">="
275
+ - - ">"
247
276
  - !ruby/object:Gem::Version
248
- version: '0'
277
+ version: 1.3.1
249
278
  requirements: []
250
279
  rubygems_version: 3.0.3
251
280
  signing_key: