背景
下图显示了使用动态序言生成书籍的架构。图片顶部显示了书籍主题与其序言之间的数据库关系。顶部的一组编号项目代表:
- LaTeX片段,随后整理成序言,存储在表格中。
- 控制最终文档各个方面(例如颜色、字体、布局)的各种片段。
- A主题由一组默认的代码片段组成(例如,A,乙,&C以下)。
当用户选择主题时,数据库查询会动态创建序言。用户可以选择主题,然后通过覆盖默认片段来调整它,如浏览器线框所示(即调色板、字体、照片等)。
输出格式
用户创建了一本书,如图所示。当用户点击“下载”按钮时,系统执行以下操作:
- 生成一个 XML 文档来收集书籍的信息。
- 根据主题和调整动态创建 LaTeX 序言。
- 将 XML 转换为
.tex
文件,注入 LaTeX 前言。 - 调用
pdflatex
创建一个.pdf
,包含多个索引、目录等。 - 将 PDF 返回给用户。
尽管 LaTeX 序言几乎全部由数据库驱动,但部分内容是用 XSLT 编码的,例如声明\documentclass
。参数化很容易。
问题
我想修改架构,让用户可以为不同的设备和文件格式(例如 ePub、Mobi、Kindle、PDF)创建文档版本。这没什么好说的,但任何图像都必须固定在页面上(即它们不能浮动;这里肯定是这样的)。
考虑到这种架构的限制,我应该采用什么方法来转换各种电子阅读器的 LaTeX 文档,以使产生的输出尽可能高质量,并且尽可能符合 PDF 布局?
努力
我曾尝试将现有的 LaTeX 直接转换为 XHTML。使用 Hevea、latex2html、pandoc 和 mk4ht (htlatex) 都以惊人的方式失败,主要是因为对文件的依赖性.cls
。
我的想法是,我至少要做到以下几点:
- 允许用户选择 ePub 格式(在图表中“点击”之前)。
- 更新 XSLT 以删除对该
.cls
文件的引用(针对 ePub 格式)。
在那之后...?
源代码
这.cls 源代码是开源项目。 有一个例如 .tex存储库中的文件,以及示例主题。请注意,示例文件中的图像.tex
不在存储库中,因此生成 PDF 需要进行微小的修改。
此外,还有一个安装脚本 ( install.sh
),可将依赖的工件放入特定目录中。如果不进行修改,它可能无法适用于其他 LaTeX 安装。
错误
本节根据记忆描述我遇到的错误。
潘多克
无法解析该.tex
文件。
latex2html
无法找到.cls
文件,尽管它位于TEXMFHOME
。pdflatex
程序可以毫无问题地生成 PDF。生成许多难以阅读的 PNG 图像,尽管内容大部分是文本:
mk4ht 和 htlatex
能够生成 HTML 文档,但似乎存在一些 UTF8 编码问题(输出是乱码)。还有图像缩放问题(即图像没有缩小)。不确定为什么结果是乱码,因为它是 UTF8 编码的:
$ file -bi 22.tex
text/x-tex; charset=utf-8
橡胶树
要求.cls
将文件转换为.hva
。该.cls
文件依赖于memoir
和enumitem
,但目前尚未实现。
塑料制品
生成许多警告和一些错误,例如:
ERROR: Error while expanding "csname" in /usr/local/texlive/2013/texmf-
dist/tex/latex/ccicons/ccicons.sty on line 31 (sequence item 4: expected
string or Unicode, @currname found)
尽管它最初可以找到该.cls
文件,但无法打开它:
Traceback (most recent call last):
File "/usr/local/bin/plastex", line 108, in <module>
main(sys.argv)
File "/usr/local/bin/plastex", line 54, in main
tex.parse()
File "/usr/local/lib/python2.7/dist-packages/plasTeX/TeX.py", line 387, in parse
for item in tokens:
...
LaTeX 的替代品
我倾向于非 LaTeX 解决方案。由于 XML 和 XSLT 已经是架构的一部分,因此使用 DocBook 创建书籍可能是一种更简单的方法。有许多支持工具,DocBook 可以轻松转换为 EPUB2、EPUB3、HTML 等格式。
答案1
我能够使用 tex4ht 编译包含索引的示例。制作4小时(参见安装说明)。结果不太美观,需要一些 css 和配置,而且缺少图像:示例书.html
但这是你可以在此基础上进行构建的。
我不得不对示例书.tex:
\usepackage[noautomatic]{imakeidx}
\makeindex[name=flatingred]
\makeindex[name=catingred]
\title{Dan's Delicious Desserts}
\date{2013-06-09}
\author{Dave Jarvis}
\frontcoverphoto[]{}
\begin{document}
\let\index\Index
此代码使用imakeidx
而不是memoir
进行索引。我对 进行了一些配置imakeidx
,imakeidx.4ht
我使用它来使用 xindy 和 tex4ht 处理索引,以获取从索引到术语位置的正确链接:
\usepackage[]{etoolbox}
\newcounter{indexcnt}
\let\@Index\@index
\patchcmd{\@Index}{\@wrindex}{\@Wrindex}{}{}
\let\@Wrindex\@wrindex
\patchcmd{\@Wrindex}{\thepage}{\theindexcnt/}{}{}
\let\xIndex\index
\patchcmd{\xIndex}{\@index}{\@Index}{}{}
\patchcmd{\xIndex}{\@index}{\@Index}{}{}
\pretocmd{\xIndex}{\@stepindexcnt\@indexanchor}
%\patchcmd{\index}{\@index}{\@Index}{}{}
%\patchcmd{\xIndex}{\@index}{\@Index}{}{}
%\let\protected@iwrite\protected@write
%\let\@index\@Index
%\patchcmd{\protected@iwrite}{\write}{\immediate\write}{}{}
\patchcmd{\@Wrindex}{\protected@write}{\protected@iwrite}{}{}
\let\Index\xIndex
%\show\Index
\newcommand\@indexanchor{%
\edef\idx@anch{idx-anch\theindexcnt}%
\Link[]{}{\idx@anch}\EndLink%
%\Ref{(idx-link-\idx@anch)}{\FileName/\idx@anch}
}
\newcommand\@stepindexcnt{\stepcounter{indexcnt}}
\newcommand\hello[1]{\@hello#1}
\def\@hello#1/{%
\Link{idx-anch#1}{}#1\EndLink%
}
以及xindy
用此方法生成的要处理的模块imakeidx.xdy
:
(define-location-class "t4ht-loc"
("arabic-numbers" :sep "/")
:hierdepth 1
)
(define-attributes (("definition" "default")))
(merge-to "definition" "default" :drop)
(markup-locref :open "\hello{" :close "}" :class "t4ht-loc")
(markup-locref :open "\textbf{\hello{" :close "}}" :class "t4ht-loc" :attr "textbf")
(markup-locref :open "\textbf{\hello{" :close "}}" :class "t4ht-loc" :attr "definition")
现在我们必须指示make4ht
运行 xindy,使用自定义的 make 脚本example-book.mk4
:
Make:add("texindy", "texindy -M imakeidx -L ${lang} ${name}.idx", {lang="english"})
Make:htlatex {}
Make:texindy {name="flatingred"}
Make:texindy {name="catingred"}
Make:htlatex {}
现在我们可以使用命令来处理该文件:
make4ht -u example-book
最后一个问题是 生成了大量的空图像tex4ht
。我发现这是由包引起的。因此,您必须在运行时wallpaper
编辑文件recipe-book.cls
以注释掉:wallpaper.sty
tex4ht
\RequirePackage{endnotes}
\RequirePackage{afterpage}
\ifdefined\HCode
\else
\RequirePackage{wallpaper}
\fi
\RequirePackage{pdflscape}
\RequirePackage{wrapfig}
\RequirePackage{filecontents}
\RequirePackage{microtype}
\RequirePackage{bookmark}
\RequirePackage{relsize}
您可能需要添加一些配置来模拟缺少的功能,但对于我来说,该示例编译时没有错误。