metanorma-standoc 1.7.3 → 1.8.5

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 (62) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/rake.yml +11 -41
  3. data/.rubocop.yml +1 -1
  4. data/lib/asciidoctor/standoc/base.rb +34 -45
  5. data/lib/asciidoctor/standoc/basicdoc.rng +5 -3
  6. data/lib/asciidoctor/standoc/blocks.rb +20 -11
  7. data/lib/asciidoctor/standoc/blocks_notes.rb +2 -2
  8. data/lib/asciidoctor/standoc/cleanup.rb +29 -77
  9. data/lib/asciidoctor/standoc/cleanup_block.rb +39 -27
  10. data/lib/asciidoctor/standoc/cleanup_boilerplate.rb +56 -0
  11. data/lib/asciidoctor/standoc/cleanup_inline.rb +26 -29
  12. data/lib/asciidoctor/standoc/cleanup_maths.rb +123 -0
  13. data/lib/asciidoctor/standoc/cleanup_ref.rb +4 -98
  14. data/lib/asciidoctor/standoc/cleanup_ref_dl.rb +94 -0
  15. data/lib/asciidoctor/standoc/cleanup_section.rb +5 -0
  16. data/lib/asciidoctor/standoc/cleanup_terms.rb +2 -2
  17. data/lib/asciidoctor/standoc/converter.rb +0 -1
  18. data/lib/asciidoctor/standoc/front.rb +2 -2
  19. data/lib/asciidoctor/standoc/inline.rb +8 -16
  20. data/lib/asciidoctor/standoc/isodoc.rng +108 -2
  21. data/lib/asciidoctor/standoc/lists.rb +2 -2
  22. data/lib/asciidoctor/standoc/macros_plantuml.rb +1 -1
  23. data/lib/asciidoctor/standoc/ref_sect.rb +2 -2
  24. data/lib/asciidoctor/standoc/reqt.rb +6 -1
  25. data/lib/asciidoctor/standoc/section.rb +12 -80
  26. data/lib/asciidoctor/standoc/table.rb +1 -1
  27. data/lib/asciidoctor/standoc/terms.rb +125 -0
  28. data/lib/asciidoctor/standoc/utils.rb +2 -120
  29. data/lib/asciidoctor/standoc/validate.rb +16 -1
  30. data/lib/metanorma/standoc/version.rb +1 -1
  31. data/metanorma-standoc.gemspec +4 -4
  32. data/spec/{asciidoctor-standoc → asciidoctor}/base_spec.rb +30 -1
  33. data/spec/{asciidoctor-standoc → asciidoctor}/blocks_spec.rb +0 -0
  34. data/spec/{asciidoctor-standoc → asciidoctor}/cleanup_sections_spec.rb +0 -0
  35. data/spec/{asciidoctor-standoc → asciidoctor}/cleanup_spec.rb +408 -6
  36. data/spec/{asciidoctor-standoc → asciidoctor}/datamodel/attributes_table_preprocessor_spec.rb +0 -0
  37. data/spec/{asciidoctor-standoc → asciidoctor}/datamodel/diagram_preprocessor_spec.rb +0 -0
  38. data/spec/{asciidoctor-standoc → asciidoctor}/inline_spec.rb +2 -0
  39. data/spec/{asciidoctor-standoc → asciidoctor}/isobib_cache_spec.rb +4 -4
  40. data/spec/{asciidoctor-standoc → asciidoctor}/lists_spec.rb +0 -0
  41. data/spec/{asciidoctor-standoc → asciidoctor}/macros_json2text_spec.rb +0 -0
  42. data/spec/{asciidoctor-standoc → asciidoctor}/macros_lutaml_spec.rb +0 -0
  43. data/spec/{asciidoctor-standoc → asciidoctor}/macros_plantuml_spec.rb +0 -0
  44. data/spec/{asciidoctor-standoc → asciidoctor}/macros_spec.rb +0 -0
  45. data/spec/{asciidoctor-standoc → asciidoctor}/macros_yaml2text_spec.rb +0 -0
  46. data/spec/{asciidoctor-standoc → asciidoctor}/refs_dl_spec.rb +13 -1
  47. data/spec/{asciidoctor-standoc → asciidoctor}/refs_spec.rb +175 -153
  48. data/spec/{asciidoctor-standoc → asciidoctor}/section_spec.rb +22 -3
  49. data/spec/{asciidoctor-standoc → asciidoctor}/table_spec.rb +0 -0
  50. data/spec/{asciidoctor-standoc → asciidoctor}/validate_spec.rb +20 -0
  51. data/spec/fixtures/action_schemaexpg1.svg +122 -0
  52. data/spec/spec_helper.rb +8 -0
  53. data/spec/vcr_cassettes/dated_iso_ref_joint_iso_iec.yml +47 -47
  54. data/spec/vcr_cassettes/isobib_get_123.yml +14 -14
  55. data/spec/vcr_cassettes/isobib_get_123_1.yml +27 -27
  56. data/spec/vcr_cassettes/isobib_get_123_1_fr.yml +36 -36
  57. data/spec/vcr_cassettes/isobib_get_123_2001.yml +13 -13
  58. data/spec/vcr_cassettes/isobib_get_124.yml +13 -13
  59. data/spec/vcr_cassettes/rfcbib_get_rfc8341.yml +94 -30
  60. data/spec/vcr_cassettes/separates_iev_citations_by_top_level_clause.yml +45 -45
  61. metadata +49 -46
  62. data/lib/asciidoctor/standoc/log.rb +0 -59
@@ -50,6 +50,7 @@ module Asciidoctor
50
50
  def biblio_renumber(xmldoc)
51
51
  i = 0
52
52
  xmldoc.xpath("//bibliography//references | //clause//references | //annex//references").each do |r|
53
+ next if r["normative"] == "true"
53
54
  r.xpath("./bibitem").each do |b|
54
55
  i += 1
55
56
  next unless docid = b.at("./docidentifier[@type = 'metanorma']")
@@ -88,18 +89,8 @@ module Asciidoctor
88
89
  end
89
90
  end
90
91
 
91
- def docid_prefix(prefix, docid)
92
- docid = "#{prefix} #{docid}" unless omit_docid_prefix(prefix)
93
- docid
94
- end
95
-
96
- def omit_docid_prefix(prefix)
97
- return true if prefix.nil? || prefix.empty?
98
- %(ISO IEC IEV ITU metanorma).include? prefix
99
- end
100
-
101
- def format_ref(ref, type, isopub)
102
- return docid_prefix(type, ref) if isopub
92
+ def format_ref(ref, type)
93
+ return @isodoc.docid_prefix(type, ref) if type != "metanorma"
103
94
  return "[#{ref}]" if /^\d+$/.match(ref) && !/^\[.*\]$/.match(ref)
104
95
  ref
105
96
  end
@@ -115,96 +106,11 @@ module Asciidoctor
115
106
  isopub = ref.at(ISO_PUBLISHER_XPATH)
116
107
  docid = ref.at("./docidentifier[@type = 'metanorma']") ||
117
108
  ref.at("./docidentifier[not(@type = 'DOI')]") or next
118
- reference = format_ref(docid.text, docid["type"], isopub)
109
+ reference = format_ref(docid.text, docid["type"])
119
110
  @anchors[ref["id"]] = { xref: reference }
120
111
  end
121
112
  end
122
113
 
123
- def ref_dl_cleanup(xmldoc)
124
- xmldoc.xpath("//clause[@bibitem = 'true']").each do |c|
125
- bib = dl_bib_extract(c) or next
126
- validate_ref_dl(bib, c)
127
- bibitemxml = RelatonBib::BibliographicItem.new(RelatonBib::HashConverter::hash_to_bib(bib)).to_xml or next
128
- bibitem = Nokogiri::XML(bibitemxml)
129
- bibitem.root["id"] = c["id"] if c["id"] && !/^_/.match(c["id"])
130
- c.replace(bibitem.root)
131
- end
132
- end
133
-
134
- def validate_ref_dl(bib, c)
135
- id = bib["id"]
136
- id ||= c["id"] unless /^_/.match(c["id"]) # do not accept implicit id
137
- unless id
138
- @log.add("Anchors", c, "The following reference is missing an anchor:\n" + c.to_xml)
139
- return
140
- end
141
- bib["title"] or @log.add("Bibliography", c, "Reference #{id} is missing a title")
142
- bib["docid"] or @log.add("Bibliography", c, "Reference #{id} is missing a document identifier (docid)")
143
- end
144
-
145
- def extract_from_p(tag, bib, key)
146
- return unless bib[tag]
147
- "<#{key}>#{bib[tag].at('p').children}</#{key}>"
148
- end
149
-
150
- # if the content is a single paragraph, replace it with its children
151
- # single links replaced with uri
152
- def p_unwrap(p)
153
- elems = p.elements
154
- if elems.size == 1 && elems[0].name == "p"
155
- link_unwrap(elems[0]).children.to_xml.strip
156
- else
157
- p.to_xml.strip
158
- end
159
- end
160
-
161
- def link_unwrap(p)
162
- elems = p.elements
163
- if elems.size == 1 && elems[0].name == "link"
164
- p.at("./link").replace(elems[0]["target"].strip)
165
- end
166
- p
167
- end
168
-
169
- def dd_bib_extract(dtd)
170
- return nil if dtd.children.empty?
171
- dtd.at("./dl") and return dl_bib_extract(dtd)
172
- elems = dtd.remove.elements
173
- return p_unwrap(dtd) unless elems.size == 1 && %w(ol ul).include?(elems[0].name)
174
- ret = []
175
- elems[0].xpath("./li").each do |li|
176
- ret << p_unwrap(li)
177
- end
178
- ret
179
- end
180
-
181
- def add_to_hash(bib, key, val)
182
- Utils::set_nested_value(bib, key.split(/\./), val)
183
- end
184
-
185
- # definition list, with at most one level of unordered lists
186
- def dl_bib_extract(c, nested = false)
187
- dl = c.at("./dl") or return
188
- bib = {}
189
- key = ""
190
- dl.xpath("./dt | ./dd").each do |dtd|
191
- dtd.name == "dt" and key = dtd.text.sub(/:+$/, "") or add_to_hash(bib, key, dd_bib_extract(dtd))
192
- end
193
- c.xpath("./clause").each do |c1|
194
- key = c1&.at("./title")&.text&.downcase&.strip
195
- next unless %w(contributor relation series).include? key
196
- add_to_hash(bib, key, dl_bib_extract(c1, true))
197
- end
198
- if !nested and c.at("./title")
199
- title = c.at("./title").remove.children.to_xml
200
- bib["title"] = [bib["title"]] if bib["title"].is_a? Hash
201
- bib["title"] = [bib["title"]] if bib["title"].is_a? String
202
- bib["title"] = [] unless bib["title"]
203
- bib["title"] << title if !title.empty?
204
- end
205
- bib
206
- end
207
-
208
114
  def fetch_termbase(termbase, id)
209
115
  ""
210
116
  end
@@ -0,0 +1,94 @@
1
+ require "set"
2
+ require "relaton_bib"
3
+
4
+ module Asciidoctor
5
+ module Standoc
6
+ module Cleanup
7
+ def ref_dl_cleanup(xmldoc)
8
+ xmldoc.xpath("//clause[@bibitem = 'true']").each do |c|
9
+ bib = dl_bib_extract(c) or next
10
+ validate_ref_dl(bib, c)
11
+ bibitemxml = RelatonBib::BibliographicItem.new(RelatonBib::HashConverter::hash_to_bib(bib)).to_xml or next
12
+ bibitem = Nokogiri::XML(bibitemxml)
13
+ bibitem.root["id"] = c["id"] if c["id"] && !/^_/.match(c["id"])
14
+ c.replace(bibitem.root)
15
+ end
16
+ end
17
+
18
+ def validate_ref_dl(bib, c)
19
+ id = bib["id"]
20
+ id ||= c["id"] unless /^_/.match(c["id"]) # do not accept implicit id
21
+ unless id
22
+ @log.add("Anchors", c, "The following reference is missing an anchor:\n" + c.to_xml)
23
+ return
24
+ end
25
+ @refids << id
26
+ bib["title"] or @log.add("Bibliography", c, "Reference #{id} is missing a title")
27
+ bib["docid"] or @log.add("Bibliography", c, "Reference #{id} is missing a document identifier (docid)")
28
+ end
29
+
30
+ def extract_from_p(tag, bib, key)
31
+ return unless bib[tag]
32
+ "<#{key}>#{bib[tag].at('p').children}</#{key}>"
33
+ end
34
+
35
+ # if the content is a single paragraph, replace it with its children
36
+ # single links replaced with uri
37
+ def p_unwrap(p)
38
+ elems = p.elements
39
+ if elems.size == 1 && elems[0].name == "p"
40
+ link_unwrap(elems[0]).children.to_xml.strip
41
+ else
42
+ p.to_xml.strip
43
+ end
44
+ end
45
+
46
+ def link_unwrap(p)
47
+ elems = p.elements
48
+ if elems.size == 1 && elems[0].name == "link"
49
+ p.at("./link").replace(elems[0]["target"].strip)
50
+ end
51
+ p
52
+ end
53
+
54
+ def dd_bib_extract(dtd)
55
+ return nil if dtd.children.empty?
56
+ dtd.at("./dl") and return dl_bib_extract(dtd)
57
+ elems = dtd.remove.elements
58
+ return p_unwrap(dtd) unless elems.size == 1 && %w(ol ul).include?(elems[0].name)
59
+ ret = []
60
+ elems[0].xpath("./li").each do |li|
61
+ ret << p_unwrap(li)
62
+ end
63
+ ret
64
+ end
65
+
66
+ def add_to_hash(bib, key, val)
67
+ Metanorma::Utils::set_nested_value(bib, key.split(/\./), val)
68
+ end
69
+
70
+ # definition list, with at most one level of unordered lists
71
+ def dl_bib_extract(c, nested = false)
72
+ dl = c.at("./dl") or return
73
+ bib = {}
74
+ key = ""
75
+ dl.xpath("./dt | ./dd").each do |dtd|
76
+ dtd.name == "dt" and key = dtd.text.sub(/:+$/, "") or add_to_hash(bib, key, dd_bib_extract(dtd))
77
+ end
78
+ c.xpath("./clause").each do |c1|
79
+ key = c1&.at("./title")&.text&.downcase&.strip
80
+ next unless %w(contributor relation series).include? key
81
+ add_to_hash(bib, key, dl_bib_extract(c1, true))
82
+ end
83
+ if !nested and c.at("./title")
84
+ title = c.at("./title").remove.children.to_xml
85
+ bib["title"] = [bib["title"]] if bib["title"].is_a? Hash
86
+ bib["title"] = [bib["title"]] if bib["title"].is_a? String
87
+ bib["title"] = [] unless bib["title"]
88
+ bib["title"] << title if !title.empty?
89
+ end
90
+ bib
91
+ end
92
+ end
93
+ end
94
+ end
@@ -62,10 +62,15 @@ module Asciidoctor
62
62
  end
63
63
  end
64
64
 
65
+ def make_indexsect(x, s)
66
+ x.xpath("//sections/indexsect").reverse_each { |r| s.next = r.remove }
67
+ end
68
+
65
69
  def sections_order_cleanup(x)
66
70
  s = x.at("//sections")
67
71
  make_preface(x, s)
68
72
  make_annexes(x)
73
+ make_indexsect(x, s)
69
74
  make_bibliography(x, s)
70
75
  x.xpath("//sections/annex").reverse_each { |r| s.next = r.remove }
71
76
  end
@@ -97,7 +97,7 @@ module Asciidoctor
97
97
  termdocsource_cleanup(xmldoc)
98
98
  end
99
99
 
100
- # Indices sort after letter but before any following
100
+ # Indices sort after letter but before any following
101
101
  # letter (x, x_m, x_1, xa); we use colon to force that sort order.
102
102
  # Numbers sort *after* letters; we use thorn to force that sort order.
103
103
  def symbol_key(x)
@@ -107,7 +107,7 @@ module Asciidoctor
107
107
  n.replace(grkletters(MathML2AsciiMath.m2a(n.to_xml)))
108
108
  end
109
109
  ret = Nokogiri::XML(key.to_xml)
110
- HTMLEntities.new.decode(ret.text).
110
+ HTMLEntities.new.decode(ret.text.downcase).
111
111
  gsub(/[\[\]\{\}<>\(\)]/, "").gsub(/\s/m, "").
112
112
  gsub(/[[:punct:]]|[_^]/, ":\\0").gsub(/`/, "").
113
113
  gsub(/[0-9]+/, "þ\\0")
@@ -14,7 +14,6 @@ require "asciidoctor/standoc/utils"
14
14
  require "asciidoctor/standoc/cleanup"
15
15
  require "asciidoctor/standoc/reqt"
16
16
  require_relative "./macros.rb"
17
- require_relative "./log.rb"
18
17
 
19
18
  module Asciidoctor
20
19
  module Standoc
@@ -93,7 +93,7 @@ module Asciidoctor
93
93
  end
94
94
 
95
95
  def metadata_script(node, xml)
96
- xml.script (node.attr("script") || "Latn")
96
+ xml.script (node.attr("script") || default_script(node.attr("language")))
97
97
  end
98
98
 
99
99
  def relaton_relations
@@ -186,7 +186,7 @@ module Asciidoctor
186
186
  ["en"].each do |lang|
187
187
  at = { language: lang, format: "text/plain" }
188
188
  xml.title **attr_code(at) do |t|
189
- t << (Utils::asciidoc_sub(node.attr("title") ||
189
+ t << (Metanorma::Utils::asciidoc_sub(node.attr("title") ||
190
190
  node.attr("title-en")) || node.title)
191
191
  end
192
192
  end
@@ -145,6 +145,10 @@ module Asciidoctor
145
145
  end
146
146
  end
147
147
 
148
+ def highlight_parse(text, xml)
149
+ xml << text
150
+ end
151
+
148
152
  def inline_quoted(node)
149
153
  noko do |xml|
150
154
  case node.type
@@ -157,6 +161,7 @@ module Asciidoctor
157
161
  when :subscript then xml.sub { |s| s << node.text }
158
162
  when :asciimath then stem_parse(node.text, xml, :asciimath)
159
163
  when :latexmath then stem_parse(node.text, xml, :latexmath)
164
+ when :mark then highlight_parse(node.text, xml)
160
165
  else
161
166
  case node.role
162
167
  # the following three are legacy, they are now handled by macros
@@ -175,26 +180,13 @@ module Asciidoctor
175
180
  end.join
176
181
  end
177
182
 
178
- def datauri(uri)
179
- return uri if /^data:/.match(uri)
180
- types = MIME::Types.type_for(@localdir + uri)
181
- type = types ? types.first.to_s : 'text/plain; charset="utf-8"'
182
- # FIXME: nested uri path error(
183
- # sources/plantuml/plantuml20200524-90467-1iqek5i.png ->
184
- # sources/sources/plantuml/plantuml20200524-90467-1iqek5i.png)
185
- path = File.file?(uri) ? uri : @localdir + uri
186
- bin = File.open(path, 'rb', &:read)
187
- data = Base64.strict_encode64(bin)
188
- "data:#{type};base64,#{data}"
189
- end
190
-
191
183
  def image_attributes(node)
192
184
  uri = node.image_uri (node.attr("target") || node.target)
193
- types = /^data:/.match(uri) ? datauri2mime(uri) : MIME::Types.type_for(uri)
185
+ types = /^data:/.match(uri) ? Metanorma::Utils::datauri2mime(uri) : MIME::Types.type_for(uri)
194
186
  type = types.first.to_s
195
187
  uri = uri.sub(%r{^data:image/\*;}, "data:#{type};")
196
- attr_code(src: uri, #@datauriimage ? datauri(uri) : uri,
197
- id: Utils::anchor_or_uuid,
188
+ attr_code(src: uri,
189
+ id: Metanorma::Utils::anchor_or_uuid,
198
190
  mimetype: type,
199
191
  height: node.attr("height") || "auto",
200
192
  width: node.attr("width") || "auto" ,
@@ -102,7 +102,7 @@
102
102
  </attribute>
103
103
  </optional>
104
104
  <oneOrMore>
105
- <ref name="li"/>
105
+ <ref name="ul_li"/>
106
106
  </oneOrMore>
107
107
  <zeroOrMore>
108
108
  <ref name="note"/>
@@ -789,6 +789,9 @@
789
789
  <attribute name="width"/>
790
790
  </element>
791
791
  </define>
792
+ <define name="BibItemType" combine="choice">
793
+ <value>internal</value>
794
+ </define>
792
795
  <define name="TextElement" combine="choice">
793
796
  <ref name="concept"/>
794
797
  </define>
@@ -809,6 +812,8 @@
809
812
  <ref name="requirement"/>
810
813
  <ref name="recommendation"/>
811
814
  <ref name="permission"/>
815
+ <ref name="imagemap"/>
816
+ <ref name="svgmap"/>
812
817
  </choice>
813
818
  </define>
814
819
  <define name="bibliography">
@@ -914,6 +919,9 @@
914
919
  </choice>
915
920
  </attribute>
916
921
  <ref name="bibdata"/>
922
+ <optional>
923
+ <ref name="misccontainer"/>
924
+ </optional>
917
925
  <optional>
918
926
  <ref name="boilerplate"/>
919
927
  </optional>
@@ -924,11 +932,21 @@
924
932
  <zeroOrMore>
925
933
  <ref name="annex"/>
926
934
  </zeroOrMore>
935
+ <optional>
936
+ <ref name="bibliography"/>
937
+ </optional>
927
938
  <zeroOrMore>
928
- <ref name="references"/>
939
+ <ref name="indexsect"/>
929
940
  </zeroOrMore>
930
941
  </element>
931
942
  </define>
943
+ <define name="misccontainer">
944
+ <element name="misc-container">
945
+ <oneOrMore>
946
+ <ref name="AnyElement"/>
947
+ </oneOrMore>
948
+ </element>
949
+ </define>
932
950
  <define name="preface">
933
951
  <element name="preface">
934
952
  <oneOrMore>
@@ -952,6 +970,11 @@
952
970
  <ref name="Content-Section"/>
953
971
  </element>
954
972
  </define>
973
+ <define name="indexsect">
974
+ <element name="indexsect">
975
+ <ref name="Content-Section"/>
976
+ </element>
977
+ </define>
955
978
  <define name="boilerplate">
956
979
  <element name="boilerplate">
957
980
  <optional>
@@ -1632,4 +1655,87 @@
1632
1655
  <text/>
1633
1656
  </element>
1634
1657
  </define>
1658
+ <define name="imagemap">
1659
+ <element name="imagemap">
1660
+ <ref name="figure"/>
1661
+ <zeroOrMore>
1662
+ <element name="area">
1663
+ <attribute name="type">
1664
+ <choice>
1665
+ <value>rect</value>
1666
+ <value>circle</value>
1667
+ <value>ellipse</value>
1668
+ <value>poly</value>
1669
+ </choice>
1670
+ </attribute>
1671
+ <choice>
1672
+ <ref name="xref"/>
1673
+ <ref name="hyperlink"/>
1674
+ <ref name="eref"/>
1675
+ </choice>
1676
+ <oneOrMore>
1677
+ <element name="coords">
1678
+ <attribute name="x">
1679
+ <data type="float"/>
1680
+ </attribute>
1681
+ <attribute name="y">
1682
+ <data type="float"/>
1683
+ </attribute>
1684
+ </element>
1685
+ </oneOrMore>
1686
+ <optional>
1687
+ <element name="radius">
1688
+ <attribute name="x">
1689
+ <data type="float"/>
1690
+ </attribute>
1691
+ <optional>
1692
+ <attribute name="y">
1693
+ <data type="float"/>
1694
+ </attribute>
1695
+ </optional>
1696
+ </element>
1697
+ </optional>
1698
+ </element>
1699
+ </zeroOrMore>
1700
+ </element>
1701
+ </define>
1702
+ <define name="svgmap">
1703
+ <element name="svgmap">
1704
+ <ref name="figure"/>
1705
+ <zeroOrMore>
1706
+ <element name="target">
1707
+ <attribute name="href">
1708
+ <data type="anyURI"/>
1709
+ </attribute>
1710
+ <choice>
1711
+ <ref name="xref"/>
1712
+ <ref name="hyperlink"/>
1713
+ <ref name="eref"/>
1714
+ </choice>
1715
+ </element>
1716
+ </zeroOrMore>
1717
+ </element>
1718
+ </define>
1719
+ <define name="ul_li">
1720
+ <element name="li">
1721
+ <optional>
1722
+ <attribute name="id">
1723
+ <data type="ID"/>
1724
+ </attribute>
1725
+ </optional>
1726
+ <optional>
1727
+ <attribute name="uncheckedcheckbox">
1728
+ <data type="boolean"/>
1729
+ </attribute>
1730
+ </optional>
1731
+ <optional>
1732
+ <attribute name="checkedcheckbox">
1733
+ <data type="boolean"/>
1734
+ </attribute>
1735
+ </optional>
1736
+ <oneOrMore>
1737
+ <ref name="BasicBlock"/>
1738
+ </oneOrMore>
1739
+ </element>
1740
+ </define>
1635
1741
  </grammar>