
Название говорит само за себя: как я могу игнорировать пробелы, например \ignorespaces
, делает, но включая ~
?
Причина, по которой я спрашиваю, заключается в том, что мы — несколько авторов, пишущих документ, и у них разные привычки в отношении ввода французских гильеметов в исходном коде (например, «bla»
, « bla »
и «~bla~»
), и я хочу унифицировать это, установив \newunicodechar{«}
с соответствующим определением.
Что касается закрывающего жаберного кольца, \unskip
то, похоже, оно срабатывает во всех случаях.
решение1
Вот решение на основе LuaLaTeX. Оно определяет функцию Lua, которая выполняет большую часть работы, плюс пару макросов утилит LaTeX, которые активируют и деактивируют функцию Lua. Под «активировать» я подразумеваю «назначить функцию Lua process_input_buffer
обратному вызову LuaTeX», чтобы она могла действовать как препроцессор входного потокадоTeX начинает обычную обработку.
% !TEX TS-program = lualatex
\documentclass{article}
\usepackage[french]{babel} % for "\og" and "\fg" macros
\usepackage[french=guillemets]{csquotes} % for "\enquote" macro
\usepackage{luacode} % for "luacode" environment
%% Lua-side code
\begin{luacode}
function delete_whitespace ( s )
s = s:gsub ( "«[ ~]*" , "\\og " )
s = s:gsub ( "[ ~]*»" , "\\fg " )
-- s = s:gsub ( "[ ~]+([%:%;%?%!])" , "%1" ) -- if needed
return s
end
\end{luacode}
%% LaTeX-side code
\newcommand\DeletewhitespaceOn{\luadirect{luatexbase.add_to_callback (
"process_input_buffer", delete_whitespace , "deletewhitespace" )}}
\newcommand\DeletewhitespaceOff{\luadirect{luatexbase.remove_from_callback (
"process_input_buffer", "deletewhitespace" )}}
\AtBeginDocument{\DeletewhitespaceOn} % enable by default
\begin{document}
\enquote{bla} \og{}bla\fg{} «bla» « bla » «~bla~» «~ bla ~ »
\DeletewhitespaceOff
\enquote{bla} \og{}bla\fg{} «bla» « bla » «~bla~» «~ bla ~ »
\end{document}
решение2
С expl3 это действительно просто (хотя из-за чрезвычайной общности соответствующих функций производительность может быть не идеальной):
%! TEX program = lualatex
\documentclass{article}
\usepackage{newunicodechar}
\ExplSyntaxOn
\newunicodechar{×}{123\ignorespaces}
\newunicodechar{≡}{123\peek_regex_remove_once:nT{(\cA\~|\cS\ )+}{}}
\ExplSyntaxOff
\begin{document}
× 456
×~456 %unfortunately does not work
% all of the below works:
≡ 456
≡~456
≡~~456
≡~ ~ 456
\end{document}
Просто для наглядности я использую два нерелевантных символа Unicode.
Производительность можно немного оптимизировать, предварительно скомпилировав регулярное выражение:
\regex_new:N \l_ysalmon_regex
\regex_set:Nn \l_ysalmon_regex {(\cA\~|\cS\ )+}
\newunicodechar{≡}{123\peek_regex_remove_once:NT\l_ysalmon_regex{}}
(переменная названа в соответствии с именем пользователя OP. При необходимости измените)
Семейство peek
функций не обрабатывает некоторые особые случаи правильно, но это настолько редко, что на практике это практически невозможно.
решение3
Легче удалить весь клей, керны и штрафы перед закрывающей каймой, чем то, что находится после открывающей.
В любом случае, это должно быть довольно эффективно.
\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{newunicodechar}
\newunicodechar{«}{<<\ignoreallspaces}
\newunicodechar{»}{\removeallspaces~>>}
\ExplSyntaxOn
\NewDocumentCommand{\removeallspaces}{}
{
\int_case:nnT { \lastnodetype }
{
{11}{\unskip}
{12}{\unkern}
{13}{\unpenalty}
}
{\removeallspaces}
}
\NewDocumentCommand{\ignoreallspaces}{}
{
\peek_remove_filler:n { \peek_charcode_remove:NT \c_tilde_str { \ignoreallspaces } }
}
\ExplSyntaxOff
\begin{document}
« ~ a ~~ »
\end{document}
решение4
Я хотел бы отметить, что babel-french v3.5o устраняет проблему (только для движка LuaTeX): кодирование «bla»
или « bla »
или «~bla~»
дает одинаковый результат.
\documentclass{article}
\usepackage{fontspec}
\usepackage[french]{babel}
\frenchsetup{og=«, fg=»}
\begin{document}
«bla» « bla » «~bla~» \frquote{bla}
\end{document}
отпечатки