metanorma-standoc 3.1.2 → 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/README.adoc +1 -1
- data/lib/metanorma/standoc/base.rb +1 -1
- data/lib/metanorma/standoc/basicdoc.rng +1 -1
- data/lib/metanorma/standoc/biblio-standoc.rng +0 -49
- data/lib/metanorma/standoc/biblio.rng +11 -1
- data/lib/metanorma/standoc/blocks.rb +5 -2
- data/lib/metanorma/standoc/blocks_notes.rb +15 -0
- data/lib/metanorma/standoc/cleanup.rb +4 -1
- data/lib/metanorma/standoc/cleanup_bibdata.rb +16 -1
- data/lib/metanorma/standoc/cleanup_bibitem.rb +7 -1
- data/lib/metanorma/standoc/cleanup_boilerplate.rb +62 -16
- data/lib/metanorma/standoc/cleanup_maths.rb +12 -1
- data/lib/metanorma/standoc/converter.rb +1 -2
- 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 +7 -60
- data/lib/metanorma/standoc/macros_inline.rb +1 -3
- data/lib/metanorma/standoc/macros_note.rb +0 -14
- data/lib/metanorma/standoc/ref.rb +7 -4
- data/lib/metanorma/standoc/ref_queue.rb +5 -3
- data/lib/metanorma/standoc/ref_utility.rb +83 -61
- data/lib/metanorma/standoc/regex.rb +6 -5
- data/lib/metanorma/standoc/sectiontype.rb +1 -0
- data/lib/metanorma/standoc/utils.rb +2 -0
- data/lib/metanorma/standoc/version.rb +1 -1
- data/metanorma-standoc.gemspec +1 -1
- metadata +4 -3
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
|
data/README.adoc
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
image:https://img.shields.io/gem/v/metanorma-standoc.svg["Gem Version", link="https://rubygems.org/gems/metanorma-standoc"]
|
4
4
|
image:https://github.com/metanorma/metanorma-standoc/workflows/rake/badge.svg["Build Status", link="https://github.com/metanorma/metanorma-standoc/actions?workflow=rake"]
|
5
|
-
image:https://codeclimate.com/github/metanorma/metanorma-standoc/badges/gpa.svg["Code Climate", link="https://codeclimate.com/github/metanorma/metanorma-standoc"]
|
5
|
+
// image:https://codeclimate.com/github/metanorma/metanorma-standoc/badges/gpa.svg["Code Climate", link="https://codeclimate.com/github/metanorma/metanorma-standoc"]
|
6
6
|
image:https://img.shields.io/github/issues-pr-raw/metanorma/metanorma-standoc.svg["Pull Requests", link="https://github.com/metanorma/metanorma-standoc/pulls"]
|
7
7
|
image:https://img.shields.io/github/commits-since/metanorma/metanorma-standoc/latest.svg["Commits since latest",link="https://github.com/metanorma/metanorma-standoc/releases"]
|
8
8
|
|
@@ -139,7 +139,7 @@ module Metanorma
|
|
139
139
|
%w(presentation semantic).each do |t|
|
140
140
|
/^#{t}-metadata-/.match?(k) or next
|
141
141
|
k = k.sub(/^#{t}-metadata-/, "")
|
142
|
-
quoted_csv_split(v)&.each do |c|
|
142
|
+
quoted_csv_split(v.gsub("&#", "&#"))&.each do |c|
|
143
143
|
ret << "<#{t}-metadata><#{k}>#{c}</#{k}></#{t}-metadata>"
|
144
144
|
end
|
145
145
|
end
|
@@ -1291,13 +1291,13 @@ Restricted recursively to contain only other such inline elements with no identi
|
|
1291
1291
|
<ref name="pure_strike"/>
|
1292
1292
|
<ref name="pure_smallcap"/>
|
1293
1293
|
<ref name="br"/>
|
1294
|
+
<ref name="stem"/>
|
1294
1295
|
</choice>
|
1295
1296
|
</define>
|
1296
1297
|
<define name="NestedTextElement">
|
1297
1298
|
<a:documentation>Contents of TextElement tags: leaves out tags that should occur only at top level of block: bookmark image hr pagebreak</a:documentation>
|
1298
1299
|
<choice>
|
1299
1300
|
<ref name="PureTextElement"/>
|
1300
|
-
<ref name="stem"/>
|
1301
1301
|
<ref name="eref"/>
|
1302
1302
|
<ref name="xref"/>
|
1303
1303
|
<ref name="hyperlink"/>
|
@@ -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>
|
@@ -161,12 +161,15 @@ module Metanorma
|
|
161
161
|
type: node.attr("type"))))
|
162
162
|
end
|
163
163
|
|
164
|
-
# term sources occasionally turning up as "source source"?
|
164
|
+
# TODO: term sources occasionally turning up as "source source"?
|
165
165
|
def paragraph(node)
|
166
166
|
node.role&.sub(/ .*$/, "") == "source" and return termsource(node)
|
167
|
+
content = node.content
|
168
|
+
content.start_with?("TODO: ") and return todo_prefixed_para(node)
|
169
|
+
content.start_with?("EDITOR: ") and return editor_prefixed_para(node)
|
167
170
|
noko do |xml|
|
168
171
|
xml.p **para_attrs(node) do |xml_t|
|
169
|
-
xml_t <<
|
172
|
+
xml_t << content
|
170
173
|
end
|
171
174
|
end
|
172
175
|
end
|
@@ -6,6 +6,7 @@ module Metanorma
|
|
6
6
|
.merge(
|
7
7
|
"keep-separate": node.attr("keep-separate"),
|
8
8
|
keepasterm: node.option?("termnote") ? "true" : nil,
|
9
|
+
type: node.attr("type")
|
9
10
|
)))
|
10
11
|
end
|
11
12
|
|
@@ -46,6 +47,20 @@ module Metanorma
|
|
46
47
|
end
|
47
48
|
end
|
48
49
|
|
50
|
+
# -TO-DO :
|
51
|
+
def todo_prefixed_para(node)
|
52
|
+
node.lines[0].sub!(/^TODO: /, "")
|
53
|
+
todo(node)
|
54
|
+
end
|
55
|
+
|
56
|
+
# EDITOR:
|
57
|
+
def editor_prefixed_para(node)
|
58
|
+
node.lines[0].sub!(/^EDITOR: /, "")
|
59
|
+
node.set_attr("type", "editorial")
|
60
|
+
node.assign_caption "EDITOR"
|
61
|
+
admonition(node)
|
62
|
+
end
|
63
|
+
|
49
64
|
def termnote(node)
|
50
65
|
noko do |xml|
|
51
66
|
xml.termnote **termnote_attrs(node) do |ex|
|
@@ -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
|
@@ -6,6 +6,9 @@ module Metanorma
|
|
6
6
|
ret = new_bibitem_from_formattedref_spans(b)
|
7
7
|
merge_bibitem_from_formattedref_spans(b, ret)
|
8
8
|
end
|
9
|
+
xmldoc.xpath("//bibitem[@amend]").each do |b|
|
10
|
+
b.delete("amend")
|
11
|
+
end
|
9
12
|
end
|
10
13
|
|
11
14
|
def new_bibitem_from_formattedref_spans(bib)
|
@@ -18,9 +21,12 @@ module Metanorma
|
|
18
21
|
|
19
22
|
def merge_bibitem_from_formattedref_spans(bib, new)
|
20
23
|
new["type"] and bib["type"] = new["type"]
|
21
|
-
if bib.at("./title")
|
24
|
+
if bib.at("./title") && bib["amend"]
|
25
|
+
# there already is a fetched record here: merge
|
22
26
|
bib.children = MergeBibitems
|
23
27
|
.new(bib.to_xml, new.to_xml).merge.to_noko.children
|
28
|
+
elsif bib.at("./title") # replace record
|
29
|
+
bib.children = new.children.to_xml
|
24
30
|
else bib << new.children.to_xml
|
25
31
|
end
|
26
32
|
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
|
@@ -179,6 +180,7 @@ module Metanorma
|
|
179
180
|
end
|
180
181
|
|
181
182
|
def mathml_cleanup(xmldoc)
|
183
|
+
mathml_number_to_mathml(xmldoc)
|
182
184
|
xmldoc.xpath("//stem[@type = 'MathML'][not(@validate = 'false')]")
|
183
185
|
.each do |x|
|
184
186
|
mathml_xml_cleanup(x)
|
@@ -189,6 +191,15 @@ module Metanorma
|
|
189
191
|
mathml_unitsml(xmldoc)
|
190
192
|
end
|
191
193
|
|
194
|
+
def mathml_number_to_mathml(xmldoc)
|
195
|
+
xmldoc.xpath("//mathml-number").each do |n|
|
196
|
+
n.name = "stem"
|
197
|
+
n["type"] = "MathML"
|
198
|
+
n.children =
|
199
|
+
"<math xmlns='#{MATHML_NS}'><mn>#{n.children.to_xml}</mn></math>"
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
192
203
|
include ::Metanorma::Standoc::Regex
|
193
204
|
end
|
194
205
|
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
|
@@ -80,8 +81,6 @@ module Metanorma
|
|
80
81
|
inline_macro Metanorma::Standoc::SourceIncludeInlineMacro
|
81
82
|
block Metanorma::Standoc::ToDoAdmonitionBlock
|
82
83
|
block Metanorma::Standoc::EditorAdmonitionBlock
|
83
|
-
treeprocessor Metanorma::Standoc::EditorInlineAdmonitionBlock
|
84
|
-
treeprocessor Metanorma::Standoc::ToDoInlineAdmonitionBlock
|
85
84
|
block Metanorma::Standoc::PlantUMLBlockMacro
|
86
85
|
block Metanorma::Standoc::PseudocodeBlockMacro
|
87
86
|
block_macro Metanorma::Standoc::ColumnBreakBlockMacro
|
@@ -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
|
@@ -42,36 +42,6 @@ All IdRefType instances point not to `@id` in Semantic XML, which is the Content
|
|
42
42
|
but to `@anchor`, the user-supplied cross-reference</a:documentation>
|
43
43
|
<text/>
|
44
44
|
</define>
|
45
|
-
<define name="index-primary">
|
46
|
-
<element name="primary">
|
47
|
-
<oneOrMore>
|
48
|
-
<choice>
|
49
|
-
<ref name="PureTextElement"/>
|
50
|
-
<ref name="stem"/>
|
51
|
-
</choice>
|
52
|
-
</oneOrMore>
|
53
|
-
</element>
|
54
|
-
</define>
|
55
|
-
<define name="index-secondary">
|
56
|
-
<element name="secondary">
|
57
|
-
<oneOrMore>
|
58
|
-
<choice>
|
59
|
-
<ref name="PureTextElement"/>
|
60
|
-
<ref name="stem"/>
|
61
|
-
</choice>
|
62
|
-
</oneOrMore>
|
63
|
-
</element>
|
64
|
-
</define>
|
65
|
-
<define name="index-tertiary">
|
66
|
-
<element name="tertiary">
|
67
|
-
<oneOrMore>
|
68
|
-
<choice>
|
69
|
-
<ref name="PureTextElement"/>
|
70
|
-
<ref name="stem"/>
|
71
|
-
</choice>
|
72
|
-
</oneOrMore>
|
73
|
-
</element>
|
74
|
-
</define>
|
75
45
|
<define name="review">
|
76
46
|
<a:documentation>Generalise BasicDoc element from just review comments, to general annotations;
|
77
47
|
the type attribute defaults to `review` for reviews</a:documentation>
|
@@ -592,28 +562,6 @@ normative or informative references, some split references into sections organiz
|
|
592
562
|
</oneOrMore>
|
593
563
|
</element>
|
594
564
|
</define>
|
595
|
-
<define name="sub">
|
596
|
-
<a:documentation>Subscript text. Corresponds to HTML `sub</a:documentation>
|
597
|
-
<element name="sub">
|
598
|
-
<zeroOrMore>
|
599
|
-
<choice>
|
600
|
-
<ref name="PureTextElement"/>
|
601
|
-
<ref name="stem"/>
|
602
|
-
</choice>
|
603
|
-
</zeroOrMore>
|
604
|
-
</element>
|
605
|
-
</define>
|
606
|
-
<define name="sup">
|
607
|
-
<a:documentation>Superscript text. Corresponds to HTML `sup`</a:documentation>
|
608
|
-
<element name="sup">
|
609
|
-
<zeroOrMore>
|
610
|
-
<choice>
|
611
|
-
<ref name="PureTextElement"/>
|
612
|
-
<ref name="stem"/>
|
613
|
-
</choice>
|
614
|
-
</zeroOrMore>
|
615
|
-
</element>
|
616
|
-
</define>
|
617
565
|
<define name="pagebreak">
|
618
566
|
<a:documentation>Page break. Only applicable in paged layouts (e.g. PDF, Word), and not flow layouts (e.g. HTML)</a:documentation>
|
619
567
|
<element name="pagebreak">
|
@@ -1094,7 +1042,6 @@ That concept may be defined as a term within the current document, or it may be
|
|
1094
1042
|
<zeroOrMore>
|
1095
1043
|
<choice>
|
1096
1044
|
<ref name="PureTextElement"/>
|
1097
|
-
<ref name="stem"/>
|
1098
1045
|
<ref name="index"/>
|
1099
1046
|
<ref name="index-xref"/>
|
1100
1047
|
</choice>
|
@@ -1107,7 +1054,6 @@ That concept may be defined as a term within the current document, or it may be
|
|
1107
1054
|
<zeroOrMore>
|
1108
1055
|
<choice>
|
1109
1056
|
<ref name="PureTextElement"/>
|
1110
|
-
<ref name="stem"/>
|
1111
1057
|
<ref name="index"/>
|
1112
1058
|
<ref name="index-xref"/>
|
1113
1059
|
</choice>
|
@@ -2025,10 +1971,7 @@ used in document amendments</a:documentation>
|
|
2025
1971
|
<element name="name">
|
2026
1972
|
<a:documentation>The symbolic form of the designation</a:documentation>
|
2027
1973
|
<oneOrMore>
|
2028
|
-
<
|
2029
|
-
<ref name="PureTextElement"/>
|
2030
|
-
<ref name="stem"/>
|
2031
|
-
</choice>
|
1974
|
+
<ref name="PureTextElement"/>
|
2032
1975
|
</oneOrMore>
|
2033
1976
|
</element>
|
2034
1977
|
</element>
|
@@ -2081,7 +2024,6 @@ used in document amendments</a:documentation>
|
|
2081
2024
|
<zeroOrMore>
|
2082
2025
|
<choice>
|
2083
2026
|
<ref name="PureTextElement"/>
|
2084
|
-
<ref name="stem"/>
|
2085
2027
|
<ref name="index"/>
|
2086
2028
|
<ref name="index-xref"/>
|
2087
2029
|
</choice>
|
@@ -2291,6 +2233,11 @@ used in document amendments</a:documentation>
|
|
2291
2233
|
<ref name="RequiredId"/>
|
2292
2234
|
<ref name="NumberingAttributes"/>
|
2293
2235
|
<ref name="BlockAttributes"/>
|
2236
|
+
<optional>
|
2237
|
+
<attribute name="type">
|
2238
|
+
<a:documentation>Semantic classification of note</a:documentation>
|
2239
|
+
</attribute>
|
2240
|
+
</optional>
|
2294
2241
|
<oneOrMore>
|
2295
2242
|
<choice>
|
2296
2243
|
<a:documentation>Content of the term note</a:documentation>
|
@@ -233,9 +233,7 @@ module Metanorma
|
|
233
233
|
fmt = format(out, target)
|
234
234
|
fmt.empty? and fmt = "default"
|
235
235
|
fmt = %( number-format="#{fmt}")
|
236
|
-
|
237
|
-
<stem type="MathML"#{fmt}><math xmlns='#{MATHML_NS}'><mn>#{number(target)}</mn></math></stem>
|
238
|
-
OUTPUT
|
236
|
+
"<mathml-number#{fmt}>#{number(target)}</mathml-number>"
|
239
237
|
end
|
240
238
|
end
|
241
239
|
end
|
@@ -14,20 +14,6 @@ module Metanorma
|
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
|
-
class ToDoInlineAdmonitionBlock < Asciidoctor::Extensions::Treeprocessor
|
18
|
-
def process(document)
|
19
|
-
(document.find_by context: :paragraph).each do |para|
|
20
|
-
next unless /^TODO: /.match? para.lines[0]
|
21
|
-
|
22
|
-
para.set_attr("name", "todo")
|
23
|
-
para.set_attr("caption", "TODO")
|
24
|
-
para.lines[0].sub!(/^TODO: /, "")
|
25
|
-
# these will be converted from admonition to annotation downstream
|
26
|
-
para.context = :admonition
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
17
|
class FootnoteBlockInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
|
32
18
|
use_dsl
|
33
19
|
named :footnoteblock
|
@@ -130,10 +130,7 @@ module Metanorma
|
|
130
130
|
end
|
131
131
|
|
132
132
|
def refitem_render(xml, match, code)
|
133
|
-
xml.bibitem **
|
134
|
-
anchor: match[:anchor], suppress_identifier: code[:dropid],
|
135
|
-
hidden: code[:hidden], id: "_#{UUIDTools::UUID.random_create}"
|
136
|
-
) do |t|
|
133
|
+
xml.bibitem **refitem_render_attrs(match, code) do |t|
|
137
134
|
refitem_render_formattedref(t, match[:text])
|
138
135
|
yr_match = refitem1yr(code[:id])
|
139
136
|
refitem_render1(match, code, t)
|
@@ -143,6 +140,12 @@ module Metanorma
|
|
143
140
|
end
|
144
141
|
end
|
145
142
|
|
143
|
+
def refitem_render_attrs(match, code)
|
144
|
+
attr_code(anchor: match[:anchor], suppress_identifier: code[:dropid],
|
145
|
+
amend: code[:amend], hidden: code[:hidden],
|
146
|
+
id: "_#{UUIDTools::UUID.random_create}")
|
147
|
+
end
|
148
|
+
|
146
149
|
def refitem_render_formattedref(bibitem, title)
|
147
150
|
(title.nil? || title.empty?) and title = @i18n.no_information_available
|
148
151
|
bibitem.formattedref format: "application/x-isodoc+xml" do |i|
|
@@ -42,8 +42,9 @@ module Metanorma
|
|
42
42
|
ref, i, doc = results.pop
|
43
43
|
m[i.to_i] = { ref: }
|
44
44
|
if doc.is_a?(RelatonBib::RequestError)
|
45
|
-
@log.add("Bibliography", nil,
|
46
|
-
|
45
|
+
@log.add("Bibliography", nil,
|
46
|
+
"Could not retrieve #{ref[:code]}: " \
|
47
|
+
"no access to online site", severity: 1)
|
47
48
|
else m[i.to_i][:doc] = doc end
|
48
49
|
end
|
49
50
|
end
|
@@ -130,7 +131,7 @@ module Metanorma
|
|
130
131
|
|
131
132
|
def fetch_ref(xml, code, year, **opts)
|
132
133
|
opts[:no_year] and return nil
|
133
|
-
code = code
|
134
|
+
_, code = extract_balanced_parentheses(code)
|
134
135
|
hit = fetch_ref1(code, year, opts) or return nil
|
135
136
|
xml.parent.add_child(smart_render_xml(hit, code, opts))
|
136
137
|
xml
|
@@ -206,6 +207,7 @@ module Metanorma
|
|
206
207
|
xml.parent.add_child(smart_render_xml(item[:doc], item[:ref][:code],
|
207
208
|
item[:ref]))
|
208
209
|
use_my_anchor(xml, item[:ref][:match][:anchor],
|
210
|
+
amend: item.dig(:ref, :analyse_code, :amend),
|
209
211
|
hidden: item.dig(:ref, :analyse_code, :hidden),
|
210
212
|
dropid: item.dig(:ref, :analyse_code, :dropid))
|
211
213
|
end
|
@@ -32,16 +32,17 @@ module Metanorma
|
|
32
32
|
end
|
33
33
|
|
34
34
|
def use_my_anchor(ref, id, opt)
|
35
|
-
ref.parent.elements.last
|
36
|
-
|
37
|
-
|
38
|
-
a = opt[:
|
39
|
-
|
35
|
+
elem = ref.parent.elements.last
|
36
|
+
elem["anchor"] = id
|
37
|
+
add_id(elem)
|
38
|
+
a = opt[:hidden] and elem["hidden"] = a
|
39
|
+
a = opt[:amend] and elem["amend"] = a
|
40
|
+
a = opt[:dropid] and elem["suppress_identifier"] = a
|
40
41
|
ref
|
41
42
|
end
|
42
43
|
|
43
44
|
def docid(bib, code, codetype = nil)
|
44
|
-
type, code1 = if /^\[\d+\]$|^\(
|
45
|
+
type, code1 = if /^\[\d+\]$|^\(.+\).*$/.match?(code)
|
45
46
|
["metanorma", mn_code(code)]
|
46
47
|
elsif %w(attachment repo path).include?(codetype)
|
47
48
|
[nil, code]
|
@@ -61,45 +62,28 @@ module Metanorma
|
|
61
62
|
end
|
62
63
|
|
63
64
|
def mn_code(code)
|
64
|
-
|
65
|
+
# Handle balanced parentheses at the start of the string
|
66
|
+
balance, remainder = extract_balanced_parentheses(code)
|
67
|
+
balance and return "[#{balance}]"
|
68
|
+
remainder
|
65
69
|
.sub(/^dropid\((.+)\)$/, "\\1")
|
66
70
|
.sub(/^hidden\((.+)\)$/, "\\1")
|
67
71
|
.sub(/^nofetch\((.+)\)$/, "\\1")
|
68
72
|
.sub(/^local-file\((.+)\)$/, "\\1")
|
69
|
-
|
70
|
-
|
71
|
-
def analyse_ref_localfile(ret)
|
72
|
-
m = /^local-file\((?:(?<source>[^,)]+),\s*)?(?<id>[^)]+)\)$/
|
73
|
-
.match(ret[:id])
|
74
|
-
m or return ret
|
75
|
-
ret.merge(id: m[:id], localfile: m[:source] || "default")
|
76
|
-
end
|
77
|
-
|
78
|
-
def analyse_ref_nofetch(ret)
|
79
|
-
m = /^nofetch\((?<id>.+)\)$/.match(ret[:id]) or return ret
|
80
|
-
ret.merge(id: m[:id], nofetch: true)
|
81
|
-
end
|
82
|
-
|
83
|
-
def analyse_ref_hidden(ret)
|
84
|
-
m = /^hidden\((?<id>.+)\)$/.match(ret[:id]) or return ret
|
85
|
-
ret.merge(id: m[:id], hidden: true)
|
86
|
-
end
|
87
|
-
|
88
|
-
def analyse_ref_dropid(ret)
|
89
|
-
m = /^dropid\((?<id>.+)\)$/.match(ret[:id]) or return ret
|
90
|
-
ret.merge(id: m[:id], dropid: true)
|
73
|
+
.sub(/^amend\((.+)\)$/, "\\1")
|
91
74
|
end
|
92
75
|
|
93
76
|
def analyse_ref_repo_path(ret)
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
end
|
101
|
-
|
102
|
-
|
77
|
+
%i(repo path attachment).each do |type|
|
78
|
+
ret[type] or next
|
79
|
+
id = if ret[:id].empty?
|
80
|
+
if type == :attachment then "(#{ret[type]})"
|
81
|
+
else ret[type].sub(%r{^[^/]+/}, "")
|
82
|
+
end
|
83
|
+
else ret[:id] end
|
84
|
+
ret.merge!(id: id, type: type.to_s, key: ret[type], nofetch: true)
|
85
|
+
end
|
86
|
+
ret
|
103
87
|
end
|
104
88
|
|
105
89
|
def analyse_ref_numeric(ret)
|
@@ -107,16 +91,6 @@ module Metanorma
|
|
107
91
|
ret.merge(numeric: true)
|
108
92
|
end
|
109
93
|
|
110
|
-
def analyse_ref_dual(ret)
|
111
|
-
m = /^(?<type>merge|dual)\((?<keys>.+)\)$/.match(ret[:id]) or
|
112
|
-
return ret
|
113
|
-
line = CSV.parse_line(m[:keys], liberal_parsing: true) or return ret
|
114
|
-
line.size > 1 or return ret
|
115
|
-
ret[:id] = line.first
|
116
|
-
ret[m[:type].to_sym] = line[1..].map(&:strip)
|
117
|
-
ret
|
118
|
-
end
|
119
|
-
|
120
94
|
def analyse_ref_code(code)
|
121
95
|
ret = { id: code }
|
122
96
|
code.nil? || code.empty? and return ret
|
@@ -166,23 +140,49 @@ module Metanorma
|
|
166
140
|
end
|
167
141
|
end
|
168
142
|
|
143
|
+
def analyse_ref_code_nested(ret)
|
144
|
+
opts, id = parse_ref_code_nested({}, ret[:id])
|
145
|
+
ret[:id] = id
|
146
|
+
ret.merge!(opts)
|
147
|
+
analyse_ref_numeric(ret)
|
148
|
+
analyse_ref_repo_path(ret)
|
149
|
+
ret
|
150
|
+
end
|
151
|
+
|
169
152
|
# ref id = (usrlbl)code[:-]year
|
170
153
|
# code = \[? number \]? | ident | nofetch(code) | hidden(code) |
|
171
|
-
# dropid(code) |
|
154
|
+
# dropid(code) | amend(code) | (repo|path|attachment):(key,code) |
|
172
155
|
# local-file(source,? key) |
|
173
156
|
# merge(code, code) | dual(code, code)
|
174
|
-
def
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
157
|
+
def parse_ref_code_nested(ret, ident)
|
158
|
+
keys = %w(nofetch hidden dropid local-file repo path attachment merge
|
159
|
+
dual amend)
|
160
|
+
if (m = /^(?<key>[a-z-]+):?\((?<val>.*)\)$/.match(ident)) &&
|
161
|
+
keys.include?(m[:key])
|
162
|
+
case m[:key]
|
163
|
+
when "nofetch", "hidden", "dropid", "amend"
|
164
|
+
ret[m[:key].to_sym] = true
|
165
|
+
parse_ref_code_nested(ret, m[:val])
|
166
|
+
when "repo", "path", "attachment"
|
167
|
+
kv = m[:val].split(",", 2).map(&:strip)
|
168
|
+
ret[m[:key].to_sym] = kv[0]
|
169
|
+
parse_ref_code_nested(ret, kv.size == 1 ? "" : kv[1])
|
170
|
+
when "local-file"
|
171
|
+
kv = m[:val].split(",", 2).map(&:strip)
|
172
|
+
source = kv.size == 1 ? "default" : kv[0]
|
173
|
+
ret[:localfile] = source
|
174
|
+
parse_ref_code_nested(ret, kv[-1])
|
175
|
+
when "merge", "dual"
|
176
|
+
line = CSV.parse_line(m[:val],
|
177
|
+
liberal_parsing: true) or return [ret, ident]
|
178
|
+
line.size > 1 or return [ret, ident]
|
179
|
+
ret[:id] = line.first
|
180
|
+
ret[m[:key].to_sym] = line[1..].map(&:strip)
|
181
|
+
[ret, ret[:id]]
|
182
|
+
end
|
183
|
+
|
184
|
+
else [ret, ident]
|
185
|
+
end
|
186
186
|
end
|
187
187
|
|
188
188
|
# if no year is supplied, interpret as no_year reference
|
@@ -221,6 +221,28 @@ module Metanorma
|
|
221
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.')
|
222
222
|
XPATH
|
223
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
|
224
246
|
end
|
225
247
|
end
|
226
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
|
@@ -87,8 +87,10 @@ module Metanorma
|
|
87
87
|
conv = presentation_xml_converter(EmptyAttr.new)
|
88
88
|
i18n = conv.i18n_init(lang, script, locale, i18nyaml)
|
89
89
|
conv.metadata_init(lang, script, locale, i18n)
|
90
|
+
conv.meta.localdir = @localdir
|
90
91
|
conv.xref_init(lang, script, nil, i18n, {})
|
91
92
|
conv.xrefs.klass.meta = conv.meta
|
93
|
+
conv.xrefs.klass.localdir = @localdir
|
92
94
|
conv
|
93
95
|
end
|
94
96
|
|
data/metanorma-standoc.gemspec
CHANGED
@@ -57,6 +57,6 @@ Gem::Specification.new do |spec|
|
|
57
57
|
spec.add_development_dependency "timecop", "~> 0.9"
|
58
58
|
spec.add_development_dependency "vcr", "~> 6.1.0"
|
59
59
|
spec.add_development_dependency "webmock"
|
60
|
-
spec.add_development_dependency "
|
60
|
+
spec.add_development_dependency "canon"
|
61
61
|
# spec.metadata["rubygems_mfa_required"] = "true"
|
62
62
|
end
|
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-
|
11
|
+
date: 2025-08-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: addressable
|
@@ -389,7 +389,7 @@ dependencies:
|
|
389
389
|
- !ruby/object:Gem::Version
|
390
390
|
version: '0'
|
391
391
|
- !ruby/object:Gem::Dependency
|
392
|
-
name:
|
392
|
+
name: canon
|
393
393
|
requirement: !ruby/object:Gem::Requirement
|
394
394
|
requirements:
|
395
395
|
- - ">="
|
@@ -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
|