metanorma-ietf 1.0.10 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
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