metanorma-ieee 0.0.1

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 (59) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/rake.yml +13 -0
  3. data/.rubocop.yml +10 -0
  4. data/CODE_OF_CONDUCT.md +74 -0
  5. data/Gemfile +11 -0
  6. data/LICENSE +25 -0
  7. data/README.adoc +30 -0
  8. data/Rakefile +8 -0
  9. data/bin/console +14 -0
  10. data/bin/rspec +17 -0
  11. data/bin/setup +8 -0
  12. data/lib/html2doc/ieee.rb +89 -0
  13. data/lib/isodoc/ieee/base_convert.rb +33 -0
  14. data/lib/isodoc/ieee/html/header.html +146 -0
  15. data/lib/isodoc/ieee/html/html_ieee_intro.html +12 -0
  16. data/lib/isodoc/ieee/html/html_ieee_titlepage.html +44 -0
  17. data/lib/isodoc/ieee/html/htmlstyle.css +1027 -0
  18. data/lib/isodoc/ieee/html/htmlstyle.scss +736 -0
  19. data/lib/isodoc/ieee/html/ieee.css +3603 -0
  20. data/lib/isodoc/ieee/html/ieee.scss +3418 -0
  21. data/lib/isodoc/ieee/html/scripts.html +70 -0
  22. data/lib/isodoc/ieee/html/word_ieee_intro.html +70 -0
  23. data/lib/isodoc/ieee/html/word_ieee_titlepage.html +28 -0
  24. data/lib/isodoc/ieee/html/wordstyle.css +5310 -0
  25. data/lib/isodoc/ieee/html/wordstyle.scss +5026 -0
  26. data/lib/isodoc/ieee/html_convert.rb +52 -0
  27. data/lib/isodoc/ieee/i18n-en.yaml +28 -0
  28. data/lib/isodoc/ieee/i18n.rb +19 -0
  29. data/lib/isodoc/ieee/ieee.amendment.xsl +11177 -0
  30. data/lib/isodoc/ieee/ieee.rb +11 -0
  31. data/lib/isodoc/ieee/ieee.standard.xsl +11177 -0
  32. data/lib/isodoc/ieee/init.rb +28 -0
  33. data/lib/isodoc/ieee/metadata.rb +136 -0
  34. data/lib/isodoc/ieee/pdf_convert.rb +24 -0
  35. data/lib/isodoc/ieee/presentation_terms.rb +181 -0
  36. data/lib/isodoc/ieee/presentation_xml_convert.rb +89 -0
  37. data/lib/isodoc/ieee/word_authority.rb +160 -0
  38. data/lib/isodoc/ieee/word_cleanup.rb +134 -0
  39. data/lib/isodoc/ieee/word_convert.rb +75 -0
  40. data/lib/isodoc/ieee/xref.rb +77 -0
  41. data/lib/isodoc/ieee.rb +11 -0
  42. data/lib/metanorma/ieee/basicdoc.rng +1150 -0
  43. data/lib/metanorma/ieee/biblio.rng +1385 -0
  44. data/lib/metanorma/ieee/boilerplate.xml +298 -0
  45. data/lib/metanorma/ieee/cleanup.rb +160 -0
  46. data/lib/metanorma/ieee/converter.rb +81 -0
  47. data/lib/metanorma/ieee/front.rb +120 -0
  48. data/lib/metanorma/ieee/ieee.rng +97 -0
  49. data/lib/metanorma/ieee/isodoc.rng +2776 -0
  50. data/lib/metanorma/ieee/processor.rb +56 -0
  51. data/lib/metanorma/ieee/reqt.rng +226 -0
  52. data/lib/metanorma/ieee/validate.rb +198 -0
  53. data/lib/metanorma/ieee/validate_section.rb +119 -0
  54. data/lib/metanorma/ieee/validate_style.rb +108 -0
  55. data/lib/metanorma/ieee/version.rb +5 -0
  56. data/lib/metanorma/ieee.rb +11 -0
  57. data/lib/metanorma-ieee.rb +8 -0
  58. data/metanorma-itu.gemspec +41 -0
  59. metadata +284 -0
@@ -0,0 +1,28 @@
1
+ require "isodoc"
2
+ require_relative "metadata"
3
+ require_relative "xref"
4
+ require_relative "i18n"
5
+
6
+ module IsoDoc
7
+ module IEEE
8
+ module Init
9
+ def metadata_init(lang, script, i18n)
10
+ @meta = Metadata.new(lang, script, i18n)
11
+ end
12
+
13
+ def xref_init(lang, script, _klass, i18n, options)
14
+ html = HtmlConvert.new(language: lang, script: script)
15
+ options = options.merge(hierarchical_assets: @hierarchical_assets)
16
+ @xrefs = Xref.new(lang, script, html, i18n, options)
17
+ end
18
+
19
+ def i18n_init(lang, script, i18nyaml = nil)
20
+ @i18n = I18n.new(lang, script, i18nyaml: i18nyaml || @i18nyaml)
21
+ end
22
+
23
+ def fileloc(loc)
24
+ File.join(File.dirname(__FILE__), loc)
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,136 @@
1
+ require "isodoc"
2
+ require "twitter_cldr"
3
+
4
+ module IsoDoc
5
+ module IEEE
6
+ class Metadata < IsoDoc::Metadata
7
+ def initialize(lang, script, i18n, fonts_options = {})
8
+ super
9
+ @metadata[:confirmeddate] = "&lt;Date Approved&gt;"
10
+ end
11
+
12
+ def bibdate(isoxml, _out)
13
+ super
14
+ draft = isoxml.at(ns("//bibdata/date[@type = 'issued']")) ||
15
+ isoxml.at(ns("//bibdata/date[@type = 'circulated']")) ||
16
+ isoxml.at(ns("//bibdata/date[@type = 'created']")) ||
17
+ isoxml.at(ns("//bibdata/version/revision-date")) or return
18
+ date = DateTime.parse(draft.text)
19
+ set(:draft_month, date.strftime("%B"))
20
+ set(:draft_year, date.strftime("%Y"))
21
+ rescue StandardError
22
+ end
23
+
24
+ def doctype(isoxml, _out)
25
+ b = isoxml.at(ns("//bibdata/ext/doctype"))&.text or return
26
+ set(:doctype, b.split(/[- ]/).map(&:capitalize).join(" "))
27
+ set(:doctype_abbrev, @labels["doctype_abbrev"][b])
28
+ s = isoxml.at(ns("//bibdata/ext/docsubtype"))&.text and
29
+ set(:docsubtype, s.split(/[- ]/).map(&:capitalize).join(" "))
30
+ end
31
+
32
+ def author(xml, _out)
33
+ super
34
+ society(xml)
35
+ tc(xml)
36
+ wg(xml)
37
+ bg(xml)
38
+ std_group(xml)
39
+ end
40
+
41
+ def society(xml)
42
+ society = xml.at(ns("//bibdata/ext/editorialgroup/"\
43
+ "society"))&.text || "&lt;Society&gt;"
44
+ set(:society, society)
45
+ end
46
+
47
+ def tc(xml)
48
+ tc = xml.at(ns("//bibdata/ext/editorialgroup/"\
49
+ "technical-committee"))&.text || "&lt;Committee Name&gt;"
50
+ set(:technical_committee, tc)
51
+ end
52
+
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
+ def wg(xml)
64
+ wg = xml.at(ns("//bibdata/ext/editorialgroup/"\
65
+ "working-group")) or return nil
66
+ 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
+ end
82
+
83
+ def bg(xml)
84
+ bg = xml.at(ns("//bibdata/ext/editorialgroup/"\
85
+ "balloting-group")) or return nil
86
+ 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)
106
+ end
107
+
108
+ def otherid(isoxml, _out)
109
+ id = "bibdata/docidentifier[@type = 'ISBN']"
110
+ dn = isoxml.at(ns("//#{id}[@scope = 'PDF']"))
111
+ set(:isbn_pdf, dn&.text || "978-0-XXXX-XXXX-X")
112
+ dn = isoxml.at(ns("//#{id}[@scope = 'print']"))
113
+ set(:isbn_print, dn&.text || "978-0-XXXX-XXXX-X")
114
+ end
115
+
116
+ def docid(isoxml, _out)
117
+ super
118
+ id = "bibdata/docidentifier[@type = 'IEEE']"
119
+ dn = isoxml.at(ns("//#{id}[@scope = 'PDF']"))
120
+ set(:stdid_pdf, dn&.text || "STDXXXXX")
121
+ dn = isoxml.at(ns("//#{id}[@scope = 'print']"))
122
+ set(:stdid_print, dn&.text || "STDPDXXXXX")
123
+ end
124
+
125
+ def title(isoxml, _out)
126
+ super
127
+ draft = isoxml&.at(ns("//bibdata/version/draft"))
128
+ doctype(isoxml, _out)
129
+ title = "#{@metadata[:doctype_abbrev] || '???'} for "\
130
+ "#{@metadata[:doctitle] || '???'}"
131
+ draft and title = "Draft #{title}"
132
+ set(:full_doctitle, title)
133
+ end
134
+ end
135
+ end
136
+ end
@@ -0,0 +1,24 @@
1
+ require "isodoc"
2
+ require "fileutils"
3
+
4
+ module IsoDoc
5
+ module IEEE
6
+ # A {Converter} implementation that generates PDF HTML output, and a
7
+ # document schema encapsulation of the document for validation
8
+ class PdfConvert < IsoDoc::XslfoPdfConvert
9
+ def initialize(options)
10
+ @libdir = File.dirname(__FILE__)
11
+ super
12
+ end
13
+
14
+ def pdf_stylesheet(docxml)
15
+ doctype = docxml&.at(ns("//bibdata/ext/doctype"))&.text
16
+ if doctype == "amendment"
17
+ "ieee.amendment.xsl"
18
+ else
19
+ "ieee.standard.xsl"
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,181 @@
1
+ module IsoDoc
2
+ module IEEE
3
+ class PresentationXMLConvert < IsoDoc::PresentationXMLConvert
4
+ def multidef(elem)
5
+ number_multidef(elem)
6
+ collapse_multidef(elem)
7
+ end
8
+
9
+ def number_multidef(elem)
10
+ c = IsoDoc::XrefGen::Counter.new("@")
11
+ elem.xpath(ns("./definition")).each do |d|
12
+ c.increment(d)
13
+ d.elements.first.previous = "<strong>(#{c.print})</strong>&#xa0;"
14
+ end
15
+ end
16
+
17
+ def collapse_multidef(elem)
18
+ ins = elem.at(ns("./definition")).previous_element
19
+ coll = elem.xpath(ns("./definition"))
20
+ coll.each(&:remove)
21
+ ins.next = "<definition>#{coll.map do |c|
22
+ c.children.to_xml
23
+ end }</definition>"
24
+ end
25
+
26
+ def unwrap_definition(docxml)
27
+ docxml.xpath(ns("//definition/verbal-definition")).each do |v|
28
+ next unless v.elements.all? { |e| %w(termsource p).include?(e.name) }
29
+
30
+ s = v.xpath(ns("./termsource"))
31
+ p = v.xpath(ns("./p"))
32
+ v.children =
33
+ "<p>#{p.map(&:children).map(&:to_xml).join("\n")}</p>#{s.to_xml}"
34
+ end
35
+ super
36
+ end
37
+
38
+ def related(docxml)
39
+ docxml.xpath(ns("//term[related]")).each { |f| related_term(f) }
40
+ end
41
+
42
+ def related_term(term)
43
+ coll = term_related_reorder(term.xpath(ns("./related")))
44
+ term_related_collapse(coll)
45
+ end
46
+
47
+ def term_related_collapse(coll)
48
+ prev = 0
49
+ 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
55
+ end
56
+ end
57
+ end
58
+
59
+ def sort_terms_key(term)
60
+ d = term.at(ns("./preferred/expression/name | "\
61
+ "./preferred/letter-designation/name | "\
62
+ "./preferred/graphical-symbol/figure/name | "\
63
+ "./preferred/graphical-symbol/figure/@id"))
64
+ d&.text&.downcase
65
+ end
66
+
67
+ def term_related_reorder(coll)
68
+ ins = coll.first.previous_element
69
+ ret = sort_related(coll)
70
+ coll.each(&:remove)
71
+ ret.reverse.each { |t| ins.next = t }
72
+ ins.parent.xpath(ns("./related"))
73
+ end
74
+
75
+ def sort_related(coll)
76
+ coll.sort do |a, b|
77
+ sort_related_key(a) <=> sort_related_key(b)
78
+ end
79
+ end
80
+
81
+ def sort_related_key(related)
82
+ type = case related["type"]
83
+ when "contrast" then 1
84
+ when "equivalent" then 2
85
+ when "see" then 3
86
+ when "seealso" then 4
87
+ else "5-#{related['type']}"
88
+ end
89
+ "#{type} :: #{sort_terms_key(related)}"
90
+ end
91
+
92
+ def terms(docxml)
93
+ admitted_to_related docxml
94
+ super
95
+ collapse_term docxml
96
+ end
97
+
98
+ 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>"
103
+ end
104
+ end
105
+
106
+ def collapse_term(docxml)
107
+ docxml.xpath(ns("//term")).each do |t|
108
+ collapse_term1(t)
109
+ end
110
+ end
111
+
112
+ def collapse_term1(term)
113
+ ret = collapse_term_template(
114
+ pref: term.at(ns("./preferred")).remove,
115
+ def: term.at(ns("./definition")),
116
+ rels: term.xpath(ns("./related")).map(&:remove),
117
+ source: term.at(ns("./termsource")),
118
+ )
119
+ (ins = term.elements.first and ins.previous = ret) or
120
+ term << ret
121
+ end
122
+
123
+ def collapse_term_related(rels)
124
+ ret = rels.map do |r|
125
+ "<em>#{@i18n.relatedterms[r['type']]}:</em> "\
126
+ "#{r.at(ns('./preferred')).children.to_xml}"
127
+ end.join(". ")
128
+ ret += "." unless ret.empty?
129
+ ret
130
+ end
131
+
132
+ def collapse_term_template(opt)
133
+ defn = collapse_unwrap_definition(opt[:def])
134
+ source = opt[:source] ? "(#{opt[:source].remove.children.to_xml})" : nil
135
+ <<~TERM
136
+ <p>#{opt[:pref].children.to_xml}: #{defn}
137
+ #{collapse_term_related(opt[:rels])}
138
+ #{source}</p>
139
+ TERM
140
+ end
141
+
142
+ def collapse_unwrap_definition(defn)
143
+ return nil if defn.nil?
144
+
145
+ s = defn.remove.xpath(ns("./termsource"))
146
+ p = defn.at(ns("./p"))
147
+ !s.empty? && p and p << s.map(&:remove).map(&:children).map(&:to_xml).join
148
+ if defn.elements.size == 1 && defn.elements.first.name == "p"
149
+ defn.elements.first.children
150
+ else defn.elements
151
+ end
152
+ end
153
+
154
+ def termsource1(elem)
155
+ while elem&.next_element&.name == "termsource"
156
+ elem << "; #{elem.next_element.remove.children.to_xml}"
157
+ end
158
+ end
159
+
160
+ def designation_field(desgn, name)
161
+ if desgn.name == "preferred"
162
+ f = desgn.xpath(ns("./../domain | ./../subject")).map(&:remove)
163
+ .map { |u| u.children.to_xml }.join(", ")
164
+ name << ", &#x3c;#{f}&#x3e;" unless f.empty?
165
+ end
166
+ super
167
+ end
168
+
169
+ 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
176
+ end
177
+
178
+ def term(docxml); end
179
+ end
180
+ end
181
+ end
@@ -0,0 +1,89 @@
1
+ require_relative "init"
2
+ require_relative "presentation_terms"
3
+ require "isodoc"
4
+
5
+ module IsoDoc
6
+ module IEEE
7
+ class PresentationXMLConvert < IsoDoc::PresentationXMLConvert
8
+ def initialize(options)
9
+ @hierarchical_assets = options[:hierarchical_assets]
10
+ super
11
+ end
12
+
13
+ def eref_localities_conflated(refs, target, node)
14
+ droploc = node["droploc"]
15
+ node["droploc"] = true
16
+ ret = resolve_eref_connectives(eref_locality_stacks(refs, target,
17
+ node))
18
+ node["droploc"] = droploc
19
+ eref_localities1(target,
20
+ prefix_clause(target, refs.first.at(ns("./locality"))),
21
+ l10n(ret[1..-1].join), nil, node, @lang)
22
+ end
23
+
24
+ def prefix_clause(target, loc)
25
+ loc["type"] == "clause" or return loc["type"]
26
+
27
+ if subclause?(target, loc["type"],
28
+ loc&.at(ns("./referenceFrom"))&.text)
29
+ ""
30
+ else "clause"
31
+ end
32
+ end
33
+
34
+ def subclause?(target, type, from)
35
+ (from&.match?(/\./) && type == "clause") ||
36
+ target&.gsub(/<[^>]+>/, "")&.match(/^IEV$|^IEC 60050-/)
37
+ end
38
+
39
+ def eref_localities1(target, type, from, upto, node, lang = "en")
40
+ return nil if type == "anchor"
41
+
42
+ type = type.downcase
43
+ lang == "zh" and
44
+ return l10n(eref_localities1_zh(target, type, from, upto,
45
+ node))
46
+ ret = ""
47
+ node["droploc"] != "true" && !subclause?(target, type,
48
+ from) and
49
+ ret = eref_locality_populate(type, node)
50
+ ret += " #{from}" if from
51
+ ret += "&#x2013;#{upto}" if upto
52
+ ret += ")" if type == "list"
53
+ l10n(ret)
54
+ end
55
+
56
+ def anchor_linkend1(node)
57
+ linkend = @xrefs.anchor(node["target"], :xref)
58
+ @xrefs.anchor(node["target"], :type) == "clause" &&
59
+ @xrefs.anchor(node["target"], :level) > 1 &&
60
+ !start_of_sentence(node) and
61
+ linkend = linkend.sub(/^Clause /, "")
62
+ container = @xrefs.anchor(node["target"], :container, false)
63
+ prefix_container?(container, node) and
64
+ linkend = prefix_container(container, linkend, node["target"])
65
+ capitalise_xref(node, linkend, anchor_value(node["target"]))
66
+ end
67
+
68
+ def block_delim
69
+ "&#x2014;"
70
+ end
71
+
72
+ def display_order(docxml)
73
+ i = 0
74
+ i = display_order_xpath(docxml, "//preface/*", i)
75
+ i = display_order_at(docxml, "//clause[@type = 'overview']", i)
76
+ i = display_order_at(docxml, @xrefs.klass.norm_ref_xpath, i)
77
+ i = display_order_at(docxml, "//sections/terms | "\
78
+ "//sections/clause[descendant::terms]", i)
79
+ i = display_order_at(docxml, "//sections/definitions", i)
80
+ i = display_order_xpath(docxml, @xrefs.klass.middle_clause(docxml), i)
81
+ i = display_order_xpath(docxml, "//annex", i)
82
+ i = display_order_xpath(docxml, @xrefs.klass.bibliography_xpath, i)
83
+ display_order_xpath(docxml, "//indexsect", i)
84
+ end
85
+
86
+ include Init
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,160 @@
1
+ module IsoDoc
2
+ module IEEE
3
+ class WordConvert < IsoDoc::WordConvert
4
+ def authority_cleanup(docxml)
5
+ feedback_footnote(docxml)
6
+ %w(copyright license disclaimers participants).each do |t|
7
+ authority_cleanup1(docxml, t)
8
+ end
9
+ coverpage_note_cleanup(docxml)
10
+ authority_style(docxml)
11
+ end
12
+
13
+ def feedback_footnote(docxml)
14
+ feedback_style(docxml)
15
+ feedback_table(docxml)
16
+ f = docxml.at("//div[@class = 'boilerplate-feedback']") or return
17
+ docxml.at("//aside").previous = <<~FN
18
+ <aside id="ftn0">#{f.remove.to_xml}</aside>
19
+ FN
20
+ end
21
+
22
+ def authority_style(docxml)
23
+ copyright_style(docxml)
24
+ license_style(docxml)
25
+ officer_style(docxml)
26
+ end
27
+
28
+ def copyright_style(docxml)
29
+ docxml.at("//div[@class = 'boilerplate-copyright']")&.xpath(".//p")
30
+ &.reverse&.each_with_index do |p, i|
31
+ p["class"] =
32
+ i.zero? ? "IEEEStdsTitleDraftCRBody" : "IEEEStdsTitleDraftCRaddr"
33
+ end
34
+ end
35
+
36
+ def license_style(docxml)
37
+ docxml.at("//div[@class = 'boilerplate-license']")&.xpath(".//p")
38
+ &.reverse&.each_with_index do |p, i|
39
+ p["class"] =
40
+ i.zero? ? "IEEEStdsTitleDraftCRBody" : "IEEEStdsTitleDraftCRaddr"
41
+ end
42
+ end
43
+
44
+ def officer_style(docxml)
45
+ docxml.xpath("//p[@type = 'officeholder']").each do |p|
46
+ officeholder_style(p)
47
+ end
48
+ officemember_style(docxml)
49
+ three_column_officemembers(docxml
50
+ .at("//div[@id = 'boilerplate-participants']"))
51
+ end
52
+
53
+ def officeholder_style(para)
54
+ n = para.next_element
55
+ p = para.previous_element
56
+ n && n.name == "p" && n["type"] == "officeholder" and
57
+ klass = "IEEEStdsNamesCtrCxSpLast"
58
+ p && p.name == "p" && p["type"] == "officeholder" and
59
+ klass = "IEEEStdsNamesCtrCxSpFirst"
60
+ para["class"] = klass || "IEEEStdsNamesCtrCxSpMiddle"
61
+ end
62
+
63
+ SECTIONBREAK = <<~BREAK.freeze
64
+ <span lang="EN-US" style='font-size:9.0pt;mso-bidi-font-size:10.0pt;font-family:
65
+ "Times New Roman",serif;mso-fareast-font-family:"Times New Roman";mso-ansi-language:
66
+ EN-US;mso-fareast-language:JA;mso-bidi-language:AR-SA'><br clear="all"
67
+ style='page-break-before:auto;mso-break-type:section-break'></span>
68
+ BREAK
69
+
70
+ def officemember_style(docxml)
71
+ docxml.xpath("//p[@type = 'officemember']").each do |p|
72
+ p["class"] = "IEEEStdsNamesList"
73
+ end
74
+ docxml.xpath("//p[@type = 'emeritus_sign']").each do |p|
75
+ p["class"] = "IEEEStdsParaMemEmeritus"
76
+ end
77
+ end
78
+
79
+ def three_column_officemembers(div)
80
+ return unless div
81
+
82
+ ret = three_column_officemembers_split(div)
83
+ three_column_officemembers_render(div, ret)
84
+ end
85
+
86
+ def three_column_officemembers_split(div)
87
+ prev = false
88
+ div.elements.each_with_object([[]]) do |e, m|
89
+ member = e.name == "p" && e["type"] == "officemember"
90
+ (prev == member and m[-1] << e.to_xml) or m << [e.to_xml]
91
+ prev = member
92
+ end.map(&:join)
93
+ end
94
+
95
+ def three_column_officemembers_render(div, ret)
96
+ div.children = ret[0]
97
+ out = ret[1..-1].map.with_index do |d, i|
98
+ para = i % 2 == 1 && i != ret.size - 2 ? "<p>&#xa0;</p>" : ""
99
+ "<div class='WordSection'>#{para}#{d}</div>"
100
+ end.join(SECTIONBREAK)
101
+ div.document.at("//div[@class = 'WordSection11']")
102
+ .previous_element.previous = SECTIONBREAK + out
103
+ end
104
+
105
+ def feedback_table(docxml)
106
+ docxml.at("//div[@class = 'boilerplate-feedback']")&.xpath(".//table")
107
+ &.each do |t|
108
+ t.xpath(".//tr").each do |tr|
109
+ feedback_table1(tr)
110
+ end
111
+ t.replace(t.at(".//tbody").elements)
112
+ end
113
+ end
114
+
115
+ def feedback_table1(trow)
116
+ trow.name = "p"
117
+ trow["class"] = "IEEEStdsCRTextReg"
118
+ trow.xpath("./td").each do |td|
119
+ td.next_element and td << "<span style='mso-tab-count:1'> </span>"
120
+ td.replace(td.children)
121
+ end
122
+ end
123
+
124
+ def feedback_style(docxml)
125
+ docxml.at("//div[@class = 'boilerplate-feedback']")&.xpath("./div")
126
+ &.each_with_index do |div, i|
127
+ i.zero? or div.elements.first.previous = "<p>&#xa0;</p>"
128
+ feedback_style1(div, i)
129
+ end
130
+ end
131
+
132
+ def feedback_style1(div, idx)
133
+ div.xpath(".//p").each_with_index do |p, j|
134
+ p["class"] = idx == 4 ? "IEEEStdsCRTextItal" : "IEEEStdsCRTextReg"
135
+ j.zero? && idx.zero? and
136
+ p.children.first.previous =
137
+ '<a style="mso-footnote-id:ftn0" href="#_ftnref0" name="_ftn0" title=""/>'
138
+ end
139
+ end
140
+
141
+ def authority_cleanup1(docxml, klass)
142
+ dest = docxml.at("//div[@id = 'boilerplate-#{klass}-destination']")
143
+ auth = docxml.at("//div[@id = 'boilerplate-#{klass}' "\
144
+ "or @class = 'boilerplate-#{klass}']")
145
+ auth&.xpath(".//h1[not(text())] | .//h2[not(text())]")&.each(&:remove)
146
+ authority_cleanup_hdr(auth)
147
+ dest and auth and dest.replace(auth.remove)
148
+ end
149
+
150
+ def authority_cleanup_hdr(auth)
151
+ (1..2).each do |i|
152
+ auth&.xpath(".//h#{i}")&.each do |h|
153
+ h.name = "p"
154
+ h["class"] = "IEEEStdsLevel#{i}frontmatter"
155
+ end
156
+ end
157
+ end
158
+ end
159
+ end
160
+ end