metanorma-ieee 0.0.1 → 0.0.4

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 (48) hide show
  1. checksums.yaml +4 -4
  2. data/README.adoc +1 -1
  3. data/lib/html2doc/ieee/lists.rb +44 -0
  4. data/lib/html2doc/ieee/notes.rb +57 -0
  5. data/lib/html2doc/ieee.rb +4 -86
  6. data/lib/isodoc/ieee/base_convert.rb +56 -0
  7. data/lib/isodoc/ieee/html/header.html +1 -2
  8. data/lib/isodoc/ieee/html/header_amd.html +105 -0
  9. data/lib/isodoc/ieee/html/html_ieee_titlepage.html +14 -12
  10. data/lib/isodoc/ieee/html/htmlstyle.css +2 -1
  11. data/lib/isodoc/ieee/html/htmlstyle.scss +1 -0
  12. data/lib/isodoc/ieee/html/ieee.css +46 -273
  13. data/lib/isodoc/ieee/html/ieee.scss +46 -257
  14. data/lib/isodoc/ieee/html/word_ieee_intro.html +1 -1
  15. data/lib/isodoc/ieee/html/word_ieee_titlepage.html +12 -1
  16. data/lib/isodoc/ieee/html/wordstyle.css +20 -23
  17. data/lib/isodoc/ieee/html/wordstyle.scss +20 -17
  18. data/lib/isodoc/ieee/html_convert.rb +37 -1
  19. data/lib/isodoc/ieee/i18n-en.yaml +5 -0
  20. data/lib/isodoc/ieee/ieee.amendment.xsl +5488 -3540
  21. data/lib/isodoc/ieee/ieee.standard.xsl +5488 -3540
  22. data/lib/isodoc/ieee/metadata.rb +35 -51
  23. data/lib/isodoc/ieee/pdf_convert.rb +2 -2
  24. data/lib/isodoc/ieee/presentation_ref.rb +70 -0
  25. data/lib/isodoc/ieee/presentation_terms.rb +105 -32
  26. data/lib/isodoc/ieee/presentation_xml_convert.rb +136 -0
  27. data/lib/isodoc/ieee/word_authority.rb +73 -3
  28. data/lib/isodoc/ieee/word_cleanup.rb +55 -65
  29. data/lib/isodoc/ieee/word_cleanup_blocks.rb +151 -0
  30. data/lib/isodoc/ieee/word_convert.rb +98 -2
  31. data/lib/isodoc/ieee/xref.rb +31 -0
  32. data/lib/metanorma/ieee/boilerplate.xml +72 -23
  33. data/lib/metanorma/ieee/cleanup.rb +142 -77
  34. data/lib/metanorma/ieee/cleanup_ref.rb +126 -0
  35. data/lib/metanorma/ieee/converter.rb +8 -0
  36. data/lib/metanorma/ieee/front.rb +44 -53
  37. data/lib/metanorma/ieee/ieee.rng +44 -6
  38. data/lib/metanorma/ieee/isodoc.rng +32 -1
  39. data/lib/metanorma/ieee/reqt.rng +1 -1
  40. data/lib/metanorma/ieee/term_lookup_cleanup.rb +11 -0
  41. data/lib/metanorma/ieee/validate.rb +105 -57
  42. data/lib/metanorma/ieee/validate_section.rb +14 -7
  43. data/lib/metanorma/ieee/validate_style.rb +58 -1
  44. data/lib/metanorma/ieee/version.rb +1 -1
  45. data/lib/relaton/render/config.yml +44 -0
  46. data/lib/relaton/render/general.rb +13 -0
  47. data/metanorma-itu.gemspec +1 -1
  48. metadata +13 -4
@@ -6,11 +6,13 @@ module IsoDoc
6
6
  class Metadata < IsoDoc::Metadata
7
7
  def initialize(lang, script, i18n, fonts_options = {})
8
8
  super
9
- @metadata[:confirmeddate] = "&lt;Date Approved&gt;"
9
+ @metadata[:issueddate] = "&lt;Date Approved&gt;"
10
10
  end
11
11
 
12
12
  def bibdate(isoxml, _out)
13
- super
13
+ isoxml.xpath(ns("//bibdata/date[@format = 'ddMMMyyyy']")).each do |d|
14
+ set("#{d['type'].gsub(/-/, '_')}date".to_sym, Common::date_range(d))
15
+ end
14
16
  draft = isoxml.at(ns("//bibdata/date[@type = 'issued']")) ||
15
17
  isoxml.at(ns("//bibdata/date[@type = 'circulated']")) ||
16
18
  isoxml.at(ns("//bibdata/date[@type = 'created']")) ||
@@ -25,8 +27,10 @@ module IsoDoc
25
27
  b = isoxml.at(ns("//bibdata/ext/doctype"))&.text or return
26
28
  set(:doctype, b.split(/[- ]/).map(&:capitalize).join(" "))
27
29
  set(:doctype_abbrev, @labels["doctype_abbrev"][b])
28
- s = isoxml.at(ns("//bibdata/ext/docsubtype"))&.text and
30
+ s = isoxml.at(ns("//bibdata/ext/subdoctype"))&.text and
29
31
  set(:docsubtype, s.split(/[- ]/).map(&:capitalize).join(" "))
32
+ s = isoxml.at(ns("//bibdata/ext/trial-use"))&.text and s == "true" and
33
+ set(:trial_use, true)
30
34
  end
31
35
 
32
36
  def author(xml, _out)
@@ -35,7 +39,6 @@ module IsoDoc
35
39
  tc(xml)
36
40
  wg(xml)
37
41
  bg(xml)
38
- std_group(xml)
39
42
  end
40
43
 
41
44
  def society(xml)
@@ -46,63 +49,21 @@ module IsoDoc
46
49
 
47
50
  def tc(xml)
48
51
  tc = xml.at(ns("//bibdata/ext/editorialgroup/"\
49
- "technical-committee"))&.text || "&lt;Committee Name&gt;"
52
+ "committee"))&.text || "&lt;Committee Name&gt;"
50
53
  set(:technical_committee, tc)
51
54
  end
52
55
 
53
- def editor_names(xml, role)
54
- xml.xpath(ns("//bibdata/contributor[role/@type = 'editor']"\
55
- "[role = '#{role}']/person/name/completename"))
56
- &.each&.map(&:text)
57
- end
58
-
59
- def editor_name(xml, role)
60
- editor_names(xml, role)&.first
61
- end
62
-
63
56
  def wg(xml)
64
57
  wg = xml.at(ns("//bibdata/ext/editorialgroup/"\
65
58
  "working-group")) or return nil
66
59
  set(:working_group, wg.text)
67
- m = {}
68
- ["Chair", "Vice-Chair", "Secretary"].each do |r|
69
- a = editor_name(xml, "Working Group #{r}") and
70
- m[r.downcase.gsub(/ /, "-")] = a
71
- end
72
- wg_members(xml, m)
73
- end
74
-
75
- def wg_members(xml, members)
76
- a = editor_names(xml, "Working Group Member") and members["members"] = a
77
- members["members"].empty? and (1..9).each do |i|
78
- members["members"] << "Participant#{i}"
79
- end
80
- set(:wg_members, members)
81
60
  end
82
61
 
83
62
  def bg(xml)
84
63
  bg = xml.at(ns("//bibdata/ext/editorialgroup/"\
85
64
  "balloting-group")) or return nil
86
65
  set(:balloting_group, bg.text)
87
- m = {}
88
- m["members"] = editor_names(xml, "Balloting Group Member")
89
- m["members"].empty? and (1..9).each do |i|
90
- m["members"] << "Balloter#{i}"
91
- end
92
- set(:balloting_group_members, m["members"])
93
- end
94
-
95
- def std_group(xml)
96
- m = {}
97
- ["Chair", "Vice-Chair", "Past Chair", "Secretary"].each do |r|
98
- m[r.downcase.gsub(/ /, "-")] =
99
- editor_name(xml, "Standards Board #{r}") || "&lt;Name&gt;"
100
- end
101
- m["members"] = editor_names(xml, "Standards Board Member")
102
- m["members"].empty? and (1..9).each do |i|
103
- m["members"] << "SBMember#{i}"
104
- end
105
- set(:std_board, m)
66
+ set(:balloting_group_type, bg["type"])
106
67
  end
107
68
 
108
69
  def otherid(isoxml, _out)
@@ -120,16 +81,39 @@ module IsoDoc
120
81
  set(:stdid_pdf, dn&.text || "STDXXXXX")
121
82
  dn = isoxml.at(ns("//#{id}[@scope = 'print']"))
122
83
  set(:stdid_print, dn&.text || "STDPDXXXXX")
84
+ dn = isoxml.at(ns("//bibdata/ext/structuredidentifier/amendment")) and
85
+ set(:amd, dn.text)
86
+ dn = isoxml.at(ns("//bibdata/ext/structuredidentifier/corrigendum")) and
87
+ set(:corr, dn.text)
123
88
  end
124
89
 
125
90
  def title(isoxml, _out)
126
91
  super
127
92
  draft = isoxml&.at(ns("//bibdata/version/draft"))
128
93
  doctype(isoxml, _out)
129
- title = "#{@metadata[:doctype_abbrev] || '???'} for "\
130
- "#{@metadata[:doctitle] || '???'}"
94
+ set(:full_doctitle, fulltitle(@metadata[:doctype], draft))
95
+ set(:abbrev_doctitle, fulltitle(@metadata[:doctype_abbrev], draft))
96
+ prov = isoxml&.at(ns("//bibdata/title[@type='provenance']")) and
97
+ set(:provenance_doctitle, prov.children.to_xml)
98
+ end
99
+
100
+ def fulltitle(type, draft)
101
+ title = "#{type || '???'} for #{@metadata[:doctitle] || '???'}"
131
102
  draft and title = "Draft #{title}"
132
- set(:full_doctitle, title)
103
+ title
104
+ end
105
+
106
+ def ddMMMyyyy(isodate)
107
+ return nil if isodate.nil?
108
+
109
+ arr = isodate.split("-")
110
+ if arr.size == 1 && (/^\d+$/.match isodate)
111
+ Date.new(*arr.map(&:to_i)).strftime("%Y")
112
+ elsif arr.size == 2
113
+ Date.new(*arr.map(&:to_i)).strftime("%b %Y")
114
+ else
115
+ Date.parse(isodate).strftime("%d %b %Y")
116
+ end
133
117
  end
134
118
  end
135
119
  end
@@ -12,8 +12,8 @@ module IsoDoc
12
12
  end
13
13
 
14
14
  def pdf_stylesheet(docxml)
15
- doctype = docxml&.at(ns("//bibdata/ext/doctype"))&.text
16
- if doctype == "amendment"
15
+ doctype = docxml&.at(ns("//bibdata/ext/subdoctype"))&.text
16
+ if %w(amendment corrigendum erratum).include?(doctype)
17
17
  "ieee.amendment.xsl"
18
18
  else
19
19
  "ieee.standard.xsl"
@@ -0,0 +1,70 @@
1
+ module IsoDoc
2
+ module IEEE
3
+ class PresentationXMLConvert < IsoDoc::PresentationXMLConvert
4
+ # Style manual 19
5
+ def anchor_linkend(node, linkend)
6
+ @bibanchors ||= biblio_ids_titles(node.document)
7
+ if node["citeas"] && i = @bibanchors[node["bibitemid"]]
8
+ biblio_anchor_linkend(node, i)
9
+ else super
10
+ end
11
+ end
12
+
13
+ def biblio_anchor_linkend(node, bib)
14
+ if %w(techreport standard).include?(bib[:type])
15
+ node["citeas"] + " #{bib[:ord]}"
16
+ else
17
+ "#{bib[:title]} " + node["citeas"]
18
+ end
19
+ end
20
+
21
+ def biblio_ids_titles(xmldoc)
22
+ xmldoc.xpath(ns("//references[@normative = 'false']/bibitem"))
23
+ .each_with_object({}) do |b, m|
24
+ m[b["id"]] =
25
+ { docid: pref_ref_code(b), type: b["type"],
26
+ title: (b.at(ns("./title")) ||
27
+ b.at(ns("./formattedref")))&.text,
28
+ ord: b.at(ns("./docidentifier[@type = 'metanorma' or "\
29
+ "@type = 'metanorma-ordinal']")).text }
30
+ end
31
+ end
32
+
33
+ def bibrenderer
34
+ ::Relaton::Render::IEEE::General.new(language: @lang,
35
+ i18nhash: @i18n.get)
36
+ end
37
+
38
+ def bibrender_relaton(xml)
39
+ bib = xml.dup
40
+ bib["suppress_identifier"] == true and
41
+ bib.xpath(ns("./docidentifier")).each(&:remove)
42
+ xml.children =
43
+ "#{bibrenderer.render(bib.to_xml)}"\
44
+ "#{xml.xpath(ns('./docidentifier | ./uri | ./note | ./title')).to_xml}"
45
+ end
46
+
47
+ def creatornames(bibitem)
48
+ ::Relaton::Render::IEEE::General
49
+ .new(language: @lang, i18nhash: @i18n.get,
50
+ template: { (bibitem["type"] || "misc").to_sym =>
51
+ "{{ creatornames }}" })
52
+ .parse1(RelatonBib::XMLParser.from_xml(bibitem.to_xml))
53
+ end
54
+
55
+ def bibliography_bibitem_number1(bibitem, idx)
56
+ if mn = bibitem.at(ns(".//docidentifier[@type = 'metanorma']"))
57
+ /^\[?\d\]?$/.match?(mn&.text) and
58
+ idx = mn.text.sub(/^\[B?/, "").sub(/\]$/, "").to_i
59
+ end
60
+ unless bibliography_bibitem_number_skip(bibitem)
61
+
62
+ idx += 1
63
+ bibitem.at(ns(".//docidentifier")).previous =
64
+ "<docidentifier type='metanorma-ordinal'>[B#{idx}]</docidentifier>"
65
+ end
66
+ idx
67
+ end
68
+ end
69
+ end
70
+ end
@@ -1,3 +1,5 @@
1
+ require_relative "../../relaton/render/general"
2
+
1
3
  module IsoDoc
2
4
  module IEEE
3
5
  class PresentationXMLConvert < IsoDoc::PresentationXMLConvert
@@ -10,7 +12,8 @@ module IsoDoc
10
12
  c = IsoDoc::XrefGen::Counter.new("@")
11
13
  elem.xpath(ns("./definition")).each do |d|
12
14
  c.increment(d)
13
- d.elements.first.previous = "<strong>(#{c.print})</strong>&#xa0;"
15
+ d.elements.first.children.first.previous =
16
+ "<strong>(#{c.print})</strong>&#xa0;"
14
17
  end
15
18
  end
16
19
 
@@ -18,19 +21,29 @@ module IsoDoc
18
21
  ins = elem.at(ns("./definition")).previous_element
19
22
  coll = elem.xpath(ns("./definition"))
20
23
  coll.each(&:remove)
21
- ins.next = "<definition>#{coll.map do |c|
22
- c.children.to_xml
23
- end }</definition>"
24
+ ins.next = "<definition>#{unwrap_multidef(coll)}</definition>"
25
+ end
26
+
27
+ def unwrap_multidef(coll)
28
+ if coll.all? do |c|
29
+ c.elements.size == 1 && c.elements.first.name == "p"
30
+ end
31
+ ret = coll.map do |c|
32
+ c.elements.first.children.to_xml
33
+ end
34
+ return "<p>#{ret.join}</p>"
35
+ end
36
+ coll.map { |c| c.children.to_xml }.join
24
37
  end
25
38
 
26
39
  def unwrap_definition(docxml)
27
40
  docxml.xpath(ns("//definition/verbal-definition")).each do |v|
28
41
  next unless v.elements.all? { |e| %w(termsource p).include?(e.name) }
29
42
 
30
- s = v.xpath(ns("./termsource"))
31
43
  p = v.xpath(ns("./p"))
32
44
  v.children =
33
- "<p>#{p.map(&:children).map(&:to_xml).join("\n")}</p>#{s.to_xml}"
45
+ "<p>#{p.map(&:children).map(&:to_xml).join("\n")}</p>"\
46
+ "#{v.xpath(ns('./termsource')).to_xml}"
34
47
  end
35
48
  super
36
49
  end
@@ -47,21 +60,28 @@ module IsoDoc
47
60
  def term_related_collapse(coll)
48
61
  prev = 0
49
62
  coll[1..-1].each_with_index do |r, i|
50
- if coll[prev]["type"] == r["type"]
51
- coll[prev].at(ns("./preferred")) << "; #{r.at(ns('./preferred'))
52
- .children.to_xml}"
53
- r.remove
54
- else prev = i
63
+ if coll[prev]["type"] != r["type"]
64
+ prev = i
65
+ next
55
66
  end
67
+ coll[prev].at(ns("./preferred")) << "; #{r.at(ns('./preferred'))
68
+ .children.to_xml}"
69
+ r.remove
56
70
  end
57
71
  end
58
72
 
59
73
  def sort_terms_key(term)
60
74
  d = term.at(ns("./preferred/expression/name | "\
61
- "./preferred/letter-designation/name | "\
75
+ "./preferred/letter-symbol/name | "\
62
76
  "./preferred/graphical-symbol/figure/name | "\
63
- "./preferred/graphical-symbol/figure/@id"))
64
- d&.text&.downcase
77
+ "./preferred/graphical-symbol/figure/@id | "\
78
+ "./preferred"))
79
+ f = term.at(ns("./field-of-application")) || term.at(ns("./domain"))
80
+ HTMLEntities.new.decode("#{sort_terms_key1(d)} :: #{sort_terms_key1(f)}")
81
+ end
82
+
83
+ def sort_terms_key1(elem)
84
+ elem&.text&.strip&.downcase || "zzzz"
65
85
  end
66
86
 
67
87
  def term_related_reorder(coll)
@@ -96,22 +116,52 @@ module IsoDoc
96
116
  end
97
117
 
98
118
  def admitted_to_related(docxml)
99
- docxml.xpath(ns("//term/admitted")).each do |a|
100
- a["type"] = "equivalent"
101
- a.name = "related"
102
- a.children = "<preferred>#{a.children.to_xml}</preferred>"
119
+ docxml.xpath(ns("//term")).each do |t|
120
+ t.xpath(ns("./admitted | ./preferred")).each_with_index do |a, i|
121
+ (i.zero? ||
122
+ a.at(ns("./abbreviation-type | ./graphical-symbol"))) and next
123
+ admitted_to_related1(a, t.at(ns("./preferred")))
124
+ end
103
125
  end
126
+ term_reorder(docxml)
104
127
  end
105
128
 
106
- def collapse_term(docxml)
107
- docxml.xpath(ns("//term")).each do |t|
108
- collapse_term1(t)
129
+ def admitted_to_related1(adm, pref)
130
+ new = adm.dup
131
+ adm["type"] = "equivalent"
132
+ adm.name = "related"
133
+ adm.children = "<preferred>#{adm.children.to_xml}</preferred>"
134
+ adm.parent.next = <<~TERM
135
+ <term><preferred>#{new.children.to_xml}</preferred>
136
+ <related type='see'><preferred>#{pref.children.to_xml}</preferred></related></term>
137
+ TERM
138
+ end
139
+
140
+ def term_reorder(xmldoc)
141
+ xmldoc.xpath(ns("//terms")).each { |t| term_reorder1(t) }
142
+ end
143
+
144
+ def term_reorder1(terms)
145
+ ins = terms.at(ns("./term"))&.previous_element or return
146
+ coll = terms.xpath(ns("./term"))
147
+ ret = sort_terms(coll)
148
+ coll.each(&:remove)
149
+ ret.reverse.each { |t| ins.next = t }
150
+ end
151
+
152
+ def sort_terms(terms)
153
+ terms.sort do |a, b|
154
+ sort_terms_key(a) <=> sort_terms_key(b)
109
155
  end
110
156
  end
111
157
 
158
+ def collapse_term(docxml)
159
+ docxml.xpath(ns("//term")).each { |t| collapse_term1(t) }
160
+ end
161
+
112
162
  def collapse_term1(term)
113
163
  ret = collapse_term_template(
114
- pref: term.at(ns("./preferred")).remove,
164
+ pref: term.at(ns("./preferred"))&.remove,
115
165
  def: term.at(ns("./definition")),
116
166
  rels: term.xpath(ns("./related")).map(&:remove),
117
167
  source: term.at(ns("./termsource")),
@@ -122,8 +172,9 @@ module IsoDoc
122
172
 
123
173
  def collapse_term_related(rels)
124
174
  ret = rels.map do |r|
175
+ p = r.at(ns("./preferred"))
125
176
  "<em>#{@i18n.relatedterms[r['type']]}:</em> "\
126
- "#{r.at(ns('./preferred')).children.to_xml}"
177
+ "#{p&.children&.to_xml || '**RELATED TERM NOT FOUND**'}"
127
178
  end.join(". ")
128
179
  ret += "." unless ret.empty?
129
180
  ret
@@ -131,11 +182,12 @@ module IsoDoc
131
182
 
132
183
  def collapse_term_template(opt)
133
184
  defn = collapse_unwrap_definition(opt[:def])
134
- source = opt[:source] ? "(#{opt[:source].remove.children.to_xml})" : nil
185
+ src = nil
186
+ opt[:source] and src = "(#{opt[:source].remove.children.to_xml.strip})"
135
187
  <<~TERM
136
- <p>#{opt[:pref].children.to_xml}: #{defn}
188
+ <p>#{opt[:pref]&.children&.to_xml || '**TERM NOT FOUND**'}: #{defn}
137
189
  #{collapse_term_related(opt[:rels])}
138
- #{source}</p>
190
+ #{src}</p>
139
191
  TERM
140
192
  end
141
193
 
@@ -155,6 +207,14 @@ module IsoDoc
155
207
  while elem&.next_element&.name == "termsource"
156
208
  elem << "; #{elem.next_element.remove.children.to_xml}"
157
209
  end
210
+ adapt = termsource_adapt(elem["status"]) and
211
+ elem.children = l10n("#{adapt}#{elem.children.to_xml.strip}")
212
+ end
213
+
214
+ def termsource_adapt(status)
215
+ case status
216
+ when "adapted" then @i18n.adapted_from
217
+ end
158
218
  end
159
219
 
160
220
  def designation_field(desgn, name)
@@ -167,15 +227,28 @@ module IsoDoc
167
227
  end
168
228
 
169
229
  def merge_second_preferred(term)
170
- super
171
- term.xpath(ns("./preferred[expression/name]")).each_with_index do |p, i|
172
- unless i.zero?
173
- p.remove # whatever was eligible to display has already been merged
174
- end
175
- end
230
+ pref =
231
+ term.at(ns("./preferred[not(abbreviation-type)]/expression/name"))
232
+ x = term.xpath(ns("./preferred[expression/name][abbreviation-type] | "\
233
+ "./admitted[expression/name][abbreviation-type]"))
234
+ (pref && !x.empty?) or return
235
+ tail = x.map do |p|
236
+ p.remove.at(ns("./expression/name")).children.to_xml.strip
237
+ end.join(", ")
238
+ pref << " (#{tail})"
239
+ end
240
+
241
+ def termnote1(elem)
242
+ lbl = l10n(@xrefs.anchor(elem["id"], :label)&.strip || "???")
243
+ prefix_name(elem, block_delim, lower2cap(lbl), "name")
176
244
  end
177
245
 
178
246
  def term(docxml); end
247
+
248
+ def concept1(node)
249
+ concept_render(node, ital: "false", ref: "false",
250
+ linkref: "false", linkmention: "false")
251
+ end
179
252
  end
180
253
  end
181
254
  end
@@ -1,5 +1,6 @@
1
1
  require_relative "init"
2
2
  require_relative "presentation_terms"
3
+ require_relative "presentation_ref"
3
4
  require "isodoc"
4
5
 
5
6
  module IsoDoc
@@ -69,6 +70,16 @@ module IsoDoc
69
70
  "&#x2014;"
70
71
  end
71
72
 
73
+ def note1(elem)
74
+ return if elem.parent.name == "bibitem" || elem["notag"] == "true"
75
+
76
+ n = @xrefs.get[elem["id"]]
77
+ lbl = if n.nil? || n[:label].nil? || n[:label].empty? then @i18n.note
78
+ else l10n("#{@i18n.note} #{n[:label]}")
79
+ end
80
+ prefix_name(elem, block_delim, lbl, "name")
81
+ end
82
+
72
83
  def display_order(docxml)
73
84
  i = 0
74
85
  i = display_order_xpath(docxml, "//preface/*", i)
@@ -83,6 +94,131 @@ module IsoDoc
83
94
  display_order_xpath(docxml, "//indexsect", i)
84
95
  end
85
96
 
97
+ def annex1(elem)
98
+ lbl = @xrefs.anchor(elem["id"], :label)
99
+ if t = elem.at(ns("./title"))
100
+ t.children = "<strong>#{t.children.to_xml}</strong>"
101
+ end
102
+ prefix_name(elem, "<br/>", lbl, "title")
103
+ end
104
+
105
+ def bibdata_i18n(bib)
106
+ super
107
+ bibdata_dates(bib)
108
+ end
109
+
110
+ def bibdata_dates(bib)
111
+ bib.xpath(ns("./date")).each do |d|
112
+ d.next = d.dup
113
+ d.next["format"] = "ddMMMyyyy"
114
+ d.next.xpath(ns("./from | ./to | ./on")).each do |x|
115
+ x.children = ddMMMyyyy(x.text)
116
+ end
117
+ end
118
+ end
119
+
120
+ def ddMMMyyyy(isodate)
121
+ return nil if isodate.nil?
122
+
123
+ arr = isodate.split("-")
124
+ if arr.size == 1 && (/^\d+$/.match isodate)
125
+ Date.new(*arr.map(&:to_i)).strftime("%Y")
126
+ elsif arr.size == 2
127
+ Date.new(*arr.map(&:to_i)).strftime("%b %Y")
128
+ else
129
+ Date.parse(isodate).strftime("%d %b %Y")
130
+ end
131
+ end
132
+
133
+ def amend1(elem)
134
+ elem.xpath(ns("./description/p")).each do |p|
135
+ p.children = p.children.to_xml.strip
136
+ amend_format(p)
137
+ end
138
+ super
139
+ end
140
+
141
+ def amend_format(para)
142
+ 2.times do
143
+ para.children.size == 1 &&
144
+ %(em strong).include?(para.children.first.name) and
145
+ para.children = para.elements.first.children
146
+ end
147
+ para.children = "<strong><em>#{para.children.to_xml}</em></strong>"
148
+ end
149
+
150
+ def section(docxml)
151
+ boilerplate(docxml)
152
+ super
153
+ end
154
+
155
+ def boilerplate(docxml)
156
+ docxml.xpath(ns("//clause[@id = 'boilerplate-participants']/"\
157
+ "clause/title")).each(&:remove)
158
+ docxml.xpath(ns("//clause[@id = 'boilerplate-participants']/clause"))
159
+ .each do |clause|
160
+ participants(clause)
161
+ end
162
+ end
163
+
164
+ def participants(clause)
165
+ clause.xpath(ns(".//ul")).each_with_index do |ulist, idx|
166
+ ulist.xpath(ns("./li")).each { |list| participants1(list, idx) }
167
+ ulist.replace(ulist.children)
168
+ end
169
+ affiliation_header(clause)
170
+ end
171
+
172
+ def affiliation_header(clause)
173
+ clause.xpath(ns(".//p[@type = 'officeorgrepmember']")).each do |p|
174
+ prev = p.previous_element
175
+ prev && prev.name == "p" &&
176
+ prev["type"] == "officeorgrepmember" and next
177
+ p.previous = <<~HDR
178
+ <p type='officeorgrepmemberhdr'><em>Organization
179
+ Represented</em><tab/><em>Name of Representative</em></p>
180
+ HDR
181
+ end
182
+ end
183
+
184
+ def participants1(list, idx)
185
+ key = ""
186
+ map = list.xpath(ns(".//dt | .//dd")).each_with_object({}) do |dtd, m|
187
+ (dtd.name == "dt" and key = dtd.text) or
188
+ m[key] = @c.encode(dtd.text.strip, :hexadecimal)
189
+ end
190
+ list.replace(participant_para(map, idx))
191
+ end
192
+
193
+ def participant_para(map, idx)
194
+ name = participant_name(map)
195
+ if map["role"]&.casecmp("member")&.zero?
196
+ participant_member_para(map, name, idx)
197
+ else
198
+ participant_officeholder_para(map, name, idx)
199
+ end
200
+ end
201
+
202
+ def participant_member_para(map, name, _idx)
203
+ if map["company"] && (map["name"] || map["surname"])
204
+ pers = map["name"] || "#{map['given']} #{map['surname']}"
205
+ "<p type='officeorgrepmember'>#{name}<tab/>#{pers}</p>"
206
+ elsif map["company"] then "<p type='officeorgmember'>#{name}</p>"
207
+ else "<p type='officemember'>#{name}</p>"
208
+ end
209
+ end
210
+
211
+ def participant_officeholder_para(map, name, idx)
212
+ name = "<strong>#{name}</strong>" if idx.zero?
213
+ br = map["role"].size > 30 ? "<br/>" : ""
214
+ "<p type='officeholder' align='center'>#{name}, #{br}"\
215
+ "<em>#{map['role']}</em></p>"
216
+ end
217
+
218
+ def participant_name(map)
219
+ map["company"] || map["name"] || "#{map['given']} #{map['surname']}"
220
+ end
221
+
86
222
  include Init
87
223
  end
88
224
  end