metanorma 1.0.6 → 1.1.4
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 +4 -4
- data/.github/workflows/macos.yml +0 -8
- data/.github/workflows/ubuntu.yml +12 -16
- data/.github/workflows/windows.yml +0 -8
- data/.gitignore +4 -0
- data/.rubocop.yml +0 -4
- data/lib/metanorma.rb +6 -1
- data/lib/metanorma/collection.rb +182 -0
- data/lib/metanorma/collection_manifest.rb +111 -0
- data/lib/metanorma/collection_renderer.rb +312 -0
- data/lib/metanorma/compile.rb +65 -22
- data/lib/metanorma/document.rb +75 -5
- data/lib/metanorma/input/asciidoc.rb +5 -2
- data/lib/metanorma/output/xslfo.rb +7 -1
- data/lib/metanorma/processor.rb +16 -3
- data/lib/metanorma/registry.rb +11 -2
- data/lib/metanorma/version.rb +1 -1
- data/metanorma.gemspec +3 -1
- metadata +39 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 72a6cdf0d2785bbc70cc907a024ab4e03ce4bdf5cd744c73ccc24ee0e928e092
|
4
|
+
data.tar.gz: bae5a06c2b0b71ecc46ed52699607eb235aa05d327f474328cce113510d4616e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 78f0012cc133961e454a58e28a67c47a527a766ef85d8e995b7495f5095ec149bc7b89849ca565c8b668487e43ef90d1cc2d0c00658deee546d15295280352cd
|
7
|
+
data.tar.gz: 48a352c90ab1d5b4c2cd8e0e8581e58cd8425399d34cde1ba9ceafb333f36d2a6c048f59f739057840ce5bb6c7a0db2c5973dc26113c4d8102daf7300b806605
|
data/.github/workflows/macos.yml
CHANGED
@@ -29,18 +29,10 @@ jobs:
|
|
29
29
|
uses: actions/setup-ruby@v1
|
30
30
|
with:
|
31
31
|
ruby-version: ${{ matrix.ruby }}
|
32
|
-
architecture: 'x64'
|
33
32
|
- name: Update gems
|
34
33
|
run: |
|
35
34
|
sudo gem install bundler --force
|
36
35
|
bundle install --jobs 4 --retry 3
|
37
|
-
- name: Use Node
|
38
|
-
uses: actions/setup-node@v1
|
39
|
-
with:
|
40
|
-
node-version: '12'
|
41
|
-
- name: Install Puppeteer
|
42
|
-
run: |
|
43
|
-
npm install -g puppeteer@3.0.1
|
44
36
|
- name: Run specs
|
45
37
|
run: |
|
46
38
|
bundle exec rake
|
@@ -5,6 +5,8 @@ name: ubuntu
|
|
5
5
|
on:
|
6
6
|
push:
|
7
7
|
branches: [ master ]
|
8
|
+
tags:
|
9
|
+
- '*'
|
8
10
|
pull_request:
|
9
11
|
paths-ignore:
|
10
12
|
- .github/workflows/macos.yml
|
@@ -29,32 +31,26 @@ jobs:
|
|
29
31
|
uses: actions/setup-ruby@v1
|
30
32
|
with:
|
31
33
|
ruby-version: ${{ matrix.ruby }}
|
32
|
-
architecture: 'x64'
|
33
34
|
- name: Update gems
|
34
35
|
run: |
|
35
36
|
gem install bundler
|
36
37
|
bundle install --jobs 4 --retry 3
|
37
|
-
- name: Use Node
|
38
|
-
uses: actions/setup-node@v1
|
39
|
-
with:
|
40
|
-
node-version: '12'
|
41
|
-
- name: Install Puppeteer
|
42
|
-
run: |
|
43
|
-
sudo apt-get update
|
44
|
-
sudo apt-get install libgbm1
|
45
|
-
npm install -g puppeteer@3.0.1
|
46
38
|
- name: Run specs
|
47
39
|
run: |
|
48
40
|
bundle exec rake
|
49
|
-
- name: Trigger
|
50
|
-
if:
|
41
|
+
- name: Trigger repositories
|
42
|
+
if: matrix.ruby == '2.6'
|
51
43
|
env:
|
52
|
-
GH_USERNAME:
|
53
|
-
GH_ACCESS_TOKEN: ${{ secrets.
|
44
|
+
GH_USERNAME: metanorma-ci
|
45
|
+
GH_ACCESS_TOKEN: ${{ secrets.METANORMA_CI_PAT_TOKEN }}
|
54
46
|
run: |
|
55
47
|
curl -LO --retry 3 https://raw.githubusercontent.com/metanorma/metanorma-build-scripts/master/trigger-gh-actions.sh
|
56
48
|
[[ -f ".github/workflows/dependent_repos.env" ]] && source .github/workflows/dependent_repos.env
|
57
|
-
|
49
|
+
CLIENT_PAYLOAD=$(cat <<EOF
|
50
|
+
"{ "ref": "${GITHUB_REF}", "repo": "${GITHUB_REPOSITORY}" }"
|
51
|
+
EOF
|
52
|
+
)
|
53
|
+
for repo in $REPOS
|
58
54
|
do
|
59
|
-
sh trigger-gh-actions.sh $ORGANISATION $repo $GH_USERNAME $GH_ACCESS_TOKEN $GITHUB_REPOSITORY
|
55
|
+
sh trigger-gh-actions.sh $ORGANISATION $repo $GH_USERNAME $GH_ACCESS_TOKEN $GITHUB_REPOSITORY "$CLIENT_PAYLOAD"
|
60
56
|
done
|
@@ -29,20 +29,12 @@ jobs:
|
|
29
29
|
uses: actions/setup-ruby@v1
|
30
30
|
with:
|
31
31
|
ruby-version: ${{ matrix.ruby }}
|
32
|
-
architecture: 'x64'
|
33
32
|
- name: Update gems
|
34
33
|
shell: pwsh
|
35
34
|
run: |
|
36
35
|
gem install bundler
|
37
36
|
bundle config --local path vendor/bundle
|
38
37
|
bundle install --jobs 4 --retry 3
|
39
|
-
- name: Use Node
|
40
|
-
uses: actions/setup-node@v1
|
41
|
-
with:
|
42
|
-
node-version: '12'
|
43
|
-
- name: Install Puppeteer
|
44
|
-
run: |
|
45
|
-
npm install -g puppeteer@3.0.1
|
46
38
|
- name: Run specs
|
47
39
|
run: |
|
48
40
|
bundle exec rake
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
data/lib/metanorma.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "metanorma/version"
|
2
4
|
require "asciidoctor"
|
3
5
|
require "metanorma/util"
|
@@ -8,7 +10,10 @@ require "metanorma/registry"
|
|
8
10
|
require "metanorma/processor"
|
9
11
|
require "metanorma/asciidoctor_extensions"
|
10
12
|
require "metanorma/compile"
|
13
|
+
require "metanorma/collection"
|
14
|
+
require "metanorma/collection_renderer"
|
15
|
+
require "metanorma/document"
|
11
16
|
|
17
|
+
# Metanorma module
|
12
18
|
module Metanorma
|
13
|
-
|
14
19
|
end
|
@@ -0,0 +1,182 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "relaton"
|
4
|
+
require "relaton/cli"
|
5
|
+
require "metanorma/collection_manifest"
|
6
|
+
|
7
|
+
module Metanorma
|
8
|
+
# Metanorma collection of documents
|
9
|
+
class Collection
|
10
|
+
# @return [String]
|
11
|
+
attr_reader :file
|
12
|
+
|
13
|
+
# @return [Array<String>] documents-inline to inject the XML into
|
14
|
+
# the collection manifest; documents-external to keeps them outside
|
15
|
+
attr_reader :directives
|
16
|
+
|
17
|
+
# @return [Hash<String, Metanorma::Document>]
|
18
|
+
attr_reader :documents
|
19
|
+
|
20
|
+
# @param file [String] path to source file
|
21
|
+
# @param directives [Array<String>] documents-inline to inject the XML into
|
22
|
+
# the collection manifest; documents-external to keeps them outside
|
23
|
+
# @param bibdata [RelatonBib::BibliographicItem]
|
24
|
+
# @param manifest [Metanorma::CollectionManifest]
|
25
|
+
# @param documents [Hash<String, Metanorma::Document>]
|
26
|
+
# @param prefatory [String]
|
27
|
+
# @param final [String]
|
28
|
+
# rubocop:disable Metrics/AbcSize,Metrics/MethodLength
|
29
|
+
def initialize(**args)
|
30
|
+
@file = args[:file]
|
31
|
+
@directives = args[:directives] || []
|
32
|
+
@bibdata = args[:bibdata]
|
33
|
+
@manifest = args[:manifest]
|
34
|
+
@manifest.collection = self
|
35
|
+
@documents = args[:documents] || {}
|
36
|
+
if @documents.any? && !@directives.include?("documents-inline")
|
37
|
+
@directives << "documents-inline"
|
38
|
+
end
|
39
|
+
@documents.merge! @manifest.documents(File.dirname(@file))
|
40
|
+
@prefatory = args[:prefatory]
|
41
|
+
@final = args[:final]
|
42
|
+
end
|
43
|
+
# rubocop:enable Metrics/AbcSize,Metrics/MethodLength
|
44
|
+
|
45
|
+
# @return [String] XML
|
46
|
+
def to_xml
|
47
|
+
Nokogiri::XML::Builder.new do |xml|
|
48
|
+
xml.send("metanorma-collection",
|
49
|
+
"xmlns" => "http://metanorma.org") do |mc|
|
50
|
+
@bibdata.to_xml mc, bibdata: true, date_format: :full
|
51
|
+
@manifest.to_xml mc
|
52
|
+
content_to_xml "prefatory", mc
|
53
|
+
doccontainer mc
|
54
|
+
content_to_xml "final", mc
|
55
|
+
end
|
56
|
+
end.to_xml
|
57
|
+
end
|
58
|
+
|
59
|
+
def render(opts)
|
60
|
+
CollectionRenderer.render self, opts
|
61
|
+
end
|
62
|
+
|
63
|
+
class << self
|
64
|
+
# @param file [String]
|
65
|
+
# @return [RelatonBib::BibliographicItem,
|
66
|
+
# RelatonIso::IsoBibliographicItem]
|
67
|
+
def parse(file)
|
68
|
+
case file
|
69
|
+
when /\.xml$/ then parse_xml(file)
|
70
|
+
when /.ya?ml$/ then parse_yaml(file)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
private
|
75
|
+
|
76
|
+
def parse_xml(file)
|
77
|
+
xml = Nokogiri::XML File.read(file, encoding: "UTF-8")
|
78
|
+
if (b = xml.at("/xmlns:metanorma-collection/xmlns:bibdata"))
|
79
|
+
bd = Relaton::Cli.parse_xml b
|
80
|
+
end
|
81
|
+
mnf_xml = xml.at("/xmlns:metanorma-collection/xmlns:manifest")
|
82
|
+
mnf = CollectionManifest.from_xml mnf_xml
|
83
|
+
pref = pref_final_content xml.at("//xmlns:prefatory-content")
|
84
|
+
fnl = pref_final_content xml.at("//xmlns:final-content")
|
85
|
+
new(file: file, bibdata: bd, manifest: mnf,
|
86
|
+
documents: docs_from_xml(xml, mnf), prefatory: pref, final: fnl)
|
87
|
+
end
|
88
|
+
|
89
|
+
def parse_yaml(file)
|
90
|
+
yaml = YAML.load_file file
|
91
|
+
if yaml["bibdata"]
|
92
|
+
bd = Relaton::Cli::YAMLConvertor.convert_single_file yaml["bibdata"]
|
93
|
+
end
|
94
|
+
mnf = CollectionManifest.from_yaml yaml["manifest"]
|
95
|
+
dirs = yaml["directives"]
|
96
|
+
pref = yaml["prefatory-content"]
|
97
|
+
fnl = yaml["final-content"]
|
98
|
+
new(file: file, directives: dirs, bibdata: bd, manifest: mnf,
|
99
|
+
prefatory: pref, final: fnl)
|
100
|
+
end
|
101
|
+
|
102
|
+
# @param xml [Nokogiri::XML::Document]
|
103
|
+
# @parma mnf [Metanorma::CollectionManifest]
|
104
|
+
# @return [Hash{String=>Metanorma::Document}]
|
105
|
+
def docs_from_xml(xml, mnf)
|
106
|
+
xml.xpath("//xmlns:doc-container/*/xmlns:bibdata")
|
107
|
+
.each_with_object({}) do |b, m|
|
108
|
+
bd = Relaton::Cli.parse_xml b
|
109
|
+
docref = mnf.docref_by_id bd.docidentifier.first.id
|
110
|
+
m[docref["identifier"]] = Document.new bd, docref["fileref"]
|
111
|
+
m
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
# @param xml [Nokogiri::XML::Element, nil]
|
116
|
+
# @return [String, nil]
|
117
|
+
def pref_final_content(xml)
|
118
|
+
return unless xml
|
119
|
+
|
120
|
+
<<~CONT
|
121
|
+
|
122
|
+
== #{xml.at('title')&.text}
|
123
|
+
#{xml.at('p')&.text}
|
124
|
+
CONT
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
private
|
129
|
+
|
130
|
+
# @return [String, nil]
|
131
|
+
attr_reader :prefatory, :final
|
132
|
+
|
133
|
+
# @return [String]
|
134
|
+
def dummy_header
|
135
|
+
<<~DUMMY
|
136
|
+
= X
|
137
|
+
A
|
138
|
+
|
139
|
+
DUMMY
|
140
|
+
end
|
141
|
+
|
142
|
+
# @param elm [String] 'prefatory' or 'final'
|
143
|
+
# @param builder [Nokogiri::XML::Builder]
|
144
|
+
def content_to_xml(elm, builder)
|
145
|
+
return unless (cnt = send(elm))
|
146
|
+
|
147
|
+
require "metanorma-#{doctype}"
|
148
|
+
out = sections(dummy_header + cnt)
|
149
|
+
builder.send(elm + "-content") { |b| b << out }
|
150
|
+
end
|
151
|
+
|
152
|
+
# @param cnt [String] prefatory/final content
|
153
|
+
# @return [String] XML
|
154
|
+
def sections(cnt)
|
155
|
+
c = Asciidoctor.convert(cnt, backend: doctype.to_sym, header_footer: true)
|
156
|
+
Nokogiri::XML(c).at("//xmlns:sections").children.to_xml
|
157
|
+
end
|
158
|
+
|
159
|
+
# @param builder [Nokogiri::XML::Builder]
|
160
|
+
def doccontainer(builder)
|
161
|
+
return unless Array(@directives).include? "documents-inline"
|
162
|
+
|
163
|
+
documents.each_with_index do |(_, d), i|
|
164
|
+
id = format("doc%<index>09d", index: i)
|
165
|
+
builder.send("doc-container", id: id) { |b| d.to_xml b }
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
# @return [String]
|
170
|
+
def doctype
|
171
|
+
@doctype ||= fetch_doctype || "standoc"
|
172
|
+
end
|
173
|
+
|
174
|
+
# @return [String]
|
175
|
+
def fetch_doctype
|
176
|
+
docid = @bibdata.docidentifier.first
|
177
|
+
return unless docid
|
178
|
+
|
179
|
+
docid.type&.downcase || docid.id&.sub(/\s.*$/, "")&.downcase
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Metanorma
|
4
|
+
# Metanorma collection's manifest
|
5
|
+
class CollectionManifest
|
6
|
+
# @return [Metanorma::Collection]
|
7
|
+
attr_reader :collection
|
8
|
+
|
9
|
+
# @param level [String]
|
10
|
+
# @param title [String, nil]
|
11
|
+
# @param docref [Array<Hash{String=>String}>]
|
12
|
+
# @param manifest [Array<Metanorma::CollectionManifest>]
|
13
|
+
def initialize(level, title = nil, docref = [], manifest = [])
|
14
|
+
@level = level
|
15
|
+
@title = title
|
16
|
+
@docref = docref
|
17
|
+
@manifest = manifest
|
18
|
+
end
|
19
|
+
|
20
|
+
class << self
|
21
|
+
# @param mnf [Nokogiri::XML::Element]
|
22
|
+
# @return [Metanorma::CollectionManifest]
|
23
|
+
def from_yaml(mnf)
|
24
|
+
manifest = RelatonBib::HashConverter.array(mnf["manifest"]).map do |m|
|
25
|
+
from_yaml m
|
26
|
+
end
|
27
|
+
docref = RelatonBib::HashConverter.array mnf["docref"]
|
28
|
+
new(mnf["level"], mnf["title"], docref, manifest)
|
29
|
+
end
|
30
|
+
|
31
|
+
# @param mnf [Nokogiri::XML::Element]
|
32
|
+
# @return [Metanorma::CollectionManifest]
|
33
|
+
def from_xml(mnf)
|
34
|
+
level = mnf.at("level").text
|
35
|
+
title = mnf.at("title")&.text
|
36
|
+
manifest = mnf.xpath("xmlns:manifest").map { |m| from_xml(m) }
|
37
|
+
new(level, title, parse_docref(mnf), manifest)
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
# @param mnf [Nokogiri::XML::Element]
|
43
|
+
# @return [Hash{String=>String}]
|
44
|
+
def parse_docref(mnf)
|
45
|
+
mnf.xpath("xmlns:docref").map do |dr|
|
46
|
+
h = { "identifier" => dr.at("identifier").text }
|
47
|
+
h["fileref"] = dr[:fileref] if dr[:fileref]
|
48
|
+
h
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# @param col [Metanorma::Collection]
|
54
|
+
def collection=(col)
|
55
|
+
@collection = col
|
56
|
+
@manifest.each { |mnf| mnf.collection = col }
|
57
|
+
end
|
58
|
+
|
59
|
+
# @param dir [String] path to coolection
|
60
|
+
# @return [Hash<String, Metanorma::Document>]
|
61
|
+
def documents(dir = "")
|
62
|
+
docs = @docref.each_with_object({}) do |dr, m|
|
63
|
+
next m unless dr["fileref"]
|
64
|
+
|
65
|
+
m[dr["identifier"]] = Document.parse_file File.join(dir, dr["fileref"])
|
66
|
+
m
|
67
|
+
end
|
68
|
+
@manifest.reduce(docs) do |mem, mnf|
|
69
|
+
mem.merge mnf.documents(dir)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# @param builder [Nokogiri::XML::Builder]
|
74
|
+
def to_xml(builder)
|
75
|
+
builder.manifest do |b|
|
76
|
+
b.level @level
|
77
|
+
b.title @title if @title
|
78
|
+
docref_to_xml b
|
79
|
+
@manifest.each { |m| m.to_xml b }
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
# @return [Array<Hash{String=>String}>]
|
84
|
+
def docrefs
|
85
|
+
return @docrefs if @docrefs
|
86
|
+
|
87
|
+
drfs = @docref.map { |dr| dr }
|
88
|
+
@manifest.reduce(drfs) { |mem, mnf| mem + mnf.docrefs }
|
89
|
+
end
|
90
|
+
|
91
|
+
def docref_by_id(docid)
|
92
|
+
refs = docrefs
|
93
|
+
dref = refs.detect { |k| k["identifier"] == docid }
|
94
|
+
dref || docrefs.detect { |k| /^#{k["identifier"]}/ =~ docid }
|
95
|
+
end
|
96
|
+
|
97
|
+
private
|
98
|
+
|
99
|
+
# @param builder [Nokogiri::XML::Builder]
|
100
|
+
def docref_to_xml(builder)
|
101
|
+
@docref.each do |dr|
|
102
|
+
drf = builder.docref { |b| b.identifier dr["identifier"] }
|
103
|
+
drf[:fileref] = dr["fileref"]
|
104
|
+
if collection.directives.include?("documents-inline")
|
105
|
+
id = collection.documents.find_index { |k, _| k == dr["identifier"] }
|
106
|
+
drf[:id] = format("doc%<index>09d", index: id)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
@@ -0,0 +1,312 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "isodoc"
|
4
|
+
|
5
|
+
module Metanorma
|
6
|
+
# XML collection renderer
|
7
|
+
class CollectionRenderer
|
8
|
+
FORMATS = %i[html xml doc pdf].freeze
|
9
|
+
|
10
|
+
# This is only going to render the HTML collection
|
11
|
+
# @param xml [Metanorma::Collection] input XML collection
|
12
|
+
# @param folder [String] input folder
|
13
|
+
# @param options [Hash]
|
14
|
+
# @option options [String] :coverpage cover page HTML (Liquid template)
|
15
|
+
# @option options [Array<Symbol>] :format list of formats (xml,html,doc,pdf)
|
16
|
+
# @option options [String] :ourput_folder output directory
|
17
|
+
#
|
18
|
+
# We presuppose that the bibdata of the document is equivalent to that of
|
19
|
+
# the collection, and that the flavour gem can sensibly process it. We may
|
20
|
+
# need to enhance metadata in the flavour gems isodoc/metadata.rb with
|
21
|
+
# collection metadata
|
22
|
+
def initialize(xml, folder, options = {}) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
23
|
+
check_options options
|
24
|
+
@xml = Nokogiri::XML xml # @xml is the collection manifest
|
25
|
+
@lang = @xml&.at(ns("//bibdata/language"))&.text || "en"
|
26
|
+
@script = @xml&.at(ns("//bibdata/script"))&.text || "Latn"
|
27
|
+
@doctype = doctype
|
28
|
+
require "metanorma-#{@doctype}"
|
29
|
+
|
30
|
+
# output processor for flavour
|
31
|
+
@isodoc = isodoc
|
32
|
+
|
33
|
+
@outdir = options[:output_folder]
|
34
|
+
@coverpage = options[:coverpage]
|
35
|
+
@format = options[:format]
|
36
|
+
|
37
|
+
# list of files in the collection
|
38
|
+
@files = read_files folder
|
39
|
+
FileUtils.rm_rf @outdir
|
40
|
+
FileUtils.mkdir_p @outdir
|
41
|
+
end
|
42
|
+
|
43
|
+
# @param col [Metanorma::Collection] XML collection
|
44
|
+
# @param options [Hash]
|
45
|
+
# @option options [String] :coverpage cover page HTML (Liquid template)
|
46
|
+
# @option options [Array<Synbol>] :format list of formats
|
47
|
+
# @option options [Strong] :ourput_folder output directory
|
48
|
+
def self.render(col, options = {})
|
49
|
+
folder = File.dirname col.file
|
50
|
+
cr = new(col.to_xml, folder, options)
|
51
|
+
cr.files
|
52
|
+
cr.coverpage if options[:format]&.include?(:html)
|
53
|
+
end
|
54
|
+
|
55
|
+
# Dummy class
|
56
|
+
class Dummy
|
57
|
+
def attr(_xyz); end
|
58
|
+
end
|
59
|
+
|
60
|
+
# The isodoc class for the metanorma flavour we are using
|
61
|
+
def isodoc # rubocop:disable Metrics/MethodLength
|
62
|
+
x = Asciidoctor.load nil, backend: @doctype.to_sym
|
63
|
+
isodoc = x.converter.html_converter(Dummy.new)
|
64
|
+
isodoc.i18n_init(@lang, @script) # read in internationalisation
|
65
|
+
# create the @meta class of isodoc, with "navigation" set to the index bar
|
66
|
+
# extracted from the manifest
|
67
|
+
nav = indexfile(@xml.at(ns("//manifest")))
|
68
|
+
i18n = isodoc.i18n
|
69
|
+
i18n.set(:navigation, nav)
|
70
|
+
isodoc.metadata_init(@lang, @script, i18n)
|
71
|
+
# populate the @meta class of isodoc with the various metadata fields
|
72
|
+
# native to the flavour; used to populate Liquid
|
73
|
+
isodoc.info(@xml, nil)
|
74
|
+
isodoc
|
75
|
+
end
|
76
|
+
|
77
|
+
# infer the flavour from the first document identifier; relaton does that
|
78
|
+
def doctype
|
79
|
+
if (docid = @xml&.at(ns("//bibdata/docidentifier/@type"))&.text)
|
80
|
+
dt = docid.downcase
|
81
|
+
elsif (docid = @xml&.at(ns("//bibdata/docidentifier"))&.text)
|
82
|
+
dt = docid.sub(/\s.*$/, "").lowercase
|
83
|
+
else return "standoc"
|
84
|
+
end
|
85
|
+
@registry = Metanorma::Registry.instance
|
86
|
+
@registry.alias(dt.to_sym)&.to_s || dt
|
87
|
+
end
|
88
|
+
|
89
|
+
def ns(xpath)
|
90
|
+
IsoDoc::Convert.new({}).ns(xpath)
|
91
|
+
end
|
92
|
+
|
93
|
+
# hash for each document in collection of document identifier to:
|
94
|
+
# document reference (fileref or id), type of document reference,
|
95
|
+
# and bibdata entry for that file
|
96
|
+
# @param path [String] path to collection
|
97
|
+
# @return [Hash{String=>Hash}]
|
98
|
+
def read_files(path) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
99
|
+
files = {}
|
100
|
+
@xml.xpath(ns("//docref")).each do |d|
|
101
|
+
identifier = d.at(ns("./identifier")).text
|
102
|
+
files[identifier] = if d["fileref"]
|
103
|
+
{ type: "fileref",
|
104
|
+
ref: File.join(path, d["fileref"]) }
|
105
|
+
else { type: "id", ref: d["id"] }
|
106
|
+
end
|
107
|
+
file, _filename = targetfile(files[identifier], true)
|
108
|
+
xml = Nokogiri::XML(file)
|
109
|
+
files[identifier][:anchors] = read_anchors(xml)
|
110
|
+
files[identifier][:bibdata] = xml.at(ns("//bibdata"))
|
111
|
+
end
|
112
|
+
files
|
113
|
+
end
|
114
|
+
|
115
|
+
# map locality type and label (e.g. "clause" "1") to id = anchor for
|
116
|
+
# a document
|
117
|
+
def read_anchors(xml)
|
118
|
+
ret = {}
|
119
|
+
xrefs = @isodoc.xref_init(@lang, @script, @isodoc, @isodoc.i18n, {})
|
120
|
+
xrefs.parse xml
|
121
|
+
xrefs.get.each do |k, v|
|
122
|
+
v[:label] && v[:type] || next
|
123
|
+
ret[v[:type]] ||= {}
|
124
|
+
ret[v[:type]][v[:label]] = k
|
125
|
+
end
|
126
|
+
ret
|
127
|
+
end
|
128
|
+
|
129
|
+
# populate liquid template of ARGV[1] with metadata extracted from
|
130
|
+
# collection manifest
|
131
|
+
def coverpage
|
132
|
+
File.open(File.join(@outdir, "index.html"), "w:UTF-8") do |f|
|
133
|
+
f.write @isodoc.populate_template(File.read(@coverpage))
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
# @param elm [Nokogiri::XML::Element]
|
138
|
+
# @return [String]
|
139
|
+
def indexfile_title(elm)
|
140
|
+
lvl = elm&.at(ns("./level"))&.text&.capitalize
|
141
|
+
lbl = elm&.at(ns("./title"))&.text
|
142
|
+
"#{lvl}#{lvl && lbl ? ': ' : ''}#{lbl}"
|
143
|
+
end
|
144
|
+
|
145
|
+
# uses the identifier to label documents; other attributes (title) can be
|
146
|
+
# looked up in @files[id][:bibdata]
|
147
|
+
#
|
148
|
+
# @param elm [Nokogiri::XML::Element]
|
149
|
+
# @param builder [Nokogiri::XML::Builder]
|
150
|
+
def indexfile_docref(elm, builder)
|
151
|
+
return "" unless elm.at(ns("./docref"))
|
152
|
+
|
153
|
+
builder.ul { |b| docrefs(elm, b) }
|
154
|
+
end
|
155
|
+
|
156
|
+
# @param elm [Nokogiri::XML::Element]
|
157
|
+
# @param builder [Nokogiri::XML::Builder]
|
158
|
+
def docrefs(elm, builder)
|
159
|
+
elm.xpath(ns("./docref")).each do |d|
|
160
|
+
identifier = d.at(ns("./identifier")).text
|
161
|
+
link = if d["fileref"] then d["fileref"].sub(/\.xml$/, ".html")
|
162
|
+
else d["id"] + ".html"
|
163
|
+
end
|
164
|
+
builder.li { builder.a identifier, href: link }
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
# single level navigation list, with hierarchical nesting
|
169
|
+
# if multiple lists are needed as separate HTML fragments, multiple
|
170
|
+
# instances of this function will be needed,
|
171
|
+
# and associated to different variables in the call to @isodoc.metadata_init
|
172
|
+
# (including possibly an array of HTML fragments)
|
173
|
+
#
|
174
|
+
# @param elm [Nokogiri::XML::Element]
|
175
|
+
# @return [String] XML
|
176
|
+
def indexfile(elm)
|
177
|
+
Nokogiri::HTML::Builder.new do |b|
|
178
|
+
b.ul do
|
179
|
+
b.li indexfile_title(elm)
|
180
|
+
indexfile_docref(elm, b)
|
181
|
+
elm.xpath(ns("./manifest")).each do |d|
|
182
|
+
b << indexfile(d)
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end.doc.root.to_html
|
186
|
+
end
|
187
|
+
|
188
|
+
# return file contents + output filename for each file in the collection,
|
189
|
+
# given a docref entry
|
190
|
+
# @param data [Hash]
|
191
|
+
# @param read [Boolean]
|
192
|
+
# @return [Array<String, nil>]
|
193
|
+
def targetfile(data, read = false)
|
194
|
+
if data[:type] == "fileref" then ref_file data[:ref], read
|
195
|
+
else xml_file data[:id], read
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
# @param ref [String]
|
200
|
+
# @param read [Boolean]
|
201
|
+
# @return [Array<String, nil>]
|
202
|
+
def ref_file(ref, read)
|
203
|
+
file = File.read(ref, encoding: "utf-8") if read
|
204
|
+
filename = ref.sub(/\.xml$/, ".html")
|
205
|
+
[file, filename]
|
206
|
+
end
|
207
|
+
|
208
|
+
# @param id [String]
|
209
|
+
# @param read [Boolean]
|
210
|
+
# @return [Array<String, nil>]
|
211
|
+
def xml_file(id, read)
|
212
|
+
file = @xml.at(ns("//doc-container[@id = '#{id}']")).to_xml if read
|
213
|
+
filename = id + ".html"
|
214
|
+
[file, filename]
|
215
|
+
end
|
216
|
+
|
217
|
+
# @param bib [Nokogiri::XML::Element]
|
218
|
+
# @param identifier [String]
|
219
|
+
def update_bibitem(bib, identifier) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
220
|
+
docid = bib&.at(ns("./docidentifier"))&.text
|
221
|
+
unless @files[docid]
|
222
|
+
warn "Cannot find crossreference to document #{docid} in document "\
|
223
|
+
"#{identifier}!"
|
224
|
+
abort
|
225
|
+
end
|
226
|
+
id = bib["id"]
|
227
|
+
newbib = bib.replace(@files[docid][:bibdata])
|
228
|
+
newbib.name = "bibitem"
|
229
|
+
newbib["id"] = id
|
230
|
+
newbib&.at(ns("./ext"))&.remove
|
231
|
+
_file, url = targetfile(@files[docid], false)
|
232
|
+
uri_node = Nokogiri::XML::Node.new "uri", newbib
|
233
|
+
uri_node[:type] = "citation"
|
234
|
+
uri_node.content = url
|
235
|
+
newbib.at(ns("./docidentifier")).previous = uri_node
|
236
|
+
end
|
237
|
+
|
238
|
+
# TODO: update crossreferences to other files in the selection
|
239
|
+
# repo(current-metanorma-collection/ISO 17301-1:2016)
|
240
|
+
# replaced by
|
241
|
+
# bibdata of "ISO 17301-1:2016" in situ as bibitem
|
242
|
+
# Any erefs to that bibitem id are replaced with relative URL
|
243
|
+
# Preferably with anchor, and is a job to realise dynamic lookup of
|
244
|
+
# localities
|
245
|
+
# @param file [String] XML content
|
246
|
+
# @param identifier [String] docid
|
247
|
+
# @return [String] XML content
|
248
|
+
def update_xrefs(file, identifier)
|
249
|
+
docxml = Nokogiri::XML(file)
|
250
|
+
docxml.xpath(ns("//bibitem[not(ancestor::bibitem)]")).each do |b|
|
251
|
+
docid = b&.at(ns("./docidentifier[@type = 'repository']"))&.text
|
252
|
+
next unless docid && %r{^current-metanorma-collection/}.match(docid)
|
253
|
+
|
254
|
+
update_bibitem(b, identifier)
|
255
|
+
update_anchors(b, docxml, docid)
|
256
|
+
end
|
257
|
+
docxml.to_xml
|
258
|
+
end
|
259
|
+
|
260
|
+
# if there is a crossref to another document, with no anchor, retrieve the
|
261
|
+
# anchor given the locality, and insert it into the crossref
|
262
|
+
def update_anchors(bib, docxml, _id) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
263
|
+
docid = bib&.at(ns("./docidentifier"))&.text
|
264
|
+
docxml.xpath("//xmlns:eref[@citeas = '#{docid}']").each do |e|
|
265
|
+
e.at(ns(".//locality[@type = 'anchor']")).nil? || next
|
266
|
+
ins = e.at(ns("./localityStack")) || next
|
267
|
+
type = ins&.at(ns("./locality/@type"))&.text
|
268
|
+
ref = ins&.at(ns("./locality/referenceFrom"))&.text
|
269
|
+
(anchor = @files[docid][:anchors][type][ref]) || next
|
270
|
+
ref_from = Nokogiri::XML::Node.new "referenceFrom", bib
|
271
|
+
ref_from.content = anchor.sub(/^_/, "")
|
272
|
+
locality = Nokogiri::XML::Node.new "locality", bib
|
273
|
+
locality[:type] = "anchor"
|
274
|
+
locality.add_child ref_from
|
275
|
+
ins << locality
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
279
|
+
# process each file in the collection
|
280
|
+
# files are held in memory, and altered as postprocessing
|
281
|
+
def files # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
282
|
+
@files.each do |identifier, x|
|
283
|
+
file, filename = targetfile(x, true)
|
284
|
+
file = update_xrefs(file, identifier)
|
285
|
+
Tempfile.open(["collection", ".xml"], encoding: "utf-8") do |f|
|
286
|
+
f.write(file)
|
287
|
+
f.close
|
288
|
+
# warn "metanorma compile -x html #{f.path}"
|
289
|
+
c = Compile.new
|
290
|
+
c.compile f.path, format: :asciidoc, extension_keys: @format
|
291
|
+
@format.each do |ext|
|
292
|
+
fn = File.basename(filename).sub(/(?<=\.)[^\.]+$/, ext.to_s)
|
293
|
+
FileUtils.mv f.path.sub(/\.xml$/, ".#{ext}"), File.join(@outdir, fn)
|
294
|
+
end
|
295
|
+
end
|
296
|
+
end
|
297
|
+
end
|
298
|
+
|
299
|
+
private
|
300
|
+
|
301
|
+
# @param options [Hash]
|
302
|
+
# @raise [ArgumentError]
|
303
|
+
def check_options(options)
|
304
|
+
unless options[:format].is_a?(Array) && (FORMATS & options[:format]).any?
|
305
|
+
raise ArgumentError, "Need to specify formats (xml,html,pdf,doc)"
|
306
|
+
end
|
307
|
+
return if !options[:format].include?(:html) || options[:coverpage]
|
308
|
+
|
309
|
+
raise ArgumentError, "Need to specify a coverpage to render HTML"
|
310
|
+
end
|
311
|
+
end
|
312
|
+
end
|
data/lib/metanorma/compile.rb
CHANGED
@@ -4,14 +4,18 @@ require "htmlentities"
|
|
4
4
|
|
5
5
|
module Metanorma
|
6
6
|
class Compile
|
7
|
+
# @return [Array<String>]
|
8
|
+
attr_reader :errors
|
9
|
+
|
7
10
|
def initialize
|
8
11
|
@registry = Metanorma::Registry.instance
|
12
|
+
@errors = []
|
9
13
|
end
|
10
14
|
|
11
15
|
def compile(filename, options = {})
|
12
16
|
require_libraries(options)
|
13
17
|
options = options_extract(filename, options)
|
14
|
-
|
18
|
+
validate_type(options) && validate_format(options) || (return nil)
|
15
19
|
@processor = @registry.find_processor(options[:type].to_sym)
|
16
20
|
extensions = get_extensions(options) or return nil
|
17
21
|
(file, isodoc = process_input(filename, options)) or return nil
|
@@ -43,6 +47,7 @@ module Metanorma
|
|
43
47
|
o = Metanorma::Input::Asciidoc.new.extract_metanorma_options(content)
|
44
48
|
o = o.merge(xml_options_extract(content))
|
45
49
|
options[:type] ||= o[:type]&.to_sym
|
50
|
+
t = @registry.alias(options[:type]) and options[:type] = t
|
46
51
|
dir = filename.sub(%r(/[^/]+$), "/")
|
47
52
|
options[:relaton] ||= "#{dir}/#{o[:relaton]}" if o[:relaton]
|
48
53
|
options[:sourcecode] ||= "#{dir}/#{o[:sourcecode]}" if o[:sourcecode]
|
@@ -53,10 +58,6 @@ module Metanorma
|
|
53
58
|
options
|
54
59
|
end
|
55
60
|
|
56
|
-
def validate(options)
|
57
|
-
validate_type(options) && validate_format(options)
|
58
|
-
end
|
59
|
-
|
60
61
|
def validate_type(options)
|
61
62
|
unless options[:type]
|
62
63
|
Util.log("[metanorma] Error: Please specify a standard type: #{@registry.supported_backends}.", :error)
|
@@ -89,14 +90,22 @@ module Metanorma
|
|
89
90
|
end
|
90
91
|
|
91
92
|
def get_extensions(options)
|
92
|
-
options[:extension_keys] ||= @processor.output_formats.
|
93
|
-
memo << k
|
93
|
+
options[:extension_keys] ||= @processor.output_formats.reduce([]) do |memo, (k, _)|
|
94
|
+
memo << k
|
94
95
|
end
|
95
|
-
extensions = options[:extension_keys].
|
96
|
-
@processor.output_formats[e]
|
97
|
-
|
98
|
-
|
96
|
+
extensions = options[:extension_keys].reduce([]) do |memo, e|
|
97
|
+
if @processor.output_formats[e]
|
98
|
+
memo << e
|
99
|
+
else
|
100
|
+
message = "[metanorma] Error: #{e} format is not supported for this standard."
|
101
|
+
@errors << message
|
102
|
+
Util.log(message, :error)
|
103
|
+
memo
|
104
|
+
end
|
99
105
|
end
|
106
|
+
if !extensions.include?(:presentation) and extensions.any? { |e| @processor.use_presentation_xml(e) }
|
107
|
+
extensions << :presentation
|
108
|
+
end
|
100
109
|
extensions
|
101
110
|
end
|
102
111
|
|
@@ -110,7 +119,7 @@ module Metanorma
|
|
110
119
|
dir = File.dirname(filename)
|
111
120
|
dir != '.' and
|
112
121
|
file.gsub!(/^include::/, "include::#{dir}/")
|
113
|
-
[file, @processor.input_to_isodoc(file, filename)]
|
122
|
+
[file, @processor.input_to_isodoc(file, filename, options)]
|
114
123
|
when ".xml"
|
115
124
|
Util.log("[metanorma] Processing: Metanorma XML input.", :info)
|
116
125
|
# TODO NN: this is a hack -- we should provide/bridge the
|
@@ -195,28 +204,62 @@ module Metanorma
|
|
195
204
|
end
|
196
205
|
end
|
197
206
|
|
207
|
+
# dependency ordering
|
208
|
+
def sort_extensions_execution(ext)
|
209
|
+
case ext
|
210
|
+
when :xml then 0
|
211
|
+
when :rxl then 1
|
212
|
+
when :presentation then 2
|
213
|
+
else
|
214
|
+
99
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
def wrap_html(options, file_extension, outfilename)
|
219
|
+
if options[:wrapper] and /html$/.match file_extension
|
220
|
+
outfilename = outfilename.sub(/\.html$/, "")
|
221
|
+
FileUtils.mkdir_p outfilename
|
222
|
+
FileUtils.mv "#{outfilename}.html", outfilename
|
223
|
+
FileUtils.mv "#{outfilename}_images", outfilename, force: true
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
# isodoc is Raw Metanorma XML
|
198
228
|
def process_extensions(extensions, file, isodoc, options)
|
199
|
-
|
229
|
+
f = change_output_dir options
|
230
|
+
xml_name = f.sub(/\.[^.]+$/, ".xml")
|
231
|
+
presentationxml_name = f.sub(/\.[^.]+$/, ".presentation.xml")
|
232
|
+
extensions.sort do |a, b|
|
233
|
+
sort_extensions_execution(a) <=> sort_extensions_execution(b)
|
234
|
+
end.each do |ext|
|
200
235
|
isodoc_options = @processor.extract_options(file)
|
201
236
|
isodoc_options[:datauriimage] = true if options[:datauriimage]
|
202
237
|
file_extension = @processor.output_formats[ext]
|
203
|
-
outfilename =
|
238
|
+
outfilename = f.sub(/\.[^.]+$/, ".#{file_extension}")
|
204
239
|
if ext == :rxl
|
205
240
|
options[:relaton] = outfilename
|
206
241
|
relaton_export(isodoc, options)
|
207
242
|
else
|
208
243
|
begin
|
209
|
-
|
210
|
-
|
244
|
+
@processor.use_presentation_xml(ext) ?
|
245
|
+
@processor.output(nil, presentationxml_name, outfilename, ext, isodoc_options) :
|
246
|
+
@processor.output(isodoc, xml_name, outfilename, ext, isodoc_options)
|
247
|
+
rescue StandardError => e
|
211
248
|
puts e.message
|
212
249
|
end
|
213
250
|
end
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
251
|
+
wrap_html(options, file_extension, outfilename)
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
private
|
256
|
+
|
257
|
+
# @param options [Hash]
|
258
|
+
# @return [String]
|
259
|
+
def change_output_dir(options)
|
260
|
+
if options[:"output-dir"]
|
261
|
+
File.join options[:"output-dir"], File.basename(options[:filename])
|
262
|
+
else options[:filename]
|
220
263
|
end
|
221
264
|
end
|
222
265
|
end
|
data/lib/metanorma/document.rb
CHANGED
@@ -1,12 +1,82 @@
|
|
1
1
|
module Metanorma
|
2
2
|
class Document
|
3
|
+
# @return [Strin]
|
4
|
+
attr_reader :file
|
3
5
|
|
4
|
-
|
5
|
-
|
6
|
-
@
|
7
|
-
@
|
8
|
-
@output_formats
|
6
|
+
# @param bibitem [RelatonBib::BibliographicItem]
|
7
|
+
def initialize(bibitem, file)
|
8
|
+
@bibitem = bibitem
|
9
|
+
@file = file
|
9
10
|
end
|
10
11
|
|
12
|
+
class << self
|
13
|
+
# @param file [String] file path
|
14
|
+
# @return [Metanorma::Document]
|
15
|
+
def parse_file(file)
|
16
|
+
new bibitem(file), file
|
17
|
+
end
|
18
|
+
|
19
|
+
# #param xml [Nokogiri::XML::Document, Nokogiri::XML::Element]
|
20
|
+
# @return [Metanorma::Document]
|
21
|
+
def parse_xml(xml)
|
22
|
+
new from_xml(xml)
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
# #param xml [Nokogiri::XML::Document, Nokogiri::XML::Element]
|
28
|
+
# @return [RelatonBib::BibliographicItem,RelatonIso::IsoBibliographicItem]
|
29
|
+
def from_xml(xml)
|
30
|
+
Relaton::Cli.parse_xml xml.at("//xmlns:bibitem|//xmlns:bibdata")
|
31
|
+
end
|
32
|
+
|
33
|
+
# @param file [String]
|
34
|
+
# @return [Symbol] file type
|
35
|
+
def format(file)
|
36
|
+
case file
|
37
|
+
when /\.xml$/ then :xml
|
38
|
+
when /.ya?ml$/ then :yaml
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# @param file [String]
|
43
|
+
# @return [RelatonBib::BibliographicItem,
|
44
|
+
# RelatonIso::IsoBibliographicItem]
|
45
|
+
def bibitem(file)
|
46
|
+
case format(file)
|
47
|
+
when :xml
|
48
|
+
from_xml Nokogiri::XML(File.read(file, encoding: "UTF-8"))
|
49
|
+
when :yaml
|
50
|
+
yaml = File.read(file, ecoding: "UTF-8")
|
51
|
+
Relaton::Cli::YAMLConvertor.convert_single_file(yaml)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# @param builder [Nokogiri::XML::Builder, nil]
|
57
|
+
# @return [Nokogiri::XML::Builder, String]
|
58
|
+
def to_xml(builder = nil)
|
59
|
+
if builder
|
60
|
+
render_xml builder
|
61
|
+
else
|
62
|
+
Nokogiri::XML::Builder.new do |b|
|
63
|
+
root = render_xml b
|
64
|
+
root["xmlns"] = "http://metanorma.org"
|
65
|
+
end.to_xml
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
# @return [String]
|
70
|
+
def type
|
71
|
+
@type ||= (@bibitem.docidentifier.first&.type ||
|
72
|
+
@bibitem.docidentifier.first&.id&.match(/^[^\s]+/)&.to_s)&.downcase ||
|
73
|
+
"standoc"
|
74
|
+
end
|
75
|
+
|
76
|
+
private
|
77
|
+
|
78
|
+
def render_xml(builder)
|
79
|
+
builder.send(type + "-standard") { |b| @bibitem.to_xml b, bibdata: true }
|
80
|
+
end
|
11
81
|
end
|
12
82
|
end
|
@@ -5,7 +5,7 @@ module Metanorma
|
|
5
5
|
|
6
6
|
class Asciidoc < Base
|
7
7
|
|
8
|
-
def process(file, filename, type)
|
8
|
+
def process(file, filename, type, options = {})
|
9
9
|
require "asciidoctor"
|
10
10
|
::Asciidoctor.convert(
|
11
11
|
file,
|
@@ -13,7 +13,10 @@ module Metanorma
|
|
13
13
|
safe: :safe,
|
14
14
|
backend: type,
|
15
15
|
header_footer: true,
|
16
|
-
attributes: [
|
16
|
+
attributes: [
|
17
|
+
"nodoc", "stem", "xrefstyle=short", "docfile=#{filename}",
|
18
|
+
"output_dir=#{options[:"output-dir"]}"
|
19
|
+
],
|
17
20
|
)
|
18
21
|
end
|
19
22
|
|
@@ -7,7 +7,13 @@ module Metanorma
|
|
7
7
|
def convert(url_path, output_path, xsl_stylesheet)
|
8
8
|
return if url_path.nil? || output_path.nil? || xsl_stylesheet.nil?
|
9
9
|
|
10
|
-
Mn2pdf.convert(url_path, output_path, xsl_stylesheet)
|
10
|
+
Mn2pdf.convert(quote(url_path), quote(output_path), quote(xsl_stylesheet))
|
11
|
+
end
|
12
|
+
|
13
|
+
def quote(x)
|
14
|
+
return x if /^'.*'$/.match(x)
|
15
|
+
return x if /^".*"$/.match(x)
|
16
|
+
%("#{x}")
|
11
17
|
end
|
12
18
|
end
|
13
19
|
end
|
data/lib/metanorma/processor.rb
CHANGED
@@ -15,15 +15,28 @@ module Metanorma
|
|
15
15
|
def output_formats
|
16
16
|
{
|
17
17
|
xml: "xml",
|
18
|
+
presentation: "presentation.xml",
|
18
19
|
rxl: "rxl"
|
19
20
|
}
|
20
21
|
end
|
21
22
|
|
22
|
-
def input_to_isodoc(file, filename)
|
23
|
-
|
23
|
+
def input_to_isodoc(file, filename, options = {})
|
24
|
+
Metanorma::Input::Asciidoc.new.process(file, filename, @asciidoctor_backend, options)
|
25
|
+
end
|
26
|
+
|
27
|
+
# def input_to_isodoc(file, filename)
|
28
|
+
# raise "This is an abstract class!"
|
29
|
+
# end
|
30
|
+
|
31
|
+
def use_presentation_xml(ext)
|
32
|
+
case ext
|
33
|
+
when :html, :doc, :pdf then true
|
34
|
+
else
|
35
|
+
false
|
36
|
+
end
|
24
37
|
end
|
25
38
|
|
26
|
-
def output(isodoc_node, outname, format, options={})
|
39
|
+
def output(isodoc_node, inname, outname, format, options={})
|
27
40
|
File.open(outname, "w:UTF-8") { |f| f.write(isodoc_node) }
|
28
41
|
end
|
29
42
|
|
data/lib/metanorma/registry.rb
CHANGED
@@ -14,14 +14,23 @@ module Metanorma
|
|
14
14
|
|
15
15
|
def initialize
|
16
16
|
@processors = {}
|
17
|
+
@aliases = {csd: :cc, m3d: :m3aawg, mpfd: :mpfa, csand: :csa}
|
18
|
+
end
|
19
|
+
|
20
|
+
def alias(x)
|
21
|
+
@aliases[x]
|
17
22
|
end
|
18
23
|
|
19
24
|
def register processor
|
20
25
|
raise Error unless processor < ::Metanorma::Processor
|
21
26
|
p = processor.new
|
22
|
-
|
23
|
-
|
27
|
+
# p.short[-1] is the canonical name
|
28
|
+
short = Array(p.short)
|
29
|
+
@processors[short[-1]] = p
|
30
|
+
short.each do |s|
|
31
|
+
@aliases[s] = short[-1]
|
24
32
|
end
|
33
|
+
Array(p.short)
|
25
34
|
Util.log("[metanorma] processor \"#{Array(p.short)[0]}\" registered", :info)
|
26
35
|
end
|
27
36
|
|
data/lib/metanorma/version.rb
CHANGED
data/metanorma.gemspec
CHANGED
@@ -27,11 +27,13 @@ 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_dependency "relaton-cli", "~> 1.3.0"
|
30
31
|
|
31
32
|
spec.add_development_dependency "rake", "~> 12.0"
|
32
33
|
spec.add_development_dependency "rspec", "~> 3.0"
|
33
34
|
spec.add_development_dependency "byebug", "~> 10.0"
|
34
35
|
spec.add_development_dependency "rspec-command", "~> 1.0"
|
35
36
|
spec.add_development_dependency "equivalent-xml", "~> 0.6"
|
36
|
-
spec.add_development_dependency "metanorma-iso", "~> 1.
|
37
|
+
spec.add_development_dependency "metanorma-iso", "~> 1.5"
|
38
|
+
spec.add_development_dependency "isodoc", "~> 1.2.1"
|
37
39
|
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.
|
4
|
+
version: 1.1.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ribose Inc.
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-08-27 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: relaton-cli
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 1.3.0
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 1.3.0
|
69
83
|
- !ruby/object:Gem::Dependency
|
70
84
|
name: rake
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -142,14 +156,28 @@ dependencies:
|
|
142
156
|
requirements:
|
143
157
|
- - "~>"
|
144
158
|
- !ruby/object:Gem::Version
|
145
|
-
version: '1.
|
159
|
+
version: '1.5'
|
160
|
+
type: :development
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - "~>"
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '1.5'
|
167
|
+
- !ruby/object:Gem::Dependency
|
168
|
+
name: isodoc
|
169
|
+
requirement: !ruby/object:Gem::Requirement
|
170
|
+
requirements:
|
171
|
+
- - "~>"
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: 1.2.1
|
146
174
|
type: :development
|
147
175
|
prerelease: false
|
148
176
|
version_requirements: !ruby/object:Gem::Requirement
|
149
177
|
requirements:
|
150
178
|
- - "~>"
|
151
179
|
- !ruby/object:Gem::Version
|
152
|
-
version:
|
180
|
+
version: 1.2.1
|
153
181
|
description: Library to process any Metanorma standard.
|
154
182
|
email:
|
155
183
|
- open.source@ribose.com
|
@@ -182,6 +210,9 @@ files:
|
|
182
210
|
- lib/metanorma.rb
|
183
211
|
- lib/metanorma/asciidoctor_extensions.rb
|
184
212
|
- lib/metanorma/asciidoctor_extensions/glob_include_processor.rb
|
213
|
+
- lib/metanorma/collection.rb
|
214
|
+
- lib/metanorma/collection_manifest.rb
|
215
|
+
- lib/metanorma/collection_renderer.rb
|
185
216
|
- lib/metanorma/compile.rb
|
186
217
|
- lib/metanorma/config.rb
|
187
218
|
- lib/metanorma/document.rb
|
@@ -202,7 +233,7 @@ homepage: https://github.com/metanorma/metanorma
|
|
202
233
|
licenses:
|
203
234
|
- BSD-2-Clause
|
204
235
|
metadata: {}
|
205
|
-
post_install_message:
|
236
|
+
post_install_message:
|
206
237
|
rdoc_options: []
|
207
238
|
require_paths:
|
208
239
|
- lib
|
@@ -217,9 +248,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
217
248
|
- !ruby/object:Gem::Version
|
218
249
|
version: '0'
|
219
250
|
requirements: []
|
220
|
-
|
221
|
-
|
222
|
-
signing_key:
|
251
|
+
rubygems_version: 3.0.3
|
252
|
+
signing_key:
|
223
253
|
specification_version: 4
|
224
254
|
summary: Metanorma is the standard of standards; the metanorma gem allows you to create
|
225
255
|
any standard document type supported by Metanorma.
|