require "base64" require "emf2svg" module IsoDoc class PresentationXMLConvert < ::IsoDoc::Convert def figure(docxml) docxml.xpath(ns("//image")).each { |f| svg_extract(f) } docxml.xpath(ns("//figure")).each { |f| figure1(f) } docxml.xpath(ns("//svgmap")).each do |s| if f = s.at(ns("./figure")) then s.replace(f) else s.remove end end docxml.xpath(ns("//image")).each { |f| svg_emf_double(f) } end def svg_extract(elem) return unless %r{^data:image/svg\+xml;}.match?(elem["src"]) svg = Base64.strict_decode64(elem["src"] .sub(%r{^data:image/svg\+xml;(charset=[^;]+;)?base64,}, "")) x = Nokogiri::XML.fragment(svg.sub(/<\?xml[^>]*>/, "")) do |config| config.huge end elem["src"] = "" elem.children = x end def figure1(elem) return sourcecode1(elem) if elem["class"] == "pseudocode" || elem["type"] == "pseudocode" return if elem.at(ns("./figure")) && !elem.at(ns("./name")) lbl = @xrefs.anchor(elem["id"], :label, false) or return prefix_name(elem, " — ", l10n("#{lower2cap @i18n.figure} #{lbl}"), "name") end def svg_emf_double(img) if emf?(img["mimetype"]) img = emf_encode(img) img.children.first.previous = emf_to_svg(img) elsif img["mimetype"] == "image/svg+xml" src = svg_to_emf(img) and img << "" end end def emf_encode(img) img["mimetype"] = "image/svg+xml" unless %r{^data:image}.match?(img["src"]) img["src"] = Metanorma::Utils::datauri(img["src"]) end img.children = "" img["src"] = "" img end def emf_to_svg(img) emf = Metanorma::Utils::save_dataimage(img.at(ns("./emf/@src")).text) Emf2svg.from_file(emf).sub(/<\?[^>]+>/, "") end def svg_to_emf(node) uri = svg_to_emf_uri(node) ret = svg_to_emf_filename(uri) File.exist?(ret) and return ret exe = inkscape_installed? or raise "Inkscape missing in PATH, unable" \ "to convert EMF to SVG. Aborting." uri = Metanorma::Utils::external_path uri exe = Metanorma::Utils::external_path exe system(%(#{exe} --export-type="emf" #{uri})) and return Metanorma::Utils::datauri(ret) raise %(Fail on #{exe} --export-type="emf" #{uri}) end def svg_to_emf_uri(node) uri = if node&.elements&.first&.name == "svg" a = Base64.strict_encode64(node.children.to_xml) "data:image/svg+xml;base64,#{a}" else node["src"] end if %r{^data:}.match?(uri) uri = save_dataimage(uri) @tempfile_cache << uri end uri end def svg_to_emf_filename(uri) "#{File.join(File.dirname(uri), File.basename(uri, '.*'))}.emf" end def emf_to_svgfilename(uri) "#{File.join(File.dirname(uri), File.basename(uri, '.*'))}.svg" end def inkscape_installed? cmd = "inkscape" exts = ENV["PATHEXT"] ? ENV["PATHEXT"].split(";") : [""] ENV["PATH"].split(File::PATH_SEPARATOR).each do |path| exts.each do |ext| exe = File.join(path, "#{cmd}#{ext}") return exe if File.executable?(exe) && !File.directory?(exe) end end nil end end end