metanorma-ietf 1.0.10 → 2.0.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/.github/workflows/macos.yml +3 -2
- data/.github/workflows/ubuntu.yml +3 -2
- data/.github/workflows/windows.yml +4 -3
- data/README.adoc +9 -0
- data/lib/asciidoctor/ietf/basicdoc.rng +1045 -0
- data/lib/asciidoctor/ietf/biblio.rng +1142 -0
- data/lib/asciidoctor/ietf/blocks.rb +76 -0
- data/lib/asciidoctor/ietf/converter.rb +211 -0
- data/lib/asciidoctor/ietf/front.rb +143 -0
- data/lib/asciidoctor/ietf/ietf.rng +882 -0
- data/lib/asciidoctor/ietf/isodoc.rng +514 -0
- data/lib/asciidoctor/ietf/isostandard.rng +860 -0
- data/lib/asciidoctor/ietf/reqt.rng +171 -0
- data/lib/asciidoctor/ietf/validate.rb +84 -0
- data/lib/isodoc/ietf/blocks.rb +215 -0
- data/lib/isodoc/ietf/cleanup.rb +220 -0
- data/lib/isodoc/ietf/footnotes.rb +70 -0
- data/lib/isodoc/ietf/front.rb +232 -0
- data/lib/isodoc/ietf/inline.rb +136 -0
- data/lib/isodoc/ietf/metadata.rb +62 -0
- data/lib/isodoc/ietf/references.rb +129 -0
- data/lib/isodoc/ietf/reqt.rb +74 -0
- data/lib/isodoc/ietf/rfc_convert.rb +60 -0
- data/lib/isodoc/ietf/section.rb +162 -0
- data/lib/isodoc/ietf/table.rb +43 -0
- data/lib/isodoc/ietf/terms.rb +65 -0
- data/lib/metanorma-ietf.rb +2 -1
- data/lib/metanorma/ietf/processor.rb +16 -37
- data/lib/metanorma/ietf/version.rb +1 -1
- data/metanorma-ietf.gemspec +3 -3
- metadata +36 -36
- data/Gemfile.lock +0 -327
- data/lib/asciidoctor/rfc.rb +0 -8
- data/lib/asciidoctor/rfc/common/base.rb +0 -544
- data/lib/asciidoctor/rfc/common/front.rb +0 -120
- data/lib/asciidoctor/rfc/common/validate.rb +0 -31
- data/lib/asciidoctor/rfc/v2/base.rb +0 -380
- data/lib/asciidoctor/rfc/v2/blocks.rb +0 -299
- data/lib/asciidoctor/rfc/v2/converter.rb +0 -60
- data/lib/asciidoctor/rfc/v2/front.rb +0 -69
- data/lib/asciidoctor/rfc/v2/inline_anchor.rb +0 -111
- data/lib/asciidoctor/rfc/v2/lists.rb +0 -135
- data/lib/asciidoctor/rfc/v2/table.rb +0 -116
- data/lib/asciidoctor/rfc/v2/validate.rng +0 -716
- data/lib/asciidoctor/rfc/v3/base.rb +0 -330
- data/lib/asciidoctor/rfc/v3/blocks.rb +0 -246
- data/lib/asciidoctor/rfc/v3/converter.rb +0 -62
- data/lib/asciidoctor/rfc/v3/front.rb +0 -122
- data/lib/asciidoctor/rfc/v3/inline_anchor.rb +0 -89
- data/lib/asciidoctor/rfc/v3/lists.rb +0 -176
- data/lib/asciidoctor/rfc/v3/svg.rng +0 -9081
- data/lib/asciidoctor/rfc/v3/table.rb +0 -65
- data/lib/asciidoctor/rfc/v3/validate.rng +0 -2143
@@ -0,0 +1,220 @@
|
|
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
|
+
docxml
|
14
|
+
end
|
15
|
+
|
16
|
+
# TODO: insert <u>
|
17
|
+
|
18
|
+
def table_footnote_cleanup(docxml)
|
19
|
+
docxml.xpath("//table[descendant::fn]").each do |t|
|
20
|
+
t.xpath(".//fn").each do |a|
|
21
|
+
t << "<aside>#{a.remove.children}</aside>"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def figure_footnote_cleanup(docxml)
|
27
|
+
docxml.xpath("//figure[descendant::fn]").each do |t|
|
28
|
+
t.xpath(".//fn").each do |a|
|
29
|
+
t << "<aside>#{a.remove.children}</aside>"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def table_cleanup(docxml)
|
35
|
+
table_footnote_cleanup(docxml)
|
36
|
+
end
|
37
|
+
|
38
|
+
def figure_cleanup(docxml)
|
39
|
+
figure_postamble(docxml)
|
40
|
+
figure_wrap_artwork(docxml)
|
41
|
+
figure_unnest(docxml)
|
42
|
+
figure_footnote_cleanup(docxml)
|
43
|
+
end
|
44
|
+
|
45
|
+
def figure_wrap_artwork(docxml)
|
46
|
+
docxml.xpath("//artwork[not(parent::figure)] | "\
|
47
|
+
"//sourcecode[not(parent::figure)]").each do |a|
|
48
|
+
a.wrap("<figure></figure>")
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def figure_unnest(docxml)
|
53
|
+
docxml.xpath("//figure[descendant::figure]").each do |f|
|
54
|
+
insert = f
|
55
|
+
f.xpath(".//figure").each do |a|
|
56
|
+
insert.next = a.remove
|
57
|
+
insert = insert.next_element
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def figure_postamble(docxml)
|
63
|
+
make_postamble(docxml)
|
64
|
+
move_postamble(docxml)
|
65
|
+
move_preamble(docxml)
|
66
|
+
end
|
67
|
+
|
68
|
+
def make_postamble(docxml)
|
69
|
+
docxml.xpath("//figure").each do |f|
|
70
|
+
a = f&.at("./artwork | ./sourcecode") || next
|
71
|
+
name = f&.at("./name")&.remove
|
72
|
+
b = a&.xpath("./preceding-sibling::*")&.remove
|
73
|
+
c = a&.xpath("./following-sibling::*")&.remove
|
74
|
+
a = a.remove
|
75
|
+
name and f << name
|
76
|
+
b.empty? or f << "<preamble>#{b.to_xml}</preamble>"
|
77
|
+
a and f << a
|
78
|
+
c.empty? or f << "<postamble>#{c.to_xml}</postamble>"
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def move_postamble(docxml)
|
83
|
+
docxml.xpath("//postamble").each do |p|
|
84
|
+
insert = p.parent
|
85
|
+
p.remove.elements.each do |e|
|
86
|
+
insert.next = e
|
87
|
+
insert = insert.next_element
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def move_preamble(docxml)
|
93
|
+
docxml.xpath("//preamble").each do |p|
|
94
|
+
insert = p.parent
|
95
|
+
p.remove.elements.each do |e|
|
96
|
+
insert.previous = e
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def footnote_cleanup(docxml)
|
102
|
+
fn = footnote_refs_cleanup(docxml)
|
103
|
+
endnotes = make_endnotes(docxml)
|
104
|
+
docxml.xpath("//section[descendant::fn] | "\
|
105
|
+
"//abstract[descendant::fn]").each do |s|
|
106
|
+
s.xpath(".//fn").each do |f|
|
107
|
+
ref = f.at(".//ref") and ref.replace("[#{fn[ref.text]}] ")
|
108
|
+
endnotes << f.remove.children
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def footnote_refs_cleanup(docxml)
|
114
|
+
i = 0
|
115
|
+
fn = {}
|
116
|
+
docxml.xpath("//fnref").each do |f|
|
117
|
+
unless fn[f.text]
|
118
|
+
i = i + 1
|
119
|
+
fn[f.text] = i.to_s
|
120
|
+
end
|
121
|
+
f.replace(" [#{fn[f.text]}]")
|
122
|
+
end
|
123
|
+
fn
|
124
|
+
end
|
125
|
+
|
126
|
+
def make_endnotes(docxml)
|
127
|
+
return unless docxml.at("//fn")
|
128
|
+
endnotes = docxml.at("//back") or
|
129
|
+
docxml << "<back/>" and endnotes = docxml.at("//back")
|
130
|
+
endnotes << "<section><name>Endnotes</name></section>"
|
131
|
+
endnotes = docxml.at("//back/section[last()]")
|
132
|
+
end
|
133
|
+
|
134
|
+
def image_cleanup(docxml)
|
135
|
+
docxml.xpath("//t[descendant::artwork]").each do |t|
|
136
|
+
insert = t
|
137
|
+
t.xpath(".//artwork").each_with_index do |a, i|
|
138
|
+
insert.next = a.dup
|
139
|
+
insert = insert.next
|
140
|
+
a.replace("[IMAGE #{i+1}]")
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
# for markup in pseudocode
|
146
|
+
def sourcecode_cleanup(docxml)
|
147
|
+
docxml.xpath("//sourcecode").each do |s|
|
148
|
+
s.children = s.children.to_xml.gsub(%r{<br/>\n}, "\n").
|
149
|
+
gsub(%r{\s+(<t[ >])}, "\\1").gsub(%r{</t>\s+}, "</t>")
|
150
|
+
sourcecode_remove_markup(s)
|
151
|
+
s.children = "<![CDATA[#{s.children.to_xml.sub(/\A\n+/, "")}]]>"
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
def sourcecode_remove_markup(s)
|
156
|
+
s.traverse do |n|
|
157
|
+
next if n.text?
|
158
|
+
next if %w(name callout annotation note sourcecode).include? n.name
|
159
|
+
if n.name == "br" then n.replace("\n")
|
160
|
+
elsif n.name == "t" then n.replace("\n\n#{n.children}")
|
161
|
+
else
|
162
|
+
n.replace(n.children)
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
def annotation_cleanup(docxml)
|
168
|
+
docxml.xpath("//reference").each do |r|
|
169
|
+
next unless r&.next_element&.name == "aside"
|
170
|
+
aside = r.next_element
|
171
|
+
aside.name = "annotation"
|
172
|
+
aside.traverse do |n|
|
173
|
+
n.name == "t" and n.replace(n.children)
|
174
|
+
end
|
175
|
+
r << aside
|
176
|
+
end
|
177
|
+
docxml.xpath("//references/aside").each { |r| r.remove }
|
178
|
+
end
|
179
|
+
|
180
|
+
def deflist_cleanup(docxml)
|
181
|
+
dt_cleanup(docxml)
|
182
|
+
dd_cleanup(docxml)
|
183
|
+
end
|
184
|
+
|
185
|
+
def dt_cleanup(docxml)
|
186
|
+
docxml.xpath("//dt").each do |d|
|
187
|
+
d&.first_element_child&.name == "bookmark" and
|
188
|
+
d["anchor"] ||= d.first_element_child["anchor"]
|
189
|
+
d.xpath(".//t").each do |t|
|
190
|
+
d["anchor"] ||= t["anchor"]
|
191
|
+
t.replace(t.children)
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
def dd_cleanup(docxml)
|
197
|
+
docxml.xpath("//dd").each do |d|
|
198
|
+
d&.first_element_child&.name == "bookmark" and
|
199
|
+
d["anchor"] ||= d.first_element_child["anchor"]
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
def bookmark_cleanup(docxml)
|
204
|
+
docxml.xpath("//bookmark").each do |b|
|
205
|
+
b.remove
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
def aside_cleanup(docxml)
|
210
|
+
docxml.xpath("//t[descendant::aside] | //table[descendant::aside] | "\
|
211
|
+
"//figure[descendant::aside]").each do |p|
|
212
|
+
insert = p
|
213
|
+
p.xpath(".//aside").each do |a|
|
214
|
+
insert.next = a.remove
|
215
|
+
insert = insert.next_element
|
216
|
+
end
|
217
|
+
end
|
218
|
+
end
|
219
|
+
end
|
220
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module IsoDoc::Ietf
|
2
|
+
class RfcConvert < ::IsoDoc::Convert
|
3
|
+
def footnote_parse(node, out)
|
4
|
+
return table_footnote_parse(node, out) if @in_table || @in_figure
|
5
|
+
fn = node["reference"]
|
6
|
+
out.fnref fn
|
7
|
+
make_local_footnote(node, fn, out)
|
8
|
+
end
|
9
|
+
|
10
|
+
def make_local_footnote(node, fn, out)
|
11
|
+
return if @seen_footnote.include?(fn)
|
12
|
+
@in_footnote = true
|
13
|
+
out << make_generic_footnote_text(node, fn)
|
14
|
+
@in_footnote = false
|
15
|
+
@seen_footnote << fn
|
16
|
+
end
|
17
|
+
|
18
|
+
def make_generic_footnote_text(node, fnref)
|
19
|
+
first = node.first_element_child
|
20
|
+
noko do |xml|
|
21
|
+
xml.fn do |div|
|
22
|
+
xml.t **attr_code(anchor: first ? first["id"] : nil) do |div|
|
23
|
+
div.ref fnref
|
24
|
+
first.name == "p" and first.children.each { |n| parse(n, div) }
|
25
|
+
end
|
26
|
+
first.name == "p" and
|
27
|
+
node.elements.drop(1).each { |n| parse(n, xml) } or
|
28
|
+
node.children.each { |n| parse(n, xml) }
|
29
|
+
end
|
30
|
+
end.join
|
31
|
+
end
|
32
|
+
|
33
|
+
def table_footnote_parse(node, out)
|
34
|
+
fn = node["reference"]
|
35
|
+
tid = get_table_ancestor_id(node)
|
36
|
+
make_table_footnote_link(out, tid + fn, fn)
|
37
|
+
# do not output footnote text if we have already seen it for this table
|
38
|
+
return if @seen_footnote.include?(tid + fn)
|
39
|
+
@in_footnote = true
|
40
|
+
out.fn do |a|
|
41
|
+
a << make_table_footnote_text(node, tid + fn, fn)
|
42
|
+
end
|
43
|
+
@in_footnote = false
|
44
|
+
@seen_footnote << (tid + fn)
|
45
|
+
end
|
46
|
+
|
47
|
+
def make_table_footnote_link(out, fnid, fnref)
|
48
|
+
out << " [#{fnref}]"
|
49
|
+
end
|
50
|
+
|
51
|
+
def make_table_footnote_text(node, fnid, fnref)
|
52
|
+
first = node.first_element_child
|
53
|
+
noko do |xml|
|
54
|
+
xml.t **attr_code(anchor: first ? first["id"] : nil) do |div|
|
55
|
+
div << "[#{fnref}] "
|
56
|
+
first.name == "p" and first.children.each { |n| parse(n, div) }
|
57
|
+
end
|
58
|
+
first.name == "p" and
|
59
|
+
node.elements.drop(1).each { |n| parse(n, xml) } or
|
60
|
+
node.children.each { |n| parse(n, xml) }
|
61
|
+
end.join
|
62
|
+
end
|
63
|
+
|
64
|
+
def get_table_ancestor_id(node)
|
65
|
+
table = node.ancestors("table") || node.ancestors("figure")
|
66
|
+
return UUIDTools::UUID.random_create.to_s if table.empty?
|
67
|
+
table.last["id"]
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,232 @@
|
|
1
|
+
require "sterile"
|
2
|
+
|
3
|
+
module IsoDoc::Ietf
|
4
|
+
class RfcConvert < ::IsoDoc::Convert
|
5
|
+
def make_front(out, isoxml)
|
6
|
+
info(isoxml, out)
|
7
|
+
out.front do |front|
|
8
|
+
title isoxml, front
|
9
|
+
seriesinfo isoxml, front
|
10
|
+
author isoxml, front
|
11
|
+
date isoxml, front
|
12
|
+
area isoxml, front
|
13
|
+
workgroup isoxml, front
|
14
|
+
keyword isoxml, front
|
15
|
+
abstract isoxml, front
|
16
|
+
note isoxml, front
|
17
|
+
boilerplate isoxml, front
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def info(isoxml, out)
|
22
|
+
@meta.keywords isoxml, out
|
23
|
+
@meta.areas isoxml, out
|
24
|
+
super
|
25
|
+
end
|
26
|
+
|
27
|
+
def title(isoxml, front)
|
28
|
+
title = @meta.get[:doctitle] or return
|
29
|
+
front.title title, **attr_code(abbrev: @meta.get[:docabbrev],
|
30
|
+
ascii: @meta.get[:docascii] ||
|
31
|
+
title.transliterate)
|
32
|
+
end
|
33
|
+
|
34
|
+
def seriesinfo(isoxml, front)
|
35
|
+
rfc_seriesinfo(isoxml, front) if @meta.get[:doctype] == "Rfc"
|
36
|
+
id_seriesinfo(isoxml, front) if @meta.get[:doctype] == "Internet Draft"
|
37
|
+
end
|
38
|
+
|
39
|
+
def seriesinfo_attr(isoxml)
|
40
|
+
attr_code(value: @meta.get[:docnumber] || "",
|
41
|
+
asciiValue: @meta.get[:docnumber]&.transliterate,
|
42
|
+
status: @meta.get[:stage],
|
43
|
+
stream: isoxml&.at(ns("//bibdata/series[@type = 'stream']/"\
|
44
|
+
"title"))&.text)
|
45
|
+
end
|
46
|
+
|
47
|
+
def rfc_seriesinfo(isoxml, front)
|
48
|
+
front.seriesInfo **seriesinfo_attr(isoxml).merge({name: "RFC",
|
49
|
+
asciiName: "RFC"})
|
50
|
+
i = isoxml&.at(ns("//bibdata/series[@type = 'intended']")) and
|
51
|
+
front.seriesInfo nil,
|
52
|
+
**attr_code(name: "", status: i&.at(ns("./title"))&.text,
|
53
|
+
value: i&.at(ns("./number"))&.text || "")
|
54
|
+
end
|
55
|
+
|
56
|
+
def id_seriesinfo(isoxml, front)
|
57
|
+
front.seriesInfo nil,
|
58
|
+
**seriesinfo_attr(isoxml).merge({name: "Internet-Draft",
|
59
|
+
asciiName: "Internet-Draft"})
|
60
|
+
i = isoxml&.at(ns("//bibdata/series[@type = 'intended']/title"))&.text and
|
61
|
+
front.seriesInfo **attr_code(name: "", value: "", status: i)
|
62
|
+
end
|
63
|
+
|
64
|
+
def author(isoxml, front)
|
65
|
+
isoxml.xpath(("//xmlns:bibdata/xmlns:contributor[xmlns:role/@type = "\
|
66
|
+
"'author' or xmlns:role/@type = 'editor']")).each do |c|
|
67
|
+
role = c.at(ns("./role/@type")).text == "editor" ? "editor" : nil
|
68
|
+
c.at("./organization") and org_author(c, role, front) or
|
69
|
+
person_author(c, role, front)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def person_author_attrs(c, role)
|
74
|
+
return {} if c.nil?
|
75
|
+
full = c&.at(ns("./completename"))&.text
|
76
|
+
init = c&.at(ns("./initial"))&.text ||
|
77
|
+
c&.xpath(ns("./forename")).map { |n| n.text[0] }.join(".")
|
78
|
+
init = nil if init.empty?
|
79
|
+
ret = attr_code(role: role, fullname: full, initials: init,
|
80
|
+
surname: c&.at(ns("./surname"))&.text)
|
81
|
+
pers_author_attrs1(ret, full, init, c)
|
82
|
+
end
|
83
|
+
|
84
|
+
def pers_author_attrs1(ret, full, init, c)
|
85
|
+
full and ret.merge!(attr_code(
|
86
|
+
asciiFullname: full&.transliterate,
|
87
|
+
asciiInitials: init&.transliterate,
|
88
|
+
asciiSurname: c&.at(ns("./surname"))&.text&.transliterate))
|
89
|
+
ret
|
90
|
+
end
|
91
|
+
|
92
|
+
def person_author(c, role, front)
|
93
|
+
front.author **person_author_attrs(c.at(ns("./person/name")), role) do |a|
|
94
|
+
org = c.at(ns("./person/affiliation/organization")) and
|
95
|
+
organization(org, a, c.document.at(ns("//showOnFrontPage")))
|
96
|
+
address(c.xpath(ns(".//address")),
|
97
|
+
c.at(ns(".//phone[not(@type = 'fax')]")),
|
98
|
+
c.at(ns(".//phone[@type = 'fax']")),
|
99
|
+
c.xpath(ns(".//email")), c.xpath(ns(".//uri")), a)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def org_author(c, role, front)
|
104
|
+
front.author **attr_code(role: role) do |a|
|
105
|
+
organization(c.at(ns("./organization")), a,
|
106
|
+
c.document.at(ns("//showOnFrontPage")))
|
107
|
+
address(c.at(ns(".//address")),
|
108
|
+
c.at(ns(".//phone[not(@type = 'fax')]")),
|
109
|
+
c.at(ns(".//phone[@type = 'fax']")),
|
110
|
+
c.at(ns(".//email")), c.at(ns(".//uri")), a)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def organization(org, out, show)
|
115
|
+
name = org.at(ns("./name"))&.text
|
116
|
+
out.organization name, **attr_code(
|
117
|
+
showOnFrontPage: show&.text, ascii: name&.transliterate,
|
118
|
+
asciiAbbrev: org&.at(ns("./abbreviation"))&.transliterate,
|
119
|
+
abbrev: org.at(ns("./abbreviation")))
|
120
|
+
end
|
121
|
+
|
122
|
+
def address(addr, phone, fax, email, uri, out)
|
123
|
+
return unless addr || phone || fax || email || uri
|
124
|
+
out.address do |a|
|
125
|
+
addr and postal(addr, a)
|
126
|
+
phone and a.phone phone.text
|
127
|
+
fax and a.facsimile fax.text
|
128
|
+
email and email(email, a)
|
129
|
+
uri and a.uri uri.text
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
def postal(addr, out)
|
134
|
+
if line = addr.at(ns("./formattedAddress"))
|
135
|
+
line.text.split(/\n/).each do |l|
|
136
|
+
out.postalLine l, **attr_code(ascii: l.transliterate)
|
137
|
+
end
|
138
|
+
else
|
139
|
+
out.postal do |p|
|
140
|
+
postal_detailed(addr, p)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
def postal_detailed(addr, out)
|
146
|
+
addr.xpath(ns("./street")).each do |s|
|
147
|
+
out.street s.text, **attr_code(ascii: s.text.transliterate)
|
148
|
+
end
|
149
|
+
s = addr.at(ns("./city")) and
|
150
|
+
out.city s.text, **attr_code(ascii: s.text.transliterate)
|
151
|
+
s = addr.at(ns("./state")) and
|
152
|
+
out.region s.text, **attr_code(ascii: s.text.transliterate)
|
153
|
+
s = addr.at(ns("./country")) and
|
154
|
+
out.country s.text, **attr_code(ascii: s.text.transliterate)
|
155
|
+
s = addr.at(ns("./postcode")) and
|
156
|
+
out.code s.text, **attr_code(ascii: s.text.transliterate)
|
157
|
+
end
|
158
|
+
|
159
|
+
def email(email, out)
|
160
|
+
ascii = email.text.transliterate
|
161
|
+
out.email email.text,
|
162
|
+
**attr_code(ascii: ascii == email.text ? nil : ascii )
|
163
|
+
end
|
164
|
+
|
165
|
+
def date(isoxml, front)
|
166
|
+
date = @meta.get[:publisheddate] || @meta.get[:circulateddate] || return
|
167
|
+
date.gsub!(/T.*$/, "")
|
168
|
+
attr = date_attr(date) || return
|
169
|
+
front.date **attr_code(attr)
|
170
|
+
end
|
171
|
+
|
172
|
+
def date_attr(date)
|
173
|
+
return nil if date.nil?
|
174
|
+
if date.length == 4 && date =~ /^\d\d\d\d$/ then { year: date }
|
175
|
+
elsif date =~ /^\d\d\d\d-?\d\d$/
|
176
|
+
m = /^(?<year>\d\d\d\d)-(?<month>\d\d)$/.match date
|
177
|
+
{ month: Date::MONTHNAMES[(m[:month]).to_i], year: m[:year] }
|
178
|
+
else
|
179
|
+
begin
|
180
|
+
d = Date.iso8601 date
|
181
|
+
{ day: d.day.to_s.gsub(/^0/, ""), year: d.year,
|
182
|
+
month: Date::MONTHNAMES[d.month] }
|
183
|
+
rescue
|
184
|
+
nil
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
def area(isoxml, front)
|
190
|
+
@meta.get[:areas].each do |w|
|
191
|
+
front.area w
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
def workgroup(isoxml, front)
|
196
|
+
@meta.get[:wg].each do |w|
|
197
|
+
front.workgroup w
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
def keyword(isoxml, front)
|
202
|
+
@meta.get[:keywords].each do |kw|
|
203
|
+
front.keyword kw
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
def abstract(isoxml, front)
|
208
|
+
a = isoxml.at(ns("//preface/abstract | //preface/foreword")) || return
|
209
|
+
front.abstract **attr_code(anchor: a["id"]) do |abs|
|
210
|
+
a.children.reject { |c1| %w(title note).include? c1.name }.each do |c1|
|
211
|
+
parse(c1, abs)
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
def note(isoxml, front)
|
217
|
+
a = isoxml.at(ns("//preface/abstract/note | //preface/foreword/note")) or
|
218
|
+
return
|
219
|
+
front.note **attr_code(removeInRFC: a["removeInRFC"]) do |n|
|
220
|
+
title = a.at(ns("./name")) and n.name do |t|
|
221
|
+
title.children.each { |tt| parse(tt, t) }
|
222
|
+
end
|
223
|
+
a.children.reject { |c1| c1.name == "name" }.each do |c1|
|
224
|
+
parse(c1, n)
|
225
|
+
end
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
def boilerplate(isoxml, front)
|
230
|
+
end
|
231
|
+
end
|
232
|
+
end
|