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
- #altsource_attrs(node) ⇒ Object
- #authority_cleanup(docxml) ⇒ Object
- #authority_cleanup1(docxml, klass) ⇒ Object
- #comment_cleanup(docxml) ⇒ Object
- #comments(docxml, div) ⇒ Object
- #convert1(docxml, filename, dir) ⇒ Object
- #coverpage_note_cleanup(docxml) ⇒ Object
- #datauri(img) ⇒ Object
- #designation_tag(node) ⇒ Object
- #footnote_backlink?(elem, docxml, seen) ⇒ Boolean
- #footnote_backlinks(docxml) ⇒ Object
- #footnote_backlinks1(xref, footnote) ⇒ Object
- #footnote_delimit(docxml) ⇒ Object
- #googlefonts ⇒ Object
- #heading_anchor(hdr, id) ⇒ Object
- #heading_anchors(html) ⇒ Object
- #html5(doc) ⇒ Object
- #html_button ⇒ Object
- #html_cleanup(html) ⇒ Object
- #html_cover(docxml) ⇒ Object
- #html_footnote(html) ⇒ Object
- #html_head ⇒ Object
- #html_intro(docxml) ⇒ Object
- #html_list_clean(html) ⇒ Object
- #html_main(docxml) ⇒ Object
- #html_preface(docxml) ⇒ Object
-
#html_toc(docxml) ⇒ Object
needs to be same output as toclevel.
- #html_toc_entries(docxml, path) ⇒ Object
- #html_toc_entries_prep(docxml, path) ⇒ Object
- #html_toc_entry(level, header) ⇒ Object
- #html_toc_init(docxml) ⇒ Object
- #htmlstyle(docxml) ⇒ Object
- #htmlstylesheet(file) ⇒ Object
- #image_body_parse(node, attrs, out) ⇒ Object
- #image_body_parse_picture(node, _attrs, alts, out) ⇒ Object
- #image_body_parse_svg(svg, out) ⇒ Object
- #image_picture_img(node, out) ⇒ Object
- #image_suffix(img) ⇒ Object
- #in_comment ⇒ Object
- #inject_script(doc) ⇒ Object
- #make_body1(body, _docxml) ⇒ Object
- #make_body2(body, _docxml) ⇒ Object
- #mathjax(open, close) ⇒ Object
- #mathml(docxml) ⇒ Object
- #move_image1(img) ⇒ Object
-
#move_images(docxml) ⇒ Object
presupposes that the image source is local.
- #postprocess(result, filename, _dir) ⇒ Object
- #pseudocode_tag ⇒ Object
- #remove_placeholder_paras(html) ⇒ Object
-
#resize_images(docxml) ⇒ Object
do not resize SVG, their height is set to 1px in HTML for autofit.
- #script_cdata(result) ⇒ Object
- #select_altsource?(_altsource, tags) ⇒ Boolean
- #semx_parse(node, out) ⇒ Object
- #sourcecode_attrs(node) ⇒ Object
- #sourcecode_cleanup(html) ⇒ Object
- #sourcecode_name_parse(_node, div, name) ⇒ Object
- #sourcecode_parse(node, out) ⇒ Object
- #sourcecode_pre_wrap(tag, node, div) ⇒ Object
- #sourcecode_tag(node) ⇒ Object
- #svg2datauri(node) ⇒ Object
- #svg_supply_viewbox(svg) ⇒ Object
- #svg_supply_viewbox?(svg) ⇒ Boolean
- #table_attrs(node) ⇒ Object
- #term_header(docxml) ⇒ Object
- #toc_exclude_class ⇒ Object
- #toclevel ⇒ Object
-
#toclevel_classes ⇒ Object
array of arrays, one per level, containing XPath fragments for the elems matching that ToC level.
- #toHTML(result, filename) ⇒ Object
- #underline_parse(node, out) ⇒ Object
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 (docxml) %w(copyright license legal feedback).each do |t| (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 (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
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 |
#footnote_backlinks(docxml) ⇒ Object
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']}'>↩</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 |
#googlefonts ⇒ Object
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_button ⇒ Object
60 61 62 63 64 |
# File 'lib/isodoc/html_function/html.rb', line 60 def @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_head ⇒ Object
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 = 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) (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_comment ⇒ Object
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 << " " } # 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 << " " } # 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_tag ⇒ Object
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
157 158 159 |
# File 'lib/isodoc/html_function/html.rb', line 157 def select_altsource?(_altsource, ) .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
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_class ⇒ Object
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 |
#toclevel ⇒ Object
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_classes ⇒ Object
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((script_cdata(inject_script(result)))) # Unescape & 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 |