metanorma-ietf 1.0.10 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|