kramdown-rfc2629 0.13.1 → 0.13.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +48 -9
- data/bin/kramdown-rfc2629 +104 -1
- data/data/kramdown-rfc2629.erb +113 -0
- data/kramdown-rfc2629.gemspec +2 -2
- data/lib/kramdown-rfc2629.rb +6 -1
- metadata +32 -52
data/README.md
CHANGED
@@ -14,16 +14,20 @@ their work in markdown.
|
|
14
14
|
# Usage
|
15
15
|
|
16
16
|
Start by installing the kramdown-rfc2629 gem (this requires kramdown
|
17
|
-
version 0.13.
|
17
|
+
version 0.13.x, but has also been tested with version 0.11.0 and 0.12.0):
|
18
18
|
|
19
19
|
sudo gem install kramdown-rfc2629
|
20
20
|
|
21
21
|
The guts of kramdown-rfc2629 are in one Ruby file,
|
22
22
|
`lib/kramdown-rfc2629.rb` --- this melds nicely into the extension
|
23
|
-
structure provided by kramdown. `bin/kramdown-rfc2629`
|
24
|
-
command-line program showing how to use this
|
25
|
-
|
26
|
-
|
23
|
+
structure provided by kramdown. `bin/kramdown-rfc2629` started out as
|
24
|
+
a simple command-line program showing how to use this, but can now do
|
25
|
+
much more (see below).
|
26
|
+
|
27
|
+
To use kramdown-rfc2629, you'll need a Ruby 1.9 that can be found
|
28
|
+
under the name "ruby1.9", the command "wget" (if you want to use the
|
29
|
+
offline feature), and maybe XML2RFC if you want to see the fruits of
|
30
|
+
your work.
|
27
31
|
|
28
32
|
kramdown-rfc2629 mydraft.mkd >mydraft.xml
|
29
33
|
xml2rfc mydraft.xml
|
@@ -36,13 +40,46 @@ all features of kramdown-rfc2629. Since markdown/kramdown does not
|
|
36
40
|
cater for all the structure of an RFC 2629 style document, some of the
|
37
41
|
markup is in XML, and the example switches between XML and markdown
|
38
42
|
using kramdown's `{::nomarkdown}` and `{:/nomarkdown}` (this is ugly,
|
39
|
-
but works well enough).
|
43
|
+
but works well enough). `stupid.xml` and `stupid.txt` show what
|
44
|
+
kramdown-rfc2629 and xml2rfc make out of this.
|
45
|
+
|
46
|
+
`stupid-s.mkd` is the same document in the new sectionized format
|
47
|
+
supported by kramdown-rfc2629. The document metadata are in a short
|
48
|
+
piece of YAML at the start, and from there, `abstract`, `middle`,
|
49
|
+
references (`normative` and `informative`) and `back` are sections
|
50
|
+
delimited in the markdown file. See the example for how this works.
|
51
|
+
Much less scary, and no `{:/nomarkdown}` etc. is needed any more.
|
52
|
+
Similarly, `stupid-s.xml` and `stupid-s.txt` show what
|
53
|
+
kramdown-rfc2629 and xml2rfc make out of this.
|
54
|
+
|
55
|
+
`draft-ietf-core-block-xx.mkd` is a real-world example of a current
|
56
|
+
Internet-Draft done this way. For RFC and Internet-Draft references,
|
57
|
+
it uses document prolog entities instead of caching the references in
|
58
|
+
the XML (this is easier to handle when collaborating with XML-only
|
59
|
+
co-authors). See the `bibxml` metadata.
|
40
60
|
|
41
61
|
# Risks and Side-Effects
|
42
62
|
|
43
|
-
The code is not very polished
|
44
|
-
|
45
|
-
want to write an Internet-Draft
|
63
|
+
The code is not very polished, but it has been successfully used for a
|
64
|
+
number of non-trivial Internet-Drafts. You probably still need to
|
65
|
+
skim [RFC 2629][] if you want to write an Internet-Draft, but you
|
66
|
+
don't really need to understand XML very much. Knowing the basics of
|
67
|
+
YAML helps with the metadata (but you'll understand it from the
|
68
|
+
examples.)
|
69
|
+
|
70
|
+
# Related Work
|
71
|
+
|
72
|
+
Moving from XML to Markdown for RFC writing apparently is a
|
73
|
+
no-brainer, so I'm not the only one who has written code for this.
|
74
|
+
|
75
|
+
[Miek Gieben][] has done a [similar thing][pandoc2rfc] employing
|
76
|
+
pandoc/asciidoc. He uses multiple input files instead of
|
77
|
+
kramdown-rfc2629's sectionized input format. He keeps the metadata in
|
78
|
+
a separate XML file, similar to the way the previous version of
|
79
|
+
kramdown-rfc2629 stored (and still can store) the metadata in XML in
|
80
|
+
the markdown document. He also uses a slightly different referencing
|
81
|
+
syntax, which is closer to what markdown does elsewhere but more
|
82
|
+
verbose.
|
46
83
|
|
47
84
|
# License
|
48
85
|
|
@@ -57,3 +94,5 @@ it's probably not going to kill any RFC author.)
|
|
57
94
|
[RFC 2629]: http://xml.resource.org
|
58
95
|
[markdown]: http://en.wikipedia.org/wiki/Markdown
|
59
96
|
[IETF]: http://www.ietf.org
|
97
|
+
[Miek Gieben]: http://www.miek.nl/
|
98
|
+
[pandoc2rfc]: https://github.com/miekg/pandoc2rfc/
|
data/bin/kramdown-rfc2629
CHANGED
@@ -1,16 +1,119 @@
|
|
1
1
|
#!/usr/bin/env ruby1.9
|
2
|
+
# -*- coding: utf-8 -*-
|
2
3
|
require 'kramdown-rfc2629'
|
3
4
|
require 'yaml'
|
5
|
+
require 'pp'
|
6
|
+
require 'erb'
|
7
|
+
require 'ostruct'
|
8
|
+
require 'date'
|
4
9
|
|
5
10
|
Encoding.default_external = "UTF-8" # wake up, smell the coffee
|
6
11
|
|
7
|
-
|
12
|
+
RE_NL = /(?:\n|\r|\r\n)/
|
13
|
+
RE_SECTION = /---(?:\s+(\w+)(-?))?\s*#{RE_NL}(.*?#{RE_NL})(?=---(?:\s+\w+-?)?\s*#{RE_NL}|\Z)/m
|
14
|
+
|
15
|
+
def xml_from_sections(input)
|
16
|
+
sections = input.scan(RE_SECTION) # array of [label, nomarkdown-flag, text]
|
17
|
+
|
18
|
+
ps = ParameterSet.new(YAML.load(sections.shift[2])) # front matter parameters
|
19
|
+
coding_override = (ps.has(:coding) =~ /ascii/i) ? :symbolic : :as_char
|
20
|
+
|
21
|
+
sechash = Hash.new{ |h,k| h[k] = ""}
|
22
|
+
snames = []
|
23
|
+
sections.each do |sname, nmdflag, text|
|
24
|
+
nmdin, nmdout = {
|
25
|
+
"-" => ["", ""],
|
26
|
+
"" => ["{:/nomarkdown}\n\n", "\n{::nomarkdown}\n"],
|
27
|
+
}[nmdflag || ""]
|
28
|
+
if sname
|
29
|
+
snames << sname # --- label -> push label
|
30
|
+
else
|
31
|
+
snames.pop # --- -> pop label
|
32
|
+
end
|
33
|
+
sechash[snames.last] << "#{nmdin}#{text}#{nmdout}"
|
34
|
+
end
|
35
|
+
|
36
|
+
mydata = File.read(File.join(File.dirname(__FILE__), '..', 'data', 'kramdown-rfc2629.erb'), coding: "UTF-8")
|
37
|
+
erb = ERB.new(mydata)
|
38
|
+
input = erb.result(binding)
|
39
|
+
ps.warn_if_leftovers
|
40
|
+
sechash.delete("fluff")
|
41
|
+
if !sechash.empty?
|
42
|
+
warn "*** sections left #{sechash.keys.inspect}!"
|
43
|
+
end
|
44
|
+
|
45
|
+
[input.gsub(%r"{::nomarkdown}\s*{:/nomarkdown}"m, ""), coding_override]
|
46
|
+
end
|
47
|
+
|
48
|
+
class ParameterSet
|
49
|
+
attr_reader :f
|
50
|
+
def initialize(y)
|
51
|
+
@f = y
|
52
|
+
end
|
53
|
+
def [](pn)
|
54
|
+
@f.delete(pn.to_s)
|
55
|
+
end
|
56
|
+
def has(pn)
|
57
|
+
@f[pn.to_s]
|
58
|
+
end
|
59
|
+
def van(pn) # pn is a parameter name, possibly with an =alias
|
60
|
+
an, pn = pn.to_s.split("=")
|
61
|
+
pn ||= an
|
62
|
+
[self[pn] || self[an], an]
|
63
|
+
end
|
64
|
+
def attr(pn)
|
65
|
+
val, an = van(pn)
|
66
|
+
%{#{an}="#{val}"} if val
|
67
|
+
end
|
68
|
+
def attrs(*pns)
|
69
|
+
pns.map{ |pn| attr(pn) }.join(" ")
|
70
|
+
end
|
71
|
+
def ele(pn, attr=nil)
|
72
|
+
val, an = van(pn)
|
73
|
+
if val
|
74
|
+
val = [val] unless val.respond_to? :to_a
|
75
|
+
val.map do |val1|
|
76
|
+
%{<#{[an, attr.to_s].join(" ").strip}>#{val1}</#{an}>}
|
77
|
+
end.join(" ")
|
78
|
+
end
|
79
|
+
end
|
80
|
+
def arr(an, &block)
|
81
|
+
(self[an] || []).each(&block)
|
82
|
+
end
|
83
|
+
def rest
|
84
|
+
@f
|
85
|
+
end
|
86
|
+
def warn_if_leftovers
|
87
|
+
if !@f.empty?
|
88
|
+
warn "*** attributes left #{@f.inspect}!"
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def bibtagsys(bib)
|
94
|
+
if bib =~ /\Arfc(\d+)/i
|
95
|
+
rfc4d = "%04d" % $1.to_i
|
96
|
+
[bib.upcase,
|
97
|
+
"http://xml.resource.org/public/rfc/bibxml/reference.RFC.#{rfc4d}.xml"]
|
98
|
+
else
|
99
|
+
[bib,
|
100
|
+
"http://xml.resource.org/public/rfc/bibxml3/reference.#{bib}.xml"]
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
|
105
|
+
coding_override = :as_char
|
8
106
|
input = ARGF.read.gsub(/\{::include\s+(.*?)\}/) {
|
9
107
|
File.read($1).chomp
|
10
108
|
}
|
109
|
+
if input =~ /\A---/ # this is a sectionized file
|
110
|
+
input, coding_override = xml_from_sections(input)
|
111
|
+
end
|
11
112
|
if input =~ /\A<\?xml/ # if this is a whole XML file, protect it
|
12
113
|
input = "{::nomarkdown}\n#{input}\n{:/nomarkdown}\n"
|
13
114
|
end
|
115
|
+
options = {input: 'RFC2629Kramdown', entity_output: coding_override}
|
116
|
+
warn "options: #{options.inspect}"
|
14
117
|
doc = Kramdown::Document.new(input, options)
|
15
118
|
$stderr.puts doc.warnings.to_yaml unless doc.warnings.empty?
|
16
119
|
puts doc.to_rfc2629
|
@@ -0,0 +1,113 @@
|
|
1
|
+
<?xml version="1.0" encoding="<%=ps[:coding]||"UTF-8"%>"?>
|
2
|
+
<?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?>
|
3
|
+
|
4
|
+
<!DOCTYPE rfc SYSTEM "rfc2629.dtd" [
|
5
|
+
<% ps.arr("bibxml") do |bib|
|
6
|
+
tag, sys = bibtagsys(bib) %>
|
7
|
+
<!ENTITY <%= tag %> SYSTEM "<%= sys %>">
|
8
|
+
<% end %>
|
9
|
+
<% ps.arr("entity") do |en, ev| %>
|
10
|
+
<!ENTITY <%=en%> "<%=ev%>">
|
11
|
+
<% end %>
|
12
|
+
]>
|
13
|
+
|
14
|
+
<rfc <%= ps.attrs("ipr", "docName=docname", "category=cat",
|
15
|
+
"number", "obsoletes", "updates", "seriesNo=seriesno") %> >
|
16
|
+
|
17
|
+
<% ps.arr("pi") do |pi| %>
|
18
|
+
<?rfc <%=pi%>="yes"?>
|
19
|
+
<% end %>
|
20
|
+
|
21
|
+
<front>
|
22
|
+
<%= ps.ele("title", ps.attr("abbrev=titleabbrev")) %>
|
23
|
+
|
24
|
+
<% ps.arr("author") do |au|
|
25
|
+
aups = ParameterSet.new(au)
|
26
|
+
if ins = aups[:ins]
|
27
|
+
parts = ins.split('.').map(&:strip)
|
28
|
+
aups.rest["initials"] = parts[0..-2].join('.') << '.'
|
29
|
+
aups.rest["surname"] = parts[-1]
|
30
|
+
end
|
31
|
+
%>
|
32
|
+
|
33
|
+
<author <%=aups.attrs("initials", "surname", "fullname=name", "role")%>>
|
34
|
+
<%= aups.ele("organization=org", aups.attr("abbrev=orgabbrev")) %>
|
35
|
+
<address>
|
36
|
+
<% if aups.has("street") %>
|
37
|
+
<postal>
|
38
|
+
<%= aups.ele("street") %>
|
39
|
+
<%= aups.ele("city") %>
|
40
|
+
<%= aups.ele("region") %>
|
41
|
+
<%= aups.ele("code") %>
|
42
|
+
<%= aups.ele("country") %>
|
43
|
+
</postal>
|
44
|
+
<% end %>
|
45
|
+
<%= aups.ele("phone") %>
|
46
|
+
<%= aups.ele("facsimile") %>
|
47
|
+
<%= aups.ele("email") %>
|
48
|
+
<%= aups.ele("uri") %>
|
49
|
+
</address>
|
50
|
+
</author>
|
51
|
+
|
52
|
+
<% aups.warn_if_leftovers %>
|
53
|
+
<% end %>
|
54
|
+
|
55
|
+
<date <%= (ps[:date]||Date.today).strftime(%{year="%Y" month="%B" day="%d"}) %> />
|
56
|
+
|
57
|
+
<%= ps.ele("area") %>
|
58
|
+
<%= ps.ele("workgroup=wg") %>
|
59
|
+
<%= ps.ele("keyword=kw") %>
|
60
|
+
|
61
|
+
<abstract>
|
62
|
+
|
63
|
+
<%= sechash.delete("abstract") %>
|
64
|
+
|
65
|
+
</abstract>
|
66
|
+
|
67
|
+
<% sechash.keys.each do |k| %>
|
68
|
+
<% if k =~ /\Anote_(.*)/ %>
|
69
|
+
|
70
|
+
<note title="<%= $1.gsub("_", " ")%>">
|
71
|
+
|
72
|
+
<%= sechash.delete(k) %>
|
73
|
+
|
74
|
+
</note>
|
75
|
+
|
76
|
+
<% end %>
|
77
|
+
<% end %>
|
78
|
+
|
79
|
+
|
80
|
+
</front>
|
81
|
+
|
82
|
+
<middle>
|
83
|
+
|
84
|
+
<%= sechash.delete("middle") %>
|
85
|
+
|
86
|
+
</middle>
|
87
|
+
|
88
|
+
<back>
|
89
|
+
|
90
|
+
<% if sh = sechash.delete("normative") %>
|
91
|
+
|
92
|
+
<references title='Normative References'>
|
93
|
+
|
94
|
+
<%= sh %>
|
95
|
+
|
96
|
+
</references>
|
97
|
+
|
98
|
+
<% end %>
|
99
|
+
|
100
|
+
<% if sh = sechash.delete("informative") %>
|
101
|
+
|
102
|
+
<references title='Informative References'>
|
103
|
+
|
104
|
+
<%= sh %>
|
105
|
+
|
106
|
+
</references>
|
107
|
+
|
108
|
+
<% end %>
|
109
|
+
|
110
|
+
<%= sechash.delete("back") %>
|
111
|
+
|
112
|
+
</back>
|
113
|
+
</rfc>
|
data/kramdown-rfc2629.gemspec
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
spec = Gem::Specification.new do |s|
|
2
2
|
s.name = 'kramdown-rfc2629'
|
3
|
-
s.version = '0.13.
|
3
|
+
s.version = '0.13.2'
|
4
4
|
s.summary = "Kramdown extension for generating RFC 2629 XML."
|
5
5
|
s.description = %{An RFC2629 (XML2RFC) generating backend for Thomas Leitner's
|
6
6
|
"kramdown" markdown parser. Mostly useful for RFC writers.}
|
7
7
|
s.add_dependency('kramdown', '~> 0.13')
|
8
|
-
s.files = Dir['lib/**/*.rb'] + %w(README.md kramdown-rfc2629.gemspec bin/kramdown-rfc2629)
|
8
|
+
s.files = Dir['lib/**/*.rb'] + %w(README.md kramdown-rfc2629.gemspec bin/kramdown-rfc2629 data/kramdown-rfc2629.erb)
|
9
9
|
s.require_path = 'lib'
|
10
10
|
s.executables = ['kramdown-rfc2629']
|
11
11
|
s.default_executable = 'kramdown-rfc2629'
|
data/lib/kramdown-rfc2629.rb
CHANGED
@@ -305,7 +305,12 @@ module Kramdown
|
|
305
305
|
end
|
306
306
|
|
307
307
|
def convert_xref(el, indent, opts)
|
308
|
-
|
308
|
+
target = el.attr['target']
|
309
|
+
if target[0] == "&"
|
310
|
+
"#{target};"
|
311
|
+
else
|
312
|
+
"<xref#{el_html_attributes(el)}/>"
|
313
|
+
end
|
309
314
|
end
|
310
315
|
|
311
316
|
REFCACHEDIR = ".refcache"
|
metadata
CHANGED
@@ -1,84 +1,64 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: kramdown-rfc2629
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
|
6
|
-
- 0
|
7
|
-
- 13
|
8
|
-
- 1
|
9
|
-
version: 0.13.1
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.13.2
|
5
|
+
prerelease:
|
10
6
|
platform: ruby
|
11
|
-
authors:
|
7
|
+
authors:
|
12
8
|
- Carsten Bormann
|
13
9
|
autorequire:
|
14
10
|
bindir: bin
|
15
11
|
cert_chain: []
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
dependencies:
|
20
|
-
- !ruby/object:Gem::Dependency
|
12
|
+
date: 2012-01-14 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
21
15
|
name: kramdown
|
22
|
-
|
23
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
16
|
+
requirement: &70277384082520 !ruby/object:Gem::Requirement
|
24
17
|
none: false
|
25
|
-
requirements:
|
18
|
+
requirements:
|
26
19
|
- - ~>
|
27
|
-
- !ruby/object:Gem::Version
|
28
|
-
|
29
|
-
- 0
|
30
|
-
- 13
|
31
|
-
version: "0.13"
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0.13'
|
32
22
|
type: :runtime
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70277384082520
|
25
|
+
description: ! 'An RFC2629 (XML2RFC) generating backend for Thomas Leitner''s
|
26
|
+
|
27
|
+
"kramdown" markdown parser. Mostly useful for RFC writers.'
|
37
28
|
email: cabo@tzi.org
|
38
|
-
executables:
|
29
|
+
executables:
|
39
30
|
- kramdown-rfc2629
|
40
31
|
extensions: []
|
41
|
-
|
42
32
|
extra_rdoc_files: []
|
43
|
-
|
44
|
-
files:
|
33
|
+
files:
|
45
34
|
- lib/kramdown-rfc2629.rb
|
46
35
|
- README.md
|
47
36
|
- kramdown-rfc2629.gemspec
|
48
37
|
- bin/kramdown-rfc2629
|
49
|
-
|
38
|
+
- data/kramdown-rfc2629.erb
|
50
39
|
homepage: http://github.com/cabo/kramdown-rfc2629
|
51
40
|
licenses: []
|
52
|
-
|
53
41
|
post_install_message:
|
54
42
|
rdoc_options: []
|
55
|
-
|
56
|
-
require_paths:
|
43
|
+
require_paths:
|
57
44
|
- lib
|
58
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
45
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
59
46
|
none: false
|
60
|
-
requirements:
|
61
|
-
- -
|
62
|
-
- !ruby/object:Gem::Version
|
63
|
-
segments:
|
64
|
-
- 1
|
65
|
-
- 9
|
66
|
-
- 2
|
47
|
+
requirements:
|
48
|
+
- - ! '>='
|
49
|
+
- !ruby/object:Gem::Version
|
67
50
|
version: 1.9.2
|
68
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
51
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
69
52
|
none: false
|
70
|
-
requirements:
|
71
|
-
- -
|
72
|
-
- !ruby/object:Gem::Version
|
73
|
-
|
74
|
-
|
75
|
-
version: "0"
|
76
|
-
requirements:
|
53
|
+
requirements:
|
54
|
+
- - ! '>='
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: '0'
|
57
|
+
requirements:
|
77
58
|
- wget
|
78
59
|
rubyforge_project:
|
79
|
-
rubygems_version: 1.
|
60
|
+
rubygems_version: 1.8.12
|
80
61
|
signing_key:
|
81
62
|
specification_version: 3
|
82
63
|
summary: Kramdown extension for generating RFC 2629 XML.
|
83
64
|
test_files: []
|
84
|
-
|