我正在排版一段文本,想使用 LuaLaTeX 在双标点前添加空格。
给你这个想法:使用这个答案和这个,我编写了以下不起作用的代码(对于“Test!”它返回“Test0.1em!”并且我确实期望“Test!”)
\def\dblpnct#1{\unskip\noexpand\hspace{0.1em}#1}
\usepackage{luacode}
\begin{luacode}
function dosub(s)
s = string.gsub(s, '!', '\\dblpnct!')
s = string.gsub(s, ':', '\\dblpnct:')
s = string.gsub(s, ';', '\\dblpnct;')
s = string.gsub(s, '?', '\\dblpnct?')
return(s)
end
\end{luacode}
\AtBeginDocument{%
\luaexec{luatexbase.add_to_callback("process_input_buffer", dosub, "dosub")}%
}
答案1
\noexpand
是罪魁祸首。但移除它并不是完整的答案。
没有理由\dblpnct
用论点来定义,但这不是一个真正的问题。
如果您在双标点符号前实现法式空格,则应注意冒号遵循不同的规则:它前面和后面应有正常的单词间空格。但最重要的是,您不希望添加的空格成为可行的换行点。
防御代码也要求\unskip
只有在我们处于水平模式时才会发出。
\documentclass{article}
\usepackage{luacode}
\usepackage{etoolbox}
\newrobustcmd\dblpnct[1]{%
\ifhmode\unskip\fi
\nolinebreak#1%
}
\begin{luacode}
function dosub(s)
s = string.gsub(s, '!', '\\dblpnct{\\hspace{0.1em}}!')
s = string.gsub(s, ':', '\\dblpnct{\\space}:')
s = string.gsub(s, ';', '\\dblpnct{\\hspace{0.1em}};')
s = string.gsub(s, '?', '\\dblpnct{\\hspace{0.1em}}?')
return(s)
end
\end{luacode}
\AtBeginDocument{%
\luaexec{luatexbase.add_to_callback("process_input_buffer", dosub, "dosub")}%
}
\begin{document}
Some text ! Or is it a question ? The colon : obeys different ; rules.
Some text! Or is it a question? The colon: obeys different; rules.
\end{document}
而且您还应该在数学模式下禁用此功能,否则间距肯定是错误的。
\documentclass{article}
\usepackage{luacode}
\usepackage{etoolbox}
\newrobustcmd\dblpnct[1]{%
\ifmmode\else
\ifhmode\unskip\fi
\nolinebreak#1%
\fi
}
\begin{luacode}
function dosub(s)
s = string.gsub(s, '!', '\\dblpnct{\\hspace{0.1em}}!')
s = string.gsub(s, ':', '\\dblpnct{\\space}:')
s = string.gsub(s, ';', '\\dblpnct{\\hspace{0.1em}};')
s = string.gsub(s, '?', '\\dblpnct{\\hspace{0.1em}}?')
return(s)
end
\end{luacode}
\AtBeginDocument{%
\luaexec{luatexbase.add_to_callback("process_input_buffer", dosub, "dosub")}%
}
\begin{document}
Some text ! Or is it a question ? The colon : obeys different ; rules.
Some text! Or is it a question? The colon: obeys different; rules.
Oh, what about math ? $a:b$ and $(a;b)$
\end{document}
如果删除条件,请检查结果\ifmmode
。
为了禁用\label
和的参数中的行为\ref
,您可以使用\ifincsname
,但这需要更改的定义\label
。
\documentclass{article}
\usepackage{luacode}
\usepackage{etoolbox}
\newrobustcmd\dblpnct[1]{%
\ifincsname
\else
\ifmmode\else
\ifhmode\unskip\fi
\nolinebreak#1%
\fi
\fi
}
\makeatletter
% latex.ltx, line 4070:
\def\label#1{\@bsphack
\protected@write\@auxout{\let\dblpnct\@gobble}% <-- disable in \label
{\string\newlabel{#1}{{\@currentlabel}{\thepage}}}%
\@esphack}
\makeatother
\begin{luacode}
function dosub(s)
s = string.gsub(s, '!', '\\dblpnct{\\hspace{0.1em}}!')
s = string.gsub(s, ':', '\\dblpnct{\\space}:')
s = string.gsub(s, ';', '\\dblpnct{\\hspace{0.1em}};')
s = string.gsub(s, '?', '\\dblpnct{\\hspace{0.1em}}?')
return(s)
end
\end{luacode}
\AtBeginDocument{%
\luaexec{luatexbase.add_to_callback("process_input_buffer", dosub, "dosub")}%
}
\begin{document}
Some text ! Or is it a question ? The colon : obeys different ; rules.
Some text! Or is it a question? The colon: obeys different; rules.
Oh, what about math ? $a:b$ and $(a;b)$
Here's a reference to page~\pageref{page:x}\label{page:x}.
\end{document}
答案2
正如我在评论中指出的那样:只需
\noexpand
从 OP 的代码中删除即可。