metanorma-standoc 1.7.3 → 1.8.1
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/asciidoctor/standoc/base.rb +31 -44
- data/lib/asciidoctor/standoc/basicdoc.rng +5 -3
- data/lib/asciidoctor/standoc/blocks.rb +7 -7
- data/lib/asciidoctor/standoc/blocks_notes.rb +2 -2
- data/lib/asciidoctor/standoc/cleanup.rb +5 -6
- data/lib/asciidoctor/standoc/cleanup_block.rb +3 -3
- data/lib/asciidoctor/standoc/cleanup_boilerplate.rb +56 -0
- data/lib/asciidoctor/standoc/cleanup_inline.rb +22 -26
- data/lib/asciidoctor/standoc/cleanup_ref.rb +0 -85
- data/lib/asciidoctor/standoc/cleanup_ref_dl.rb +94 -0
- data/lib/asciidoctor/standoc/converter.rb +0 -1
- data/lib/asciidoctor/standoc/front.rb +2 -2
- data/lib/asciidoctor/standoc/inline.rb +1 -1
- data/lib/asciidoctor/standoc/isodoc.rng +3 -0
- data/lib/asciidoctor/standoc/lists.rb +2 -2
- data/lib/asciidoctor/standoc/macros_plantuml.rb +1 -1
- data/lib/asciidoctor/standoc/ref_sect.rb +2 -2
- data/lib/asciidoctor/standoc/reqt.rb +6 -1
- data/lib/asciidoctor/standoc/section.rb +3 -80
- data/lib/asciidoctor/standoc/table.rb +1 -1
- data/lib/asciidoctor/standoc/terms.rb +125 -0
- data/lib/asciidoctor/standoc/utils.rb +2 -96
- data/lib/metanorma/standoc/version.rb +1 -1
- data/metanorma-standoc.gemspec +2 -2
- data/spec/asciidoctor-standoc/base_spec.rb +30 -1
- data/spec/asciidoctor-standoc/cleanup_spec.rb +111 -2
- data/spec/asciidoctor-standoc/isobib_cache_spec.rb +4 -4
- data/spec/asciidoctor-standoc/refs_dl_spec.rb +13 -1
- data/spec/asciidoctor-standoc/refs_spec.rb +12 -12
- data/spec/asciidoctor-standoc/section_spec.rb +5 -3
- data/spec/vcr_cassettes/dated_iso_ref_joint_iso_iec.yml +47 -47
- data/spec/vcr_cassettes/isobib_get_123.yml +11 -11
- data/spec/vcr_cassettes/isobib_get_123_1.yml +26 -26
- data/spec/vcr_cassettes/isobib_get_123_1_fr.yml +36 -36
- data/spec/vcr_cassettes/isobib_get_123_2001.yml +14 -14
- data/spec/vcr_cassettes/isobib_get_124.yml +14 -14
- data/spec/vcr_cassettes/rfcbib_get_rfc8341.yml +8 -8
- data/spec/vcr_cassettes/separates_iev_citations_by_top_level_clause.yml +45 -45
- metadata +19 -18
- data/lib/asciidoctor/standoc/log.rb +0 -59
@@ -120,91 +120,6 @@ module Asciidoctor
|
|
120
120
|
end
|
121
121
|
end
|
122
122
|
|
123
|
-
def ref_dl_cleanup(xmldoc)
|
124
|
-
xmldoc.xpath("//clause[@bibitem = 'true']").each do |c|
|
125
|
-
bib = dl_bib_extract(c) or next
|
126
|
-
validate_ref_dl(bib, c)
|
127
|
-
bibitemxml = RelatonBib::BibliographicItem.new(RelatonBib::HashConverter::hash_to_bib(bib)).to_xml or next
|
128
|
-
bibitem = Nokogiri::XML(bibitemxml)
|
129
|
-
bibitem.root["id"] = c["id"] if c["id"] && !/^_/.match(c["id"])
|
130
|
-
c.replace(bibitem.root)
|
131
|
-
end
|
132
|
-
end
|
133
|
-
|
134
|
-
def validate_ref_dl(bib, c)
|
135
|
-
id = bib["id"]
|
136
|
-
id ||= c["id"] unless /^_/.match(c["id"]) # do not accept implicit id
|
137
|
-
unless id
|
138
|
-
@log.add("Anchors", c, "The following reference is missing an anchor:\n" + c.to_xml)
|
139
|
-
return
|
140
|
-
end
|
141
|
-
bib["title"] or @log.add("Bibliography", c, "Reference #{id} is missing a title")
|
142
|
-
bib["docid"] or @log.add("Bibliography", c, "Reference #{id} is missing a document identifier (docid)")
|
143
|
-
end
|
144
|
-
|
145
|
-
def extract_from_p(tag, bib, key)
|
146
|
-
return unless bib[tag]
|
147
|
-
"<#{key}>#{bib[tag].at('p').children}</#{key}>"
|
148
|
-
end
|
149
|
-
|
150
|
-
# if the content is a single paragraph, replace it with its children
|
151
|
-
# single links replaced with uri
|
152
|
-
def p_unwrap(p)
|
153
|
-
elems = p.elements
|
154
|
-
if elems.size == 1 && elems[0].name == "p"
|
155
|
-
link_unwrap(elems[0]).children.to_xml.strip
|
156
|
-
else
|
157
|
-
p.to_xml.strip
|
158
|
-
end
|
159
|
-
end
|
160
|
-
|
161
|
-
def link_unwrap(p)
|
162
|
-
elems = p.elements
|
163
|
-
if elems.size == 1 && elems[0].name == "link"
|
164
|
-
p.at("./link").replace(elems[0]["target"].strip)
|
165
|
-
end
|
166
|
-
p
|
167
|
-
end
|
168
|
-
|
169
|
-
def dd_bib_extract(dtd)
|
170
|
-
return nil if dtd.children.empty?
|
171
|
-
dtd.at("./dl") and return dl_bib_extract(dtd)
|
172
|
-
elems = dtd.remove.elements
|
173
|
-
return p_unwrap(dtd) unless elems.size == 1 && %w(ol ul).include?(elems[0].name)
|
174
|
-
ret = []
|
175
|
-
elems[0].xpath("./li").each do |li|
|
176
|
-
ret << p_unwrap(li)
|
177
|
-
end
|
178
|
-
ret
|
179
|
-
end
|
180
|
-
|
181
|
-
def add_to_hash(bib, key, val)
|
182
|
-
Utils::set_nested_value(bib, key.split(/\./), val)
|
183
|
-
end
|
184
|
-
|
185
|
-
# definition list, with at most one level of unordered lists
|
186
|
-
def dl_bib_extract(c, nested = false)
|
187
|
-
dl = c.at("./dl") or return
|
188
|
-
bib = {}
|
189
|
-
key = ""
|
190
|
-
dl.xpath("./dt | ./dd").each do |dtd|
|
191
|
-
dtd.name == "dt" and key = dtd.text.sub(/:+$/, "") or add_to_hash(bib, key, dd_bib_extract(dtd))
|
192
|
-
end
|
193
|
-
c.xpath("./clause").each do |c1|
|
194
|
-
key = c1&.at("./title")&.text&.downcase&.strip
|
195
|
-
next unless %w(contributor relation series).include? key
|
196
|
-
add_to_hash(bib, key, dl_bib_extract(c1, true))
|
197
|
-
end
|
198
|
-
if !nested and c.at("./title")
|
199
|
-
title = c.at("./title").remove.children.to_xml
|
200
|
-
bib["title"] = [bib["title"]] if bib["title"].is_a? Hash
|
201
|
-
bib["title"] = [bib["title"]] if bib["title"].is_a? String
|
202
|
-
bib["title"] = [] unless bib["title"]
|
203
|
-
bib["title"] << title if !title.empty?
|
204
|
-
end
|
205
|
-
bib
|
206
|
-
end
|
207
|
-
|
208
123
|
def fetch_termbase(termbase, id)
|
209
124
|
""
|
210
125
|
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
require "set"
|
2
|
+
require "relaton_bib"
|
3
|
+
|
4
|
+
module Asciidoctor
|
5
|
+
module Standoc
|
6
|
+
module Cleanup
|
7
|
+
def ref_dl_cleanup(xmldoc)
|
8
|
+
xmldoc.xpath("//clause[@bibitem = 'true']").each do |c|
|
9
|
+
bib = dl_bib_extract(c) or next
|
10
|
+
validate_ref_dl(bib, c)
|
11
|
+
bibitemxml = RelatonBib::BibliographicItem.new(RelatonBib::HashConverter::hash_to_bib(bib)).to_xml or next
|
12
|
+
bibitem = Nokogiri::XML(bibitemxml)
|
13
|
+
bibitem.root["id"] = c["id"] if c["id"] && !/^_/.match(c["id"])
|
14
|
+
c.replace(bibitem.root)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def validate_ref_dl(bib, c)
|
19
|
+
id = bib["id"]
|
20
|
+
id ||= c["id"] unless /^_/.match(c["id"]) # do not accept implicit id
|
21
|
+
unless id
|
22
|
+
@log.add("Anchors", c, "The following reference is missing an anchor:\n" + c.to_xml)
|
23
|
+
return
|
24
|
+
end
|
25
|
+
@refids << id
|
26
|
+
bib["title"] or @log.add("Bibliography", c, "Reference #{id} is missing a title")
|
27
|
+
bib["docid"] or @log.add("Bibliography", c, "Reference #{id} is missing a document identifier (docid)")
|
28
|
+
end
|
29
|
+
|
30
|
+
def extract_from_p(tag, bib, key)
|
31
|
+
return unless bib[tag]
|
32
|
+
"<#{key}>#{bib[tag].at('p').children}</#{key}>"
|
33
|
+
end
|
34
|
+
|
35
|
+
# if the content is a single paragraph, replace it with its children
|
36
|
+
# single links replaced with uri
|
37
|
+
def p_unwrap(p)
|
38
|
+
elems = p.elements
|
39
|
+
if elems.size == 1 && elems[0].name == "p"
|
40
|
+
link_unwrap(elems[0]).children.to_xml.strip
|
41
|
+
else
|
42
|
+
p.to_xml.strip
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def link_unwrap(p)
|
47
|
+
elems = p.elements
|
48
|
+
if elems.size == 1 && elems[0].name == "link"
|
49
|
+
p.at("./link").replace(elems[0]["target"].strip)
|
50
|
+
end
|
51
|
+
p
|
52
|
+
end
|
53
|
+
|
54
|
+
def dd_bib_extract(dtd)
|
55
|
+
return nil if dtd.children.empty?
|
56
|
+
dtd.at("./dl") and return dl_bib_extract(dtd)
|
57
|
+
elems = dtd.remove.elements
|
58
|
+
return p_unwrap(dtd) unless elems.size == 1 && %w(ol ul).include?(elems[0].name)
|
59
|
+
ret = []
|
60
|
+
elems[0].xpath("./li").each do |li|
|
61
|
+
ret << p_unwrap(li)
|
62
|
+
end
|
63
|
+
ret
|
64
|
+
end
|
65
|
+
|
66
|
+
def add_to_hash(bib, key, val)
|
67
|
+
Metanorma::Utils::set_nested_value(bib, key.split(/\./), val)
|
68
|
+
end
|
69
|
+
|
70
|
+
# definition list, with at most one level of unordered lists
|
71
|
+
def dl_bib_extract(c, nested = false)
|
72
|
+
dl = c.at("./dl") or return
|
73
|
+
bib = {}
|
74
|
+
key = ""
|
75
|
+
dl.xpath("./dt | ./dd").each do |dtd|
|
76
|
+
dtd.name == "dt" and key = dtd.text.sub(/:+$/, "") or add_to_hash(bib, key, dd_bib_extract(dtd))
|
77
|
+
end
|
78
|
+
c.xpath("./clause").each do |c1|
|
79
|
+
key = c1&.at("./title")&.text&.downcase&.strip
|
80
|
+
next unless %w(contributor relation series).include? key
|
81
|
+
add_to_hash(bib, key, dl_bib_extract(c1, true))
|
82
|
+
end
|
83
|
+
if !nested and c.at("./title")
|
84
|
+
title = c.at("./title").remove.children.to_xml
|
85
|
+
bib["title"] = [bib["title"]] if bib["title"].is_a? Hash
|
86
|
+
bib["title"] = [bib["title"]] if bib["title"].is_a? String
|
87
|
+
bib["title"] = [] unless bib["title"]
|
88
|
+
bib["title"] << title if !title.empty?
|
89
|
+
end
|
90
|
+
bib
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
@@ -93,7 +93,7 @@ module Asciidoctor
|
|
93
93
|
end
|
94
94
|
|
95
95
|
def metadata_script(node, xml)
|
96
|
-
xml.script (node.attr("script") || "
|
96
|
+
xml.script (node.attr("script") || default_script(node.attr("language")))
|
97
97
|
end
|
98
98
|
|
99
99
|
def relaton_relations
|
@@ -186,7 +186,7 @@ module Asciidoctor
|
|
186
186
|
["en"].each do |lang|
|
187
187
|
at = { language: lang, format: "text/plain" }
|
188
188
|
xml.title **attr_code(at) do |t|
|
189
|
-
t << (Utils::asciidoc_sub(node.attr("title") ||
|
189
|
+
t << (Metanorma::Utils::asciidoc_sub(node.attr("title") ||
|
190
190
|
node.attr("title-en")) || node.title)
|
191
191
|
end
|
192
192
|
end
|
@@ -194,7 +194,7 @@ module Asciidoctor
|
|
194
194
|
type = types.first.to_s
|
195
195
|
uri = uri.sub(%r{^data:image/\*;}, "data:#{type};")
|
196
196
|
attr_code(src: uri, #@datauriimage ? datauri(uri) : uri,
|
197
|
-
id: Utils::anchor_or_uuid,
|
197
|
+
id: Metanorma::Utils::anchor_or_uuid,
|
198
198
|
mimetype: type,
|
199
199
|
height: node.attr("height") || "auto",
|
200
200
|
width: node.attr("width") || "auto" ,
|
@@ -54,7 +54,7 @@ module Asciidoctor
|
|
54
54
|
end
|
55
55
|
|
56
56
|
def ol_attrs(node)
|
57
|
-
attr_code(keep_attrs(node).merge(id: Utils::anchor_or_uuid(node),
|
57
|
+
attr_code(keep_attrs(node).merge(id: Metanorma::Utils::anchor_or_uuid(node),
|
58
58
|
type: olist_style(node.style)))
|
59
59
|
end
|
60
60
|
|
@@ -88,7 +88,7 @@ module Asciidoctor
|
|
88
88
|
|
89
89
|
def dl_attrs(node)
|
90
90
|
attr_code(keep_attrs(node).
|
91
|
-
merge(id: Utils::anchor_or_uuid(node),
|
91
|
+
merge(id: Metanorma::Utils::anchor_or_uuid(node),
|
92
92
|
key: node.option?("key") ? "true" : nil))
|
93
93
|
end
|
94
94
|
|
@@ -30,7 +30,7 @@ module Asciidoctor
|
|
30
30
|
# plantuml process may finish earlier then dot, as result png file
|
31
31
|
# maybe not created yet after plantuml finish
|
32
32
|
def self.generate_file parent, reader
|
33
|
-
localdir = Utils::localdir(parent.document)
|
33
|
+
localdir = Metanorma::Utils::localdir(parent.document)
|
34
34
|
imagesdir = parent.document.attr('imagesdir')
|
35
35
|
umlfile, outfile = save_plantuml parent, reader, localdir
|
36
36
|
run(umlfile, outfile) or raise "No image output from PlantUML (#{umlfile}, #{outfile})!"
|
@@ -96,9 +96,9 @@ module Asciidoctor
|
|
96
96
|
xstr = x.to_xml(lang: opts[:lang])
|
97
97
|
xml = Nokogiri::XML(xstr)
|
98
98
|
emend_biblio(xml, code, opts[:title], opts[:usrlbl])
|
99
|
-
xml.xpath("//date").each { |d| Utils::endash_date(d) }
|
99
|
+
xml.xpath("//date").each { |d| Metanorma::Utils::endash_date(d) }
|
100
100
|
xml.traverse do |n|
|
101
|
-
n.text? and n.replace(Utils::smartformat(n.text))
|
101
|
+
n.text? and n.replace(Metanorma::Utils::smartformat(n.text))
|
102
102
|
end
|
103
103
|
xml.to_xml.sub(/<\?[^>]+>/, "")
|
104
104
|
end
|
@@ -6,6 +6,11 @@ require "base64"
|
|
6
6
|
module Asciidoctor
|
7
7
|
module Standoc
|
8
8
|
module Blocks
|
9
|
+
def reqt_subpart(x)
|
10
|
+
%w(specification measurement-target verification import label
|
11
|
+
subject inherit classification title).include? x
|
12
|
+
end
|
13
|
+
|
9
14
|
def reqt_subpart_attrs(node)
|
10
15
|
attr_code(keep_attrs(node).merge(exclude: node.option?("exclude"),
|
11
16
|
type: node.attr("type")))
|
@@ -41,7 +46,7 @@ module Asciidoctor
|
|
41
46
|
|
42
47
|
def reqt_attrs(node)
|
43
48
|
attr_code(keep_attrs(node).merge(id_unnum_attrs(node)).merge(
|
44
|
-
id: Utils::anchor_or_uuid(node),
|
49
|
+
id: Metanorma::Utils::anchor_or_uuid(node),
|
45
50
|
unnumbered: node.option?("unnumbered") ? "true" : nil,
|
46
51
|
number: node.attr("number"),
|
47
52
|
subsequence: node.attr("subsequence"),
|
@@ -1,6 +1,6 @@
|
|
1
|
-
require "htmlentities"
|
2
1
|
require "uri"
|
3
2
|
require_relative "ref_sect"
|
3
|
+
require_relative "terms"
|
4
4
|
|
5
5
|
module Asciidoctor
|
6
6
|
module Standoc
|
@@ -9,10 +9,6 @@ module Asciidoctor
|
|
9
9
|
@term_def = false
|
10
10
|
@norm_ref = false
|
11
11
|
|
12
|
-
def in_terms?
|
13
|
-
@term_def
|
14
|
-
end
|
15
|
-
|
16
12
|
def sectiontype1(node)
|
17
13
|
node&.attr("heading")&.downcase || node.title.gsub(/<[^>]+>/, "").downcase
|
18
14
|
end
|
@@ -45,10 +41,11 @@ module Asciidoctor
|
|
45
41
|
end
|
46
42
|
|
47
43
|
def section_attributes(node)
|
48
|
-
ret = { id: Utils::anchor_or_uuid(node),
|
44
|
+
ret = { id: Metanorma::Utils::anchor_or_uuid(node),
|
49
45
|
language: node.attributes["language"],
|
50
46
|
script: node.attributes["script"],
|
51
47
|
number: node.attributes["number"],
|
48
|
+
type: node.attributes["type"],
|
52
49
|
annex: ( ((node.attr("style") == "appendix" || node.role == "appendix") &&
|
53
50
|
node.level == 1) ? true : nil),
|
54
51
|
preface: (
|
@@ -147,80 +144,6 @@ module Asciidoctor
|
|
147
144
|
end
|
148
145
|
end
|
149
146
|
|
150
|
-
def nonterm_symbols_parse(attrs, xml, node)
|
151
|
-
defs = @definitions
|
152
|
-
@definitions = false
|
153
|
-
clause_parse(attrs, xml, node)
|
154
|
-
@definitions = defs
|
155
|
-
end
|
156
|
-
|
157
|
-
def symbols_attrs(node, a)
|
158
|
-
case sectiontype1(node)
|
159
|
-
when "symbols" then a.merge(type: "symbols")
|
160
|
-
when "abbreviated terms", "abbreviations" then a.merge(type: "abbreviated_terms")
|
161
|
-
else
|
162
|
-
a
|
163
|
-
end
|
164
|
-
end
|
165
|
-
|
166
|
-
def symbols_parse(attr, xml, node)
|
167
|
-
node.role == "nonterm" and return nonterm_symbols_parse(attr, xml, node)
|
168
|
-
xml.definitions **attr_code(attr) do |xml_section|
|
169
|
-
xml_section.title { |t| t << node.title }
|
170
|
-
defs = @definitions
|
171
|
-
termdefs = @term_def
|
172
|
-
@definitions = true
|
173
|
-
@term_def = false
|
174
|
-
xml_section << node.content
|
175
|
-
@definitions = defs
|
176
|
-
@term_def = termdefs
|
177
|
-
end
|
178
|
-
end
|
179
|
-
|
180
|
-
def nonterm_term_def_subclause_parse(attrs, xml, node)
|
181
|
-
defs = @term_def
|
182
|
-
@term_def = false
|
183
|
-
clause_parse(attrs, xml, node)
|
184
|
-
@term_def = defs
|
185
|
-
end
|
186
|
-
|
187
|
-
def terms_boilerplate_parse(attrs, xml, node)
|
188
|
-
defs = @term_def
|
189
|
-
@term_def = false
|
190
|
-
clause_parse(attrs.merge(type: "boilerplate"), xml, node)
|
191
|
-
@term_def = defs
|
192
|
-
end
|
193
|
-
|
194
|
-
# subclause contains subclauses
|
195
|
-
def term_def_subclause_parse(attrs, xml, node)
|
196
|
-
node.role == "nonterm" and return nonterm_term_def_subclause_parse(attrs, xml, node)
|
197
|
-
node.role == "boilerplate" and return terms_boilerplate_parse(attrs, xml, node)
|
198
|
-
st = sectiontype(node, false)
|
199
|
-
return symbols_parse(attrs, xml, node) if @definitions
|
200
|
-
sub = node.find_by(context: :section) { |s| s.level == node.level + 1 }
|
201
|
-
sub.empty? || (return term_def_parse(attrs, xml, node, false))
|
202
|
-
st == "symbols and abbreviated terms" and (return symbols_parse(attrs, xml, node))
|
203
|
-
st == "terms and definitions" and return clause_parse(attrs, xml, node)
|
204
|
-
term_def_subclause_parse1(attrs, xml, node)
|
205
|
-
end
|
206
|
-
|
207
|
-
def term_def_subclause_parse1(attrs, xml, node)
|
208
|
-
xml.term **attr_code(attrs) do |xml_section|
|
209
|
-
xml_section.preferred { |name| name << node.title }
|
210
|
-
xml_section << node.content
|
211
|
-
end
|
212
|
-
end
|
213
|
-
|
214
|
-
def term_def_parse(attrs, xml, node, toplevel)
|
215
|
-
xml.terms **attr_code(attrs) do |section|
|
216
|
-
section.title { |t| t << node.title }
|
217
|
-
(s = node.attr("source")) && s.split(/,/).each do |s1|
|
218
|
-
section.termdocsource(nil, **attr_code(bibitemid: s1))
|
219
|
-
end
|
220
|
-
section << node.content
|
221
|
-
end
|
222
|
-
end
|
223
|
-
|
224
147
|
def introduction_parse(attrs, xml, node)
|
225
148
|
xml.introduction **attr_code(attrs) do |xml_section|
|
226
149
|
xml_section.title { |t| t << @i18n.introduction }
|
@@ -2,7 +2,7 @@ module Asciidoctor
|
|
2
2
|
module Standoc
|
3
3
|
module Table
|
4
4
|
def table_attrs(node)
|
5
|
-
keep_attrs(node).merge( id: Utils::anchor_or_uuid(node),
|
5
|
+
keep_attrs(node).merge( id: Metanorma::Utils::anchor_or_uuid(node),
|
6
6
|
headerrows: node.attr("headerrows"),
|
7
7
|
unnumbered: node.option?("unnumbered") ? "true" : nil,
|
8
8
|
number: node.attr("number"),
|
@@ -0,0 +1,125 @@
|
|
1
|
+
module Asciidoctor
|
2
|
+
module Standoc
|
3
|
+
module Section
|
4
|
+
def in_terms?
|
5
|
+
@term_def
|
6
|
+
end
|
7
|
+
|
8
|
+
def nonterm_symbols_parse(attrs, xml, node)
|
9
|
+
defs = @definitions
|
10
|
+
@definitions = false
|
11
|
+
clause_parse(attrs, xml, node)
|
12
|
+
@definitions = defs
|
13
|
+
end
|
14
|
+
|
15
|
+
def symbols_attrs(node, a)
|
16
|
+
case sectiontype1(node)
|
17
|
+
when "symbols" then a.merge(type: "symbols")
|
18
|
+
when "abbreviated terms", "abbreviations" then a.merge(type: "abbreviated_terms")
|
19
|
+
else
|
20
|
+
a
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def symbols_parse(attr, xml, node)
|
25
|
+
node.role == "nonterm" and return nonterm_symbols_parse(attr, xml, node)
|
26
|
+
xml.definitions **attr_code(attr) do |xml_section|
|
27
|
+
xml_section.title { |t| t << node.title }
|
28
|
+
defs = @definitions
|
29
|
+
termdefs = @term_def
|
30
|
+
@definitions = true
|
31
|
+
@term_def = false
|
32
|
+
xml_section << node.content
|
33
|
+
@definitions = defs
|
34
|
+
@term_def = termdefs
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def nonterm_term_def_subclause_parse(attrs, xml, node)
|
39
|
+
defs = @term_def
|
40
|
+
@term_def = false
|
41
|
+
clause_parse(attrs, xml, node)
|
42
|
+
@term_def = defs
|
43
|
+
end
|
44
|
+
|
45
|
+
def terms_boilerplate_parse(attrs, xml, node)
|
46
|
+
defs = @term_def
|
47
|
+
@term_def = false
|
48
|
+
clause_parse(attrs.merge(type: "boilerplate"), xml, node)
|
49
|
+
@term_def = defs
|
50
|
+
end
|
51
|
+
|
52
|
+
# subclause contains subclauses
|
53
|
+
def term_def_subclause_parse(attrs, xml, node)
|
54
|
+
node.role == "nonterm" and return nonterm_term_def_subclause_parse(attrs, xml, node)
|
55
|
+
node.role == "boilerplate" and return terms_boilerplate_parse(attrs, xml, node)
|
56
|
+
st = sectiontype(node, false)
|
57
|
+
return symbols_parse(attrs, xml, node) if @definitions
|
58
|
+
sub = node.find_by(context: :section) { |s| s.level == node.level + 1 }
|
59
|
+
sub.empty? || (return term_def_parse(attrs, xml, node, false))
|
60
|
+
st == "symbols and abbreviated terms" and (return symbols_parse(attrs, xml, node))
|
61
|
+
st == "terms and definitions" and return clause_parse(attrs, xml, node)
|
62
|
+
term_def_subclause_parse1(attrs, xml, node)
|
63
|
+
end
|
64
|
+
|
65
|
+
def term_def_subclause_parse1(attrs, xml, node)
|
66
|
+
xml.term **attr_code(attrs) do |xml_section|
|
67
|
+
xml_section.preferred { |name| name << node.title }
|
68
|
+
xml_section << node.content
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def term_def_parse(attrs, xml, node, toplevel)
|
73
|
+
xml.terms **attr_code(attrs) do |section|
|
74
|
+
section.title { |t| t << node.title }
|
75
|
+
(s = node.attr("source")) && s.split(/,/).each do |s1|
|
76
|
+
section.termdocsource(nil, **attr_code(bibitemid: s1))
|
77
|
+
end
|
78
|
+
section << node.content
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def term_source_attrs(seen_xref)
|
83
|
+
{ bibitemid: seen_xref.children[0]["target"],
|
84
|
+
format: seen_xref.children[0]["format"], type: "inline" }
|
85
|
+
end
|
86
|
+
|
87
|
+
def add_term_source(xml_t, seen_xref, m)
|
88
|
+
if seen_xref.children[0].name == "concept"
|
89
|
+
xml_t.origin { |o| o << seen_xref.children[0].to_xml }
|
90
|
+
else
|
91
|
+
xml_t.origin seen_xref.children[0].content, **attr_code(term_source_attrs(seen_xref))
|
92
|
+
end
|
93
|
+
m[:text] && xml_t.modification do |mod|
|
94
|
+
mod.p { |p| p << m[:text].sub(/^\s+/, "") }
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
TERM_REFERENCE_RE_STR = <<~REGEXP.freeze
|
99
|
+
^(?<xref><(xref|concept)[^>]+>([^<]*</(xref|concept)>)?)
|
100
|
+
(,\s(?<text>.*))?
|
101
|
+
$
|
102
|
+
REGEXP
|
103
|
+
TERM_REFERENCE_RE =
|
104
|
+
Regexp.new(TERM_REFERENCE_RE_STR.gsub(/\s/, "").gsub(/_/, "\\s"),
|
105
|
+
Regexp::IGNORECASE | Regexp::MULTILINE)
|
106
|
+
|
107
|
+
def extract_termsource_refs(text, node)
|
108
|
+
matched = TERM_REFERENCE_RE.match text
|
109
|
+
matched.nil? and @log.add("AsciiDoc Input", node, "term reference not in expected format: #{text}")
|
110
|
+
matched
|
111
|
+
end
|
112
|
+
|
113
|
+
def termsource(node)
|
114
|
+
matched = extract_termsource_refs(node.content, node) || return
|
115
|
+
noko do |xml|
|
116
|
+
attrs = { status: matched[:text] ? "modified" : "identical" }
|
117
|
+
xml.termsource **attrs do |xml_t|
|
118
|
+
seen_xref = Nokogiri::XML.fragment(matched[:xref])
|
119
|
+
add_term_source(xml_t, seen_xref, matched)
|
120
|
+
end
|
121
|
+
end.join("\n")
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|