metanorma-standoc 1.7.3 → 1.8.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/asciidoctor/standoc/base.rb +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
|