metanorma-standoc 1.10.3 → 1.10.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/asciidoctor/standoc/base.rb +15 -5
- data/lib/asciidoctor/standoc/blocks.rb +37 -31
- data/lib/asciidoctor/standoc/cleanup.rb +12 -69
- data/lib/asciidoctor/standoc/cleanup_block.rb +6 -3
- data/lib/asciidoctor/standoc/cleanup_maths.rb +113 -21
- data/lib/asciidoctor/standoc/cleanup_reqt.rb +60 -14
- data/lib/asciidoctor/standoc/cleanup_section.rb +1 -0
- data/lib/asciidoctor/standoc/cleanup_section_names.rb +31 -14
- data/lib/asciidoctor/standoc/cleanup_text.rb +70 -0
- data/lib/asciidoctor/standoc/converter.rb +2 -0
- data/lib/asciidoctor/standoc/isodoc.rng +29 -9
- data/lib/asciidoctor/standoc/lists.rb +9 -6
- data/lib/asciidoctor/standoc/reqt.rb +39 -27
- data/lib/asciidoctor/standoc/reqt.rng +15 -4
- data/lib/asciidoctor/standoc/table.rb +22 -20
- data/lib/asciidoctor/standoc/validate_section.rb +2 -1
- data/lib/isodoc/base.standard.xsl +6003 -0
- data/lib/isodoc/pdf_convert.rb +20 -0
- data/lib/metanorma/standoc/processor.rb +5 -1
- data/lib/metanorma/standoc/version.rb +1 -1
- data/lib/metanorma-standoc.rb +1 -0
- data/metanorma-standoc.gemspec +1 -1
- data/spec/asciidoctor/base_spec.rb +6 -0
- data/spec/asciidoctor/blocks_spec.rb +43 -23
- data/spec/asciidoctor/cleanup_sections_spec.rb +67 -1
- data/spec/asciidoctor/cleanup_spec.rb +148 -21
- data/spec/asciidoctor/isobib_cache_spec.rb +8 -8
- data/spec/asciidoctor/macros_spec.rb +114 -1
- data/spec/asciidoctor/refs_dl_spec.rb +1 -1
- data/spec/asciidoctor/refs_spec.rb +218 -442
- data/spec/asciidoctor/section_spec.rb +1 -1
- data/spec/asciidoctor/validate_spec.rb +4 -0
- data/spec/examples/datamodel/address_class_profile.adoc +1 -0
- data/spec/examples/datamodel/address_component_profile.adoc +1 -0
- data/spec/examples/datamodel/blank_definition_profile.adoc +1 -0
- data/spec/examples/datamodel/common_models_diagram.adoc +2 -1
- data/spec/examples/datamodel/top_down_diagram.adoc +2 -1
- data/spec/fixtures/datamodel_description_sections_tree.xml +326 -0
- data/spec/fixtures/test.xmi +9250 -0
- data/spec/metanorma/processor_spec.rb +50 -50
- data/spec/vcr_cassettes/dated_iso_ref_joint_iso_iec.yml +231 -143
- data/spec/vcr_cassettes/dated_iso_ref_joint_iso_iec1.yml +152 -0
- data/spec/vcr_cassettes/isobib_get_123.yml +51 -35
- data/spec/vcr_cassettes/isobib_get_123_1.yml +103 -71
- data/spec/vcr_cassettes/isobib_get_123_1_fr.yml +112 -80
- data/spec/vcr_cassettes/isobib_get_123_2001.yml +51 -35
- data/spec/vcr_cassettes/isobib_get_124.yml +51 -35
- data/spec/vcr_cassettes/rfcbib_get_rfc8341.yml +14 -14
- data/spec/vcr_cassettes/separates_iev_citations_by_top_level_clause.yml +49 -47
- metadata +10 -4
@@ -1,40 +1,42 @@
|
|
1
1
|
module Asciidoctor
|
2
2
|
module Standoc
|
3
3
|
module Cleanup
|
4
|
-
def requirement_cleanup(
|
5
|
-
|
6
|
-
|
4
|
+
def requirement_cleanup(xmldoc)
|
5
|
+
requirement_metadata(xmldoc)
|
6
|
+
requirement_descriptions(xmldoc)
|
7
|
+
requirement_inherit(xmldoc)
|
7
8
|
end
|
8
9
|
|
9
|
-
|
10
|
-
|
11
|
-
|
10
|
+
REQRECPER = "//requirement | //recommendation | //permission".freeze
|
11
|
+
|
12
|
+
def requirement_inherit(xmldoc)
|
13
|
+
xmldoc.xpath(REQRECPER).each do |r|
|
12
14
|
ins = r.at("./classification") ||
|
13
15
|
r.at("./description | ./measurementtarget | ./specification | "\
|
14
16
|
"./verification | ./import | ./description | ./requirement | "\
|
15
|
-
"./recommendation | ./permission")
|
17
|
+
"./recommendation | ./permission | ./component")
|
16
18
|
r.xpath("./*//inherit").each { |i| ins.previous = i }
|
17
19
|
end
|
18
20
|
end
|
19
21
|
|
20
|
-
def requirement_descriptions(
|
21
|
-
|
22
|
-
.each do |r|
|
22
|
+
def requirement_descriptions(xmldoc)
|
23
|
+
xmldoc.xpath(REQRECPER).each do |r|
|
23
24
|
r.children.each do |e|
|
24
25
|
unless e.element? && (reqt_subpart(e.name) ||
|
25
26
|
%w(requirement recommendation permission).include?(e.name))
|
26
|
-
|
27
|
+
next if e.text.strip.empty?
|
28
|
+
t = Nokogiri::XML::Element.new("description", r)
|
27
29
|
e.before(t)
|
28
30
|
t.children = e.remove
|
29
31
|
end
|
30
32
|
end
|
31
|
-
|
33
|
+
requirement_description_cleanup1(r)
|
32
34
|
end
|
33
35
|
end
|
34
36
|
|
35
|
-
def
|
37
|
+
def requirement_description_cleanup1(reqt)
|
36
38
|
while d = reqt.at("./description[following-sibling::*[1]"\
|
37
|
-
|
39
|
+
"[self::description]]")
|
38
40
|
n = d.next.remove
|
39
41
|
d << n.children
|
40
42
|
end
|
@@ -42,6 +44,50 @@ module Asciidoctor
|
|
42
44
|
r.replace("\n")
|
43
45
|
end
|
44
46
|
end
|
47
|
+
|
48
|
+
def requirement_metadata(xmldoc)
|
49
|
+
xmldoc.xpath(REQRECPER).each do |r|
|
50
|
+
dl = r&.at("./dl[@metadata = 'true']")&.remove or next
|
51
|
+
requirement_metadata1(r, dl)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def requirement_metadata1(reqt, dlist)
|
56
|
+
unless ins = reqt.at("./title")
|
57
|
+
reqt.children.first.previous = " "
|
58
|
+
ins = reqt.children.first
|
59
|
+
end
|
60
|
+
%w(label subject inherit).each do |a|
|
61
|
+
ins = reqt_dl_to_elems(ins, reqt, dlist, a)
|
62
|
+
end
|
63
|
+
reqt_dl_to_classif(ins, reqt, dlist)
|
64
|
+
end
|
65
|
+
|
66
|
+
def reqt_dl_to_elems(ins, reqt, dlist, name)
|
67
|
+
if a = reqt.at("./#{name}[last()]")
|
68
|
+
ins = a
|
69
|
+
end
|
70
|
+
dlist.xpath("./dt[text()='#{name}']").each do |e|
|
71
|
+
val = e.at("./following::dd/p") || e.at("./following::dd")
|
72
|
+
val.name = name
|
73
|
+
ins.next = val
|
74
|
+
ins = ins.next
|
75
|
+
end
|
76
|
+
ins
|
77
|
+
end
|
78
|
+
|
79
|
+
def reqt_dl_to_classif(ins, reqt, dlist)
|
80
|
+
if a = reqt.at("./classification[last()]")
|
81
|
+
ins = a
|
82
|
+
end
|
83
|
+
dlist.xpath("./dt[text()='classification']").each do |e|
|
84
|
+
val = e.at("./following::dd/p") || e.at("./following::dd")
|
85
|
+
req_classif_parse(val.text).each do |r|
|
86
|
+
ins.next = "<classification><tag>#{r[0]}</tag>"\
|
87
|
+
"<value>#{r[1]}</value></classification>"
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
45
91
|
end
|
46
92
|
end
|
47
93
|
end
|
@@ -37,39 +37,56 @@ module Asciidoctor
|
|
37
37
|
end
|
38
38
|
|
39
39
|
def section_names_refs_cleanup(xml)
|
40
|
-
replace_title(xml, "//references[@normative = 'true']",
|
40
|
+
replace_title(xml, "//bibliography/references[@normative = 'true']",
|
41
41
|
@i18n&.normref, true)
|
42
|
-
replace_title(xml, "//references[@normative = 'false']",
|
42
|
+
replace_title(xml, "//bibliography/references[@normative = 'false']",
|
43
43
|
@i18n&.bibliography, true)
|
44
44
|
end
|
45
45
|
|
46
46
|
NO_SYMABBR = "[.//definitions[not(@type)]]".freeze
|
47
47
|
SYMABBR = "[.//definitions[@type = 'symbols']]"\
|
48
|
-
|
48
|
+
"[.//definitions[@type = 'abbreviated_terms']]".freeze
|
49
49
|
SYMnoABBR = "[.//definitions[@type = 'symbols']]"\
|
50
|
-
|
50
|
+
"[not(.//definitions[@type = 'abbreviated_terms'])]".freeze
|
51
51
|
ABBRnoSYM = "[.//definitions[@type = 'abbreviated_terms']]"\
|
52
|
-
|
52
|
+
"[not(.//definitions[@type = 'symbols'])]".freeze
|
53
53
|
|
54
|
-
def section_names_terms_cleanup(
|
55
|
-
replace_title(
|
56
|
-
replace_title(
|
54
|
+
def section_names_terms_cleanup(xml)
|
55
|
+
replace_title(xml, "//definitions[@type = 'symbols']", @i18n&.symbols)
|
56
|
+
replace_title(xml, "//definitions[@type = 'abbreviated_terms']",
|
57
57
|
@i18n&.abbrev)
|
58
|
-
replace_title(
|
59
|
-
replace_title(
|
58
|
+
replace_title(xml, "//definitions[not(@type)]", @i18n&.symbolsabbrev)
|
59
|
+
replace_title(xml, "//terms#{SYMnoABBR} | //clause[.//terms]#{SYMnoABBR}",
|
60
60
|
@i18n&.termsdefsymbols, true)
|
61
|
-
replace_title(
|
61
|
+
replace_title(xml, "//terms#{ABBRnoSYM} | //clause[.//terms]#{ABBRnoSYM}",
|
62
62
|
@i18n&.termsdefabbrev, true)
|
63
|
-
replace_title(
|
63
|
+
replace_title(xml, "//terms#{SYMABBR} | //clause[.//terms]#{SYMABBR}",
|
64
64
|
@i18n&.termsdefsymbolsabbrev, true)
|
65
|
-
replace_title(
|
65
|
+
replace_title(xml, "//terms#{NO_SYMABBR} | //clause[.//terms]#{NO_SYMABBR}",
|
66
66
|
@i18n&.termsdefsymbolsabbrev, true)
|
67
67
|
replace_title(
|
68
|
-
|
68
|
+
xml,
|
69
69
|
"//terms[not(.//definitions)] | //clause[.//terms][not(.//definitions)]",
|
70
70
|
@i18n&.termsdef, true
|
71
71
|
)
|
72
72
|
end
|
73
|
+
|
74
|
+
SECTION_CONTAINERS = %w(foreword introduction acknowledgements abstract
|
75
|
+
clause clause references terms definitions annex
|
76
|
+
appendix).freeze
|
77
|
+
|
78
|
+
def sections_variant_title_cleanup(xml)
|
79
|
+
path = SECTION_CONTAINERS.map { |x| "./ancestor::#{x}" }.join(" | ")
|
80
|
+
xml.xpath("//p[@variant_title]").each do |p|
|
81
|
+
p.xpath("(#{path})[last()]").each do |sect|
|
82
|
+
p.name = "variant-title"
|
83
|
+
p.delete("id")
|
84
|
+
if ins = sect.at("./title") then ins.next = p
|
85
|
+
else sect.children.first.previous = p
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
73
90
|
end
|
74
91
|
end
|
75
92
|
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module Asciidoctor
|
2
|
+
module Standoc
|
3
|
+
module Cleanup
|
4
|
+
def textcleanup(result)
|
5
|
+
text = result.flatten.map { |l| l.sub(/\s*$/, "") } * "\n"
|
6
|
+
!@keepasciimath and text = asciimath2mathml(text)
|
7
|
+
text = text.gsub(/\s+<fn /, "<fn ")
|
8
|
+
text.gsub(%r{<passthrough\s+formats="metanorma">([^<]*)
|
9
|
+
</passthrough>}mx) { HTMLEntities.new.decode($1) }
|
10
|
+
end
|
11
|
+
|
12
|
+
IGNORE_DUMBQUOTES = "//pre | //pre//* | //tt | //tt//* | "\
|
13
|
+
"//sourcecode | //sourcecode//* | //bibdata//* | //stem | "\
|
14
|
+
"//stem//* | //figure[@class = 'pseudocode'] | "\
|
15
|
+
"//figure[@class = 'pseudocode']//*".freeze
|
16
|
+
|
17
|
+
def smartquotes_cleanup(xmldoc)
|
18
|
+
xmldoc.xpath("//date").each { |d| Metanorma::Utils::endash_date(d) }
|
19
|
+
if @smartquotes then smartquotes_cleanup1(xmldoc)
|
20
|
+
else dumbquote_cleanup(xmldoc)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def smartquotes_cleanup1(xmldoc)
|
25
|
+
uninterrupt_quotes_around_xml(xmldoc)
|
26
|
+
dumb2smart_quotes(xmldoc)
|
27
|
+
end
|
28
|
+
|
29
|
+
# "abc<tag/>", def => "abc",<tag/> def
|
30
|
+
def uninterrupt_quotes_around_xml(xmldoc)
|
31
|
+
xmldoc.xpath("//*[following::text()[1]"\
|
32
|
+
"[starts-with(., '\"') or starts-with(., \"'\")]]")
|
33
|
+
.each do |x|
|
34
|
+
next if !x.ancestors("pre, tt, sourcecode, stem, figure").empty?
|
35
|
+
uninterrupt_quotes_around_xml1(x)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def uninterrupt_quotes_around_xml1(elem)
|
40
|
+
prev = elem.at(".//preceding::text()[1]") or return
|
41
|
+
/\S$/.match?(prev.text) or return
|
42
|
+
foll = elem.at(".//following::text()[1]")
|
43
|
+
m = /^(["'][[:punct:]]*)(\s|$)/.match(HTMLEntities.new.decode(foll&.text)) or return
|
44
|
+
foll.content = foll.text.sub(/^(["'][[:punct:]]*)/, "")
|
45
|
+
prev.content = "#{prev.text}#{m[1]}"
|
46
|
+
end
|
47
|
+
|
48
|
+
def dumb2smart_quotes(xmldoc)
|
49
|
+
(xmldoc.xpath("//*[child::text()]") - xmldoc.xpath(IGNORE_DUMBQUOTES))
|
50
|
+
.each do |x|
|
51
|
+
x.children.each do |n|
|
52
|
+
next unless n.text?
|
53
|
+
|
54
|
+
/[-'"(<>]|\.\.|\dx/.match(n) or next
|
55
|
+
|
56
|
+
n.replace(Metanorma::Utils::smartformat(n.text))
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def dumbquote_cleanup(xmldoc)
|
62
|
+
xmldoc.traverse do |n|
|
63
|
+
next unless n.text?
|
64
|
+
|
65
|
+
n.replace(n.text.gsub(/(?<=\p{Alnum})\u2019(?=\p{Alpha})/, "'")) # .
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -27,6 +27,7 @@ module Asciidoctor
|
|
27
27
|
preprocessor Metanorma::Plugin::Datastruct::Yaml2TextPreprocessor
|
28
28
|
preprocessor Metanorma::Plugin::Lutaml::LutamlPreprocessor
|
29
29
|
preprocessor Metanorma::Plugin::Lutaml::LutamlUmlAttributesTablePreprocessor
|
30
|
+
preprocessor Metanorma::Plugin::Lutaml::LutamlUmlDatamodelDescriptionPreprocessor
|
30
31
|
inline_macro Asciidoctor::Standoc::AltTermInlineMacro
|
31
32
|
inline_macro Asciidoctor::Standoc::DeprecatedTermInlineMacro
|
32
33
|
inline_macro Asciidoctor::Standoc::DomainTermInlineMacro
|
@@ -48,6 +49,7 @@ module Asciidoctor
|
|
48
49
|
inline_macro Asciidoctor::Standoc::FormSelectMacro
|
49
50
|
inline_macro Asciidoctor::Standoc::FormOptionMacro
|
50
51
|
inline_macro Asciidoctor::Standoc::ToCInlineMacro
|
52
|
+
inline_macro Metanorma::Plugin::Lutaml::LutamlFigureInlineMacro
|
51
53
|
block_macro Metanorma::Plugin::Lutaml::LutamlDiagramBlockMacro
|
52
54
|
block Asciidoctor::Standoc::ToDoAdmonitionBlock
|
53
55
|
treeprocessor Asciidoctor::Standoc::ToDoInlineAdmonitionBlock
|
@@ -32,6 +32,18 @@
|
|
32
32
|
<ref name="DocumentType"/>
|
33
33
|
</element>
|
34
34
|
</define>
|
35
|
+
<define name="section-title">
|
36
|
+
<element name="title">
|
37
|
+
<zeroOrMore>
|
38
|
+
<ref name="TextElement"/>
|
39
|
+
</zeroOrMore>
|
40
|
+
</element>
|
41
|
+
<zeroOrMore>
|
42
|
+
<element name="variant-title">
|
43
|
+
<ref name="TypedTitleString"/>
|
44
|
+
</element>
|
45
|
+
</zeroOrMore>
|
46
|
+
</define>
|
35
47
|
<define name="hyperlink">
|
36
48
|
<element name="link">
|
37
49
|
<attribute name="target">
|
@@ -158,15 +170,17 @@
|
|
158
170
|
<data type="boolean"/>
|
159
171
|
</attribute>
|
160
172
|
</optional>
|
161
|
-
<
|
162
|
-
<
|
163
|
-
<
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
173
|
+
<optional>
|
174
|
+
<attribute name="type">
|
175
|
+
<choice>
|
176
|
+
<value>roman</value>
|
177
|
+
<value>alphabet</value>
|
178
|
+
<value>arabic</value>
|
179
|
+
<value>roman_upper</value>
|
180
|
+
<value>alphabet_upper</value>
|
181
|
+
</choice>
|
182
|
+
</attribute>
|
183
|
+
</optional>
|
170
184
|
<oneOrMore>
|
171
185
|
<ref name="li"/>
|
172
186
|
</oneOrMore>
|
@@ -1011,8 +1025,14 @@
|
|
1011
1025
|
<ref name="imagemap"/>
|
1012
1026
|
<ref name="svgmap"/>
|
1013
1027
|
<ref name="inputform"/>
|
1028
|
+
<ref name="toc"/>
|
1014
1029
|
</choice>
|
1015
1030
|
</define>
|
1031
|
+
<define name="toc">
|
1032
|
+
<element name="toc">
|
1033
|
+
<ref name="ul"/>
|
1034
|
+
</element>
|
1035
|
+
</define>
|
1016
1036
|
<define name="inputform">
|
1017
1037
|
<element name="form">
|
1018
1038
|
<attribute name="id">
|
@@ -31,7 +31,7 @@ module Asciidoctor
|
|
31
31
|
c = node.attr?("checked")
|
32
32
|
attr_code(
|
33
33
|
uncheckedcheckbox: node.attr?("checkbox") ? !c : nil,
|
34
|
-
checkedcheckbox: node.attr?("checkbox") ? c : nil
|
34
|
+
checkedcheckbox: node.attr?("checkbox") ? c : nil,
|
35
35
|
)
|
36
36
|
end
|
37
37
|
|
@@ -52,12 +52,14 @@ module Asciidoctor
|
|
52
52
|
return "roman" if style == "lowerroman"
|
53
53
|
return "roman_upper" if style == "upperroman"
|
54
54
|
return "alphabet_upper" if style == "upperalpha"
|
55
|
+
|
55
56
|
style
|
56
57
|
end
|
57
58
|
|
58
59
|
def ol_attrs(node)
|
59
|
-
attr_code(keep_attrs(node)
|
60
|
-
|
60
|
+
attr_code(keep_attrs(node)
|
61
|
+
.merge(id: Metanorma::Utils::anchor_or_uuid(node),
|
62
|
+
type: olist_style(node.style)))
|
61
63
|
end
|
62
64
|
|
63
65
|
def olist(node)
|
@@ -89,9 +91,10 @@ module Asciidoctor
|
|
89
91
|
end
|
90
92
|
|
91
93
|
def dl_attrs(node)
|
92
|
-
attr_code(keep_attrs(node)
|
93
|
-
merge(id: Metanorma::Utils::anchor_or_uuid(node),
|
94
|
-
|
94
|
+
attr_code(keep_attrs(node)
|
95
|
+
.merge(id: Metanorma::Utils::anchor_or_uuid(node),
|
96
|
+
metadata: node.option?("metadata") ? "true" : nil,
|
97
|
+
key: node.option?("key") ? "true" : nil))
|
95
98
|
end
|
96
99
|
|
97
100
|
def dlist(node)
|
@@ -6,20 +6,23 @@ require "base64"
|
|
6
6
|
module Asciidoctor
|
7
7
|
module Standoc
|
8
8
|
module Blocks
|
9
|
-
def reqt_subpart(
|
9
|
+
def reqt_subpart(name)
|
10
10
|
%w(specification measurement-target verification import label
|
11
|
-
|
11
|
+
component subject inherit classification title).include? name
|
12
12
|
end
|
13
13
|
|
14
|
-
def reqt_subpart_attrs(node)
|
15
|
-
|
16
|
-
|
14
|
+
def reqt_subpart_attrs(node, name)
|
15
|
+
klass = node.attr("class") || "component"
|
16
|
+
attr_code(keep_attrs(node)
|
17
|
+
.merge(exclude: node.option?("exclude"),
|
18
|
+
type: node.attr("type"),
|
19
|
+
class: name == "component" ? klass : nil))
|
17
20
|
end
|
18
21
|
|
19
22
|
def requirement_subpart(node)
|
20
23
|
name = node.role || node.attr("style")
|
21
24
|
noko do |xml|
|
22
|
-
xml.send name, **reqt_subpart_attrs(node) do |o|
|
25
|
+
xml.send name, **reqt_subpart_attrs(node, name) do |o|
|
23
26
|
o << node.content
|
24
27
|
end
|
25
28
|
end
|
@@ -30,14 +33,15 @@ module Asciidoctor
|
|
30
33
|
HTMLEntities.new.decode(classif).split(/;\s*/).each do |c|
|
31
34
|
c1 = c.split(/:\s*/)
|
32
35
|
next unless c1.size == 2
|
33
|
-
|
36
|
+
|
37
|
+
c1[1].split(/,\s*/).each { |v| ret << [c1[0], v] }
|
34
38
|
end
|
35
39
|
ret
|
36
40
|
end
|
37
41
|
|
38
|
-
def requirement_classification(classif,
|
42
|
+
def requirement_classification(classif, out)
|
39
43
|
req_classif_parse(classif).each do |r|
|
40
|
-
|
44
|
+
out.classification do |c|
|
41
45
|
c.tag { |t| t << r[0] }
|
42
46
|
c.value { |v| v << r[1] }
|
43
47
|
end
|
@@ -46,29 +50,37 @@ module Asciidoctor
|
|
46
50
|
|
47
51
|
def reqt_attrs(node)
|
48
52
|
attr_code(keep_attrs(node).merge(id_unnum_attrs(node)).merge(
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
53
|
+
id: Metanorma::Utils::anchor_or_uuid(node),
|
54
|
+
unnumbered: node.option?("unnumbered") ? "true" : nil,
|
55
|
+
number: node.attr("number"),
|
56
|
+
subsequence: node.attr("subsequence"),
|
57
|
+
obligation: node.attr("obligation"),
|
58
|
+
filename: node.attr("filename"),
|
59
|
+
type: node.attr("type"),
|
60
|
+
model: node.attr("model"),
|
61
|
+
))
|
62
|
+
end
|
63
|
+
|
64
|
+
def requirement_elems(node, out)
|
65
|
+
node.title and out.title { |t| t << node.title }
|
66
|
+
a = node.attr("label") and out.label do |l|
|
67
|
+
l << a
|
68
|
+
end
|
69
|
+
a = node.attr("subject") and csv_split(a)&.each do |subj|
|
70
|
+
out.subject { |s| s << subj }
|
71
|
+
end
|
72
|
+
a = HTMLEntities.new.decode(node.attr("inherit")) and
|
73
|
+
csv_split(a)&.each do |i|
|
74
|
+
out.inherit { |inh| inh << i }
|
75
|
+
end
|
76
|
+
classif = node.attr("classification") and
|
77
|
+
requirement_classification(classif, out)
|
58
78
|
end
|
59
79
|
|
60
80
|
def requirement(node, obligation)
|
61
|
-
classif = node.attr("classification")
|
62
81
|
noko do |xml|
|
63
82
|
xml.send obligation, **reqt_attrs(node) do |ex|
|
64
|
-
node
|
65
|
-
node.attr("label") and ex.label { |l| l << node.attr("label") }
|
66
|
-
node.attr("subject") and ex.subject { |s| s << node.attr("subject") }
|
67
|
-
i = HTMLEntities.new.decode(node.attr("inherit"))
|
68
|
-
i&.split(/;\s*/)&.each do |i|
|
69
|
-
ex.inherit { |inh| inh << i }
|
70
|
-
end
|
71
|
-
requirement_classification(classif, ex) if classif
|
83
|
+
requirement_elems(node, ex)
|
72
84
|
wrap_in_para(node, ex)
|
73
85
|
end
|
74
86
|
end.join("\n")
|