kramdown-rfc2629 1.7.11 → 1.7.13

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 65eafab5401726cc8bc76b674b42e783436d603b4c3b5080ba0d374f953905f8
4
- data.tar.gz: 64dd363a024b30944017274f1e2765e145e6596af7e337627189019e22f4c9ed
3
+ metadata.gz: 37a6e52b1686d310bf22c8c2530ce893e3ea30b74675b6cdd17143c141a51321
4
+ data.tar.gz: f9cedeb1b71146d4be4affd7ba343c1a2a497b607e82565b772445d7fc686c06
5
5
  SHA512:
6
- metadata.gz: 0dd35229efeddba497fdc091b262f2f90e200b798f873b42394dd65dd037ea1c4d2620aaa6740c59f32e8e5ba65eb3f352f58a56e4e89121fb1d6159aec76386
7
- data.tar.gz: 1789e1772da25692d7f9e7706d537927e4e09ec03cba97037f12bdd6b9fbf8caebc848cb0ddac292da42b02aa1321d54ee7b94176b17272ff08aa23163aeef41
6
+ metadata.gz: 92fc3fc628cbcc21b0368f692f078206caa01fa8d5eb8f712777f369632f1d472efa20c0af96cd71a0e0e2752449d1efbeb2c354973fca4f740722545811b213
7
+ data.tar.gz: 924dc4cd075193b1cc9310ddee259290e5bd0026a5ccbb7ff2da65ea897ec3a6560e2fccbaee5122cacaa262ac9d4b692bfb14417359b6f39dfbdb8aaea7b340
data/README.md CHANGED
@@ -12,6 +12,11 @@ Who would care? Anybody who is writing Internet-Drafts and RFCs in
12
12
  the [IETF][] and prefers (or has co-authors who prefer) to do part of
13
13
  their work in markdown.
14
14
 
15
+ kramdown-rfc is documented on this page, and also on
16
+ [the wiki][].
17
+
18
+ [the wiki]: https://github.com/cabo/kramdown-rfc/wiki
19
+
15
20
  # Usage
16
21
 
17
22
  Start by installing the kramdown-rfc gem (this automatically
@@ -0,0 +1,269 @@
1
+ #!/usr/bin/env ruby -KU
2
+ # frozen_string_literal: true
3
+
4
+ # List Section References from a RFCXML document
5
+ #
6
+ # (PoC, in urgent need of refactoring)
7
+ # Requires xml2rfc and tidy commands in path
8
+ # Use without open-uri-cached is untested
9
+
10
+ require 'rexml/document'
11
+ require 'yaml'
12
+ require 'json'
13
+ require 'shellwords'
14
+ require 'fileutils'
15
+ begin
16
+ require 'open-uri/cached'
17
+ rescue LoadError
18
+ warn '*** please "gem install open-uri-cached" to enable caching'
19
+ require 'open-uri'
20
+ end
21
+ require_relative '../lib/kramdown-rfc/rexml-all-text.rb'
22
+
23
+ target = :shortname
24
+ require 'optparse'
25
+ begin
26
+ op = OptionParser.new do |opts|
27
+ opts.banner = "Usage: kramdown-rfc-lsr [options] xml-source"
28
+ opts.on("-u", "--url", "Source is URL") do |v|
29
+ target = :url
30
+ end
31
+ opts.on("-s", "--shortname", "Source is shortname (default)") do |v|
32
+ target = :shortname
33
+ end
34
+ opts.on("-f", "--file", "Source is filename") do |v|
35
+ target = :file
36
+ end
37
+ end
38
+ op.parse!
39
+ rescue Exception => e
40
+ warn e
41
+ exit 1
42
+ end
43
+
44
+ $exit_code = 0
45
+
46
+ if target != :file && ARGV.size != 1
47
+ puts op
48
+ exit 1
49
+ end
50
+ xmlsource = ARGV[0]
51
+ if target == :shortname
52
+ xmlsource = case xmlsource
53
+ when /^(?:rfc)?(\d+)$/i
54
+ "https://www.rfc-editor.org/rfc/rfc#{$1.to_i.to_s}.xml"
55
+ when /^(?:draft-|I-D.|)(.*-\d\d)$/
56
+ "https://www.ietf.org/archive/id/draft-#$1.xml"
57
+ # XXX find xml source for most recent version!
58
+ else
59
+ warn "*** Can't parse shortname #{xmlsource.inspect}"
60
+ puts op
61
+ exit 1
62
+ end
63
+ target = :url
64
+ end
65
+
66
+ begin
67
+ xml = case target
68
+ when :file
69
+ ARGF.read
70
+ when :url
71
+ URI(xmlsource).open.read
72
+ else
73
+ fail
74
+ end
75
+ rescue Exception => e
76
+ warn "#{xmlsource.inspect}: #{e}"
77
+ exit 1
78
+ end
79
+
80
+ doc = REXML::Document.new(xml)
81
+
82
+ def series_info_to_URI(si)
83
+ case si[:name]
84
+ when "RFC"
85
+ "https://www.rfc-editor.org/rfc/rfc#{si[:value]}.xml"
86
+ when "Internet-Draft"
87
+ "https://www.ietf.org/archive/id/#{si[:value]}.xml"
88
+ end
89
+ end
90
+
91
+
92
+ def series_info_to_name(si)
93
+ case si[:name]
94
+ when "RFC"
95
+ "RFC#{si[:value]}"
96
+ when "Internet-Draft"
97
+ si[:value]
98
+ end
99
+ end
100
+
101
+ def section_number_to_pn_candidates(s)
102
+ if /^[0-9]/ =~ s
103
+ ["section-#{s}"]
104
+ elsif /[.]/ =~ s
105
+ ["section-#{s.downcase}", "section-appendix.#{s.downcase}"]
106
+ else
107
+ ["section-appendix.#{s.downcase}"]
108
+ end
109
+ end
110
+
111
+ def section_number_to_htmlid(s)
112
+ if /^[0-9]/ =~ s
113
+ "section-#{s}"
114
+ else
115
+ "appendix-#{s.upcase}"
116
+ end
117
+ end
118
+
119
+ references = Hash[REXML::XPath.match(doc.root, "//reference").map {|r|
120
+ si = REXML::XPath.match(r, "seriesInfo").map {|s|
121
+ series_info_to_URI(s)}.compact.first
122
+ sn = REXML::XPath.match(r, "seriesInfo").map {|s|
123
+ series_info_to_name(s)}.compact.first
124
+ [r[:anchor], si ? [si, sn] : nil]
125
+ }] # XXX duplicates?
126
+
127
+ heading1 = "# #{xmlsource}"
128
+ title = REXML::XPath.first(doc.root, "//title")
129
+ heading1 << "\n(#{title.all_text})" if title
130
+ puts heading1
131
+
132
+ per_reference = Hash.new { |h, k| h[k] = Set[]}
133
+
134
+ REXML::XPath.each(doc.root, "//xref[@section]") do |x|
135
+ trg = x[:target]
136
+ if x[:relative]
137
+ puts "\n## #{x[:target]}#{x[:relative]}: #{x[:section]}"
138
+ else
139
+ # p x
140
+ per_reference[trg] << x[:section]
141
+ end
142
+ end
143
+
144
+ def error_out(s)
145
+ warn ""
146
+ warn s
147
+ warn ""
148
+ $exit_code = 1
149
+ end
150
+
151
+ def num_expand(s)
152
+ s.gsub(/\d+/) {|n| "%09d" % n.to_i}
153
+ end
154
+
155
+ require 'open3'
156
+
157
+ module OpenURI
158
+ class << self
159
+ def prepped(uri, *rest)
160
+ newuri = uri.to_s.sub(/\.xml$/, ".prepped.xml")
161
+ response = Cache.get(newuri) || (
162
+ unprepped = open_uri(uri, *rest).read
163
+ fn = [OpenURI::Cache.cache_path, uri.sub(/.*\//, '')].join('/')
164
+ File.open(fn, 'wb'){|f| f.write unprepped }
165
+ _prep_out, s = Open3.capture2("xml2rfc", "--prep", fn)
166
+ fail s.inspect unless s.success?
167
+ new_fn = fn.sub(/\.xml$/, ".prepped.xml")
168
+ Cache.set(newuri, File.open(new_fn))
169
+ )
170
+ response
171
+ end
172
+ def tidied(uri, *rest)
173
+ newuri = uri.to_s.sub(/\.html$/, ".tidied.html")
174
+ response = Cache.get(newuri) || (
175
+ unprepped = open_uri(uri, *rest).read
176
+ fn = [OpenURI::Cache.cache_path, uri.sub(/.*\//, '')].join('/')
177
+ File.open(fn, 'wb'){|f| f.write unprepped }
178
+ _prep_out, s = Open3.capture2("tidy", "-mq", "-asxml", "-f", "/dev/null", fn)
179
+ fail s.inspect unless s.exited?
180
+ Cache.set(newuri, File.open(fn))
181
+ )
182
+ response
183
+ end
184
+ end
185
+ end
186
+
187
+ # go through section-referenced documents in sequence
188
+ per_reference.keys.sort_by {|x| num_expand(x)}.each do |trg|
189
+ uri, sname = references[trg]
190
+ add = +''
191
+ if sname != trg
192
+ add << " [#{sname}]"
193
+ end
194
+ begin
195
+ ref = URI(uri).open.read
196
+ refdoc = REXML::Document.new(ref)
197
+ if REXML::XPath.match(refdoc.root, "/rfc/front/abstract[@pn]").size == 0
198
+ ref = OpenURI.prepped(uri).read
199
+ refdoc = REXML::Document.new(ref)
200
+ add << " [+prep]"
201
+ end
202
+ add << " (#{REXML::XPath.match(refdoc.root, "//title").first.all_text})"
203
+ rescue OpenURI::HTTPError => e
204
+ begin
205
+ jsonuri = uri.sub(/\.xml$/, ".json")
206
+ refjson = URI(jsonuri).open.read
207
+ refdata = JSON.load(refjson)
208
+ add << " (#{refdata["title"].strip})"
209
+ rescue OpenURI::HTTPError => e
210
+ add << " [No XML or JSON]"
211
+ rescue Exception => e
212
+ warn "*** error getting #{jsonuri.inspect}: #{e}"
213
+ end
214
+ rescue Exception => e
215
+ warn "*** error getting #{uri.inspect}: #{e}"
216
+ end
217
+ puts "\n## #{trg}#{add}"
218
+ unless refdoc
219
+ begin
220
+ htmluri = uri.sub(/\.xml$/, ".html")
221
+ refhtml = OpenURI.tidied(htmluri).read
222
+ refhtmldoc = REXML::Document.new(refhtml)
223
+ rescue Exception => e
224
+ warn "*** error tidying up HTML for #{htmluri.inspect}: #{e}"
225
+ end
226
+ end
227
+ # go through individual section references in sequence
228
+ per_reference[trg].to_a.sort_by {|x| num_expand(x)}.each do |s|
229
+ add = +''
230
+ if refdoc # find section name in XML from anchor s
231
+ secpn = section_number_to_pn_candidates(s)
232
+ secs = secpn.flat_map{ |c|
233
+ REXML::XPath.match(refdoc.root, "//section[@pn=$pn]",
234
+ {}, {"pn" => c})}
235
+ what = "#{secpn.join(" or ")} in #{trg}"
236
+ add << " (#{case secs.size
237
+ when 0
238
+ error_out "*** cannot match #{what}"
239
+ "*** DOESN'T EXIST ***"
240
+ when 1
241
+ sec = secs.first
242
+ sec[:title] || sec.elements["name"].all_text
243
+ else
244
+ error_out "*** multiple matches for #{what}"
245
+ "*** MULTIPLE MATCHES ***"
246
+ end})"
247
+ elsif refhtmldoc # find section name in HTML from anchor s
248
+ secpn = section_number_to_htmlid(s)
249
+ secs = REXML::XPath.match(refhtmldoc.root,
250
+ "//xmlns:a[@id=$pn]/ancestor::xmlns:span",
251
+ {"xmlns" => "http://www.w3.org/1999/xhtml"},
252
+ {"pn" => secpn})
253
+ what = "#{secpn} in #{trg}"
254
+ add << " (#{case secs.size
255
+ when 0
256
+ error_out "*** cannot match #{what}"
257
+ "*** DOESN'T EXIST ***"
258
+ when 1
259
+ secs.first.text.sub(/^\.\s+/, '')
260
+ else
261
+ error_out "*** multiple matches for #{what}"
262
+ "*** MULTIPLE MATCHES ***"
263
+ end})"
264
+ end
265
+ puts "* #{/^[0-9]/ =~ s ? "Section" : "Appendix"} #{s}#{add}"
266
+ end
267
+ end
268
+
269
+ exit $exit_code
@@ -1,6 +1,6 @@
1
1
  spec = Gem::Specification.new do |s|
2
2
  s.name = 'kramdown-rfc2629'
3
- s.version = '1.7.11'
3
+ s.version = '1.7.13'
4
4
  s.summary = "Kramdown extension for generating RFCXML (RFC 799x)."
5
5
  s.description = %{An RFCXML (RFC 799x) generating backend for Thomas Leitner's
6
6
  "kramdown" markdown parser. Mostly useful for RFC writers.}
@@ -13,11 +13,12 @@ spec = Gem::Specification.new do |s|
13
13
  s.add_dependency('unicode-scripts', '~> 1.0')
14
14
  s.add_dependency('net-http-persistent', '~> 4.0')
15
15
  s.add_dependency('differ', '~>0.1')
16
- s.files = Dir['lib/**/*.rb'] + %w(README.md LICENSE kramdown-rfc2629.gemspec bin/kdrfc bin/kramdown-rfc bin/kramdown-rfc2629 bin/doilit bin/echars bin/kramdown-rfc-extract-markdown bin/kramdown-rfc-extract-sourcecode data/kramdown-rfc2629.erb data/encoding-fallbacks.txt data/math.json bin/kramdown-rfc-cache-subseries-bibxml bin/kramdown-rfc-autolink-iref-cleanup bin/de-gfm bin/kramdown-rfc-clean-svg-ids)
16
+ s.files = Dir['lib/**/*.rb'] + %w(README.md LICENSE kramdown-rfc2629.gemspec bin/kdrfc bin/kramdown-rfc bin/kramdown-rfc2629 bin/doilit bin/echars bin/kramdown-rfc-extract-markdown bin/kramdown-rfc-extract-sourcecode bin/kramdown-rfc-lsr data/kramdown-rfc2629.erb data/encoding-fallbacks.txt data/math.json bin/kramdown-rfc-cache-subseries-bibxml bin/kramdown-rfc-autolink-iref-cleanup bin/de-gfm bin/kramdown-rfc-clean-svg-ids)
17
17
  s.require_path = 'lib'
18
18
  s.executables = ['kramdown-rfc', 'kramdown-rfc2629', 'doilit', 'echars',
19
19
  'kramdown-rfc-extract-markdown',
20
20
  'kramdown-rfc-extract-sourcecode',
21
+ 'kramdown-rfc-lsr',
21
22
  'kdrfc', 'kramdown-rfc-cache-i-d-bibxml',
22
23
  'kramdown-rfc-cache-subseries-bibxml',
23
24
  'kramdown-rfc-autolink-iref-cleanup',
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.7.11
4
+ version: 1.7.13
5
5
  platform: ruby
6
6
  authors:
7
7
  - Carsten Bormann
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-04-21 00:00:00.000000000 Z
11
+ date: 2024-05-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: kramdown
@@ -147,6 +147,7 @@ executables:
147
147
  - echars
148
148
  - kramdown-rfc-extract-markdown
149
149
  - kramdown-rfc-extract-sourcecode
150
+ - kramdown-rfc-lsr
150
151
  - kdrfc
151
152
  - kramdown-rfc-cache-i-d-bibxml
152
153
  - kramdown-rfc-cache-subseries-bibxml
@@ -169,6 +170,7 @@ files:
169
170
  - bin/kramdown-rfc-clean-svg-ids
170
171
  - bin/kramdown-rfc-extract-markdown
171
172
  - bin/kramdown-rfc-extract-sourcecode
173
+ - bin/kramdown-rfc-lsr
172
174
  - bin/kramdown-rfc2629
173
175
  - data/encoding-fallbacks.txt
174
176
  - data/kramdown-rfc2629.erb
@@ -206,7 +208,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
206
208
  - !ruby/object:Gem::Version
207
209
  version: '0'
208
210
  requirements: []
209
- rubygems_version: 3.5.4
211
+ rubygems_version: 3.5.9
210
212
  signing_key:
211
213
  specification_version: 4
212
214
  summary: Kramdown extension for generating RFCXML (RFC 799x).