Dies könnte ein sehr grundlegendes Problem sein (als Folge vondiese Frage), aber ich weiß nicht, wie ich das machen soll: Ich brauche ein Makro \mycmd{sometext}
, das einen String abhängig vom ersten Buchstaben seines Arguments erzeugt. Dieser resultierende String sollte anschließend mit groß geschrieben werden \makefirstuc
.
\documentclass{article}
\usepackage{xparse} % used in example below
\usepackage{pgffor} % used in example below
\usepackage{xstring} % used in example below
\newcommand{\mycmd}[1]{
% here, I define a list of letters {a,e,i,o,u,A,E,I,O,U}
% that will lead to the output "an " in case
% the argument string starts by one of them.
% Otherwise the output shall be "a ".
}
\begin{document}
\mycmd{somestring} % should print "a "
\makefirstuc{\mycmd{sometext}} % should print "A "
\mycmd{otherstring} % should print "an "
\makefirstuc{\mycmd{otherstring}} % should print "An "
\end{document}
Ich habe versucht, dies zu realisieren, indem ich das pfgfor
Paket für die Schleife verwende und dabei das erste Zeichen mit dem \IfBeginWith
aus dem xstring
Paket vergleiche. Dies führt jedoch anscheinend zu nicht erweiterbaren Befehlen, sodass dies \makefirstuc
fehlschlägt.Wie kann man einen erweiterbaren Befehl mit dieser Funktionalität erreichen?
Bisher habe ich den folgenden nicht erweiterbaren Befehl erstellt:
\NewDocumentCommand{\mycmd}{m}{%
\def\undefart{a\space}%
\foreach \c in {a,e,i,o,u,A,E,I,O,U}{%
\IfBeginWith{#1}{\c}{\global\def\undefart{an\space}}{}%
}%
\undefart%
}
Antwort1
Dies ist ganz einfach mit expl3
(es gibt mehrere mögliche Ansätze):
\documentclass{article}
\usepackage{expl3,xparse}
\ExplSyntaxOn
\DeclareExpandableDocumentCommand \mycmd { m }
{
\__mycmd_loop:nN {#1} aeiouAEIOU \q_recursion_tail \q_recursion_stop
}
\cs_new:Npn \__mycmd_loop:nN #1#2
{
\quark_if_recursion_tail_stop_do:nn {#2} { a }
\tl_if_head_eq_charcode:nNT {#1} #2
{
\use_i_delimit_by_q_recursion_stop:nw { an }
}
\__mycmd_loop:nN {#1}
}
\ExplSyntaxOff
\usepackage{mfirstuc}
\begin{document}
\mycmd{somestring} % should print "a "
\emakefirstuc{\mycmd{sometext}} % should print "A "
\mycmd{otherstring} % should print "an "
\emakefirstuc{\mycmd{otherstring}} % should print "An "
\end{document}
Da \makefirstuc
keine Erweiterung vorhanden ist, musste ich die e
Version verwenden. Ich würde das wahrscheinlich lieber umgehen, indem ich die erweiterbare (und Unicode-fähige) Version verwende \text_titlecase:n
:
\documentclass{article}
\usepackage{expl3,xparse}
\ExplSyntaxOn
\DeclareExpandableDocumentCommand \mycmd { m }
{
\__mycmd_loop:nN {#1} aeiouAEIOU \q_recursion_tail \q_recursion_stop
}
\cs_new:Npn \__mycmd_loop:nN #1#2
{
\quark_if_recursion_tail_stop_do:nn {#2} { a }
\tl_if_head_eq_charcode:nNT {#1} #2
{
\use_i_delimit_by_q_recursion_stop:nw { an }
}
\__mycmd_loop:nN {#1}
}
\cs_new_eq:NN \Mymakefirstuc \text_uppercase:n
\ExplSyntaxOff
\begin{document}
\mycmd{somestring} % should print "a "
\Mymakefirstuc{\mycmd{sometext}} % should print "A "
\mycmd{otherstring} % should print "an "
\Mymakefirstuc{\mycmd{otherstring}} % should print "An "
\end{document}
Abhängig von der Anzahl der Fälle kann es wünschenswert sein, alle Eingaben zunächst in Kleinbuchstaben zu schreiben.
\DeclareExpandableDocumentCommand \mycmd { m }
{
\exp_args:Nf \__mycmd:n { \text_lowercase:n {#1} }
}
\cs_new:Npn \__mycmd:n #1
{
\__mycmd_loop:nN {#1} aeiou \q_recursion_tail \q_recursion_stop
}
Antwort2
Hier ist ein Ansatz mitexpl3
\documentclass{article}
\usepackage{xparse,glossaries}
\ExplSyntaxOn
\DeclareExpandableDocumentCommand{\indef}{m}
{
\str_case_x:nnF { \tl_head:f { \tl_lower_case:n { #1 } } }
{
{a}{an}
{e}{an}
{i}{an}
{o}{an}
{u}{an}
}
{a}~#1
}
\ExplSyntaxOff
\begin{document}
\indef{abc} --- \indef{cde} --- \indef{ABC} --- \indef{CDE}
\emakefirstuc{\indef{abc}} --- \emakefirstuc{\indef{cde}} ---
\emakefirstuc{\indef{ABC}} --- \emakefirstuc{\indef{CDE}}
\end{document}
Antwort3
Hier ist eine LuaLaTeX-basierte Lösung. Sie definiert zwei vollständig erweiterbare „Wrapper“-Makros mit den Namen \mycmd
und \mkfirstuc
, die ihre Argumente an Lua-Funktionen mit den Namen mycmd
und übergeben mkfirstuc
. Die Lua-Funktionen führen die eigentliche Arbeit aus, indem sie einem String jeweils „an“ oder „a“ voranstellen und das erste Zeichen im String groß schreiben.
% !TEX TS-program = lualatex
\documentclass{article}
%% Lua-side code
\usepackage{luacode}
\begin{luacode}
function mycmd ( s )
if string.match ( string.sub(s,1,1) , "[aeiouAEIOU]" ) then
return tex.sprint ("an " .. s)
else
return tex.sprint ("a " .. s)
end
end
function mkfirstuc ( s )
return tex.sprint ( string.upper(string.sub(s,1,1)) .. string.sub(s,2) )
end
\end{luacode}
%% TeX-side code
\newcommand\mycmd[1]{\directlua{mycmd(\luastring{#1})}}
\newcommand\mkfirstuc[1]{\directlua{mkfirstuc(\luastring{#1})}}
\begin{document}
\mycmd{abc}, \mycmd{def}, \mycmd{ABC}, \mycmd{DEF}.
\mkfirstuc{\mycmd{abc}}, \mkfirstuc{\mycmd{def}},
\mkfirstuc{\mycmd{ABC}}, \mkfirstuc{\mycmd{DEF}}.
\end{document}
Antwort4
Ist das gemeint? expl3
Ich weiß, das ist nicht die effektivste Verwendung von ;-)
\documentclass{article}
\usepackage{xparse} % used in example below
\usepackage{pgffor} % used in example below
\usepackage{xstring} % used in example below
\ExplSyntaxOn
\clist_set:Nn \l_tinytot_lowercaseletters_clist {a,e,i,o,u}
\clist_set:Nn \l_tinytot_letters_clist {a,e,i,o,u,A,E,I,O,U}
\NewDocumentCommand{\makefirstuc}{m}{%
\tl_to_uppercase:n {#1}
}
\NewDocumentCommand{\checkstart}{m}{%
\tl_set:Nx \l_tmpa_tl {#1}
\tl_trim_spaces:N \l_tmpa_tl
\tl_set:Nx \l_tmpb_tl { \tl_item:Nn \l_tmpa_tl {1}}
\clist_if_in:NVTF \l_tinytot_letters_clist {\l_tmpb_tl }{%
\clist_if_in:NVTF \l_tinytot_lowercaseletters_clist {\l_tmpb_tl}
{
an
}{
An
}
}{
\clist_if_in:NVTF \l_tinytot_lowercaseletters_clist {\l_tmpb_tl}
{
a
}{
A
}
}
}
\ExplSyntaxOff
\newcommand{\mycmd}[1]{%
\checkstart{#1}
% here, I define a list of letters {a,e,i,o,u,A,E,I,O,U}
% that will lead to the output "an " in case
% the argument string starts by one of them.
% Otherwise the output shall be "a ".
}
\begin{document}
\mycmd{somestring} % should print "a "
\makefirstuc{\mycmd{sometext}} % should print "A "
\mycmd{otherstring} % should print "an "
\makefirstuc{\mycmd{otherstring}} % should print "An "
\end{document}