metanorma-ietf 1.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 +7 -0
  2. data/.gitignore +18 -0
  3. data/.hound.yml +3 -0
  4. data/.oss-guides.rubocop.yml +1077 -0
  5. data/.rspec +2 -0
  6. data/.rubocop.ribose.yml +65 -0
  7. data/.rubocop.tb.yml +650 -0
  8. data/.rubocop.yml +15 -0
  9. data/.travis.yml +23 -0
  10. data/CODE_OF_CONDUCT.md +74 -0
  11. data/Gemfile +4 -0
  12. data/Guardfile +22 -0
  13. data/LICENSE +25 -0
  14. data/README.adoc +1660 -0
  15. data/Rakefile +6 -0
  16. data/bin/asciidoctor-rfc2 +14 -0
  17. data/bin/asciidoctor-rfc3 +14 -0
  18. data/bin/console +14 -0
  19. data/bin/rspec +17 -0
  20. data/bin/setup +8 -0
  21. data/docs/installation.md +21 -0
  22. data/docs/navigation.md +10 -0
  23. data/docs/overview.md +5 -0
  24. data/lib/asciidoctor/rfc.rb +8 -0
  25. data/lib/asciidoctor/rfc/common/base.rb +531 -0
  26. data/lib/asciidoctor/rfc/common/front.rb +120 -0
  27. data/lib/asciidoctor/rfc/v2/base.rb +379 -0
  28. data/lib/asciidoctor/rfc/v2/blocks.rb +261 -0
  29. data/lib/asciidoctor/rfc/v2/converter.rb +60 -0
  30. data/lib/asciidoctor/rfc/v2/front.rb +69 -0
  31. data/lib/asciidoctor/rfc/v2/inline_anchor.rb +111 -0
  32. data/lib/asciidoctor/rfc/v2/lists.rb +135 -0
  33. data/lib/asciidoctor/rfc/v2/table.rb +114 -0
  34. data/lib/asciidoctor/rfc/v2/validate.rb +32 -0
  35. data/lib/asciidoctor/rfc/v2/validate2.rng +716 -0
  36. data/lib/asciidoctor/rfc/v3/base.rb +329 -0
  37. data/lib/asciidoctor/rfc/v3/blocks.rb +246 -0
  38. data/lib/asciidoctor/rfc/v3/converter.rb +62 -0
  39. data/lib/asciidoctor/rfc/v3/front.rb +122 -0
  40. data/lib/asciidoctor/rfc/v3/inline_anchor.rb +89 -0
  41. data/lib/asciidoctor/rfc/v3/lists.rb +176 -0
  42. data/lib/asciidoctor/rfc/v3/svg.rng +9081 -0
  43. data/lib/asciidoctor/rfc/v3/table.rb +65 -0
  44. data/lib/asciidoctor/rfc/v3/validate.rb +34 -0
  45. data/lib/asciidoctor/rfc/v3/validate.rng +2143 -0
  46. data/lib/metanorma-ietf.rb +7 -0
  47. data/lib/metanorma/ietf.rb +8 -0
  48. data/lib/metanorma/ietf/processor.rb +89 -0
  49. data/lib/metanorma/ietf/version.rb +5 -0
  50. data/metanorma-ietf.gemspec +51 -0
  51. data/rfc2629-other.ent +61 -0
  52. data/rfc2629-xhtml.ent +165 -0
  53. data/rfc2629.dtd +312 -0
  54. metadata +289 -0
@@ -0,0 +1,329 @@
1
+ # coding: utf-8
2
+
3
+ module Asciidoctor
4
+ module Rfc::V3
5
+ module Base
6
+ # Syntax:
7
+ # =Title
8
+ # Author
9
+ # :ipr
10
+ # :obsoletes
11
+ # :updates
12
+ # :submissionType
13
+ # :indexInclude
14
+ # :iprExtract
15
+ # :sortRefs
16
+ # :symRefs
17
+ # :tocInclude
18
+ # :tocDepth
19
+ #
20
+ # ABSTRACT
21
+ #
22
+ # NOTEs
23
+ #
24
+ # ==first title
25
+ # CONTENT
26
+ #
27
+ # [bibliography] # start of back matter
28
+ # == Bibliography
29
+ #
30
+ # [appendix] # start of back matter if not already started
31
+ # == Appendix
32
+ def document(node)
33
+ $seen_back_matter = false
34
+ # If this is present, then BCP14 keywords in boldface are not assumed to be <bcp14> tags. By default they are.
35
+ $bcp_bold = !(node.attr? "no-rfc-bold-bcp14")
36
+ $smart_quotes = (node.attr("smart-quotes") != "false")
37
+ $xreftext = {}
38
+ result = []
39
+ result << '<?xml version="1.0" encoding="UTF-8"?>'
40
+
41
+ t = Time.now.getutc
42
+ preptime = sprintf(
43
+ "%04d-%02d-%02dT%02d:%02d:%02dZ",
44
+ t.year, t.month, t.day, t.hour, t.min, t.sec
45
+ )
46
+
47
+ rfc_attributes = {
48
+ ipr: node.attr("ipr"),
49
+ obsoletes: node.attr("obsoletes"),
50
+ updates: node.attr("updates"),
51
+ indexInclude: node.attr("index-include"),
52
+ iprExtract: node.attr("ipr-extract"),
53
+ sortRefs: node.attr("sort-refs"),
54
+ symRefs: node.attr("sym-refs"),
55
+ tocInclude: node.attr("toc-include"),
56
+ tocDepth: node.attr("toc-depth"),
57
+ submissionType: node.attr("submission-type") || "IETF",
58
+ 'xml:lang': node.attr("xml-lang"),
59
+ prepTime: preptime,
60
+ version: "3",
61
+ 'xmlns:xi': "http://www.w3.org/2001/XInclude",
62
+ }
63
+
64
+ rfc_open = noko { |xml| xml.rfc **attr_code(rfc_attributes) }.join.gsub(/\/>$/, ">")
65
+ result << rfc_open
66
+
67
+ result << (link node)
68
+
69
+ result << noko { |xml| front node, xml }
70
+ result.last.last.gsub! /<\/front>$/, "" # FIXME: this is a hack!
71
+ result << "</front><middle1>"
72
+
73
+ result << node.content if node.blocks?
74
+ result << ($seen_back_matter ? "</back>" : "</middle>")
75
+ result << "</rfc>"
76
+
77
+ # <middle> needs to move after preamble
78
+ result = result.flatten
79
+ result = if result.any? { |e| e =~ /<\/front><middle>/ } && result.any? { |e| e =~ /<\/front><middle1>/ }
80
+ result.reject { |e| e =~ /<\/front><middle1>/ }
81
+ else
82
+ result.map { |e| e =~ /<\/front><middle1>/ ? "</front><middle>" : e }
83
+ end
84
+ ret = result * "\n"
85
+ ret = cleanup(ret)
86
+ ret1 = Nokogiri::XML(ret)
87
+ ret1 = set_pis(node, ret1)
88
+ ret1 = insert_biblio(node, ret1) unless node.attr("biblio-dir").nil? || node.attr("biblio-dir").empty?
89
+ Validate::validate(ret1)
90
+ ret1 = resolve_references(node, ret1)
91
+ # Validate::validate(ret1)
92
+ ret1.to_xml
93
+ end
94
+
95
+ def resolve_references(node, doc)
96
+ extract_entities(node, doc).each do |entity|
97
+ # TODO actual XML
98
+ entity[:node].replace("<xi:include href='#{entity[:url]}' parse='text'/>")
99
+ end
100
+ doc
101
+ end
102
+
103
+ # Syntax:
104
+ # = Title
105
+ # Author
106
+ # :link href,href rel
107
+ def link(node)
108
+ result = []
109
+ result << noko do |xml|
110
+ links = (node.attr("link") || "").split(/,\s*/)
111
+ links.each do |link|
112
+ matched = /^(?<href>\S+)\s+(?<rel>\S+)$/.match link
113
+ link_attributes = {
114
+ href: matched.nil? ? link : matched[:href],
115
+ rel: matched.nil? ? nil : matched[:rel],
116
+ }
117
+ xml.link **attr_code(link_attributes)
118
+ end
119
+ end
120
+ result
121
+ end
122
+
123
+ def inline_break(node)
124
+ # <br> is only defined within tables
125
+ noko do |xml|
126
+ xml << node.text
127
+ xml.br if node.parent.context == :cell
128
+ end.join
129
+ end
130
+
131
+ BCP_KEYWORDS = [
132
+ "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
133
+ "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", "OPTIONAL"
134
+ ].freeze
135
+
136
+ def inline_quoted(node)
137
+ noko do |xml|
138
+ case node.type
139
+ when :emphasis then xml.em node.text
140
+ when :strong
141
+ if $bcp_bold && BCP_KEYWORDS.include?(node.text)
142
+ xml.bcp14 node.text
143
+ else
144
+ xml.strong node.text
145
+ end
146
+ when :monospaced then xml.tt node.text
147
+ when :double
148
+ xml << ($smart_quotes ? "“#{node.text}”" : "\"#{node.text}\"")
149
+ when :single
150
+ xml << ($smart_quotes ? "‘#{node.text}’" : "'#{node.text}'")
151
+ when :superscript then xml.sup node.text
152
+ when :subscript then xml.sub node.text
153
+ else
154
+ # [bcp14]#MUST NOT#
155
+ if node.role == "bcp14"
156
+ xml.bcp14 node.text.upcase
157
+ elsif node.role == "comment"
158
+ xml.comment " " + node.text + " "
159
+ else
160
+ xml << node.text
161
+ end
162
+ end
163
+ end.join
164
+ end
165
+
166
+ # Syntax:
167
+ # [[id]]
168
+ # [keepWithNext=true,keepWithPrevious=true] (optional)
169
+ # Text
170
+ def paragraph(node)
171
+ if node.role == "comment"
172
+ return noko do |xml|
173
+ xml.comment " " + [flatten_rawtext(node)].flatten.join("\n") + " "
174
+ end.join("\n")
175
+ end
176
+
177
+ t_attributes = {
178
+ anchor: node.id,
179
+ keepWithNext: node.attr("keep-with-next"),
180
+ keepWithPrevious: node.attr("keep-with-previous"),
181
+ }
182
+ return noko do |xml|
183
+ xml.t **attr_code(t_attributes) do |xml_t|
184
+ xml_t << node.content
185
+ end
186
+ end.join("\n")
187
+ end
188
+
189
+ def ref_section(node)
190
+ result = []
191
+ $processing_reflist = true
192
+ references_attributes = {
193
+ anchor: node.id,
194
+ }
195
+
196
+ if node.blocks.empty?
197
+ result << noko do |xml|
198
+ xml.references **references_attributes do |xml_references|
199
+ xml_references.name node.title unless node.title.nil?
200
+ end
201
+ end
202
+ end
203
+ node.blocks.each do |block|
204
+ if block.context == :section
205
+ result << section(block)
206
+ elsif block.context == :pass
207
+ # we are assuming a single contiguous :pass block of XML
208
+ result << noko do |xml|
209
+ xml.references **references_attributes do |xml_references|
210
+ xml_references.name node.title unless node.title.nil?
211
+ # xml_references << reflist(block).join("\n")
212
+ # NOTE: we're allowing the user to do more or less whathever
213
+ # in the passthrough since the xpath below just fishes out ALL
214
+ # <reference>s in an unrooted fragment, regardless of structure.
215
+ Nokogiri::XML::DocumentFragment.
216
+ parse(block.content).xpath(".//reference").
217
+ each { |reference| xml_references << reference.to_xml }
218
+ end
219
+ end
220
+ elsif block.context == :ulist
221
+ block.items.each(&:text)
222
+ # we only process the item for its displayreferences
223
+ end
224
+ end
225
+
226
+ unless $xreftext.empty? || $seen_back_matter
227
+ result = result.unshift($xreftext.keys.map { |k| %(<displayreference target="#{k}" to="#{$xreftext[k]}"/>) })
228
+ end
229
+ result = result.unshift("</middle><back>") unless $seen_back_matter
230
+ $processing_reflist = false
231
+ $seen_back_matter = true
232
+ result
233
+ end
234
+
235
+ # Syntax:
236
+ # :sectnums: (toggle)
237
+ # :sectnums!: (toggle)
238
+ # [[id]]
239
+ # [removeInRFC=true,toc=include|exclude|default] (optional)
240
+ # == title
241
+ # Content
242
+ #
243
+ # [[id]]
244
+ # [bibliography]
245
+ # == Normative|Informative References
246
+ # * [[[ref1]]] Ref [must provide references as list]
247
+ # * [[[ref2]]] Ref
248
+ def section(node)
249
+ if node.attr("style") == "bibliography" ||
250
+ node.parent.context == :section && node.parent.attr("style") == "bibliography"
251
+ result = ref_section(node)
252
+ else
253
+ result = []
254
+ if node.attr("style") == "appendix"
255
+ result << "</middle><back>" unless $seen_back_matter
256
+ $seen_back_matter = true
257
+ end
258
+
259
+ section_attributes = {
260
+ anchor: node.id,
261
+ removeInRFC: node.attr("remove-in-rfc"),
262
+ toc: node.attr("toc"),
263
+ numbered: node.attr?("sectnums"),
264
+ }
265
+
266
+ result << noko do |xml|
267
+ xml.section **attr_code(section_attributes) do |section_xml|
268
+ section_xml.name { |name| name << node.title } unless node.title.nil?
269
+ section_xml << node.content
270
+ end
271
+ end
272
+ end
273
+ result
274
+ end
275
+
276
+ # Syntax:
277
+ # [[id]]
278
+ # .Name
279
+ # [link=xxx,align=left|center|right,alt=alt_text,type]
280
+ # image::filename[alt,width,height]
281
+ # @note ignoring width, height attributes
282
+ def image(node)
283
+ uri = node.image_uri node.attr("target")
284
+ artwork_attributes = {
285
+ align: node.attr("align"),
286
+ alt: node.alt,
287
+ anchor: node.id,
288
+ height: node.attr("height"),
289
+ name: node.title,
290
+ src: uri,
291
+ type: (uri =~ /\.svg$/ ? "svg" : "binary-art"),
292
+ width: node.attr("width"),
293
+ }
294
+
295
+ noko do |xml|
296
+ if node.parent.context != :example
297
+ xml.figure do |xml_figure|
298
+ xml_figure.artwork **attr_code(artwork_attributes)
299
+ end
300
+ else
301
+ xml.artwork **attr_code(artwork_attributes)
302
+ end
303
+ end
304
+ end
305
+
306
+ # clean up XML
307
+ def cleanup(doc)
308
+ xmldoc = Nokogiri::XML(doc)
309
+ crefs = xmldoc.xpath("//cref")
310
+ # any crefs that are direct children of section should become children of the preceding
311
+ # paragraph, if it exists; otherwise, they need to be wrapped in a paragraph
312
+ crefs.each do |cref|
313
+ if cref.parent.name == "section"
314
+ prev = cref.previous_element
315
+ if !prev.nil? && prev.name == "t"
316
+ cref.parent = prev
317
+ else
318
+ t = Nokogiri::XML::Element.new("t", xmldoc)
319
+ cref.before(t)
320
+ cref.parent = t
321
+ end
322
+ end
323
+ end
324
+ xmldoc = smart_quote_cleanup(xmldoc) unless $smart_quotes
325
+ xmldoc.to_xml(encoding: "US-ASCII")
326
+ end
327
+ end
328
+ end
329
+ end
@@ -0,0 +1,246 @@
1
+ require "htmlentities"
2
+ require "uri"
3
+
4
+ module Asciidoctor
5
+ module Rfc::V3
6
+ module Blocks
7
+ # Syntax:
8
+ # [discrete]
9
+ # == Section
10
+ def floating_title(node)
11
+ noko do |xml|
12
+ xml.t { |xml_t| xml_t.strong node.title }
13
+ end
14
+ end
15
+
16
+ # Syntax:
17
+ # [[id]]
18
+ # .name
19
+ # [align=left|center|right,alt=alt_text] (optional)
20
+ # ....
21
+ # literal
22
+ # ....
23
+ def literal(node)
24
+ artwork_attributes = {
25
+ anchor: node.id,
26
+ align: node.attr("align"),
27
+ type: "ascii-art",
28
+ name: node.title,
29
+ alt: node.attr("alt"),
30
+ }
31
+
32
+ # NOTE: html escaping is performed by Nokogiri
33
+ artwork_content = "\n" + node.lines.join("\n") + "\n"
34
+
35
+ noko do |xml|
36
+ if node.parent.context != :example
37
+ xml.figure do |xml_figure|
38
+ # xml_figure.artwork artwork_content, **attr_code(artwork_attributes)
39
+ xml_figure.artwork **attr_code(artwork_attributes) do |a|
40
+ a.cdata artwork_content
41
+ end
42
+ end
43
+ else
44
+ # xml.artwork artwork_content, **attr_code(artwork_attributes)
45
+ xml.artwork **attr_code(artwork_attributes) do |a|
46
+ a.cdata artwork_content
47
+ end
48
+ end
49
+ end
50
+ end
51
+
52
+ # stem is treated as literal, but with center alignment
53
+ def stem(node)
54
+ artwork_attributes = {
55
+ anchor: node.id,
56
+ align: node.attr("align") || "center",
57
+ type: "ascii-art",
58
+ name: node.title,
59
+ alt: node.attr("alt"),
60
+ }
61
+
62
+ # NOTE: html escaping is performed by Nokogiri
63
+ artwork_content = "\n" + node.lines.join("\n") + "\n"
64
+
65
+ noko do |xml|
66
+ if node.parent.context != :example
67
+ xml.figure do |xml_figure|
68
+ # xml_figure.artwork artwork_content, **attr_code(artwork_attributes)
69
+ xml_figure.artwork **attr_code(artwork_attributes) do |a|
70
+ a.cdata artwork_content
71
+ end
72
+ end
73
+ else
74
+ # xml.artwork artwork_content, **attr_code(artwork_attributes)
75
+ xml.artwork **attr_code(artwork_attributes) do |a|
76
+ a.cdata artwork_content
77
+ end
78
+ end
79
+ end
80
+ end
81
+
82
+ # Syntax:
83
+ # [[id]]
84
+ # [quote, attribution, citation info] # citation info limited to URL
85
+ # Text
86
+ def quote(node)
87
+ cite_value = node.attr("citetitle")
88
+ cite_value = nil unless cite_value.to_s =~ URI::DEFAULT_PARSER.make_regexp
89
+
90
+ blockquote_attributes = {
91
+ anchor: node.id,
92
+ quotedFrom: node.attr("attribution"),
93
+ cite: cite_value,
94
+ }
95
+
96
+ noko do |xml|
97
+ xml.blockquote **attr_code(blockquote_attributes) do |xml_blockquote|
98
+ xml_blockquote << node.content
99
+ end
100
+ end
101
+ end
102
+
103
+ # realise as quote() ; <br/> in v3 does not have the applicability of <vspace/>,
104
+ # it is restricted to tables
105
+ def verse(node)
106
+ quote(node)
107
+ end
108
+
109
+ # Syntax:
110
+ # = Title
111
+ # Author
112
+ # :HEADER
113
+ #
114
+ # ABSTRACT
115
+ #
116
+ # NOTE: note
117
+ #
118
+ # [NOTE]
119
+ # .Title (in preamble)
120
+ # ====
121
+ # Content
122
+ # ====
123
+ #
124
+ # [NOTE,removeInRFC=true] (in preamble)
125
+ # [NOTE,display=true|false,source=name] (in body)
126
+ # .Title
127
+ # ====
128
+ # Content
129
+ # ====
130
+ # @note admonitions within preamble are notes. Elsewhere, they are comments.
131
+ def admonition(node)
132
+ result = []
133
+ if node.parent.context == :preamble
134
+ note_attributes = {
135
+ removeInRFC: node.attr("remove-in-rfc"),
136
+ }
137
+
138
+ result << noko do |xml|
139
+ xml.note **attr_code(note_attributes) do |xml_note|
140
+ xml_note.name node.title unless node.title.nil?
141
+ xml_note << HTMLEntities.new.decode([paragraph1(node)].flatten.join("\n"))
142
+ end
143
+ end
144
+ else
145
+ cref_attributes = {
146
+ anchor: node.id,
147
+ display: node.attr("display"),
148
+ source: node.attr("source"),
149
+ }
150
+
151
+ cref_contents = node.blocks? ? flatten(node) : node.content
152
+ cref_contents = [cref_contents].flatten.join("\n")
153
+ warn <<~WARNING_MESSAGE if node.blocks?
154
+ asciidoctor: WARNING (#{current_location(node)}): comment can not contain blocks of text in XML RFC:\n #{node.content}
155
+ WARNING_MESSAGE
156
+
157
+ result << noko do |xml|
158
+ xml.cref **attr_code(cref_attributes) do |xml_cref|
159
+ xml_cref << cref_contents
160
+ end
161
+ end
162
+ end
163
+ result
164
+ end
165
+
166
+ # Syntax:
167
+ # [[id]]
168
+ # ****
169
+ # Sidebar
170
+ # ****
171
+ def sidebar(node)
172
+ aside_attributes = {
173
+ anchor: node.id,
174
+ }
175
+ noko do |xml|
176
+ xml.aside **attr_code(aside_attributes) do |xml_aside|
177
+ xml_aside << node.content
178
+ end
179
+ end
180
+ end
181
+
182
+ # Syntax:
183
+ # .Title
184
+ # ====
185
+ # Example
186
+ # ====
187
+ def example(node)
188
+ node.blocks.each do |b|
189
+ unless %i{listing image literal stem}.include? b.context
190
+ warn "asciidoctor: WARNING (#{current_location(b)}): examples (figures) should only contain listings (sourcecode), images (artwork), or literal (artwork):\n#{b.lines}"
191
+ end
192
+ end
193
+
194
+ figure_attributes = {
195
+ anchor: node.id,
196
+ }
197
+
198
+ noko do |xml|
199
+ xml.figure **attr_code(figure_attributes) do |xml_figure|
200
+ xml_figure.name node.title if node.title?
201
+ # TODO iref
202
+ xml_figure << node.content
203
+ end
204
+ end
205
+ end
206
+
207
+ # Syntax:
208
+ # .name
209
+ # [source,type,src=uri] (src is mutually exclusive with listing content) (v3)
210
+ # [source,type,src=uri,align,alt] (src is mutually exclusive with listing content) (v2)
211
+ # ----
212
+ # code
213
+ # ----
214
+ def listing(node)
215
+ sourcecode_attributes = {
216
+ anchor: node.id,
217
+ align: nil,
218
+ alt: nil,
219
+ name: node.title,
220
+ type: node.attr("language"),
221
+ src: node.attr("src"),
222
+ }
223
+
224
+ # NOTE: html escaping is performed by Nokogiri
225
+ sourcecode_content =
226
+ sourcecode_attributes[:src].nil? ? "\n" + node.lines.join("\n") + "\n" : ""
227
+
228
+ noko do |xml|
229
+ if node.parent.context != :example
230
+ xml.figure do |xml_figure|
231
+ # xml_figure.sourcecode sourcecode_content, **attr_code(sourcecode_attributes)
232
+ xml_figure.sourcecode **attr_code(sourcecode_attributes) do |a|
233
+ a.cdata sourcecode_content
234
+ end
235
+ end
236
+ else
237
+ # xml.sourcecode sourcecode_content, **attr_code(sourcecode_attributes)
238
+ xml.sourcecode **attr_code(sourcecode_attributes) do |a|
239
+ a.cdata sourcecode_content
240
+ end
241
+ end
242
+ end
243
+ end
244
+ end
245
+ end
246
+ end