我正在使用make4ht
将文档转换为 odt,并且我希望底层content.xml
采用 utf-8 编码。我使用u
以下选项make4ht
:
make4ht -uf odt filename.tex
请考虑以下文档:
\documentclass{article}
\usepackage[utf8]{inputenc}
\begin{document}
Hello World!!!
áéíóúâêîôûüãõç.
\end{document}
结果.odt
显示正确,但底层content.xml
将重音字符呈现为:
<text:p text:style-name="First-line-indent"> áéíóúâêîôûüãõç.
</text:p>
(即使 UTF-8 标头已经到位:)<?xml version="1.0" encoding="UTF-8"?>
。
和:
htlatex filename.tex "xhtml,ooffice,charset=utf-8" " -cmozhtf -utf8" " -coo"
我确实得到了正确的 utf-8 编码content.xml
。我还尝试将这些相同的参数传递给make4ht
,但无济于事。我应该怎么做才能确保make4ht
提供 utf-8 编码的.odt
输出?
答案1
编辑:的开发版本make4ht
现在支持ODT
输出中的过滤器,因此不再需要ODT
使用zip
方法更新文件。
简化的构建文件可能如下所示:
local filter = require "make4ht-filter"
local utfchar = unicode.utf8.char
local process = filter {
function(content)
return content:gsub("%&%#x([A-Fa-f0-9]+);", function(entity)
-- convert hexadecimal entity to Unicode
print(entity,utfchar(tonumber(entity, 16)))
return utfchar(tonumber(entity, 16))
end)
end
}
Make:match("4oo$", process)
只需要使用 生成的临时文件名tex4ht
,因此需要content.xml
处理带有.4oo
包含文档文本的扩展名的文件。
原始答案:
命令将Unicode 字符content.xml
转义为 XML 实体xtpipes
,对文件进行后期处理以修复一些与数学和部分有关的问题。xtpipes
可以t4ht
使用选项从命令中请求-cooxtpipes
,make4ht
默认使用此选项进行输出ODT
。
如果使用与 for 相同的参数htlatex
并省略xtpipes
,make4ht
将产生相同的结果,带有 Unicode 字符:
make4ht sample.tex "xhtml,ooffice" " -cmozhtf -utf8" " -coo"
<text:p text:style-name="First-line-indent"> áéíóúâêîôûüãõç.
但我建议不要禁用xtpipes
,因为这样最终可能会得到无效的 ODT 文件。
相反,可以使用make4ht
构建文件将实体转换为 Unicode:
local mkutils = require "mkutils"
local zip = require "zip"
local utfchar = unicode.utf8.char
-- use function to change contents of the ODT file
local function update_odt(odtfilename, file_path, fn)
-- get name of the odt file
local odtname = mkutils.remove_extension(odtfilename) .. ".odt"
-- open and read contents of the requested file inside ODT file
local odtfile = zip.open(odtname)
local local_file = odtfile:open(file_path)
local content = local_file:read("*all")
local_file:close()
odtfile:close()
-- update the content using user function
content = fn(content)
-- write the updated file
local local_file_file = io.open(file_path,"w")
local_file_file:write(content)
local_file_file:close()
os.execute("zip " .. odtname .. " " .. file_path)
os.remove(file_path)
end
Make:match("tmp$", function(name, par)
update_odt(name, "content.xml", function(content)
return content:gsub("%&%#x([A-Fa-f0-9]+);", function(entity)
-- convert hexadecimal entity to Unicode
print(entity,utfchar(tonumber(entity, 16)))
return utfchar(tonumber(entity, 16))
end)
end)
end)
因为ODT文件是按照调用的相同步骤进行压缩的xtpipes
,所以需要打开ODT文件,读取content.xml
文件内容,然后再次打包。
那么内容似乎是正确的:
<text:p text:style-name="First-line-indent"> áéíóúâêîôûüãõç.