metanorma 1.1.1 → 1.1.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -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 +330 -0
- data/lib/metanorma/compile.rb +21 -12
- data/lib/metanorma/document.rb +86 -5
- data/lib/metanorma/input/asciidoc.rb +27 -5
- data/lib/metanorma/output/xslfo.rb +7 -1
- data/lib/metanorma/processor.rb +6 -2
- data/lib/metanorma/registry.rb +11 -2
- data/lib/metanorma/version.rb +1 -1
- data/metanorma.gemspec +5 -1
- metadata +7 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: aecd92b31139e0a3f76ff7485f3bde8e5b6d89be735eafadc0215962b8b1aec1
|
4
|
+
data.tar.gz: 4c00ec06b3d9a632bbdbc810aa46635fef4c85f88382c6e014a8238261987f7e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 570efb165e57540e107f6f29acd53a373d702c825eefd1c9ee3e04fac4644432fc9347400dea3a1b48f8aa03c28ac31634bd4a3545dc86622768d2285a9cb87f
|
7
|
+
data.tar.gz: 554df7349b548f35d6fbf3f04d453964c3aa7a9067c496f4815eed42de07ceeaca4b93a7278f41709343744569c7c45b096916b184050366369597b22281ed46
|
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_accessor :directives
|
16
|
+
|
17
|
+
# @return [Hash<String, Metanorma::Document>]
|
18
|
+
attr_accessor :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,330 @@
|
|
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.concatenate(col, options)
|
53
|
+
cr.coverpage if options[:format]&.include?(:html)
|
54
|
+
end
|
55
|
+
|
56
|
+
def concatenate(col, options)
|
57
|
+
options[:format].each do |e|
|
58
|
+
next unless %i(presentation xml).include?(e)
|
59
|
+
ext = e == :presentation ? "presentation.xml" : e.to_s
|
60
|
+
out = col.clone
|
61
|
+
out.directives << "documents-inline"
|
62
|
+
out.documents.keys.each do |id|
|
63
|
+
filename = @files[id][:outputs][e]
|
64
|
+
out.documents[id] = Metanorma::Document.raw_file(filename)
|
65
|
+
end
|
66
|
+
File.open(File.join(@outdir, "collection.#{ext}"), "w:UTF-8") { |f| f.write(out.to_xml) }
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
# Dummy class
|
71
|
+
class Dummy
|
72
|
+
def attr(_xyz); end
|
73
|
+
end
|
74
|
+
|
75
|
+
# The isodoc class for the metanorma flavour we are using
|
76
|
+
def isodoc # rubocop:disable Metrics/MethodLength
|
77
|
+
x = Asciidoctor.load nil, backend: @doctype.to_sym
|
78
|
+
isodoc = x.converter.html_converter(Dummy.new)
|
79
|
+
isodoc.i18n_init(@lang, @script) # read in internationalisation
|
80
|
+
# create the @meta class of isodoc, with "navigation" set to the index bar
|
81
|
+
# extracted from the manifest
|
82
|
+
nav = indexfile(@xml.at(ns("//manifest")))
|
83
|
+
i18n = isodoc.i18n
|
84
|
+
i18n.set(:navigation, nav)
|
85
|
+
isodoc.metadata_init(@lang, @script, i18n)
|
86
|
+
# populate the @meta class of isodoc with the various metadata fields
|
87
|
+
# native to the flavour; used to populate Liquid
|
88
|
+
isodoc.info(@xml, nil)
|
89
|
+
isodoc
|
90
|
+
end
|
91
|
+
|
92
|
+
# infer the flavour from the first document identifier; relaton does that
|
93
|
+
def doctype
|
94
|
+
if (docid = @xml&.at(ns("//bibdata/docidentifier/@type"))&.text)
|
95
|
+
dt = docid.downcase
|
96
|
+
elsif (docid = @xml&.at(ns("//bibdata/docidentifier"))&.text)
|
97
|
+
dt = docid.sub(/\s.*$/, "").lowercase
|
98
|
+
else return "standoc"
|
99
|
+
end
|
100
|
+
@registry = Metanorma::Registry.instance
|
101
|
+
@registry.alias(dt.to_sym)&.to_s || dt
|
102
|
+
end
|
103
|
+
|
104
|
+
def ns(xpath)
|
105
|
+
IsoDoc::Convert.new({}).ns(xpath)
|
106
|
+
end
|
107
|
+
|
108
|
+
# hash for each document in collection of document identifier to:
|
109
|
+
# document reference (fileref or id), type of document reference,
|
110
|
+
# and bibdata entry for that file
|
111
|
+
# @param path [String] path to collection
|
112
|
+
# @return [Hash{String=>Hash}]
|
113
|
+
def read_files(path) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
114
|
+
files = {}
|
115
|
+
@xml.xpath(ns("//docref")).each do |d|
|
116
|
+
identifier = d.at(ns("./identifier")).text
|
117
|
+
files[identifier] = if d["fileref"]
|
118
|
+
{ type: "fileref",
|
119
|
+
ref: File.join(path, d["fileref"]) }
|
120
|
+
else { type: "id", ref: d["id"] }
|
121
|
+
end
|
122
|
+
file, _filename = targetfile(files[identifier], true)
|
123
|
+
xml = Nokogiri::XML(file)
|
124
|
+
files[identifier][:anchors] = read_anchors(xml)
|
125
|
+
files[identifier][:bibdata] = xml.at(ns("//bibdata"))
|
126
|
+
end
|
127
|
+
files
|
128
|
+
end
|
129
|
+
|
130
|
+
# map locality type and label (e.g. "clause" "1") to id = anchor for
|
131
|
+
# a document
|
132
|
+
def read_anchors(xml)
|
133
|
+
ret = {}
|
134
|
+
xrefs = @isodoc.xref_init(@lang, @script, @isodoc, @isodoc.i18n, {})
|
135
|
+
xrefs.parse xml
|
136
|
+
xrefs.get.each do |k, v|
|
137
|
+
v[:label] && v[:type] || next
|
138
|
+
ret[v[:type]] ||= {}
|
139
|
+
ret[v[:type]][v[:label]] = k
|
140
|
+
end
|
141
|
+
ret
|
142
|
+
end
|
143
|
+
|
144
|
+
# populate liquid template of ARGV[1] with metadata extracted from
|
145
|
+
# collection manifest
|
146
|
+
def coverpage
|
147
|
+
File.open(File.join(@outdir, "index.html"), "w:UTF-8") do |f|
|
148
|
+
f.write @isodoc.populate_template(File.read(@coverpage))
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
# @param elm [Nokogiri::XML::Element]
|
153
|
+
# @return [String]
|
154
|
+
def indexfile_title(elm)
|
155
|
+
lvl = elm&.at(ns("./level"))&.text&.capitalize
|
156
|
+
lbl = elm&.at(ns("./title"))&.text
|
157
|
+
"#{lvl}#{lvl && lbl ? ': ' : ''}#{lbl}"
|
158
|
+
end
|
159
|
+
|
160
|
+
# uses the identifier to label documents; other attributes (title) can be
|
161
|
+
# looked up in @files[id][:bibdata]
|
162
|
+
#
|
163
|
+
# @param elm [Nokogiri::XML::Element]
|
164
|
+
# @param builder [Nokogiri::XML::Builder]
|
165
|
+
def indexfile_docref(elm, builder)
|
166
|
+
return "" unless elm.at(ns("./docref"))
|
167
|
+
|
168
|
+
builder.ul { |b| docrefs(elm, b) }
|
169
|
+
end
|
170
|
+
|
171
|
+
# @param elm [Nokogiri::XML::Element]
|
172
|
+
# @param builder [Nokogiri::XML::Builder]
|
173
|
+
def docrefs(elm, builder)
|
174
|
+
elm.xpath(ns("./docref")).each do |d|
|
175
|
+
identifier = d.at(ns("./identifier")).text
|
176
|
+
link = if d["fileref"] then d["fileref"].sub(/\.xml$/, ".html")
|
177
|
+
else d["id"] + ".html"
|
178
|
+
end
|
179
|
+
builder.li { builder.a identifier, href: link }
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
# single level navigation list, with hierarchical nesting
|
184
|
+
# if multiple lists are needed as separate HTML fragments, multiple
|
185
|
+
# instances of this function will be needed,
|
186
|
+
# and associated to different variables in the call to @isodoc.metadata_init
|
187
|
+
# (including possibly an array of HTML fragments)
|
188
|
+
#
|
189
|
+
# @param elm [Nokogiri::XML::Element]
|
190
|
+
# @return [String] XML
|
191
|
+
def indexfile(elm)
|
192
|
+
Nokogiri::HTML::Builder.new do |b|
|
193
|
+
b.ul do
|
194
|
+
b.li indexfile_title(elm)
|
195
|
+
indexfile_docref(elm, b)
|
196
|
+
elm.xpath(ns("./manifest")).each do |d|
|
197
|
+
b << indexfile(d)
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end.doc.root.to_html
|
201
|
+
end
|
202
|
+
|
203
|
+
# return file contents + output filename for each file in the collection,
|
204
|
+
# given a docref entry
|
205
|
+
# @param data [Hash]
|
206
|
+
# @param read [Boolean]
|
207
|
+
# @return [Array<String, nil>]
|
208
|
+
def targetfile(data, read = false)
|
209
|
+
if data[:type] == "fileref" then ref_file data[:ref], read
|
210
|
+
else xml_file data[:id], read
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
# @param ref [String]
|
215
|
+
# @param read [Boolean]
|
216
|
+
# @return [Array<String, nil>]
|
217
|
+
def ref_file(ref, read)
|
218
|
+
file = File.read(ref, encoding: "utf-8") if read
|
219
|
+
filename = ref.sub(/\.xml$/, ".html")
|
220
|
+
[file, filename]
|
221
|
+
end
|
222
|
+
|
223
|
+
# @param id [String]
|
224
|
+
# @param read [Boolean]
|
225
|
+
# @return [Array<String, nil>]
|
226
|
+
def xml_file(id, read)
|
227
|
+
file = @xml.at(ns("//doc-container[@id = '#{id}']")).to_xml if read
|
228
|
+
filename = id + ".html"
|
229
|
+
[file, filename]
|
230
|
+
end
|
231
|
+
|
232
|
+
# @param bib [Nokogiri::XML::Element]
|
233
|
+
# @param identifier [String]
|
234
|
+
def update_bibitem(bib, identifier) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
235
|
+
docid = bib&.at(ns("./docidentifier"))&.text
|
236
|
+
unless @files[docid]
|
237
|
+
warn "Cannot find crossreference to document #{docid} in document "\
|
238
|
+
"#{identifier}!"
|
239
|
+
abort
|
240
|
+
end
|
241
|
+
id = bib["id"]
|
242
|
+
newbib = bib.replace(@files[docid][:bibdata])
|
243
|
+
newbib.name = "bibitem"
|
244
|
+
newbib["id"] = id
|
245
|
+
newbib&.at(ns("./ext"))&.remove
|
246
|
+
_file, url = targetfile(@files[docid], false)
|
247
|
+
uri_node = Nokogiri::XML::Node.new "uri", newbib
|
248
|
+
uri_node[:type] = "citation"
|
249
|
+
uri_node.content = url
|
250
|
+
newbib.at(ns("./docidentifier")).previous = uri_node
|
251
|
+
end
|
252
|
+
|
253
|
+
# TODO: update crossreferences to other files in the selection
|
254
|
+
# repo(current-metanorma-collection/ISO 17301-1:2016)
|
255
|
+
# replaced by
|
256
|
+
# bibdata of "ISO 17301-1:2016" in situ as bibitem
|
257
|
+
# Any erefs to that bibitem id are replaced with relative URL
|
258
|
+
# Preferably with anchor, and is a job to realise dynamic lookup of
|
259
|
+
# localities
|
260
|
+
# @param file [String] XML content
|
261
|
+
# @param identifier [String] docid
|
262
|
+
# @return [String] XML content
|
263
|
+
def update_xrefs(file, identifier)
|
264
|
+
docxml = Nokogiri::XML(file)
|
265
|
+
docxml.xpath(ns("//bibitem[not(ancestor::bibitem)]")).each do |b|
|
266
|
+
docid = b&.at(ns("./docidentifier[@type = 'repository']"))&.text
|
267
|
+
next unless docid && %r{^current-metanorma-collection/}.match(docid)
|
268
|
+
|
269
|
+
update_bibitem(b, identifier)
|
270
|
+
update_anchors(b, docxml, docid)
|
271
|
+
end
|
272
|
+
docxml.to_xml
|
273
|
+
end
|
274
|
+
|
275
|
+
# if there is a crossref to another document, with no anchor, retrieve the
|
276
|
+
# anchor given the locality, and insert it into the crossref
|
277
|
+
def update_anchors(bib, docxml, _id) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
278
|
+
docid = bib&.at(ns("./docidentifier"))&.text
|
279
|
+
docxml.xpath("//xmlns:eref[@citeas = '#{docid}']").each do |e|
|
280
|
+
e.at(ns(".//locality[@type = 'anchor']")).nil? || next
|
281
|
+
ins = e.at(ns("./localityStack")) || next
|
282
|
+
type = ins&.at(ns("./locality/@type"))&.text
|
283
|
+
ref = ins&.at(ns("./locality/referenceFrom"))&.text
|
284
|
+
(anchor = @files[docid][:anchors][type][ref]) || next
|
285
|
+
ref_from = Nokogiri::XML::Node.new "referenceFrom", bib
|
286
|
+
ref_from.content = anchor.sub(/^_/, "")
|
287
|
+
locality = Nokogiri::XML::Node.new "locality", bib
|
288
|
+
locality[:type] = "anchor"
|
289
|
+
locality.add_child ref_from
|
290
|
+
ins << locality
|
291
|
+
end
|
292
|
+
end
|
293
|
+
|
294
|
+
# process each file in the collection
|
295
|
+
# files are held in memory, and altered as postprocessing
|
296
|
+
def files # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
297
|
+
@files.each do |identifier, x|
|
298
|
+
file, filename = targetfile(x, true)
|
299
|
+
file = update_xrefs(file, identifier)
|
300
|
+
Tempfile.open(["collection", ".xml"], encoding: "utf-8") do |f|
|
301
|
+
f.write(file)
|
302
|
+
f.close
|
303
|
+
# warn "metanorma compile -x html #{f.path}"
|
304
|
+
c = Compile.new
|
305
|
+
c.compile f.path, format: :asciidoc, extension_keys: @format
|
306
|
+
@files[identifier][:outputs] = {}
|
307
|
+
@format.each do |e|
|
308
|
+
ext = c.processor.output_formats[e]
|
309
|
+
fn = File.basename(filename).sub(/(?<=\.)[^\.]+$/, ext.to_s)
|
310
|
+
FileUtils.mv f.path.sub(/\.xml$/, ".#{ext}"), File.join(@outdir, fn)
|
311
|
+
@files[identifier][:outputs][e] = File.join(@outdir, fn)
|
312
|
+
end
|
313
|
+
end
|
314
|
+
end
|
315
|
+
end
|
316
|
+
|
317
|
+
private
|
318
|
+
|
319
|
+
# @param options [Hash]
|
320
|
+
# @raise [ArgumentError]
|
321
|
+
def check_options(options)
|
322
|
+
unless options[:format].is_a?(Array) && (FORMATS & options[:format]).any?
|
323
|
+
raise ArgumentError, "Need to specify formats (xml,html,pdf,doc)"
|
324
|
+
end
|
325
|
+
return if !options[:format].include?(:html) || options[:coverpage]
|
326
|
+
|
327
|
+
raise ArgumentError, "Need to specify a coverpage to render HTML"
|
328
|
+
end
|
329
|
+
end
|
330
|
+
end
|
data/lib/metanorma/compile.rb
CHANGED
@@ -5,7 +5,7 @@ require "htmlentities"
|
|
5
5
|
module Metanorma
|
6
6
|
class Compile
|
7
7
|
# @return [Array<String>]
|
8
|
-
attr_reader :errors
|
8
|
+
attr_reader :errors, :processor
|
9
9
|
|
10
10
|
def initialize
|
11
11
|
@registry = Metanorma::Registry.instance
|
@@ -15,7 +15,7 @@ module Metanorma
|
|
15
15
|
def compile(filename, options = {})
|
16
16
|
require_libraries(options)
|
17
17
|
options = options_extract(filename, options)
|
18
|
-
|
18
|
+
validate_type(options) && validate_format(options) || (return nil)
|
19
19
|
@processor = @registry.find_processor(options[:type].to_sym)
|
20
20
|
extensions = get_extensions(options) or return nil
|
21
21
|
(file, isodoc = process_input(filename, options)) or return nil
|
@@ -47,6 +47,7 @@ module Metanorma
|
|
47
47
|
o = Metanorma::Input::Asciidoc.new.extract_metanorma_options(content)
|
48
48
|
o = o.merge(xml_options_extract(content))
|
49
49
|
options[:type] ||= o[:type]&.to_sym
|
50
|
+
t = @registry.alias(options[:type]) and options[:type] = t
|
50
51
|
dir = filename.sub(%r(/[^/]+$), "/")
|
51
52
|
options[:relaton] ||= "#{dir}/#{o[:relaton]}" if o[:relaton]
|
52
53
|
options[:sourcecode] ||= "#{dir}/#{o[:sourcecode]}" if o[:sourcecode]
|
@@ -57,10 +58,6 @@ module Metanorma
|
|
57
58
|
options
|
58
59
|
end
|
59
60
|
|
60
|
-
def validate(options)
|
61
|
-
validate_type(options) && validate_format(options)
|
62
|
-
end
|
63
|
-
|
64
61
|
def validate_type(options)
|
65
62
|
unless options[:type]
|
66
63
|
Util.log("[metanorma] Error: Please specify a standard type: #{@registry.supported_backends}.", :error)
|
@@ -122,7 +119,7 @@ module Metanorma
|
|
122
119
|
dir = File.dirname(filename)
|
123
120
|
dir != '.' and
|
124
121
|
file.gsub!(/^include::/, "include::#{dir}/")
|
125
|
-
[file, @processor.input_to_isodoc(file, filename)]
|
122
|
+
[file, @processor.input_to_isodoc(file, filename, options)]
|
126
123
|
when ".xml"
|
127
124
|
Util.log("[metanorma] Processing: Metanorma XML input.", :info)
|
128
125
|
# TODO NN: this is a hack -- we should provide/bridge the
|
@@ -229,15 +226,16 @@ module Metanorma
|
|
229
226
|
|
230
227
|
# isodoc is Raw Metanorma XML
|
231
228
|
def process_extensions(extensions, file, isodoc, options)
|
232
|
-
|
233
|
-
|
229
|
+
f = change_output_dir options
|
230
|
+
xml_name = f.sub(/\.[^.]+$/, ".xml")
|
231
|
+
presentationxml_name = f.sub(/\.[^.]+$/, ".presentation.xml")
|
234
232
|
extensions.sort do |a, b|
|
235
233
|
sort_extensions_execution(a) <=> sort_extensions_execution(b)
|
236
234
|
end.each do |ext|
|
237
|
-
file_extension = @processor.output_formats[ext]
|
238
|
-
outfilename = options[:filename].sub(/\.[^.]+$/, ".#{file_extension}")
|
239
235
|
isodoc_options = @processor.extract_options(file)
|
240
236
|
isodoc_options[:datauriimage] = true if options[:datauriimage]
|
237
|
+
file_extension = @processor.output_formats[ext]
|
238
|
+
outfilename = f.sub(/\.[^.]+$/, ".#{file_extension}")
|
241
239
|
if ext == :rxl
|
242
240
|
options[:relaton] = outfilename
|
243
241
|
relaton_export(isodoc, options)
|
@@ -246,12 +244,23 @@ module Metanorma
|
|
246
244
|
@processor.use_presentation_xml(ext) ?
|
247
245
|
@processor.output(nil, presentationxml_name, outfilename, ext, isodoc_options) :
|
248
246
|
@processor.output(isodoc, xml_name, outfilename, ext, isodoc_options)
|
249
|
-
rescue StandardError => e
|
247
|
+
rescue StandardError => e
|
250
248
|
puts e.message
|
251
249
|
end
|
252
250
|
end
|
253
251
|
wrap_html(options, file_extension, outfilename)
|
254
252
|
end
|
255
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]
|
263
|
+
end
|
264
|
+
end
|
256
265
|
end
|
257
266
|
end
|
data/lib/metanorma/document.rb
CHANGED
@@ -1,12 +1,93 @@
|
|
1
1
|
module Metanorma
|
2
2
|
class Document
|
3
|
+
# @return [Strin]
|
4
|
+
attr_reader :file
|
3
5
|
|
4
|
-
|
5
|
-
|
6
|
-
@
|
7
|
-
@
|
8
|
-
@
|
6
|
+
# @param bibitem [RelatonBib::BibliographicItem]
|
7
|
+
def initialize(bibitem, file, options = {})
|
8
|
+
@bibitem = bibitem
|
9
|
+
@file = file
|
10
|
+
@raw = options[:raw]
|
9
11
|
end
|
10
12
|
|
13
|
+
class << self
|
14
|
+
# @param file [String] file path
|
15
|
+
# @return [Metanorma::Document]
|
16
|
+
def parse_file(file)
|
17
|
+
new bibitem(file), file
|
18
|
+
end
|
19
|
+
|
20
|
+
# #param xml [Nokogiri::XML::Document, Nokogiri::XML::Element]
|
21
|
+
# @return [Metanorma::Document]
|
22
|
+
def parse_xml(xml)
|
23
|
+
new from_xml(xml)
|
24
|
+
end
|
25
|
+
|
26
|
+
# raw XML file, can be used to put in entire file instead of just bibitem
|
27
|
+
def raw_file(filename)
|
28
|
+
doc = Nokogiri::XML(File.read(filename, encoding: "UTF-8"))
|
29
|
+
new(doc, filename, raw: true)
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
# #param xml [Nokogiri::XML::Document, Nokogiri::XML::Element]
|
35
|
+
# @return [RelatonBib::BibliographicItem,RelatonIso::IsoBibliographicItem]
|
36
|
+
def from_xml(xml)
|
37
|
+
Relaton::Cli.parse_xml xml.at("//xmlns:bibitem|//xmlns:bibdata")
|
38
|
+
end
|
39
|
+
|
40
|
+
# @param file [String]
|
41
|
+
# @return [Symbol] file type
|
42
|
+
def format(file)
|
43
|
+
case file
|
44
|
+
when /\.xml$/ then :xml
|
45
|
+
when /.ya?ml$/ then :yaml
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# @param file [String]
|
50
|
+
# @return [RelatonBib::BibliographicItem,
|
51
|
+
# RelatonIso::IsoBibliographicItem]
|
52
|
+
def bibitem(file)
|
53
|
+
case format(file)
|
54
|
+
when :xml
|
55
|
+
from_xml Nokogiri::XML(File.read(file, encoding: "UTF-8"))
|
56
|
+
when :yaml
|
57
|
+
yaml = File.read(file, encoding: "UTF-8")
|
58
|
+
Relaton::Cli::YAMLConvertor.convert_single_file(yaml)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# @param builder [Nokogiri::XML::Builder, nil]
|
64
|
+
# @return [Nokogiri::XML::Builder, String]
|
65
|
+
def to_xml(builder = nil)
|
66
|
+
if builder
|
67
|
+
render_xml builder
|
68
|
+
else
|
69
|
+
Nokogiri::XML::Builder.new do |b|
|
70
|
+
root = render_xml b
|
71
|
+
root["xmlns"] = "http://metanorma.org"
|
72
|
+
end.to_xml
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
# @return [String]
|
77
|
+
def type
|
78
|
+
@type ||= (@bibitem.docidentifier.first&.type&.downcase ||
|
79
|
+
@bibitem.docidentifier.first&.id&.match(/^[^\s]+/)&.to_s)&.downcase ||
|
80
|
+
"standoc"
|
81
|
+
end
|
82
|
+
|
83
|
+
private
|
84
|
+
|
85
|
+
def render_xml(builder)
|
86
|
+
if @raw
|
87
|
+
builder << @bibitem.root.to_xml
|
88
|
+
else
|
89
|
+
builder.send(type + "-standard") { |b| @bibitem.to_xml b, bibdata: true }
|
90
|
+
end
|
91
|
+
end
|
11
92
|
end
|
12
93
|
end
|
@@ -5,16 +5,38 @@ 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
|
-
|
11
|
-
file,
|
10
|
+
out_opts = {
|
12
11
|
to_file: false,
|
13
12
|
safe: :safe,
|
14
13
|
backend: type,
|
15
14
|
header_footer: true,
|
16
|
-
attributes: [
|
17
|
-
|
15
|
+
attributes: [
|
16
|
+
"nodoc", "stem", "xrefstyle=short", "docfile=#{filename}",
|
17
|
+
"output_dir=#{options[:"output-dir"]}"
|
18
|
+
]
|
19
|
+
}
|
20
|
+
unless asciidoctor_validate(file, filename, out_opts)
|
21
|
+
warn "Cannot continue compiling Asciidoctor document"
|
22
|
+
abort
|
23
|
+
end
|
24
|
+
::Asciidoctor.convert(file, out_opts)
|
25
|
+
end
|
26
|
+
|
27
|
+
def asciidoctor_validate(file, filename, options)
|
28
|
+
err = nil
|
29
|
+
begin
|
30
|
+
previous_stderr, $stderr = $stderr, StringIO.new
|
31
|
+
::Asciidoctor.load(file, options)
|
32
|
+
%r{(\n|^)asciidoctor: ERROR: ['"]?#{Regexp.escape(filename ||
|
33
|
+
"<empty>")}['"]?: line \d+: include file not found: }.match($stderr.string) and
|
34
|
+
err = $stderr.string
|
35
|
+
ensure
|
36
|
+
$stderr = previous_stderr
|
37
|
+
end
|
38
|
+
warn err unless err.nil?
|
39
|
+
err.nil?
|
18
40
|
end
|
19
41
|
|
20
42
|
def extract_metanorma_options(file)
|
@@ -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
@@ -20,10 +20,14 @@ module Metanorma
|
|
20
20
|
}
|
21
21
|
end
|
22
22
|
|
23
|
-
def input_to_isodoc(file, filename)
|
24
|
-
|
23
|
+
def input_to_isodoc(file, filename, options = {})
|
24
|
+
Metanorma::Input::Asciidoc.new.process(file, filename, @asciidoctor_backend, options)
|
25
25
|
end
|
26
26
|
|
27
|
+
# def input_to_isodoc(file, filename)
|
28
|
+
# raise "This is an abstract class!"
|
29
|
+
# end
|
30
|
+
|
27
31
|
def use_presentation_xml(ext)
|
28
32
|
case ext
|
29
33
|
when :html, :doc, :pdf then true
|
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,15 @@ 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
|
+
# get relaton-cli to avoic circular reference with metanorma-standoc
|
31
|
+
#spec.add_dependency "relaton-cli"
|
32
|
+
#spec.add_dependency "metanorma-standoc", "~> 1.5.3"
|
30
33
|
|
31
34
|
spec.add_development_dependency "rake", "~> 12.0"
|
32
35
|
spec.add_development_dependency "rspec", "~> 3.0"
|
33
36
|
spec.add_development_dependency "byebug", "~> 10.0"
|
34
37
|
spec.add_development_dependency "rspec-command", "~> 1.0"
|
35
38
|
spec.add_development_dependency "equivalent-xml", "~> 0.6"
|
36
|
-
spec.add_development_dependency "metanorma-iso", "~> 1.
|
39
|
+
spec.add_development_dependency "metanorma-iso", "~> 1.5.8"
|
40
|
+
#spec.add_development_dependency "isodoc", "~> 1.2.1"
|
37
41
|
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.1.
|
4
|
+
version: 1.1.6
|
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
|
+
date: 2020-09-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: asciidoctor
|
@@ -142,14 +142,14 @@ dependencies:
|
|
142
142
|
requirements:
|
143
143
|
- - "~>"
|
144
144
|
- !ruby/object:Gem::Version
|
145
|
-
version:
|
145
|
+
version: 1.5.8
|
146
146
|
type: :development
|
147
147
|
prerelease: false
|
148
148
|
version_requirements: !ruby/object:Gem::Requirement
|
149
149
|
requirements:
|
150
150
|
- - "~>"
|
151
151
|
- !ruby/object:Gem::Version
|
152
|
-
version:
|
152
|
+
version: 1.5.8
|
153
153
|
description: Library to process any Metanorma standard.
|
154
154
|
email:
|
155
155
|
- open.source@ribose.com
|
@@ -182,6 +182,9 @@ files:
|
|
182
182
|
- lib/metanorma.rb
|
183
183
|
- lib/metanorma/asciidoctor_extensions.rb
|
184
184
|
- lib/metanorma/asciidoctor_extensions/glob_include_processor.rb
|
185
|
+
- lib/metanorma/collection.rb
|
186
|
+
- lib/metanorma/collection_manifest.rb
|
187
|
+
- lib/metanorma/collection_renderer.rb
|
185
188
|
- lib/metanorma/compile.rb
|
186
189
|
- lib/metanorma/config.rb
|
187
190
|
- lib/metanorma/document.rb
|