isodoc 1.0.23 → 1.0.28

Sign up to get free protection for your applications and to get access to all the features.
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