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.
@@ -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
- <text/>
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
- <ref name="BasicBlock"/>
197
+ <choice>
198
+ <ref name="BasicBlock"/>
199
+ <ref name="component"/>
200
+ </choice>
180
201
  </oneOrMore>
181
202
  </define>
182
203
  <define name="ObligationType">
@@ -64,11 +64,11 @@ module IsoDoc
64
64
  spacing: node["spacing"])
65
65
  end
66
66
 
67
- def dt_parse(dt, term)
68
- if dt.elements.empty?
69
- term << dt.text
67
+ def dt_parse(dterm, term)
68
+ if dterm.elements.empty?
69
+ term << dterm.text
70
70
  else
71
- dt.children.each { |n| parse(n, term) }
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 and name.children.each { |n| parse(n, p) }
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(dl, out)
143
- return unless dl
142
+ def formula_where(dlist, out)
143
+ return unless dlist
144
144
 
145
145
  out.t { |p| p << @i18n.where }
146
- parse(dl, out)
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")) and c.name do |div|
201
- name.children.each { |n| parse(n, div) }
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
@@ -1,236 +1,199 @@
1
- module IsoDoc::Ietf
2
- class RfcConvert < ::IsoDoc::Convert
3
- def cleanup(docxml)
4
- image_cleanup(docxml)
5
- figure_cleanup(docxml)
6
- table_cleanup(docxml)
7
- footnote_cleanup(docxml)
8
- sourcecode_cleanup(docxml)
9
- annotation_cleanup(docxml)
10
- deflist_cleanup(docxml)
11
- bookmark_cleanup(docxml)
12
- aside_cleanup(docxml)
13
- front_cleanup(docxml)
14
- docxml
15
- end
16
-
17
- # TODO: insert <u>
18
-
19
- def front_cleanup(xmldoc)
20
- xmldoc.xpath("//title").each { |s| s.children = s.text }
21
- xmldoc.xpath("//reference/front[not(author)]").each do |f|
22
- insert = f.at("./seriesInfo[last()]") || f.at("./title")
23
- insert.next = "<author surname='Unknown'/>"
24
- end
25
- end
26
-
27
- def table_footnote_cleanup(docxml)
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
- def figure_footnote_cleanup(docxml)
36
- docxml.xpath("//figure[descendant::fn]").each do |t|
37
- t.xpath(".//fn").each do |a|
38
- t << "<aside>#{a.remove.children}</aside>"
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
- def figure_cleanup(docxml)
48
- figure_postamble(docxml)
49
- figure_unnest(docxml)
50
- figure_footnote_cleanup(docxml)
51
- figure_data_uri(docxml)
52
- end
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
- def figure_unnest(docxml)
65
- docxml.xpath("//figure[descendant::figure]").each do |f|
66
- insert = f
67
- f.xpath(".//figure").each do |a|
68
- title = f.at("./name") and a.children.first.previous = title.remove
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
- def figure_postamble(docxml)
77
- make_postamble(docxml)
78
- move_postamble(docxml)
79
- move_preamble(docxml)
80
- end
55
+ def table_cleanup(docxml)
56
+ table_footnote_cleanup(docxml)
57
+ end
81
58
 
82
- def make_postamble(docxml)
83
- docxml.xpath("//figure").each do |f|
84
- a = f&.at("./artwork | ./sourcecode") || next
85
- name = f&.at("./name")&.remove
86
- b = a&.xpath("./preceding-sibling::*")&.remove
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
- def move_postamble(docxml)
97
- docxml.xpath("//postamble").each do |p|
98
- insert = p.parent
99
- p.remove.elements.each do |e|
100
- insert.next = e
101
- insert = insert.next_element
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
- def move_preamble(docxml)
107
- docxml.xpath("//preamble").each do |p|
108
- insert = p.parent
109
- p.remove.elements.each do |e|
110
- insert.previous = e
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
- def footnote_cleanup(docxml)
116
- fn = footnote_refs_cleanup(docxml)
117
- endnotes = make_endnotes(docxml)
118
- docxml.xpath("//section[descendant::fn] | "\
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
- def footnote_refs_cleanup(docxml)
128
- i = 0
129
- fn = {}
130
- docxml.xpath("//fnref").each do |f|
131
- unless fn[f.text]
132
- i = i + 1
133
- fn[f.text] = i.to_s
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
- def make_endnotes(docxml)
141
- return unless docxml.at("//fn")
142
-
143
- unless endnotes = docxml.at("//back")
144
- docxml << "<back/>" and endnotes = docxml.at("//back")
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
- def image_cleanup(docxml)
151
- docxml.xpath("//t[descendant::artwork]").each do |t|
152
- insert = t
153
- t.xpath(".//artwork").each_with_index do |a, i|
154
- insert.next = a.dup
155
- insert = insert.next
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
- # for markup in pseudocode
162
- def sourcecode_cleanup(docxml)
163
- docxml.xpath("//sourcecode").each do |s|
164
- s.children = s.children.to_xml.gsub(%r{<br/>\n}, "\n")
165
- .gsub(%r{\s+(<t[ >])}, "\\1").gsub(%r{</t>\s+}, "</t>")
166
- sourcecode_remove_markup(s)
167
- s.children = "<![CDATA[#{HTMLEntities.new.decode(s
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
- def sourcecode_remove_markup(node)
173
- node.traverse do |n|
174
- next if n.text?
175
- next if %w(name callout annotation note sourcecode).include? n.name
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
- case n.name
178
- when "br" then n.replace("\n")
179
- when "t" then n.replace("\n\n#{n.children}")
180
- else
181
- n.replace(n.children)
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
- def annotation_cleanup(docxml)
187
- docxml.xpath("//reference").each do |r|
188
- next unless r&.next_element&.name == "aside"
152
+ def annotation_cleanup(docxml)
153
+ docxml.xpath("//reference").each do |r|
154
+ next unless r&.next_element&.name == "aside"
189
155
 
190
- aside = r.next_element
191
- aside.name = "annotation"
192
- aside.traverse do |n|
193
- n.name == "t" and n.replace(n.children)
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
- r << aside
163
+ docxml.xpath("//references/aside").each(&:remove)
196
164
  end
197
- docxml.xpath("//references/aside").each(&:remove)
198
- end
199
165
 
200
- def deflist_cleanup(docxml)
201
- dt_cleanup(docxml)
202
- dd_cleanup(docxml)
203
- end
166
+ def deflist_cleanup(docxml)
167
+ dt_cleanup(docxml)
168
+ dd_cleanup(docxml)
169
+ end
204
170
 
205
- def dt_cleanup(docxml)
206
- docxml.xpath("//dt").each do |d|
207
- d&.first_element_child&.name == "bookmark" and
208
- d["anchor"] ||= d.first_element_child["anchor"]
209
- d.xpath(".//t").each do |t|
210
- d["anchor"] ||= t["anchor"]
211
- t.replace(t.children)
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
- def dd_cleanup(docxml)
217
- docxml.xpath("//dd").each do |d|
218
- d&.first_element_child&.name == "bookmark" and
219
- d["anchor"] ||= d.first_element_child["anchor"]
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
- def aside_cleanup(docxml)
228
- docxml.xpath("//t[descendant::aside] | //table[descendant::aside] | "\
229
- "//figure[descendant::aside]").each do |p|
230
- insert = p
231
- p.xpath(".//aside").each do |a|
232
- insert.next = a.remove
233
- insert = insert.next_element
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