使用 dvisvgm 与 htlatex 或 make4ht 输出不同的数学符号 SVG

使用 dvisvgm 与 htlatex 或 make4ht 输出不同的数学符号 SVG

下面代码的tex文件要转换成html。

\documentclass{article}
    \usepackage{amsmath,amssymb}
    \begin{document}
    \(\implies\) and \(\iff\) \\
    \(a \implies b\) \(a \iff b\)
    \end{document}

命令

htlatex texfile "xhtml,svg"

用于将 tex 文件转换为 html。符号\implies\iff转换为 svg 图像。生成的 svg 图像对于这些符号是不同的,如附图所示。如何解决这个问题?

在此处输入图片描述

答案1

编辑:

正如 Martin 在评论中提到的,一些字形可能会超出其边界框,这可能会导致其部分被裁剪。可以dvisvgm使用选项来跟踪实际的字形形状--exact。我将更新tex4ht以使用它。与此同时,您可以使用以下.mk4构建文件:

Make:image("svg$", "dvisvgm -n -p ${page} --exact -c 1.4,1.4 -s ${source} > ${output}")

结果:

在此处输入图片描述

原始答案:

似乎dvisvgm某些图片的尺寸设置错误,就像您示例中的独立箭头一样。似乎前两张图片的高度太小,因此图片被裁剪了。

第一张图片的高度是3.26027pt,而9.6859pt第三张图片的高度是。很明显,高度差异并不大。

我猜最好的解决方案是修复dvisvgm,但与此同时,可以使用make4ht过滤器来猜测正确的高度值。字符SVG作为<path>元素保存在文件中:

<path d='M7.23288 -3.25778C7.65131 -2.89913 8.1594 -2.6401 8.48817 -2.49066C8.12951 -2.33126 7.64134 -2.07223 7.23288 -1.72354H0.9066C0.737235 -1.72354 0.547945 -1.72354 0.547945 -1.52428S0.727273 -1.32503 0.896638 -1.32503H6.78456C6.30635 -0.86675 5.78829 0.00996264 5.78829 0.139477C5.78829 0.249066 5.91781 0.249066 5.97758 0.249066C6.05729 0.249066 6.12702 0.249066 6.16687 0.169365C6.37609 -0.209215 6.65504 -0.737235 7.30262 -1.31507C7.99004 -1.92279 8.65753 -2.19178 9.17559 -2.34122C9.34496 -2.401 9.35492 -2.41096 9.37484 -2.43088C9.39477 -2.44085 9.39477 -2.47073 9.39477 -2.49066S9.39477 -2.53051 9.38481 -2.55044L9.35492 -2.57036C9.33499 -2.58032 9.32503 -2.59029 9.13574 -2.65006C7.79078 -3.04857 6.79452 -3.95517 6.23661 -5.02117C6.12702 -5.22042 6.11706 -5.23039 5.97758 -5.23039C5.91781 -5.23039 5.78829 -5.23039 5.78829 -5.1208C5.78829 -4.99128 6.29639 -4.12453 6.78456 -3.65629H0.896638C0.727273 -3.65629 0.547945 -3.65629 0.547945 -3.45704S0.737235 -3.25778 0.9066 -3.25778H7.23288Z' id='g0-41'/>

路径中每个第二个数字都是y坐标。我的简单方法是处理文件y中的所有坐标svg,找到最大值,并将图像的高度设置为该值(如果它大于原始值)。这种方法并不是很可靠,因为曲线部分可能会在最大坐标上方渲染,但我不知道如何解决这个问题,我也不想编写适当的 SVG 路径解析器。所以我们希望这不会有太大影响。

将以下文件另存为mybuild.mk4

local filter = require "make4ht-filter"

local max = function(a,b)
  return a > b and a or b
end

local function get_height(svg)
  local height = svg:match("height='([0-9%.]+)pt'")
  return tonumber(height)
end

local function get_max_height(path,max_number)
  local coordinates = {}
  for number in path:gmatch("(%-?[0-9%.]+)") do
    table.insert(coordinates, tonumber(number))
  end
  for i = 2, #coordinates, 2 do
    max_number = max(max_number, coordinates[i])
  end
  return max_number
end

local function update_height(svg, height)
  return svg:gsub("height='.-pt'", "height='"..height .."pt'")
end

-- we need to fix the svg height
local process_svg = filter {function(svg)
  local max_height = 0
  local height = get_height(svg)
  for path in svg:gmatch("path d='([^']+)'") do
    -- find highest height in all paths in the svg file
    max_height = get_max_height(path, max_height)
  end
  -- update the height only if the max_height is larger than height set in the SVG file
  print(max_height, height)
  if max_height > height then
    svg = update_height(svg, max_height)
  end
  return svg
end}

Make:match("svg$", process_svg)

使用命令编译文件

make4ht -u -e mybuild.mk4 texfile svg

这是渲染的结果:

在此处输入图片描述

相关内容