Class: IsoDoc::NIST::WordConvert

Inherits:
WordConvert
  • Object
show all
Includes:
BaseConvert, Init
Defined in:
lib/isodoc/nist/word_convert.rb,
lib/isodoc/nist/word_convert_toc.rb

Overview

A Converter implementation that generates Word output, and a document schema encapsulation of the document for validation

Constant Summary collapse

WORD_TOC_APPENDIX_PREFACE1 =
<<~TOC.freeze
<span lang="EN-GB"><span
  style='mso-element:field-begin'></span><span
  style='mso-spacerun:yes'>&#xA0;</span>TOC
  \\h \\z \\t &quot;h1Annex,1,h2Annex,2,h3Annex,3&quot; <span
  style='mso-element:field-separator'></span></span>
TOC
WORD_TOC_TABLE_PREFACE1 =
<<~TOC.freeze
<span lang="EN-GB"><span
  style='mso-element:field-begin'></span><span
  style='mso-spacerun:yes'>&#xA0;</span>TOC
  \\h \\z \\t &quot;TableTitle,tabletitle&quot; <span
  style='mso-element:field-separator'></span></span>
TOC
WORD_TOC_FIGURE_PREFACE1 =
<<~TOC.freeze
<span lang="EN-GB"><span
  style='mso-element:field-begin'></span><span
  style='mso-spacerun:yes'>&#xA0;</span>TOC
  \\h \\z \\t &quot;FigureTitle,figuretitle&quot; <span
  style='mso-element:field-separator'></span></span>
TOC

Constants included from BaseConvert

BaseConvert::FRONT_CLAUSE, BaseConvert::NIST_PUBLISHER_XPATH

Instance Method Summary collapse

Methods included from Init

#fileloc, #i18n_init, #metadata_init, #suppress_biblio_title, #xref_init

Methods included from BaseConvert

#abstract, #bibliography, #bibliography_parse, #boilerplate, #bracket_if_num, #children_parse, #dl_parse, #errata_body, #errata_head, #errata_parse, #error_parse, #foreword, #info, #is_clause?, #keywords, #middle, #middle_clause, #modification_parse, #nistvariable_parse, #nonstd_bibitem, #ol_depth, #omit_docid_prefix, #preface, #preface1, #reference_format, #reference_format1, #requirement_cleanup, #skip_render, #std_bibitem_entry, #term_and_termref_parse, #term_cleanup, #term_rest_parse, #termref_parse, #terms_parse

Constructor Details

#initialize(options) ⇒ WordConvert

Returns a new instance of WordConvert.



14
15
16
17
18
19
20
21
# File 'lib/isodoc/nist/word_convert.rb', line 14

def initialize(options)
  @libdir = File.dirname(__FILE__)
  super
  @wordToClevels = options[:doctoclevels].to_i
  @wordToClevels = 3 if @wordToClevels.zero?
  @htmlToClevels = options[:htmltoclevels].to_i
  @htmlToClevels = 3 if @htmlToClevels.zero?
end

Instance Method Details

#authority_cleanup(docxml) ⇒ Object



102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/isodoc/nist/word_convert.rb', line 102

def authority_cleanup(docxml)
  docxml&.xpath("//div[@class = 'authority']//h1 | "\
                "//div[@class = 'authority']//h2")&.each do |h|
    h.name = "p"
    h["class"] = "IntroTitle"
  end
  dest1 = docxml.xpath("//div[@class = 'authority6' and "\
                       "not(@id = 'authority6')]")
  auth1 = docxml&.at("//div[@id = 'authority6']")&.remove
  dest1 and auth1 and dest1.each { |d| d.replace(auth1) }
  insert = docxml.at("//div[@class = 'WordSection2']")
  if @cswp
    auth = docxml&.at("//div[@class = 'authority']")&.remove || return
    insert.children.first.add_previous_sibling(auth)
  end
  authority_cleanup1(docxml)
end

#authority_cleanup1(docxml) ⇒ Object



120
121
122
123
124
125
126
127
128
129
# File 'lib/isodoc/nist/word_convert.rb', line 120

def authority_cleanup1(docxml)
  a = docxml.at("//div[@id = 'authority1']") and a["class"] = "authority1"
  a = docxml.at("//div[@id = 'authority2']") and a["class"] = "authority2"
  a = docxml.at("//div[@id = 'authority3']") and a["class"] = "authority3"
  a = docxml.at("//div[@id = 'authority3a']") and
    a["class"] = "authority3"
  a = docxml.at("//div[@id = 'authority4']") and a["class"] = "authority4"
  a = docxml.at("//div[@id = 'authority5']") and a["class"] = "authority5"
  a = docxml.at("//div[@id = 'authority6']") and a["class"] = "authority6"
end

#cleanup(docxml) ⇒ Object



131
132
133
134
135
136
137
138
139
# File 'lib/isodoc/nist/word_convert.rb', line 131

def cleanup(docxml)
  super
  term_cleanup(docxml)
  requirement_cleanup(docxml)
  h1_cleanup(docxml)
  word_annex_cleanup(docxml) # need it earlier
  word_preface_cleanup(docxml) # ditto, since early ToC insertion
  toc_insert(docxml, @wordToClevels)
end

#convert1(docxml, filename, dir) ⇒ Object



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/isodoc/nist/word_convert.rb', line 23

def convert1(docxml, filename, dir)
  @series =  docxml&.at(ns("//bibdata/series/abbreviation"))&.text
  @cswp = ["NIST CSWP", "NIST CSTS"].include?(@series)
  @bibliographycount =
    docxml.xpath(ns("//bibliography/references | //annex/references | "\
                    "//bibliography/clause/references")).size
  if @cswp
    @wordstylesheet_name = html_doc_path("wordstyle_cswp.scss")
    @standardstylesheet_name = html_doc_path("nist_cswp.scss")
    @wordcoverpage = html_doc_path("word_nist_titlepage_cswp.html")
    @wordintropage = html_doc_path("word_nist_intro_cswp.html")
    @header = html_doc_path("header_cswp.html")
  end
  super
end

#default_file_locations(_options) ⇒ Object



50
51
52
53
54
55
56
57
58
# File 'lib/isodoc/nist/word_convert.rb', line 50

def default_file_locations(_options)
  { wordstylesheet: html_doc_path("wordstyle.scss"),
    standardstylesheet: html_doc_path("nist.scss"),
    header: html_doc_path("header.html"),
    wordcoverpage: html_doc_path("word_nist_titlepage.html"),
    wordintropage: html_doc_path("word_nist_intro.html"),
    ulstyle: "l3",
    olstyle: "l2" }
end

#default_fonts(options) ⇒ Object



39
40
41
42
43
44
45
46
47
48
# File 'lib/isodoc/nist/word_convert.rb', line 39

def default_fonts(options)
  { bodyfont: '"Times New Roman",serif',
    headerfont: '"Arial",sans-serif',
    monospacefont: '"Courier New",monospace',
    normalfontsize: "12.0pt",
    footnotefontsize: "10.0pt",
    monospacefontsize: "10.0pt",
    smallerfontsize: "10.0pt",
  }
end

#glossary_parse(node, out) ⇒ Object



197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
# File 'lib/isodoc/nist/word_convert.rb', line 197

def glossary_parse(node, out)
  out.table  **attr_code(id: node["id"], class: "terms_dl") do |t|
    node.elements.select { |n| dt_dd? n }.each_slice(2) do |dt, dd|
      t.tr do |v|
        v.td **attr_code(id: dt["id"], valign: "top", align: "left") do |term|
          dt_parse(dt, term)
        end
        v.td  **attr_code(id: dd["id"], valign: "top") do |listitem|
          dd.children.each { |n| parse(n, listitem) }
        end
      end
    end
  end
  node.elements.reject { |n| dt_dd? n }.each { |n| parse(n, out) }
end

#h1_cleanup(docxml) ⇒ Object

create fallback h1 class to deal with page breaks



142
143
144
145
146
# File 'lib/isodoc/nist/word_convert.rb', line 142

def h1_cleanup(docxml)
  docxml.xpath("//h1[not(@class)]").each do |h|
    h["class"] = "NormalTitle"
  end
end

#header_strip(h) ⇒ Object



50
51
52
53
54
# File 'lib/isodoc/nist/word_convert_toc.rb', line 50

def header_strip(h)
  h = h.to_s.gsub(/<\/?p[^>]*>/, "").
    gsub(%r{<a [^>]+>[^<]+</a><aside>.*</aside>}m, "")
  super
end

#make_AppendixWordToC(docxml) ⇒ Object



74
75
76
77
78
79
80
81
82
# File 'lib/isodoc/nist/word_convert_toc.rb', line 74

def make_AppendixWordToC(docxml)
  toc = ""
  docxml.xpath("//p[@class = 'h1Annex'] | //p[@class = 'h2Annex'] | "\
               "p[@class = 'h3Annex']").each do |h|
    toc += word_toc_entry(h["class"][1].to_i, header_strip(h))
  end
  toc.sub(/(<p class="MsoToc1">)/,
          %{\\1#{WORD_TOC_APPENDIX_PREFACE1}}) +  WORD_TOC_SUFFIX1
end

#make_body(xml, docxml) ⇒ Object



60
61
62
63
64
65
66
67
# File 'lib/isodoc/nist/word_convert.rb', line 60

def make_body(xml, docxml)
  body_attr = { lang: "EN-US", link: "blue", vlink: "#954F72" }
  xml.body **body_attr do |body|
    make_body1(body, docxml)
    make_body2(body, docxml)
    make_body3(body, docxml)
  end
end

#make_body2(body, docxml) ⇒ Object



69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/isodoc/nist/word_convert.rb', line 69

def make_body2(body, docxml)
  body.div **{ class: "WordSection2" } do |div2|
    @prefacenum = 0
    info docxml, div2
    preface_block docxml, div2
    foreword docxml, div2
    abstract docxml, div2
    keywords docxml, div2
    boilerplate docxml, div2
    preface docxml, div2
    div2.p { |p| p << "&nbsp;" } # placeholder
  end
  section_break(body)
end

#make_FigureWordToC(docxml) ⇒ Object



65
66
67
68
69
70
71
72
# File 'lib/isodoc/nist/word_convert_toc.rb', line 65

def make_FigureWordToC(docxml)
  toc = ""
  docxml.xpath("//p[@class = 'FigureTitle']").each do |h|
    toc += word_toc_entry(1, header_strip(h))
  end
  toc.sub(/(<p class="MsoToc1">)/,
          %{\\1#{WORD_TOC_FIGURE_PREFACE1}}) +  WORD_TOC_SUFFIX1
end

#make_TableWordToC(docxml) ⇒ Object



56
57
58
59
60
61
62
63
# File 'lib/isodoc/nist/word_convert_toc.rb', line 56

def make_TableWordToC(docxml)
  toc = ""
  docxml.xpath("//p[@class = 'TableTitle']").each do |h|
    toc += word_toc_entry(1, header_strip(h))
  end
  toc.sub(/(<p class="MsoToc1">)/,
          %{\\1#{WORD_TOC_TABLE_PREFACE1}}) +  WORD_TOC_SUFFIX1
end

#termdef_parse(node, out) ⇒ Object



184
185
186
187
188
189
190
191
192
193
194
195
# File 'lib/isodoc/nist/word_convert.rb', line 184

def termdef_parse(node, out)
  out.table **{ class: "terms_dl" } do |dl|
    dl.tr do |tr|
      tr.td **{ valign: "top", align: "left" } do |dt|
        term_and_termref_parse(node, dt)
      end
      tr.td **{ valign: "top" } do |dd|
        term_rest_parse(node, dd)
      end
    end
  end
end

#toc_insert(docxml, level) ⇒ Object



4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# File 'lib/isodoc/nist/word_convert_toc.rb', line 4

def toc_insert(docxml, level)
  insertion = docxml.at("//div[h1 = 'Executive Summary']/"\
                        "preceding-sibling::div[h1][1]") ||
  docxml.at("//div[@class = 'WordSection2']/child::*[last()]")
  if docxml.at("//p[@class = 'TableTitle']")
    insertion.next = make_TableWordToC(docxml)
    insertion.next = %{<p class="TOCTitle">List of Tables</p>}
  end
  if docxml.at("//p[@class = 'FigureTitle']")
    insertion.next = make_FigureWordToC(docxml)
    insertion.next = %{<p class="TOCTitle">List of Figures</p>}
  end
  if docxml.at("//p[@class = 'h1Annex']")
    insertion.next = make_AppendixWordToC(docxml)
    insertion.next = %{<p class="TOCTitle">List of Appendices</p>}
  end
  insertion.next = make_WordToC(docxml, level)
  insertion.next = %{<p class="TOCTitle" style="page-break-before:
  always;">Table of Contents</p>}
  docxml
end

#toWord(result, filename, dir, header) ⇒ Object



84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/isodoc/nist/word_convert.rb', line 84

def toWord(result, filename, dir, header)
  result = populate_template(result, :word)
  result = from_xhtml(word_cleanup(to_xhtml(result)))
  unless @landscapestyle.nil? || @landscapestyle.empty?
    @wordstylesheet&.open
    @wordstylesheet&.write(@landscapestyle)
    @wordstylesheet&.close
  end
  Html2Doc.process(result, filename: filename,
                   stylesheet: @wordstylesheet&.path,
                   header_file: header&.path, dir: dir,
                   asciimathdelims: [@openmathdelim, @closemathdelim],
                   liststyles: { ul: @ulstyle, ol: @olstyle,
                                 steps: "l4" })
  header&.unlink
  @wordstylesheet&.unlink
end

#word_annex_cleanup(docxml) ⇒ Object



155
156
157
158
159
160
161
162
# File 'lib/isodoc/nist/word_convert.rb', line 155

def word_annex_cleanup(docxml)
  word_annex_cleanup1(docxml, 1)
  word_annex_cleanup1(docxml, 2)
  word_annex_cleanup1(docxml, 3)
  word_annex_cleanup1(docxml, 4)
  word_annex_cleanup1(docxml, 5)
  word_annex_cleanup1(docxml, 6)
end

#word_annex_cleanup1(docxml, i) ⇒ Object



148
149
150
151
152
153
# File 'lib/isodoc/nist/word_convert.rb', line 148

def word_annex_cleanup1(docxml, i)
  docxml.xpath("//h#{i}[ancestor::*[@class = 'Section3']]").each do |h2|
    h2.name = "p"
    h2["class"] = "h#{i}Annex"
  end
end

#word_cleanup(docxml) ⇒ Object



178
179
180
181
182
# File 'lib/isodoc/nist/word_convert.rb', line 178

def word_cleanup(docxml)
  super
  word_preface_cleanup(docxml)
  docxml
end

#word_preface_cleanup(docxml) ⇒ Object



164
165
166
167
168
169
170
171
172
173
174
175
176
# File 'lib/isodoc/nist/word_convert.rb', line 164

def word_preface_cleanup(docxml)
  docxml.xpath("//h1[@class = 'AbstractTitle'] | "\
               "//h1[@class = 'IntroTitle'] | "\
               "//h1[@class = 'ForewordTitle'] |
               //h1[parent::div/@class = 'authority']").each do |h2|
    h2.name = "p"
    h2["class"] = "h1Preface"
  end
  docxml.xpath("//h2[ancestor::div/@class = 'authority']").each do |h2|
    h2.name = "p"
    h2["class"] = "h2Preface"
  end
end