我知道这个标题很糟糕,但我想不出更好的了。基本上,我想要的是能够编写普通文本,但编译后它会以自定义字母显示在 PDF 中。这与仅使用自定义字体不同,因为例如,如果我写“la”,它应该对应一个字符,而“lo”应该对应另一个不同的字符。关键是我希望能够在不使用一百亿个宏的情况下编写它,例如,如果我想写一行又一行,那么写 \customLA \customLO 而不是 la lo 会非常繁琐。
有没有一种简单而自动的方法可以用 LaTeX 来实现这一点?或者我应该用 C++ 编写自己的解析程序来修改 LaTeX 文件,用宏替换字符组合?
答案1
这是一个简单的 Lua 级替换工具。 中写入的所有内容\parseme
都是替换的目标,但 TeX 命令不会展开,我们可以隐藏替换过程中的一部分文本。替换项存储在一个简单的 Lua 表中,第一列包含搜索到的术语,第二列包含它们的替换项。测试从上到下进行。例如,A
很快就会被替换,并且不会再被替换。另一方面,X
将是Y
,然后Y
变为Z
,然后变为A
。命令的名称将被替换,例如\colorme
将变为。如果需要,\cojuicerme
我使用命令来说明一种快速的解决方法。\clrme
如果你需要比该库提供的更高级的字符串操作工具string
,我推荐你LPeg
库,这是 LuaTeX 中已经安装的工具。一些示例在使用 LuaTeX 进行编程文章。
如果你运行我的例子,你会1 2 3 4 5 6
在终端看到三次。这意味着\parseme
在排版过程中,命令调用了 6 个替换测试,共调用了 3 次。
%! lualatex mal-text-parser.tex
\documentclass[a4paper]{article}
\pagestyle{empty}
\parindent=0pt
% It fixes beginnings and endings of I/O lines, among other things...
\usepackage{luatextra}
\pagestyle{empty}
\usepackage{luacode}
\usepackage{xcolor}
\begin{document}
\def\parseme#1{% TeX definition...
\directlua{parseme("\unexpanded{#1}")}%
% This is working: "\unexpanded{#1}" but one must write \\ instead of backslash in the \parseme command.
}% End of \parseme command...
\begin{luacode*}
-- A conversion table, from -> to
local maltable={
{"la", "beer"},
{"lo", "juice"},
{"A", "Hello World! I was here! Phantom-as!"},
{"X","Y"},
{"Y","Z"},
{"Z","A"},
}
function parseme(text) -- Lua function
-- Read an argument sent by TeX...
content=text -- Backup of original text...
-- Do all the necessary replacements...
for i=1,#maltable do
tex.sprint("\\message{"..i.."}")
content=string.gsub(content,maltable[i][1],maltable[i][2])
end
-- Typeset the result at the terminal and to the document...
print(content)
tex.print(content)
end
\end{luacode*}
\def\formated{\textbf{lalo}} % This part is not replaced.
\def\clrme#1{{\color{red}#1}} % Definition of the command.
% We use \clrme instead of \colorme because we would get -> \cojuicerme as lo is being replaced...
% lalo in \formated is protected from expansion and replacement...
Text of the paragraph. \parseme{My long \\formated{} sentence. \\clrme{To la red!} \\textbf{Hey!} Ending. lalala lo lo lo A}\par
End of the paragraph. \parseme{My \\clrme{next} try.} The end.\par
Input is X, result is: \parseme{X}; X goes to Y to Z to A, but A is not replaced anymore.
\end{document}