
Der Titel sagt alles: Wie kann ich Leerzeichen wie „ \ignorespaces
dos“ ignorieren, aber ein einfügen ~
?
Der Grund für meine Frage ist, dass wir mehrere Autoren sind, die ein Dokument schreiben, und sie haben unterschiedliche Gewohnheiten im Hinblick auf die Eingabe französischer Guillemets in ihrem Quellcode (d. h. «bla»
, « bla »
und «~bla~»
), und ich möchte dies vereinheitlichen, indem ich ein \newunicodechar{«}
mit der entsprechenden Definition setze.
Zum Abschluss \unskip
scheint Guillemet in allen Fällen zu funktionieren.
Antwort1
Hier ist eine LuaLaTeX-basierte Lösung. Sie definiert eine Lua-Funktion, die den Großteil der Arbeit erledigt, sowie einige LaTeX-Hilfsmakros, die die Lua-Funktion aktivieren und deaktivieren. Mit „aktivieren“ meine ich „die Lua-Funktion dem process_input_buffer
Callback von LuaTeX zuweisen“, damit sie als Präprozessor für den Eingabestrom fungieren kann.VorTeX startet seine übliche Verarbeitung.
% !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}
Antwort2
Mit expl3 ist es wirklich einfach (obwohl die Leistung aufgrund der extremen Allgemeingültigkeit der relevanten Funktionen möglicherweise nicht optimal ist):
%! 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}
Nur zur Demonstration verwende ich hier zwei irrelevante Unicode-Zeichen.
Die Leistung könnte durch Vorkompilieren des regulären Ausdrucks etwas optimiert werden:
\regex_new:N \l_ysalmon_regex
\regex_set:Nn \l_ysalmon_regex {(\cA\~|\cS\ )+}
\newunicodechar{≡}{123\peek_regex_remove_once:NT\l_ysalmon_regex{}}
(Variable nach dem Benutzernamen des OP benannt. Bei Bedarf ändern)
Die peek
Funktionsfamilie behandelt einige Sonderfälle nicht richtig, aber das ist so selten, dass es in der Praxis praktisch unmöglich ist.
Antwort3
Es ist einfacher, vor einem schließenden Guillemet allen Kleber, alle Kerne und Strafen zu entfernen, als das zu entfernen, was nach einem öffnenden Guillemet kommt.
Auf jeden Fall sollte dies ziemlich effizient sein.
\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}
Antwort4
Ich möchte erwähnen, dass babel-french v3.5o das Problem behebt (nur für die LuaTeX-Engine): Die Codierung „ «bla»
or“ « bla »
oder „or“ «~bla~»
erzeugt dieselbe Ausgabe.
\documentclass{article}
\usepackage{fontspec}
\usepackage[french]{babel}
\frenchsetup{og=«, fg=»}
\begin{document}
«bla» « bla » «~bla~» \frquote{bla}
\end{document}
druckt