isodoc 1.2.4 → 1.3.0

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 (56) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/rake.yml +69 -0
  3. data/README.adoc +1 -3
  4. data/isodoc.gemspec +3 -1
  5. data/lib/isodoc-yaml/i18n-en.yaml +1 -0
  6. data/lib/isodoc-yaml/i18n-fr.yaml +8 -7
  7. data/lib/isodoc-yaml/i18n-zh-Hans.yaml +1 -0
  8. data/lib/isodoc/base_style/all.css +5 -1
  9. data/lib/isodoc/base_style/blocks.scss +2 -2
  10. data/lib/isodoc/base_style/reset.css +5 -1
  11. data/lib/isodoc/base_style/reset.scss +6 -1
  12. data/lib/isodoc/base_style/typography.scss +1 -1
  13. data/lib/isodoc/convert.rb +12 -97
  14. data/lib/isodoc/css.rb +95 -0
  15. data/lib/isodoc/function/inline.rb +0 -33
  16. data/lib/isodoc/function/lists.rb +2 -1
  17. data/lib/isodoc/function/references.rb +8 -13
  18. data/lib/isodoc/function/to_word_html.rb +2 -2
  19. data/lib/isodoc/html_function/postprocess.rb +12 -3
  20. data/lib/isodoc/i18n.rb +23 -51
  21. data/lib/isodoc/metadata.rb +44 -111
  22. data/lib/isodoc/metadata_contributor.rb +90 -0
  23. data/lib/isodoc/metadata_date.rb +11 -0
  24. data/lib/isodoc/presentation_function/bibdata.rb +96 -0
  25. data/lib/isodoc/presentation_function/block.rb +14 -9
  26. data/lib/isodoc/presentation_function/inline.rb +151 -34
  27. data/lib/isodoc/presentation_xml_convert.rb +6 -0
  28. data/lib/isodoc/version.rb +1 -1
  29. data/lib/isodoc/word_convert.rb +0 -20
  30. data/lib/isodoc/word_function/body.rb +12 -0
  31. data/lib/isodoc/word_function/postprocess.rb +1 -1
  32. data/lib/isodoc/xref/xref_anchor.rb +8 -3
  33. data/lib/isodoc/xref/xref_counter.rb +20 -9
  34. data/lib/isodoc/xref/xref_gen.rb +4 -4
  35. data/lib/isodoc/xref/xref_sect_gen.rb +1 -1
  36. data/lib/isodoc/xslfo_convert.rb +6 -1
  37. data/spec/assets/html.scss +14 -0
  38. data/spec/assets/i18n.yaml +22 -5
  39. data/spec/isodoc/blocks_spec.rb +100 -221
  40. data/spec/isodoc/footnotes_spec.rb +4 -5
  41. data/spec/isodoc/i18n_spec.rb +89 -16
  42. data/spec/isodoc/inline_spec.rb +185 -163
  43. data/spec/isodoc/lists_spec.rb +1 -1
  44. data/spec/isodoc/metadata_spec.rb +69 -19
  45. data/spec/isodoc/postproc_spec.rb +33 -8
  46. data/spec/isodoc/presentation_xml_spec.rb +584 -1
  47. data/spec/isodoc/ref_spec.rb +328 -10
  48. data/spec/isodoc/section_spec.rb +9 -9
  49. data/spec/isodoc/table_spec.rb +1 -1
  50. data/spec/isodoc/terms_spec.rb +1 -1
  51. data/spec/isodoc/xref_spec.rb +35 -35
  52. data/spec/spec_helper.rb +6 -0
  53. metadata +36 -7
  54. data/.github/workflows/macos.yml +0 -42
  55. data/.github/workflows/ubuntu.yml +0 -62
  56. data/.github/workflows/windows.yml +0 -44
@@ -67,19 +67,6 @@ module IsoDoc::Function
67
67
  out << "Termbase #{node['base']}, term ID #{node['target']}"
68
68
  end
69
69
 
70
- def concept_parse(node, out)
71
- content = node.first_element_child.children.select do |c|
72
- !%w{locality localityStack}.include? c.name
73
- end.select { |c| !c.text? || /\S/.match(c) }
74
- if content.empty?
75
- out << "[Term defined in "
76
- parse(node.first_element_child, out)
77
- out << "]"
78
- else
79
- content.each { |n| parse(n, out) }
80
- end
81
- end
82
-
83
70
  def stem_parse(node, out)
84
71
  ooml = if node["type"] == "AsciiMath"
85
72
  "#{@openmathdelim}#{HTMLEntities.new.encode(node.text)}"\
@@ -131,25 +118,5 @@ module IsoDoc::Function
131
118
  p.b(**{ role: "strong" }) { |e| e << text }
132
119
  end
133
120
  end
134
-
135
- def variant_parse(node, out)
136
- if node["lang"] == @lang && node["script"] == @script
137
- node.children.each { |n| parse(n, out) }
138
- else
139
- return if found_matching_variant_sibling(node)
140
- return unless !node.at("./preceding-sibling::xmlns:variant")
141
- node.children.each { |n| parse(n, out) }
142
- end
143
- end
144
-
145
- def found_matching_variant_sibling(node)
146
- prev = node.xpath("./preceding-sibling::xmlns:variant")
147
- foll = node.xpath("./following-sibling::xmlns:variant")
148
- found = false
149
- (prev + foll).each do |n|
150
- found = true if n["lang"] == @lang && n["script"] == @script
151
- end
152
- found
153
- end
154
121
  end
155
122
  end
@@ -38,7 +38,8 @@ module IsoDoc::Function
38
38
  end
39
39
 
40
40
  def ol_attrs(node)
41
- { type: ol_depth(node), id: node["id"], style: keep_style(node) }
41
+ { type: node["type"] ? ol_style(node["type"].to_sym) : ol_depth(node),
42
+ id: node["id"], style: keep_style(node) }
42
43
  end
43
44
 
44
45
  def ol_parse(node, out)
@@ -80,7 +80,8 @@ module IsoDoc::Function
80
80
  end
81
81
 
82
82
  def docid_prefix(prefix, docid)
83
- docid = "#{prefix} #{docid}" if prefix && !omit_docid_prefix(prefix)
83
+ docid = "#{prefix} #{docid}" if prefix && !omit_docid_prefix(prefix) &&
84
+ !/^#{prefix}\b/.match(docid)
84
85
  docid_l10n(docid)
85
86
  end
86
87
 
@@ -90,7 +91,7 @@ module IsoDoc::Function
90
91
  end
91
92
 
92
93
  def date_note_process(b, ref)
93
- date_note = b.at(ns("./note[@type = 'ISO DATE']"))
94
+ date_note = b.at(ns("./note[@type = 'Unpublished-Status']"))
94
95
  return if date_note.nil?
95
96
  date_note.children.first.replace("<p>#{date_note.content}</p>")
96
97
  footnote_parse(date_note, ref)
@@ -111,7 +112,7 @@ module IsoDoc::Function
111
112
  # reference not to be rendered because it is deemed implicit
112
113
  # in the standards environment
113
114
  def implicit_reference(b)
114
- false
115
+ b["hidden"] == "true"
115
116
  end
116
117
 
117
118
  def prefix_bracketed_ref(ref, text)
@@ -160,7 +161,7 @@ module IsoDoc::Function
160
161
  end
161
162
 
162
163
  def norm_ref(isoxml, out, num)
163
- f = isoxml.at(ns(norm_ref_xpath)) or return num
164
+ f = isoxml.at(ns(norm_ref_xpath)) and f["hidden"] != "true" or return num
164
165
  out.div do |div|
165
166
  num = num + 1
166
167
  clause_name(num, f.at(ns("./title")), div, nil)
@@ -180,10 +181,9 @@ module IsoDoc::Function
180
181
  end
181
182
 
182
183
  def bibliography(isoxml, out)
183
- f = isoxml.at(ns(bibliography_xpath)) || return
184
+ f = isoxml.at(ns(bibliography_xpath)) and f["hidden"] != "true" or return
184
185
  page_break(out)
185
186
  out.div do |div|
186
- #div.h1 @bibliography_lbl, **{ class: "Section3" }
187
187
  div.h1 **{class: "Section3"} do |h1|
188
188
  f&.at(ns("./title"))&.children&.each { |c2| parse(c2, h1) }
189
189
  end
@@ -192,6 +192,7 @@ module IsoDoc::Function
192
192
  end
193
193
 
194
194
  def bibliography_parse(node, out)
195
+ node["hidden"] != true or return
195
196
  title = node&.at(ns("./title"))&.text || ""
196
197
  out.div do |div|
197
198
  clause_parse_title(node, div, node.at(ns("./title")), out,
@@ -202,15 +203,9 @@ module IsoDoc::Function
202
203
 
203
204
  def format_ref(ref, prefix, isopub, date, allparts)
204
205
  ref = docid_prefix(prefix, ref)
205
- return "[#{ref}]" if /^\d+$/.match(ref) && !prefix &&
206
+ return "[#{ref}]" if ref && /^\d+$/.match(ref) && !prefix &&
206
207
  !/^\[.*\]$/.match(ref)
207
208
  ref
208
209
  end
209
-
210
- # def ref_names(ref)
211
- # linkend = ref.text
212
- # linkend.gsub!(/[\[\]]/, "") unless /^\[\d+\]$/.match linkend
213
- # @anchors[ref["id"]] = { xref: linkend }
214
- # end
215
210
  end
216
211
  end
@@ -96,6 +96,7 @@ module IsoDoc::Function
96
96
  @meta.subtitle isoxml, out
97
97
  @meta.docstatus isoxml, out
98
98
  @meta.docid isoxml, out
99
+ @meta.otherid isoxml, out
99
100
  @meta.docnumeric isoxml, out
100
101
  @meta.doctype isoxml, out
101
102
  @meta.author isoxml, out
@@ -104,6 +105,7 @@ module IsoDoc::Function
104
105
  @meta.version isoxml, out
105
106
  @meta.url isoxml, out
106
107
  @meta.keywords isoxml, out
108
+ @meta.note isoxml, out
107
109
  @meta.get
108
110
  end
109
111
 
@@ -213,14 +215,12 @@ module IsoDoc::Function
213
215
  when "verification" then requirement_component_parse(node, out)
214
216
  when "import" then requirement_component_parse(node, out)
215
217
  when "index" then index_parse(node, out)
216
- when "concept" then concept_parse(node, out)
217
218
  when "termref" then termrefelem_parse(node, out)
218
219
  when "copyright-statement" then copyright_parse(node, out)
219
220
  when "license-statement" then license_parse(node, out)
220
221
  when "legal-statement" then legal_parse(node, out)
221
222
  when "feedback-statement" then feedback_parse(node, out)
222
223
  when "passthrough" then passthrough_parse(node, out)
223
- when "variant" then variant_parse(node, out)
224
224
  when "amend" then amend_parse(node, out)
225
225
  when "tab" then clausedelimspace(out) # in Presentation XML only
226
226
  else
@@ -186,14 +186,22 @@ module IsoDoc::HtmlFunction
186
186
  docxml
187
187
  end
188
188
 
189
+ def footnote_backlinks1(x, fn)
190
+ xdup = x.dup
191
+ xdup.remove["id"]
192
+ if fn.elements.empty?
193
+ fn.children.first.previous = xdup
194
+ else
195
+ fn.elements.first.children.first.previous = xdup
196
+ end
197
+ end
198
+
189
199
  def footnote_backlinks(docxml)
190
200
  seen = {}
191
201
  docxml.xpath('//a[@class = "FootnoteRef"]').each_with_index do |x, i|
192
202
  seen[x["href"]] and next or seen[x["href"]] = true
193
203
  fn = docxml.at(%<//*[@id = '#{x['href'].sub(/^#/, '')}']>) || next
194
- xdup = x.dup
195
- xdup.remove["id"]
196
- fn.elements.first.children.first.previous = xdup
204
+ footnote_backlinks1(x, fn)
197
205
  x["id"] ||= "fnref:#{i + 1}"
198
206
  fn.add_child "<a href='##{x['id']}'>&#x21A9;</a>"
199
207
  end
@@ -221,6 +229,7 @@ module IsoDoc::HtmlFunction
221
229
  MATHJAX = <<~"MATHJAX".freeze
222
230
  <script type="text/x-mathjax-config">
223
231
  MathJax.Hub.Config({
232
+ "HTML-CSS": { preferredFont: "STIX" },
224
233
  asciimath2jax: { delimiters: [['OPEN', 'CLOSE']] }
225
234
  });
226
235
  </script>
@@ -4,8 +4,21 @@ module IsoDoc
4
4
  class I18n
5
5
  def load_yaml(lang, script, i18nyaml = nil)
6
6
  ret = load_yaml1(lang, script)
7
- return ret.merge(YAML.load_file(i18nyaml)) if i18nyaml
8
- ret
7
+ return normalise_hash(ret.merge(YAML.load_file(i18nyaml))) if i18nyaml
8
+ normalise_hash(ret)
9
+ end
10
+
11
+ def normalise_hash(ret)
12
+ if ret.is_a? Hash
13
+ ret.each do |k, v|
14
+ ret[k] = normalise_hash(v)
15
+ end
16
+ ret
17
+ elsif ret.is_a? Array then ret.map { |n| normalise_hash(n) }
18
+ elsif ret.is_a? String then ret.unicode_normalize(:nfc)
19
+ else
20
+ ret
21
+ end
9
22
  end
10
23
 
11
24
  def load_yaml1(lang, script)
@@ -42,55 +55,6 @@ module IsoDoc
42
55
  @labels.each do |k, v|
43
56
  self.class.send(:define_method, k.downcase) { v }
44
57
  end
45
- =begin
46
- @term_def_boilerplate = y["term_def_boilerplate"]
47
- @scope_lbl = y["scope"]
48
- @symbols_lbl = y["symbols"]
49
- @table_of_contents_lbl = y["table_of_contents"]
50
- @introduction_lbl = y["introduction"]
51
- @foreword_lbl = y["foreword"]
52
- @abstract_lbl = y["abstract"]
53
- @termsdef_lbl = y["termsdef"]
54
- @termsdefsymbols_lbl = y["termsdefsymbols"]
55
- @normref_lbl = y["normref"]
56
- @bibliography_lbl = y["bibliography"]
57
- @clause_lbl = y["clause"]
58
- @annex_lbl = y["annex"]
59
- @appendix_lbl = y["appendix"]
60
- @no_terms_boilerplate = y["no_terms_boilerplate"]
61
- @internal_terms_boilerplate = y["internal_terms_boilerplate"]
62
- @norm_with_refs_pref = y["norm_with_refs_pref"]
63
- @norm_empty_pref = y["norm_empty_pref"]
64
- @external_terms_boilerplate = y["external_terms_boilerplate"]
65
- @internal_external_terms_boilerplate =
66
- y["internal_external_terms_boilerplate"]
67
- @note_lbl = y["note"]
68
- @note_xref_lbl = y["note_xref"]
69
- @termnote_lbl = y["termnote"]
70
- @figure_lbl = y["figure"]
71
- @list_lbl = y["list"]
72
- @formula_lbl = y["formula"]
73
- @inequality_lbl = y["inequality"]
74
- @table_lbl = y["table"]
75
- @key_lbl = y["key"]
76
- @example_lbl = y["example"]
77
- @example_xref_lbl = y["example_xref"]
78
- @where_lbl = y["where"]
79
- @wholeoftext_lbl = y["wholeoftext"]
80
- @draft_lbl = y["draft_label"]
81
- @inform_annex_lbl = y["inform_annex"]
82
- @norm_annex_lbl = y["norm_annex"]
83
- @modified_lbl = y["modified"]
84
- @deprecated_lbl = y["deprecated"]
85
- @source_lbl = y["source"]
86
- @and_lbl = y["and"]
87
- @all_parts_lbl = y["all_parts"]
88
- @permission_lbl = y["permission"]
89
- @recommendation_lbl = y["recommendation"]
90
- @requirement_lbl = y["requirement"]
91
- @locality = y["locality"]
92
- @admonition = y["admonition"]
93
- =end
94
58
  end
95
59
 
96
60
  def self.l10n(x, lang = @lang, script = @script)
@@ -115,6 +79,14 @@ module IsoDoc
115
79
  end
116
80
  end
117
81
 
82
+ def multiple_and(names, andword)
83
+ return '' if names.empty?
84
+ return names[0] if names.length == 1
85
+ (names.length == 2) &&
86
+ (return l10n("#{names[0]} #{andword} #{names[1]}", @lang, @script))
87
+ l10n(names[0..-2].join(', ') + " #{andword} #{names[-1]}", @lang, @script)
88
+ end
89
+
118
90
  #module_function :l10n
119
91
 
120
92
  end
@@ -1,14 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative './metadata_date'
4
+ require_relative './metadata_contributor'
4
5
 
5
6
  module IsoDoc
6
7
  class Metadata
7
- DATETYPES = %w{published accessed created implemented obsoleted confirmed
8
- updated issued received transmitted copied unchanged
9
- circulated vote-started
10
- vote-ended}.freeze
11
-
12
8
  attr_accessor :fonts_options
13
9
 
14
10
  def ns(xpath)
@@ -20,7 +16,7 @@ module IsoDoc
20
16
  end
21
17
 
22
18
  def initialize(lang, script, i18n, fonts_options = {})
23
- @metadata = {}
19
+ @metadata = { lang: lang, script: script }
24
20
  DATETYPES.each { |w| @metadata["#{w.gsub(/-/, '_')}date".to_sym] = 'XXX' }
25
21
  @lang = lang
26
22
  @script = script
@@ -42,113 +38,37 @@ module IsoDoc
42
38
  @metadata[key] = value
43
39
  end
44
40
 
45
- def extract_person_names(authors)
46
- authors.reduce([]) do |ret, a|
47
- if a.at(ns('./name/completename'))
48
- ret << a.at(ns('./name/completename')).text
49
- else
50
- fn = []
51
- forenames = a.xpath(ns('./name/forename'))
52
- forenames.each { |f| fn << f.text }
53
- surname = a&.at(ns('./name/surname'))&.text
54
- ret << fn.join(' ') + ' ' + surname
55
- end
56
- end
57
- end
41
+ NOLANG = "[not(@language) or @language = '']".freeze
58
42
 
59
- def extract_person_affiliations(authors)
60
- authors.reduce([]) do |m, a|
61
- name = a&.at(ns('./affiliation/organization/name'))&.text
62
- location = a&.at(ns('./affiliation/organization/address/'\
63
- 'formattedAddress'))&.text
64
- m << (!name.nil? && !location.nil? ? "#{name}, #{location}" :
65
- (name || location || ''))
66
- m
67
- end
68
- end
69
-
70
- def extract_person_names_affiliations(authors)
71
- names = extract_person_names(authors)
72
- affils = extract_person_affiliations(authors)
73
- ret = {}
74
- affils.each_with_index do |a, i|
75
- ret[a] ||= []
76
- ret[a] << names[i]
77
- end
78
- ret
79
- end
80
-
81
- def personal_authors(isoxml)
82
- authors = isoxml.xpath(ns("//bibdata/contributor[role/@type = 'author' "\
83
- "or xmlns:role/@type = 'editor']/person"))
84
- set(:authors, extract_person_names(authors))
85
- set(:authors_affiliations, extract_person_names_affiliations(authors))
86
- end
87
-
88
- def author(xml, _out)
89
- personal_authors(xml)
90
- agency(xml)
91
- end
92
-
93
- def bibdate(isoxml, _out)
94
- isoxml.xpath(ns('//bibdata/date')).each do |d|
95
- set("#{d['type'].gsub(/-/, '_')}date".to_sym, Common::date_range(d))
96
- end
43
+ def currlang
44
+ "[@language = '#{@lang}']"
97
45
  end
98
46
 
99
47
  def doctype(isoxml, _out)
100
- b = isoxml&.at(ns('//bibdata/ext/doctype'))&.text || return
101
- t = b.split(/[- ]/).map(&:capitalize).join(' ')
102
- set(:doctype, t)
103
- end
104
-
105
- def iso?(org)
106
- name = org&.at(ns('./name'))&.text
107
- abbrev = org&.at(ns('./abbreviation'))&.text
108
- (abbrev == 'ISO' ||
109
- name == 'International Organization for Standardization')
110
- end
111
-
112
- def agency(xml)
113
- agency = ''
114
- publisher = []
115
- xml.xpath(ns("//bibdata/contributor[xmlns:role/@type = 'publisher']/"\
116
- 'organization')).each do |org|
117
- name = org&.at(ns('./name'))&.text
118
- agency1 = org&.at(ns('./abbreviation'))&.text || name
119
- publisher << name if name
120
- agency = iso?(org) ? "ISO/#{agency}" : "#{agency}#{agency1}/"
121
- end
122
- set(:agency, agency.sub(%r{/$}, ''))
123
- set(:publisher, multiple_and(publisher, @labels['and']))
124
- end
125
-
126
- def multiple_and(names, andword)
127
- return '' if names.empty?
128
- return names[0] if names.length == 1
129
- (names.length == 2) &&
130
- (return l10n("#{names[0]} #{andword} #{names[1]}", @lang, @script))
131
- l10n(names[0..-2].join(', ') + " #{andword} #{names[-1]}", @lang, @script)
48
+ b = isoxml&.at(ns("//bibdata/ext/doctype#{NOLANG}"))&.text || return
49
+ set(:doctype, status_print(b))
50
+ b1 = isoxml&.at(ns("//bibdata/ext/doctype#{currlang}"))&.text || b
51
+ set(:doctype_display, status_print(b1))
132
52
  end
133
53
 
134
- def docstatus(isoxml, _out)
135
- docstatus = isoxml.at(ns('//bibdata/status/stage'))
54
+ def docstatus(xml, _out)
136
55
  set(:unpublished, true)
137
- if docstatus
138
- set(:stage, status_print(docstatus.text))
139
- (i = isoxml&.at(ns('//bibdata/status/substage'))&.text) &&
140
- set(:substage, i)
141
- (i = isoxml&.at(ns('//bibdata/status/iteration'))&.text) &&
142
- set(:iteration, i)
143
- set(:unpublished, unpublished(docstatus.text))
144
- unpublished(docstatus.text) &&
145
- set(:stageabbr, stage_abbr(docstatus.text))
146
- end
56
+ return unless s = xml.at(ns("//bibdata/status/stage#{NOLANG}"))
57
+ s1 = xml.at(ns("//bibdata/status/stage#{currlang}")) || s
58
+ set(:stage, status_print(s.text))
59
+ s1 and set(:stage_display, status_print(s1.text))
60
+ (i = xml&.at(ns("//bibdata/status/substage#{NOLANG}"))&.text) and
61
+ set(:substage, i)
62
+ (i1 = xml&.at(ns("//bibdata/status/substage#{currlang}"))&.text || i) and
63
+ set(:substage_display, i1)
64
+ (i2 = xml&.at(ns('//bibdata/status/iteration'))&.text) and
65
+ set(:iteration, i2)
66
+ set(:unpublished, unpublished(s.text))
67
+ unpublished(s.text) && set(:stageabbr, stage_abbr(s.text))
147
68
  end
148
69
 
149
70
  def stage_abbr(docstatus)
150
- status_print(docstatus).split(/ /)
151
- .map { |s| s[0].upcase }.join('')
71
+ status_print(docstatus).split(/ /).map { |s| s[0].upcase }.join('')
152
72
  end
153
73
 
154
74
  def unpublished(status)
@@ -156,7 +76,7 @@ module IsoDoc
156
76
  end
157
77
 
158
78
  def status_print(status)
159
- status.split(/-/).map(&:capitalize).join(' ')
79
+ status.split(/[- ]/).map(&:capitalize).join(' ')
160
80
  end
161
81
 
162
82
  def docid(isoxml, _out)
@@ -164,18 +84,23 @@ module IsoDoc
164
84
  set(:docnumber, dn&.text)
165
85
  end
166
86
 
87
+ def otherid(isoxml, _out)
88
+ dn = isoxml.at(ns('//bibdata/docidentifier[@type = "ISBN"]'))
89
+ set(:isbn, dn&.text)
90
+ dn = isoxml.at(ns('//bibdata/docidentifier[@type = "ISBN10"]'))
91
+ set(:isbn10, dn&.text)
92
+ end
93
+
167
94
  def docnumeric(isoxml, _out)
168
95
  dn = isoxml.at(ns('//bibdata/docnumber'))
169
96
  set(:docnumeric, dn&.text)
170
97
  end
171
98
 
172
99
  def draftinfo(draft, revdate)
173
- draftinfo = ''
174
- if draft
175
- draftinfo = " (#{@labels['draft_label']} #{draft}"
176
- draftinfo += ", #{revdate}" if revdate
177
- draftinfo += ')'
178
- end
100
+ return "" unless draft
101
+ draftinfo = " (#{@labels['draft_label']} #{draft}"
102
+ draftinfo += ", #{revdate}" if revdate
103
+ draftinfo += ')'
179
104
  l10n(draftinfo, @lang, @script)
180
105
  end
181
106
 
@@ -191,7 +116,7 @@ module IsoDoc
191
116
  end
192
117
 
193
118
  def title(isoxml, _out)
194
- main = isoxml&.at(ns("//bibdata/title[@language='en']"))&.text
119
+ main = isoxml&.at(ns("//bibdata/title[@language='#{@lang}']"))&.text
195
120
  set(:doctitle, main)
196
121
  end
197
122
 
@@ -231,5 +156,13 @@ module IsoDoc
231
156
  isoxml.xpath(ns('//bibdata/keyword')).each { |kw| ret << kw.text }
232
157
  set(:keywords, ret)
233
158
  end
159
+
160
+ def note(isoxml, _out)
161
+ ret = []
162
+ isoxml.xpath(ns("//bibdata/note[@type = 'title-footnote']")).each do |n|
163
+ ret << n.text
164
+ end
165
+ set(:title_footnote, ret)
166
+ end
234
167
  end
235
168
  end