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,261 @@
1
+ require "htmlentities"
2
+
3
+ module Asciidoctor
4
+ module Rfc::V2
5
+ module Blocks
6
+ # Syntax:
7
+ # [discrete]
8
+ # == Section
9
+ def floating_title(node)
10
+ noko do |xml|
11
+ xml.t do |xml_t|
12
+ xml_t.spanx node.title, style: "strong"
13
+ end
14
+ end
15
+ end
16
+
17
+ # Syntax:
18
+ # [[id]]
19
+ # .Name
20
+ # [align=left|center|right,alt=alt_text,type] (optional)
21
+ # ....
22
+ # literal
23
+ # ....
24
+ def literal(node)
25
+ artwork_attributes = {
26
+ align: node.attr("align"),
27
+ type: node.attr("type"),
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
+ ret = noko do |xml|
36
+ if node.parent.context != :example
37
+ figure_attributes = {
38
+ anchor: node.id,
39
+ }
40
+ xml.figure **attr_code(figure_attributes) do |xml_figure|
41
+ # xml_figure.artwork artwork_content, **attr_code(artwork_attributes)
42
+ xml_figure.artwork **attr_code(artwork_attributes) do |a|
43
+ a.cdata artwork_content
44
+ end
45
+ end
46
+ else
47
+ # xml.artwork artwork_content, **attr_code(artwork_attributes)
48
+ xml.artwork **attr_code(artwork_attributes) do |a|
49
+ a.cdata artwork_content
50
+ end
51
+ end
52
+ end
53
+ ret
54
+ end
55
+
56
+ # stem is treated as literal, but with center alignment
57
+ def stem(node)
58
+ artwork_attributes = {
59
+ align: node.attr("align") || "center",
60
+ type: node.attr("type"),
61
+ name: node.title,
62
+ alt: node.attr("alt"),
63
+ }
64
+
65
+ # NOTE: html escaping is performed by Nokogiri
66
+ artwork_content = "\n" + node.lines.join("\n") + "\n"
67
+
68
+ ret = noko do |xml|
69
+ if node.parent.context != :example
70
+ figure_attributes = {
71
+ anchor: node.id,
72
+ }
73
+ xml.figure **attr_code(figure_attributes) do |xml_figure|
74
+ # xml_figure.artwork artwork_content, **attr_code(artwork_attributes)
75
+ xml_figure.artwork **attr_code(artwork_attributes) do |a|
76
+ a.cdata artwork_content
77
+ end
78
+ end
79
+ else
80
+ # xml.artwork artwork_content, **attr_code(artwork_attributes)
81
+ xml.artwork **attr_code(artwork_attributes) do |a|
82
+ a.cdata artwork_content
83
+ end
84
+ end
85
+ end
86
+ ret
87
+ end
88
+
89
+ # Syntax:
90
+ # = Title
91
+ # Author
92
+ # :HEADER
93
+ #
94
+ # ABSTRACT
95
+ #
96
+ # NOTE: note
97
+ #
98
+ # [NOTE]
99
+ # .Title (in preamble)
100
+ # ====
101
+ # Content
102
+ # ====
103
+ #
104
+ # [NOTE] (in preamble)
105
+ # [NOTE,source=name] (in body)
106
+ # .Title
107
+ # ====
108
+ # Content
109
+ # ====
110
+ #
111
+ # @note admonitions within preamble are notes. Elsewhere, they are comments.
112
+ def admonition(node)
113
+ result = []
114
+ if node.parent.context == :preamble
115
+ note_attributes = {
116
+ # default title provided: title is mandatory
117
+ title: (node.title.nil? ? "NOTE" : node.title),
118
+ }
119
+
120
+ note_contents = HTMLEntities.new.decode([paragraph1(node)].flatten.join("\n"))
121
+
122
+ result << noko do |xml|
123
+ xml.note **attr_code(note_attributes) do |xml_note|
124
+ xml_note << note_contents
125
+ end
126
+ end
127
+ else
128
+ cref_attributes = {
129
+ anchor: node.id,
130
+ source: node.attr("source"),
131
+ }
132
+
133
+ # remove all formatting: cref content is pure text
134
+ cref_contents = flatten_rawtext(node)
135
+ cref_contents = [cref_contents].flatten.join("\n")
136
+ warn <<~WARNING_MESSAGE if node.blocks?
137
+ asciidoctor: WARNING (#{node.lineno}): comment can not contain blocks of text in XML RFC:\n #{node.content}
138
+ WARNING_MESSAGE
139
+
140
+ result << noko do |xml|
141
+ if node.parent.context !~ /table|example|paragraph|section/
142
+ xml.t do |xml_t|
143
+ xml_t.cref **attr_code(cref_attributes) do |xml_cref|
144
+ xml_cref << cref_contents
145
+ end
146
+ end
147
+ else
148
+ xml.cref **attr_code(cref_attributes) do |xml_cref|
149
+ xml_cref << cref_contents
150
+ end
151
+ end
152
+ end
153
+ end
154
+ result
155
+ end
156
+
157
+ # Syntax:
158
+ # [[id]]
159
+ # .Title
160
+ # [align,alt,suppress-title]
161
+ # ====
162
+ # Example
163
+ # ====
164
+ def example(node)
165
+ figure_attributes = {
166
+ anchor: node.id,
167
+ align: node.attr("align"),
168
+ alt: node.alt,
169
+ title: node.title,
170
+ 'suppress-title': node.attr("suppress-title"),
171
+ # TODO: is 'suppress-title' the correct attribute name?
172
+ }
173
+ # TODO iref
174
+ seen_artwork = false
175
+ noko do |xml|
176
+ xml.figure **attr_code(figure_attributes) do |xml_figure|
177
+ node.blocks.each do |b|
178
+ case b.context
179
+ when :listing, :image, :literal, :stem
180
+ xml_figure << send(b.context, b).join("\n")
181
+ seen_artwork = true
182
+ else
183
+ # we want to see the para text, not its <t> container
184
+ if seen_artwork
185
+ xml_figure.postamble do |postamble|
186
+ postamble << b.content
187
+ end
188
+ else
189
+ xml_figure.preamble do |preamble|
190
+ preamble << b.content
191
+ end
192
+ end
193
+ end
194
+ end
195
+ end
196
+ end
197
+ end
198
+
199
+ # Syntax:
200
+ # .name
201
+ # [source,type,src=uri] (src is mutually exclusive with listing content) (v3)
202
+ # [source,type,src=uri,align,alt] (src is mutually exclusive with listing content) (v2)
203
+ # ----
204
+ # code
205
+ # ----
206
+ def listing(node)
207
+ sourcecode_attributes = {
208
+ align: node.attr("align"),
209
+ alt: node.alt,
210
+ name: node.title,
211
+ type: node.attr("language"),
212
+ src: node.attr("src"),
213
+ }
214
+
215
+ # NOTE: html escaping is performed by Nokogiri
216
+ sourcecode_content =
217
+ sourcecode_attributes[:src].nil? ? "\n" + node.lines.join("\n") + "\n" : ""
218
+
219
+ noko do |xml|
220
+ if node.parent.context != :example
221
+ figure_attributes = {
222
+ anchor: node.id,
223
+ }
224
+ xml.figure **attr_code(figure_attributes) do |xml_figure|
225
+ # xml_figure.artwork sourcecode_content, **attr_code(sourcecode_attributes)
226
+ xml_figure.artwork **attr_code(sourcecode_attributes) do |a|
227
+ a.cdata sourcecode_content
228
+ end
229
+
230
+ end
231
+ else
232
+ # xml.artwork sourcecode_content, **attr_code(sourcecode_attributes)
233
+ xml.artwork **attr_code(sourcecode_attributes) do |a|
234
+ a.cdata sourcecode_content
235
+ end
236
+ end
237
+ end
238
+ end
239
+
240
+ def quote(node)
241
+ result = []
242
+ if node.blocks?
243
+ node.blocks.each do |b|
244
+ result << send(b.context, b)
245
+ end
246
+ else
247
+ result = paragraph(node)
248
+ end
249
+ if node.attr("citetitle") || node.attr("attribution")
250
+ cite = node.attr("attribution") || ""
251
+ cite += ", " if node.attr("citetitle") && node.attr("attribution")
252
+ cite += (node.attr("citetitle") || "")
253
+ cite = "-- " + cite
254
+ result << "<t>#{cite}</t>"
255
+ end
256
+ result
257
+ end
258
+
259
+ end
260
+ end
261
+ end
@@ -0,0 +1,60 @@
1
+ require "asciidoctor"
2
+
3
+ require_relative "../common/base"
4
+ require_relative "../common/front"
5
+ require_relative "base"
6
+ require_relative "blocks"
7
+ require_relative "front"
8
+ require_relative "inline_anchor"
9
+ require_relative "lists"
10
+ require_relative "table"
11
+ require_relative "validate"
12
+
13
+ module Asciidoctor
14
+ module Rfc::V2
15
+ # A {Converter} implementation that generates RFC XML 2 output, a format used to
16
+ # format RFC proposals (https://tools.ietf.org/html/rfc7749)
17
+ #
18
+ # Features drawn from https://github.com/miekg/mmark/wiki/Syntax and
19
+ # https://github.com/riboseinc/rfc2md
20
+ class Converter
21
+ include ::Asciidoctor::Converter
22
+ include ::Asciidoctor::Writer
23
+
24
+ include ::Asciidoctor::Rfc::Common::Base
25
+ include ::Asciidoctor::Rfc::Common::Front
26
+ include ::Asciidoctor::Rfc::V2::Base
27
+ include ::Asciidoctor::Rfc::V2::Blocks
28
+ include ::Asciidoctor::Rfc::V2::Front
29
+ include ::Asciidoctor::Rfc::V2::InlineAnchor
30
+ include ::Asciidoctor::Rfc::V2::Lists
31
+ include ::Asciidoctor::Rfc::V2::Table
32
+ include ::Asciidoctor::Rfc::V2::Validate
33
+
34
+ register_for "rfc2"
35
+
36
+ $seen_back_matter = false
37
+ $xreftext = {}
38
+
39
+ def initialize(backend, opts)
40
+ super
41
+ Asciidoctor::Compliance.natural_xrefs = false
42
+ basebackend "html"
43
+ outfilesuffix ".xml"
44
+ end
45
+
46
+ # alias_method :pass, :content
47
+ alias_method :embedded, :content
48
+ alias_method :sidebar, :content
49
+ alias_method :audio, :skip
50
+ alias_method :colist, :skip
51
+ alias_method :page_break, :skip
52
+ alias_method :thematic_break, :skip
53
+ alias_method :video, :skip
54
+ alias_method :inline_button, :skip
55
+ alias_method :inline_kbd, :skip
56
+ alias_method :inline_menu, :skip
57
+ alias_method :inline_image, :skip
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,69 @@
1
+ module Asciidoctor
2
+ module Rfc::V2
3
+ module Front
4
+ # Syntax:
5
+ # = Title
6
+ # Author
7
+ # :METADATA
8
+ def front(node, xml)
9
+ xml.front do |xml_front|
10
+ title node, xml_front
11
+ author node, xml_front
12
+ date node, xml_front
13
+ area node, xml_front
14
+ workgroup node, xml_front
15
+ keyword node, xml_front
16
+ end
17
+ end
18
+
19
+ def organization(node, suffix, xml)
20
+ organization = node.attr("organization#{suffix}")
21
+ organization_abbrev = node.attr("organization_abbrev#{suffix}")
22
+ organization_attributes = {
23
+ abbrev: organization_abbrev,
24
+ }
25
+ unless organization.nil?
26
+ xml.organization **attr_code(organization_attributes) do |org|
27
+ org << organization
28
+ end
29
+ end
30
+ end
31
+
32
+ def address(node, suffix, xml)
33
+ email = node.attr("email#{suffix}")
34
+ facsimile = node.attr("fax#{suffix}")
35
+ phone = node.attr("phone#{suffix}")
36
+ street = node.attr("street#{suffix}")
37
+ uri = node.attr("uri#{suffix}")
38
+
39
+ # If there is no provided elements for address, don't show it
40
+ return unless [email, facsimile, phone, street, uri].any?
41
+
42
+ # https://tools.ietf.org/html/rfc7749#section-2.27
43
+ # Note that at least one <street> element needs to be present;
44
+ # however, formatters will handle empty values just fine.
45
+ street = street ? street.split("\\ ") : [""]
46
+
47
+ xml.address do |xml_address|
48
+ xml_address.postal do |xml_postal|
49
+ city = node.attr("city#{suffix}")
50
+ code = node.attr("code#{suffix}")
51
+ country = node.attr("country#{suffix}")
52
+ region = node.attr("region#{suffix}")
53
+
54
+ street.each { |st| xml_postal.street { |s| s << st } }
55
+ xml_postal.city { |c| c << city } unless city.nil?
56
+ xml_postal.region { |r| r << region } unless region.nil?
57
+ xml_postal.code { |c| c << code } unless code.nil?
58
+ xml_postal.country { |c| c << country } unless country.nil?
59
+ end
60
+
61
+ xml_address.phone { |p| p << phone } unless phone.nil?
62
+ xml_address.facsimile { |f| f << facsimile } unless facsimile.nil?
63
+ xml_address.email { |e| e << email } unless email.nil?
64
+ xml_address.uri { |u| u << uri } unless uri.nil?
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,111 @@
1
+ module Asciidoctor
2
+ module Rfc::V2
3
+ module InlineAnchor
4
+ def inline_anchor(node)
5
+ case node.type
6
+ when :xref
7
+ inline_anchor_xref node
8
+ when :link
9
+ inline_anchor_link node
10
+ when :bibref
11
+ inline_anchor_bibref node
12
+ when :ref
13
+ inline_anchor_ref node
14
+ else
15
+ warn %(asciidoctor: WARNING (#{current_location(node)}): unknown anchor type: #{node.type.inspect})
16
+ end
17
+ end
18
+
19
+ private
20
+
21
+ def inline_anchor_xref(node)
22
+ if node.text =~ /^\S+ (of|comma|parens|bare)\b/
23
+ # <<crossreference#fragment,section (of|comma|parens|bare): text>> = relref:
24
+ # render equivalent in v2
25
+ matched = /(?<section>\S+)\s+(?<format>[a-z]+)(: )?(?<text>.*)$/.match node.text
26
+
27
+ # fragment inserts file suffix, e.g. rfc2911#fragment becomes rfc2911.xml#fragment
28
+ target = node.target.gsub(/^#/, "").gsub(/(.)(\.xml)?#.*$/, "\\1")
29
+ # reftarget = target
30
+ warn %(asciidoctor: WARNING (#{current_location(node)}): fragments not supported on crossreferences in v2: #{node.target} #{node.text}) if node.target =~ /.#/
31
+ # reftarget = "#{target}##{node.attributes['fragment']}" unless node.attributes["path"].nil?
32
+
33
+ xref_contents = ""
34
+ case matched[:format]
35
+ when "of"
36
+ prefix = "Section #{matched[:section]} of "
37
+ when "comma"
38
+ suffix = ", Section #{matched[:section]}"
39
+ when "parens"
40
+ suffix = " (Section #{matched[:section]})"
41
+ when "bare"
42
+ xref_contents = matched[:section]
43
+ end
44
+ unless matched[:text].empty?
45
+ xref_contents = if xref_contents.empty?
46
+ matched[:text].to_s
47
+ else
48
+ "#{xref_contents}: #{matched[:text]}"
49
+ end
50
+ end
51
+
52
+ xref_attributes = {
53
+ target: target,
54
+ }.reject { |_, value| value.nil? }
55
+
56
+ else
57
+
58
+ matched = /^format=(?<format>counter|title|none|default)(?<text>:\s*.*)?$/.match node.text
59
+ xref_contents = if matched.nil?
60
+ node.text
61
+ else
62
+ matched[:text].nil? ? "" : matched[:text].gsub(/^:\s*/, "")
63
+ end
64
+ matched ||= {}
65
+
66
+ warn %(asciidoctor: WARNING (#{current_location(node)}): fragments not supported on crossreferences in v2: #{node.target} #{node.text}) if node.target =~ /.#/
67
+ xref_attributes = {
68
+ # fragment inserts file suffix, e.g. rfc2911#fragment becomes rfc2911.xml#fragment
69
+ target: node.target.gsub(/^#/, "").gsub(/(.)(\.xml)?#.*$/, "\\1"),
70
+ format: matched[:format],
71
+ align: node.attr("align"),
72
+ }
73
+ end
74
+
75
+ noko do |xml|
76
+ xml << prefix unless prefix.nil? || prefix.empty?
77
+ xml.xref xref_contents, **attr_code(xref_attributes)
78
+ xml << suffix unless suffix.nil? || suffix.empty?
79
+ end.join
80
+ end
81
+
82
+ def inline_anchor_link(node)
83
+ eref_contents = node.target == node.text ? nil : node.text
84
+
85
+ eref_attributes = {
86
+ target: node.target,
87
+ }
88
+
89
+ noko do |xml|
90
+ xml.eref eref_contents, **attr_code(eref_attributes)
91
+ end.join
92
+ end
93
+
94
+ def inline_anchor_bibref(node)
95
+ unless node.xreftext.nil?
96
+ x = node.xreftext.gsub(/^\[(.+)\]$/, "\\1")
97
+ if node.id != x
98
+ $xreftext[node.id] = x
99
+ end
100
+ end
101
+ # NOTE technically node.text should be node.reftext, but subs have already been applied to text
102
+ # %(<bibanchor="#{node.id}">) # will convert to anchor attribute upstream
103
+ nil
104
+ end
105
+
106
+ def inline_anchor_ref(node)
107
+ warn %(asciidoctor: WARNING (#{current_location(node)}): anchor "#{node.id}" is not in a place where XML RFC will recognise it as an anchor attribute)
108
+ end
109
+ end
110
+ end
111
+ end