kramdown-rfc2629 1.0.42 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +36 -3
- data/bin/kramdown-rfc2629 +47 -13
- data/data/kramdown-rfc2629.erb +1 -2
- data/kramdown-rfc2629.gemspec +1 -1
- data/lib/kramdown-rfc/refxml.rb +9 -3
- data/lib/kramdown-rfc2629.rb +29 -11
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: eccebf9e2835616858b24412132d8ef16799526f
|
4
|
+
data.tar.gz: ca13164f41dc311f2ef333c21dfa11489057bf07
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b6aec8582e3b6a5ca6e3ebd32eacde950f89246a1595eaa8fd13dd9fe8d1d7fe7e04affe118751d2a6781910b051419cf9d9fdb3e0e1491f21191a1de50772d5
|
7
|
+
data.tar.gz: 034c56c7f6baa6aaac94fd94ad43dc7240dd12fe39e67b09e5b3ca43127c75759d9d6f5bf4e2c2c9bc454fd92104a4c50a2cc3e38544e8a8cc9acbdc313c0989
|
data/README.md
CHANGED
@@ -14,7 +14,8 @@ their work in markdown.
|
|
14
14
|
# Usage
|
15
15
|
|
16
16
|
Start by installing the kramdown-rfc2629 gem (this automatically
|
17
|
-
installs
|
17
|
+
installs appropriate versions of referenced gems such as kramdown as
|
18
|
+
well):
|
18
19
|
|
19
20
|
gem install kramdown-rfc2629
|
20
21
|
|
@@ -33,6 +34,10 @@ To use kramdown-rfc2629, you'll need a Ruby 1.9 or 2.x, and maybe
|
|
33
34
|
kramdown-rfc2629 mydraft.mkd >mydraft.xml
|
34
35
|
xml2rfc mydraft.xml
|
35
36
|
|
37
|
+
(The most popular file name extension that IETF people have for
|
38
|
+
markdown is .md -- for those who tend to think about GNU machine
|
39
|
+
descriptions here, any extension such as .mkd will do, too.)
|
40
|
+
|
36
41
|
# Examples
|
37
42
|
|
38
43
|
For historical interest
|
@@ -149,8 +154,36 @@ and then just write `{{RFC2119}}` or `{{RFC1925}}`. (Yes, there is a
|
|
149
154
|
colon in the YAML, because this is a hash that could provide other
|
150
155
|
information.)
|
151
156
|
|
152
|
-
|
153
|
-
|
157
|
+
Since version 1.1, references imported from the [XML2RFC][] databases
|
158
|
+
can be supplied with a replacement label (anchor name). E.g., RFC 793
|
159
|
+
could be referenced as `{{!TCP=RFC0793}}, further references then just
|
160
|
+
can say `{{TCP}}`; both will get `[TCP]` as the label. In the
|
161
|
+
YAML, the same replacement can be expressed as in the first example:
|
162
|
+
|
163
|
+
normative:
|
164
|
+
TCP: RFC0793
|
165
|
+
informative:
|
166
|
+
SST: DOI.10.1145/1282427.1282421
|
167
|
+
|
168
|
+
Notes about this feature:
|
169
|
+
|
170
|
+
* At the time of writing, the DOI and IANA repositories are
|
171
|
+
slightly unstable.
|
172
|
+
* Thank you, Martin Thomson, for supplying an implementation and
|
173
|
+
insisting this be done.
|
174
|
+
* While this feature is now available, you are not forced to use it
|
175
|
+
for everything: readers of documents often benefit from not having
|
176
|
+
to look up references, so continuing to use the draft names and RFC
|
177
|
+
numbers as labels may be the preferrable style in many cases.
|
178
|
+
* As a final caveat, renaming anchors does not work in the
|
179
|
+
`stand_alone: no` mode (except for IANA and DOI), as there is no
|
180
|
+
such mechanism in XML entity referencing; exporting to XML while
|
181
|
+
maintaining live references then may require some manual editing to
|
182
|
+
get rid of the custom anchors.
|
183
|
+
|
184
|
+
If your references are not in the [XML2RFC][] databases and do not
|
185
|
+
have a DOI (that also happens to have correct data) either, you need
|
186
|
+
to spell it out like in the examples below:
|
154
187
|
|
155
188
|
informative:
|
156
189
|
RFC1925:
|
data/bin/kramdown-rfc2629
CHANGED
@@ -52,18 +52,25 @@ def xml_from_sections(input)
|
|
52
52
|
end
|
53
53
|
|
54
54
|
ref_replacements = { }
|
55
|
+
anchor_to_bibref = { }
|
55
56
|
|
56
57
|
[:ref, :normative, :informative].each do |sn|
|
57
58
|
if refs = ps.has(sn)
|
58
59
|
warn "*** bad section #{sn}: #{refs.inspect}" unless refs.respond_to? :each
|
59
60
|
refs.each do |k, v|
|
60
61
|
if v.respond_to? :to_str
|
62
|
+
if bibtagsys(v) # enable "foo: RFC4711" as a custom anchor definition
|
63
|
+
anchor_to_bibref[k] = v.to_str
|
64
|
+
end
|
61
65
|
ref_replacements[v.to_str] = k
|
62
66
|
end
|
63
|
-
if v
|
67
|
+
if Hash === v
|
64
68
|
if aliasname = v.delete("-")
|
65
69
|
ref_replacements[aliasname] = k
|
66
70
|
end
|
71
|
+
if bibref = v.delete("=")
|
72
|
+
anchor_to_bibref[k] = bibref
|
73
|
+
end
|
67
74
|
end
|
68
75
|
end
|
69
76
|
end
|
@@ -76,18 +83,29 @@ def xml_from_sections(input)
|
|
76
83
|
# collect normative/informative tagging {{!RFC2119}} {{?RFC4711}}
|
77
84
|
sechash.each do |k, v|
|
78
85
|
next if k == "fluff"
|
79
|
-
v.gsub!(/{{(?:([?!])(-)?|(-))([\w
|
86
|
+
v.gsub!(/{{(?:([?!])(-)?|(-))([\w._\-]+)(?:=([\w.\/_\-]+))?}}/) do |match|
|
80
87
|
norminform = $1
|
81
88
|
replacing = $2 || $3
|
82
89
|
word = $4
|
90
|
+
bibref = $5
|
83
91
|
if replacing
|
84
92
|
if new = ref_replacements[word]
|
85
93
|
word = new
|
86
94
|
else
|
87
|
-
warn "*** no alias replacement for {{-#{word}}}"
|
95
|
+
warn "*** no alias replacement for {{-#{word}}}"
|
88
96
|
word = "-#{word}"
|
89
97
|
end
|
98
|
+
end # now, word is the anchor
|
99
|
+
if bibref
|
100
|
+
if old = anchor_to_bibref[word]
|
101
|
+
if bibref != old
|
102
|
+
warn "*** conflicting definitions for xref #{anchor}: #{old} != #{bibref}"
|
103
|
+
end
|
104
|
+
else
|
105
|
+
anchor_to_bibref[word] = bibref
|
106
|
+
end
|
90
107
|
end
|
108
|
+
|
91
109
|
# things can be normative in one place and informative in another -> normative
|
92
110
|
# collect norm/inform above and assign it by priority here
|
93
111
|
if norminform
|
@@ -126,19 +144,24 @@ def xml_from_sections(input)
|
|
126
144
|
refs.each do |k, v|
|
127
145
|
href = k.gsub(/\A[0-9]/) { "_#{$&}" } # can't start an IDREF with a number
|
128
146
|
link_defs[k] = ["##{href}", nil] # allow [RFC2119] in addition to {{RFC2119}}
|
129
|
-
|
130
|
-
|
147
|
+
|
148
|
+
bibref = anchor_to_bibref[k] || k
|
149
|
+
bts, url = bibtagsys(bibref, k, stand_alone)
|
150
|
+
if bts
|
151
|
+
if v && v != {}
|
131
152
|
warn "*** redundant in #{k}: #{v.inspect}" unless v.respond_to? :to_str
|
132
153
|
end
|
133
154
|
if stand_alone
|
134
|
-
|
155
|
+
a = %{{: anchor="#{k}"}}
|
156
|
+
sechash[sn.to_s] << %{\n#{NMDTAGS[0]}\n![:include:](#{bts})#{a}\n#{NMDTAGS[1]}\n}
|
135
157
|
else
|
136
|
-
(
|
137
|
-
|
158
|
+
bts.gsub!('/', '_')
|
159
|
+
(ps.rest["bibxml"] ||= []) << [bts, url]
|
160
|
+
sechash[sn.to_s] << %{&#{bts};\n} # ???
|
138
161
|
end
|
139
162
|
else
|
140
163
|
unless v && Hash === v
|
141
|
-
warn "*** don't know how to expand ref #{k}"
|
164
|
+
warn "*** don't know how to expand ref #{k}"
|
142
165
|
next
|
143
166
|
end
|
144
167
|
sechash[sn.to_s] << KramdownRFC::ref_to_xml(k, v)
|
@@ -163,23 +186,34 @@ end
|
|
163
186
|
|
164
187
|
XML_RESOURCE_ORG_PREFIX = Kramdown::Converter::Rfc2629::XML_RESOURCE_ORG_PREFIX
|
165
188
|
|
166
|
-
|
189
|
+
# return XML entity name, url, rewrite_anchor flag
|
190
|
+
def bibtagsys(bib, anchor=nil, stand_alone=true)
|
167
191
|
if bib =~ /\Arfc(\d+)/i
|
168
192
|
rfc4d = "%04d" % $1.to_i
|
169
193
|
[bib.upcase,
|
170
194
|
"#{XML_RESOURCE_ORG_PREFIX}/bibxml/reference.RFC.#{rfc4d}.xml"]
|
171
195
|
elsif bib =~ /\A([-A-Z0-9]+)\./ &&
|
172
|
-
dir = Kramdown::Converter::Rfc2629::XML_RESOURCE_ORG_MAP[$1]
|
196
|
+
(dir, _ttl, rewrite_anchor = Kramdown::Converter::Rfc2629::XML_RESOURCE_ORG_MAP[$1])
|
173
197
|
bib1 = bib.gsub(/\A[0-9]/) { "_#{$&}" } # can't start an ID with a number
|
198
|
+
if anchor && bib1 != anchor
|
199
|
+
if rewrite_anchor
|
200
|
+
a = %{?anchor=#{anchor}}
|
201
|
+
else
|
202
|
+
if !stand_alone
|
203
|
+
warn "*** selecting a custom anchor '#{anchor}' for '#{bib1}' requires stand_alone mode"
|
204
|
+
warn " the output will need manual editing to correct this"
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
174
208
|
[bib1,
|
175
|
-
"#{XML_RESOURCE_ORG_PREFIX}/#{dir}/reference.#{bib}.xml"]
|
209
|
+
"#{XML_RESOURCE_ORG_PREFIX}/#{dir}/reference.#{bib}.xml#{a}"]
|
176
210
|
end
|
177
211
|
end
|
178
212
|
|
179
213
|
def read_encodings
|
180
214
|
encfilename = File.expand_path '../../data/encoding-fallbacks.txt', __FILE__
|
181
215
|
encfile = File.read(encfilename, coding: "UTF-8")
|
182
|
-
Hash[encfile.lines.map{|l|
|
216
|
+
Hash[encfile.lines.map{|l|
|
183
217
|
l.chomp!;
|
184
218
|
x, s = l.split(" ", 2)
|
185
219
|
[x.hex.chr(Encoding::UTF_8), s || " "]}]
|
data/data/kramdown-rfc2629.erb
CHANGED
@@ -4,8 +4,7 @@
|
|
4
4
|
Gem.loaded_specs["kramdown-rfc2629"].version rescue nil %> -->
|
5
5
|
|
6
6
|
<!DOCTYPE rfc SYSTEM "rfc2629.dtd" [
|
7
|
-
<% ps.arr("bibxml") do |
|
8
|
-
tag, sys = bibtagsys(bib) -%>
|
7
|
+
<% ps.arr("bibxml") do |tag, sys| -%>
|
9
8
|
<!ENTITY <%= tag %> SYSTEM "<%= sys %>">
|
10
9
|
<% end -%>
|
11
10
|
<% ps.arr("entity", false) do |en, ev| -%>
|
data/kramdown-rfc2629.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
spec = Gem::Specification.new do |s|
|
2
2
|
s.name = 'kramdown-rfc2629'
|
3
|
-
s.version = '1.0
|
3
|
+
s.version = '1.1.0'
|
4
4
|
s.summary = "Kramdown extension for generating RFC 7749 XML."
|
5
5
|
s.description = %{An RFC7749 (XML2RFC) generating backend for Thomas Leitner's
|
6
6
|
"kramdown" markdown parser. Mostly useful for RFC writers.}
|
data/lib/kramdown-rfc/refxml.rb
CHANGED
@@ -1,9 +1,15 @@
|
|
1
1
|
module KramdownRFC
|
2
2
|
|
3
|
+
extend Kramdown::Utils::Html
|
4
|
+
|
5
|
+
def self.escattr(str)
|
6
|
+
escape_html(str.to_s, :attribute)
|
7
|
+
end
|
8
|
+
|
3
9
|
def self.ref_to_xml(k, v)
|
4
10
|
vps = KramdownRFC::ParameterSet.new(v)
|
5
11
|
erb = ERB.new <<-REFERB, nil, '-'
|
6
|
-
<reference anchor="<%= k %>" <%= vps.attr("target") %>>
|
12
|
+
<reference anchor="<%= escattr(k) %>" <%= vps.attr("target") %>>
|
7
13
|
<front>
|
8
14
|
<%= vps.ele("title") -%>
|
9
15
|
|
@@ -18,10 +24,10 @@ module KramdownRFC
|
|
18
24
|
<date <%= dateattrs(vps[:date]) %>/>
|
19
25
|
</front>
|
20
26
|
<% vps.arr("seriesinfo", false) do |k, v| -%>
|
21
|
-
<seriesInfo name="<%=k%>" value="<%=v%>"/>
|
27
|
+
<seriesInfo name="<%=escattr(k)%>" value="<%=escattr(v)%>"/>
|
22
28
|
<% end -%>
|
23
29
|
<% vps.arr("format", false) do |k, v| -%>
|
24
|
-
<format type="<%=k%>" target="<%=v%>"/>
|
30
|
+
<format type="<%=escattr(k)%>" target="<%=escattr(v)%>"/>
|
25
31
|
<% end -%>
|
26
32
|
<%= vps.ele("annotation=ann") -%>
|
27
33
|
</reference>
|
data/lib/kramdown-rfc2629.rb
CHANGED
@@ -412,9 +412,10 @@ module Kramdown
|
|
412
412
|
KRAMDOWN_OFFLINE = ENV["KRAMDOWN_OFFLINE"]
|
413
413
|
KRAMDOWN_REFCACHE_REFETCH = ENV["KRAMDOWN_REFCACHE_REFETCH"]
|
414
414
|
|
415
|
-
|
415
|
+
# this is now slightly dangerous as multiple urls could map to the same cachefile
|
416
|
+
def get_and_cache_resource(url, cachefile, tvalid = 7200, tn = Time.now)
|
417
|
+
fn = "#{REFCACHEDIR}/#{cachefile}"
|
416
418
|
Dir.mkdir(REFCACHEDIR) unless Dir.exists?(REFCACHEDIR)
|
417
|
-
fn = "#{REFCACHEDIR}/#{File.basename(url)}"
|
418
419
|
f = File.stat(fn) rescue nil unless KRAMDOWN_REFCACHE_REFETCH
|
419
420
|
if !KRAMDOWN_OFFLINE && (!f || tn - f.ctime >= tvalid)
|
420
421
|
if f
|
@@ -457,7 +458,11 @@ module Kramdown
|
|
457
458
|
end
|
458
459
|
end
|
459
460
|
end
|
460
|
-
|
461
|
+
begin
|
462
|
+
File.read(fn) # this blows up if no cache available after fetch attempt
|
463
|
+
rescue Errno::ENOENT => e
|
464
|
+
warn "*** #{e} for ${fn}"
|
465
|
+
end
|
461
466
|
end
|
462
467
|
|
463
468
|
XML_RESOURCE_ORG_MAP = {
|
@@ -475,8 +480,8 @@ module Kramdown
|
|
475
480
|
"NIST" => "bibxml2",
|
476
481
|
"OASIS" => "bibxml2",
|
477
482
|
"PKCS" => "bibxml2",
|
478
|
-
"DOI" => ["bibxml7", 86400], # 24 h cache at source anyway
|
479
|
-
"IANA" => ["bibxml8", 86400], # ditto
|
483
|
+
"DOI" => ["bibxml7", 86400, true], # 24 h cache at source anyway
|
484
|
+
"IANA" => ["bibxml8", 86400, true], # ditto
|
480
485
|
}
|
481
486
|
|
482
487
|
# XML_RESOURCE_ORG_HOST = ENV["XML_RESOURCE_ORG_HOST"] || "xml.resource.org"
|
@@ -490,23 +495,36 @@ module Kramdown
|
|
490
495
|
if a = el.attr
|
491
496
|
alt = a.delete('alt').strip
|
492
497
|
alt = '' if alt == '!' # work around re-wrap uglyness
|
493
|
-
if
|
494
|
-
a['target'] =
|
498
|
+
if src = a.delete('src')
|
499
|
+
a['target'] = src
|
495
500
|
end
|
496
501
|
end
|
497
502
|
if alt == ":include:" # Really bad misuse of tag...
|
503
|
+
anchor = el.attr.delete('anchor') || (
|
504
|
+
# not yet
|
505
|
+
warn "*** missing anchor for '#{src}'"
|
506
|
+
src
|
507
|
+
)
|
508
|
+
anchor.sub!(/\A[0-9]/) { "_#{$&}" } # can't start an ID with a number
|
509
|
+
anchor.gsub!('/', '_') # should take out all illegals
|
498
510
|
to_insert = ""
|
499
|
-
|
511
|
+
src.scan(/(W3C|3GPP|[A-Z-]+)[.]?([A-Za-z_0-9.\/\+-]+)/) do |t, n|
|
500
512
|
fn = "reference.#{t}.#{n}.xml"
|
501
513
|
sub, ttl = XML_RESOURCE_ORG_MAP[t]
|
502
514
|
ttl ||= KRAMDOWN_REFCACHETTL # everything but RFCs might change a lot
|
503
515
|
puts "Huh: ${fn}" unless sub
|
504
516
|
url = "#{XML_RESOURCE_ORG_PREFIX}/#{sub}/#{fn}"
|
505
|
-
to_insert = get_and_cache_resource(url, ttl)
|
517
|
+
to_insert = get_and_cache_resource(url, fn.gsub('/', '_'), ttl)
|
506
518
|
to_insert.scrub! rescue nil # only do this for Ruby >= 2.1
|
519
|
+
# this may be a bit controversial: Don't break the build if reference is broken
|
520
|
+
if KRAMDOWN_OFFLINE
|
521
|
+
to_insert ||= "<reference anchor='#{anchor}'> <front> <title>*** BROKEN REFERENCE ***</title> <author> <organization/> </author> <date/> </front> </reference>"
|
522
|
+
else
|
523
|
+
exit 66 unless to_insert # EX_NOINPUT
|
524
|
+
end
|
507
525
|
end
|
508
|
-
to_insert.
|
509
|
-
|
526
|
+
to_insert.sub(/<\?xml version=["']1.0["'] encoding=["']UTF-8["']\?>/, '')
|
527
|
+
.sub(/\banchor=(?:"[^"]+"|'[^']+')/, "anchor=\"#{anchor}\"")
|
510
528
|
else
|
511
529
|
"<xref#{el_html_attributes(el)}>#{alt}</xref>"
|
512
530
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kramdown-rfc2629
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Carsten Bormann
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-03-
|
11
|
+
date: 2017-03-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: kramdown
|