kramdown-rfc2629 1.6.31 → 1.6.32

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: 78da707841d2475396ae7578307bf10ab16440755d79591078490738b9dd89ed
4
- data.tar.gz: dc0143966fdc29ebe27e1cb07c28e4541b27038fac6d5a783d3dc2368e50d657
3
+ metadata.gz: 06d7a5e3575eaa6044b71492725d0aec45cae30106b435d7053dc6003a4a8ae2
4
+ data.tar.gz: 3f5aee93845187265047bb40decdfe9c24fa78acbf5f417c8609e04759ee882a
5
5
  SHA512:
6
- metadata.gz: 71abd171f1fce10fd52d5ba1d1cbedcd7c982090acf5d120c23be6702528a2eb5e09da2da9a6fc2d161eba5fc0980f5850eced87c403b7d21971e52588f849b8
7
- data.tar.gz: ea9ffd32a3189c778f3e74ead8ea43e8bc3961e9886a3b2055377da32f4ec36148eeee56c120fa627c3739cb41c9ab037d48f1300801ce3a6e61d96564003cb6
6
+ metadata.gz: c5b30e9a7de489ab05f1cea4ce856be9d5dd166a6989457da448b187963eccaefec4b92a76fa90e1c49e0e3016d11598e877f57f9f0a2c1ebd4003152818b58d
7
+ data.tar.gz: c2c2b61afbf59ba47aa0a0fd21969e3326beb02ddf7bad048fd252081daf4351a387133b0223510215a2afdbd9456bc41d1f1dae34c67589046dcb1ae9ad8a4e
@@ -0,0 +1,108 @@
1
+ #!/usr/bin/env ruby -KU
2
+ require 'rexml/document' # for SVG and bibxml acrobatics
3
+ require 'yaml'
4
+ require 'shellwords'
5
+ require 'fileutils'
6
+
7
+ def clean(s)
8
+ s.gsub!(/\//, ":")
9
+ s.gsub!(/[^:\w]/, "_") # handles leading dot, too -- s.gsub!(/\A([.]+)/) {"_" * $1.size } otherwise
10
+ s
11
+ end
12
+
13
+ target = nil
14
+ dir = nil
15
+ targets = [:list, :files, :zip, :yaml]
16
+ require 'optparse'
17
+ begin
18
+ op = OptionParser.new do |opts|
19
+ opts.banner = "Usage: kramdown-rfc-extract-sourcecode [options] document.xml"
20
+ opts.on("-tFMT", "--to=FMT", targets, "Target format #{targets.map(&:to_s)}") do |v|
21
+ target = v
22
+ end
23
+ opts.on("-dDIR", "--dir=DIR", "Target directory (default: sourcecode)") do |v|
24
+ dir = v
25
+ end
26
+ end
27
+ op.parse!
28
+ rescue Exception => e
29
+ warn e
30
+ exit 1
31
+ end
32
+ if dir
33
+ target ||= :files
34
+ unless [:files, :zip].include? target
35
+ warn "** Unused argument --dir=#{dir}"
36
+ end
37
+ end
38
+ dir ||= "sourcecode"
39
+
40
+ target ||= :list
41
+
42
+ gensym = "unnamed-000"
43
+ taken = Hash.new { |h, k| h[k] = Hash.new }
44
+ warned = Hash.new { |h, k| h[k] = Hash.new }
45
+ d = REXML::Document.new(ARGF)
46
+ REXML::XPath.each(d.root, "//sourcecode|//artwork") do |x|
47
+ if ty = x[:type]
48
+ ty = clean(ty)
49
+ name = x[:name] || gensym.succ!
50
+ name = clean(name)
51
+ if taken[ty][name]
52
+ unless warned[ty][name]
53
+ warn "Concatenating to #{ty}/#{name}."
54
+ warned[ty][name] = true
55
+ end
56
+ else
57
+ taken[ty][name] = ''
58
+ end
59
+ taken[ty][name] << x.text
60
+ end
61
+ end
62
+
63
+ def make_directory_from(dir, taken)
64
+ if File.exist?(dir)
65
+ bak = "#{dir}.bak"
66
+ begin
67
+ FileUtils.mv(dir, bak)
68
+ rescue Errno::EEXIST
69
+ bak.succ!
70
+ retry
71
+ end
72
+ end
73
+ FileUtils.mkdir_p(dir)
74
+ taken.each { |dir1, v|
75
+ FileUtils.mkdir_p("#{dir}/#{dir1}")
76
+ v.each { |fn, value|
77
+ IO.write("#{dir}/#{dir1}/#{fn}", value)
78
+ }
79
+ }
80
+ end
81
+
82
+ case target
83
+ when :yaml
84
+ puts taken.to_yaml
85
+ when :list
86
+ puts Hash[
87
+ taken.map {|k, v|
88
+ [k, v.keys]
89
+ }
90
+ ].to_yaml
91
+ when :files
92
+ make_directory_from(dir, taken)
93
+ when :zip
94
+ make_directory_from(dir, taken)
95
+ zip = "#{dir}.zip"
96
+ if File.exist?(zip)
97
+ bak = "#{zip}.bak"
98
+ begin
99
+ FileUtils.mv(zip, bak)
100
+ rescue Errno::EEXIST # This doesn't actually happen. XXX
101
+ bak.succ!
102
+ retry
103
+ end
104
+ end
105
+ cmd = ["zip", "-mr", zip, dir].shelljoin
106
+ warn cmd
107
+ system(cmd)
108
+ end
@@ -1,6 +1,6 @@
1
1
  spec = Gem::Specification.new do |s|
2
2
  s.name = 'kramdown-rfc2629'
3
- s.version = '1.6.31'
3
+ s.version = '1.6.32'
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,10 +13,11 @@ 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 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 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
+ 'kramdown-rfc-extract-sourcecode',
20
21
  'kdrfc', 'kramdown-rfc-cache-i-d-bibxml',
21
22
  'kramdown-rfc-cache-subseries-bibxml',
22
23
  'kramdown-rfc-autolink-iref-cleanup',
@@ -13,13 +13,6 @@ KDRFC_VERSION=Gem.loaded_specs["kramdown-rfc2629"].version rescue "unknown-versi
13
13
 
14
14
  Encoding.default_external = "UTF-8" # wake up, smell the coffee
15
15
 
16
- # Note that this doesn't attempt to handle HT characters
17
- def remove_indentation(s)
18
- l = s.lines
19
- indent = l.grep(/\S/).map {|l| l[/^\s*/].size}.min
20
- l.map {|li| li.sub(/^ {0,#{indent}}/, "")}.join
21
- end
22
-
23
16
  def add_quote(s)
24
17
  l = s.lines
25
18
  l.map {|li| "> #{li}"}.join
@@ -141,8 +134,8 @@ def do_the_tls_dance
141
134
  end
142
135
  end
143
136
 
144
- RE_NL = /(?:\n|\r|\r\n)/
145
- RE_SECTION = /---(?: +(\w+)(-?))?\s*#{RE_NL}(.*?#{RE_NL})(?=---(?:\s+\w+-?)?\s*#{RE_NL}|\Z)/m
137
+ RE_NL = /(?:\r\n|\n|\r)/
138
+ RE_SECTION = /---(?: +(\w+)(-?))? *#{RE_NL}(.*?#{RE_NL})(?=---(?:\s+\w+-?)?\s*#{RE_NL}|\Z)/m
146
139
 
147
140
  NMDTAGS = ["{:/nomarkdown}\n\n", "\n\n{::nomarkdown}\n"]
148
141
 
@@ -240,6 +233,12 @@ def xml_from_sections(input)
240
233
 
241
234
  sections = input.scan(RE_SECTION)
242
235
  # resulting in an array; each section is [section-label, nomarkdown-flag, section-text]
236
+ line = 1 # skip "---"
237
+ sections.each do |section|
238
+ section << line
239
+ line += 1 + section[2].lines.count
240
+ end
241
+ # warn "#{line-1} lines"
243
242
 
244
243
  # the first section is a YAML with front matter parameters (don't put a label here)
245
244
  # We put back the "---" plus gratuitous blank lines to hack the line number in errors
@@ -278,7 +277,7 @@ def xml_from_sections(input)
278
277
  # all the other sections are put in a Hash, possibly concatenated from parts there
279
278
  sechash = Hash.new{ |h,k| h[k] = ""}
280
279
  snames = [] # a stack of section names
281
- sections.each do |sname, nmdflag, text|
280
+ sections.each do |sname, nmdflag, text, line|
282
281
  # warn [:SNAME, sname, nmdflag, text[0..10]].inspect
283
282
  nmdin, nmdout = {
284
283
  "-" => ["", ""], # stay in nomarkdown
@@ -289,7 +288,7 @@ def xml_from_sections(input)
289
288
  else
290
289
  snames.pop # just "---" -> pop label (previous now current)
291
290
  end
292
- sechash[snames.last] << "#{nmdin}#{text}#{nmdout}"
291
+ sechash[snames.last] << "#{nmdin}<?line #{line}?>\n#{text}#{nmdout}"
293
292
  end
294
293
 
295
294
  ref_replacements = { }
@@ -540,7 +539,9 @@ if input[-1] != "\n"
540
539
  end
541
540
  process_includes(input) unless ENV["KRAMDOWN_SAFE"]
542
541
  input.gsub!(/^\{::boilerplate\s+(.*?)\}/) {
543
- boilerplate($1)
542
+ bp = boilerplate($1)
543
+ delta = bp.lines.count
544
+ bp + "<?line -#{delta+1}?>\n"
544
545
  }
545
546
  if input =~ /[\t]/
546
547
  warn "*** Input contains HT (\"tab\") characters. Undefined behavior will ensue."
@@ -1,3 +1,12 @@
1
+
2
+ # Note that this doesn't attempt to handle HT characters
3
+ def remove_indentation(s)
4
+ l = s.lines
5
+ indent = l.grep(/\S/).map {|l| l[/^\s*/].size}.min
6
+ l.map {|li| li.sub(/^ {0,#{indent}}/, "")}.join
7
+ end
8
+
9
+
1
10
  FOLD_MSG = "NOTE: '\\' line wrapping per RFC 8792".freeze
2
11
  MIN_FOLD_COLUMNS = FOLD_MSG.size
3
12
  FOLD_COLUMNS = 69
@@ -23,6 +23,7 @@ require 'json' # for math
23
23
  require 'rexml/document' # for SVG and bibxml acrobatics
24
24
 
25
25
  require 'kramdown-rfc/doi' # for fetching information for a DOI
26
+ require 'kramdown-rfc/rfc8792'
26
27
 
27
28
  class Object
28
29
  def deep_clone
@@ -315,15 +316,21 @@ module Kramdown
315
316
  def initialize(*doc)
316
317
  super
317
318
  @sec_level = 1
319
+ @location_delta = 100000 # until reset
320
+ @location_correction = 0 # pre-scanning corrections
318
321
  @in_dt = 0
319
322
  @footnote_names_in_use = {}
320
323
  end
321
324
 
325
+ def correct_location(location)
326
+ location + @location_delta + @location_correction
327
+ end
328
+
322
329
  def convert(el, indent = -INDENTATION, opts = {})
323
330
  if el.children[-1].type == :raw
324
331
  raw = convert1(el.children.pop, indent, opts)
325
332
  end
326
- "#{convert1(el, indent, opts)}#{end_sections(1, indent)}#{raw}"
333
+ "#{convert1(el, indent, opts)}#{end_sections(1, indent, el.options[:location])}#{raw}"
327
334
  end
328
335
 
329
336
  def convert1(el, indent, opts = {})
@@ -658,34 +665,77 @@ COLORS
658
665
  if anchor = el.attr['anchor']
659
666
  "##{anchor}"
660
667
  elsif lineno = el.options[:location]
661
- "approx. line #{lineno}" # XXX
668
+ "#{correct_location(lineno)}"
662
669
  else
663
670
  "UNKNOWN"
664
671
  end
672
+ preprocs = el.attr.delete("pre")
673
+ checks = el.attr.delete("check")
674
+ postprocs = el.attr.delete("post")
665
675
  case t
666
676
  when "json"
677
+ checks ||= "json"
678
+ when /\A(.*)-from-yaml\z/
679
+ t = $1
680
+ preprocs ||= "yaml2json"
681
+ end
682
+ preprocs = (preprocs || '').split("-")
683
+ checks = (checks || '').split("-")
684
+ postprocs = (postprocs || '').split("-")
685
+ result = sourcecode_checkproc(preprocs, checks, postprocs, loc_str, result)
686
+ "#{' '*indent}<figure#{el_html_attributes(el)}><#{gi}#{html_attributes(artwork_attr)}><![CDATA[#{result}#{result =~ /\n\Z/ ? '' : "\n"}]]></#{gi}></figure>\n"
687
+ end
688
+ end
689
+ end
690
+
691
+ def sourcecode_proc(proc, loc_str, result)
692
+ case proc
693
+ when "dedent"
694
+ result = remove_indentation(result)
695
+ when /\Afold(\d*)(left(\d*))?(dry)?\z/
696
+ fold = [$1.to_i, # col 0 for ''
697
+ ($3.to_i if $2), # left 0 for '', nil if no "left"
698
+ $4] # dry
699
+ result = fold8792_1(result, *fold)
700
+ when "yaml2json"
701
+ begin
702
+ y = YAML.safe_load(result, aliases: true, filename: loc_str)
703
+ result = JSON.pretty_generate(y)
704
+ rescue => e
705
+ warn "*** #{loc_str}: YAML isn't: #{e.message}\n"
706
+ end
707
+ else
708
+ warn "*** #{loc_str}: unknown proc '#{proc}'"
709
+ end
710
+ result
711
+ end
712
+
713
+ def sourcecode_checkproc(preprocs, checks, postprocs, loc_str, result)
714
+ preprocs.each do |proc|
715
+ result = sourcecode_proc(proc, loc_str, result)
716
+ end if preprocs
717
+ checks.each do |check|
718
+ case check
719
+ when "json"
720
+ # XXX check for 8792; undo if needed!
721
+ begin
722
+ JSON.load(result)
723
+ rescue => e
724
+ err1 = "*** #{loc_str}: JSON isn't: #{JSON.dump(e.message[0..40])}\n"
667
725
  begin
668
- JSON.load(result)
669
- rescue => e
670
- err1 = "*** #{loc_str}: JSON isn't: #{e.message[0..40]}\n"
671
- begin
672
- JSON.load("{" << result << "}")
673
- rescue => e
674
- warn err1 << "*** not even with braces added around: #{e.message[0..40]}"
675
- end
676
- end
677
- when "json-from-yaml"
678
- begin
679
- y = YAML.safe_load(result, aliases: true, filename: loc_str)
680
- result = JSON.pretty_generate(y)
681
- t = "json" # XXX, this could be another format!
726
+ JSON.load("{" << result << "}")
682
727
  rescue => e
683
- warn "*** YAML isn't: #{e.message}\n"
728
+ warn err1 << "*** not even with braces added around: #{JSON.dump(e.message[0..40])}"
684
729
  end
685
730
  end
686
- "#{' '*indent}<figure#{el_html_attributes(el)}><#{gi}#{html_attributes(artwork_attr)}><![CDATA[#{result}#{result =~ /\n\Z/ ? '' : "\n"}]]></#{gi}></figure>\n"
731
+ else
732
+ warn "*** #{loc_str}: unknown check '#{check}'"
687
733
  end
688
- end
734
+ end if checks
735
+ postprocs.each do |proc|
736
+ result = sourcecode_proc(proc, loc_str, result)
737
+ end if postprocs
738
+ result
689
739
  end
690
740
 
691
741
  def mk_artwork(artwork_attr, typ, content)
@@ -707,7 +757,7 @@ COLORS
707
757
  end
708
758
  end
709
759
 
710
- def end_sections(to_level, indent)
760
+ def end_sections(to_level, indent, location)
711
761
  if indent < 0
712
762
  indent = 0
713
763
  end
@@ -716,7 +766,7 @@ COLORS
716
766
  @sec_level = to_level
717
767
  "#{' '*indent}</section>\n" * delta
718
768
  else
719
- $stderr.puts "Incorrect section nesting: Need to start with 1"
769
+ $stderr.puts "** #{correct_location(location)}: Bad section nesting: start heading level at 1 and increment by 1"
720
770
  end
721
771
  end
722
772
 
@@ -768,7 +818,7 @@ COLORS
768
818
  clean, irefs = clean_pcdata(inner_a(el, indent, opts))
769
819
  el.attr['title'] = clean
770
820
  end
771
- "#{end_sections(el.options[:level], indent)}#{' '*indent}<section#{@sec_level += 1; el_html_attributes(el)}>#{irefs}\n"
821
+ "#{end_sections(el.options[:level], indent, el.options[:location])}#{' '*indent}<section#{@sec_level += 1; el_html_attributes(el)}>#{irefs}\n"
772
822
  end
773
823
 
774
824
  def convert_hr(el, indent, opts) # misuse for page break
@@ -885,6 +935,15 @@ COLORS
885
935
  end
886
936
 
887
937
  def convert_xml_comment(el, indent, opts)
938
+ if el.value =~ /\A<\?line (([-+]?)[0-9]+)\?>\z/
939
+ lineno = $1.to_i
940
+ case $2
941
+ when '' # absolute
942
+ @location_delta = lineno - el.options[:location]
943
+ when '+', '-' # correction (pre-scanning!)
944
+ @location_correction += lineno
945
+ end
946
+ end
888
947
  if el.options[:category] == :block && !el.options[:parent_is_raw]
889
948
  ' '*indent + el.value + "\n"
890
949
  else
@@ -1277,7 +1336,7 @@ COLORS
1277
1336
  end
1278
1337
 
1279
1338
  def convert_raw(el, indent, opts)
1280
- end_sections(1, indent) +
1339
+ end_sections(1, indent, el.options[:location]) +
1281
1340
  el.value + (el.options[:category] == :block ? "\n" : '')
1282
1341
  end
1283
1342
 
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.6.31
4
+ version: 1.6.32
5
5
  platform: ruby
6
6
  authors:
7
7
  - Carsten Bormann
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-04-20 00:00:00.000000000 Z
11
+ date: 2023-04-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: kramdown
@@ -146,6 +146,7 @@ executables:
146
146
  - doilit
147
147
  - echars
148
148
  - kramdown-rfc-extract-markdown
149
+ - kramdown-rfc-extract-sourcecode
149
150
  - kdrfc
150
151
  - kramdown-rfc-cache-i-d-bibxml
151
152
  - kramdown-rfc-cache-subseries-bibxml
@@ -167,6 +168,7 @@ files:
167
168
  - bin/kramdown-rfc-cache-subseries-bibxml
168
169
  - bin/kramdown-rfc-clean-svg-ids
169
170
  - bin/kramdown-rfc-extract-markdown
171
+ - bin/kramdown-rfc-extract-sourcecode
170
172
  - bin/kramdown-rfc2629
171
173
  - data/encoding-fallbacks.txt
172
174
  - data/kramdown-rfc2629.erb