metanorma-ieee 0.0.1

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