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,136 @@
|
|
1
|
+
require "mathml2asciimath"
|
2
|
+
|
3
|
+
module IsoDoc::Ietf
|
4
|
+
class RfcConvert < ::IsoDoc::Convert
|
5
|
+
def em_parse(node, out)
|
6
|
+
out.em do |e|
|
7
|
+
node.children.each { |n| parse(n, e) }
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def sup_parse(node, out)
|
12
|
+
out.sup do |e|
|
13
|
+
node.children.each { |n| parse(n, e) }
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def sub_parse(node, out)
|
18
|
+
out.sub do |e|
|
19
|
+
node.children.each { |n| parse(n, e) }
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def tt_parse(node, out)
|
24
|
+
out.tt do |e|
|
25
|
+
node.children.each { |n| parse(n, e) }
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def strong_parse(node, out)
|
30
|
+
out.strong do |e|
|
31
|
+
node.children.each { |n| parse(n, e) }
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def bcp14_parse(node, out)
|
36
|
+
out.bcp14 do |e|
|
37
|
+
node.children.each { |n| parse(n, e) }
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def strike_parse(node, out)
|
42
|
+
node.children.each { |n| parse(n, out) }
|
43
|
+
end
|
44
|
+
|
45
|
+
def smallcap_parse(node, out)
|
46
|
+
node.children.each { |n| parse(n, out) }
|
47
|
+
end
|
48
|
+
|
49
|
+
def keyword_parse(node, out)
|
50
|
+
node.children.each { |n| parse(n, out) }
|
51
|
+
end
|
52
|
+
|
53
|
+
def text_parse(node, out)
|
54
|
+
return if node.nil? || node.text.nil?
|
55
|
+
text = node.to_s
|
56
|
+
out << text
|
57
|
+
end
|
58
|
+
|
59
|
+
def stem_parse(node, out)
|
60
|
+
stem = case node["type"]
|
61
|
+
when "MathML" then MathML2AsciiMath.m2a(node.children.to_xml)
|
62
|
+
else
|
63
|
+
HTMLEntities.new.encode(node.text)
|
64
|
+
end
|
65
|
+
out << "#{@openmathdelim} #{stem} #{@closemathdelim}"
|
66
|
+
end
|
67
|
+
|
68
|
+
def page_break(_out)
|
69
|
+
end
|
70
|
+
|
71
|
+
def br_parse(node, out)
|
72
|
+
if @sourcecode
|
73
|
+
out.br
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def hr_parse(node, out)
|
78
|
+
end
|
79
|
+
|
80
|
+
def link_parse(node, out)
|
81
|
+
out.eref **attr_code(target: node["target"]) do |l|
|
82
|
+
node.children.each { |n| parse(n, l) }
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def image_parse(node, out, caption)
|
87
|
+
attrs = { src: node["src"], title: node["title"],
|
88
|
+
align: node["align"], name: node["filename"],
|
89
|
+
anchor: node["id"], type: "svg",
|
90
|
+
alt: node["alt"] }
|
91
|
+
out.artwork **attr_code(attrs)
|
92
|
+
image_title_parse(out, caption)
|
93
|
+
end
|
94
|
+
|
95
|
+
def image_title_parse(out, caption)
|
96
|
+
unless caption.nil?
|
97
|
+
out.t **{ align: "center", keepWithPrevious: "true" } do |p|
|
98
|
+
p << caption.to_s
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def xref_parse(node, out)
|
104
|
+
out.xref **attr_code(target: node["target"], format: node["format"],
|
105
|
+
relative: node["relative"]) do |l|
|
106
|
+
l << get_linkend(node)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def eref_parse(node, out)
|
111
|
+
linkend = node.children.select { |c| c.name != "locality" }
|
112
|
+
section = eref_clause(node.xpath(ns("./locality")), nil) || ""
|
113
|
+
out.relref **attr_code(target: node["bibitemid"], section: section,
|
114
|
+
displayFormat: node["displayFormat"]) do |l|
|
115
|
+
linkend.each { |n| parse(n, l) }
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def eref_clause(refs, target)
|
120
|
+
refs.each do |l|
|
121
|
+
next unless %w(clause section).include? l["type"]
|
122
|
+
return l&.at(ns("./referenceFrom"))&.text
|
123
|
+
end
|
124
|
+
return nil
|
125
|
+
end
|
126
|
+
|
127
|
+
def index_parse(node, out)
|
128
|
+
out.iref nil, **attr_code(item: node["primary"],
|
129
|
+
subitem: node["secondary"])
|
130
|
+
end
|
131
|
+
|
132
|
+
def bookmark_parse(node, out)
|
133
|
+
out.bookmark nil, **attr_code(anchor: node["id"])
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require "isodoc"
|
2
|
+
|
3
|
+
module IsoDoc
|
4
|
+
module Ietf
|
5
|
+
class Metadata < IsoDoc::Metadata
|
6
|
+
TITLE_RFC = "//bibdata//title[@type='main' and @language='en']".freeze
|
7
|
+
|
8
|
+
def title(isoxml, _out)
|
9
|
+
t = isoxml.at(ns(TITLE_RFC)) and
|
10
|
+
set(:doctitle, t.text)
|
11
|
+
t = isoxml.at(ns(TITLE_RFC.sub(/main/, "abbrev"))) and
|
12
|
+
set(:docabbrev, t.text)
|
13
|
+
t = isoxml.at(ns(TITLE_RFC.sub(/main/, "ascii"))) and
|
14
|
+
set(:docascii, t.text)
|
15
|
+
end
|
16
|
+
|
17
|
+
def relaton_relations
|
18
|
+
%w(included-in described-by derived-from equivalent)
|
19
|
+
# = item describedby convertedfrom alternate
|
20
|
+
end
|
21
|
+
|
22
|
+
def keywords(isoxml, _out)
|
23
|
+
ret = []
|
24
|
+
isoxml.xpath(ns("//bibdata/keyword")).each do |kw|
|
25
|
+
ret << kw.text
|
26
|
+
end
|
27
|
+
set(:keywords, ret)
|
28
|
+
end
|
29
|
+
|
30
|
+
def areas(isoxml, _out)
|
31
|
+
ret = []
|
32
|
+
isoxml.xpath(ns("//bibdata/ext/area")).each do |kw|
|
33
|
+
ret << kw.text
|
34
|
+
end
|
35
|
+
set(:areas, ret)
|
36
|
+
end
|
37
|
+
|
38
|
+
def docid(isoxml, _out)
|
39
|
+
dn = isoxml.at(ns("//bibdata/docnumber"))
|
40
|
+
set(:docnumber, dn&.text&.sub(/^rfc-/, "")&.sub(/\.[a-z0-9]+$/i, ""))
|
41
|
+
end
|
42
|
+
|
43
|
+
def author(xml, _out)
|
44
|
+
super
|
45
|
+
wg(xml)
|
46
|
+
end
|
47
|
+
|
48
|
+
def wg(xml)
|
49
|
+
workgroups = []
|
50
|
+
xml.xpath(ns("//bibdata/ext/editorialgroup/workgroup")).each do |wg|
|
51
|
+
workgroups << wg.text
|
52
|
+
end
|
53
|
+
set(:wg, workgroups)
|
54
|
+
end
|
55
|
+
|
56
|
+
def doctype(isoxml, _out)
|
57
|
+
super
|
58
|
+
set(:doctype, "Rfc") if get[:doctype].nil?
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,129 @@
|
|
1
|
+
module IsoDoc::Ietf
|
2
|
+
class RfcConvert < ::IsoDoc::Convert
|
3
|
+
# TODO displayreference will be implemented as combination of autofetch and user-provided citations
|
4
|
+
|
5
|
+
def bibliography(isoxml, out)
|
6
|
+
isoxml.xpath(ns("//references")).each do |f|
|
7
|
+
out.references **attr_code(anchor: f["id"]) do |div|
|
8
|
+
title = f.at(ns("./title")) and div.name do |name|
|
9
|
+
title.children.each { |n| parse(n, name) }
|
10
|
+
end
|
11
|
+
f.elements.reject do |e|
|
12
|
+
%w(reference title bibitem note).include? e.name
|
13
|
+
end.each { |e| parse(e, div) }
|
14
|
+
biblio_list(f, div, true)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def biblio_list(f, div, biblio)
|
20
|
+
i = 0
|
21
|
+
f.xpath(ns("./bibitem | ./note")).each do |b|
|
22
|
+
next if implicit_reference(b)
|
23
|
+
i += 1 if b.name == "bibitem"
|
24
|
+
if b.name == "note" then note_parse(b, div)
|
25
|
+
elsif(is_ietf(b)) then ietf_bibitem_entry(div, b, i)
|
26
|
+
else
|
27
|
+
nonstd_bibitem(div, b, i, biblio)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def nonstd_bibitem(list, b, ordinal, bibliography)
|
33
|
+
uris = b.xpath(ns("./uri"))
|
34
|
+
list.reference **attr_code(target: uris.empty? ? nil : uris[0]&.text,
|
35
|
+
anchor: b["id"]) do |r|
|
36
|
+
r.front do |f|
|
37
|
+
relaton_to_title(b, f)
|
38
|
+
relaton_to_author(b, f)
|
39
|
+
relaton_to_date(b, f)
|
40
|
+
relaton_to_keyword(b, f)
|
41
|
+
relaton_to_abstract(b, f)
|
42
|
+
end
|
43
|
+
uris[1..-1]&.each do |u|
|
44
|
+
r.format nil, **attr_code(target: u.text, type: u["type"])
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def relaton_to_title(b, f)
|
50
|
+
id = bibitem_ref_code(b)
|
51
|
+
identifier = render_identifier(id)
|
52
|
+
title = b&.at(ns("./title")) || b&.at(ns("./formattedref")) or return
|
53
|
+
f.title do |t|
|
54
|
+
t << "#{identifier}, "
|
55
|
+
title.children.each { |n| parse(n, t) }
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def relaton_to_author(b, f)
|
60
|
+
auths = b.xpath(ns("./contributor[xmlns:role/@type = 'author' or "\
|
61
|
+
"xmlns:role/@type = 'editor']"))
|
62
|
+
auths.empty? and auths = b.xpath(ns("./contributor[xmlns:role/@type = "\
|
63
|
+
"'publisher']"))
|
64
|
+
auths.each do |a|
|
65
|
+
role = a.at(ns("./role[@type = 'editor']")) ? "editor" : nil
|
66
|
+
p = a&.at(ns("./person/name")) and
|
67
|
+
relaton_person_to_author(p, role, f) or
|
68
|
+
relaton_org_to_author(a&.at(ns("./organization")), role, f)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def relaton_person_to_author(p, role, f)
|
73
|
+
fullname = p&.at(ns("./completename"))&.text
|
74
|
+
surname = p&.at(ns("./surname"))&.text
|
75
|
+
initials = p&.xpath(ns("./initial"))&.map { |i| i.text }&.join(" ") ||
|
76
|
+
p&.xpath(ns("./forename"))&.map { |i| i.text[0] }&.join(" ")
|
77
|
+
initials = nil if initials.empty?
|
78
|
+
f.author nil,
|
79
|
+
**attr_code(fullname: fullname, asciiFullname: fullname&.transliterate,
|
80
|
+
role: role, surname: surname, initials: initials,
|
81
|
+
asciiSurname: fullname ? surname&.transliterate : nil,
|
82
|
+
asciiInitials: fullname ? initials&.transliterate : nil)
|
83
|
+
end
|
84
|
+
|
85
|
+
def relaton_org_to_author(o, role, f)
|
86
|
+
name = o&.at(ns("./name"))&.text
|
87
|
+
abbrev = o&.at(ns("./abbreviation"))&.text
|
88
|
+
f.author do |a|
|
89
|
+
f.organization name, **attr_code(ascii: name&.transliterate,
|
90
|
+
abbrev: abbrev)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def relaton_to_date(b, f)
|
95
|
+
date = b.at(ns("./date[@type = 'published']")) ||
|
96
|
+
b.at(ns("./date[@type = 'issued']")) ||
|
97
|
+
b.at(ns("./date[@type = 'circulated']"))
|
98
|
+
return unless date
|
99
|
+
attr = date_attr(date&.at(ns("./on | ./from"))&.text) || return
|
100
|
+
f.date **attr_code(attr)
|
101
|
+
end
|
102
|
+
|
103
|
+
def relaton_to_keyword(b, f)
|
104
|
+
b.xpath(ns("./keyword")).each do |k|
|
105
|
+
f.keyword do |keyword|
|
106
|
+
k.children.each { |n| parse(n, keyword) }
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def relaton_to_abstract(b, f)
|
112
|
+
b.xpath(ns("./abstract")).each do |k|
|
113
|
+
f.abstract do |abstract|
|
114
|
+
k.children.each { |n| parse(n, abstract) }
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def ietf_bibitem_entry(div, b, i)
|
120
|
+
url = b&.at(ns("./uri[@type = 'xml']"))&.text
|
121
|
+
div << "<xi:include href='#{url}'/>"
|
122
|
+
end
|
123
|
+
|
124
|
+
def is_ietf(b)
|
125
|
+
url = b.at(ns("./uri[@type = 'xml']")) or return false
|
126
|
+
/xml2rfc\.tools\.ietf\.org/.match(url)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
module IsoDoc::Ietf
|
2
|
+
class RfcConvert < ::IsoDoc::Convert
|
3
|
+
def recommendation_name(node, out, type)
|
4
|
+
label, title, lbl = recommendation_labels(node)
|
5
|
+
out.t **{ keepWithNext: "true" } do |b|
|
6
|
+
b << (lbl.nil? ? l10n("#{type}:") : l10n("#{type} #{lbl}:"))
|
7
|
+
end
|
8
|
+
if label || title
|
9
|
+
out.t **{ keepWithNext: "true" } do |b|
|
10
|
+
label and label.children.each { |n| parse(n,b) }
|
11
|
+
b << "#{clausedelim} " if label && title
|
12
|
+
title and title.children.each { |n| parse(n,b) }
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def recommendation_attributes(node, out)
|
18
|
+
ret = recommendation_attributes1(node)
|
19
|
+
return if ret.empty?
|
20
|
+
out.ul do |p|
|
21
|
+
ret.each do |l|
|
22
|
+
p.li do |i|
|
23
|
+
i.em { |e| i << l }
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def recommendation_parse(node, out)
|
30
|
+
recommendation_name(node, out, @recommendation_lbl)
|
31
|
+
recommendation_attributes(node, out)
|
32
|
+
node.children.each do |n|
|
33
|
+
parse(n, out) unless %w(label title).include? n.name
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def requirement_parse(node, out)
|
38
|
+
recommendation_name(node, out, @requirement_lbl)
|
39
|
+
recommendation_attributes(node, out)
|
40
|
+
node.children.each do |n|
|
41
|
+
parse(n, out) unless %w(label title).include? n.name
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def permission_parse(node, out)
|
46
|
+
recommendation_name(node, out, @permission_lbl)
|
47
|
+
recommendation_attributes(node, out)
|
48
|
+
node.children.each do |n|
|
49
|
+
parse(n, out) unless %w(label title).include? n.name
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def inline?(node)
|
54
|
+
return true if node.first_element_child.nil?
|
55
|
+
%w(em link eref xref strong tt sup sub strike keyword smallcap
|
56
|
+
br hr bookmark pagebreak stem origin term preferred admitted
|
57
|
+
deprecates domain termsource modification).include? node.first_element_child.name
|
58
|
+
end
|
59
|
+
|
60
|
+
def requirement_component_parse(node, out)
|
61
|
+
return if node["exclude"] == "true"
|
62
|
+
out1 = out
|
63
|
+
if inline?(node)
|
64
|
+
out.t do |p|
|
65
|
+
p << "INHERIT: " if node.name == "inherit"
|
66
|
+
node.children.each { |n| parse(n, p) }
|
67
|
+
end
|
68
|
+
else
|
69
|
+
node.children.each { |n| parse(n, out) }
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require_relative "./terms"
|
2
|
+
require_relative "./blocks"
|
3
|
+
require_relative "./metadata"
|
4
|
+
require_relative "./front"
|
5
|
+
require_relative "./table"
|
6
|
+
require_relative "./inline"
|
7
|
+
require_relative "./reqt"
|
8
|
+
require_relative "./cleanup"
|
9
|
+
require_relative "./footnotes"
|
10
|
+
require_relative "./references"
|
11
|
+
require_relative "./section"
|
12
|
+
|
13
|
+
module IsoDoc::Ietf
|
14
|
+
class RfcConvert < ::IsoDoc::Convert
|
15
|
+
def convert1(docxml, filename, dir)
|
16
|
+
anchor_names docxml
|
17
|
+
info docxml, nil
|
18
|
+
xml = noko do |xml|
|
19
|
+
xml.rfc **attr_code(rfc_attributes(docxml)) do |html|
|
20
|
+
make_link(html, docxml)
|
21
|
+
make_front(html, docxml)
|
22
|
+
make_middle(html, docxml)
|
23
|
+
make_back(html, docxml)
|
24
|
+
end
|
25
|
+
end.join("\n").sub(/<!DOCTYPE[^>]+>\n/, "")
|
26
|
+
set_pis(docxml, Nokogiri::XML(xml))
|
27
|
+
end
|
28
|
+
|
29
|
+
def metadata_init(lang, script, labels)
|
30
|
+
@meta = Metadata.new(lang, script, labels)
|
31
|
+
end
|
32
|
+
|
33
|
+
def extract_delims(text)
|
34
|
+
@openmathdelim = "$$"
|
35
|
+
@closemathdelim = "$$"
|
36
|
+
while %r{#{Regexp.escape(@openmathdelim)}}m.match(text) ||
|
37
|
+
%r{#{Regexp.escape(@closemathdelim)}}m.match(text)
|
38
|
+
@openmathdelim += "$"
|
39
|
+
@closemathdelim += "$"
|
40
|
+
end
|
41
|
+
[@openmathdelim, @closemathdelim]
|
42
|
+
end
|
43
|
+
|
44
|
+
def error_parse(node, out)
|
45
|
+
case node.name
|
46
|
+
when "bcp14" then bcp14_parse(node, out)
|
47
|
+
else
|
48
|
+
text = node.to_xml.gsub(/</, "<").gsub(/>/, ">")
|
49
|
+
out.t { |p| p << text }
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def postprocess(result, filename, dir)
|
54
|
+
result = from_xhtml(cleanup(to_xhtml(result))).sub(/<!DOCTYPE[^>]+>\n/, "").
|
55
|
+
sub(/(<rfc[^<]+? )lang="[^"]+"/, "\\1")
|
56
|
+
File.open("#{filename}.rfc.xml", "w:UTF-8") { |f| f.write(result) }
|
57
|
+
@files_to_delete.each { |f| FileUtils.rm_rf f }
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|