make4ht 使用通过 TiKZ 生成的内联 SVG,而不是外部文件

make4ht 使用通过 TiKZ 生成的内联 SVG,而不是外部文件

默认情况下,make4ht将 TiKZ 转换为单独的 SVG 文件并将其单独放入活动文件夹中。有没有办法覆盖此行为并强制make4ht将 SVG 内联到输出 HTML 中?

答案1

使用 XML DOM 后处理可以很容易地完成此操作make4ht。将以下代码保存为build.lua

local domfilter = require "make4ht-domfilter"
local domobject = require "luaxml-domobject"

local function fix_ids(dom, prefix)
  -- we need to prevent duplicate ID attributes in included SVG, so we add a prefix to them
  dom:traverse_elements(function(element)
    local id = element:get_attribute("id")
    if id then
      element:set_attribute("id",  prefix .. id)
    end

    local xlink = element:get_attribute("xlink:href")
    if xlink and xlink:sub(1,1) == "#"  then
      element:set_attribute("xlink:href", "#" .. prefix .. xlink:sub(2))
    end

    local clip = element:get_attribute("clip-path")
    if clip then
      element:set_attribute("clip-path", clip:gsub("%#", "#" .. prefix))
    end

  end)

end

local process = domfilter {
  function(dom)
    for count, img in ipairs(dom:query_selector "img") do
      local file = img:get_attribute "src" or ""
      -- because we sometimes use imgdir option, script should not search in imgdir directory
      -- the next line therefore transformes imgdir/tikz.svg to tikz.svg
      local filename = file:match("^.+/(.+)$")
      if not filename then filename = file end
      -- process all SVG images 
      if filename:match("svg$") then
        -- open the SVG file and load it into a string
        local f = io.open(filename, "r")
        local content = f:read("*all")
        f:close()
        -- parse it to a new DOM object
        local newdom = domobject.parse(content)
        fix_ids(newdom, "x" .. count .. "-")
        -- now find the <svg> element
        local root = newdom:root_node()
        -- <svg> should be a child of the root node
        for _, child in ipairs(root:get_children()) do
          -- replace <img> with <svg>
          if child:is_element() and child:get_element_name() == "svg" then
            img:replace_node(child)
          end
        end
      end
    end
    return dom
  end
}

-- call the LuaXML dom processing on all HTML files
Make:match("html$", process)

现在你可以使用以下方式编译你的文件

$ make4ht -e build.lua filename.tex

构建文件循环遍历所有<img>元素,当它链接到一个svg文件时,它将使用 LuaXML 对其进行解析,并<img>用解析后的 SVG 替换该元素。

以下是一个例子:

\documentclass{article}
\usepackage{tikz}
\begin{document}

Hello TikZ

\begin{tikzpicture}[scale=4,cap=round,>=latex]
% Radius of regular polygons
  \newdimen\R
  \R=0.8cm
  \coordinate (center) at (0,0);
 \draw (0:\R)
     \foreach \x in {60,120,...,360} {  -- (\x:\R) }
              -- cycle (300:\R) node[below] {$\csc \theta$}
              -- cycle (240:\R) node[below] {$\sec \theta$}
              -- cycle (180:\R) node[left] {$\tan \theta$}
              -- cycle (120:\R) node[above] {$\sin \theta$}
              -- cycle (60:\R) node[above] {$\cos \theta$}
              -- cycle (0:\R) node[right] {$\cot \theta$};
  \draw { (60:\R) -- (120:\R) -- (center) -- (60:\R) } [fill=gray];
  \draw { (180:\R) -- (240:\R) -- (center) -- (180:\R) } [fill=gray];
  \draw { (0:\R) -- (300:\R) -- (center) -- (0:\R) }  [fill=gray];
   \R=0.1cm
  \draw (0:\R) \foreach \x in {60,120,...,360} { -- (\x:\R) }
    [fill=white] -- cycle (center) node {1};
\end{tikzpicture}


\begin{tikzpicture}[sibling distance=10em,
  every node/.style = {shape=rectangle, rounded corners,
    draw, align=center,
    top color=white, bottom color=blue!20}]]
  \node {Formulas}
    child { node {single-line} }
    child { node {multi-line}
      child { node {aligned at}
        child { node {relation sign} }
        child { node {several places} }
        child { node {center} } }
      child { node {first left,\\centered,\\last right} } };
\end{tikzpicture}
\end{document}

看起来像这样:

在此处输入图片描述

生成的文件太大,无法粘贴到这里,但图像已内联包含。

相关内容