metanorma-ietf 2.4.1 → 2.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/asciidoctor/ietf/basicdoc.rng +21 -4
- data/lib/asciidoctor/ietf/cleanup.rb +29 -6
- data/lib/asciidoctor/ietf/converter.rb +6 -64
- data/lib/asciidoctor/ietf/ietf.rng +13 -25
- data/lib/asciidoctor/ietf/isodoc.rng +435 -78
- data/lib/asciidoctor/ietf/macros.rb +17 -0
- data/lib/asciidoctor/ietf/reqt.rng +23 -2
- data/lib/isodoc/ietf/blocks.rb +11 -10
- data/lib/isodoc/ietf/cleanup.rb +149 -186
- data/lib/isodoc/ietf/cleanup_inline.rb +76 -0
- data/lib/isodoc/ietf/inline.rb +127 -124
- data/lib/isodoc/ietf/references.rb +23 -9
- data/lib/isodoc/ietf/reqt.rb +63 -59
- data/lib/isodoc/ietf/rfc_convert.rb +2 -0
- data/lib/isodoc/ietf/terms.rb +52 -45
- data/lib/isodoc/ietf/validation.rb +1 -1
- data/lib/metanorma/ietf/version.rb +1 -1
- data/metanorma-ietf.gemspec +1 -3
- metadata +8 -34
@@ -0,0 +1,17 @@
|
|
1
|
+
require "asciidoctor/extensions"
|
2
|
+
|
3
|
+
module Asciidoctor
|
4
|
+
module Ietf
|
5
|
+
class InlineCrefMacro < Asciidoctor::Extensions::InlineMacroProcessor
|
6
|
+
use_dsl
|
7
|
+
named :cref
|
8
|
+
parse_content_as :text
|
9
|
+
using_format :short
|
10
|
+
|
11
|
+
def process(parent, _target, attrs)
|
12
|
+
out = Asciidoctor::Inline.new(parent, :quoted, attrs["text"]).convert
|
13
|
+
%{<crefref>#{out}</crefref>}
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -58,6 +58,14 @@
|
|
58
58
|
<optional>
|
59
59
|
<attribute name="type"/>
|
60
60
|
</optional>
|
61
|
+
<optional>
|
62
|
+
<attribute name="tag"/>
|
63
|
+
</optional>
|
64
|
+
<optional>
|
65
|
+
<attribute name="multilingual-rendering">
|
66
|
+
<ref name="MultilingualRenderingType"/>
|
67
|
+
</attribute>
|
68
|
+
</optional>
|
61
69
|
<optional>
|
62
70
|
<ref name="reqtitle"/>
|
63
71
|
</optional>
|
@@ -101,7 +109,9 @@
|
|
101
109
|
</define>
|
102
110
|
<define name="label">
|
103
111
|
<element name="label">
|
104
|
-
<
|
112
|
+
<oneOrMore>
|
113
|
+
<ref name="TextElement"/>
|
114
|
+
</oneOrMore>
|
105
115
|
</element>
|
106
116
|
</define>
|
107
117
|
<define name="subject">
|
@@ -175,8 +185,19 @@
|
|
175
185
|
<data type="boolean"/>
|
176
186
|
</attribute>
|
177
187
|
</optional>
|
188
|
+
<optional>
|
189
|
+
<attribute name="tag"/>
|
190
|
+
</optional>
|
191
|
+
<optional>
|
192
|
+
<attribute name="multilingual-rendering">
|
193
|
+
<ref name="MultilingualRenderingType"/>
|
194
|
+
</attribute>
|
195
|
+
</optional>
|
178
196
|
<oneOrMore>
|
179
|
-
<
|
197
|
+
<choice>
|
198
|
+
<ref name="BasicBlock"/>
|
199
|
+
<ref name="component"/>
|
200
|
+
</choice>
|
180
201
|
</oneOrMore>
|
181
202
|
</define>
|
182
203
|
<define name="ObligationType">
|
data/lib/isodoc/ietf/blocks.rb
CHANGED
@@ -64,11 +64,11 @@ module IsoDoc
|
|
64
64
|
spacing: node["spacing"])
|
65
65
|
end
|
66
66
|
|
67
|
-
def dt_parse(
|
68
|
-
if
|
69
|
-
term <<
|
67
|
+
def dt_parse(dterm, term)
|
68
|
+
if dterm.elements.empty?
|
69
|
+
term << dterm.text
|
70
70
|
else
|
71
|
-
|
71
|
+
dterm.children.each { |n| parse(n, term) }
|
72
72
|
end
|
73
73
|
end
|
74
74
|
|
@@ -108,7 +108,7 @@ module IsoDoc
|
|
108
108
|
end
|
109
109
|
p << lbl
|
110
110
|
name and !lbl.nil? and p << ": "
|
111
|
-
name
|
111
|
+
name&.children&.each { |e| parse(e, p) }
|
112
112
|
end
|
113
113
|
end
|
114
114
|
|
@@ -139,11 +139,11 @@ module IsoDoc
|
|
139
139
|
@annotation = false
|
140
140
|
end
|
141
141
|
|
142
|
-
def formula_where(
|
143
|
-
return unless
|
142
|
+
def formula_where(dlist, out)
|
143
|
+
return unless dlist
|
144
144
|
|
145
145
|
out.t { |p| p << @i18n.where }
|
146
|
-
parse(
|
146
|
+
parse(dlist, out)
|
147
147
|
end
|
148
148
|
|
149
149
|
def formula_parse1(node, out)
|
@@ -197,8 +197,9 @@ module IsoDoc
|
|
197
197
|
def review_note_parse(node, out)
|
198
198
|
out.cref **attr_code(anchor: node["id"], display: node["display"],
|
199
199
|
source: node["reviewer"]) do |c|
|
200
|
-
name = node.at(ns("./name"))
|
201
|
-
name.children.each { |n| parse(n,
|
200
|
+
if name = node.at(ns("./name"))
|
201
|
+
name.children.each { |n| parse(n, c) }
|
202
|
+
c << " "
|
202
203
|
end
|
203
204
|
node.children.each { |n| parse(n, c) unless n.name == "name" }
|
204
205
|
end
|
data/lib/isodoc/ietf/cleanup.rb
CHANGED
@@ -1,236 +1,199 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
docxml.xpath("//table[descendant::fn]").each do |t|
|
29
|
-
t.xpath(".//fn").each do |a|
|
30
|
-
t << "<aside>#{a.remove.children}</aside>"
|
1
|
+
require_relative "cleanup_inline"
|
2
|
+
|
3
|
+
module IsoDoc
|
4
|
+
module Ietf
|
5
|
+
class RfcConvert < ::IsoDoc::Convert
|
6
|
+
def cleanup(docxml)
|
7
|
+
image_cleanup(docxml)
|
8
|
+
figure_cleanup(docxml)
|
9
|
+
table_cleanup(docxml)
|
10
|
+
footnote_cleanup(docxml)
|
11
|
+
sourcecode_cleanup(docxml)
|
12
|
+
annotation_cleanup(docxml)
|
13
|
+
li_cleanup(docxml)
|
14
|
+
deflist_cleanup(docxml)
|
15
|
+
bookmark_cleanup(docxml)
|
16
|
+
cref_cleanup(docxml)
|
17
|
+
aside_cleanup(docxml)
|
18
|
+
front_cleanup(docxml)
|
19
|
+
u_cleanup(docxml)
|
20
|
+
docxml
|
21
|
+
end
|
22
|
+
|
23
|
+
def li_cleanup(xmldoc)
|
24
|
+
xmldoc.xpath("//li[t]").each do |li|
|
25
|
+
next unless li.elements.size == 1
|
26
|
+
|
27
|
+
li.children = li.elements[0].children
|
31
28
|
end
|
32
29
|
end
|
33
|
-
end
|
34
30
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
31
|
+
def front_cleanup(xmldoc)
|
32
|
+
xmldoc.xpath("//title").each { |s| s.children = s.text }
|
33
|
+
xmldoc.xpath("//reference/front[not(author)]").each do |f|
|
34
|
+
insert = f.at("./seriesInfo[last()]") || f.at("./title")
|
35
|
+
insert.next = "<author surname='Unknown'/>"
|
39
36
|
end
|
40
37
|
end
|
41
|
-
end
|
42
|
-
|
43
|
-
def table_cleanup(docxml)
|
44
|
-
table_footnote_cleanup(docxml)
|
45
|
-
end
|
46
38
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
def figure_data_uri(docxml)
|
55
|
-
docxml.xpath("//artwork").each do |a|
|
56
|
-
next unless %r{^data:image/svg\+xml;base64}.match?(a["src"])
|
57
|
-
|
58
|
-
f = Metanorma::Utils::save_dataimage(a["src"])
|
59
|
-
a.delete("src")
|
60
|
-
a.children = File.read(f).sub(%r{<\?.+\?>}, "")
|
39
|
+
def table_footnote_cleanup(docxml)
|
40
|
+
docxml.xpath("//table[descendant::fn]").each do |t|
|
41
|
+
t.xpath(".//fn").each do |a|
|
42
|
+
t << "<aside>#{a.remove.children}</aside>"
|
43
|
+
end
|
44
|
+
end
|
61
45
|
end
|
62
|
-
end
|
63
46
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
insert.next = a.remove
|
70
|
-
insert = insert.next_element
|
47
|
+
def figure_footnote_cleanup(docxml)
|
48
|
+
docxml.xpath("//figure[descendant::fn]").each do |t|
|
49
|
+
t.xpath(".//fn").each do |a|
|
50
|
+
t << "<aside>#{a.remove.children}</aside>"
|
51
|
+
end
|
71
52
|
end
|
72
|
-
f.remove
|
73
53
|
end
|
74
|
-
end
|
75
54
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
move_preamble(docxml)
|
80
|
-
end
|
55
|
+
def table_cleanup(docxml)
|
56
|
+
table_footnote_cleanup(docxml)
|
57
|
+
end
|
81
58
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
c = a&.xpath("./following-sibling::*")&.remove
|
88
|
-
a = a.remove
|
89
|
-
name and f << name
|
90
|
-
b.empty? or f << "<preamble>#{b.to_xml}</preamble>"
|
91
|
-
a and f << a
|
92
|
-
c.empty? or f << "<postamble>#{c.to_xml}</postamble>"
|
59
|
+
def figure_cleanup(docxml)
|
60
|
+
figure_postamble(docxml)
|
61
|
+
figure_unnest(docxml)
|
62
|
+
figure_footnote_cleanup(docxml)
|
63
|
+
figure_data_uri(docxml)
|
93
64
|
end
|
94
|
-
end
|
95
65
|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
66
|
+
def figure_data_uri(docxml)
|
67
|
+
docxml.xpath("//artwork").each do |a|
|
68
|
+
next unless %r{^data:image/svg\+xml;base64}.match?(a["src"])
|
69
|
+
|
70
|
+
f = Metanorma::Utils::save_dataimage(a["src"])
|
71
|
+
a.delete("src")
|
72
|
+
a.children = File.read(f).sub(%r{<\?.+\?>}, "")
|
102
73
|
end
|
103
74
|
end
|
104
|
-
end
|
105
75
|
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
76
|
+
def figure_unnest(docxml)
|
77
|
+
docxml.xpath("//figure[descendant::figure]").each do |f|
|
78
|
+
insert = f
|
79
|
+
f.xpath(".//figure").each do |a|
|
80
|
+
title = f.at("./name") and a.children.first.previous = title.remove
|
81
|
+
insert.next = a.remove
|
82
|
+
insert = insert.next_element
|
83
|
+
end
|
84
|
+
f.remove
|
111
85
|
end
|
112
86
|
end
|
113
|
-
end
|
114
87
|
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
"//abstract[descendant::fn]").each do |s|
|
120
|
-
s.xpath(".//fn").each do |f|
|
121
|
-
ref = f.at(".//ref") and ref.replace("[#{fn[ref.text]}] ")
|
122
|
-
endnotes << f.remove.children
|
123
|
-
end
|
88
|
+
def figure_postamble(docxml)
|
89
|
+
make_postamble(docxml)
|
90
|
+
move_postamble(docxml)
|
91
|
+
move_preamble(docxml)
|
124
92
|
end
|
125
|
-
end
|
126
93
|
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
94
|
+
def make_postamble(docxml)
|
95
|
+
docxml.xpath("//figure").each do |f|
|
96
|
+
a = f&.at("./artwork | ./sourcecode") || next
|
97
|
+
name = f&.at("./name")&.remove
|
98
|
+
b = a&.xpath("./preceding-sibling::*")&.remove
|
99
|
+
c = a&.xpath("./following-sibling::*")&.remove
|
100
|
+
a = a.remove
|
101
|
+
name and f << name
|
102
|
+
b.empty? or f << "<preamble>#{b.to_xml}</preamble>"
|
103
|
+
a and f << a
|
104
|
+
c.empty? or f << "<postamble>#{c.to_xml}</postamble>"
|
134
105
|
end
|
135
|
-
f.replace(" [#{fn[f.text]}]")
|
136
106
|
end
|
137
|
-
fn
|
138
|
-
end
|
139
107
|
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
108
|
+
def move_postamble(docxml)
|
109
|
+
docxml.xpath("//postamble").each do |p|
|
110
|
+
insert = p.parent
|
111
|
+
p.remove.elements.each do |e|
|
112
|
+
insert.next = e
|
113
|
+
insert = insert.next_element
|
114
|
+
end
|
115
|
+
end
|
145
116
|
end
|
146
|
-
endnotes << "<section><name>Endnotes</name></section>"
|
147
|
-
docxml.at("//back/section[last()]")
|
148
|
-
end
|
149
117
|
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
a.replace("[IMAGE #{i + 1}]")
|
118
|
+
def move_preamble(docxml)
|
119
|
+
docxml.xpath("//preamble").each do |p|
|
120
|
+
insert = p.parent
|
121
|
+
p.remove.elements.each do |e|
|
122
|
+
insert.previous = e
|
123
|
+
end
|
157
124
|
end
|
158
125
|
end
|
159
|
-
end
|
160
126
|
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
127
|
+
# for markup in pseudocode
|
128
|
+
def sourcecode_cleanup(docxml)
|
129
|
+
docxml.xpath("//sourcecode").each do |s|
|
130
|
+
s.children = s.children.to_xml.gsub(%r{<br/>\n}, "\n")
|
131
|
+
.gsub(%r{\s+(<t[ >])}, "\\1").gsub(%r{</t>\s+}, "</t>")
|
132
|
+
sourcecode_remove_markup(s)
|
133
|
+
s.children = "<![CDATA[#{HTMLEntities.new.decode(s
|
168
134
|
.children.to_xml.sub(/\A\n+/, ''))}]]>"
|
135
|
+
end
|
169
136
|
end
|
170
|
-
end
|
171
137
|
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
138
|
+
def sourcecode_remove_markup(node)
|
139
|
+
node.traverse do |n|
|
140
|
+
next if n.text?
|
141
|
+
next if %w(name callout annotation note sourcecode).include? n.name
|
176
142
|
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
143
|
+
case n.name
|
144
|
+
when "br" then n.replace("\n")
|
145
|
+
when "t" then n.replace("\n\n#{n.children}")
|
146
|
+
else
|
147
|
+
n.replace(n.children)
|
148
|
+
end
|
182
149
|
end
|
183
150
|
end
|
184
|
-
end
|
185
151
|
|
186
|
-
|
187
|
-
|
188
|
-
|
152
|
+
def annotation_cleanup(docxml)
|
153
|
+
docxml.xpath("//reference").each do |r|
|
154
|
+
next unless r&.next_element&.name == "aside"
|
189
155
|
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
156
|
+
aside = r.next_element
|
157
|
+
aside.name = "annotation"
|
158
|
+
aside.traverse do |n|
|
159
|
+
n.name == "t" and n.replace(n.children)
|
160
|
+
end
|
161
|
+
r << aside
|
194
162
|
end
|
195
|
-
|
163
|
+
docxml.xpath("//references/aside").each(&:remove)
|
196
164
|
end
|
197
|
-
docxml.xpath("//references/aside").each(&:remove)
|
198
|
-
end
|
199
165
|
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
166
|
+
def deflist_cleanup(docxml)
|
167
|
+
dt_cleanup(docxml)
|
168
|
+
dd_cleanup(docxml)
|
169
|
+
end
|
204
170
|
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
171
|
+
def dt_cleanup(docxml)
|
172
|
+
docxml.xpath("//dt").each do |d|
|
173
|
+
d&.first_element_child&.name == "bookmark" and
|
174
|
+
d["anchor"] ||= d.first_element_child["anchor"]
|
175
|
+
d.xpath(".//t").each do |t|
|
176
|
+
d["anchor"] ||= t["anchor"]
|
177
|
+
t.replace(t.children)
|
178
|
+
end
|
212
179
|
end
|
213
180
|
end
|
214
|
-
end
|
215
181
|
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
182
|
+
def dd_cleanup(docxml)
|
183
|
+
docxml.xpath("//dd").each do |d|
|
184
|
+
d&.first_element_child&.name == "bookmark" and
|
185
|
+
d["anchor"] ||= d.first_element_child["anchor"]
|
186
|
+
end
|
220
187
|
end
|
221
|
-
end
|
222
|
-
|
223
|
-
def bookmark_cleanup(docxml)
|
224
|
-
docxml.xpath("//bookmark").each(&:remove)
|
225
|
-
end
|
226
188
|
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
189
|
+
def aside_cleanup(docxml)
|
190
|
+
docxml.xpath("//t[descendant::aside] | //table[descendant::aside] | "\
|
191
|
+
"//figure[descendant::aside]").each do |p|
|
192
|
+
insert = p
|
193
|
+
p.xpath(".//aside").each do |a|
|
194
|
+
insert.next = a.remove
|
195
|
+
insert = insert.next_element
|
196
|
+
end
|
234
197
|
end
|
235
198
|
end
|
236
199
|
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
module IsoDoc
|
2
|
+
module Ietf
|
3
|
+
class RfcConvert < ::IsoDoc::Convert
|
4
|
+
def u_cleanup(xmldoc)
|
5
|
+
xmldoc.traverse do |n|
|
6
|
+
next unless n.text?
|
7
|
+
next unless %w(t blockquote li dd preamble td th annotation)
|
8
|
+
.include? n.parent.name
|
9
|
+
|
10
|
+
n.replace(n.text.gsub(/[\u0080-\uffff]/, "<u>\\0</u>"))
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def footnote_cleanup(docxml)
|
15
|
+
fn = footnote_refs_cleanup(docxml)
|
16
|
+
endnotes = make_endnotes(docxml)
|
17
|
+
docxml.xpath("//section[descendant::fn] | "\
|
18
|
+
"//abstract[descendant::fn]").each do |s|
|
19
|
+
s.xpath(".//fn").each do |f|
|
20
|
+
ref = f.at(".//ref") and ref.replace("[#{fn[ref.text]}] ")
|
21
|
+
endnotes << f.remove.children
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def footnote_refs_cleanup(docxml)
|
27
|
+
i = 0
|
28
|
+
fn = {}
|
29
|
+
docxml.xpath("//fnref").each do |f|
|
30
|
+
unless fn[f.text]
|
31
|
+
i = i + 1
|
32
|
+
fn[f.text] = i.to_s
|
33
|
+
end
|
34
|
+
f.replace(" [#{fn[f.text]}]")
|
35
|
+
end
|
36
|
+
fn
|
37
|
+
end
|
38
|
+
|
39
|
+
def make_endnotes(docxml)
|
40
|
+
return unless docxml.at("//fn")
|
41
|
+
|
42
|
+
unless endnotes = docxml.at("//back")
|
43
|
+
docxml << "<back/>" and endnotes = docxml.at("//back")
|
44
|
+
end
|
45
|
+
endnotes << "<section><name>Endnotes</name></section>"
|
46
|
+
docxml.at("//back/section[last()]")
|
47
|
+
end
|
48
|
+
|
49
|
+
def image_cleanup(docxml)
|
50
|
+
docxml.xpath("//t[descendant::artwork]").each do |t|
|
51
|
+
insert = t
|
52
|
+
t.xpath(".//artwork").each_with_index do |a, i|
|
53
|
+
insert.next = a.dup
|
54
|
+
insert = insert.next
|
55
|
+
a.replace("[IMAGE #{i + 1}]")
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def bookmark_cleanup(docxml)
|
61
|
+
docxml.xpath("//bookmark").each(&:remove)
|
62
|
+
end
|
63
|
+
|
64
|
+
def cref_cleanup(docxml)
|
65
|
+
docxml.xpath("//cref").each do |c|
|
66
|
+
c.xpath("./t").each do |t|
|
67
|
+
t.replace(t.children)
|
68
|
+
end
|
69
|
+
next unless %w(section abstract).include? c.parent.name
|
70
|
+
|
71
|
+
c.wrap("<t></t>")
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|