asciidoctor-rfc 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (130) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +5 -0
  3. data/.oss-guides.rubocop.yml +1077 -0
  4. data/.rspec +1 -0
  5. data/.rubocop.yml +19 -1063
  6. data/.travis.yml +3 -2
  7. data/Guardfile +22 -0
  8. data/README.adoc +1151 -0
  9. data/Rakefile +1 -1
  10. data/asciidoctor-rfc.gemspec +20 -3
  11. data/bin/asciidoctor-rfc2 +15 -0
  12. data/bin/asciidoctor-rfc3 +15 -0
  13. data/bin/rspec +0 -1
  14. data/lib/asciidoctor-rfc.rb +4 -0
  15. data/lib/asciidoctor/rfc/common/base.rb +218 -0
  16. data/lib/asciidoctor/rfc/common/front.rb +120 -0
  17. data/lib/asciidoctor/rfc/v2/base.rb +341 -0
  18. data/lib/asciidoctor/rfc/v2/blocks.rb +192 -0
  19. data/lib/asciidoctor/rfc/v2/converter.rb +64 -0
  20. data/lib/asciidoctor/rfc/v2/front.rb +69 -0
  21. data/lib/asciidoctor/rfc/v2/inline_anchor.rb +102 -0
  22. data/lib/asciidoctor/rfc/v2/lists.rb +134 -0
  23. data/lib/asciidoctor/rfc/v2/table.rb +112 -0
  24. data/lib/asciidoctor/rfc/v2/validate.rb +738 -0
  25. data/lib/asciidoctor/rfc/v2/validate2.rng +716 -0
  26. data/lib/asciidoctor/rfc/v3/base.rb +358 -0
  27. data/lib/asciidoctor/rfc/v3/blocks.rb +203 -0
  28. data/lib/asciidoctor/rfc/v3/converter.rb +64 -0
  29. data/lib/asciidoctor/rfc/v3/front.rb +115 -0
  30. data/lib/asciidoctor/rfc/v3/inline_anchor.rb +90 -0
  31. data/lib/asciidoctor/rfc/v3/lists.rb +190 -0
  32. data/lib/asciidoctor/rfc/v3/svg.rng +9081 -0
  33. data/lib/asciidoctor/rfc/v3/table.rb +65 -0
  34. data/lib/asciidoctor/rfc/v3/validate.rb +2168 -0
  35. data/lib/asciidoctor/rfc/v3/validate.rng +2143 -0
  36. data/lib/asciidoctor/rfc/version.rb +2 -2
  37. data/spec/asciidoctor/rfc/v2/appendix_spec.rb +124 -0
  38. data/spec/asciidoctor/rfc/v2/area_spec.rb +60 -0
  39. data/spec/asciidoctor/rfc/v2/author_spec.rb +444 -0
  40. data/spec/asciidoctor/rfc/v2/comments_spec.rb +316 -0
  41. data/spec/asciidoctor/rfc/v2/crossref_spec.rb +205 -0
  42. data/spec/asciidoctor/rfc/v2/date_spec.rb +166 -0
  43. data/spec/asciidoctor/rfc/v2/dlist_spec.rb +108 -0
  44. data/spec/asciidoctor/rfc/v2/document_spec.rb +161 -0
  45. data/spec/asciidoctor/rfc/v2/example_spec.rb +50 -0
  46. data/spec/asciidoctor/rfc/v2/front_spec.rb +75 -0
  47. data/spec/asciidoctor/rfc/v2/image_spec.rb +81 -0
  48. data/spec/asciidoctor/rfc/v2/indexterm_spec.rb +66 -0
  49. data/spec/asciidoctor/rfc/v2/inline_formatting_spec.rb +177 -0
  50. data/spec/asciidoctor/rfc/v2/keyword_spec.rb +63 -0
  51. data/spec/asciidoctor/rfc/v2/listing_spec.rb +59 -0
  52. data/spec/asciidoctor/rfc/v2/literal_spec.rb +53 -0
  53. data/spec/asciidoctor/rfc/v2/olist_spec.rb +147 -0
  54. data/spec/asciidoctor/rfc/v2/paragraph_spec.rb +68 -0
  55. data/spec/asciidoctor/rfc/v2/preamble_spec.rb +140 -0
  56. data/spec/asciidoctor/rfc/v2/quote_spec.rb +24 -0
  57. data/spec/asciidoctor/rfc/v2/references_spec.rb +96 -0
  58. data/spec/asciidoctor/rfc/v2/section_spec.rb +260 -0
  59. data/spec/asciidoctor/rfc/v2/sidebar_spec.rb +32 -0
  60. data/spec/asciidoctor/rfc/v2/table_spec.rb +293 -0
  61. data/spec/asciidoctor/rfc/v2/ulist_spec.rb +96 -0
  62. data/spec/asciidoctor/rfc/v2/workgroup_spec.rb +60 -0
  63. data/spec/asciidoctor/rfc/v3/appendix_spec.rb +130 -0
  64. data/spec/asciidoctor/rfc/v3/area_spec.rb +63 -0
  65. data/spec/asciidoctor/rfc/v3/author_spec.rb +540 -0
  66. data/spec/asciidoctor/rfc/v3/comments_spec.rb +308 -0
  67. data/spec/asciidoctor/rfc/v3/crossref_spec.rb +269 -0
  68. data/spec/asciidoctor/rfc/v3/date_spec.rb +149 -0
  69. data/spec/asciidoctor/rfc/v3/dlist_spec.rb +121 -0
  70. data/spec/asciidoctor/rfc/v3/document_spec.rb +109 -0
  71. data/spec/asciidoctor/rfc/v3/example_spec.rb +34 -0
  72. data/spec/asciidoctor/rfc/v3/front_spec.rb +43 -0
  73. data/spec/asciidoctor/rfc/v3/image_spec.rb +81 -0
  74. data/spec/asciidoctor/rfc/v3/indexterm_spec.rb +69 -0
  75. data/spec/asciidoctor/rfc/v3/inline_formatting_spec.rb +319 -0
  76. data/spec/asciidoctor/rfc/v3/keyword_spec.rb +33 -0
  77. data/spec/asciidoctor/rfc/v3/link_spec.rb +34 -0
  78. data/spec/asciidoctor/rfc/v3/listing_spec.rb +59 -0
  79. data/spec/asciidoctor/rfc/v3/literal_spec.rb +51 -0
  80. data/spec/asciidoctor/rfc/v3/olist_spec.rb +168 -0
  81. data/spec/asciidoctor/rfc/v3/paragraph_spec.rb +73 -0
  82. data/spec/asciidoctor/rfc/v3/preamble_spec.rb +112 -0
  83. data/spec/asciidoctor/rfc/v3/quote_spec.rb +91 -0
  84. data/spec/asciidoctor/rfc/v3/references_spec.rb +147 -0
  85. data/spec/asciidoctor/rfc/v3/section_spec.rb +198 -0
  86. data/spec/asciidoctor/rfc/v3/series_info_spec.rb +151 -0
  87. data/spec/asciidoctor/rfc/v3/sidebar_spec.rb +30 -0
  88. data/spec/asciidoctor/rfc/v3/table_spec.rb +275 -0
  89. data/spec/asciidoctor/rfc/v3/ulist_spec.rb +74 -0
  90. data/spec/asciidoctor/rfc/v3/workgroup_spec.rb +33 -0
  91. data/spec/examples/davies-template-bare-06.adoc +361 -0
  92. data/spec/examples/davies-template-bare-06.xml.orig +426 -0
  93. data/spec/examples/example-v2.adoc +181 -0
  94. data/spec/examples/example-v2.xml +675 -0
  95. data/spec/examples/example-v3.adoc +185 -0
  96. data/spec/examples/example-v3.xml +1009 -0
  97. data/spec/examples/mib-doc-template-xml-06.adoc +596 -0
  98. data/spec/examples/mib-doc-template-xml-06.xml.orig +654 -0
  99. data/spec/examples/rfc1149.md +76 -0
  100. data/spec/examples/rfc1149.md.2.xml +94 -0
  101. data/spec/examples/rfc1149.md.3.xml +93 -0
  102. data/spec/examples/rfc1149.md.adoc +65 -0
  103. data/spec/examples/rfc2100.md +149 -0
  104. data/spec/examples/rfc2100.md.2.xml +169 -0
  105. data/spec/examples/rfc2100.md.3.xml +163 -0
  106. data/spec/examples/rfc2100.md.adoc +136 -0
  107. data/spec/examples/rfc3514.md +203 -0
  108. data/spec/examples/rfc3514.md.2.xml +238 -0
  109. data/spec/examples/rfc3514.md.3.xml +258 -0
  110. data/spec/examples/rfc3514.md.adoc +324 -0
  111. data/spec/examples/rfc5841.md +342 -0
  112. data/spec/examples/rfc5841.md.2.xml +393 -0
  113. data/spec/examples/rfc5841.md.3.xml +449 -0
  114. data/spec/examples/rfc5841.md.adoc +414 -0
  115. data/spec/examples/rfc6350.adoc +3499 -0
  116. data/spec/examples/rfc6350.bib +763 -0
  117. data/spec/examples/rfc748.md +79 -0
  118. data/spec/examples/rfc748.md.2.xml +116 -0
  119. data/spec/examples/rfc748.md.3.xml +109 -0
  120. data/spec/examples/rfc748.md.adoc +80 -0
  121. data/spec/examples/rfc7511.md +257 -0
  122. data/spec/examples/rfc7511.md.2.xml +300 -0
  123. data/spec/examples/rfc7511.md.3.xml +347 -0
  124. data/spec/examples/rfc7511.md.adoc +417 -0
  125. data/spec/spec_helper.rb +115 -5
  126. metadata +274 -9
  127. data/.hound.yml +0 -3
  128. data/README.md +0 -84
  129. data/lib/asciidoctor/rfc.rb +0 -7
  130. data/spec/asciidoctor-rfc/.keep +0 -0
@@ -0,0 +1,64 @@
1
+ require "asciidoctor"
2
+
3
+ require "asciidoctor/rfc/version"
4
+ require "asciidoctor/rfc/common/base"
5
+ require "asciidoctor/rfc/common/front"
6
+ require "asciidoctor/rfc/v3/base"
7
+ require "asciidoctor/rfc/v3/blocks"
8
+ require "asciidoctor/rfc/v3/front"
9
+ require "asciidoctor/rfc/v3/inline_anchor"
10
+ require "asciidoctor/rfc/v3/lists"
11
+ require "asciidoctor/rfc/v3/table"
12
+ require "asciidoctor/rfc/v3/validate"
13
+
14
+ module Asciidoctor
15
+ module RFC::V3
16
+ # A {Converter} implementation that generates RFC XML output, a format used to
17
+ # format RFC proposals (https://tools.ietf.org/html/rfc7991)
18
+ #
19
+ # Features drawn from https://github.com/miekg/mmark/wiki/Syntax and
20
+ # https://github.com/riboseinc/rfc2md
21
+ class Converter
22
+ include ::Asciidoctor::Converter
23
+ include ::Asciidoctor::Writer
24
+
25
+ include ::Asciidoctor::RFC::Common::Base
26
+ include ::Asciidoctor::RFC::Common::Front
27
+ include ::Asciidoctor::RFC::V3::Base
28
+ include ::Asciidoctor::RFC::V3::Blocks
29
+ include ::Asciidoctor::RFC::V3::Front
30
+ include ::Asciidoctor::RFC::V3::InlineAnchor
31
+ include ::Asciidoctor::RFC::V3::Lists
32
+ include ::Asciidoctor::RFC::V3::Table
33
+ include ::Asciidoctor::RFC::V3::Validate
34
+
35
+ register_for "rfc3"
36
+
37
+ $seen_back_matter = false
38
+ $seen_abstract = false
39
+ $xreftext = {}
40
+
41
+ def initialize(backend, opts)
42
+ super
43
+ # basebackend 'html'
44
+ outfilesuffix ".xml"
45
+ end
46
+
47
+ # alias_method :pass, :content
48
+ alias_method :embedded, :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
+
59
+ alias_method :stem, :literal
60
+
61
+ alias_method :inline_callout, :content
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,115 @@
1
+ module Asciidoctor
2
+ module RFC::V3
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
+ series_info node, xml_front
12
+ author node, xml_front
13
+ date node, xml_front
14
+ area node, xml_front
15
+ workgroup node, xml_front
16
+ keyword node, xml_front
17
+ end
18
+ end
19
+
20
+ def series_info(node, xml)
21
+ docname = node.attr("name")
22
+ return if docname.nil? || docname&.empty?
23
+ is_rfc = docname =~ /^rfc-?/i || node.attr("doctype") == "rfc"
24
+
25
+ name = is_rfc ? docname.gsub(/^rfc-?/i, "") : docname
26
+ nameattr = is_rfc ? "RFC" : "Internet-Draft"
27
+ value = name.gsub(/\.[^\/]+$/, "")
28
+
29
+ seriesInfo_attributes = {
30
+ name: nameattr,
31
+ status: node.attr("status"),
32
+ stream: node.attr("submission-type") || "IETF",
33
+ value: value,
34
+ }
35
+ xml.seriesInfo **attr_code(seriesInfo_attributes)
36
+
37
+ intendedstatus = node.attr("intended-series")
38
+ if !is_rfc && !intendedstatus.nil?
39
+ unless intendedstatus =~ /^(standard|full-standard|bcp|fyi|informational|experimental|historic)$/
40
+ warn %(asciidoctor: WARNING: disallowed value for intended-series: #{intendedstatus})
41
+ end
42
+ seriesInfo_attributes = {
43
+ name: "",
44
+ status: intendedstatus,
45
+ value: value,
46
+ }
47
+ xml.seriesInfo **attr_code(seriesInfo_attributes)
48
+ end
49
+
50
+ rfcstatus = intendedstatus
51
+ if is_rfc && !rfcstatus.nil?
52
+ m = /^(\S+) (\d+)$/.match rfcstatus
53
+ if m.nil?
54
+ rfcstatus = "exp" if rfcstatus == "experimental"
55
+ rfcstatus = "info" if rfcstatus == "informational"
56
+ warn %(asciidoctor: WARNING: disallowed value for intended-series with no series number: #{rfcstatus}) unless rfcstatus =~ /^(info|exp|historic)$/
57
+ else
58
+ warn %(asciidoctor: WARNING: disallowed value for intended-series with series number: #{m[1]}) unless m[1] =~ /^(standard|full-standard|bcp)$/
59
+ end
60
+ seriesInfo_attributes = {
61
+ name: "",
62
+ status: m.nil? ? rfcstatus : m[1],
63
+ value: m.nil? ? value : m[2],
64
+ }
65
+ xml.seriesInfo **attr_code(seriesInfo_attributes)
66
+ end
67
+ end
68
+
69
+ def organization(node, suffix, xml)
70
+ organization = node.attr("organization#{suffix}")
71
+ xml.organization { |org| org << organization } unless organization.nil?
72
+ end
73
+
74
+ def address(node, suffix, xml)
75
+ email = node.attr("email#{suffix}")
76
+ facsimile = node.attr("fax#{suffix}")
77
+ phone = node.attr("phone#{suffix}")
78
+ postalline = node.attr("postal-line#{suffix}")
79
+ street = node.attr("street#{suffix}")
80
+ uri = node.attr("uri#{suffix}")
81
+ if [email, facsimile, phone, postalline, street, uri].any?
82
+ xml.address do |xml_address|
83
+ address1 node, suffix, xml_address if [postalline, street].any?
84
+ xml_address.phone { |p| p << phone } unless phone.nil?
85
+ xml_address.facsimile { |f| f << facsimile } unless facsimile.nil?
86
+ xml_address.email { |e| e << email } unless email.nil?
87
+ xml_address.uri { |u| u << uri } unless uri.nil?
88
+ end
89
+ end
90
+ end
91
+
92
+ private
93
+
94
+ def address1(node, suffix, xml_address)
95
+ postalline = node.attr("postal-line#{suffix}")
96
+ street = node.attr("street#{suffix}")
97
+ xml_address.postal do |xml_postal|
98
+ if postalline.nil?
99
+ city = node.attr("city#{suffix}")
100
+ code = node.attr("code#{suffix}")
101
+ country = node.attr("country#{suffix}")
102
+ region = node.attr("region#{suffix}")
103
+ street&.split("\\ ")&.each { |st| xml_postal.street { |s| s << st } }
104
+ xml_postal.city { |c| c << city } unless city.nil?
105
+ xml_postal.region { |r| r << region } unless region.nil?
106
+ xml_postal.code { |c| c << code } unless code.nil?
107
+ xml_postal.country { |c| c << country } unless country.nil?
108
+ else
109
+ postalline&.split("\\ ")&.each { |pl| xml_postal.postalLine { |p| p << pl } }
110
+ end
111
+ end
112
+ end
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,90 @@
1
+ module Asciidoctor
2
+ module RFC::V3
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: unknown anchor type: #{node.type.inspect})
16
+ end
17
+ end
18
+
19
+ private
20
+
21
+ def inline_anchor_xref(node)
22
+ text = node.text
23
+ if text =~ /^\S+ (of|comma|parens|bare)\b/
24
+ # <<crossreference#fragment,section (of|comma|parens|bare): text>> = relref
25
+ matched = /(?<section>\S+)\s+(?<format>[a-z]+)(: )?(?<text>.*)$/.match node.text
26
+
27
+ relref_contents = matched[:text]
28
+
29
+ relref_attributes = {
30
+ relative: node.attributes["path"].nil? ? nil : node.attributes["fragment"],
31
+ section: matched[:section],
32
+ displayFormat: matched[:format],
33
+ target: node.target.gsub(/\..*$/, "").gsub(/^#/, ""),
34
+ }
35
+
36
+ noko do |xml|
37
+ xml.relref relref_contents, **attr_code(relref_attributes)
38
+ end.join
39
+ else
40
+ xref_contents = node.text
41
+
42
+ matched = /^format=(?<format>counter|title|none|default):\s*(?<text>.*)$/.match xref_contents
43
+
44
+ xref_contents = matched[:text] if matched
45
+
46
+ xref_attributes = {
47
+ format: matched&.[](:format),
48
+ target: node.target.gsub(/^#/, ""),
49
+ }
50
+
51
+ noko do |xml|
52
+ xml.xref xref_contents, **attr_code(xref_attributes)
53
+ end.join
54
+ end
55
+ end
56
+
57
+ def inline_anchor_link(node)
58
+ eref_contents = node.target == node.text ? nil : node.text
59
+
60
+ eref_attributes = {
61
+ target: node.target,
62
+ }
63
+
64
+ noko do |xml|
65
+ xml.eref eref_contents, **attr_code(eref_attributes)
66
+ end.join
67
+ end
68
+
69
+ def inline_anchor_bibref(node)
70
+ unless node.xreftext.nil?
71
+ x = node.xreftext.gsub(/^\[(.+)\]$/, "\\1")
72
+ if node.id != x
73
+ $xreftext[node.id] = x
74
+ end
75
+ end
76
+ # NOTE technically node.text should be node.reftext, but subs have already been applied to text
77
+ %(<bibanchor="#{node.id}">) # will convert to anchor attribute upstream
78
+ end
79
+
80
+ def inline_anchor_ref(node)
81
+ # If this is within referencegroup, output as bibanchor anyway
82
+ if $processing_reflist
83
+ %(<bibanchor="#{node.id}">) # will convert to anchor attribute upstream
84
+ else
85
+ warn %(asciidoctor: WARNING: anchor "#{node.id}" is not in a place where XML RFC will recognise it as an anchor attribute)
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,190 @@
1
+ module Asciidoctor
2
+ module RFC::V3
3
+ module Lists
4
+ # Syntax:
5
+ # * [[[ref1]]] A
6
+ # * [[[ref2]]] B
7
+ # * [[[ref3]]] (Referencegroup: no content)
8
+ # * [[[ref4]]] C
9
+ # * [[[ref4]]] D
10
+ # @note ulist repurposed as reference list
11
+ # def reflist(node)
12
+ # result = []
13
+ # if node.context == :ulist
14
+ # node.items.each do |item|
15
+ # # we expect the biblio anchor to be right at the start of the reference
16
+ # if item.blocks?
17
+ # # we expect any list to be embedded, and only one level of embedding
18
+ # # we expect no content in the referencegroup line other than the bibliographic anchor
19
+ # result << "<referencegroup>#{item.text}".gsub(/<referencegroup>\s*\[?<bibanchor="([^"]+)">\]?.*$/, "<referencegroup anchor=\"\\1\">")
20
+ # item.blocks.each { |b| result << reflist(b) }
21
+ # result << "</referencegroup>"
22
+ # else
23
+ # # quoteTitle = get_header_attribute item, "quoteTitle"
24
+ # # target = get_header_attribute item, "target"
25
+ # # annotation = get_header_attribute item, "annotation"
26
+ # # FIXME: [[[x]]] within embedded list is processed as [<bibref>]
27
+ # result << "<reference>#{item.text}</refcontent></reference>".gsub(/<reference>\s*\[?<bibanchor="([^"]+)">\]?\s*/, "<reference anchor=\"\\1\"><refcontent>")
28
+ # end
29
+ # end
30
+ # elsif node.context == :pass
31
+ # # we expect raw xml
32
+ # node.lines.each do |item|
33
+ # # undo XML substitution
34
+ # ref = item.gsub(/\&lt;/, "<").gsub(/\&gt;/, ">")
35
+ # result << ref
36
+ # end
37
+ # else
38
+ # warn %(asciidoctor: WARNING: references are not a ulist or raw XML: #{node.context})
39
+ # end
40
+ # result
41
+ # end
42
+
43
+ # Syntax:
44
+ # [[id]]
45
+ # [empty=true,spacing=compact|normal] (optional)
46
+ # * A
47
+ # * B
48
+ def ulist(node)
49
+ result = []
50
+
51
+ if node.parent.context == :preamble && !$seen_abstract
52
+ $seen_abstract = true
53
+ result << "<abstract>"
54
+ end
55
+
56
+ result << noko do |xml|
57
+ ul_attributes = {
58
+ anchor: node.id,
59
+ empty: node.attr("empty"),
60
+ spacing: node.attr("spacing"),
61
+ }
62
+
63
+ xml.ul **attr_code(ul_attributes) do |xml_ul|
64
+ node.items.each do |item|
65
+ li_attributes = {
66
+ anchor: item.id,
67
+ }
68
+
69
+ xml_ul.li **attr_code(li_attributes) do |xml_li|
70
+ if item.blocks?
71
+ xml_li.t do |t|
72
+ t << item.text
73
+ end
74
+ xml_li << item.content
75
+ else
76
+ xml_li << item.text
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
82
+
83
+ result
84
+ end
85
+
86
+ OLIST_TYPES = Hash.new("1").merge(
87
+ arabic: "1",
88
+ # decimal: "1", # not supported
89
+ loweralpha: "a",
90
+ # lowergreek: "lower-greek", # not supported
91
+ lowerroman: "i",
92
+ upperalpha: "A",
93
+ upperroman: "I",
94
+ ).freeze
95
+
96
+ # Syntax:
97
+ # [[id]]
98
+ # [start=n,group=n,spacing=normal|compact] (optional)
99
+ # . A
100
+ # . B
101
+ def olist(node)
102
+ result = []
103
+ if node.parent.context == :preamble && !$seen_abstract
104
+ $seen_abstract = true
105
+ result << "<abstract>"
106
+ end
107
+
108
+ result << noko do |xml|
109
+ type = OLIST_TYPES[node.style.to_sym]
110
+ type = node.attr("format") unless node.attr("format").nil?
111
+ ol_attributes = {
112
+ anchor: node.id,
113
+ start: node.attr("start"),
114
+ group: node.attr("group"),
115
+ type: type,
116
+ spacing: ("compact" if node.style == "compact") || node.attr("spacing"),
117
+ }
118
+
119
+ xml.ol **attr_code(ol_attributes) do |xml_ol|
120
+ node.items.each do |item|
121
+ li_attributes = {
122
+ anchor: item.id,
123
+ }
124
+ xml_ol.li **attr_code(li_attributes) do |xml_li|
125
+ if item.blocks?
126
+ xml_li.t do |t|
127
+ t << item.text
128
+ end
129
+ xml_li << item.content
130
+ else
131
+ xml_li << item.text
132
+ end
133
+ end
134
+ end
135
+ end
136
+ end
137
+ result
138
+ end
139
+
140
+ # Syntax:
141
+ # [[id]]
142
+ # [horizontal,compact] (optional)
143
+ # A:: B
144
+ # C:: D
145
+ def dlist(node)
146
+ result = []
147
+
148
+ if node.parent.context == :preamble && !$seen_abstract
149
+ $seen_abstract = true
150
+ result << "<abstract>"
151
+ end
152
+
153
+ result << noko do |xml|
154
+ dl_attributes = {
155
+ anchor: node.id,
156
+ hanging: ("true" if node.style == "horizontal"),
157
+ spacing: ("compact" if node.style == "compact"),
158
+ }
159
+
160
+ xml.dl **attr_code(dl_attributes) do |xml_dl|
161
+ node.items.each do |terms, dd|
162
+ terms.each_with_index do |dt, idx|
163
+ xml_dl.dt { |xml_dt| xml_dt << dt.text }
164
+ if idx < terms.size - 1
165
+ xml_dl.dd
166
+ end
167
+ end
168
+
169
+ if dd.nil?
170
+ xml_dl.dd
171
+ else
172
+ xml_dl.dd do |xml_dd|
173
+ if dd.blocks?
174
+ if dd.text?
175
+ xml_dd.t { |t| t << dd.text }
176
+ end
177
+ xml_dd << dd.content
178
+ else
179
+ xml_dd << dd.text
180
+ end
181
+ end
182
+ end
183
+ end
184
+ end
185
+ end
186
+ result
187
+ end
188
+ end
189
+ end
190
+ end