metanorma-ietf 1.0.10 → 2.0.0

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.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/macos.yml +3 -2
  3. data/.github/workflows/ubuntu.yml +3 -2
  4. data/.github/workflows/windows.yml +4 -3
  5. data/README.adoc +9 -0
  6. data/lib/asciidoctor/ietf/basicdoc.rng +1045 -0
  7. data/lib/asciidoctor/ietf/biblio.rng +1142 -0
  8. data/lib/asciidoctor/ietf/blocks.rb +76 -0
  9. data/lib/asciidoctor/ietf/converter.rb +211 -0
  10. data/lib/asciidoctor/ietf/front.rb +143 -0
  11. data/lib/asciidoctor/ietf/ietf.rng +882 -0
  12. data/lib/asciidoctor/ietf/isodoc.rng +514 -0
  13. data/lib/asciidoctor/ietf/isostandard.rng +860 -0
  14. data/lib/asciidoctor/ietf/reqt.rng +171 -0
  15. data/lib/asciidoctor/ietf/validate.rb +84 -0
  16. data/lib/isodoc/ietf/blocks.rb +215 -0
  17. data/lib/isodoc/ietf/cleanup.rb +220 -0
  18. data/lib/isodoc/ietf/footnotes.rb +70 -0
  19. data/lib/isodoc/ietf/front.rb +232 -0
  20. data/lib/isodoc/ietf/inline.rb +136 -0
  21. data/lib/isodoc/ietf/metadata.rb +62 -0
  22. data/lib/isodoc/ietf/references.rb +129 -0
  23. data/lib/isodoc/ietf/reqt.rb +74 -0
  24. data/lib/isodoc/ietf/rfc_convert.rb +60 -0
  25. data/lib/isodoc/ietf/section.rb +162 -0
  26. data/lib/isodoc/ietf/table.rb +43 -0
  27. data/lib/isodoc/ietf/terms.rb +65 -0
  28. data/lib/metanorma-ietf.rb +2 -1
  29. data/lib/metanorma/ietf/processor.rb +16 -37
  30. data/lib/metanorma/ietf/version.rb +1 -1
  31. data/metanorma-ietf.gemspec +3 -3
  32. metadata +36 -36
  33. data/Gemfile.lock +0 -327
  34. data/lib/asciidoctor/rfc.rb +0 -8
  35. data/lib/asciidoctor/rfc/common/base.rb +0 -544
  36. data/lib/asciidoctor/rfc/common/front.rb +0 -120
  37. data/lib/asciidoctor/rfc/common/validate.rb +0 -31
  38. data/lib/asciidoctor/rfc/v2/base.rb +0 -380
  39. data/lib/asciidoctor/rfc/v2/blocks.rb +0 -299
  40. data/lib/asciidoctor/rfc/v2/converter.rb +0 -60
  41. data/lib/asciidoctor/rfc/v2/front.rb +0 -69
  42. data/lib/asciidoctor/rfc/v2/inline_anchor.rb +0 -111
  43. data/lib/asciidoctor/rfc/v2/lists.rb +0 -135
  44. data/lib/asciidoctor/rfc/v2/table.rb +0 -116
  45. data/lib/asciidoctor/rfc/v2/validate.rng +0 -716
  46. data/lib/asciidoctor/rfc/v3/base.rb +0 -330
  47. data/lib/asciidoctor/rfc/v3/blocks.rb +0 -246
  48. data/lib/asciidoctor/rfc/v3/converter.rb +0 -62
  49. data/lib/asciidoctor/rfc/v3/front.rb +0 -122
  50. data/lib/asciidoctor/rfc/v3/inline_anchor.rb +0 -89
  51. data/lib/asciidoctor/rfc/v3/lists.rb +0 -176
  52. data/lib/asciidoctor/rfc/v3/svg.rng +0 -9081
  53. data/lib/asciidoctor/rfc/v3/table.rb +0 -65
  54. data/lib/asciidoctor/rfc/v3/validate.rng +0 -2143
@@ -1,327 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- metanorma-ietf (1.0.9)
5
- isodoc (~> 1.0.0)
6
- metanorma-standoc (~> 1.3.0)
7
-
8
- GEM
9
- remote: https://rubygems.org/
10
- specs:
11
- addressable (2.7.0)
12
- public_suffix (>= 2.0.2, < 5.0)
13
- asciidoctor (2.0.10)
14
- asciimath (1.0.9)
15
- ast (2.4.0)
16
- byebug (9.1.0)
17
- camertron-eprun (1.1.1)
18
- cldr-plurals-runtime-rb (1.0.1)
19
- cnccs (0.1.5)
20
- coderay (1.1.2)
21
- concurrent-ruby (1.1.5)
22
- crack (0.4.3)
23
- safe_yaml (~> 1.0.0)
24
- diff-lcs (1.3)
25
- docile (1.3.2)
26
- equivalent-xml (0.6.0)
27
- nokogiri (>= 1.4.3)
28
- faraday (0.17.1)
29
- multipart-post (>= 1.2, < 3)
30
- ffi (1.11.3)
31
- formatador (0.2.5)
32
- gb-agencies (0.0.6)
33
- git (1.5.0)
34
- guard (2.16.1)
35
- formatador (>= 0.2.4)
36
- listen (>= 2.7, < 4.0)
37
- lumberjack (>= 1.0.12, < 2.0)
38
- nenv (~> 0.1)
39
- notiffany (~> 0.0)
40
- pry (>= 0.9.12)
41
- shellany (~> 0.0)
42
- thor (>= 0.18.1)
43
- guard-compat (1.2.1)
44
- guard-rspec (4.7.3)
45
- guard (~> 2.1)
46
- guard-compat (~> 1.1)
47
- rspec (>= 2.99.0, < 4.0)
48
- hashdiff (1.0.0)
49
- html2doc (0.9.2)
50
- asciimath (~> 1.0.9)
51
- htmlentities (~> 4.3.4)
52
- image_size
53
- mime-types
54
- nokogiri (>= 1.10.4)
55
- thread_safe
56
- uuidtools
57
- htmlentities (4.3.4)
58
- iev (0.2.3)
59
- nokogiri (>= 1.10.4)
60
- image_size (2.0.2)
61
- iso-639 (0.2.8)
62
- isodoc (1.0.9)
63
- asciimath
64
- html2doc (~> 0.9.0)
65
- htmlentities (~> 4.3.4)
66
- liquid
67
- metanorma (~> 0.3.0)
68
- nokogiri (>= 1.10.4)
69
- rake (~> 12.0)
70
- roman-numerals
71
- sassc (~> 2.2.1)
72
- thread_safe
73
- uuidtools
74
- isoics (0.1.8)
75
- jaro_winkler (1.5.4)
76
- json (2.2.0)
77
- liquid (4.0.3)
78
- listen (3.2.1)
79
- rb-fsevent (~> 0.10, >= 0.10.3)
80
- rb-inotify (~> 0.9, >= 0.9.10)
81
- lumberjack (1.0.13)
82
- metanorma (0.3.18)
83
- asciidoctor
84
- htmlentities
85
- metanorma-acme (1.3.7)
86
- htmlentities (~> 4.3.4)
87
- isodoc (~> 1.0.0)
88
- metanorma-standoc (~> 1.3.0)
89
- ruby-jing
90
- metanorma-cli (1.2.8)
91
- git (~> 1.5)
92
- isodoc (~> 1.0.0)
93
- metanorma (~> 0.3.9)
94
- metanorma-acme (~> 1.3.0)
95
- metanorma-csand (~> 1.3.0)
96
- metanorma-csd (~> 1.3.0)
97
- metanorma-gb (~> 1.3.0)
98
- metanorma-iec (~> 0.1.0)
99
- metanorma-ietf (~> 1.0.1)
100
- metanorma-iso (~> 1.3.0)
101
- metanorma-itu (~> 1.0.0)
102
- metanorma-m3d (~> 1.3.0)
103
- metanorma-nist (~> 0.2.0)
104
- metanorma-ogc (~> 0.2.0)
105
- metanorma-standoc (~> 1.3.0)
106
- metanorma-unece (~> 0.2.0)
107
- thor (~> 0.20.3)
108
- metanorma-csand (1.3.7)
109
- htmlentities (~> 4.3.4)
110
- image_size
111
- isodoc (~> 1.0.0)
112
- metanorma-standoc (~> 1.3.0)
113
- mime-types
114
- ruby-jing
115
- thread_safe
116
- uuidtools
117
- metanorma-csd (1.3.7)
118
- isodoc (~> 1.0.0)
119
- metanorma-standoc (~> 1.3.0)
120
- metanorma-gb (1.3.9)
121
- gb-agencies (~> 0.0.4)
122
- htmlentities (~> 4.3.4)
123
- isodoc (~> 1.0.0)
124
- metanorma-iso (~> 1.3.0)
125
- twitter_cldr (~> 4.4.4)
126
- metanorma-iec (0.1.1)
127
- isodoc (~> 1.0.0)
128
- metanorma-iso (~> 1.3.0)
129
- ruby-jing
130
- metanorma-iso (1.3.10)
131
- isodoc (~> 1.0.0)
132
- metanorma-standoc (~> 1.3.0)
133
- ruby-jing
134
- metanorma-itu (1.0.0)
135
- htmlentities (~> 4.3.4)
136
- isodoc (~> 1.0.0)
137
- metanorma-standoc (~> 1.3.0)
138
- ruby-jing
139
- metanorma-m3d (1.3.7)
140
- asciimath
141
- htmlentities (~> 4.3.4)
142
- image_size
143
- isodoc (~> 1.0.0)
144
- metanorma-standoc (~> 1.3.0)
145
- mime-types
146
- ruby-jing
147
- thread_safe
148
- uuidtools
149
- metanorma-nist (0.2.8)
150
- htmlentities (~> 4.3.4)
151
- isodoc (~> 1.0.0)
152
- metanorma-standoc (~> 1.3.0)
153
- ruby-jing
154
- twitter_cldr
155
- tzinfo-data
156
- metanorma-ogc (0.2.8)
157
- htmlentities (~> 4.3.4)
158
- iso-639
159
- isodoc (~> 1.0.0)
160
- metanorma-standoc (~> 1.3.0)
161
- ruby-jing
162
- metanorma-standoc (1.3.9)
163
- asciidoctor (~> 2.0.0)
164
- concurrent-ruby
165
- html2doc (~> 0.9.0)
166
- iev (~> 0.2.1)
167
- isodoc (~> 1.0.0)
168
- mimemagic
169
- relaton (~> 0.5.0)
170
- relaton-iev (~> 0.1.0)
171
- ruby-jing
172
- sterile (~> 1.0.14)
173
- unicode2latex (~> 0.0.1)
174
- metanorma-unece (0.2.9)
175
- htmlentities (~> 4.3.4)
176
- iso-639
177
- isodoc (~> 1.0.0)
178
- metanorma-standoc (~> 1.3.0)
179
- roman-numerals
180
- ruby-jing
181
- twitter_cldr
182
- method_source (0.9.2)
183
- mime-types (3.3)
184
- mime-types-data (~> 3.2015)
185
- mime-types-data (3.2019.1009)
186
- mimemagic (0.3.3)
187
- mini_portile2 (2.4.0)
188
- multipart-post (2.1.1)
189
- nenv (0.3.0)
190
- nokogiri (1.10.7)
191
- mini_portile2 (~> 2.4.0)
192
- notiffany (0.1.3)
193
- nenv (~> 0.1)
194
- shellany (~> 0.0)
195
- optout (0.0.2)
196
- parallel (1.19.1)
197
- parser (2.6.5.0)
198
- ast (~> 2.4.0)
199
- pry (0.12.2)
200
- coderay (~> 1.1.0)
201
- method_source (~> 0.9.0)
202
- public_suffix (4.0.1)
203
- rainbow (3.0.0)
204
- rake (12.3.3)
205
- rb-fsevent (0.10.3)
206
- rb-inotify (0.10.0)
207
- ffi (~> 1.0)
208
- relaton (0.5.19)
209
- relaton-calconnect (~> 0.1.0)
210
- relaton-gb (~> 0.6.0)
211
- relaton-iec (~> 0.4.0)
212
- relaton-ietf (~> 0.6.0)
213
- relaton-iso (~> 0.6.0)
214
- relaton-itu (~> 0.3.0)
215
- relaton-nist (~> 0.3.0)
216
- relaton-ogc (~> 0.1.0)
217
- relaton-bib (0.3.12)
218
- addressable
219
- nokogiri
220
- relaton-calconnect (0.1.2)
221
- faraday
222
- relaton-iso-bib (~> 0.3.0)
223
- relaton-gb (0.6.8)
224
- cnccs (~> 0.1.1)
225
- gb-agencies (~> 0.0.1)
226
- relaton-iso-bib (~> 0.3.0)
227
- relaton-iec (0.4.12)
228
- addressable
229
- relaton-iso-bib (~> 0.3.0)
230
- relaton-ietf (0.6.10)
231
- relaton-bib (~> 0.3.0)
232
- relaton-iev (0.1.1)
233
- relaton (~> 0.5.0)
234
- relaton-iso (0.6.10)
235
- relaton-iec (~> 0.4.0)
236
- relaton-iso-bib (~> 0.3.0)
237
- relaton-iso-bib (0.3.12)
238
- isoics (~> 0.1.6)
239
- relaton-bib (~> 0.3.0)
240
- ruby_deep_clone (~> 0.8.0)
241
- relaton-itu (0.3.11)
242
- relaton-iso-bib (~> 0.3.0)
243
- relaton-nist (0.3.9)
244
- relaton-bib (~> 0.3.0)
245
- rubyzip
246
- relaton-ogc (0.1.4)
247
- faraday
248
- relaton-iso-bib (~> 0.3.0)
249
- roman-numerals (0.3.0)
250
- rspec (3.9.0)
251
- rspec-core (~> 3.9.0)
252
- rspec-expectations (~> 3.9.0)
253
- rspec-mocks (~> 3.9.0)
254
- rspec-core (3.9.0)
255
- rspec-support (~> 3.9.0)
256
- rspec-expectations (3.9.0)
257
- diff-lcs (>= 1.2.0, < 2.0)
258
- rspec-support (~> 3.9.0)
259
- rspec-mocks (3.9.0)
260
- diff-lcs (>= 1.2.0, < 2.0)
261
- rspec-support (~> 3.9.0)
262
- rspec-support (3.9.0)
263
- rubocop (0.77.0)
264
- jaro_winkler (~> 1.5.1)
265
- parallel (~> 1.10)
266
- parser (>= 2.6)
267
- rainbow (>= 2.2.2, < 4.0)
268
- ruby-progressbar (~> 1.7)
269
- unicode-display_width (>= 1.4.0, < 1.7)
270
- ruby-jing (0.0.1)
271
- optout (>= 0.0.2)
272
- ruby-progressbar (1.10.1)
273
- ruby_deep_clone (0.8.0)
274
- rubyzip (2.0.0)
275
- safe_yaml (1.0.5)
276
- sassc (2.2.1)
277
- ffi (~> 1.9)
278
- shellany (0.0.1)
279
- simplecov (0.17.1)
280
- docile (~> 1.1)
281
- json (>= 1.8, < 3)
282
- simplecov-html (~> 0.10.0)
283
- simplecov-html (0.10.2)
284
- sterile (1.0.14)
285
- nokogiri
286
- thor (0.20.3)
287
- thread_safe (0.3.6)
288
- timecop (0.9.1)
289
- twitter_cldr (4.4.5)
290
- camertron-eprun
291
- cldr-plurals-runtime-rb (~> 1.0)
292
- tzinfo
293
- tzinfo (2.0.0)
294
- concurrent-ruby (~> 1.0)
295
- tzinfo-data (1.2019.3)
296
- tzinfo (>= 1.0.0)
297
- unicode-display_width (1.6.0)
298
- unicode2latex (0.0.3)
299
- uuidtools (2.1.5)
300
- vcr (5.0.0)
301
- webmock (3.7.6)
302
- addressable (>= 2.3.6)
303
- crack (>= 0.3.2)
304
- hashdiff (>= 0.4.0, < 2.0.0)
305
-
306
- PLATFORMS
307
- ruby
308
-
309
- DEPENDENCIES
310
- bundler (~> 2.0.1)
311
- byebug (~> 9.1)
312
- equivalent-xml (~> 0.6)
313
- guard (~> 2.14)
314
- guard-rspec (~> 4.7)
315
- metanorma (~> 0.3.0)
316
- metanorma-cli
317
- metanorma-ietf!
318
- rake (~> 12.0)
319
- rspec (~> 3.6)
320
- rubocop (~> 0.50)
321
- simplecov (~> 0.15)
322
- timecop (~> 0.9)
323
- vcr (~> 5.0.0)
324
- webmock
325
-
326
- BUNDLED WITH
327
- 2.0.2
@@ -1,8 +0,0 @@
1
- module Asciidoctor
2
- module Rfc
3
-
4
- end
5
- end
6
-
7
- require_relative "rfc/v2/converter"
8
- require_relative "rfc/v3/converter"
@@ -1,544 +0,0 @@
1
- require "date"
2
- require "nokogiri"
3
- require "htmlentities"
4
- require "json"
5
- require "pathname"
6
- require "open-uri"
7
- require "set"
8
- require "fileutils"
9
-
10
- module Asciidoctor
11
- module Rfc::Common
12
- module Base
13
- def convert(node, transform = nil, opts = {})
14
- transform ||= node.node_name
15
- opts.empty? ? (send transform, node) : (send transform, node, opts)
16
- end
17
-
18
- def document_ns_attributes(_doc)
19
- # ' xmlns="http://projectmallard.org/1.0/" xmlns:its="http://www.w3.org/2005/11/its"'
20
- nil
21
- end
22
-
23
- def content(node)
24
- node.content
25
- end
26
-
27
- def skip(node, name = nil)
28
- warn %(asciidoctor: WARNING (#{current_location(node)}): converter missing for #{name || node.node_name} node in RFC backend)
29
- nil
30
- end
31
-
32
- # Syntax:
33
- # = Title
34
- # Author
35
- # :HEADER
36
- #
37
- # ABSTRACT
38
- #
39
- # NOTE: note
40
- #
41
- # @note (boilerplate is ignored)
42
- def preamble(node)
43
- result = []
44
-
45
- # NOTE: *list is V3, verse is V2, paragraph is both
46
- abstractable_contexts = %i{paragraph dlist olist ulist verse open}
47
-
48
- abstract_blocks = node.blocks.take_while do |block|
49
- abstractable_contexts.include? block.context
50
- end
51
-
52
- remainder_blocks = node.blocks[abstract_blocks.length..-1]
53
-
54
- result << noko do |xml|
55
- if abstract_blocks.any?
56
- xml.abstract do |xml_abstract|
57
- xml_abstract << abstract_blocks.map(&:render).flatten.join("\n")
58
- end
59
- end
60
- xml << remainder_blocks.map(&:render).flatten.join("\n")
61
- end
62
-
63
- result << "</front><middle>"
64
- result
65
- end
66
-
67
- IETF_AREAS = ["art", "Applications and Real-Time",
68
- "gen", "General",
69
- "int", "Internet",
70
- "ops", "Operations and Management",
71
- "rtg", "Routing",
72
- "sec", "Security",
73
- "tsv", "Transport"].freeze
74
-
75
- # Syntax:
76
- # = Title
77
- # Author
78
- # :area x, y
79
- def area(node, xml)
80
- node.attr("area")&.split(/, ?/)&.each do |ar|
81
- if ar =~ / Area$/i
82
- warn %(asciidoctor: WARNING (#{current_location(node)}): stripping suffix "Area" from area #{ar})
83
- ar = ar.gsub(/ Area$/i, "")
84
- end
85
- warn %(asciidoctor: WARNING (#{current_location(node)}): unrecognised area #{ar}) unless IETF_AREAS.include?(ar)
86
- xml.area { |a| a << ar }
87
- end
88
- end
89
-
90
- # Syntax:
91
- # = Title
92
- # Author
93
- # :workgroup x, y
94
- def workgroup(node, xml)
95
- workgroups = cache_workgroup(node)
96
- node.attr("workgroup")&.split(/, ?/)&.each do |wg|
97
- if wg =~ / (Working Group)$/i
98
- warn %(asciidoctor: WARNING (#{current_location(node)}): suffix "Working Group" will be stripped in published RFC from #{wg})
99
- wg_norm = wg.gsub(/ Working Group$/i, "")
100
- end
101
- if wg =~ / (Research Group)$/i
102
- warn %(asciidoctor: WARNING (#{current_location(node)}): suffix "Research Group" will be stripped from working group #{wg})
103
- wg_norm = wg.gsub(/ Research Group$/i, "")
104
- end
105
- warn %(asciidoctor: WARNING (#{current_location(node)}): unrecognised working group #{wg}) unless workgroups.include?(wg_norm)
106
- xml.workgroup { |w| w << wg }
107
- end
108
- end
109
-
110
- # Syntax:
111
- # = Title
112
- # Author
113
- # :keyword x, y
114
- def keyword(node, xml)
115
- node.attr("keyword")&.split(/, ?/)&.each do |kw|
116
- xml.keyword { |k| k << kw }
117
- end
118
- end
119
-
120
- def paragraph1(node)
121
- result = []
122
- result1 = node.content
123
- if result1 =~ /^(<t>|<dl>|<ol>|<ul>)/
124
- result = result1
125
- else
126
- t_attributes = {
127
- anchor: node.id,
128
- }
129
- result << noko { |xml| xml.t result1, **attr_code(t_attributes) }
130
- end
131
- result
132
- end
133
-
134
- def inline_indexterm(node)
135
- # supports only primary and secondary terms
136
- # primary attribute (highlighted major entry) not supported
137
- if node.type == :visible
138
- iref_attributes = {
139
- item: node.text,
140
- }
141
- node.text + noko { |xml| xml.iref **attr_code(iref_attributes) }.join
142
- else
143
- terms = node.attr "terms"
144
- warn %(asciidoctor: WARNING (#{current_location(node)}): only primary and secondary index terms supported: #{terms.join(': ')}) if terms.size > 2
145
- iref_attributes = {
146
- item: terms[0],
147
- subitem: (terms.size > 1 ? terms[1] : nil),
148
- }
149
- noko { |xml| xml.iref **attr_code(iref_attributes) }.join
150
- end
151
- end
152
-
153
- # ulist repurposed as reference list
154
- def reflist(node)
155
- # ++++
156
- # <xml>
157
- # ++++
158
- result = []
159
- if node.context == :pass
160
- node.lines.each do |item|
161
- # undo XML substitution
162
- ref = item.gsub(/\&lt;/, "<").gsub(/\&gt;/, ">")
163
- result << ref
164
- end
165
- else
166
- warn %(asciidoctor: WARNING (#{current_location(node)}): references are not raw XML: #{node.context})
167
- end
168
- result
169
- end
170
-
171
- def open(node)
172
- # open block is a container of multiple blocks, treated as a single block.
173
- # We append each contained block to its parent
174
- result = []
175
- if node.role == "comment"
176
- return noko do |xml|
177
- xml.comment " " + [flatten_rawtext(node).map { |x| [x, ""] } ].flatten.join("\n") + " "
178
- end
179
- end
180
-
181
- if node.blocks?
182
- node.blocks.each do |b|
183
- result << send(b.context, b)
184
- end
185
- else
186
- result = paragraph(node)
187
- end
188
- result
189
- end
190
-
191
- # def dash(camel_cased_word)
192
- # camel_cased_word.gsub(/([a-z])([A-Z])/, '\1-\2').downcase
193
- # end
194
-
195
- def common_rfc_pis(node)
196
- # Below are generally applicable Processing Instructions (PIs)
197
- # that most I-Ds might want to use, common to v2 and v3.
198
- # These are set only if explicitly specified, with the exception
199
- # of compact and subcompact
200
- rfc_pis = {
201
- artworkdelimiter: node.attr("artworkdelimiter"),
202
- artworklines: node.attr("artworklines"),
203
- authorship: node.attr("authorship"),
204
- autobreaks: node.attr("autobreaks"),
205
- background: node.attr("background"),
206
- colonspace: node.attr("colonspace"),
207
- comments: node.attr("comments"),
208
- docmapping: node.attr("docmapping"),
209
- editing: node.attr("editing"),
210
- emoticonic: node.attr("emoticonic"),
211
- footer: node.attr("footer"),
212
- header: node.attr("header"),
213
- inline: node.attr("inline"),
214
- iprnotified: node.attr("iprnotified"),
215
- linkmailto: node.attr("linkmailto"),
216
- linefile: node.attr("linefile"),
217
- notedraftinprogress: node.attr("notedraftinprogress"),
218
- private: node.attr("private"),
219
- refparent: node.attr("refparent"),
220
- rfcedstyle: node.attr("rfcedstyle"),
221
- slides: node.attr("slides"),
222
- "text-list-symbols": node.attr("text-list-symbols"),
223
- tocappendix: node.attr("tocappendix"),
224
- tocindent: node.attr("tocindent"),
225
- tocnarrow: node.attr("tocnarrow"),
226
- tocompact: node.attr("tocompact"),
227
- topblock: node.attr("topblock"),
228
- useobject: node.attr("useobject"),
229
-
230
- # give errors regarding ID-nits and DTD validation
231
- strict: node.attr("strict") || "yes",
232
-
233
- # Vertical whitespace control
234
- # (using these PIs as follows is recommended by the RFC Editor)
235
-
236
- # do not start each main section on a new page
237
- compact: node.attr("compact") || "yes",
238
- # keep one blank line between list items
239
- subcompact: node.attr("subcompact") || "no",
240
-
241
- # TOC control
242
- # generate a ToC
243
- toc: node.attr("toc-include") == "false" ? "no" : "yes",
244
-
245
- # the number of levels of subsections in ToC. default: 3
246
- tocdepth: node.attr("toc-depth") || "4",
247
-
248
- # use anchors rather than numbers for references
249
- symrefs: node.attr("sym-refs") || "yes",
250
- # sort references
251
- sortrefs: node.attr("sort-refs") || "yes",
252
- }
253
-
254
- attr_code(rfc_pis)
255
- end
256
-
257
- def set_pis(node, doc)
258
- # Below are generally applicable Processing Instructions (PIs)
259
- # that most I-Ds might want to use. (Here they are set differently than
260
- # their defaults in xml2rfc v1.32)
261
-
262
- if node.attr("rfc2629xslt") != "false"
263
- pi = Nokogiri::XML::ProcessingInstruction.new(doc, "xml-stylesheet",
264
- 'type="text/xsl" href="rfc2629.xslt"')
265
- doc.root.add_previous_sibling(pi)
266
- end
267
-
268
- doc.create_internal_subset("rfc", nil, Metanorma::Ietf::RFC2629DTD_URL)
269
- rfc_pis = common_rfc_pis(node)
270
- rfc_pis.each_pair do |k, v|
271
- pi = Nokogiri::XML::ProcessingInstruction.new(doc,
272
- "rfc",
273
- "#{k}=\"#{v}\"")
274
- doc.root.add_previous_sibling(pi)
275
- end
276
-
277
- doc
278
- end
279
-
280
- # extract references which can be expressed as externally defined entities
281
- def extract_entities(node, xmldoc)
282
- refs = xmldoc.xpath("//reference")
283
- ret = []
284
- biblio = cache_biblio(node)
285
- refs.each do |ref|
286
- next if ref.parent.name == "referencegroup"
287
- id = ref.at('.//seriesInfo[@name="Internet-Draft"]')
288
- anchor = ref["anchor"]
289
- url = if id.nil?
290
- biblio[anchor]
291
- else
292
- biblio["I-D.#{id['value']}"] # the specific version reference
293
- end
294
- if biblio.has_key? anchor
295
- ret << { entity: anchor,
296
- node: ref,
297
- url: url }
298
- end
299
- end
300
- ret
301
- end
302
-
303
- # if node contains blocks, flatten them into a single line
304
- def flatten(node)
305
- result = []
306
- result << node.text if node.respond_to?(:text)
307
- if node.blocks?
308
- node.blocks.each { |b| result << flatten(b) }
309
- else
310
- result << node.content
311
- end
312
- result.reject(&:empty?)
313
- end
314
-
315
- # if node contains blocks, flatten them into a single line; and extract only raw text
316
- def flatten_rawtext(node)
317
- result = []
318
- if node.respond_to?(:blocks) && node.blocks?
319
- node.blocks.each { |b| result << flatten_rawtext(b) }
320
- elsif node.respond_to?(:lines)
321
- node.lines.each do |x|
322
- result << if node.respond_to?(:context) && (node.context == :literal || node.context == :listing)
323
- x.gsub(/</, "&lt;").gsub(/>/, "&gt;")
324
- else
325
- # strip not only HTML tags <tag>, but also Asciidoc crossreferences <<xref>>
326
- x.gsub(/<[^>]*>+/, "")
327
- end
328
- end
329
- elsif node.respond_to?(:text)
330
- result << node.text.gsub(/<[^>]*>+/, "")
331
- else
332
- result << node.content.gsub(/<[^>]*>+/, "")
333
- end
334
- result.reject(&:empty?)
335
- end
336
-
337
- # block for processing XML document fragments as XHTML, to allow for HTMLentities
338
- def noko(&block)
339
- # fragment = ::Nokogiri::XML::DocumentFragment.parse("")
340
- # fragment.doc.create_internal_subset("xml", nil, "xhtml.dtd")
341
- head = <<HERE
342
- <!DOCTYPE html SYSTEM
343
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
344
- <html xmlns="http://www.w3.org/1999/xhtml">
345
- <head>
346
- <title></title>
347
- <meta charset="UTF-8" />
348
- </head>
349
- <body>
350
- </body>
351
- </html>
352
- HERE
353
- doc = ::Nokogiri::XML.parse(head)
354
- fragment = doc.fragment("")
355
- ::Nokogiri::XML::Builder.with fragment, &block
356
- fragment.to_xml(encoding: "US-ASCII").lines.map { |l| l.gsub(/\s*\n/, "") }
357
- end
358
-
359
- def attr_code(attributes)
360
- attributes = attributes.reject { |_, val| val.nil? }.map
361
- attributes.map do |k, v|
362
- [k, (v.is_a? String) ? HTMLEntities.new.decode(v) : v]
363
- end.to_h
364
- end
365
-
366
- def current_location(node)
367
- return "Line #{node.lineno}" if node.respond_to?(:lineno) && !node.lineno.nil? && !node.lineno.empty?
368
- return "ID #{node.id}" if node.respond_to?(:id) && !node.id.nil?
369
- while !node.nil? && (!node.respond_to?(:level) || node.level > 0) && node.context != :section
370
- node = node.parent
371
- return "Section: #{node.title}" if !node.nil? && node.context == :section
372
- end
373
- "??"
374
- end
375
-
376
- def cache_workgroup(node)
377
- wgcache_name = "#{Dir.home}/.metanorma-ietf-workgroup-cache.json"
378
- # If we are required to, clear the wg cache
379
- if node.attr("flush-caches") == "true"
380
- FileUtils.rm wgcache_name, :force => true
381
- end
382
- # Is there already a wg cache? If not, create it.
383
- wg = []
384
-
385
- if Pathname.new(wgcache_name).file?
386
- begin
387
- File.open(wgcache_name, "r") do |f|
388
- wg = JSON.parse(f.read)
389
- end
390
- rescue Exception => e
391
- STDERR.puts "Cache #{wgcache_name} is invalid, drop it"
392
- end
393
- end
394
-
395
- if wg.empty?
396
- File.open(wgcache_name, "w") do |b|
397
- STDERR.puts "Reading workgroups from https://tools.ietf.org/wg/..."
398
- Kernel.open("https://tools.ietf.org/wg/") do |f|
399
- f.each_line do |line|
400
- line.scan(%r{<td width="50%" style='padding: 0 1ex'>([^<]+)</td>}) do |w|
401
- wg << w[0].gsub(/\s+$/, "").gsub(/ Working Group$/, "")
402
- end
403
- end
404
- end
405
- STDERR.puts "Reading workgroups from https://irtf.org/groups..."
406
- Kernel.open("https://irtf.org/groups", ssl_verify_mode: OpenSSL::SSL::VERIFY_NONE) do |f|
407
- f.each_line do |line|
408
- line.scan(%r{<a title="([^"]+) Research Group"[^>]+>([^<]+)<}) do |w|
409
- wg << w[0].gsub(/\s+$/, "")
410
- wg << w[1].gsub(/\s+$/, "") # abbrev
411
- end
412
- end
413
- end
414
- b << wg.to_json
415
- end
416
- end
417
- wg
418
- end
419
-
420
- def cache_biblio(node)
421
- bibliocache_name = "#{Dir.home}/.metanorma-ietf-biblio-cache.json"
422
- # If we are required to, clear the biblio cache
423
- if node.attr("flush-caches") == "true"
424
- system("rm -f #{bibliocache_name}")
425
- end
426
- # Is there already a biblio cache? If not, create it.
427
- biblio = {}
428
- if Pathname.new(bibliocache_name).file?
429
- begin
430
- File.open(bibliocache_name, "r") do |f|
431
- biblio = JSON.parse(f.read)
432
- end
433
- rescue Exception => e
434
- warn "JSON in #{bibliocache_name} is corrupt: deleting"
435
- end
436
- end
437
-
438
- if biblio.empty?
439
- File.open(bibliocache_name, "w") do |b|
440
- STDERR.puts "Reading references from https://xml2rfc.tools.ietf.org/public/rfc/bibxml/..."
441
- Kernel.open("https://xml2rfc.tools.ietf.org/public/rfc/bibxml/") do |f|
442
- # I'm just working off the ls output
443
- f.each_line do |line|
444
- line.scan(/a href="reference.RFC.(\d+).xml">/) do |w|
445
- biblio["RFC#{w[0]}"] = "https://xml2rfc.tools.ietf.org/public/rfc/bibxml/reference.RFC.#{w[0]}.xml"
446
- end
447
- end
448
- ["https://xml2rfc.tools.ietf.org/public/rfc/bibxml2/",
449
- "https://xml2rfc.tools.ietf.org/public/rfc/bibxml3/",
450
- "https://xml2rfc.tools.ietf.org/public/rfc/bibxml4/",
451
- "https://xml2rfc.tools.ietf.org/public/rfc/bibxml5/"].each do |url|
452
- STDERR.puts "Reading references from #{url}..."
453
- Kernel.open(url) do |f1|
454
- f1.each_line do |line|
455
- line.scan(/a href="reference.(\S+).xml">/) do |w|
456
- biblio[w[0]] = "#{url}/reference.#{w[0]}.xml"
457
- end
458
- end
459
- end
460
- end
461
- end
462
- b << biblio.to_json
463
- end
464
- end
465
- biblio
466
- end
467
-
468
- # insert bibliography based on anchors, references directory, and list of normatives in doc attribute
469
- def insert_biblio(node, xmldoc)
470
- # we want no references in this document, so we can ignore any anchors of references
471
- xmldoc.xpath("//referencegroup | //reference").each(&:remove)
472
- refs = Set.new
473
- xmldoc.xpath("//xref | //relref").each { |r| refs << r["target"] }
474
- anchors1 = Set.new
475
- # we have no references in this document, so any remaining anchors are internal cross-refs only
476
- xmldoc.xpath("//@anchor").each { |r| anchors1 << r.value }
477
- refs = refs - anchors1
478
- anchors = {}
479
-
480
- norm_refs_spec = Set.new(node.attr("normative").split(/,[ ]?/))
481
- anchors[:norm] = refs.intersection(norm_refs_spec)
482
- anchors[:info] = refs - anchors[:norm]
483
- seen_refs = { norm: Set.new, info: Set.new }
484
- refxml_in = { norm: {}, info: {} }
485
- refxml_out = { norm: [], info: [] }
486
-
487
- bibliodir = node.attr("biblio-dir")
488
- Dir.foreach bibliodir do |f|
489
- next if [".", ".."].include? f
490
- text = File.read("#{bibliodir}/#{f}", encoding: "utf-8")
491
- next unless text =~ /<reference/
492
- text =~ /<reference[^>]*anchor=['"]([^'"]*)/
493
- anchor = Regexp.last_match(1)
494
- next if anchor.nil? || anchor.empty?
495
- if anchors[:norm].include?(anchor)
496
- refxml_in[:norm][anchor] = text
497
- seen_refs[:norm] << anchor
498
- else
499
- refxml_in[:info][anchor] = text
500
- seen_refs[:info] << anchor
501
- end
502
- end
503
-
504
- biblio = cache_biblio(node)
505
- [:norm, :info].each do |reftype|
506
- anchors[reftype].each do |r|
507
- if refxml_in[reftype].has_key?(r)
508
- # priority to on-disk references over skeleton references: they may contain draft information
509
- refxml_out[reftype] << refxml_in[reftype][r]
510
- elsif biblio.has_key?(r)
511
- refxml_out[reftype] << %{<reference anchor="#{r}"/>}
512
- else
513
- warn "Reference #{r} has not been includes in references directory, and is not a recognised external RFC reference"
514
- end
515
- end
516
- end
517
-
518
- xml_location = xmldoc.at('//references[@title="Normative References" or name="Normative References"]')
519
- xml_location&.children = Nokogiri::XML.fragment(refxml_out[:norm].join)
520
- xml_location = xmldoc.at('//references[@title="Informative References" or name="Informative References"]')
521
- xml_location&.children = Nokogiri::XML.fragment(refxml_out[:info].join)
522
- xmldoc
523
- end
524
-
525
- def smart_quote_cleanup(xmldoc)
526
- # smart quotes: handle smart apostrophe
527
- xmldoc.traverse do |node|
528
- if node.text?
529
- node.content = node.content.tr("\u2019", "'")
530
- node.content = node.content.gsub(/\&#8217;/, "'")
531
- node.content = node.content.gsub(/\&#x2019;/, "'")
532
- elsif node.element?
533
- node.attributes.each do |k, v|
534
- node.set_attribute(k, v.content.tr("\u2019", "'"))
535
- node.set_attribute(k, v.content.gsub(/\&#8217;/, "'"))
536
- node.set_attribute(k, v.content.gsub(/\&#x2019;/, "'"))
537
- end
538
- end
539
- end
540
- xmldoc
541
- end
542
- end
543
- end
544
- end