kramdown-rfc2629 1.5.22 → 1.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +13 -0
- data/bin/kdrfc +17 -0
- data/bin/kramdown-rfc +9 -0
- data/bin/kramdown-rfc2629 +1 -525
- data/data/kramdown-rfc2629.erb +16 -3
- data/kramdown-rfc2629.gemspec +3 -3
- data/lib/kramdown-rfc/command.rb +572 -0
- data/lib/kramdown-rfc/kdrfc-processor.rb +3 -1
- data/lib/kramdown-rfc/parameterset.rb +22 -2
- data/lib/kramdown-rfc/refxml.rb +107 -10
- data/lib/kramdown-rfc/rfc8792.rb +26 -8
- data/lib/kramdown-rfc2629.rb +10 -2
- metadata +6 -3
data/lib/kramdown-rfc/refxml.rb
CHANGED
@@ -8,6 +8,12 @@ module KramdownRFC
|
|
8
8
|
escape_html(str.to_s, :attribute)
|
9
9
|
end
|
10
10
|
|
11
|
+
AUTHOR_ATTRIBUTES = %w{
|
12
|
+
initials surname fullname
|
13
|
+
asciiInitials asciiSurname asciiFullname
|
14
|
+
role
|
15
|
+
}
|
16
|
+
|
11
17
|
def self.ref_to_xml(k, v)
|
12
18
|
vps = KramdownRFC::ParameterSet.new(v)
|
13
19
|
erb = ERB.trim_new <<-REFERB, '-'
|
@@ -18,7 +24,7 @@ module KramdownRFC
|
|
18
24
|
<% vps.arr("author", true, true) do |au|
|
19
25
|
aups = authorps_from_hash(au)
|
20
26
|
-%>
|
21
|
-
<author <%=aups.attrs(
|
27
|
+
<author <%=aups.attrs(*AUTHOR_ATTRIBUTES)%>>
|
22
28
|
<%= aups.ele("organization=org", aups.attr("abbrev=orgabbrev"), "") %>
|
23
29
|
</author>
|
24
30
|
<% aups.warn_if_leftovers -%>
|
@@ -40,19 +46,110 @@ module KramdownRFC
|
|
40
46
|
ret
|
41
47
|
end
|
42
48
|
|
49
|
+
def self.treat_multi_attribute_member(ps, an)
|
50
|
+
value = ps.rest[an]
|
51
|
+
if Hash === value
|
52
|
+
value.each do |k, v|
|
53
|
+
ps.rest[if k == ':'
|
54
|
+
an
|
55
|
+
else
|
56
|
+
Kramdown::Element.attrmangle(k + an) ||
|
57
|
+
Kramdown::Element.attrmangle(k) ||
|
58
|
+
k
|
59
|
+
end] = v
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.initializify(s) # XXX Jean-Pierre
|
65
|
+
w = '\p{Lu}\p{Lo}'
|
66
|
+
if s =~ /\A[-.#{w}]+[.]/u
|
67
|
+
$&
|
68
|
+
elsif s =~ /\A([#{w}])[^-]*/u
|
69
|
+
ret = "#$1."
|
70
|
+
while (s = $') && s =~ /\A(-[\p{L}])[^-]*/u
|
71
|
+
ret << "#$1."
|
72
|
+
end
|
73
|
+
ret
|
74
|
+
else
|
75
|
+
warn "*** Can't initializify #{s}"
|
76
|
+
s
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def self.looks_like_initial(s)
|
81
|
+
s =~ /\A[\p{Lu}\p{Lo}]([-.][\p{Lu}\p{Lo}]?)*\z/u
|
82
|
+
end
|
83
|
+
|
84
|
+
def self.initials_from_parts_and_surname(aups, parts, s)
|
85
|
+
ssz = s.size
|
86
|
+
nonsurname = parts[0...-ssz]
|
87
|
+
if (ns = parts[-ssz..-1]) != s
|
88
|
+
warn "*** inconsistent surnames #{ns} and #{s}"
|
89
|
+
end
|
90
|
+
nonsurname.map{|x| initializify(x)}.join(" ")
|
91
|
+
end
|
92
|
+
|
93
|
+
def self.handle_ins(aups, ins_k, initials_k, surname_k)
|
94
|
+
if ins = aups[ins_k]
|
95
|
+
parts = ins.split('.').map(&:strip) # split on dots first
|
96
|
+
# Coalesce H.-P.
|
97
|
+
i = 1; while i < parts.size
|
98
|
+
if parts[i][0] == "-"
|
99
|
+
parts[i-1..i] = [parts[i-1] + "." + parts[i]]
|
100
|
+
else
|
101
|
+
i += 1
|
102
|
+
end
|
103
|
+
end
|
104
|
+
# Multiple surnames in ins?
|
105
|
+
parts[-1..-1] = parts[-1].split
|
106
|
+
s = if surname = aups.rest[surname_k]
|
107
|
+
surname.split
|
108
|
+
else parts.reverse.take_while{|x| !looks_like_initial(x)}.reverse
|
109
|
+
end
|
110
|
+
aups.rest[initials_k] = initials_from_parts_and_surname(aups, parts, s)
|
111
|
+
aups.rest[surname_k] = s.join(" ")
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def self.handle_name(aups, fn_k, initials_k, surname_k)
|
116
|
+
if name = aups.rest[fn_k]
|
117
|
+
names = name.split(/ *\| */, 2) # boundary for given/last name
|
118
|
+
if names[1]
|
119
|
+
aups.rest[fn_k] = name = names.join(" ") # remove boundary
|
120
|
+
if surname = aups.rest[surname_k]
|
121
|
+
if surname != names[1]
|
122
|
+
warn "*** inconsistent embedded surname #{names[1]} and surname #{surname}"
|
123
|
+
end
|
124
|
+
end
|
125
|
+
aups.rest[surname_k] = names[1]
|
126
|
+
end
|
127
|
+
parts = name.split
|
128
|
+
surname = aups.rest[surname_k] || parts[-1]
|
129
|
+
s = surname.split
|
130
|
+
aups.rest[initials_k] ||= initials_from_parts_and_surname(aups, parts, s)
|
131
|
+
aups.rest[surname_k] = s.join(" ")
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
43
135
|
def self.authorps_from_hash(au)
|
44
136
|
aups = KramdownRFC::ParameterSet.new(au)
|
45
|
-
if
|
46
|
-
|
47
|
-
aups.rest["
|
48
|
-
|
137
|
+
if n = aups[:name]
|
138
|
+
warn "** both name #{n} and fullname #{fn} are set on one author" if fn = aups.rest["fullname"]
|
139
|
+
aups.rest["fullname"] = n
|
140
|
+
usename = true
|
141
|
+
end
|
142
|
+
["fullname", "ins", "initials", "surname"].each do |an|
|
143
|
+
treat_multi_attribute_member(aups, an)
|
49
144
|
end
|
145
|
+
handle_ins(aups, :ins, "initials", "surname")
|
146
|
+
handle_ins(aups, :asciiIns, "asciiInitials", "asciiSurname")
|
50
147
|
# hack ("heuristic for") initials and surname from name
|
51
148
|
# -- only works for people with exactly one last name and uncomplicated first names
|
52
|
-
|
53
|
-
|
54
|
-
aups
|
55
|
-
aups
|
149
|
+
# -- add surname for people with more than one last name
|
150
|
+
if usename
|
151
|
+
handle_name(aups, "fullname", "initials", "surname")
|
152
|
+
handle_name(aups, "asciiFullname", "asciiInitials", "asciiSurname")
|
56
153
|
end
|
57
154
|
aups
|
58
155
|
end
|
@@ -69,7 +166,7 @@ module KramdownRFC
|
|
69
166
|
# country: Germany
|
70
167
|
|
71
168
|
PERSON_ERB = <<~ERB
|
72
|
-
<<%= element_name%> <%=aups.attrs(
|
169
|
+
<<%= element_name%> <%=aups.attrs(*AUTHOR_ATTRIBUTES)%>>
|
73
170
|
<%= aups.ele("organization=org", aups.attrs("abbrev=orgabbrev",
|
74
171
|
*[$options.v3 && "ascii=orgascii"]), "") %>
|
75
172
|
<address>
|
data/lib/kramdown-rfc/rfc8792.rb
CHANGED
@@ -1,11 +1,22 @@
|
|
1
|
+
FOLD_MSG = "NOTE: '\\' line wrapping per RFC 8792".freeze
|
2
|
+
MIN_FOLD_COLUMNS = FOLD_MSG.size
|
1
3
|
FOLD_COLUMNS = 69
|
2
4
|
RE_IDENT = /\A[A-Za-z0-9_]\z/
|
3
5
|
|
4
|
-
def fold8792_1(s, columns = FOLD_COLUMNS)
|
6
|
+
def fold8792_1(s, columns = FOLD_COLUMNS, left = false, dry = false)
|
5
7
|
if s.index("\t")
|
6
8
|
warn "*** HT (\"TAB\") in text to be folded. Giving up."
|
7
9
|
return s
|
8
10
|
end
|
11
|
+
if columns < MIN_FOLD_COLUMNS
|
12
|
+
columns =
|
13
|
+
if columns == 0
|
14
|
+
FOLD_COLUMNS
|
15
|
+
else
|
16
|
+
warn "*** folding to #{MIN_FOLD_COLUMNS}, not #{columns}"
|
17
|
+
MIN_FOLD_COLUMNS
|
18
|
+
end
|
19
|
+
end
|
9
20
|
|
10
21
|
lines = s.lines.map(&:chomp)
|
11
22
|
did_fold = false
|
@@ -20,25 +31,26 @@ def fold8792_1(s, columns = FOLD_COLUMNS)
|
|
20
31
|
ix += 1
|
21
32
|
else
|
22
33
|
did_fold = true
|
34
|
+
min_indent = left || 0
|
23
35
|
col -= 1 # space for "\\"
|
24
36
|
while li[col] == " " # can't start new line with " "
|
25
37
|
col -= 1
|
26
38
|
end
|
27
|
-
if col <=
|
28
|
-
warn "*** Cannot RFC8792-fold1 #{li.inspect}"
|
39
|
+
if col <= min_indent
|
40
|
+
warn "*** Cannot RFC8792-fold1 to #{columns} cols #{"with indent #{left}" if left} |#{li.inspect}|"
|
29
41
|
else
|
30
42
|
if RE_IDENT === li[col] # Don't split IDs
|
31
43
|
col2 = col
|
32
|
-
while col2 >
|
44
|
+
while col2 > min_indent && RE_IDENT === li[col2-1]
|
33
45
|
col2 -= 1
|
34
46
|
end
|
35
|
-
if col2 >
|
47
|
+
if col2 > min_indent
|
36
48
|
col = col2
|
37
49
|
end
|
38
50
|
end
|
39
51
|
rest = li[col..-1]
|
40
|
-
indent = columns - rest.size
|
41
|
-
if li[-1] == "\\"
|
52
|
+
indent = left || columns - rest.size
|
53
|
+
if !left && li[-1] == "\\"
|
42
54
|
indent -= 1 # leave space for next round
|
43
55
|
end
|
44
56
|
if indent > 0
|
@@ -51,7 +63,13 @@ def fold8792_1(s, columns = FOLD_COLUMNS)
|
|
51
63
|
end
|
52
64
|
|
53
65
|
if did_fold
|
54
|
-
|
66
|
+
msg = FOLD_MSG.dup
|
67
|
+
if !dry && columns >= msg.size + 4
|
68
|
+
delta = columns - msg.size - 2 # 2 spaces
|
69
|
+
half = delta/2
|
70
|
+
msg = "#{"=" * half} #{msg} #{"=" * (delta - half)}"
|
71
|
+
end
|
72
|
+
lines[0...0] = [msg, ""]
|
55
73
|
lines.map{|x| x << "\n"}.join
|
56
74
|
else
|
57
75
|
s
|
data/lib/kramdown-rfc2629.rb
CHANGED
@@ -242,6 +242,14 @@ module Kramdown
|
|
242
242
|
TRUTHY["false"] = false
|
243
243
|
TRUTHY["no"] = false
|
244
244
|
|
245
|
+
# explicit or automatic studlification
|
246
|
+
# note that explicit (including trailing "_") opts out of automatic
|
247
|
+
def self.attrmangle(k)
|
248
|
+
if (d = k.gsub(/_(.|$)/) { $1.upcase }) != k or d = STUDLY_ATTR_MAP[k]
|
249
|
+
d
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
245
253
|
def rfc2629_fix(opts)
|
246
254
|
if a = attr
|
247
255
|
if anchor = a.delete('id')
|
@@ -254,7 +262,7 @@ module Kramdown
|
|
254
262
|
opts = opts.merge(noabbrev: TRUTHY[av]) # updated copy
|
255
263
|
end
|
256
264
|
attr.keys.each do |k|
|
257
|
-
if
|
265
|
+
if d = self.class.attrmangle(k)
|
258
266
|
a[d] = a.delete(k)
|
259
267
|
end
|
260
268
|
end
|
@@ -1323,7 +1331,7 @@ COLORS
|
|
1323
1331
|
if target == "#"
|
1324
1332
|
target = value
|
1325
1333
|
else
|
1326
|
-
target = target[1
|
1334
|
+
target = target[1..-1]
|
1327
1335
|
end
|
1328
1336
|
else
|
1329
1337
|
target = nil
|
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.
|
4
|
+
version: 1.6.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Carsten Bormann
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-02-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: kramdown
|
@@ -71,6 +71,7 @@ description: |-
|
|
71
71
|
"kramdown" markdown parser. Mostly useful for RFC writers.
|
72
72
|
email: cabo@tzi.org
|
73
73
|
executables:
|
74
|
+
- kramdown-rfc
|
74
75
|
- kramdown-rfc2629
|
75
76
|
- doilit
|
76
77
|
- kramdown-rfc-extract-markdown
|
@@ -86,6 +87,7 @@ files:
|
|
86
87
|
- bin/de-gfm
|
87
88
|
- bin/doilit
|
88
89
|
- bin/kdrfc
|
90
|
+
- bin/kramdown-rfc
|
89
91
|
- bin/kramdown-rfc-cache-i-d-bibxml
|
90
92
|
- bin/kramdown-rfc-cache-subseries-bibxml
|
91
93
|
- bin/kramdown-rfc-extract-markdown
|
@@ -94,6 +96,7 @@ files:
|
|
94
96
|
- data/kramdown-rfc2629.erb
|
95
97
|
- data/math.json
|
96
98
|
- kramdown-rfc2629.gemspec
|
99
|
+
- lib/kramdown-rfc/command.rb
|
97
100
|
- lib/kramdown-rfc/erb.rb
|
98
101
|
- lib/kramdown-rfc/gzip-clone.rb
|
99
102
|
- lib/kramdown-rfc/kdrfc-processor.rb
|
@@ -120,7 +123,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
120
123
|
- !ruby/object:Gem::Version
|
121
124
|
version: '0'
|
122
125
|
requirements: []
|
123
|
-
rubygems_version: 3.
|
126
|
+
rubygems_version: 3.3.3
|
124
127
|
signing_key:
|
125
128
|
specification_version: 4
|
126
129
|
summary: Kramdown extension for generating RFC 7749 XML.
|