Module: IsoDoc::WordFunction::Body

Included in:
IsoDoc::WordConvert
Defined in:
lib/isodoc/word_function/body.rb

Constant Summary collapse

SW1 =
"solid windowtext".freeze
WORD_DT_ATTRS =
{class: @note ? "Note" : nil, align: "left",
style: "margin-left:0pt;text-align:left;"}.freeze

Instance Method Summary collapse

Instance Method Details

#body_attrObject

def anchor_names(docxml)

  super
  renumber_footnotes(docxml)
end

# undo merger of seen footnotes
def renumber_footnotes(docxml)
  docxml.xpath(ns("//fn[not(ancestor::table or "\
                  "ancestor::figure)]")).each_with_index do |f, i|
    f["reference"] = (i + 1).to_s
  end
end


28
29
30
# File 'lib/isodoc/word_function/body.rb', line 28

def body_attr
  { lang: "EN-US", link: "blue", vlink: "#954F72" }
end

#define_head(head, filename, _dir) ⇒ Object



3
4
5
6
7
8
9
10
11
# File 'lib/isodoc/word_function/body.rb', line 3

def define_head(head, filename, _dir)
  head.style do |style|
    loc = File.join(File.dirname(__FILE__), "..", "base_style",
                    "metanorma_word.scss")
    stylesheet = File.read(loc, encoding: "utf-8")
    style.comment "\n#{stylesheet}\n"
  end
  super
end

#dl_parse(node, out) ⇒ Object



133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'lib/isodoc/word_function/body.rb', line 133

def dl_parse(node, out)
  out.table **{ class: "dl" } do |v|
    node.elements.select { |n| dt_dd? n }.each_slice(2) do |dt, dd|
      v.tr do |tr|
        tr.td **{ valign: "top", align: "left" } do |term|
          dt_parse(dt, term)
        end
        tr.td **{ valign: "top" } do |listitem|
          dd.children.each { |n| parse(n, listitem) }
        end
      end
    end
    dl_parse_notes(node, v)
  end
end

#dl_parse_notes(node, v) ⇒ Object



149
150
151
152
153
154
155
156
# File 'lib/isodoc/word_function/body.rb', line 149

def dl_parse_notes(node, v)
  return if node.elements.reject { |n| dt_dd? n }.empty?
  v.tr do |tr|
    tr.td **{ colspan: 2 } do |td|
      node.elements.reject { |n| dt_dd? n }.each { |n| parse(n, td) }
    end
  end
end

#dt_parse(dt, term) ⇒ Object



123
124
125
126
127
128
129
130
131
# File 'lib/isodoc/word_function/body.rb', line 123

def dt_parse(dt, term)
  term.p **attr_code(WORD_DT_ATTRS) do |p|
    if dt.elements.empty?
      p << dt.text
    else
      dt.children.each { |n| parse(n, p) }
    end
  end
end

#example_table_attr(node) ⇒ Object



247
248
249
250
251
252
253
254
# File 'lib/isodoc/word_function/body.rb', line 247

def example_table_attr(node)
  super.merge({
    style: "mso-table-lspace:15.0cm;margin-left:423.0pt;"\
    "mso-table-rspace:15.0cm;margin-right:423.0pt;"\
    "mso-table-anchor-horizontal:column;"\
    "mso-table-overlap:never;border-collapse:collapse;"
  })
end

#figure_aside_process(f, aside, key) ⇒ Object



167
168
169
170
171
172
173
174
175
176
177
178
179
# File 'lib/isodoc/word_function/body.rb', line 167

def figure_aside_process(f, aside, key)
  # get rid of footnote link, it is in diagram
  f&.at("./a[@class='TableFootnoteRef']")&.remove
  fnref = f.at(".//span[@class='TableFootnoteRef']/..")
  tr = key.add_child("<tr></tr>").first
  dt = tr.add_child("<td valign='top' align='left'></td>").first
  dd = tr.add_child("<td valign='top'></td>").first
  fnref.parent = dt
  aside.xpath(".//p").each do |a|
    a.delete("class")
    a.parent = dd
  end
end

#figure_get_or_make_dl(t) ⇒ Object



158
159
160
161
162
163
164
165
# File 'lib/isodoc/word_function/body.rb', line 158

def figure_get_or_make_dl(t)
  dl = t.at(".//table[@class = 'dl']")
  if dl.nil?
    t.add_child("<p><b>#{@key_lbl}</b></p><table class='dl'></table>")
    dl = t.at(".//table[@class = 'dl']")
  end
  dl
end

#image_parse(node, out, caption) ⇒ Object



227
228
229
230
231
232
233
234
235
236
237
238
239
# File 'lib/isodoc/word_function/body.rb', line 227

def image_parse(node, out, caption)
  attrs = { src: imgsrc(node["src"]),
            height: node["height"],
            alt: node["alt"],
            title: node["title"],
            width: node["width"] }
  if node["height"] == "auto" || node["width"] == "auto"
    attrs[:height] = nil
    attrs[:width] = nil
  end
  out.img **attr_code(attrs)
  image_title_parse(out, caption)
end

#imgsrc(uri) ⇒ Object



222
223
224
225
# File 'lib/isodoc/word_function/body.rb', line 222

def imgsrc(uri)
  return uri unless %r{^data:image/}.match uri
  save_dataimage(uri)
end

#insert_tab(out, n) ⇒ Object



59
60
61
62
63
# File 'lib/isodoc/word_function/body.rb', line 59

def insert_tab(out, n)
  out.span **attr_code(style: "mso-tab-count:#{n}") do |span|
    [1..n].each { span << "&#xA0; " }
  end
end

#make_body1(body, _docxml) ⇒ Object



32
33
34
35
36
37
38
39
# File 'lib/isodoc/word_function/body.rb', line 32

def make_body1(body, _docxml)
  FileUtils.rm_rf tmpimagedir
  FileUtils.mkdir tmpimagedir
  body.div **{ class: "WordSection1" } do |div1|
    div1.p { |p| p << "&nbsp;" } # placeholder
  end
  section_break(body)
end

#make_body2(body, docxml) ⇒ Object



41
42
43
44
45
46
47
48
49
# File 'lib/isodoc/word_function/body.rb', line 41

def make_body2(body, docxml)
  body.div **{ class: "WordSection2" } do |div2|
    abstract docxml, div2
    foreword docxml, div2
    introduction docxml, div2
    div2.p { |p| p << "&nbsp;" } # placeholder
  end
  section_break(body)
end

#make_body3(body, docxml) ⇒ Object



51
52
53
54
55
56
57
# File 'lib/isodoc/word_function/body.rb', line 51

def make_body3(body, docxml)
  body.div **{ class: "WordSection3" } do |div3|
    middle docxml, div3
    footnotes div3
    comments div3
  end
end

#make_table_attr(node) ⇒ Object



256
257
258
259
260
261
262
263
264
# File 'lib/isodoc/word_function/body.rb', line 256

def make_table_attr(node)
  super.merge(attr_code({
    summary: node["summary"],
    style: "mso-table-lspace:15.0cm;margin-left:423.0pt;"\
    "mso-table-rspace:15.0cm;margin-right:423.0pt;"\
    "mso-table-anchor-horizontal:column;"\
    "mso-table-overlap:never;border-spacing:0;border-width:1px;"
  }))
end

#make_tr_attr(td, row, totalrows, _header) ⇒ Object



93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/isodoc/word_function/body.rb', line 93

def make_tr_attr(td, row, totalrows, _header)
  style = td.name == "th" ? "font-weight:bold;" : ""
  rowmax = td["rowspan"] ? row + td["rowspan"].to_i - 1 : row
  style += <<~STYLE
    border-top:#{row.zero? ? "#{SW1} 1.5pt;" : 'none;'}
    mso-border-top-alt:#{row.zero? ? "#{SW1} 1.5pt;" : 'none;'}
    border-bottom:#{SW1} #{rowmax == totalrows ? '1.5' : '1.0'}pt;
    mso-border-bottom-alt:#{SW1} #{rowmax == totalrows ? '1.5' : '1.0'}pt;
  STYLE
  { rowspan: td["rowspan"], colspan: td["colspan"],
    align: td["align"], style: style.gsub(/\n/, "") }
end

#new_fullcolspan_row(t, tfoot) ⇒ Object



81
82
83
84
85
86
87
88
89
90
91
# File 'lib/isodoc/word_function/body.rb', line 81

def new_fullcolspan_row(t, tfoot)
  # how many columns in the table?
  cols = 0
  t.at(".//tr").xpath("./td | ./th").each do |td|
    cols += (td["colspan"] ? td["colspan"].to_i : 1)
  end
  style = "border-top:0pt;mso-border-top-alt:0pt;"\
    "border-bottom:#{SW1} 1.5pt;mso-border-bottom-alt:#{SW1} 1.5pt;"
  tfoot.add_child("<tr><td colspan='#{cols}' style='#{style}'/></tr>")
  tfoot.xpath(".//td").last
end

#note_p_parse(node, div) ⇒ Object



181
182
183
184
185
186
187
188
189
190
# File 'lib/isodoc/word_function/body.rb', line 181

def note_p_parse(node, div)
  div.p **{ class: "Note" } do |p|
    p.span **{ class: "note_label" } do |s|
      s << note_label(node)
    end
    insert_tab(p, 1)
    node.first_element_child.children.each { |n| parse(n, p) }
  end
  node.element_children[1..-1].each { |n| parse(n, div) }
end

#note_parse1(node, div) ⇒ Object



192
193
194
195
196
197
198
199
200
# File 'lib/isodoc/word_function/body.rb', line 192

def note_parse1(node, div)
  div.p **{ class: "Note" } do |p|
    p.span **{ class: "note_label" } do |s|
      s << note_label(node)
    end
    insert_tab(p, 1)
  end
  node.children.each { |n| parse(n, div) }
end

#page_break(out) ⇒ Object



112
113
114
115
116
117
118
# File 'lib/isodoc/word_function/body.rb', line 112

def page_break(out)
  out.p do |p|
    p.br **{ clear: "all",
             style: "mso-special-character:line-break;"\
             "page-break-before:always" }
  end
end

#para_attrs(node) ⇒ Object



213
214
215
216
217
218
219
220
# File 'lib/isodoc/word_function/body.rb', line 213

def para_attrs(node)
  attrs = { class: para_class(node), id: node["id"] }
  unless node["align"].nil?
    attrs[:align] = node["align"] unless node["align"] == "justify"
    attrs[:style] = "text-align:#{node['align']}"
  end
  attrs
end

#para_class(_node) ⇒ Object



65
66
67
68
69
70
71
# File 'lib/isodoc/word_function/body.rb', line 65

def para_class(_node)
  classtype = nil
  classtype = "Note" if @note
  classtype = "MsoCommentText" if in_comment
  classtype = "Sourcecode" if @annotation
  classtype
end

#remove_bottom_border(td) ⇒ Object



73
74
75
76
77
# File 'lib/isodoc/word_function/body.rb', line 73

def remove_bottom_border(td)
  td["style"] =
    td["style"].gsub(/border-bottom:[^;]+;/, "border-bottom:0pt;").
    gsub(/mso-border-bottom-alt:[^;]+;/, "mso-border-bottom-alt:0pt;")
end

#section_break(body) ⇒ Object



106
107
108
109
110
# File 'lib/isodoc/word_function/body.rb', line 106

def section_break(body)
  body.p do |p|
    p.br **{ clear: "all", class: "section" }
  end
end

#table_parse(node, out) ⇒ Object



266
267
268
269
270
271
272
273
274
275
276
277
278
279
# File 'lib/isodoc/word_function/body.rb', line 266

def table_parse(node, out)
  @in_table = true
  table_title_parse(node, out)
  out.div **{ align: "center", class: "table_container" } do |div|
    div.table **make_table_attr(node) do |t|
      thead_parse(node, t)
      tbody_parse(node, t)
      tfoot_parse(node, t)
      (dl = node.at(ns("./dl"))) && parse(dl, out)
      node.xpath(ns("./note")).each { |n| parse(n, out) }
    end
  end
  @in_table = false
end

#termnote_parse(node, out) ⇒ Object



202
203
204
205
206
207
208
209
210
211
# File 'lib/isodoc/word_function/body.rb', line 202

def termnote_parse(node, out)
  out.div **{ class: "Note" } do |div|
    first = node.first_element_child
    div.p **{ class: "Note" } do |p|
      anchor = get_anchors[node['id']]
      p << "#{anchor&.dig(:label) || '???'}: "
      para_then_remainder(first, node, p, div)
    end
  end
end

#xref_parse(node, out) ⇒ Object



241
242
243
244
245
# File 'lib/isodoc/word_function/body.rb', line 241

def xref_parse(node, out)
  target = /#/.match(node["target"]) ? node["target"].sub(/#/, ".doc#") :
    "##{node["target"]}"
    out.a(**{ "href": target }) { |l| l << get_linkend(node) }
end