metanorma-ietf 1.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 +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