Module: IsoDoc::HtmlFunction::Html

Included in:
IsoDoc::HeadlessHtmlConvert, IsoDoc::HtmlConvert, PdfConvert
Defined in:
lib/isodoc/html_function/html.rb,
lib/isodoc/html_function/postprocess.rb,
lib/isodoc/html_function/postprocess_cover.rb,
lib/isodoc/html_function/postprocess_footnotes.rb

Constant Summary collapse

MATHJAX_ADDR =
"https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/latest.js".freeze
MATHJAX =
<<~"MATHJAX".freeze
  <script type="text/x-mathjax-config">
    MathJax.Hub.Config({
      "HTML-CSS": {
        preferredFont: "STIX",
        linebreaks: {
          automatic: true,
          width: "container"  // or specify something like "90%"/"30em"
        }
      },
      MathML: {
        linebreaks: {
          automatic: true
        }
      },
      asciimath2jax: { delimiters: [['(#(', ')#)']] }
    });
  </script>
  <script src="#{MATHJAX_ADDR}?config=MML_HTMLorMML-full" async="async"></script>
MATHJAX

Instance Method Summary collapse

Instance Method Details

#altsource_attrs(node) ⇒ Object



190
191
192
193
194
# File 'lib/isodoc/html_function/html.rb', line 190

def altsource_attrs(node)
  media = node["media"]
  media.blank? and media = "all"
  { srcset: node["src"], media: @c.decode(media), type: node["type"] }
end

#authority_cleanup(docxml) ⇒ Object



64
65
66
67
68
69
# File 'lib/isodoc/html_function/postprocess_cover.rb', line 64

def authority_cleanup(docxml)
  %w(copyright license legal feedback).each do |t|
    authority_cleanup1(docxml, t)
  end
  coverpage_note_cleanup(docxml)
end

#authority_cleanup1(docxml, klass) ⇒ Object



55
56
57
58
59
60
61
62
# File 'lib/isodoc/html_function/postprocess_cover.rb', line 55

def authority_cleanup1(docxml, klass)
  dest = docxml.at("//div[@id = 'boilerplate-#{klass}-destination']")
  auth = docxml.at("//div[@id = 'boilerplate-#{klass}' or " \
                   "@class = 'boilerplate-#{klass}']") or return
  auth.xpath(".//h1[not(text())] | .//h2[not(text())]").each(&:remove)
  auth.xpath(".//h1 | .//h2").each { |h| h["class"] = "IntroTitle" }
  dest && auth and dest.replace(auth.remove)
end

#comment_cleanup(docxml) ⇒ Object



228
# File 'lib/isodoc/html_function/html.rb', line 228

def comment_cleanup(docxml); end

#comments(docxml, div) ⇒ Object



227
# File 'lib/isodoc/html_function/html.rb', line 227

def comments(docxml, div); end

#convert1(docxml, filename, dir) ⇒ Object



7
8
9
10
11
12
13
14
15
16
# File 'lib/isodoc/html_function/html.rb', line 7

def convert1(docxml, filename, dir)
  noko do |xml|
    xml.html lang: @lang.to_s do |html|
      info docxml, nil
      populate_css
      html.head { |head| define_head head, filename, dir }
      make_body(html, docxml)
    end
  end.join("\n")
end

#coverpage_note_cleanup(docxml) ⇒ Object



71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/isodoc/html_function/postprocess_cover.rb', line 71

def coverpage_note_cleanup(docxml)
  if dest = docxml.at("//div[@id = 'coverpage-note-destination']")
    auth = docxml.xpath("//*[@coverpage]")
    if auth.empty? then dest.remove
    else
      auth.each do |x|
        dest << x.remove
      end
    end
  end
  docxml.xpath("//*[@coverpage]").each { |x| x.delete("coverpage") }
end

#datauri(img) ⇒ Object



107
108
109
# File 'lib/isodoc/html_function/postprocess.rb', line 107

def datauri(img)
  img["src"] = Vectory::Utils::datauri(img["src"], @localdir)
end

#designation_tag(node) ⇒ Object



213
214
215
216
217
218
219
220
221
# File 'lib/isodoc/html_function/html.rb', line 213

def designation_tag(node)
  term = node.at("./ancestor::xmlns:term")
  if node["element"] == "expression/name"
    e = term.at(".//*[@id = '#{node['source']}']")
    # <expression type='abbreviation'><name>...
    e&.parent && e.parent["type"] == "abbreviation" and return "abbr"
  end
  "dfn"
end

#footnote_backlink?(elem, docxml, seen) ⇒ Boolean

Returns:

  • (Boolean)


42
43
44
45
# File 'lib/isodoc/html_function/postprocess_footnotes.rb', line 42

def footnote_backlink?(elem, docxml, seen)
  seen[elem["href"]] and return
  docxml.at(%<//*[@id = '#{elem['href'].sub(/^#/, '')}']>)
end


30
31
32
33
34
35
36
37
38
39
40
# File 'lib/isodoc/html_function/postprocess_footnotes.rb', line 30

def footnote_backlinks(docxml)
  seen = {}
  docxml.xpath('//a[@class = "FootnoteRef"]').each_with_index do |x, i|
    fn = footnote_backlink?(x, docxml, seen) or next
    seen[x["href"]] = true
    footnote_backlinks1(x, fn)
    x["id"] ||= "fnref:#{i + 1}"
    fn.add_child "<a href='##{x['id']}'>&#x21A9;</a>"
  end
  docxml
end

#footnote_backlinks1(xref, footnote) ⇒ Object



20
21
22
23
24
25
26
27
28
# File 'lib/isodoc/html_function/postprocess_footnotes.rb', line 20

def footnote_backlinks1(xref, footnote)
  xdup = xref.dup
  xdup.remove["id"]
  if footnote.elements.empty?
    footnote.add_first_child xdup
  else
    footnote.elements.first.add_first_child xdup
  end
end

#footnote_delimit(docxml) ⇒ Object



8
9
10
11
12
13
14
15
16
17
18
# File 'lib/isodoc/html_function/postprocess_footnotes.rb', line 8

def footnote_delimit(docxml)
  k = %w(FootnoteRef TableFootnoteRef)
  docxml.xpath("//a").each do |a|
    k.include?(a["class"]) or next
    a1 = a.next_element or next
    k.include?(a1["class"]) or next
    sup = a.at("./sup") and a = sup
    a << ", "
  end
  docxml
end

#googlefontsObject



34
35
36
37
38
39
# File 'lib/isodoc/html_function/html.rb', line 34

def googlefonts
  <<~HEAD.freeze
    <link href="https://fonts.googleapis.com/css?family=Overpass:300,300i,600,900" rel="stylesheet"/>
    <link href="https://fonts.googleapis.com/css?family=Lato:400,400i,700,900" rel="stylesheet"/>
  HEAD
end

#heading_anchor(hdr, id) ⇒ Object



48
49
50
51
52
# File 'lib/isodoc/html_function/postprocess.rb', line 48

def heading_anchor(hdr, id)
  hdr.children = <<~HTML.strip
    <a class='anchor' href='##{id}'/><a class='header' href='##{id}'>#{hdr.children.to_xml}</a>
  HTML
end

#heading_anchors(html) ⇒ Object



37
38
39
40
41
42
43
44
45
46
# File 'lib/isodoc/html_function/postprocess.rb', line 37

def heading_anchors(html)
  html.xpath("//h1 | //h2 | //h3 | //h4 | //h5 | //h6 | //h7 | //h8 | " \
             "//span[@class = 'inline-header']").each do |h|
    h.at("./ancestor::div[@id='toc']") and next
    div = h.xpath("./ancestor::div[@id]")
    div.empty? and next
    heading_anchor(h, div[-1]["id"])
  end
  html
end

#html5(doc) ⇒ Object



26
27
28
29
# File 'lib/isodoc/html_function/postprocess.rb', line 26

def html5(doc)
  doc.sub(%r{\A<!DOCTYPE html [^<>]+>}, "<!DOCTYPE html>")
    .sub(%r{\A<\?xml[^<>]+>}, "")
end

#html_buttonObject



60
61
62
63
64
# File 'lib/isodoc/html_function/html.rb', line 60

def html_button
  @bare and return ""
  '<button onclick="topFunction()" id="myBtn" ' \
  'title="Go to top">Top</button>'.freeze
end

#html_cleanup(html) ⇒ Object



31
32
33
34
35
# File 'lib/isodoc/html_function/postprocess.rb', line 31

def html_cleanup(html)
  html = term_header(html_preface(htmlstyle(html)))
  html = html_list_clean(remove_placeholder_paras(html_footnote(html)))
  html_toc(heading_anchors(sourcecode_cleanup(mathml(html))))
end

#html_cover(docxml) ⇒ Object



84
85
86
87
88
89
90
# File 'lib/isodoc/html_function/postprocess_cover.rb', line 84

def html_cover(docxml)
  doc = to_xhtml_fragment(File.read(@htmlcoverpage, encoding: "UTF-8"))
  d = docxml.at('//div[@class="title-section"]')
  d.add_first_child(
    populate_template(doc.to_xml(encoding: "US-ASCII"), :html),
  )
end

#html_footnote(html) ⇒ Object



4
5
6
# File 'lib/isodoc/html_function/postprocess_footnotes.rb', line 4

def html_footnote(html)
  footnote_delimit(footnote_backlinks(html))
end

#html_headObject



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/isodoc/html_function/html.rb', line 41

def html_head
  <<~HEAD.freeze
    <title>#{@meta&.get&.dig(:doctitle)}</title>
    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

    <!--TOC script import-->
    <script type="text/javascript"  src="https://cdn.rawgit.com/jgallen23/toc/0.3.2/dist/toc.min.js"></script>
    <script type="text/javascript">#{toclevel}</script>

    <!--Google fonts-->
    <link rel="preconnect" href="https://fonts.gstatic.com"/>
    #{googlefonts}
    <!--Font awesome import for the link icon-->
    <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.8/css/solid.css" integrity="sha384-v2Tw72dyUXeU3y4aM2Y0tBJQkGfplr39mxZqlTBDUZAb9BGoC40+rdFCG0m10lXk" crossorigin="anonymous"/>
    <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.8/css/fontawesome.css" integrity="sha384-q3jl8XQu1OpdLgGFvNRnPdj5VIlCvgsDQTQB6owSOHWlAurxul7f+JpUOVdAiJ5P" crossorigin="anonymous"/>
    <style class="anchorjs"></style>
  HEAD
end

#html_intro(docxml) ⇒ Object



92
93
94
95
96
97
98
# File 'lib/isodoc/html_function/postprocess_cover.rb', line 92

def html_intro(docxml)
  doc = to_xhtml_fragment(File.read(@htmlintropage, encoding: "UTF-8"))
  d = docxml.at('//div[@class="prefatory-section"]')
  d.add_first_child(
    populate_template(doc.to_xml(encoding: "US-ASCII"), :html),
  )
end

#html_list_clean(html) ⇒ Object



73
74
75
76
77
78
79
80
# File 'lib/isodoc/html_function/postprocess.rb', line 73

def html_list_clean(html)
  html.xpath("//ol/div | //ul/div").each do |div|
    li = div.xpath("./preceding-sibling::li")&.last ||
      div.at("./following-sibling::li")
    div.parent = li
  end
  html
end

#html_main(docxml) ⇒ Object



66
67
68
69
70
71
# File 'lib/isodoc/html_function/html.rb', line 66

def html_main(docxml)
  docxml.at("//head") << Nokogiri::HTML.fragment(html_head)
  d = docxml.at('//div[@class="main-section"]')
  d.name = "main"
  d.children.empty? or d.children.first.previous = html_button
end

#html_preface(docxml) ⇒ Object



44
45
46
47
48
49
50
51
52
53
# File 'lib/isodoc/html_function/postprocess_cover.rb', line 44

def html_preface(docxml)
  @htmlcoverpage && !@htmlcoverpage.empty? && !@bare and
    html_cover(docxml)
  @htmlintropage && !@htmlintropage.empty? && !@bare and
    html_intro(docxml)
  docxml.at("//body") << mathjax(@openmathdelim, @closemathdelim)
  html_main(docxml)
  authority_cleanup(docxml)
  docxml
end

#html_toc(docxml) ⇒ Object

needs to be same output as toclevel



125
126
127
128
129
130
131
132
133
134
# File 'lib/isodoc/html_function/postprocess_cover.rb', line 125

def html_toc(docxml)
  idx = html_toc_init(docxml) or return docxml
  path = toclevel_classes.map do |x|
    x.map { |l| "//main//#{l}#{toc_exclude_class}" }
  end
  toc = html_toc_entries(docxml, path)
    .map { |k| k[:entry] }.join("\n")
  idx << "<ul>#{toc}</ul>"
  docxml
end

#html_toc_entries(docxml, path) ⇒ Object



144
145
146
147
148
149
150
151
152
# File 'lib/isodoc/html_function/postprocess_cover.rb', line 144

def html_toc_entries(docxml, path)
  headers = html_toc_entries_prep(docxml, path)
  path.each_with_index.with_object([]) do |(p, i), m|
    docxml.xpath(p.join(" | ")).each do |h|
      m << { entry: html_toc_entry("h#{i + 1}", h),
             line: headers[h["id"]] }
    end
  end.sort_by { |k| k[:line] }
end

#html_toc_entries_prep(docxml, path) ⇒ Object



154
155
156
157
158
159
160
# File 'lib/isodoc/html_function/postprocess_cover.rb', line 154

def html_toc_entries_prep(docxml, path)
  docxml.xpath(path.join(" | "))
    .each_with_index.with_object({}) do |(h, i), m|
      h["id"] ||= "_#{UUIDTools::UUID.random_create}"
      m[h["id"]] = i
    end
end

#html_toc_entry(level, header) ⇒ Object



100
101
102
103
104
105
106
107
# File 'lib/isodoc/html_function/postprocess_cover.rb', line 100

def html_toc_entry(level, header)
  content = header.at("./following-sibling::p" \
                      "[@class = 'variant-title-toc']") || header
  id = header.at(".//a[@class = 'anchor']/@href")&.text&.sub(/^#/, "") ||
    header["id"]
  %(<li class="#{level}"><a href="##{id}">\
#{header_strip(content)}</a></li>)
end

#html_toc_init(docxml) ⇒ Object



136
137
138
139
140
141
142
# File 'lib/isodoc/html_function/postprocess_cover.rb', line 136

def html_toc_init(docxml)
  dest = docxml.at("//div[@id = 'toc']") or return
  if source = docxml.at("//div[@class = 'TOC']")
    dest << to_xml(source.remove.children)
  end
  dest
end

#htmlstyle(docxml) ⇒ Object



31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/isodoc/html_function/postprocess_cover.rb', line 31

def htmlstyle(docxml)
  @htmlstylesheet or return docxml
  head = docxml.at("//*[local-name() = 'head']")
  head << Nokogiri::HTML.fragment("<style>#{htmlstylesheet(@htmlstylesheet)}</style>")
  s = htmlstylesheet(@htmlstylesheet_override) and head << Nokogiri::HTML.fragment("<style>#{s}</style>")
  s = @meta.get[:code_css] and
    head << Nokogiri::HTML.fragment("<style>#{s.gsub('sourcecode',
                                                     'pre.sourcecode')}</style>")
  @bare and
    head << "<style>body {margin-left: 2em; margin-right: 2em;}</style>"
  docxml
end

#htmlstylesheet(file) ⇒ Object



22
23
24
25
26
27
28
29
# File 'lib/isodoc/html_function/postprocess_cover.rb', line 22

def htmlstylesheet(file)
  file.nil? and return
  file.open if file.is_a?(Tempfile)
  stylesheet = file.read
  file.close
  file.unlink if file.is_a?(Tempfile)
  stylesheet
end

#image_body_parse(node, attrs, out) ⇒ Object



161
162
163
164
165
166
167
168
169
# File 'lib/isodoc/html_function/html.rb', line 161

def image_body_parse(node, attrs, out)
  svg = node.at(".//m:svg", "m" => "http://www.w3.org/2000/svg")
  alts = select_altsource(node)
  if svg && alts.empty?
    image_body_parse_svg(svg, out)
  else
    image_body_parse_picture(node, attrs, alts, out)
  end
end

#image_body_parse_picture(node, _attrs, alts, out) ⇒ Object



171
172
173
174
175
176
177
178
179
180
181
182
# File 'lib/isodoc/html_function/html.rb', line 171

def image_body_parse_picture(node, _attrs, alts, out)
  out.picture do |p|
    alts.each do |i|
      if i["tag"] == "default" then next
      else
        p.source **attr_code(altsource_attrs(i)
          .merge({ srcset: svg2datauri(i) }.compact))
      end
    end
    image_picture_img(node, p)
  end
end

#image_body_parse_svg(svg, out) ⇒ Object



150
151
152
153
154
155
# File 'lib/isodoc/html_function/html.rb', line 150

def image_body_parse_svg(svg, out)
  svg_supply_viewbox(svg)
  out.div class: "svg-container" do |div|
    div.parent.add_child(svg)
  end
end

#image_picture_img(node, out) ⇒ Object



184
185
186
187
188
# File 'lib/isodoc/html_function/html.rb', line 184

def image_picture_img(node, out)
  default = node.at(ns("./altsource[@tag = 'default']")) || node
  out.img **attr_code(image_attrs(default)
    .merge({ src: svg2datauri(default) }.compact))
end

#image_suffix(img) ⇒ Object



111
112
113
114
115
116
117
# File 'lib/isodoc/html_function/postprocess.rb', line 111

def image_suffix(img)
  type = img["mimetype"]&.sub(%r{^[^/*]+/}, "")
  matched = /\.(?<suffix>[^. \r\n\t]+)$/.match img["src"]
  type and !type.empty? and return type
  !matched.nil? and matched[:suffix] and return matched[:suffix]
  "png"
end

#in_commentObject



223
224
225
# File 'lib/isodoc/html_function/html.rb', line 223

def in_comment
  @in_comment
end

#inject_script(doc) ⇒ Object



167
168
169
170
171
172
173
174
175
# File 'lib/isodoc/html_function/postprocess_cover.rb', line 167

def inject_script(doc)
  @scripts or return doc
  scripts = File.read(@scripts, encoding: "UTF-8")
  scripts_override = ""
  @scripts_override and
    scripts_override = File.read(@scripts_override, encoding: "UTF-8")
  a = doc.split(%r{</body>})
  "#{a[0]}#{scripts}#{scripts_override}</body>#{a[1]}"
end

#make_body1(body, _docxml) ⇒ Object



18
19
20
21
22
23
24
# File 'lib/isodoc/html_function/html.rb', line 18

def make_body1(body, _docxml)
  @bare and return
  body.div class: "title-section" do |div1|
    div1.p { |p| p << "&#xa0;" } # placeholder
  end
  section_break(body)
end

#make_body2(body, _docxml) ⇒ Object



26
27
28
29
30
31
32
# File 'lib/isodoc/html_function/html.rb', line 26

def make_body2(body, _docxml)
  @bare and return
  body.div class: "prefatory-section" do |div2|
    div2.p { |p| p << "&#xa0;" } # placeholder
  end
  section_break(body)
end

#mathjax(open, close) ⇒ Object



200
201
202
# File 'lib/isodoc/html_function/postprocess_cover.rb', line 200

def mathjax(open, close)
  MATHJAX.gsub("OPEN", open).gsub("CLOSE", close)
end

#mathml(docxml) ⇒ Object



82
83
84
# File 'lib/isodoc/html_function/postprocess.rb', line 82

def mathml(docxml)
  IsoDoc::HtmlFunction::MathvariantToPlain.new(docxml).convert
end

#move_image1(img) ⇒ Object



119
120
121
122
123
124
125
126
127
# File 'lib/isodoc/html_function/postprocess.rb', line 119

def move_image1(img)
  suffix = image_suffix(img)
  uuid = UUIDTools::UUID.random_create.to_s
  fname = "#{uuid}.#{suffix}"
  new_full_filename = File.join(tmpimagedir, fname)
  local_filename = image_localfile(img)
  FileUtils.cp local_filename, new_full_filename
  img["src"] = File.join(rel_tmpimagedir, fname)
end

#move_images(docxml) ⇒ Object

presupposes that the image source is local



97
98
99
100
101
102
103
104
105
# File 'lib/isodoc/html_function/postprocess.rb', line 97

def move_images(docxml)
  FileUtils.rm_rf tmpimagedir
  FileUtils.mkdir tmpimagedir
  docxml.xpath("//*[local-name() = 'img'][@src]").each do |i|
    /^data:/.match? i["src"] and next
    @datauriimage ? datauri(i) : move_image1(i)
  end
  docxml
end

#postprocess(result, filename, _dir) ⇒ Object



9
10
11
12
13
14
# File 'lib/isodoc/html_function/postprocess.rb', line 9

def postprocess(result, filename, _dir)
  result = from_xhtml(cleanup(to_xhtml(textcleanup(result))))
  result = toHTML(result, filename)
  @files_to_delete.each { |f| FileUtils.rm_rf f }
  result
end

#pseudocode_tagObject



115
116
117
# File 'lib/isodoc/html_function/html.rb', line 115

def pseudocode_tag
  "figure"
end

#remove_placeholder_paras(html) ⇒ Object



66
67
68
69
70
71
# File 'lib/isodoc/html_function/postprocess.rb', line 66

def remove_placeholder_paras(html)
  %w(title-section prefatory-section).each do |s|
    html&.at("//div[@class = '#{s}']/p[last()]")&.remove
  end
  html
end

#resize_images(docxml) ⇒ Object

do not resize SVG, their height is set to 1px in HTML for autofit



87
88
89
90
91
92
93
94
# File 'lib/isodoc/html_function/postprocess.rb', line 87

def resize_images(docxml)
  docxml.xpath("//*[local-name() = 'img']").each do |i|
    loc = image_localfile(i) or next
    i["width"], i["height"] = Vectory::ImageResize.new
      .call(i, loc, @maxheight, @maxwidth)
  end
  docxml
end

#script_cdata(result) ⇒ Object



8
9
10
11
12
13
14
15
16
17
18
19
20
# File 'lib/isodoc/html_function/postprocess_cover.rb', line 8

def script_cdata(result)
  # Use explicit [ \t\n\r]* rather than \s* with the m flag:
  # [^<>]* and [ \t\n\r]* are disjoint character classes (whitespace
  # chars are not < or >), preventing polynomial backtracking.
  result.gsub(%r{<script([^<>]*)>[ \t\n\r]*<!\[CDATA\[}, "<script\\1>")
    .gsub(%r{\]\]>[ \t\n\r]*</script>}, "</script>")
    .gsub(%r{<!\[CDATA\[[ \t\n\r]*<script([^<>]*)>}, "<script\\1>")
    .gsub(%r{</script>[ \t\n\r]*\]\]>}, "</script>")
    .gsub(%r{<style([^<>]*)>[ \t\n\r]*<!\[CDATA\[}, "<style\\1>")
    .gsub(%r{\]\]>[ \t\n\r]*</style>}, "</style>")
    .gsub(%r{<!\[CDATA\[[ \t\n\r]*<style([^<>]*)>}, "<style\\1>")
    .gsub(%r{</style>[ \t\n\r]*\]\]>}, "</style>")
end

#select_altsource?(_altsource, tags) ⇒ Boolean

Returns:

  • (Boolean)


157
158
159
# File 'lib/isodoc/html_function/html.rb', line 157

def select_altsource?(_altsource, tags)
  tags.include?("html")
end

#semx_parse(node, out) ⇒ Object



203
204
205
206
207
208
209
210
211
# File 'lib/isodoc/html_function/html.rb', line 203

def semx_parse(node, out)
  if %w(expression/name letter-symbol/name).include?(node["element"])
    tag = designation_tag(node)
    out.send tag do |d|
      children_parse(node, d)
    end
  else super
  end
end

#sourcecode_attrs(node) ⇒ Object



84
85
86
# File 'lib/isodoc/html_function/html.rb', line 84

def sourcecode_attrs(node)
  super.merge(spellcheck: "false", translation: "no")
end

#sourcecode_cleanup(html) ⇒ Object



54
55
56
57
58
59
60
61
62
63
64
# File 'lib/isodoc/html_function/postprocess.rb', line 54

def sourcecode_cleanup(html)
  ann = ".//div[@class = 'annotation']"
  html.xpath("//pre[#{ann}] | //figure[@class = 'sourcecode'][#{ann}]")
    .each do |p|
    ins = p.after("<pre class='sourcecode'/>").next_element
    p.xpath(ann).each do |d|
      ins << d.remove.children
    end
  end
  html
end

#sourcecode_name_parse(_node, div, name) ⇒ Object



108
109
110
111
112
113
# File 'lib/isodoc/html_function/html.rb', line 108

def sourcecode_name_parse(_node, div, name)
  name.nil? and return
  div.figcaption class: "SourceTitle" do |p|
    children_parse(name, p)
  end
end

#sourcecode_parse(node, out) ⇒ Object



73
74
75
76
77
78
79
80
81
82
# File 'lib/isodoc/html_function/html.rb', line 73

def sourcecode_parse(node, out)
  tag, child_tag = sourcecode_tag(node)
  s = node.at(ns("./fmt-sourcecode")) || node
  attr = sourcecode_attrs(node).merge(class: "sourcecode")
  out.send tag, **attr do |div|
    sourcecode_pre_wrap(child_tag, s, div)
    annotation_parse(s, div)
    sourcecode_name_parse(node, div, node.at(ns("./fmt-name")))
  end
end

#sourcecode_pre_wrap(tag, node, div) ⇒ Object



98
99
100
101
102
103
104
105
106
# File 'lib/isodoc/html_function/html.rb', line 98

def sourcecode_pre_wrap(tag, node, div)
  if tag == "pre"
    div.pre do |pre|
      sourcecode_parse1(node, pre)
    end
  else
    sourcecode_parse1(node, div)
  end
end

#sourcecode_tag(node) ⇒ Object



88
89
90
91
92
93
94
95
96
# File 'lib/isodoc/html_function/html.rb', line 88

def sourcecode_tag(node)
  ancestors = node.ancestors.map(&:name)
    .intersection(%w(sourcecode table))
  tag = ancestors.empty? ? "figure" : "pre"
  child_tag = "pre"
  tag == "pre" || node.at(ns(".//sourcecode | .//table")) and
    child_tag = "figure"
  [tag, child_tag]
end

#svg2datauri(node) ⇒ Object



196
197
198
199
200
201
# File 'lib/isodoc/html_function/html.rb', line 196

def svg2datauri(node)
  svg = node.at(".//m:svg", "m" => "http://www.w3.org/2000/svg") or
    return nil
  v = Vectory::Svg.from_node(svg.parent)
  Vectory::Datauri.from_vector(v).content
end

#svg_supply_viewbox(svg) ⇒ Object



136
137
138
139
140
141
142
# File 'lib/isodoc/html_function/html.rb', line 136

def svg_supply_viewbox(svg)
  svg_supply_viewbox?(svg) or return
  h = svg["height"].to_s[/\d+/].to_s
  w = svg["width"].to_s[/\d+/].to_s
  (h.to_i.positive? && w.to_i.positive?) or return
  svg["viewbox"] = "0 0 #{w} #{h}"
end

#svg_supply_viewbox?(svg) ⇒ Boolean

Returns:

  • (Boolean)


144
145
146
147
148
# File 'lib/isodoc/html_function/html.rb', line 144

def svg_supply_viewbox?(svg)
  svg["viewbox"] and return false
  (svg["height"] && svg["width"]) or return false
  true
end

#table_attrs(node) ⇒ Object



127
128
129
130
131
132
133
134
# File 'lib/isodoc/html_function/html.rb', line 127

def table_attrs(node)
  ret = super
  if node.at(ns("./colgroup"))
    ret[:style] ||= ""
    ret[:style] += "table-layout:fixed;"
  end
  ret
end

#term_header(docxml) ⇒ Object



129
130
131
132
133
134
135
136
137
138
139
# File 'lib/isodoc/html_function/postprocess.rb', line 129

def term_header(docxml)
  %w(h1 h2 h3 h4 h5 h6 h7 h8).each do |h|
    docxml.xpath("//p[@class = 'TermNum'][../#{h}]").each do |p|
      p.name = "h#{h[1].to_i + 1}"
      id = p["id"]
      p["id"] = "_#{UUIDTools::UUID.random_create}"
      p.wrap("<div id='#{id}'></div>")
    end
  end
  docxml
end

#toc_exclude_classObject



162
163
164
165
# File 'lib/isodoc/html_function/postprocess_cover.rb', line 162

def toc_exclude_class
  "[not(@class = 'TermNum')][not(@class = 'noTOC')]" \
    "[string-length(normalize-space(.))>0]"
end

#toclevelObject



115
116
117
118
119
120
121
122
# File 'lib/isodoc/html_function/postprocess_cover.rb', line 115

def toclevel
  ret = toclevel_classes.flatten.map do |l|
    "#{l}:not(:empty):not(.TermNum):not(.noTOC)"
  end
  <<~HEAD.freeze
    function toclevel() { return "#{ret.join(',')}";}
  HEAD
end

#toclevel_classesObject

array of arrays, one per level, containing XPath fragments for the elems matching that ToC level



111
112
113
# File 'lib/isodoc/html_function/postprocess_cover.rb', line 111

def toclevel_classes
  (1..@htmlToClevels).reduce([]) { |m, i| m << ["h#{i}"] }
end

#toHTML(result, filename) ⇒ Object



16
17
18
19
20
21
22
23
24
# File 'lib/isodoc/html_function/postprocess.rb', line 16

def toHTML(result, filename)
  result = from_xhtml(html_cleanup(to_xhtml(result)))
  result = from_xhtml(move_images(resize_images(to_xhtml(result))))
  result = html5(empty_tags(script_cdata(inject_script(result))))
  # Unescape &#x26; to & in href attributes after all Nokogiri processing
  result = unescape_amp_in_hrefs(result)
  File.open(filename, "w:UTF-8") { |f| f.write(result) }
  result
end

#underline_parse(node, out) ⇒ Object



119
120
121
122
123
124
125
# File 'lib/isodoc/html_function/html.rb', line 119

def underline_parse(node, out)
  style = node["style"] ? " #{node['style']}" : ""
  attr = { style: "text-decoration: underline#{style}" }
  out.span(**attr) do |e|
    node.children.each { |n| parse(n, e) }
  end
end