metanorma 1.2.1 → 1.2.6pre

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