metanorma-standoc 1.10.5 → 1.11.0
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 +19 -23
- data/Rakefile +1 -1
- data/lib/asciidoctor/standoc/base.rb +14 -17
- data/lib/asciidoctor/standoc/basicdoc.rng +21 -4
- data/lib/asciidoctor/standoc/blocks.rb +26 -23
- data/lib/asciidoctor/standoc/blocks_notes.rb +17 -22
- data/lib/asciidoctor/standoc/cleanup.rb +46 -12
- data/lib/asciidoctor/standoc/cleanup_block.rb +5 -70
- data/lib/asciidoctor/standoc/cleanup_image.rb +6 -7
- data/lib/asciidoctor/standoc/cleanup_inline.rb +44 -102
- data/lib/asciidoctor/standoc/cleanup_maths.rb +5 -6
- data/lib/asciidoctor/standoc/cleanup_ref.rb +5 -0
- data/lib/asciidoctor/standoc/cleanup_reqt.rb +51 -33
- data/lib/asciidoctor/standoc/cleanup_section_names.rb +5 -5
- data/lib/asciidoctor/standoc/cleanup_symbols.rb +48 -0
- data/lib/asciidoctor/standoc/cleanup_table.rb +68 -0
- data/lib/asciidoctor/standoc/cleanup_terms.rb +38 -78
- data/lib/asciidoctor/standoc/cleanup_terms_designations.rb +162 -0
- data/lib/asciidoctor/standoc/cleanup_text.rb +5 -2
- data/lib/asciidoctor/standoc/cleanup_xref.rb +107 -0
- data/lib/asciidoctor/standoc/converter.rb +15 -0
- data/lib/asciidoctor/standoc/inline.rb +7 -5
- data/lib/asciidoctor/standoc/isodoc.rng +435 -78
- data/lib/asciidoctor/standoc/lists.rb +15 -15
- data/lib/asciidoctor/standoc/macros.rb +14 -43
- data/lib/asciidoctor/standoc/macros_note.rb +45 -0
- data/lib/asciidoctor/standoc/macros_plantuml.rb +29 -14
- data/lib/asciidoctor/standoc/macros_terms.rb +82 -20
- data/lib/asciidoctor/standoc/ref_sect.rb +24 -17
- data/lib/asciidoctor/standoc/reqt.rb +2 -2
- data/lib/asciidoctor/standoc/reqt.rng +23 -2
- data/lib/asciidoctor/standoc/term_lookup_cleanup.rb +50 -11
- data/lib/asciidoctor/standoc/terms.rb +21 -3
- data/lib/asciidoctor/standoc/utils.rb +36 -23
- data/lib/asciidoctor/standoc/validate.rb +45 -27
- data/lib/asciidoctor/standoc/validate_section.rb +5 -2
- data/lib/metanorma/standoc/version.rb +1 -1
- data/metanorma-standoc.gemspec +1 -1
- data/spec/asciidoctor/base_spec.rb +4 -36
- data/spec/asciidoctor/blank_spec.rb +37 -0
- data/spec/asciidoctor/blocks_spec.rb +296 -47
- data/spec/asciidoctor/cleanup_blocks_spec.rb +1018 -0
- data/spec/asciidoctor/cleanup_sections_spec.rb +153 -12
- data/spec/asciidoctor/cleanup_spec.rb +179 -1265
- data/spec/asciidoctor/cleanup_terms_spec.rb +990 -0
- data/spec/asciidoctor/inline_spec.rb +38 -2
- data/spec/asciidoctor/lists_spec.rb +6 -6
- data/spec/asciidoctor/macros_plantuml_spec.rb +37 -2
- data/spec/asciidoctor/macros_spec.rb +226 -138
- data/spec/asciidoctor/refs_spec.rb +4 -26
- data/spec/asciidoctor/section_spec.rb +18 -18
- data/spec/asciidoctor/validate_spec.rb +109 -1
- data/spec/assets/xref_error.adoc +1 -0
- data/spec/fixtures/datamodel_description_sections_tree.xml +327 -326
- data/spec/spec_helper.rb +6 -7
- data/spec/vcr_cassettes/dated_iso_ref_joint_iso_iec.yml +51 -51
- data/spec/vcr_cassettes/dated_iso_ref_joint_iso_iec1.yml +13 -13
- data/spec/vcr_cassettes/isobib_get_123.yml +13 -13
- data/spec/vcr_cassettes/isobib_get_123_1.yml +26 -26
- data/spec/vcr_cassettes/isobib_get_123_1_fr.yml +34 -34
- data/spec/vcr_cassettes/isobib_get_123_2001.yml +12 -12
- data/spec/vcr_cassettes/isobib_get_124.yml +13 -13
- data/spec/vcr_cassettes/rfcbib_get_rfc8341.yml +16 -16
- data/spec/vcr_cassettes/separates_iev_citations_by_top_level_clause.yml +51 -49
- metadata +13 -5
@@ -15,9 +15,8 @@ module Asciidoctor
|
|
15
15
|
def svgmap_moveattrs(xmldoc)
|
16
16
|
xmldoc.xpath("//svgmap").each do |s|
|
17
17
|
f = s.at(".//figure") or next
|
18
|
-
|
18
|
+
(t = s.at("./name")) && !f.at("./name") and
|
19
19
|
f.children.first.previous = t.remove
|
20
|
-
end
|
21
20
|
if s["id"] && guid?(f["id"])
|
22
21
|
f["id"] = s["id"]
|
23
22
|
s.delete("id")
|
@@ -26,13 +25,13 @@ module Asciidoctor
|
|
26
25
|
end
|
27
26
|
end
|
28
27
|
|
29
|
-
def svgmap_moveattrs1(
|
28
|
+
def svgmap_moveattrs1(svgmap, figure)
|
30
29
|
%w(unnumbered number subsequence keep-with-next
|
31
|
-
keep-lines-together).each do |a|
|
32
|
-
next if
|
30
|
+
keep-lines-together tag multilingual-rendering).each do |a|
|
31
|
+
next if figure[a] || !svgmap[a]
|
33
32
|
|
34
|
-
|
35
|
-
|
33
|
+
figure[a] = svgmap[a]
|
34
|
+
svgmap.delete(a)
|
36
35
|
end
|
37
36
|
end
|
38
37
|
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require "metanorma-utils"
|
2
|
+
require "digest"
|
2
3
|
|
3
4
|
module Asciidoctor
|
4
5
|
module Standoc
|
@@ -55,114 +56,30 @@ module Asciidoctor
|
|
55
56
|
end
|
56
57
|
end
|
57
58
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
(?<ref>[^"][^ \\t\\n,:-]*|"[^"]+")
|
64
|
-
(-(?<to>[^"][^ \\t\\n,:-]*|"[^"]"))?|
|
65
|
-
(?<locality2>whole|locality:[^ \\t\\n\\r:,;=]+))(?<punct>[,:;]?)\\s*
|
66
|
-
(?<text>.*)$
|
67
|
-
REGEXP
|
68
|
-
LOCALITY_RE = Regexp.new(LOCALITY_REGEX_STR.gsub(/\s/, ""),
|
69
|
-
Regexp::IGNORECASE | Regexp::MULTILINE)
|
70
|
-
|
71
|
-
def tq(text)
|
72
|
-
text.sub(/^"/, "").sub(/"$/, "")
|
73
|
-
end
|
74
|
-
|
75
|
-
def extract_localities(elem)
|
76
|
-
f = elem&.children&.first or return
|
77
|
-
f.text? or return
|
78
|
-
head = f.remove.text
|
79
|
-
tail = elem&.children&.remove
|
80
|
-
extract_localities1(elem, head)
|
81
|
-
tail and elem << tail
|
82
|
-
end
|
83
|
-
|
84
|
-
def extract_localities1(elem, text)
|
85
|
-
b = elem.add_child("<localityStack/>").first if LOCALITY_RE.match text
|
86
|
-
while (m = LOCALITY_RE.match text)
|
87
|
-
ref = m[:ref] ? "<referenceFrom>#{tq m[:ref]}</referenceFrom>" : ""
|
88
|
-
refto = m[:to] ? "<referenceTo>#{tq m[:to]}</referenceTo>" : ""
|
89
|
-
loc = m[:locality]&.downcase || m[:locality2]&.downcase
|
90
|
-
b.add_child("<locality type='#{loc}'>#{ref}#{refto}</locality>")
|
91
|
-
text = m[:text]
|
92
|
-
b = elem.add_child("<localityStack/>").first if m[:punct] == ";"
|
93
|
-
end
|
94
|
-
elem.add_child(text) if text
|
95
|
-
end
|
96
|
-
|
97
|
-
def xref_to_eref(elem)
|
98
|
-
elem["bibitemid"] = elem["target"]
|
99
|
-
unless elem["citeas"] = @anchors&.dig(elem["target"], :xref)
|
100
|
-
@internal_eref_namespaces.include?(elem["type"]) or
|
101
|
-
@log.add("Crossreferences", elem,
|
102
|
-
"#{elem['target']} does not have a corresponding "\
|
103
|
-
"anchor ID in the bibliography!")
|
104
|
-
end
|
105
|
-
elem.delete("target")
|
106
|
-
extract_localities(elem) unless elem.children.empty?
|
107
|
-
end
|
108
|
-
|
109
|
-
def xref_cleanup(xmldoc)
|
110
|
-
xmldoc.xpath("//xref").each do |x|
|
111
|
-
/:/.match(x["target"]) and xref_to_internal_eref(x)
|
112
|
-
next unless x.name == "xref"
|
113
|
-
|
114
|
-
if refid? x["target"]
|
115
|
-
x.name = "eref"
|
116
|
-
xref_to_eref(x)
|
117
|
-
else x.delete("type")
|
118
|
-
end
|
119
|
-
end
|
120
|
-
end
|
121
|
-
|
122
|
-
def xref_to_internal_eref(elem)
|
123
|
-
a = elem["target"].split(":", 3)
|
124
|
-
unless a.size < 2 || a[0].empty? || a[1].empty?
|
125
|
-
elem["target"] = "#{a[0]}_#{a[1]}"
|
126
|
-
a.size > 2 and
|
127
|
-
elem.children = %{anchor="#{a[2..-1].join}",#{elem&.children&.text}}
|
128
|
-
elem["type"] = a[0]
|
129
|
-
@internal_eref_namespaces << a[0]
|
130
|
-
elem.name = "eref"
|
131
|
-
xref_to_eref(elem)
|
132
|
-
end
|
133
|
-
end
|
134
|
-
|
135
|
-
def quotesource_cleanup(xmldoc)
|
136
|
-
xmldoc.xpath("//quote/source | //terms/source").each do |x|
|
137
|
-
xref_to_eref(x)
|
59
|
+
def concept_cleanup(xmldoc)
|
60
|
+
xmldoc.xpath("//concept[not(termxref)]").each do |x|
|
61
|
+
term = x.at("./refterm")
|
62
|
+
term&.remove if term&.text&.empty?
|
63
|
+
concept_cleanup1(x)
|
138
64
|
end
|
139
65
|
end
|
140
66
|
|
141
|
-
def
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
x["citeas"] = @anchors&.dig(x["bibitemid"], :xref) or
|
148
|
-
@log.add("Crossreferences", x,
|
149
|
-
"#{x['bibitemid']} does not have a corresponding anchor "\
|
150
|
-
"ID in the bibliography!")
|
151
|
-
extract_localities(x) unless x.children.empty?
|
67
|
+
def concept_cleanup1(elem)
|
68
|
+
elem.children.remove if elem&.children&.text&.strip&.empty?
|
69
|
+
key_extract_locality(elem)
|
70
|
+
if /:/.match?(elem["key"]) then concept_termbase_cleanup(elem)
|
71
|
+
elsif refid? elem["key"] then concept_eref_cleanup(elem)
|
72
|
+
else concept_xref_cleanup(elem)
|
152
73
|
end
|
74
|
+
elem.delete("key")
|
153
75
|
end
|
154
76
|
|
155
|
-
def
|
156
|
-
xmldoc.xpath("//
|
77
|
+
def related_cleanup(xmldoc)
|
78
|
+
xmldoc.xpath("//related[not(termxref)]").each do |x|
|
157
79
|
term = x.at("./refterm")
|
158
|
-
term
|
159
|
-
|
160
|
-
|
161
|
-
if /:/.match?(x["key"]) then concept_termbase_cleanup(x)
|
162
|
-
elsif refid? x["key"] then concept_eref_cleanup(x)
|
163
|
-
else concept_xref_cleanup(x)
|
164
|
-
end
|
165
|
-
x.delete("key")
|
80
|
+
term.replace("<preferred>#{term_expr(term.children.to_xml)}"\
|
81
|
+
"</preferred>")
|
82
|
+
concept_cleanup1(x)
|
166
83
|
end
|
167
84
|
end
|
168
85
|
|
@@ -203,11 +120,13 @@ module Asciidoctor
|
|
203
120
|
end
|
204
121
|
|
205
122
|
IDREF = "//*/@id | //review/@from | //review/@to | "\
|
206
|
-
|
123
|
+
"//callout/@target | //citation/@bibitemid | "\
|
124
|
+
"//eref/@bibitemid".freeze
|
207
125
|
|
208
126
|
def anchor_cleanup(elem)
|
209
127
|
anchor_cleanup1(elem)
|
210
128
|
xreftarget_cleanup(elem)
|
129
|
+
contenthash_id_cleanup(elem)
|
211
130
|
end
|
212
131
|
|
213
132
|
def anchor_cleanup1(elem)
|
@@ -233,6 +152,29 @@ module Asciidoctor
|
|
233
152
|
end
|
234
153
|
end
|
235
154
|
end
|
155
|
+
|
156
|
+
def guid?(str)
|
157
|
+
/^_[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/
|
158
|
+
.match?(str)
|
159
|
+
end
|
160
|
+
|
161
|
+
def contenthash_id_cleanup(doc)
|
162
|
+
ids = doc.xpath("//*[@id]").each_with_object({}) do |x, m|
|
163
|
+
next unless guid?(x["id"])
|
164
|
+
|
165
|
+
m[x["id"]] = contenthash(x)
|
166
|
+
x["id"] = m[x["id"]]
|
167
|
+
end
|
168
|
+
[%w(review from), %(review to), %(callout target), %(eref bibitemid),
|
169
|
+
%(citation bibitemid), %(xref target), %(xref to)].each do |a|
|
170
|
+
doc.xpath("//#{a[0]}").each { |x| ids[a[1]] and x[a[1]] = ids[a[1]] }
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
def contenthash(elem)
|
175
|
+
Digest::MD5.hexdigest("#{elem.path}////#{elem.text}")
|
176
|
+
.sub(/^(.{8})(.{4})(.{4})(.{4})(.{12})$/, "_\\1-\\2-\\3-\\4-\\5")
|
177
|
+
end
|
236
178
|
end
|
237
179
|
end
|
238
180
|
end
|
@@ -69,13 +69,12 @@ module Asciidoctor
|
|
69
69
|
return false if char.length > 1
|
70
70
|
|
71
71
|
if /\p{Greek}/.match?(char)
|
72
|
-
/\p{Lower}/.match(char) && !mathml_mi_italics[:lowergreek] ||
|
73
|
-
/\p{Upper}/.match(char) && !mathml_mi_italics[:uppergreek]
|
72
|
+
(/\p{Lower}/.match(char) && !mathml_mi_italics[:lowergreek]) ||
|
73
|
+
(/\p{Upper}/.match(char) && !mathml_mi_italics[:uppergreek])
|
74
74
|
elsif /\p{Latin}/.match?(char)
|
75
|
-
/\p{Lower}/.match(char) && !mathml_mi_italics[:lowerroman] ||
|
76
|
-
/\p{Upper}/.match(char) && !mathml_mi_italics[:upperroman]
|
77
|
-
else
|
78
|
-
false
|
75
|
+
(/\p{Lower}/.match(char) && !mathml_mi_italics[:lowerroman]) ||
|
76
|
+
(/\p{Upper}/.match(char) && !mathml_mi_italics[:upperroman])
|
77
|
+
else false
|
79
78
|
end
|
80
79
|
end
|
81
80
|
|
@@ -3,37 +3,61 @@ module Asciidoctor
|
|
3
3
|
module Cleanup
|
4
4
|
def requirement_cleanup(xmldoc)
|
5
5
|
requirement_metadata(xmldoc)
|
6
|
-
requirement_descriptions(xmldoc)
|
7
6
|
requirement_inherit(xmldoc)
|
7
|
+
requirement_descriptions(xmldoc)
|
8
8
|
end
|
9
9
|
|
10
10
|
REQRECPER = "//requirement | //recommendation | //permission".freeze
|
11
11
|
|
12
12
|
def requirement_inherit(xmldoc)
|
13
13
|
xmldoc.xpath(REQRECPER).each do |r|
|
14
|
-
ins = r
|
15
|
-
r.at("./description | ./measurementtarget | ./specification | "\
|
16
|
-
"./verification | ./import | ./description | ./requirement | "\
|
17
|
-
"./recommendation | ./permission | ./component")
|
14
|
+
ins = requirement_inherit_insert(r)
|
18
15
|
r.xpath("./*//inherit").each { |i| ins.previous = i }
|
19
16
|
end
|
20
17
|
end
|
21
18
|
|
19
|
+
def requirement_inherit_insert(reqt)
|
20
|
+
ins = reqt.at("./classification") || reqt.at(
|
21
|
+
"./description | ./measurementtarget | ./specification | "\
|
22
|
+
"./verification | ./import | ./description | ./component | "\
|
23
|
+
"./requirement | ./recommendation | ./permission",
|
24
|
+
) and return ins
|
25
|
+
requirement_inherit_insert1(reqt)
|
26
|
+
end
|
27
|
+
|
28
|
+
def requirement_inherit_insert1(reqt)
|
29
|
+
if t = reqt.at("./title")
|
30
|
+
t.next = " "
|
31
|
+
t.next
|
32
|
+
else
|
33
|
+
if reqt.children.empty? then reqt.add_child(" ")
|
34
|
+
else reqt.children.first.previous = " "
|
35
|
+
end
|
36
|
+
reqt.children.first
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
22
40
|
def requirement_descriptions(xmldoc)
|
23
41
|
xmldoc.xpath(REQRECPER).each do |r|
|
42
|
+
r.xpath(".//p[not(./*)][normalize-space(.)='']").each(&:remove)
|
24
43
|
r.children.each do |e|
|
25
|
-
|
26
|
-
%w(requirement recommendation permission).include?(e.name))
|
27
|
-
next if e.text.strip.empty?
|
28
|
-
t = Nokogiri::XML::Element.new("description", r)
|
29
|
-
e.before(t)
|
30
|
-
t.children = e.remove
|
31
|
-
end
|
44
|
+
requirement_description_wrap(r, e)
|
32
45
|
end
|
33
46
|
requirement_description_cleanup1(r)
|
34
47
|
end
|
35
48
|
end
|
36
49
|
|
50
|
+
def requirement_description_wrap(reqt, text)
|
51
|
+
return if text.element? && (reqt_subpart(text.name) ||
|
52
|
+
%w(requirement recommendation
|
53
|
+
permission).include?(text.name)) ||
|
54
|
+
text.text.strip.empty?
|
55
|
+
|
56
|
+
t = Nokogiri::XML::Element.new("description", reqt)
|
57
|
+
text.before(t)
|
58
|
+
t.children = text.remove
|
59
|
+
end
|
60
|
+
|
37
61
|
def requirement_description_cleanup1(reqt)
|
38
62
|
while d = reqt.at("./description[following-sibling::*[1]"\
|
39
63
|
"[self::description]]")
|
@@ -48,45 +72,39 @@ module Asciidoctor
|
|
48
72
|
def requirement_metadata(xmldoc)
|
49
73
|
xmldoc.xpath(REQRECPER).each do |r|
|
50
74
|
dl = r&.at("./dl[@metadata = 'true']")&.remove or next
|
51
|
-
requirement_metadata1(r, dl)
|
75
|
+
requirement_metadata1(r, dl, r.at("./title"))
|
52
76
|
end
|
53
77
|
end
|
54
78
|
|
55
|
-
def
|
56
|
-
|
79
|
+
def requirement_metadata1_tags
|
80
|
+
%w(label subject inherit)
|
81
|
+
end
|
82
|
+
|
83
|
+
def requirement_metadata1(reqt, dlist, ins)
|
84
|
+
unless ins
|
57
85
|
reqt.children.first.previous = " "
|
58
86
|
ins = reqt.children.first
|
59
87
|
end
|
60
|
-
%w(
|
61
|
-
|
88
|
+
%w(obligation model type).each do |a|
|
89
|
+
dl_to_attrs(reqt, dlist, a)
|
62
90
|
end
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
def reqt_dl_to_elems(ins, reqt, dlist, name)
|
67
|
-
if a = reqt.at("./#{name}[last()]")
|
68
|
-
ins = a
|
91
|
+
requirement_metadata1_tags.each do |a|
|
92
|
+
ins = dl_to_elems(ins, reqt, dlist, a)
|
69
93
|
end
|
70
|
-
|
71
|
-
val = e.at("./following::dd/p") || e.at("./following::dd")
|
72
|
-
val.name = name
|
73
|
-
ins.next = val
|
74
|
-
ins = ins.next
|
75
|
-
end
|
76
|
-
ins
|
94
|
+
reqt_dl_to_classif(ins, reqt, dlist)
|
77
95
|
end
|
78
96
|
|
79
97
|
def reqt_dl_to_classif(ins, reqt, dlist)
|
80
|
-
if a = reqt.at("./classification[last()]")
|
81
|
-
ins = a
|
82
|
-
end
|
98
|
+
if a = reqt.at("./classification[last()]") then ins = a end
|
83
99
|
dlist.xpath("./dt[text()='classification']").each do |e|
|
84
100
|
val = e.at("./following::dd/p") || e.at("./following::dd")
|
85
101
|
req_classif_parse(val.text).each do |r|
|
86
102
|
ins.next = "<classification><tag>#{r[0]}</tag>"\
|
87
103
|
"<value>#{r[1]}</value></classification>"
|
104
|
+
ins = ins.next
|
88
105
|
end
|
89
106
|
end
|
107
|
+
ins
|
90
108
|
end
|
91
109
|
end
|
92
110
|
end
|
@@ -78,12 +78,12 @@ module Asciidoctor
|
|
78
78
|
def sections_variant_title_cleanup(xml)
|
79
79
|
path = SECTION_CONTAINERS.map { |x| "./ancestor::#{x}" }.join(" | ")
|
80
80
|
xml.xpath("//p[@variant_title]").each do |p|
|
81
|
+
p.name = "variant-title"
|
82
|
+
p.delete("id")
|
83
|
+
p.delete("variant_title")
|
81
84
|
p.xpath("(#{path})[last()]").each do |sect|
|
82
|
-
|
83
|
-
|
84
|
-
if ins = sect.at("./title") then ins.next = p
|
85
|
-
else sect.children.first.previous = p
|
86
|
-
end
|
85
|
+
ins = sect.at("./title") and ins.next = p or
|
86
|
+
sect.children.first.previous = p
|
87
87
|
end
|
88
88
|
end
|
89
89
|
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Asciidoctor
|
2
|
+
module Standoc
|
3
|
+
module Cleanup
|
4
|
+
# Indices sort after letter but before any following
|
5
|
+
# letter (x, x_m, x_1, xa); we use colon to force that sort order.
|
6
|
+
# Numbers sort *after* letters; we use thorn to force that sort order.
|
7
|
+
def symbol_key(sym)
|
8
|
+
key = sym.dup
|
9
|
+
key.traverse do |n|
|
10
|
+
n.name == "math" and
|
11
|
+
n.replace(grkletters(MathML2AsciiMath.m2a(n.to_xml)))
|
12
|
+
end
|
13
|
+
ret = Nokogiri::XML(key.to_xml)
|
14
|
+
HTMLEntities.new.decode(ret.text.downcase)
|
15
|
+
.gsub(/[\[\]{}<>()]/, "").gsub(/\s/m, "")
|
16
|
+
.gsub(/[[:punct:]]|[_^]/, ":\\0").gsub(/`/, "")
|
17
|
+
.gsub(/[0-9]+/, "þ\\0")
|
18
|
+
end
|
19
|
+
|
20
|
+
def grkletters(text)
|
21
|
+
text.gsub(/\b(alpha|beta|gamma|delta|epsilon|zeta|eta|theta|iota|kappa|
|
22
|
+
lambda|mu|nu|xi|omicron|pi|rho|sigma|tau|upsilon|phi|chi|
|
23
|
+
psi|omega)\b/xi, "&\\1;")
|
24
|
+
end
|
25
|
+
|
26
|
+
def extract_symbols_list(dlist)
|
27
|
+
dl_out = []
|
28
|
+
dlist.xpath("./dt | ./dd").each do |dtd|
|
29
|
+
if dtd.name == "dt"
|
30
|
+
dl_out << { dt: dtd.remove, key: symbol_key(dtd) }
|
31
|
+
else
|
32
|
+
dl_out.last[:dd] = dtd.remove
|
33
|
+
end
|
34
|
+
end
|
35
|
+
dl_out
|
36
|
+
end
|
37
|
+
|
38
|
+
def symbols_cleanup(docxml)
|
39
|
+
docxml.xpath("//definitions/dl").each do |dl|
|
40
|
+
dl_out = extract_symbols_list(dl)
|
41
|
+
dl_out.sort! { |a, b| a[:key] <=> b[:key] || a[:dt] <=> b[:dt] }
|
42
|
+
dl.children = dl_out.map { |d| d[:dt].to_s + d[:dd].to_s }.join("\n")
|
43
|
+
end
|
44
|
+
docxml
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module Asciidoctor
|
2
|
+
module Standoc
|
3
|
+
module Cleanup
|
4
|
+
def dl1_table_cleanup(xmldoc)
|
5
|
+
q = "//table/following-sibling::*[1][self::dl]"
|
6
|
+
xmldoc.xpath(q).each do |s|
|
7
|
+
s["key"] == "true" and s.previous_element << s.remove
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
# move Key dl after table footer
|
12
|
+
def dl2_table_cleanup(xmldoc)
|
13
|
+
q = "//table/following-sibling::*[1][self::p]"
|
14
|
+
xmldoc.xpath(q).each do |s|
|
15
|
+
if s.text =~ /^\s*key[^a-z]*$/i && s&.next_element&.name == "dl"
|
16
|
+
s.next_element["key"] = "true"
|
17
|
+
s.previous_element << s.next_element.remove
|
18
|
+
s.remove
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def insert_thead(table)
|
24
|
+
thead = table.at("./thead")
|
25
|
+
return thead unless thead.nil?
|
26
|
+
|
27
|
+
if tname = table.at("./name")
|
28
|
+
thead = tname.add_next_sibling("<thead/>").first
|
29
|
+
return thead
|
30
|
+
end
|
31
|
+
table.children.first.add_previous_sibling("<thead/>").first
|
32
|
+
end
|
33
|
+
|
34
|
+
def header_rows_cleanup(xmldoc)
|
35
|
+
xmldoc.xpath("//table[@headerrows]").each do |s|
|
36
|
+
thead = insert_thead(s)
|
37
|
+
(thead.xpath("./tr").size...s["headerrows"].to_i).each do
|
38
|
+
row = s.at("./tbody/tr")
|
39
|
+
row.parent = thead
|
40
|
+
end
|
41
|
+
thead.xpath(".//td").each { |n| n.name = "th" }
|
42
|
+
s.delete("headerrows")
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def table_cleanup(xmldoc)
|
47
|
+
dl1_table_cleanup(xmldoc)
|
48
|
+
dl2_table_cleanup(xmldoc)
|
49
|
+
notes_table_cleanup(xmldoc)
|
50
|
+
header_rows_cleanup(xmldoc)
|
51
|
+
end
|
52
|
+
|
53
|
+
# move notes into table
|
54
|
+
def notes_table_cleanup(xmldoc)
|
55
|
+
nomatches = false
|
56
|
+
until nomatches
|
57
|
+
nomatches = true
|
58
|
+
xmldoc.xpath("//table/following-sibling::*[1]"\
|
59
|
+
"[self::note[not(@keep-separate = 'true')]]").each do |n|
|
60
|
+
n.delete("keep-separate")
|
61
|
+
n.previous_element << n.remove
|
62
|
+
nomatches = false
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|