metanorma-iso 1.10.5 → 2.0.2
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/rake.yml +3 -33
- data/.gitignore +26 -0
- data/Makefile +1 -1
- data/lib/asciidoctor/iso/base.rb +2 -69
- data/lib/asciidoctor/iso/cleanup.rb +2 -175
- data/lib/asciidoctor/iso/converter.rb +2 -17
- data/lib/asciidoctor/iso/deprecated.rb +5 -0
- data/lib/asciidoctor/iso/front.rb +2 -169
- data/lib/asciidoctor/iso/front_id.rb +2 -224
- data/lib/asciidoctor/iso/section.rb +2 -48
- data/lib/asciidoctor/iso/validate.rb +2 -171
- data/lib/asciidoctor/iso/validate_image.rb +2 -96
- data/lib/asciidoctor/iso/validate_requirements.rb +2 -110
- data/lib/asciidoctor/iso/validate_section.rb +2 -246
- data/lib/asciidoctor/iso/validate_style.rb +2 -169
- data/lib/asciidoctor/iso/validate_title.rb +2 -104
- data/lib/isodoc/iso/html/style-human.css +19 -14
- data/lib/isodoc/iso/html/style-human.scss +8 -2
- data/lib/isodoc/iso/html/style-iso.css +21 -15
- data/lib/isodoc/iso/html/style-iso.scss +9 -2
- data/lib/isodoc/iso/html_convert.rb +6 -4
- data/lib/isodoc/iso/iso.amendment.xsl +1449 -1222
- data/lib/isodoc/iso/iso.international-standard.xsl +1449 -1222
- data/lib/isodoc/iso/word_convert.rb +2 -0
- data/lib/metanorma/iso/base.rb +70 -0
- data/lib/{asciidoctor → metanorma}/iso/basicdoc.rng +0 -0
- data/lib/{asciidoctor → metanorma}/iso/biblio.rng +2 -2
- data/lib/{asciidoctor → metanorma}/iso/boilerplate-fr.xml +0 -0
- data/lib/{asciidoctor → metanorma}/iso/boilerplate.xml +0 -0
- data/lib/metanorma/iso/cleanup.rb +176 -0
- data/lib/metanorma/iso/converter.rb +18 -0
- data/lib/metanorma/iso/front.rb +170 -0
- data/lib/metanorma/iso/front_id.rb +225 -0
- data/lib/{asciidoctor → metanorma}/iso/isodoc.rng +98 -1
- data/lib/{asciidoctor → metanorma}/iso/isostandard-amd.rng +0 -0
- data/lib/{asciidoctor → metanorma}/iso/isostandard.rnc +0 -0
- data/lib/{asciidoctor → metanorma}/iso/isostandard.rng +0 -0
- data/lib/{asciidoctor → metanorma}/iso/reqt.rng +0 -0
- data/lib/metanorma/iso/section.rb +49 -0
- data/lib/metanorma/iso/validate.rb +172 -0
- data/lib/metanorma/iso/validate_image.rb +97 -0
- data/lib/metanorma/iso/validate_requirements.rb +111 -0
- data/lib/metanorma/iso/validate_section.rb +247 -0
- data/lib/metanorma/iso/validate_style.rb +170 -0
- data/lib/metanorma/iso/validate_title.rb +105 -0
- data/lib/metanorma/iso/version.rb +1 -1
- data/lib/metanorma-iso.rb +1 -1
- data/metanorma-iso.gemspec +2 -2
- data/spec/isodoc/ref_spec.rb +4 -2
- data/spec/isodoc/section_spec.rb +1 -1
- data/spec/{asciidoctor → metanorma}/amd_spec.rb +1 -1
- data/spec/{asciidoctor → metanorma}/base_spec.rb +141 -130
- data/spec/{asciidoctor → metanorma}/blank_spec.rb +1 -1
- data/spec/{asciidoctor → metanorma}/blocks_spec.rb +1 -1
- data/spec/{asciidoctor → metanorma}/cleanup_spec.rb +1 -1
- data/spec/{asciidoctor → metanorma}/inline_spec.rb +1 -1
- data/spec/{asciidoctor → metanorma}/lists_spec.rb +1 -1
- data/spec/metanorma/processor_spec.rb +1 -1
- data/spec/{asciidoctor → metanorma}/refs_spec.rb +1 -1
- data/spec/{asciidoctor → metanorma}/section_spec.rb +1 -1
- data/spec/{asciidoctor → metanorma}/table_spec.rb +1 -1
- data/spec/{asciidoctor → metanorma}/validate_spec.rb +1 -1
- data/spec/spec_helper.rb +1 -1
- data/spec/vcr_cassettes/docrels.yml +21 -216
- metadata +39 -26
@@ -154,11 +154,13 @@ module IsoDoc
|
|
154
154
|
end
|
155
155
|
|
156
156
|
def annex_name(_annex, name, div)
|
157
|
+
preceding_floating_titles(name, div)
|
157
158
|
return if name.nil?
|
158
159
|
|
159
160
|
name&.at(ns("./strong"))&.remove # supplied by CSS list numbering
|
160
161
|
div.h1 **{ class: "Annex" } do |t|
|
161
162
|
name.children.each { |c2| parse(c2, t) }
|
163
|
+
clause_parse_subtitle(name, t)
|
162
164
|
end
|
163
165
|
end
|
164
166
|
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require "date"
|
2
|
+
require "nokogiri"
|
3
|
+
require "json"
|
4
|
+
require "pathname"
|
5
|
+
require "open-uri"
|
6
|
+
require "isodoc"
|
7
|
+
require "fileutils"
|
8
|
+
|
9
|
+
module Metanorma
|
10
|
+
module ISO
|
11
|
+
class Converter < Standoc::Converter
|
12
|
+
XML_ROOT_TAG = "iso-standard".freeze
|
13
|
+
XML_NAMESPACE = "https://www.metanorma.org/ns/iso".freeze
|
14
|
+
|
15
|
+
def html_converter(node)
|
16
|
+
IsoDoc::Iso::HtmlConvert.new(html_extract_attributes(node))
|
17
|
+
end
|
18
|
+
|
19
|
+
def html_converter_alt(node)
|
20
|
+
IsoDoc::Iso::HtmlConvert.new(html_extract_attributes(node)
|
21
|
+
.merge(alt: true))
|
22
|
+
end
|
23
|
+
|
24
|
+
def doc_converter(node)
|
25
|
+
IsoDoc::Iso::WordConvert.new(doc_extract_attributes(node))
|
26
|
+
end
|
27
|
+
|
28
|
+
def pdf_converter(node)
|
29
|
+
return nil if node.attr("no-pdf")
|
30
|
+
|
31
|
+
IsoDoc::Iso::PdfConvert.new(pdf_extract_attributes(node))
|
32
|
+
end
|
33
|
+
|
34
|
+
def sts_converter(node)
|
35
|
+
return nil if node.attr("no-pdf")
|
36
|
+
|
37
|
+
IsoDoc::Iso::StsConvert.new(html_extract_attributes(node))
|
38
|
+
end
|
39
|
+
|
40
|
+
def presentation_xml_converter(node)
|
41
|
+
IsoDoc::Iso::PresentationXMLConvert.new(html_extract_attributes(node))
|
42
|
+
end
|
43
|
+
|
44
|
+
def init(node)
|
45
|
+
super
|
46
|
+
@amd = %w(amendment technical-corrigendum).include? doctype(node)
|
47
|
+
@vocab = node.attr("docsubtype") == "vocabulary"
|
48
|
+
end
|
49
|
+
|
50
|
+
def ol_attrs(node)
|
51
|
+
attr_code(keep_attrs(node)
|
52
|
+
.merge(id: ::Metanorma::Utils::anchor_or_uuid(node)))
|
53
|
+
end
|
54
|
+
|
55
|
+
def outputs(node, ret)
|
56
|
+
File.open("#{@filename}.xml", "w:UTF-8") { |f| f.write(ret) }
|
57
|
+
presentation_xml_converter(node).convert("#{@filename}.xml")
|
58
|
+
html_converter_alt(node).convert("#{@filename}.presentation.xml",
|
59
|
+
nil, false, "#{@filename}_alt.html")
|
60
|
+
html_converter(node).convert("#{@filename}.presentation.xml",
|
61
|
+
nil, false, "#{@filename}.html")
|
62
|
+
doc_converter(node).convert("#{@filename}.presentation.xml",
|
63
|
+
nil, false, "#{@filename}.doc")
|
64
|
+
pdf_converter(node)&.convert("#{@filename}.presentation.xml",
|
65
|
+
nil, false, "#{@filename}.pdf")
|
66
|
+
# sts_converter(node)&.convert(@filename + ".xml")
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1,176 @@
|
|
1
|
+
require "date"
|
2
|
+
require "nokogiri"
|
3
|
+
require "htmlentities"
|
4
|
+
require "json"
|
5
|
+
require "pathname"
|
6
|
+
|
7
|
+
module Metanorma
|
8
|
+
module ISO
|
9
|
+
class Converter < Standoc::Converter
|
10
|
+
PRE_NORMREF_FOOTNOTES = "//preface//fn | "\
|
11
|
+
"//clause[@type = 'scope']//fn".freeze
|
12
|
+
|
13
|
+
NORMREF_FOOTNOTES =
|
14
|
+
"//references[@normative = 'true']//fn".freeze
|
15
|
+
|
16
|
+
POST_NORMREF_FOOTNOTES =
|
17
|
+
"//sections//clause[not(@type = 'scope')]//fn | "\
|
18
|
+
"//annex//fn | "\
|
19
|
+
"//references[@normative = 'false']//fn".freeze
|
20
|
+
|
21
|
+
def other_footnote_renumber(xmldoc)
|
22
|
+
seen = {}
|
23
|
+
i = 0
|
24
|
+
[PRE_NORMREF_FOOTNOTES, NORMREF_FOOTNOTES,
|
25
|
+
POST_NORMREF_FOOTNOTES].each do |xpath|
|
26
|
+
xmldoc.xpath(xpath).each do |fn|
|
27
|
+
i, seen = other_footnote_renumber1(fn, i, seen)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def id_prefix(prefix, id)
|
33
|
+
# we're just inheriting the prefixes from parent doc
|
34
|
+
return id.text if @amd
|
35
|
+
|
36
|
+
prefix.join("/") + (id.text.match?(%{^/}) ? "" : " ") + id.text
|
37
|
+
end
|
38
|
+
|
39
|
+
def get_id_prefix(xmldoc)
|
40
|
+
prefix = []
|
41
|
+
xmldoc.xpath("//bibdata/contributor[role/@type = 'publisher']"\
|
42
|
+
"/organization").each do |x|
|
43
|
+
x1 = x.at("abbreviation")&.text || x.at("name")&.text
|
44
|
+
(x1 == "ISO" and prefix.unshift("ISO")) or prefix << x1
|
45
|
+
end
|
46
|
+
prefix
|
47
|
+
end
|
48
|
+
|
49
|
+
# ISO as a prefix goes first
|
50
|
+
def docidentifier_cleanup(xmldoc)
|
51
|
+
prefix = get_id_prefix(xmldoc)
|
52
|
+
id = xmldoc.at("//bibdata/docidentifier[@type = 'ISO']") or return
|
53
|
+
id.content = id_prefix(prefix, id)
|
54
|
+
id = xmldoc.at("//bibdata/ext/structuredidentifier/project-number") and
|
55
|
+
id.content = id_prefix(prefix, id)
|
56
|
+
id = xmldoc.at("//bibdata/docidentifier[@type = 'iso-with-lang']") and
|
57
|
+
id.content = id_prefix(prefix, id)
|
58
|
+
id = xmldoc.at("//bibdata/docidentifier[@type = 'iso-reference']") and
|
59
|
+
id.content = id_prefix(prefix, id)
|
60
|
+
end
|
61
|
+
|
62
|
+
def format_ref(ref, type)
|
63
|
+
ref = ref.sub(/ \(All Parts\)/i, "")
|
64
|
+
super
|
65
|
+
end
|
66
|
+
|
67
|
+
TERM_CLAUSE =
|
68
|
+
"//sections//terms | "\
|
69
|
+
"//sections//clause[descendant::terms][not(descendant::definitions)]"
|
70
|
+
.freeze
|
71
|
+
|
72
|
+
PUBLISHER = "./contributor[role/@type = 'publisher']/organization".freeze
|
73
|
+
|
74
|
+
OTHERIDS = "@type = 'DOI' or @type = 'metanorma' or @type = 'ISSN' or "\
|
75
|
+
"@type = 'ISBN'".freeze
|
76
|
+
|
77
|
+
def pub_class(bib)
|
78
|
+
return 1 if bib.at("#{PUBLISHER}[abbreviation = 'ISO']")
|
79
|
+
return 1 if bib.at("#{PUBLISHER}[name = 'International Organization "\
|
80
|
+
"for Standardization']")
|
81
|
+
return 2 if bib.at("#{PUBLISHER}[abbreviation = 'IEC']")
|
82
|
+
return 2 if bib.at("#{PUBLISHER}[name = 'International "\
|
83
|
+
"Electrotechnical Commission']")
|
84
|
+
return 3 if bib.at("./docidentifier[@type][not(#{OTHERIDS})]")
|
85
|
+
|
86
|
+
4
|
87
|
+
end
|
88
|
+
|
89
|
+
def sort_biblio(bib)
|
90
|
+
bib.sort do |a, b|
|
91
|
+
sort_biblio_key(a) <=> sort_biblio_key(b)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
# TODO sort by authors
|
96
|
+
# sort by: doc class (ISO, IEC, other standard (not DOI &c), other
|
97
|
+
# then standard class (docid class other than DOI &c)
|
98
|
+
# then docnumber if present, numeric sort
|
99
|
+
# else alphanumeric metanorma id (abbreviation)
|
100
|
+
# then doc part number if present, numeric sort
|
101
|
+
# then doc id (not DOI &c)
|
102
|
+
# then title
|
103
|
+
def sort_biblio_key(bib)
|
104
|
+
pubclass = pub_class(bib)
|
105
|
+
num = bib&.at("./docnumber")&.text
|
106
|
+
id = bib&.at("./docidentifier[not(#{OTHERIDS})]")
|
107
|
+
metaid = bib&.at("./docidentifier[@type = 'metanorma']")&.text
|
108
|
+
abbrid = metaid unless /^\[\d+\]$/.match?(metaid)
|
109
|
+
/\d-(?<partid>\d+)/ =~ id&.text
|
110
|
+
type = id["type"] if id
|
111
|
+
title = bib&.at("./title[@type = 'main']")&.text ||
|
112
|
+
bib&.at("./title")&.text || bib&.at("./formattedref")&.text
|
113
|
+
"#{pubclass} :: #{type} :: "\
|
114
|
+
"#{num.nil? ? abbrid : sprintf('%09d', num.to_i)} :: "\
|
115
|
+
"#{sprintf('%09d', partid.to_i)} :: #{id&.text} :: #{title}"
|
116
|
+
end
|
117
|
+
|
118
|
+
def sections_cleanup(xml)
|
119
|
+
super
|
120
|
+
return unless @amd
|
121
|
+
|
122
|
+
xml.xpath("//*[@inline-header]").each do |h|
|
123
|
+
h.delete("inline-header")
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
def boilerplate_file(_xmldoc)
|
128
|
+
file = @lang == "fr" ? "boilerplate-fr.xml" : "boilerplate.xml"
|
129
|
+
File.join(@libdir, file)
|
130
|
+
end
|
131
|
+
|
132
|
+
def footnote_cleanup(xmldoc)
|
133
|
+
unpub_footnotes(xmldoc)
|
134
|
+
super
|
135
|
+
end
|
136
|
+
|
137
|
+
def unpub_footnotes(xmldoc)
|
138
|
+
xmldoc.xpath("//bibitem/note[@type = 'Unpublished-Status']").each do |n|
|
139
|
+
id = n.parent["id"]
|
140
|
+
e = xmldoc.at("//eref[@bibitemid = '#{id}']") or next
|
141
|
+
fn = n.children.to_xml
|
142
|
+
n&.elements&.first&.name == "p" or fn = "<p>#{fn}</p>"
|
143
|
+
e.next = "<fn>#{fn}</fn>"
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
def bibitem_cleanup(xmldoc)
|
148
|
+
super
|
149
|
+
unpublished_note(xmldoc)
|
150
|
+
end
|
151
|
+
|
152
|
+
def unpublished_note(xmldoc)
|
153
|
+
xmldoc.xpath("//bibitem[not(note[@type = 'Unpublished-Status'])]")
|
154
|
+
.each do |b|
|
155
|
+
next if pub_class(b) > 2
|
156
|
+
next unless (s = b.at("./status/stage")) && (s.text.to_i < 60)
|
157
|
+
|
158
|
+
id = b.at("docidentifier").text
|
159
|
+
b.at("./language | ./script | ./abstract | ./status")
|
160
|
+
.previous = %(<note type="Unpublished-Status">
|
161
|
+
<p>#{@i18n.under_preparation.sub(/%/, id)}</p></note>)
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
def termdef_boilerplate_insert(xmldoc, isodoc, once = false)
|
166
|
+
once = true
|
167
|
+
super
|
168
|
+
end
|
169
|
+
|
170
|
+
def term_defs_boilerplate_cont(src, term, isodoc)
|
171
|
+
@vocab and src.empty? and return
|
172
|
+
super
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require "asciidoctor"
|
2
|
+
require "metanorma-standoc"
|
3
|
+
require "metanorma/iso/version"
|
4
|
+
require "metanorma/iso/base"
|
5
|
+
require "metanorma/iso/front"
|
6
|
+
require "metanorma/iso/section"
|
7
|
+
require "metanorma/iso/validate"
|
8
|
+
require "metanorma/iso/cleanup"
|
9
|
+
|
10
|
+
module Metanorma
|
11
|
+
module ISO
|
12
|
+
# A {Converter} implementation that generates ISO output, and a document
|
13
|
+
# schema encapsulation of the document for validation
|
14
|
+
class Converter < ::Metanorma::Standoc::Converter
|
15
|
+
register_for "iso"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,170 @@
|
|
1
|
+
require "date"
|
2
|
+
require "nokogiri"
|
3
|
+
require "htmlentities"
|
4
|
+
require "json"
|
5
|
+
require "pathname"
|
6
|
+
require "open-uri"
|
7
|
+
require_relative "front_id"
|
8
|
+
|
9
|
+
module Metanorma
|
10
|
+
module ISO
|
11
|
+
class Converter < Standoc::Converter
|
12
|
+
def metadata_ext(node, xml)
|
13
|
+
super
|
14
|
+
structured_id(node, xml)
|
15
|
+
xml.stagename stage_name(get_stage(node), get_substage(node),
|
16
|
+
doctype(node), node.attr("iteration"))
|
17
|
+
@amd && a = node.attr("updates-document-type") and
|
18
|
+
xml.updates_document_type a
|
19
|
+
end
|
20
|
+
|
21
|
+
def metadata_subdoctype(node, xml)
|
22
|
+
super
|
23
|
+
a = node.attr("horizontal") and xml.horizontal a
|
24
|
+
end
|
25
|
+
|
26
|
+
def org_abbrev
|
27
|
+
{ "International Organization for Standardization" => "ISO",
|
28
|
+
"International Electrotechnical Commission" => "IEC" }
|
29
|
+
end
|
30
|
+
|
31
|
+
def metadata_author(node, xml)
|
32
|
+
publishers = node.attr("publisher") || "ISO"
|
33
|
+
csv_split(publishers).each do |p|
|
34
|
+
xml.contributor do |c|
|
35
|
+
c.role **{ type: "author" }
|
36
|
+
c.organization do |a|
|
37
|
+
organization(a, p, false, node, !node.attr("publisher"))
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def metadata_publisher(node, xml)
|
44
|
+
publishers = node.attr("publisher") || "ISO"
|
45
|
+
csv_split(publishers).each do |p|
|
46
|
+
xml.contributor do |c|
|
47
|
+
c.role **{ type: "publisher" }
|
48
|
+
c.organization do |a|
|
49
|
+
organization(a, p, true, node, !node.attr("publisher"))
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def metadata_copyright(node, xml)
|
56
|
+
publishers = node.attr("copyright-holder") || node.attr("publisher") ||
|
57
|
+
"ISO"
|
58
|
+
csv_split(publishers).each do |p|
|
59
|
+
xml.copyright do |c|
|
60
|
+
c.from (node.attr("copyright-year") || Date.today.year)
|
61
|
+
c.owner do |owner|
|
62
|
+
owner.organization do |o|
|
63
|
+
organization(
|
64
|
+
o, p, true, node,
|
65
|
+
!(node.attr("copyright-holder") || node.attr("publisher"))
|
66
|
+
)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def metadata_status(node, xml)
|
74
|
+
stage = get_stage(node)
|
75
|
+
substage = get_substage(node)
|
76
|
+
xml.status do |s|
|
77
|
+
s.stage stage, **attr_code(abbreviation: cover_stage_abbr(node))
|
78
|
+
s.substage substage
|
79
|
+
node.attr("iteration") && (s.iteration node.attr("iteration"))
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def metadata_committee(node, xml)
|
84
|
+
xml.editorialgroup do |a|
|
85
|
+
committee_component("technical-committee", node, a)
|
86
|
+
committee_component("subcommittee", node, a)
|
87
|
+
committee_component("workgroup", node, a)
|
88
|
+
node.attr("secretariat") && a.secretariat(node.attr("secretariat"))
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def title_intro(node, xml, lang, at)
|
93
|
+
return unless node.attr("title-intro-#{lang}")
|
94
|
+
|
95
|
+
xml.title(**attr_code(at.merge(type: "title-intro"))) do |t1|
|
96
|
+
t1 << Metanorma::Utils::asciidoc_sub(node.attr("title-intro-#{lang}"))
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def title_main(node, xml, lang, at)
|
101
|
+
xml.title **attr_code(at.merge(type: "title-main")) do |t1|
|
102
|
+
t1 << Metanorma::Utils::asciidoc_sub(node.attr("title-main-#{lang}"))
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
def title_part(node, xml, lang, at)
|
107
|
+
return unless node.attr("title-part-#{lang}")
|
108
|
+
|
109
|
+
xml.title(**attr_code(at.merge(type: "title-part"))) do |t1|
|
110
|
+
t1 << Metanorma::Utils::asciidoc_sub(node.attr("title-part-#{lang}"))
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def title_amd(node, xml, lang, at)
|
115
|
+
return unless node.attr("title-amendment-#{lang}")
|
116
|
+
|
117
|
+
xml.title(**attr_code(at.merge(type: "title-amd"))) do |t1|
|
118
|
+
t1 << Metanorma::Utils::asciidoc_sub(
|
119
|
+
node.attr("title-amendment-#{lang}"),
|
120
|
+
)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def title_full(node, xml, lang, at)
|
125
|
+
title = node.attr("title-main-#{lang}")
|
126
|
+
intro = node.attr("title-intro-#{lang}")
|
127
|
+
part = node.attr("title-part-#{lang}")
|
128
|
+
amd = node.attr("title-amendment-#{lang}")
|
129
|
+
title = "#{intro} -- #{title}" if intro
|
130
|
+
title = "#{title} -- #{part}" if part
|
131
|
+
title = "#{title} -- #{amd}" if amd && @amd
|
132
|
+
xml.title **attr_code(at.merge(type: "main")) do |t1|
|
133
|
+
t1 << Metanorma::Utils::asciidoc_sub(title)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
def title(node, xml)
|
138
|
+
["en", "fr"].each do |lang|
|
139
|
+
at = { language: lang, format: "text/plain" }
|
140
|
+
title_full(node, xml, lang, at)
|
141
|
+
title_intro(node, xml, lang, at)
|
142
|
+
title_main(node, xml, lang, at)
|
143
|
+
title_part(node, xml, lang, at)
|
144
|
+
title_amd(node, xml, lang, at) if @amd
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
def relaton_relations
|
149
|
+
super + %w(obsoletes successor-of manifestation-of related annotation-of)
|
150
|
+
end
|
151
|
+
|
152
|
+
def relaton_relation_descriptions
|
153
|
+
super.merge(
|
154
|
+
"amends" => "updates", "revises" => "updates",
|
155
|
+
"replaces" => "obsoletes",
|
156
|
+
"supersedes" => "obsoletes",
|
157
|
+
"corrects" => "updates",
|
158
|
+
"informatively-cited-in" => "isCitedIn",
|
159
|
+
"informatively-cites" => "cites",
|
160
|
+
"normatively-cited in" => "isCitedIn",
|
161
|
+
"normatively-cites" => "cites",
|
162
|
+
"identical-adopted-from" => "adoptedFrom",
|
163
|
+
"modified-adopted-from" => "adoptedFrom",
|
164
|
+
"related-directive" => "related",
|
165
|
+
"related-mandate" => "related",
|
166
|
+
)
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
@@ -0,0 +1,225 @@
|
|
1
|
+
require "date"
|
2
|
+
require "nokogiri"
|
3
|
+
require "htmlentities"
|
4
|
+
require "json"
|
5
|
+
require "pathname"
|
6
|
+
require "open-uri"
|
7
|
+
require "twitter_cldr"
|
8
|
+
|
9
|
+
module Metanorma
|
10
|
+
module ISO
|
11
|
+
class Converter < Standoc::Converter
|
12
|
+
STAGE_ABBRS = {
|
13
|
+
"00": "PWI",
|
14
|
+
"10": "NP",
|
15
|
+
"20": "WD",
|
16
|
+
"30": "CD",
|
17
|
+
"40": "DIS",
|
18
|
+
"50": "FDIS",
|
19
|
+
"60": "IS",
|
20
|
+
"90": "(Review)",
|
21
|
+
"95": "(Withdrawal)",
|
22
|
+
}.freeze
|
23
|
+
|
24
|
+
STAGE_NAMES = {
|
25
|
+
"00": "Preliminary work item",
|
26
|
+
"10": "New work item proposal",
|
27
|
+
"20": "Working draft",
|
28
|
+
"30": "Committee draft",
|
29
|
+
"40": "Draft",
|
30
|
+
"50": "Final draft",
|
31
|
+
"60": "International standard",
|
32
|
+
"90": "Review",
|
33
|
+
"95": "Withdrawal",
|
34
|
+
}.freeze
|
35
|
+
|
36
|
+
def stage_abbr(stage, substage, doctype)
|
37
|
+
return nil if stage.to_i > 60
|
38
|
+
|
39
|
+
ret = STAGE_ABBRS[stage.to_sym]
|
40
|
+
ret = "PRF" if stage == "60" && substage == "00"
|
41
|
+
ret = "AWI" if stage == "10" && substage == "99"
|
42
|
+
if %w(amendment technical-corrigendum technical-report
|
43
|
+
technical-specification).include?(doctype)
|
44
|
+
ret = "D" if stage == "40" && doctype == "amendment"
|
45
|
+
ret = "FD" if stage == "50" && %w(amendment technical-corrigendum)
|
46
|
+
.include?(doctype)
|
47
|
+
end
|
48
|
+
ret
|
49
|
+
end
|
50
|
+
|
51
|
+
def stage_name(stage, substage, _doctype, iteration = nil)
|
52
|
+
return "Proof" if stage == "60" && substage == "00"
|
53
|
+
|
54
|
+
ret = STAGE_NAMES[stage.to_sym]
|
55
|
+
if iteration && %w(20 30).include?(stage)
|
56
|
+
prefix = iteration.to_i.localize(@lang.to_sym)
|
57
|
+
.to_rbnf_s("SpelloutRules", "spellout-ordinal")
|
58
|
+
ret = "#{prefix.capitalize} #{ret.downcase}"
|
59
|
+
end
|
60
|
+
ret
|
61
|
+
end
|
62
|
+
|
63
|
+
def metadata_id(node, xml)
|
64
|
+
iso_id(node, xml)
|
65
|
+
node&.attr("tc-docnumber")&.split(/,\s*/)&.each do |n|
|
66
|
+
xml.docidentifier(n, **attr_code(type: "iso-tc"))
|
67
|
+
end
|
68
|
+
xml.docnumber node&.attr("docnumber")
|
69
|
+
end
|
70
|
+
|
71
|
+
def iso_id(node, xml)
|
72
|
+
(!@amd && node.attr("docnumber")) || (@amd && node.attr("updates")) or
|
73
|
+
return
|
74
|
+
|
75
|
+
dn = iso_id1(node)
|
76
|
+
dn1 = id_stage_prefix(dn, node, false)
|
77
|
+
dn2 = id_stage_prefix(dn, node, true)
|
78
|
+
xml.docidentifier dn1, **attr_code(type: "ISO")
|
79
|
+
xml.docidentifier(id_langsuffix(dn1, node),
|
80
|
+
**attr_code(type: "iso-with-lang"))
|
81
|
+
xml.docidentifier(id_langsuffix(dn2, node),
|
82
|
+
**attr_code(type: "iso-reference"))
|
83
|
+
end
|
84
|
+
|
85
|
+
def iso_id1(node)
|
86
|
+
if @amd
|
87
|
+
dn = node.attr("updates")
|
88
|
+
add_amd_parts(dn, node)
|
89
|
+
else
|
90
|
+
part, subpart = node&.attr("partnumber")&.split(/-/)
|
91
|
+
add_id_parts(node.attr("docnumber"), part, subpart)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def add_amd_parts(docnum, node)
|
96
|
+
case doctype(node)
|
97
|
+
when "amendment"
|
98
|
+
"#{docnum}/Amd #{node.attr('amendment-number')}"
|
99
|
+
when "technical-corrigendum"
|
100
|
+
"#{docnum}/Cor.#{node.attr('corrigendum-number')}"
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def id_langsuffix(docnum, node)
|
105
|
+
lang = node.attr("language") || "en"
|
106
|
+
suffix = case lang
|
107
|
+
when "en" then "(E)"
|
108
|
+
when "fr" then "(F)"
|
109
|
+
else
|
110
|
+
"(X)"
|
111
|
+
end
|
112
|
+
"#{docnum}#{suffix}"
|
113
|
+
end
|
114
|
+
|
115
|
+
def structured_id(node, xml)
|
116
|
+
return unless node.attr("docnumber")
|
117
|
+
|
118
|
+
part, subpart = node&.attr("partnumber")&.split(/-/)
|
119
|
+
xml.structuredidentifier do |i|
|
120
|
+
i.project_number(node.attr("docnumber"), **attr_code(
|
121
|
+
part: part, subpart: subpart,
|
122
|
+
amendment: node.attr("amendment-number"),
|
123
|
+
corrigendum: node.attr("corrigendum-number"),
|
124
|
+
origyr: node.attr("created-date")
|
125
|
+
))
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
def add_id_parts(docnum, part, subpart)
|
130
|
+
docnum += "-#{part}" if part
|
131
|
+
docnum += "-#{subpart}" if subpart
|
132
|
+
docnum
|
133
|
+
end
|
134
|
+
|
135
|
+
def id_stage_abbr(stage, substage, node, bare = false)
|
136
|
+
ret = id_stage_abbr1(stage, substage, node, bare)
|
137
|
+
if %w(amendment technical-corrigendum technical-report
|
138
|
+
technical-specification).include?(doctype(node)) &&
|
139
|
+
!%w(D FD).include?(ret)
|
140
|
+
ret = "#{ret} "
|
141
|
+
end
|
142
|
+
ret
|
143
|
+
end
|
144
|
+
|
145
|
+
def id_stage_abbr1(stage, substage, node, bare)
|
146
|
+
if bare
|
147
|
+
IsoDoc::Iso::Metadata.new("en", "Latn", @i18n)
|
148
|
+
.status_abbrev(stage_abbr(stage, substage, doctype(node)),
|
149
|
+
substage, nil, nil, doctype(node))
|
150
|
+
else
|
151
|
+
IsoDoc::Iso::Metadata.new("en", "Latn", @i18n)
|
152
|
+
.status_abbrev(stage_abbr(stage, substage, doctype(node)),
|
153
|
+
substage, node.attr("iteration"),
|
154
|
+
node.attr("draft"), doctype(node))
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
def cover_stage_abbr(node)
|
159
|
+
stage = get_stage(node)
|
160
|
+
abbr = id_stage_abbr(get_stage(node), get_substage(node), node, true)
|
161
|
+
typeabbr = get_typeabbr(node, true)
|
162
|
+
if stage.to_i > 50 || (stage.to_i == 60 && get_substage(node).to_i < 60)
|
163
|
+
typeabbr = ""
|
164
|
+
end
|
165
|
+
"#{abbr}#{typeabbr}".strip
|
166
|
+
end
|
167
|
+
|
168
|
+
def id_stage_prefix(docnum, node, force_year)
|
169
|
+
stage = get_stage(node)
|
170
|
+
typeabbr = get_typeabbr(node)
|
171
|
+
if stage && (stage.to_i < 60)
|
172
|
+
docnum = unpub_stage_prefix(docnum, stage, typeabbr, node)
|
173
|
+
elsif typeabbr == "DIR " then docnum = "#{typeabbr}#{docnum}"
|
174
|
+
elsif typeabbr && !@amd then docnum = "/#{typeabbr}#{docnum}"
|
175
|
+
end
|
176
|
+
(force_year || !(stage && (stage.to_i < 60))) and
|
177
|
+
docnum = id_add_year(docnum, node)
|
178
|
+
docnum
|
179
|
+
end
|
180
|
+
|
181
|
+
def unpub_stage_prefix(docnum, stage, typeabbr, node)
|
182
|
+
abbr = id_stage_abbr(stage, get_substage(node), node)
|
183
|
+
%w(40 50).include?(stage) && i = node.attr("iteration") and
|
184
|
+
itersuffix = ".#{i}"
|
185
|
+
return docnum if abbr.nil? || abbr.empty? # prefixes added in cleanup
|
186
|
+
return "/#{abbr}#{typeabbr} #{docnum}#{itersuffix}" unless @amd
|
187
|
+
|
188
|
+
a = docnum.split(%r{/})
|
189
|
+
a[-1] = "#{abbr}#{a[-1]}#{itersuffix}"
|
190
|
+
a.join("/")
|
191
|
+
end
|
192
|
+
|
193
|
+
def id_add_year(docnum, node)
|
194
|
+
year = node.attr("copyright-year")
|
195
|
+
@amd and year ||= node.attr("updated-date")&.sub(/-.*$/, "")
|
196
|
+
docnum += ":#{year}" if year
|
197
|
+
docnum
|
198
|
+
end
|
199
|
+
|
200
|
+
def get_stage(node)
|
201
|
+
a = node.attr("status")
|
202
|
+
a = node.attr("docstage") if a.nil? || a.empty?
|
203
|
+
a = "60" if a.nil? || a.empty?
|
204
|
+
a
|
205
|
+
end
|
206
|
+
|
207
|
+
def get_substage(node)
|
208
|
+
stage = get_stage(node)
|
209
|
+
ret = node.attr("docsubstage")
|
210
|
+
ret = (stage == "60" ? "60" : "00") if ret.nil? || ret.empty?
|
211
|
+
ret
|
212
|
+
end
|
213
|
+
|
214
|
+
def get_typeabbr(node, amd = false)
|
215
|
+
case doctype(node)
|
216
|
+
when "directive" then "DIR "
|
217
|
+
when "technical-report" then "TR "
|
218
|
+
when "technical-specification" then "TS "
|
219
|
+
when "amendment" then (amd ? "Amd " : "")
|
220
|
+
when "technical-corrigendum" then (amd ? "Cor " : "")
|
221
|
+
end
|
222
|
+
end
|
223
|
+
end
|
224
|
+
end
|
225
|
+
end
|