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,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