isodoc 1.0.23 → 1.0.28

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 (50) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/macos.yml +10 -2
  3. data/.github/workflows/ubuntu.yml +13 -3
  4. data/.github/workflows/windows.yml +10 -2
  5. data/isodoc.gemspec +1 -1
  6. data/lib/isodoc-yaml/i18n-en.yaml +3 -1
  7. data/lib/isodoc-yaml/i18n-fr.yaml +3 -1
  8. data/lib/isodoc-yaml/i18n-zh-Hans.yaml +3 -1
  9. data/lib/isodoc/base_style/reset.scss +1 -1
  10. data/lib/isodoc/convert.rb +1 -0
  11. data/lib/isodoc/function/blocks.rb +6 -1
  12. data/lib/isodoc/function/cleanup.rb +16 -2
  13. data/lib/isodoc/function/i18n.rb +5 -5
  14. data/lib/isodoc/function/inline.rb +77 -79
  15. data/lib/isodoc/function/inline_simple.rb +72 -0
  16. data/lib/isodoc/function/references.rb +49 -37
  17. data/lib/isodoc/function/section.rb +19 -8
  18. data/lib/isodoc/function/table.rb +0 -1
  19. data/lib/isodoc/function/to_word_html.rb +23 -13
  20. data/lib/isodoc/function/utils.rb +11 -5
  21. data/lib/isodoc/function/xref_gen.rb +2 -1
  22. data/lib/isodoc/function/xref_sect_gen.rb +24 -24
  23. data/lib/isodoc/headlesshtml_convert.rb +5 -0
  24. data/lib/isodoc/html_convert.rb +5 -0
  25. data/lib/isodoc/html_function/footnotes.rb +3 -3
  26. data/lib/isodoc/html_function/html.rb +15 -0
  27. data/lib/isodoc/html_function/postprocess.rb +6 -5
  28. data/lib/isodoc/metadata.rb +10 -3
  29. data/lib/isodoc/metadata_date.rb +19 -7
  30. data/lib/isodoc/pdf_convert.rb +5 -0
  31. data/lib/isodoc/version.rb +1 -1
  32. data/lib/isodoc/word_convert.rb +5 -0
  33. data/lib/isodoc/word_function/body.rb +0 -4
  34. data/lib/isodoc/word_function/footnotes.rb +3 -3
  35. data/lib/isodoc/word_function/postprocess.rb +13 -2
  36. data/lib/isodoc/xslfo_convert.rb +5 -0
  37. data/spec/assets/i18n.yaml +4 -1
  38. data/spec/isodoc/blocks_spec.rb +59 -8
  39. data/spec/isodoc/cleanup_spec.rb +317 -25
  40. data/spec/isodoc/footnotes_spec.rb +20 -5
  41. data/spec/isodoc/i18n_spec.rb +12 -12
  42. data/spec/isodoc/inline_spec.rb +118 -5
  43. data/spec/isodoc/metadata_spec.rb +8 -3
  44. data/spec/isodoc/postproc_spec.rb +34 -12
  45. data/spec/isodoc/ref_spec.rb +120 -51
  46. data/spec/isodoc/section_spec.rb +236 -207
  47. data/spec/isodoc/table_spec.rb +24 -24
  48. data/spec/isodoc/terms_spec.rb +50 -6
  49. data/spec/isodoc/xref_spec.rb +53 -26
  50. metadata +5 -4
@@ -0,0 +1,72 @@
1
+ module IsoDoc::Function
2
+ module Inline
3
+ def section_break(body)
4
+ body.br
5
+ end
6
+
7
+ def page_break(out)
8
+ out.br
9
+ end
10
+
11
+ def pagebreak_parse(_node, out)
12
+ out.br
13
+ end
14
+
15
+ def hr_parse(node, out)
16
+ out.hr
17
+ end
18
+
19
+ def br_parse(node, out)
20
+ out.br
21
+ end
22
+
23
+ def index_parse(node, out)
24
+ end
25
+
26
+ def bookmark_parse(node, out)
27
+ out.a **attr_code(id: node["id"])
28
+ end
29
+
30
+ def keyword_parse(node, out)
31
+ out.span **{ class: "keyword" } do |s|
32
+ node.children.each { |n| parse(n, s) }
33
+ end
34
+ end
35
+
36
+ def em_parse(node, out)
37
+ out.i do |e|
38
+ node.children.each { |n| parse(n, e) }
39
+ end
40
+ end
41
+
42
+ def strong_parse(node, out)
43
+ out.b do |e|
44
+ node.children.each { |n| parse(n, e) }
45
+ end
46
+ end
47
+
48
+ def sup_parse(node, out)
49
+ out.sup do |e|
50
+ node.children.each { |n| parse(n, e) }
51
+ end
52
+ end
53
+
54
+ def sub_parse(node, out)
55
+ out.sub do |e|
56
+ node.children.each { |n| parse(n, e) }
57
+ end
58
+ end
59
+
60
+ def tt_parse(node, out)
61
+ out.tt do |e|
62
+ node.children.each { |n| parse(n, e) }
63
+ end
64
+ end
65
+
66
+ def strike_parse(node, out)
67
+ out.s do |e|
68
+ node.children.each { |n| parse(n, e) }
69
+ end
70
+ end
71
+ end
72
+ end
@@ -5,30 +5,30 @@ module IsoDoc::Function
5
5
  # references anyway; keeping here instead of in IsoDoc::Iso for now
6
6
  def docid_l10n(x)
7
7
  return x if x.nil?
8
- x.gsub(/All Parts/i, @all_parts_lbl.downcase)
8
+ x.gsub(/All Parts/i, @all_parts_lbl.downcase) if @all_parts_lbl
9
9
  end
10
10
 
11
11
  # TODO generate formatted ref if not present
12
- def nonstd_bibitem(list, b, ordinal, bibliography)
13
- list.p **attr_code(iso_bibitem_entry_attrs(b, bibliography)) do |r|
14
- id = bibitem_ref_code(b)
15
- identifier = render_identifier(id)
16
- if bibliography then ref_entry_code(r, ordinal, identifier, id)
12
+ def nonstd_bibitem(list, b, ordinal, biblio)
13
+ list.p **attr_code(iso_bibitem_entry_attrs(b, biblio)) do |ref|
14
+ ids = bibitem_ref_code(b)
15
+ identifiers = render_identifier(ids)
16
+ if biblio then ref_entry_code(ref, ordinal, identifiers, ids)
17
17
  else
18
- identifier = "[#{identifier}]" if id["type"] == "metanorma"
19
- r << "#{identifier}, "
18
+ ref << "#{identifiers[0] || identifiers[1]}, "
19
+ ref << "#{identifiers[1]}, " if identifiers[0] && identifiers[1]
20
20
  end
21
- reference_format(b, r)
21
+ reference_format(b, ref)
22
22
  end
23
23
  end
24
24
 
25
25
  def std_bibitem_entry(list, b, ordinal, biblio)
26
26
  list.p **attr_code(iso_bibitem_entry_attrs(b, biblio)) do |ref|
27
- prefix_bracketed_ref(ref, ordinal) if biblio
28
- id = bibitem_ref_code(b)
29
- identifier = render_identifier(id)
30
- identifier = "[#{identifier}]" if id["type"] == "metanorma" && !biblio
31
- ref << identifier
27
+ ids = bibitem_ref_code(b)
28
+ identifiers = render_identifier(ids)
29
+ prefix_bracketed_ref(ref, "[#{ordinal}]") if biblio
30
+ ref << "#{identifiers[0] || identifiers[1]}"
31
+ ref << ", #{identifiers[1]}" if identifiers[0] && identifiers[1]
32
32
  date_note_process(b, ref)
33
33
  ref << ", "
34
34
  reference_format(b, ref)
@@ -38,29 +38,43 @@ module IsoDoc::Function
38
38
  # if t is just a number, only use that ([1] Non-Standard)
39
39
  # else, use both ordinal, as prefix, and t
40
40
  def ref_entry_code(r, ordinal, t, id)
41
- if id["type"] == "metanorma"
42
- prefix_bracketed_ref(r, t)
43
- else
44
- prefix_bracketed_ref(r, ordinal)
45
- if !t.empty? && !%w(DOI ISSN ISBN).include?(id["type"])
46
- r << "#{t}, "
47
- end
41
+ prefix_bracketed_ref(r, t[0] || "[#{ordinal}]")
42
+ if t[1]
43
+ r << "#{t[1]}, "
48
44
  end
49
45
  end
50
46
 
47
+ def pref_ref_code(b)
48
+ b.at(ns("./docidentifier[not(@type = 'DOI' or @type = 'metanorma' "\
49
+ "or @type = 'ISSN' or @type = 'ISBN' or @type = 'rfc-anchor')]"))
50
+ end
51
+
52
+ # returns [metanorma, non-metanorma, DOI/ISSN/ISBN] identifiers
51
53
  def bibitem_ref_code(b)
52
54
  id = b.at(ns("./docidentifier[@type = 'metanorma']"))
53
- id ||= b.at(ns("./docidentifier[not(@type = 'DOI' or @type = 'metanorma' "\
54
- "or @type = 'ISSN' or @type = 'ISBN')]"))
55
- id ||= b.at(ns("./docidentifier"))
56
- return id if id
55
+ id1 = pref_ref_code(b)
56
+ id2 = b.at(ns("./docidentifier[@type = 'DOI' or @type = 'ISSN' or @type = 'ISBN']"))
57
+ return [id, id1, id2] if id || id1 || id2
57
58
  id = Nokogiri::XML::Node.new("docidentifier", b.document)
58
59
  id << "(NO ID)"
59
- id
60
+ [nil, id, nil]
61
+ end
62
+
63
+ def bracket_if_num(x)
64
+ return nil if x.nil?
65
+ x = x.text.sub(/^\[/, "").sub(/\]$/, "")
66
+ return "[#{x}]" if /^\d+$/.match(x)
67
+ x
60
68
  end
61
69
 
62
70
  def render_identifier(id)
63
- docid_prefix(id["type"], id.text.sub(/^\[/, "").sub(/\]$/, ""))
71
+ [
72
+ bracket_if_num(id[0]),
73
+ id[1].nil? ? nil :
74
+ docid_prefix(id[1]["type"], id[1].text.sub(/^\[/, "").sub(/\]$/, "")),
75
+ id[2].nil? ? nil :
76
+ docid_prefix(id[2]["type"], id[2].text.sub(/^\[/, "").sub(/\]$/, "")),
77
+ ]
64
78
  end
65
79
 
66
80
  def docid_prefix(prefix, docid)
@@ -70,7 +84,7 @@ module IsoDoc::Function
70
84
 
71
85
  def omit_docid_prefix(prefix)
72
86
  return true if prefix.nil? || prefix.empty?
73
- return %w(ISO IEC ITU metanorma).include? prefix
87
+ return %w(ISO IEC ITU W3C metanorma).include? prefix
74
88
  end
75
89
 
76
90
  def date_note_process(b, ref)
@@ -100,7 +114,7 @@ module IsoDoc::Function
100
114
  end
101
115
 
102
116
  def prefix_bracketed_ref(ref, text)
103
- ref << "[#{text}]"
117
+ ref << text.to_s
104
118
  insert_tab(ref, 1)
105
119
  end
106
120
 
@@ -146,8 +160,7 @@ module IsoDoc::Function
146
160
  end
147
161
 
148
162
  def norm_ref(isoxml, out, num)
149
- q = "//bibliography/references[title = 'Normative References' or "\
150
- "title = 'Normative references']"
163
+ q = "//bibliography/references[@normative = 'true']"
151
164
  f = isoxml.at(ns(q)) or return num
152
165
  out.div do |div|
153
166
  num = num + 1
@@ -157,8 +170,8 @@ module IsoDoc::Function
157
170
  num
158
171
  end
159
172
 
160
- BIBLIOGRAPHY_XPATH = "//bibliography/clause[title = 'Bibliography'] | "\
161
- "//bibliography/references[title = 'Bibliography']".freeze
173
+ BIBLIOGRAPHY_XPATH = "//bibliography/clause[.//references[@normative = 'false']] | "\
174
+ "//bibliography/references[@normative = 'false']".freeze
162
175
 
163
176
  def bibliography(isoxml, out)
164
177
  f = isoxml.at(ns(BIBLIOGRAPHY_XPATH)) || return
@@ -188,12 +201,11 @@ module IsoDoc::Function
188
201
 
189
202
  def reference_names(ref)
190
203
  isopub = ref.at(ns(ISO_PUBLISHER_XPATH))
191
- docid = bibitem_ref_code(ref)
192
- prefix = docid["type"]
204
+ ids = bibitem_ref_code(ref)
205
+ identifiers = render_identifier(ids)
193
206
  date = ref.at(ns("./date[@type = 'published']"))
194
207
  allparts = ref.at(ns("./extent[@type='part'][referenceFrom='all']"))
195
- reference = format_ref(docid_l10n(docid.text), prefix, isopub, date,
196
- allparts)
208
+ reference = docid_l10n(identifiers[0] || identifiers[1])
197
209
  @anchors[ref["id"]] = { xref: reference }
198
210
  end
199
211
 
@@ -16,6 +16,7 @@ module IsoDoc::Function
16
16
  clausedelimspace(out)
17
17
  end
18
18
  c1&.children&.each { |c2| parse(c2, b) }
19
+ clausedelimspace(out) if /\S/.match(c1&.text)
19
20
  end
20
21
  end
21
22
  end
@@ -109,20 +110,29 @@ module IsoDoc::Function
109
110
  num
110
111
  end
111
112
 
112
- def terms_defs_title(f)
113
- symbols = f.at(ns(".//definitions"))
114
- return @termsdefsymbols_lbl if symbols
115
- @termsdef_lbl
116
- end
117
-
118
113
  TERM_CLAUSE = "//sections/terms | "\
119
114
  "//sections/clause[descendant::terms]".freeze
120
115
 
116
+ def term_def_title(title)
117
+ case title&.text
118
+ when "Terms, definitions, symbols and abbreviated terms"
119
+ @labels["termsdefsymbolsabbrev"]
120
+ when "Terms, definitions and symbols"
121
+ @labels["termsdefsymbols"]
122
+ when "Terms, definitions and abbreviated terms"
123
+ @labels["termsdefabbrev"]
124
+ when "Terms and definitions"
125
+ @labels["termsdef"]
126
+ else
127
+ title
128
+ end
129
+ end
130
+
121
131
  def terms_defs(isoxml, out, num)
122
132
  f = isoxml.at(ns(TERM_CLAUSE)) or return num
123
133
  out.div **attr_code(id: f["id"]) do |div|
124
134
  num = num + 1
125
- clause_name(num, terms_defs_title(f), div, nil)
135
+ clause_name(num, term_def_title(f&.at(ns("./title"))), div, nil)
126
136
  f.elements.each do |e|
127
137
  parse(e, div) unless %w{title source}.include? e.name
128
138
  end
@@ -198,7 +208,8 @@ module IsoDoc::Function
198
208
 
199
209
  def preface(isoxml, out)
200
210
  title_attr = { class: "IntroTitle" }
201
- isoxml.xpath(ns("//preface/clause")).each do |f|
211
+ isoxml.xpath(ns("//preface/clause | //preface/terms | //preface/definitions | "\
212
+ "//preface/references")).each do |f|
202
213
  page_break(out)
203
214
  out.div **{ class: "Section3", id: f["id"] } do |div|
204
215
  clause_name(nil, f&.at(ns("./title")), div, title_attr)
@@ -91,7 +91,6 @@ module IsoDoc::Function
91
91
  style += <<~STYLE
92
92
  border-top:#{row.zero? ? "#{SW} 1.5pt;" : 'none;'}
93
93
  border-bottom:#{SW} #{rowmax == totalrows ? '1.5' : '1.0'}pt;
94
- padding:0;
95
94
  STYLE
96
95
  header and scope = (td["colspan"] ? "colgroup" : "col")
97
96
  !header and td.name == "th" and scope =
@@ -21,7 +21,7 @@ module IsoDoc::Function
21
21
  filename = filepath.sub_ext('').to_s
22
22
  dir = "#{filename}_files"
23
23
  unless debug
24
- Dir.mkdir(dir) unless File.exists?(dir)
24
+ Dir.mkdir(dir, 0777) unless File.exists?(dir)
25
25
  FileUtils.rm_rf "#{dir}/*"
26
26
  end
27
27
  @filename = filename
@@ -79,7 +79,7 @@ module IsoDoc::Function
79
79
 
80
80
  def make_body3(body, docxml)
81
81
  body.div **{ class: "main-section" } do |div3|
82
- boilerplate docxml, div3
82
+ boilerplate docxml, div3
83
83
  abstract docxml, div3
84
84
  foreword docxml, div3
85
85
  introduction docxml, div3
@@ -102,6 +102,7 @@ module IsoDoc::Function
102
102
  @meta.relations isoxml, out
103
103
  @meta.version isoxml, out
104
104
  @meta.url isoxml, out
105
+ @meta.keywords isoxml, out
105
106
  @meta.get
106
107
  end
107
108
 
@@ -109,8 +110,15 @@ module IsoDoc::Function
109
110
  out.p(**{ class: "zzSTDTitle1" }) { |p| p << @meta.get[:doctitle] }
110
111
  end
111
112
 
113
+ def middle_admonitions(isoxml, out)
114
+ isoxml.xpath(ns("//sections/note | //sections/admonition")).each do |x|
115
+ parse(x, out)
116
+ end
117
+ end
118
+
112
119
  def middle(isoxml, out)
113
120
  middle_title(out)
121
+ middle_admonitions(isoxml, out)
114
122
  i = scope isoxml, out, 0
115
123
  i = norm_ref isoxml, out, i
116
124
  i = terms_defs isoxml, out, i
@@ -120,20 +128,20 @@ module IsoDoc::Function
120
128
  bibliography isoxml, out
121
129
  end
122
130
 
123
- def boilerplate(node, out)
124
- boilerplate = node.at(ns("//boilerplate")) or return
125
- out.div **{class: "authority"} do |s|
126
- boilerplate.children.each do |n|
127
- if n.name == "title"
128
- s.h1 do |h|
129
- n.children.each { |nn| parse(nn, h) }
130
- end
131
- else
132
- parse(n, s)
131
+ def boilerplate(node, out)
132
+ boilerplate = node.at(ns("//boilerplate")) or return
133
+ out.div **{class: "authority"} do |s|
134
+ boilerplate.children.each do |n|
135
+ if n.name == "title"
136
+ s.h1 do |h|
137
+ n.children.each { |nn| parse(nn, h) }
133
138
  end
139
+ else
140
+ parse(n, s)
134
141
  end
135
142
  end
136
143
  end
144
+ end
137
145
 
138
146
  def parse(node, out)
139
147
  if node.text?
@@ -157,7 +165,7 @@ module IsoDoc::Function
157
165
  when "clause" then clause_parse(node, out)
158
166
  when "xref" then xref_parse(node, out)
159
167
  when "eref" then eref_parse(node, out)
160
- when "origin" then eref_parse(node, out)
168
+ when "origin" then origin_parse(node, out)
161
169
  when "link" then link_parse(node, out)
162
170
  when "ul" then ul_parse(node, out)
163
171
  when "ol" then ol_parse(node, out)
@@ -210,6 +218,8 @@ module IsoDoc::Function
210
218
  when "license-statement" then license_parse(node, out)
211
219
  when "legal-statement" then legal_parse(node, out)
212
220
  when "feedback-statement" then feedback_parse(node, out)
221
+ when "passthrough" then passthrough_parse(node, out)
222
+ when "variant" then variant_parse(node, out)
213
223
  else
214
224
  error_parse(node, out)
215
225
  end
@@ -49,7 +49,12 @@ module IsoDoc::Function
49
49
  /^(\&[^ \t\r\n#;]+;)/.match(t) ?
50
50
  HTMLEntities.new.encode(HTMLEntities.new.decode(t), :hexadecimal) : t
51
51
  end.join("")
52
- Nokogiri::XML.parse(xml)
52
+ begin
53
+ Nokogiri::XML.parse(xml) { |config| config.strict }
54
+ rescue Nokogiri::XML::SyntaxError => e
55
+ File.open("#{@filename}.#{@format}.err", "w:UTF-8") { |f| f.write xml }
56
+ abort "Malformed Output XML for #{@format}: #{e} (see #{@filename}.#{@format}.err)"
57
+ end
53
58
  end
54
59
 
55
60
  def to_xhtml_fragment(xml)
@@ -64,7 +69,7 @@ module IsoDoc::Function
64
69
 
65
70
  CLAUSE_ANCESTOR =
66
71
  ".//ancestor::*[local-name() = 'annex' or "\
67
- "local-name() = 'acknowledgements' or "\
72
+ "local-name() = 'acknowledgements' or local-name() = 'term' or "\
68
73
  "local-name() = 'appendix' or local-name() = 'foreword' or "\
69
74
  "local-name() = 'introduction' or local-name() = 'terms' or "\
70
75
  "local-name() = 'clause' or local-name() = 'references']/@id".freeze
@@ -78,7 +83,7 @@ module IsoDoc::Function
78
83
  ".//ancestor::*[local-name() = 'annex' or "\
79
84
  "local-name() = 'foreword' or local-name() = 'appendix' or "\
80
85
  "local-name() = 'introduction' or local-name() = 'terms' or "\
81
- "local-name() = 'acknowledgements' or "\
86
+ "local-name() = 'acknowledgements' or local-name() = 'term' or "\
82
87
  "local-name() = 'clause' or local-name() = 'references' or "\
83
88
  "local-name() = 'figure' or local-name() = 'formula' or "\
84
89
  "local-name() = 'table' or local-name() = 'example']/@id".freeze
@@ -110,12 +115,13 @@ module IsoDoc::Function
110
115
  end
111
116
 
112
117
  def header_strip(h)
113
- h = h.to_s.gsub(%r{<br/>}, " ").sub(/<\/?h[123456][^>]*>/, "")
118
+ h = h.to_s.gsub(%r{<br\s*/>}, " ").gsub(/<\/?h[123456][^>]*>/, "").
119
+ gsub(/<\/?b[^>]*>/, "")
114
120
  h1 = to_xhtml_fragment(h.dup)
115
121
  h1.traverse do |x|
116
122
  x.replace(" ") if x.name == "span" && /mso-tab-count/.match(x["style"])
117
123
  x.remove if x.name == "span" && x["class"] == "MsoCommentReference"
118
- x.remove if x.name == "a" && x["epub:type"] == "footnote"
124
+ x.remove if x.name == "a" && x["class"] == "FootnoteRef"
119
125
  x.remove if x.name == "span" && /mso-bookmark/.match(x["style"])
120
126
  x.replace(x.children) if x.name == "a"
121
127
  end
@@ -40,6 +40,7 @@ module IsoDoc::Function
40
40
 
41
41
  SECTIONS_XPATH =
42
42
  "//foreword | //introduction | //acknowledgements | //preface/clause | "\
43
+ "//preface/terms | preface/definitions | preface/references | "\
43
44
  "//sections/terms | //annex | "\
44
45
  "//sections/clause | //sections/definitions | "\
45
46
  "//bibliography/references | //bibliography/clause".freeze
@@ -68,7 +69,7 @@ module IsoDoc::Function
68
69
  "not(self::xmlns:terms) and not(self::xmlns:definitions)]//"\
69
70
  "xmlns:example | ./xmlns:example".freeze
70
71
 
71
- CHILD_SECTIONS = "./clause | ./appendix | ./terms | ./definitions"
72
+ CHILD_SECTIONS = "./clause | ./appendix | ./terms | ./definitions | ./references"
72
73
 
73
74
  def example_anchor_names(sections)
74
75
  sections.each do |s|
@@ -5,10 +5,9 @@ module IsoDoc::Function
5
5
  annex_names(c, (65 + i).chr.to_s)
6
6
  end
7
7
  docxml.xpath(
8
- ns("//bibliography/clause[not(xmlns:title = 'Normative References' or "\
9
- "xmlns:title = 'Normative references')] |"\
10
- "//bibliography/references[not(xmlns:title = 'Normative References'"\
11
- " or xmlns:title = 'Normative references')]")).each do |b|
8
+ ns("//bibliography/clause[.//references[@normative = 'false']] | "\
9
+ "//bibliography/references[@normative = 'false']"
10
+ )).each do |b|
12
11
  preface_names(b)
13
12
  end
14
13
  docxml.xpath(ns("//bibitem[not(ancestor::bibitem)]")).each do |ref|
@@ -17,23 +16,13 @@ module IsoDoc::Function
17
16
  end
18
17
 
19
18
  def initial_anchor_names(d)
20
- preface_names(d.at(ns("//preface/abstract")))
21
- preface_names(d.at(ns("//foreword")))
22
- preface_names(d.at(ns("//introduction")))
23
- d.xpath(ns("//preface/clause")).each do |c|
24
- preface_names(c)
25
- end
26
- preface_names(d.at(ns("//acknowledgements")))
19
+ d.xpath(ns("//preface/*")).each { |c| c.element? and preface_names(c) }
27
20
  # potentially overridden in middle_section_asset_names()
28
- sequential_asset_names(
29
- d.xpath(ns("//preface/abstract | //foreword | //introduction | "\
30
- "//preface/clause | //acknowledgements")))
21
+ sequential_asset_names(d.xpath(ns("//preface/*")))
31
22
  n = section_names(d.at(ns("//clause[title = 'Scope']")), 0, 1)
32
23
  n = section_names(d.at(ns(
33
- "//bibliography/clause[title = 'Normative References' or "\
34
- "title = 'Normative references'] |"\
35
- "//bibliography/references[title = 'Normative References' or "\
36
- "title = 'Normative references']")), n, 1)
24
+ "//bibliography/clause[.//references[@normative = 'true']] | "\
25
+ "//bibliography/references[@normative = 'true']")), n, 1)
37
26
  n = section_names(d.at(ns("//sections/terms | "\
38
27
  "//sections/clause[descendant::terms]")), n, 1)
39
28
  n = section_names(d.at(ns("//sections/definitions")), n, 1)
@@ -76,10 +65,8 @@ module IsoDoc::Function
76
65
 
77
66
  def middle_section_asset_names(d)
78
67
  middle_sections = "//clause[title = 'Scope'] | "\
79
- "//references[title = 'Normative References' or title = "\
80
- "'Normative references'] | "\
81
- "//sections/terms | //preface/abstract | //foreword | "\
82
- "//introduction | //preface/clause | //acknowledgements "\
68
+ "//references[@normative = 'true'] | "\
69
+ "//sections/terms | //preface/* | "\
83
70
  "//sections/definitions | //clause[parent::sections]"
84
71
  sequential_asset_names(d.xpath(ns(middle_sections)))
85
72
  end
@@ -120,12 +107,25 @@ module IsoDoc::Function
120
107
  l10n("<b>#{@annex_lbl} #{num}</b><br/>#{obl}")
121
108
  end
122
109
 
110
+ def single_annex_special_section(clause)
111
+ a = clause.xpath(ns("./references | ./terms | ./definitions"))
112
+ a.size == 1 or return nil
113
+ clause.xpath(ns("./clause | ./p | ./table | ./ol | ./ul | ./dl | "\
114
+ "./note | ./admonition | ./figure")).size == 0 or
115
+ return nil
116
+ a[0]
117
+ end
118
+
123
119
  def annex_names(clause, num)
124
120
  @anchors[clause["id"]] = { label: annex_name_lbl(clause, num),
125
121
  type: "clause",
126
122
  xref: "#{@annex_lbl} #{num}", level: 1 }
127
- clause.xpath(ns(SUBCLAUSES)).each_with_index do |c, i|
128
- annex_names1(c, "#{num}.#{i + 1}", 2)
123
+ if a = single_annex_special_section(clause)
124
+ annex_names1(a, "#{num}", 1)
125
+ else
126
+ clause.xpath(ns(SUBCLAUSES)).each_with_index do |c, i|
127
+ annex_names1(c, "#{num}.#{i + 1}", 2)
128
+ end
129
129
  end
130
130
  hierarchical_asset_names(clause, num)
131
131
  end