metanorma-standoc 3.1.3 → 3.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/lib/metanorma/standoc/biblio-standoc.rng +0 -49
- data/lib/metanorma/standoc/biblio.rng +11 -1
- data/lib/metanorma/standoc/blocks_notes.rb +1 -0
- data/lib/metanorma/standoc/cleanup.rb +4 -1
- data/lib/metanorma/standoc/cleanup_bibdata.rb +16 -1
- data/lib/metanorma/standoc/cleanup_boilerplate.rb +62 -16
- data/lib/metanorma/standoc/cleanup_maths.rb +2 -1
- data/lib/metanorma/standoc/converter.rb +1 -0
- data/lib/metanorma/standoc/front.rb +0 -8
- data/lib/metanorma/standoc/front_committee.rb +138 -0
- data/lib/metanorma/standoc/front_contributor.rb +2 -0
- data/lib/metanorma/standoc/front_organisation.rb +24 -18
- data/lib/metanorma/standoc/isodoc.rng +6 -1
- data/lib/metanorma/standoc/ref_queue.rb +1 -1
- data/lib/metanorma/standoc/ref_utility.rb +27 -2
- data/lib/metanorma/standoc/regex.rb +6 -5
- data/lib/metanorma/standoc/sectiontype.rb +1 -0
- data/lib/metanorma/standoc/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 07dd4263f3139ccb6d6f742e52e7ccf48a4d5f585dc442fd4fe22019f68a2173
|
4
|
+
data.tar.gz: 013cd7e28bb591c2b09b138de8debe85831bc30460ed6192aae2dd9d4434de89
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4a856c20cb73fb75982c1e473d5d959e1aeed8cd1354eb53af33d612d8769e03b4f85229bfd93adaafb0840e1a4071eca7c99e49e4ed5ae0dd2211e55d6ec8fa
|
7
|
+
data.tar.gz: bcc1fa89fe0ddd3b33c0bf9d0bd7696a1668a9d123b289aff61d4f82969bcdc54c7dc0088e7debb3d3256221eefbc5609b8e0ac3d074c62dfcbde826e5b995e7
|
@@ -76,12 +76,6 @@ from other documents in the same doctype</a:documentation>
|
|
76
76
|
<ref name="flavor">
|
77
77
|
<a:documentation>Flavour of Metanorma used to process this document</a:documentation>
|
78
78
|
</ref>
|
79
|
-
<optional>
|
80
|
-
<ref name="editorialgroup">
|
81
|
-
<a:documentation>Groups associated with the production of the standards document, typically within
|
82
|
-
a standards definition organization</a:documentation>
|
83
|
-
</ref>
|
84
|
-
</optional>
|
85
79
|
<zeroOrMore>
|
86
80
|
<ref name="ics">
|
87
81
|
<a:documentation>Classification of the document contents taken from the International Classification of Standards</a:documentation>
|
@@ -130,49 +124,6 @@ a standards definition organization</a:documentation>
|
|
130
124
|
However we prefer not to hardcode it, given ongoing extension.</a:documentation>
|
131
125
|
<text/>
|
132
126
|
</define>
|
133
|
-
<define name="editorialgroup">
|
134
|
-
<a:documentation>A group associated with the production of the standards document, typically within
|
135
|
-
a standards definition organization</a:documentation>
|
136
|
-
<element name="editorialgroup">
|
137
|
-
<oneOrMore>
|
138
|
-
<ref name="technical-committee">
|
139
|
-
<a:documentation>A technical committee associated with the production of the standards document</a:documentation>
|
140
|
-
</ref>
|
141
|
-
</oneOrMore>
|
142
|
-
</element>
|
143
|
-
</define>
|
144
|
-
<define name="technical-committee">
|
145
|
-
<a:documentation>Technical committee associated with the production of a standards document</a:documentation>
|
146
|
-
<element name="technical-committee">
|
147
|
-
<ref name="IsoWorkgroup"/>
|
148
|
-
</element>
|
149
|
-
</define>
|
150
|
-
<define name="IsoWorkgroup">
|
151
|
-
<optional>
|
152
|
-
<attribute name="number">
|
153
|
-
<a:documentation>Numeric identifier of the technical committee</a:documentation>
|
154
|
-
</attribute>
|
155
|
-
</optional>
|
156
|
-
<optional>
|
157
|
-
<attribute name="type">
|
158
|
-
<a:documentation>Type of the technical committee, used in identifying the technical committee</a:documentation>
|
159
|
-
</attribute>
|
160
|
-
</optional>
|
161
|
-
<optional>
|
162
|
-
<attribute name="identifier">
|
163
|
-
<a:documentation>Non-numeric, complete identifier of the technical committee</a:documentation>
|
164
|
-
</attribute>
|
165
|
-
</optional>
|
166
|
-
<optional>
|
167
|
-
<attribute name="prefix">
|
168
|
-
<a:documentation>Disambiguating prefix added to number to form the identifier of the technical committee,
|
169
|
-
typically indicating its type</a:documentation>
|
170
|
-
</attribute>
|
171
|
-
</optional>
|
172
|
-
<text>
|
173
|
-
<a:documentation>Name of the technical committee</a:documentation>
|
174
|
-
</text>
|
175
|
-
</define>
|
176
127
|
<define name="ics">
|
177
128
|
<a:documentation>Classification taken from the International Classification of Standards.
|
178
129
|
ICS is defined by ISO here -- https://www.iso.org/publication/PUB100033.html</a:documentation>
|
@@ -242,6 +242,8 @@ Detailed in https://www.relaton.org/model/creator/</a:documentation>
|
|
242
242
|
</choice>
|
243
243
|
</define>
|
244
244
|
<define name="roledescription">
|
245
|
+
<a:documentation>A more detailed description of the role of the contributor
|
246
|
+
Some descriptions are reserved words; in particular, the editorial committee of a standard has the role description "committee"</a:documentation>
|
245
247
|
<element name="description">
|
246
248
|
<ref name="LocalizedMarkedUpString"/>
|
247
249
|
</element>
|
@@ -443,7 +445,10 @@ real names (if the person is named with a pseudonym or user name); previous lega
|
|
443
445
|
</oneOrMore>
|
444
446
|
<zeroOrMore>
|
445
447
|
<ref name="subdivision">
|
446
|
-
<a:documentation>The subdivision of the organization directly involved with the production of the bibliographic item
|
448
|
+
<a:documentation>The subdivision of the organization directly involved with the production of the bibliographic item.
|
449
|
+
Multiple subdivisions can be specified for an organization, with no implication of hierarchical
|
450
|
+
relation between them
|
451
|
+
Editorial and advisory groups are represented as consecutive subdivisions of the SDO</a:documentation>
|
447
452
|
</ref>
|
448
453
|
</zeroOrMore>
|
449
454
|
<optional>
|
@@ -485,6 +490,11 @@ real names (if the person is named with a pseudonym or user name); previous lega
|
|
485
490
|
<a:documentation>The type of subdivision</a:documentation>
|
486
491
|
</attribute>
|
487
492
|
</optional>
|
493
|
+
<optional>
|
494
|
+
<attribute name="subtype">
|
495
|
+
<a:documentation>The subtype of subdivision; e.g. different types of technical committee</a:documentation>
|
496
|
+
</attribute>
|
497
|
+
</optional>
|
488
498
|
<ref name="OrganizationType">
|
489
499
|
<a:documentation>The subdivision, modelled recursively as an organization</a:documentation>
|
490
500
|
</ref>
|
@@ -33,7 +33,8 @@ module Metanorma
|
|
33
33
|
passthrough_cleanup(xmldoc) # feeds: smartquotes_cleanup
|
34
34
|
unnumbered_blocks_cleanup(xmldoc)
|
35
35
|
termdocsource_cleanup(xmldoc) # feeds: metadata_cleanup
|
36
|
-
metadata_cleanup(xmldoc) # feeds: boilerplate_cleanup
|
36
|
+
metadata_cleanup(xmldoc) # feeds: boilerplate_cleanup, bibdata_cleanup,
|
37
|
+
# docidentifier_cleanup (in generic: template)
|
37
38
|
misccontainer_cleanup(xmldoc)
|
38
39
|
sections_cleanup(xmldoc) # feeds: obligations_cleanup, toc_cleanup,
|
39
40
|
# floatingtitle_cleanup
|
@@ -202,6 +203,8 @@ module Metanorma
|
|
202
203
|
end
|
203
204
|
|
204
205
|
def metadata_cleanup(xmldoc)
|
206
|
+
bibdata_published(xmldoc) # feeds: bibdata_cleanup,
|
207
|
+
# docidentifier_cleanup (in generic: template)
|
205
208
|
(@metadata_attrs.nil? || @metadata_attrs.empty?) and return
|
206
209
|
ins = add_misc_container(xmldoc)
|
207
210
|
ins << @metadata_attrs
|
@@ -59,7 +59,7 @@ module Metanorma
|
|
59
59
|
end
|
60
60
|
end
|
61
61
|
|
62
|
-
def indirect_eref_to_xref(eref, ident, id_map=nil)
|
62
|
+
def indirect_eref_to_xref(eref, ident, id_map = nil)
|
63
63
|
loc = eref.at("./localityStack[locality[@type = 'anchor']]") ||
|
64
64
|
eref.at("./locality[@type = 'anchor']")
|
65
65
|
loc = loc&.remove&.text || ident
|
@@ -72,6 +72,7 @@ module Metanorma
|
|
72
72
|
else
|
73
73
|
eref.document.at("//*[@anchor = '#{loc}']") and return
|
74
74
|
end
|
75
|
+
|
75
76
|
eref.children = %(** Missing target #{loc})
|
76
77
|
eref["target"] = ident
|
77
78
|
end
|
@@ -181,6 +182,20 @@ module Metanorma
|
|
181
182
|
ins.next = c
|
182
183
|
end
|
183
184
|
end
|
185
|
+
|
186
|
+
def bibdata_published(xmldoc)
|
187
|
+
ins = add_misc_container(xmldoc)
|
188
|
+
ins ||= add_misc_container(xmldoc)
|
189
|
+
ins.at("./semantic-metadata/stage-published") and return
|
190
|
+
p = published?(xmldoc.at("bibdata/status/stage")&.text, xmldoc)
|
191
|
+
ins << <<~XML
|
192
|
+
<semantic-metadata><stage-published>#{p}</stage-published></semantic-metadata>
|
193
|
+
XML
|
194
|
+
end
|
195
|
+
|
196
|
+
def published?(stage, _xmldoc)
|
197
|
+
stage.casecmp("published").zero?
|
198
|
+
end
|
184
199
|
end
|
185
200
|
end
|
186
201
|
end
|
@@ -162,25 +162,64 @@ module Metanorma
|
|
162
162
|
end
|
163
163
|
end
|
164
164
|
|
165
|
-
#
|
166
|
-
#
|
167
|
-
#
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
#
|
172
|
-
#
|
173
|
-
#
|
174
|
-
#
|
165
|
+
# The boilerplate file is in Liquid AsciiDoc format
|
166
|
+
# (technically, `boilerplate.adoc.liquid`).
|
167
|
+
#
|
168
|
+
# This file is processed separately from the main Metanorma document and
|
169
|
+
# therefore is oblivious of the `{{ concept-mention }}` syntax.
|
170
|
+
#
|
171
|
+
# Due to historic reasons, the Liquid objects being evaluated in the
|
172
|
+
# boilerplate document are XML strings. Notably these are the document
|
173
|
+
# metadata, that are extracted from the already generated Metanorma XML.
|
174
|
+
#
|
175
|
+
# These XML strings are then passed into the AsciiDoc macros such as
|
176
|
+
# `span:publisher[...]`.
|
177
|
+
#
|
178
|
+
# Here, we need to interpolate the XML strings into the AsciiDoc macros
|
179
|
+
# without breaking the AsciiDoc syntax.
|
180
|
+
#
|
181
|
+
# EXAMPLE 1: `mailto:{{ pub_email }}[]`, we need to
|
182
|
+
# convert it to:
|
183
|
+
# `mailto:{{ pass-format:metanorma[++pub_email_xml++] }}[]`
|
184
|
+
#
|
185
|
+
# EXAMPLE 2: `link:{{ pub_uri}}[{{ pub_address }}, {{ pub_uri }}]`
|
186
|
+
# We need to convert it to:
|
187
|
+
# `link:{{ pass-format:metanorma[++pub_uri_xml++] }}[{{
|
188
|
+
# pass-format:metanorma[++pub_address_xml++] }}, {{
|
189
|
+
# pass-format:metanorma[++pub_uri_xml++] }}]`
|
190
|
+
#
|
191
|
+
# NOTE: The boilerplate may use macros that contain one or more
|
192
|
+
# `{{ ... }}` in the target, and can contain spaces in them.
|
193
|
+
#
|
194
|
+
# NOTE: The routine needs to handle cases where the content
|
195
|
+
# contains an escaped closing bracket `\]`.
|
196
|
+
|
197
|
+
ADOC_MACRO_PATTERN = /\S+:[^\[\n]*\[[^\]\\]*(?:\\.[^\]\\]*)*\]/
|
198
|
+
|
199
|
+
# Replace {{ ... }} with {{ pass-format:metanorma:[...] }} to preserve any
|
200
|
+
# XML markup provided by Metanorma XML Metadata content, through the
|
201
|
+
# `pass-format:metanorma` command.
|
202
|
+
#
|
203
|
+
# * If `{{ ... }}` is inside an Asciidoc macro, we have to wrap with
|
204
|
+
# pass-format:metanorma:[...\].
|
205
|
+
# * If this is a macro target (e.g. `mailto:{{x}}[]`, body: mailto:[{{x}}])
|
206
|
+
# then do not use pass-format:metanorma.
|
207
|
+
|
175
208
|
def boilerplate_read(file)
|
176
209
|
ret = File.read(file, encoding: "UTF-8")
|
177
|
-
/\.adoc
|
178
|
-
|
179
|
-
|
180
|
-
|
210
|
+
/\.adoc(\.liquid)?$/.match?(file) or return ret
|
211
|
+
|
212
|
+
# Split content into macro and non-macro parts
|
213
|
+
parts = ret.split(/(#{ADOC_MACRO_PATTERN})/)
|
214
|
+
|
215
|
+
parts.map.with_index do |part, index|
|
216
|
+
if index.odd? && is_valid_macro?(part)
|
217
|
+
# This is a macro - leave unchanged
|
218
|
+
part
|
181
219
|
else
|
182
|
-
|
183
|
-
|
220
|
+
# Not a macro - wrap {{ }} patterns
|
221
|
+
part.gsub(/(?<!\{)(\{\{[^{}]+\}\})(?!\})/,
|
222
|
+
"pass-format:metanorma[++\\1++]")
|
184
223
|
end
|
185
224
|
end.join
|
186
225
|
end
|
@@ -199,6 +238,13 @@ module Metanorma
|
|
199
238
|
ret
|
200
239
|
end
|
201
240
|
|
241
|
+
private
|
242
|
+
|
243
|
+
def is_valid_macro?(text)
|
244
|
+
# Simple validation - does it look like a macro?
|
245
|
+
text.match?(/^\S+:[^\[]*\[.*\]$/)
|
246
|
+
end
|
247
|
+
|
202
248
|
# remove Metanorma namespace, so generated doc containing boilerplate
|
203
249
|
# can be queried consistently
|
204
250
|
# _\d+ anchor is assigned to titleless clauses, will clash with main doc
|
@@ -96,7 +96,8 @@ module Metanorma
|
|
96
96
|
|
97
97
|
def add_misc_container(xmldoc)
|
98
98
|
unless ins = xmldoc.at("//metanorma-extension")
|
99
|
-
a = xmldoc.xpath("//termdocsource")&.last || xmldoc.at("//bibdata")
|
99
|
+
a = xmldoc.xpath("//termdocsource")&.last || xmldoc.at("//bibdata") ||
|
100
|
+
xmldoc.root.children.first
|
100
101
|
a.next = "<metanorma-extension/>"
|
101
102
|
ins = xmldoc.at("//metanorma-extension")
|
102
103
|
end
|
@@ -33,6 +33,7 @@ module Metanorma
|
|
33
33
|
block_macro Metanorma::Plugin::Lutaml::LutamlGmlDictionaryBlockMacro
|
34
34
|
block Metanorma::Plugin::Lutaml::LutamlGmlDictionaryBlock
|
35
35
|
block_macro Metanorma::Plugin::Lutaml::LutamlKlassTableBlockMacro
|
36
|
+
block_macro Metanorma::Plugin::Lutaml::LutamlEnumTableBlockMacro
|
36
37
|
preprocessor Metanorma::Standoc::EmbedIncludeProcessor
|
37
38
|
preprocessor Metanorma::Standoc::LinkProtectPreprocessor
|
38
39
|
preprocessor Metanorma::Standoc::PassProtectPreprocessor
|
@@ -53,13 +53,6 @@ module Metanorma
|
|
53
53
|
end
|
54
54
|
end
|
55
55
|
|
56
|
-
def metadata_committee(node, xml)
|
57
|
-
node.attr("technical-committee") or return
|
58
|
-
xml.editorialgroup do |a|
|
59
|
-
committee_component("technical-committee", node, a)
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
56
|
def metadata_ics(node, xml)
|
64
57
|
ics = node.attr("library-ics")
|
65
58
|
ics&.split(/,\s*/)&.each do |i|
|
@@ -194,7 +187,6 @@ module Metanorma
|
|
194
187
|
metadata_doctype(node, ext)
|
195
188
|
metadata_subdoctype(node, ext)
|
196
189
|
metadata_flavor(node, ext)
|
197
|
-
metadata_committee(node, ext)
|
198
190
|
metadata_ics(node, ext)
|
199
191
|
structured_id(node, ext)
|
200
192
|
metadata_coverpage_images(node, ext)
|
@@ -0,0 +1,138 @@
|
|
1
|
+
module Metanorma
|
2
|
+
module Standoc
|
3
|
+
module Front
|
4
|
+
def committee_number_or_name?(node, type, suffix)
|
5
|
+
node.attr("#{type}-number#{suffix}") || node.attr("#{type}#{suffix}")
|
6
|
+
end
|
7
|
+
|
8
|
+
def committee_contributors(node, xml, agency, _opts)
|
9
|
+
t = metadata_committee_types(node)
|
10
|
+
v = t.first
|
11
|
+
if committee_number_or_name?(node, v, "")
|
12
|
+
node.attr(v) or node.set_attr(v, "")
|
13
|
+
o = committee_contrib_org_prep(node, v, agency, _opts)
|
14
|
+
o[:groups] = t
|
15
|
+
org_contributor(node, xml, o)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def metadata_committee_types(_node)
|
20
|
+
%w(technical-committee)
|
21
|
+
end
|
22
|
+
|
23
|
+
def committee_contrib_org_prep(node, type, agency, _opts)
|
24
|
+
agency_arr, agency_abbrev =
|
25
|
+
committee_org_prep_agency(node, type, agency, [], [])
|
26
|
+
{ source: [type], role: "author", desc: "committee",
|
27
|
+
default_org: false, committee: true,
|
28
|
+
agency: agency_arr, agency_abbrev:,
|
29
|
+
subdivtype: type.sub(/^approval-/, "").tr("-", " ").capitalize }.compact
|
30
|
+
end
|
31
|
+
|
32
|
+
def committee_org_prep_agency(node, type, agency, agency_arr, agency_abbr)
|
33
|
+
i = 1
|
34
|
+
suffix = ""
|
35
|
+
while committee_number_or_name?(node, type, suffix)
|
36
|
+
agency_arr << (node.attr("#{type}-agency#{suffix}") || agency)
|
37
|
+
agency_abbr << node.attr("#{type}-agency-abbr#{suffix}")
|
38
|
+
i += 1
|
39
|
+
suffix = "_#{i}"
|
40
|
+
end
|
41
|
+
[agency_arr, agency_abbr]
|
42
|
+
end
|
43
|
+
|
44
|
+
def contrib_committee_build(xml, agency, committee)
|
45
|
+
if name = org_abbrev.invert[agency]
|
46
|
+
committee[:agency_abbrev] = agency
|
47
|
+
agency = name
|
48
|
+
end
|
49
|
+
xml.name agency
|
50
|
+
s = committee
|
51
|
+
loop do
|
52
|
+
contrib_committee_subdiv(xml, s)
|
53
|
+
s = s[:subdiv] or break
|
54
|
+
end
|
55
|
+
abbr = committee[:agency_abbrev] and xml.abbreviation abbr
|
56
|
+
full_committee_id(xml.parent)
|
57
|
+
end
|
58
|
+
|
59
|
+
def contrib_committee_subdiv(xml, committee)
|
60
|
+
contributors_committees_filter_empty?(committee) and return
|
61
|
+
xml.subdivision **attr_code(type: committee[:subdivtype],
|
62
|
+
subtype: committee[:type]) do |o|
|
63
|
+
o.name committee[:name]
|
64
|
+
committee[:abbr] and o.abbreviation committee[:abbr]
|
65
|
+
committee[:ident] and o.identifier committee[:ident]
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def full_committee_id(contrib)
|
70
|
+
ret = full_committee_agency_id(contrib)
|
71
|
+
ids = contrib.xpath("./subdivision").map do |x|
|
72
|
+
x.at("./identifier")&.text
|
73
|
+
end.compact
|
74
|
+
ins = contrib.at("./subdivision/identifier") and
|
75
|
+
ins.next = "<identifier type='full'>#{ret}#{ids.join('/')}</identifier>"
|
76
|
+
end
|
77
|
+
|
78
|
+
def full_committee_agency_id(contrib)
|
79
|
+
agency = contrib.at("./abbreviation")&.text
|
80
|
+
ret = agency == default_publisher ? "" : "#{agency} "
|
81
|
+
/^\s+/.match?(ret) and ret = ""
|
82
|
+
ret
|
83
|
+
end
|
84
|
+
|
85
|
+
def org_attrs_parse(node, opts)
|
86
|
+
opts_orig = opts.dup
|
87
|
+
ret = []
|
88
|
+
ret << org_attrs_parse_core(node, opts)&.map&.with_index do |x, i|
|
89
|
+
x.merge(agency: opts.dig(:agency, i), subdivtype: opts[:subdivtype],
|
90
|
+
agency_abbrev: opts.dig(:agency_abbrev, i), abbr: opts[:abbr],
|
91
|
+
committee: opts[:committee], default_org: opts[:default_org])
|
92
|
+
end
|
93
|
+
org_attrs_add_committees(node, ret, opts, opts_orig)
|
94
|
+
end
|
95
|
+
|
96
|
+
def org_attrs_add_committees(node, ret, opts, opts_orig)
|
97
|
+
opts_orig[:groups]&.each_with_index do |g, i|
|
98
|
+
i.zero? and next
|
99
|
+
contributors_committees_pad_multiples(ret.first, node, g)
|
100
|
+
opts = committee_contrib_org_prep(node, g, nil, opts_orig)
|
101
|
+
ret << org_attrs_parse_core(node, opts).map do |x|
|
102
|
+
x.merge(subdivtype: opts[:subdivtype])
|
103
|
+
end
|
104
|
+
end
|
105
|
+
contributors_committees_nest1(ret)
|
106
|
+
end
|
107
|
+
|
108
|
+
# ensure there is subcommittee, workgroup -number_2, -number_3 etc
|
109
|
+
# to parse multiple tech committees
|
110
|
+
def contributors_committees_pad_multiples(committees, node, group)
|
111
|
+
committees.each_with_index do |_r, j|
|
112
|
+
suffix = j.zero? ? "" : "_#{j + 1}"
|
113
|
+
node.attr("#{group}#{suffix}") or
|
114
|
+
node.set_attr("#{group}#{suffix}", "")
|
115
|
+
node.attr("#{group}-number#{suffix}") or
|
116
|
+
node.set_attr("#{group}-number#{suffix}", "")
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def contributors_committees_filter_empty?(committee)
|
121
|
+
(committee[:name].nil? || committee[:name].empty?) &&
|
122
|
+
committee[:ident].nil?
|
123
|
+
end
|
124
|
+
|
125
|
+
def contributors_committees_nest1(committees)
|
126
|
+
committees.empty? and return committees
|
127
|
+
committees = committees.reverse
|
128
|
+
committees.each_with_index do |m, i|
|
129
|
+
i.zero? and next
|
130
|
+
m.each_with_index do |m1, j|
|
131
|
+
m1[:subdiv] = committees[i - 1][j]
|
132
|
+
end
|
133
|
+
end
|
134
|
+
committees[-1]
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require_relative "./front_organisation"
|
2
|
+
require_relative "./front_committee"
|
2
3
|
|
3
4
|
module Metanorma
|
4
5
|
module Standoc
|
@@ -8,6 +9,7 @@ module Metanorma
|
|
8
9
|
{ source: ["publisher", "pub"], role: "author",
|
9
10
|
default: default_publisher })
|
10
11
|
personal_author(node, xml)
|
12
|
+
committee_contributors(node, xml, default_publisher, {})
|
11
13
|
end
|
12
14
|
|
13
15
|
def personal_author(node, xml)
|
@@ -1,18 +1,6 @@
|
|
1
1
|
module Metanorma
|
2
2
|
module Standoc
|
3
3
|
module Front
|
4
|
-
def committee_component(compname, node, out)
|
5
|
-
i = 1
|
6
|
-
suffix = ""
|
7
|
-
while node.attr(compname + suffix)
|
8
|
-
out.send compname.gsub(/-/, "_"), node.attr(compname + suffix),
|
9
|
-
**attr_code(number: node.attr("#{compname}-number#{suffix}"),
|
10
|
-
type: node.attr("#{compname}-type#{suffix}"))
|
11
|
-
i += 1
|
12
|
-
suffix = "_#{i}"
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
4
|
def organization(org, orgname, node = nil, default_org = nil, attrs = {})
|
17
5
|
orgname, abbr = org_name_and_abbrev(attrs, orgname)
|
18
6
|
org.name orgname
|
@@ -147,12 +135,16 @@ module Metanorma
|
|
147
135
|
end
|
148
136
|
|
149
137
|
def org_organization(node, xml, org)
|
150
|
-
|
151
|
-
|
152
|
-
|
138
|
+
if org[:committee]
|
139
|
+
contrib_committee_build(xml, org[:agency], org)
|
140
|
+
else
|
141
|
+
organization(xml, org[:name], node, !node.attr("publisher"), org)
|
142
|
+
org_address(org, xml)
|
143
|
+
org_logo(xml, org[:logo])
|
144
|
+
end
|
153
145
|
end
|
154
146
|
|
155
|
-
def
|
147
|
+
def org_attrs_parse_core(node, opts)
|
156
148
|
source = opts[:source]&.detect { |s| node.attr(s) }
|
157
149
|
org_attrs_simple_parse(node, opts, source) ||
|
158
150
|
org_attrs_complex_parse(node, opts, source)
|
@@ -178,7 +170,7 @@ module Metanorma
|
|
178
170
|
i = 1
|
179
171
|
suffix = ""
|
180
172
|
ret = []
|
181
|
-
while node
|
173
|
+
while committee_number_or_name?(node, source, suffix)
|
182
174
|
ret << extract_org_attrs_complex(node, opts, source, suffix)
|
183
175
|
i += 1
|
184
176
|
suffix = "_#{i}"
|
@@ -187,14 +179,28 @@ module Metanorma
|
|
187
179
|
end
|
188
180
|
|
189
181
|
def extract_org_attrs_complex(node, opts, source, suffix)
|
190
|
-
|
182
|
+
n = node.attr("#{source}-number#{suffix}") # for committees
|
183
|
+
t = committee_ident(node.attr("#{source}-type#{suffix}"), n, source)
|
184
|
+
{ name: node.attr(source + suffix), ident: t,
|
191
185
|
abbrev: node.attr("#{source}_abbr#{suffix}"),
|
192
186
|
role: opts[:role], desc: opts[:desc],
|
187
|
+
type: node.attr("#{source}-type#{suffix}"),
|
193
188
|
subdiv: node.attr("#{source}_subdivision#{suffix}"),
|
194
189
|
logo: node.attr("#{source}_logo#{suffix}") }.compact
|
195
190
|
.merge(extract_org_attrs_address(node, opts, suffix))
|
196
191
|
end
|
197
192
|
|
193
|
+
def committee_abbrevs
|
194
|
+
{ "technical-committee" => "TC" }
|
195
|
+
end
|
196
|
+
|
197
|
+
def committee_ident(type, number, level)
|
198
|
+
number.nil? || number.empty? and return
|
199
|
+
type ||= committee_abbrevs[level]
|
200
|
+
type == "Other" and type = ""
|
201
|
+
"#{type} #{number}".strip
|
202
|
+
end
|
203
|
+
|
198
204
|
def extract_org_attrs_address(node, opts, suffix)
|
199
205
|
%w(address phone fax email uri).each_with_object({}) do |a, m|
|
200
206
|
opts[:source]&.each do |s|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
<?xml version="1.0" encoding="UTF-8"?>
|
2
2
|
<grammar xmlns:a="http://relaxng.org/ns/compatibility/annotations/1.0" xmlns="http://relaxng.org/ns/structure/1.0" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
|
3
|
-
<!-- VERSION v2.1.
|
3
|
+
<!-- VERSION v2.1.1 -->
|
4
4
|
|
5
5
|
<!--
|
6
6
|
ALERT: cannot have root comments, because of https://github.com/metanorma/metanorma/issues/437
|
@@ -2233,6 +2233,11 @@ used in document amendments</a:documentation>
|
|
2233
2233
|
<ref name="RequiredId"/>
|
2234
2234
|
<ref name="NumberingAttributes"/>
|
2235
2235
|
<ref name="BlockAttributes"/>
|
2236
|
+
<optional>
|
2237
|
+
<attribute name="type">
|
2238
|
+
<a:documentation>Semantic classification of note</a:documentation>
|
2239
|
+
</attribute>
|
2240
|
+
</optional>
|
2236
2241
|
<oneOrMore>
|
2237
2242
|
<choice>
|
2238
2243
|
<a:documentation>Content of the term note</a:documentation>
|
@@ -131,7 +131,7 @@ module Metanorma
|
|
131
131
|
|
132
132
|
def fetch_ref(xml, code, year, **opts)
|
133
133
|
opts[:no_year] and return nil
|
134
|
-
code = code
|
134
|
+
_, code = extract_balanced_parentheses(code)
|
135
135
|
hit = fetch_ref1(code, year, opts) or return nil
|
136
136
|
xml.parent.add_child(smart_render_xml(hit, code, opts))
|
137
137
|
xml
|
@@ -42,7 +42,7 @@ module Metanorma
|
|
42
42
|
end
|
43
43
|
|
44
44
|
def docid(bib, code, codetype = nil)
|
45
|
-
type, code1 = if /^\[\d+\]$|^\(
|
45
|
+
type, code1 = if /^\[\d+\]$|^\(.+\).*$/.match?(code)
|
46
46
|
["metanorma", mn_code(code)]
|
47
47
|
elsif %w(attachment repo path).include?(codetype)
|
48
48
|
[nil, code]
|
@@ -62,7 +62,10 @@ module Metanorma
|
|
62
62
|
end
|
63
63
|
|
64
64
|
def mn_code(code)
|
65
|
-
|
65
|
+
# Handle balanced parentheses at the start of the string
|
66
|
+
balance, remainder = extract_balanced_parentheses(code)
|
67
|
+
balance and return "[#{balance}]"
|
68
|
+
remainder
|
66
69
|
.sub(/^dropid\((.+)\)$/, "\\1")
|
67
70
|
.sub(/^hidden\((.+)\)$/, "\\1")
|
68
71
|
.sub(/^nofetch\((.+)\)$/, "\\1")
|
@@ -218,6 +221,28 @@ module Metanorma
|
|
218
221
|
@type = 'DOI' or @type = 'doi' or @type = 'ISSN' or @type = 'issn' or @type = 'ISBN' or @type = 'isbn' or starts-with(@type, 'ISSN.') or starts-with(@type, 'ISBN.') or starts-with(@type, 'issn.') or starts-with(@type, 'isbn.')
|
219
222
|
XPATH
|
220
223
|
end
|
224
|
+
|
225
|
+
private
|
226
|
+
|
227
|
+
def extract_balanced_parentheses(code)
|
228
|
+
code.start_with?("(") or return [nil, code]
|
229
|
+
paren_count = 0
|
230
|
+
# Find the matching closing parenthesis
|
231
|
+
code.each_char.with_index do |char, index|
|
232
|
+
case char
|
233
|
+
when "(" then paren_count += 1
|
234
|
+
when ")"
|
235
|
+
paren_count -= 1
|
236
|
+
paren_count.zero? or next
|
237
|
+
# Found the matching closing parenthesis
|
238
|
+
content = code[1...index] # Extract content between parentheses
|
239
|
+
remaining = code[(index + 1)..] || "" # Get remaining string
|
240
|
+
return [content, remaining]
|
241
|
+
end
|
242
|
+
end
|
243
|
+
# If we get here, parentheses are unbalanced - return original
|
244
|
+
[nil, code]
|
245
|
+
end
|
221
246
|
end
|
222
247
|
end
|
223
248
|
end
|
@@ -52,27 +52,28 @@ module Metanorma
|
|
52
52
|
|
53
53
|
ISO_REF =
|
54
54
|
%r{^<ref\sid="(?<anchor>[^"]+)">
|
55
|
-
\[(?<usrlbl>\(
|
55
|
+
\[(?<usrlbl>\(.+\))?(?<code>(?:ISO|IEC)[^0-9]*\s[0-9-]+|IEV)
|
56
56
|
(?::(?<year>[0-9][0-9-]+))?\]</ref>,?\s*(?<text>.*)$}xm
|
57
57
|
|
58
58
|
ISO_REF_NO_YEAR =
|
59
59
|
%r{^<ref\sid="(?<anchor>[^"]+)">
|
60
|
-
\[(?<usrlbl>\(
|
60
|
+
\[(?<usrlbl>\(.+\))?(?<code>(?:ISO|IEC)[^0-9]*\s[0-9-]+):
|
61
61
|
(?:--|–|—|&\#821[12];)\]</ref>,?\s*
|
62
62
|
(?:<fn[^>]*>\s*<p>(?<fn>[^\]]+)</p>\s*</fn>)?,?\s?(?<text>.*)$}xm
|
63
63
|
|
64
64
|
ISO_REF_ALL_PARTS =
|
65
65
|
%r{^<ref\sid="(?<anchor>[^"]+)">
|
66
|
-
\[(?<usrlbl>\(
|
66
|
+
\[(?<usrlbl>\(.+\))?(?<code>(?:ISO|IEC)[^0-9]*\s[0-9]+)
|
67
67
|
(?::(?<year>--|–|—|&\#821[12];|[0-9][0-9-]+))?\s
|
68
68
|
\(all\sparts\)\]</ref>,?\s*
|
69
69
|
(?:<fn[^>]*>\s*<p>(?<fn>[^\]]+)</p>\s*</fn>,?\s?)?(?<text>.*)$}xm
|
70
70
|
|
71
|
+
# These regexes allow () inside usrlbl but not inside code
|
71
72
|
NON_ISO_REF = %r{^<ref\sid="(?<anchor>[^"]+)">
|
72
|
-
\[(?<usrlbl>\(
|
73
|
+
\[(?<usrlbl>\(.+\))?(?<code>.+?)\]</ref>,?\s*(?<text>.*)$}xm
|
73
74
|
|
74
75
|
NON_ISO_REF1 = %r{^<ref\sid="(?<anchor>[^"]+)">
|
75
|
-
(?<usrlbl>\(
|
76
|
+
(?<usrlbl>\(.+\))?(?<code>.+?)</ref>,?\s*(?<text>.*)$}xm
|
76
77
|
end
|
77
78
|
end
|
78
79
|
end
|
@@ -73,6 +73,7 @@ module Metanorma
|
|
73
73
|
end
|
74
74
|
|
75
75
|
def preface_main_filter(ret, node)
|
76
|
+
node.level > 1 and return ret
|
76
77
|
start_main_section(ret, node)
|
77
78
|
@preface && self.class::MAIN_CLAUSE_NAMES.include?(ret) and return nil
|
78
79
|
!@preface && self.class::PREFACE_CLAUSE_NAMES.include?(ret) and
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: metanorma-standoc
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.1.
|
4
|
+
version: 3.1.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ribose Inc.
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-08-
|
11
|
+
date: 2025-08-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: addressable
|
@@ -519,6 +519,7 @@ files:
|
|
519
519
|
- lib/metanorma/standoc/datamodel/diagram_preprocessor.rb
|
520
520
|
- lib/metanorma/standoc/datamodel/plantuml_renderer.rb
|
521
521
|
- lib/metanorma/standoc/front.rb
|
522
|
+
- lib/metanorma/standoc/front_committee.rb
|
522
523
|
- lib/metanorma/standoc/front_contributor.rb
|
523
524
|
- lib/metanorma/standoc/front_organisation.rb
|
524
525
|
- lib/metanorma/standoc/init.rb
|