metanorma-standoc 1.9.2 → 1.10.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/rake.yml +3 -13
  3. data/.hound.yml +3 -1
  4. data/.rubocop.yml +4 -6
  5. data/lib/asciidoctor/standoc/base.rb +3 -1
  6. data/lib/asciidoctor/standoc/biblio.rng +1 -0
  7. data/lib/asciidoctor/standoc/blocks.rb +1 -1
  8. data/lib/asciidoctor/standoc/cleanup.rb +34 -15
  9. data/lib/asciidoctor/standoc/cleanup_block.rb +0 -1
  10. data/lib/asciidoctor/standoc/cleanup_boilerplate.rb +2 -2
  11. data/lib/asciidoctor/standoc/cleanup_footnotes.rb +0 -1
  12. data/lib/asciidoctor/standoc/cleanup_inline.rb +117 -77
  13. data/lib/asciidoctor/standoc/cleanup_maths.rb +0 -1
  14. data/lib/asciidoctor/standoc/cleanup_ref.rb +7 -0
  15. data/lib/asciidoctor/standoc/cleanup_section.rb +73 -137
  16. data/lib/asciidoctor/standoc/cleanup_section_names.rb +75 -0
  17. data/lib/asciidoctor/standoc/cleanup_terms.rb +19 -18
  18. data/lib/asciidoctor/standoc/converter.rb +1 -0
  19. data/lib/asciidoctor/standoc/front.rb +1 -2
  20. data/lib/asciidoctor/standoc/front_contributor.rb +66 -42
  21. data/lib/asciidoctor/standoc/inline.rb +45 -34
  22. data/lib/asciidoctor/standoc/isodoc.rng +66 -10
  23. data/lib/asciidoctor/standoc/macros.rb +7 -5
  24. data/lib/asciidoctor/standoc/macros_plantuml.rb +21 -23
  25. data/lib/asciidoctor/standoc/macros_terms.rb +60 -23
  26. data/lib/asciidoctor/standoc/section.rb +19 -12
  27. data/lib/asciidoctor/standoc/term_lookup_cleanup.rb +87 -33
  28. data/lib/asciidoctor/standoc/terms.rb +1 -1
  29. data/lib/asciidoctor/standoc/utils.rb +0 -1
  30. data/lib/asciidoctor/standoc/validate.rb +22 -8
  31. data/lib/isodoc/html/html_titlepage.html +81 -0
  32. data/lib/isodoc/html/htmlstyle.css +983 -0
  33. data/lib/isodoc/html/htmlstyle.scss +714 -0
  34. data/lib/isodoc/html/scripts.html +71 -0
  35. data/lib/metanorma/standoc/processor.rb +16 -7
  36. data/lib/metanorma/standoc/version.rb +1 -1
  37. data/metanorma-standoc.gemspec +3 -3
  38. data/spec/asciidoctor/base_spec.rb +697 -557
  39. data/spec/asciidoctor/blocks_spec.rb +6 -8
  40. data/spec/asciidoctor/cleanup_sections_spec.rb +14 -14
  41. data/spec/asciidoctor/cleanup_spec.rb +899 -688
  42. data/spec/asciidoctor/inline_spec.rb +62 -14
  43. data/spec/asciidoctor/isobib_cache_spec.rb +4 -6
  44. data/spec/asciidoctor/lists_spec.rb +149 -137
  45. data/spec/asciidoctor/macros_json2text_spec.rb +1 -1
  46. data/spec/asciidoctor/macros_plantuml_spec.rb +8 -8
  47. data/spec/asciidoctor/macros_spec.rb +646 -169
  48. data/spec/asciidoctor/refs_dl_spec.rb +4 -4
  49. data/spec/asciidoctor/refs_spec.rb +1527 -1532
  50. data/spec/asciidoctor/section_spec.rb +58 -22
  51. data/spec/asciidoctor/table_spec.rb +6 -6
  52. data/spec/asciidoctor/validate_spec.rb +352 -304
  53. data/spec/spec_helper.rb +2 -0
  54. data/spec/vcr_cassettes/dated_iso_ref_joint_iso_iec.yml +49 -49
  55. data/spec/vcr_cassettes/isobib_get_123.yml +12 -12
  56. data/spec/vcr_cassettes/isobib_get_123_1.yml +27 -27
  57. data/spec/vcr_cassettes/isobib_get_123_1_fr.yml +35 -35
  58. data/spec/vcr_cassettes/isobib_get_123_2001.yml +14 -14
  59. data/spec/vcr_cassettes/isobib_get_124.yml +14 -14
  60. data/spec/vcr_cassettes/rfcbib_get_rfc8341.yml +14 -14
  61. data/spec/vcr_cassettes/separates_iev_citations_by_top_level_clause.yml +44 -44
  62. metadata +12 -11
  63. data/lib/liquid/custom_blocks/key_iterator.rb +0 -21
  64. data/lib/liquid/custom_blocks/with_json_nested_context.rb +0 -18
  65. data/lib/liquid/custom_blocks/with_yaml_nested_context.rb +0 -19
  66. data/lib/liquid/custom_filters/values.rb +0 -7
@@ -37,6 +37,7 @@ module Asciidoctor
37
37
  inline_macro Asciidoctor::Standoc::VariantInlineMacro
38
38
  inline_macro Asciidoctor::Standoc::FootnoteBlockInlineMacro
39
39
  inline_macro Asciidoctor::Standoc::TermRefInlineMacro
40
+ inline_macro Asciidoctor::Standoc::SymbolRefInlineMacro
40
41
  inline_macro Asciidoctor::Standoc::IndexXrefInlineMacro
41
42
  inline_macro Asciidoctor::Standoc::IndexRangeInlineMacro
42
43
  inline_macro Asciidoctor::Standoc::AddMacro
@@ -2,7 +2,6 @@ require "date"
2
2
  require "nokogiri"
3
3
  require "htmlentities"
4
4
  require "pathname"
5
- require "open-uri"
6
5
  require_relative "./front_contributor"
7
6
 
8
7
  module Asciidoctor
@@ -73,7 +72,7 @@ module Asciidoctor
73
72
  def datetypes
74
73
  %w{ published accessed created implemented obsoleted
75
74
  confirmed updated issued circulated unchanged received
76
- vote-started vote-ended }
75
+ vote-started vote-ended announced }
77
76
  end
78
77
 
79
78
  def metadata_date(node, xml)
@@ -2,7 +2,6 @@ require "date"
2
2
  require "nokogiri"
3
3
  require "htmlentities"
4
4
  require "pathname"
5
- require "open-uri"
6
5
  require "csv"
7
6
 
8
7
  module Asciidoctor
@@ -10,13 +9,13 @@ module Asciidoctor
10
9
  module Front
11
10
  def committee_component(compname, node, out)
12
11
  out.send compname.gsub(/-/, "_"), node.attr(compname),
13
- **attr_code(number: node.attr("#{compname}-number"),
14
- type: node.attr("#{compname}-type"))
12
+ **attr_code(number: node.attr("#{compname}-number"),
13
+ type: node.attr("#{compname}-type"))
15
14
  i = 2
16
- while node.attr(compname+"_#{i}") do
17
- out.send compname.gsub(/-/, "_"), node.attr(compname+"_#{i}"),
18
- **attr_code(number: node.attr("#{compname}-number_#{i}"),
19
- type: node.attr("#{compname}-type_#{i}"))
15
+ while node.attr(compname + "_#{i}")
16
+ out.send compname.gsub(/-/, "_"), node.attr(compname + "_#{i}"),
17
+ **attr_code(number: node.attr("#{compname}-number_#{i}"),
18
+ type: node.attr("#{compname}-type_#{i}"))
20
19
  i += 1
21
20
  end
22
21
  end
@@ -32,34 +31,36 @@ module Asciidoctor
32
31
  is_pub && node and org_address(node, org)
33
32
  end
34
33
 
35
- def org_address(node, p)
36
- node.attr("pub-address") and p.address do |ad|
34
+ def org_address(node, person)
35
+ node.attr("pub-address") and person.address do |ad|
37
36
  ad.formattedAddress do |f|
38
37
  f << node.attr("pub-address").gsub(/ \+\n/, "<br/>")
39
38
  end
40
39
  end
41
- node.attr("pub-phone") and p.phone node.attr("pub-phone")
42
- node.attr("pub-fax") and p.phone node.attr("pub-fax"), **{type: "fax"}
43
- node.attr("pub-email") and p.email node.attr("pub-email")
44
- node.attr("pub-uri") and p.uri node.attr("pub-uri")
40
+ node.attr("pub-phone") and person.phone node.attr("pub-phone")
41
+ node.attr("pub-fax") and
42
+ person.phone node.attr("pub-fax"), **{ type: "fax" }
43
+ node.attr("pub-email") and person.email node.attr("pub-email")
44
+ node.attr("pub-uri") and person.uri node.attr("pub-uri")
45
45
  end
46
46
 
47
47
  # , " => ," : CSV definition does not deal with space followed by quote
48
48
  # at start of field
49
- def csv_split(s, delim = ";")
50
- return if s.nil?
51
- CSV.parse_line(s&.gsub(/#{delim} "(?!")/, "#{delim}\""),
49
+ def csv_split(text, delim = ";")
50
+ return if text.nil?
51
+
52
+ CSV.parse_line(text&.gsub(/#{delim} "(?!")/, "#{delim}\""),
52
53
  liberal_parsing: true,
53
- col_sep: delim)&.compact&.map { |x| x.strip }
54
+ col_sep: delim)&.compact&.map(&:strip)
54
55
  end
55
56
 
56
57
  def metadata_author(node, xml)
57
- csv_split(node.attr("publisher") || default_publisher || "")&.
58
- each do |p|
58
+ csv_split(node.attr("publisher") || default_publisher || "")
59
+ &.each do |p|
59
60
  xml.contributor do |c|
60
61
  c.role **{ type: "author" }
61
62
  c.organization do |a|
62
- organization(a, p, false, node, !node.attr("publisher"))
63
+ organization(a, p, false, node, !node.attr("publisher"))
63
64
  end
64
65
  end
65
66
  end
@@ -76,17 +77,18 @@ module Asciidoctor
76
77
  end
77
78
  end
78
79
 
79
- def personal_role(node, c, suffix)
80
- c.role **{ type: node.attr("role#{suffix}")&.downcase || "author" }
80
+ def personal_role(node, contrib, suffix)
81
+ type = node.attr("role#{suffix}")&.downcase || "author"
82
+ contrib.role **{ type: type }
81
83
  end
82
84
 
83
- def personal_contact(node, suffix, p)
84
- node.attr("phone#{suffix}") and p.phone node.attr("phone#{suffix}")
85
+ def personal_contact(node, suffix, person)
86
+ node.attr("phone#{suffix}") and person.phone node.attr("phone#{suffix}")
85
87
  node.attr("fax#{suffix}") and
86
- p.phone node.attr("fax#{suffix}"), **{type: "fax"}
87
- node.attr("email#{suffix}") and p.email node.attr("email#{suffix}")
88
+ person.phone node.attr("fax#{suffix}"), **{ type: "fax" }
89
+ node.attr("email#{suffix}") and person.email node.attr("email#{suffix}")
88
90
  node.attr("contributor-uri#{suffix}") and
89
- p.uri node.attr("contributor-uri#{suffix}")
91
+ person.uri node.attr("contributor-uri#{suffix}")
90
92
  end
91
93
 
92
94
  def personal_author1(node, xml, suffix)
@@ -100,8 +102,8 @@ module Asciidoctor
100
102
  end
101
103
  end
102
104
 
103
- def person_name(node, xml, suffix, p)
104
- p.name do |n|
105
+ def person_name(node, _xml, suffix, person)
106
+ person.name do |n|
105
107
  if node.attr("fullname#{suffix}")
106
108
  n.completename node.attr("fullname#{suffix}")
107
109
  else
@@ -112,21 +114,43 @@ module Asciidoctor
112
114
  end
113
115
  end
114
116
 
115
- def person_affiliation(node, xml, suffix, p)
116
- node.attr("affiliation#{suffix}") and p.affiliation do |a|
117
+ def person_affiliation(node, _xml, suffix, person)
118
+ node.attr("affiliation#{suffix}") and person.affiliation do |a|
117
119
  a.organization do |o|
118
- o.name node.attr("affiliation#{suffix}")
119
- a = node.attr("affiliation_subdiv#{suffix}")
120
- abbr = node.attr("affiliation_abbrev#{suffix}") and o.abbreviation abbr
121
- csv_split(node.attr("affiliation_subdiv#{suffix}"))&.each do |s|
122
- o.subdivision s
123
- end
124
- node.attr("address#{suffix}") and o.address do |ad|
125
- ad.formattedAddress do |f|
126
- f << node.attr("address#{suffix}").gsub(/ \+\n/, "<br/>")
127
- end
120
+ person_organization(node, suffix, o)
121
+ end
122
+ end
123
+ end
124
+
125
+ def person_organization(node, suffix, xml)
126
+ xml.name node.attr("affiliation#{suffix}")
127
+ abbr = node.attr("affiliation_abbrev#{suffix}") and
128
+ xml.abbreviation abbr
129
+ csv_split(node.attr("affiliation_subdiv#{suffix}"))&.each do |s|
130
+ xml.subdivision s
131
+ end
132
+ person_address(node, suffix, xml)
133
+ end
134
+
135
+ def person_address(node, suffix, xml)
136
+ if node.attr("address#{suffix}")
137
+ xml.address do |ad|
138
+ ad.formattedAddress do |f|
139
+ f << node.attr("address#{suffix}").gsub(/ \+\n/, "<br/>")
128
140
  end
129
141
  end
142
+ elsif node.attr("country#{suffix}") || node.attr("city#{suffix}")
143
+ person_address_components(node, suffix, xml)
144
+ end
145
+ end
146
+
147
+ def person_address_components(node, suffix, xml)
148
+ xml.address do |ad|
149
+ s = node.attr("street#{suffix}") and ad.street s
150
+ s = node.attr("city#{suffix}") and ad.city s
151
+ s = node.attr("state#{suffix}") and ad.state s
152
+ s = node.attr("country#{suffix}") and ad.country s
153
+ s = node.attr("postcode#{suffix}") and ad.postcode s
130
154
  end
131
155
  end
132
156
 
@@ -135,7 +159,7 @@ module Asciidoctor
135
159
  end
136
160
 
137
161
  def org_abbrev
138
- { }
162
+ {}
139
163
  end
140
164
 
141
165
  def metadata_publisher(node, xml)
@@ -9,8 +9,8 @@ require "latexmath"
9
9
  module Asciidoctor
10
10
  module Standoc
11
11
  module Inline
12
- def refid?(x)
13
- @refids.include? x
12
+ def refid?(ref)
13
+ @refids.include? ref
14
14
  end
15
15
 
16
16
  def inline_anchor(node)
@@ -46,19 +46,20 @@ module Asciidoctor
46
46
  def inline_anchor_xref_attrs(node)
47
47
  m = /^(?<drop>droploc%)?(?<case>capital%|lowercase%)?(?<drop2>droploc%)?
48
48
  (?<fn>fn:?\s*)?(?<text>.*)$/x.match node.text
49
- casing = m.nil? ? nil : m[:case]&.sub(/%$/, "")
50
- droploc = m.nil? ? nil : ((m[:drop].nil? && m[:drop2].nil?) ? nil: true)
51
- f = (m.nil? || m[:fn].nil?) ? "inline" : "footnote"
52
- c = (!m.nil? && (%i[case fn drop drop2].any? { |x| !m[x].nil? })) ?
53
- m[:text] : node.text
54
49
  t = node.target.gsub(/^#/, "").gsub(%r{(\.xml|\.adoc)(#.*$)}, "\\2")
55
- { target: t, type: f, case: casing, droploc: droploc, text: c }
50
+ m.nil? and return { target: t, type: "inline", text: node.text }
51
+ droploc = m[:drop].nil? && m[:drop2].nil? ? nil : true
52
+ f = m[:fn].nil? ? "inline" : "footnote"
53
+ c = %i[case fn drop drop2].any? { |x| !m[x].nil? } ? m[:text] : node.text
54
+ { target: t, type: f, case: m[:case]&.sub(/%$/, ""), droploc: droploc,
55
+ text: c }
56
56
  end
57
57
 
58
58
  def inline_anchor_link(node)
59
59
  contents = node.text
60
60
  contents = "" if node.target.gsub(%r{^mailto:}, "") == node.text
61
- attributes = { "target": node.target, "alt": node.attr("title") }
61
+ attributes = { "target": node.target, "alt": node.attr("title"),
62
+ "updatetype": node.attr("updatetype") }
62
63
  noko do |xml|
63
64
  xml.link **attr_code(attributes) do |l|
64
65
  l << contents
@@ -67,8 +68,8 @@ module Asciidoctor
67
68
  end
68
69
 
69
70
  def inline_anchor_bibref(node)
70
- eref_contents = (node.text || node.target || node.id)&.
71
- sub(/^\[?([^\[\]]+?)\]?$/, "[\\1]")
71
+ eref_contents = (node.text || node.target || node.id)
72
+ &.sub(/^\[?([^\[\]]+?)\]?$/, "[\\1]")
72
73
  eref_attributes = { id: node.target || node.id }
73
74
  @refids << (node.target || node.id)
74
75
  noko do |xml|
@@ -105,7 +106,7 @@ module Asciidoctor
105
106
  attrs = {}
106
107
  node.option?("landscape") and attrs[:orientation] = "landscape"
107
108
  node.option?("portrait") and attrs[:orientation] = "portrait"
108
- noko { |xml| xml.pagebreak **attr_code(attrs)}.join
109
+ noko { |xml| xml.pagebreak **attr_code(attrs) }.join
109
110
  end
110
111
 
111
112
  def thematic_break(_node)
@@ -113,41 +114,45 @@ module Asciidoctor
113
114
  end
114
115
 
115
116
  def xml_encode(text)
116
- HTMLEntities.new.encode(text, :basic, :hexadecimal).
117
- gsub(/&amp;gt;/, ">").gsub(/\&amp;lt;/, "<").gsub(/&amp;amp;/, "&").
118
- gsub(/&gt;/, ">").gsub(/&lt;/, "<").gsub(/&amp;/, "&").
119
- gsub(/&quot;/, '"').gsub(/&#xa;/, "\n").gsub(/&amp;#/, "&#")
117
+ HTMLEntities.new.encode(text, :basic, :hexadecimal)
118
+ .gsub(/&amp;gt;/, ">").gsub(/&amp;lt;/, "<").gsub(/&amp;amp;/, "&")
119
+ .gsub(/&gt;/, ">").gsub(/&lt;/, "<").gsub(/&amp;/, "&")
120
+ .gsub(/&quot;/, '"').gsub(/&#xa;/, "\n").gsub(/&amp;#/, "&#")
120
121
  end
121
122
 
122
- def latex_parse(text)
123
+ def latex_parse1(text)
123
124
  lxm_input = Unicode2LaTeX.unicode2latex(HTMLEntities.new.decode(text))
124
125
  results = Latexmath.parse(lxm_input).to_mathml
125
126
  results.nil? and
126
- @log.add('Math', nil,
127
+ @log.add("Math", nil,
127
128
  "latexmlmath failed to process equation:\n#{lxm_input}")
128
129
  results&.sub(%r{<math ([^>]+ )?display="block"}, "<math \\1")
129
130
  end
130
131
 
131
132
  def stem_parse(text, xml, style)
132
133
  if /&lt;([^:>&]+:)?math(\s+[^>&]+)?&gt; |
133
- <([^:>&]+:)?math(\s+[^>&]+)?>/x.match text
134
+ <([^:>&]+:)?math(\s+[^>&]+)?>/x.match? text
134
135
  math = xml_encode(text)
135
136
  xml.stem math, **{ type: "MathML" }
136
- elsif style == :latexmath
137
- latex = latex_parse(text) or return xml.stem **{ type: "MathML" }
138
- xml.stem **{ type: "MathML" } do |s|
139
- math = Nokogiri::XML.fragment(latex.sub(/<\?[^>]+>/, "")).elements[0]
140
- math.delete("alttext")
141
- s.parent.children = math
142
- end
137
+ elsif style == :latexmath then latex_parse(text, xml)
143
138
  else
144
- xml.stem text&.gsub(/\&amp;#/, "&#"), **{ type: "AsciiMath" }
139
+ xml.stem text&.gsub(/&amp;#/, "&#"), **{ type: "AsciiMath" }
145
140
  end
146
141
  end
147
142
 
148
- def highlight_parse(text, xml)
149
- xml << text
143
+ def latex_parse(text, xml)
144
+ latex = latex_parse1(text) or return xml.stem **{ type: "MathML" }
145
+ xml.stem **{ type: "MathML" } do |s|
146
+ math = Nokogiri::XML.fragment(latex.sub(/<\?[^>]+>/, ""))
147
+ .elements[0]
148
+ math.delete("alttext")
149
+ s.parent.children = math
150
150
  end
151
+ end
152
+
153
+ def highlight_parse(text, xml)
154
+ xml << text
155
+ end
151
156
 
152
157
  def inline_quoted(node)
153
158
  noko do |xml|
@@ -182,14 +187,20 @@ module Asciidoctor
182
187
 
183
188
  def image_attributes(node)
184
189
  uri = node.image_uri (node.attr("target") || node.target)
185
- types = /^data:/.match(uri) ? Metanorma::Utils::datauri2mime(uri) : MIME::Types.type_for(uri)
190
+ types = if /^data:/.match?(uri) then Metanorma::Utils::datauri2mime(uri)
191
+ else MIME::Types.type_for(uri)
192
+ end
186
193
  type = types.first.to_s
187
194
  uri = uri.sub(%r{^data:image/\*;}, "data:#{type};")
188
- attr_code(src: uri,
195
+ image_attributes1(node, uri, type)
196
+ end
197
+
198
+ def image_attributes1(node, uri, type)
199
+ attr_code(src: uri,
189
200
  id: Metanorma::Utils::anchor_or_uuid,
190
201
  mimetype: type,
191
202
  height: node.attr("height") || "auto",
192
- width: node.attr("width") || "auto" ,
203
+ width: node.attr("width") || "auto",
193
204
  filename: node.attr("filename"),
194
205
  title: node.attr("titleattr"),
195
206
  alt: node.alt == node.attr("default-alt") ? nil : node.alt)
@@ -197,14 +208,14 @@ module Asciidoctor
197
208
 
198
209
  def inline_image(node)
199
210
  noko do |xml|
200
- xml.image **(image_attributes(node))
211
+ xml.image **image_attributes(node)
201
212
  end.join("")
202
213
  end
203
214
 
204
215
  def inline_indexterm(node)
205
216
  noko do |xml|
206
217
  node.type == :visible and xml << node.text
207
- terms = (node.attr("terms") || [node.text]).map { |x| xml_encode(x) }
218
+ terms = (node.attr("terms") || [node.text]).map { |x| xml_encode(x) }
208
219
  xml.index do |i|
209
220
  i.primary { |x| x << terms[0] }
210
221
  a = terms.dig(1) and i.secondary { |x| x << a }
@@ -45,6 +45,11 @@
45
45
  <optional>
46
46
  <attribute name="alt"/>
47
47
  </optional>
48
+ <optional>
49
+ <attribute name="updatetype">
50
+ <data type="boolean"/>
51
+ </attribute>
52
+ </optional>
48
53
  <text/>
49
54
  </element>
50
55
  </define>
@@ -199,6 +204,18 @@
199
204
  </zeroOrMore>
200
205
  </element>
201
206
  </define>
207
+ <define name="dt">
208
+ <element name="dt">
209
+ <optional>
210
+ <attribute name="id">
211
+ <data type="ID"/>
212
+ </attribute>
213
+ </optional>
214
+ <zeroOrMore>
215
+ <ref name="TextElement"/>
216
+ </zeroOrMore>
217
+ </element>
218
+ </define>
202
219
  <define name="example">
203
220
  <element name="example">
204
221
  <attribute name="id">
@@ -543,6 +560,9 @@
543
560
  </define>
544
561
  <define name="BibDataExtensionType">
545
562
  <ref name="doctype"/>
563
+ <optional>
564
+ <ref name="docsubtype"/>
565
+ </optional>
546
566
  <optional>
547
567
  <ref name="editorialgroup"/>
548
568
  </optional>
@@ -890,6 +910,14 @@
890
910
  </define>
891
911
  </include>
892
912
  <!-- end overrides -->
913
+ <define name="docsubtype">
914
+ <element name="subdoctype">
915
+ <ref name="DocumentSubtype"/>
916
+ </element>
917
+ </define>
918
+ <define name="DocumentSubtype">
919
+ <text/>
920
+ </define>
893
921
  <define name="colgroup">
894
922
  <element name="colgroup">
895
923
  <oneOrMore>
@@ -939,7 +967,34 @@
939
967
  <define name="concept">
940
968
  <element name="concept">
941
969
  <optional>
942
- <attribute name="term"/>
970
+ <attribute name="ital">
971
+ <data type="boolean"/>
972
+ </attribute>
973
+ </optional>
974
+ <optional>
975
+ <attribute name="ref">
976
+ <data type="boolean"/>
977
+ </attribute>
978
+ </optional>
979
+ <optional>
980
+ <element name="refterm">
981
+ <zeroOrMore>
982
+ <choice>
983
+ <ref name="PureTextElement"/>
984
+ <ref name="stem"/>
985
+ </choice>
986
+ </zeroOrMore>
987
+ </element>
988
+ </optional>
989
+ <optional>
990
+ <element name="renderterm">
991
+ <zeroOrMore>
992
+ <choice>
993
+ <ref name="PureTextElement"/>
994
+ <ref name="stem"/>
995
+ </choice>
996
+ </zeroOrMore>
997
+ </element>
943
998
  </optional>
944
999
  <choice>
945
1000
  <ref name="eref"/>
@@ -965,6 +1020,9 @@
965
1020
  </attribute>
966
1021
  <attribute name="name"/>
967
1022
  <attribute name="action"/>
1023
+ <optional>
1024
+ <attribute name="class"/>
1025
+ </optional>
968
1026
  <zeroOrMore>
969
1027
  <choice>
970
1028
  <ref name="TextElement"/>
@@ -1191,9 +1249,7 @@
1191
1249
  </define>
1192
1250
  <define name="IsoWorkgroup">
1193
1251
  <optional>
1194
- <attribute name="number">
1195
- <data type="int"/>
1196
- </attribute>
1252
+ <attribute name="number"/>
1197
1253
  </optional>
1198
1254
  <optional>
1199
1255
  <attribute name="type"/>
@@ -1459,26 +1515,26 @@
1459
1515
  <optional>
1460
1516
  <ref name="section-title"/>
1461
1517
  </optional>
1462
- <group>
1518
+ <choice>
1463
1519
  <choice>
1464
1520
  <group>
1465
- <zeroOrMore>
1521
+ <oneOrMore>
1466
1522
  <ref name="BasicBlock"/>
1467
- </zeroOrMore>
1523
+ </oneOrMore>
1468
1524
  <zeroOrMore>
1469
1525
  <ref name="note"/>
1470
1526
  </zeroOrMore>
1471
1527
  </group>
1472
1528
  <ref name="amend"/>
1473
1529
  </choice>
1474
- <zeroOrMore>
1530
+ <oneOrMore>
1475
1531
  <choice>
1476
1532
  <ref name="clause-subsection"/>
1477
1533
  <ref name="terms"/>
1478
1534
  <ref name="definitions"/>
1479
1535
  </choice>
1480
- </zeroOrMore>
1481
- </group>
1536
+ </oneOrMore>
1537
+ </choice>
1482
1538
  </define>
1483
1539
  <define name="Annex-Section">
1484
1540
  <optional>