Gibt das ursprüngliche Argument zurück, wenn csname nicht definiert ist

Gibt das ursprüngliche Argument zurück, wenn csname nicht definiert ist

Für einige #1definiere #2ich die \csname base:#1:#2\endcsname. Dann definiere ich Folgendes

\def\data#1#2{\ifcsname base:#1:#2\endcsname \csname base:#1:#2\endcsname\fi}

und danach

\newcommand{\name}[1]{\data{#1}{fname} \data{#1}{lname}}

\dataSie können es als zweidimensionales Array mit Informationen zu Benutzern mit ID sehen #1. Jetzt möchte ich sicherstellen, dass die ursprüngliche Eingabe gedruckt wird, wenn die Benutzer-ID nicht gefunden wird. Nehmen wir also an, ich habe Benutzer johnund elvismit vollständigen Informationen. Dann \name{elvis}wird als gedruckt Elvis Presley. Jetzt möchte ich #1drucken, wenn \csname base:#1:#2nicht definiert ist, d. h. es \name{santa}wird gedruckt, santa da Santa nicht in meiner Benutzerbasis ist. Ich habe versucht, mit zu arbeiten

\ifx\data{#1}{fname}\empty #1\else ...\fi

aber ich habe es nicht zum Laufen gebracht. Wie soll ich das machen?

Antwort1

Es wäre einfacher zu sehen, was Sie tun, und der beste Weg, dies mit einem vollständigen zu beantwortenminimales Arbeitsbeispiel (MWE), aber das ignorieren...

Die einfachste Lösung wäre eine Neudefinition \datawie folgt:

\def\data#1#2{%
  \ifcsname base:#1:#2\endcsname \csname base:#1:#2\endcsname%
  \else #1%
\fi}

aber ich vermute, dass das nicht das ist, was Sie wollen, da now \name{santa}erzeugt santa santa. Stattdessen denke ich, dass Sie wahrscheinlich etwas wie das Folgende definieren möchten:

\newif\ifDataExists
\newcommand\CheckForData[1]{%
  % assuming that fname a reasonable proxy to check for data?
  \ifcsname base:#1:fname\endcsname\DataExiststrue
  \else\DataExistsfalse
  \fi%
}
\newcommand\name[1]{\CheckForData{#1}%
  \ifDataExists{#1}{fname} \data{#1}{lname}\else #1\fi}

Wenn Sie jetzt Ihren ursprünglichen \dataBefehl verwenden, \name{santa}wird ein einzelnes erzeugt santa.

Antwort2

\documentclass{article}

\newcommand\data[2]{%
  \ifcsname base:#1:#2\endcsname
    \csname base:#1:#2\endcsname
  \else
    #1%
  \fi
}
\newcommand{\name}[1]{\data{#1}{fname} \data{#1}{lname}}

% populate one of the databases (I don't know how you do it)
\expandafter\def\csname base:elvis:fname\endcsname{Elvis}
\expandafter\def\csname base:elvis:lname\endcsname{Presley}

\begin{document}

\name{elvis}

\name{santa}

\end{document}

Bildbeschreibung hier eingeben

Es wäre zwar möglich, „Santa“ nur einmal auszudrucken, dies würde jedoch auch die Definition der \nameVerwendung von Prüfungen auf niedrigerer Ebene erschweren.


Wenn Sie meine vorgeschlagene expl3Implementierung verwenden würden, könnten Sie mit nur wenigen Änderungen ein \nameMakro erhalten, das über die gewünschte Eigenschaft verfügt:

\begin{filecontents*}{\jobname.csv}
id:john1; fname: John; lname: Doe; mail: [email protected]
id:harry1; fname: Harry; lname: Potter; mail: [email protected]
\end{filecontents*}

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn

\NewDocumentCommand{\storedata}{mm}
 {% pass control to an inner function
  \konewka_add_id:n { #1 }
  \konewka_store_data:nn { #1 } { #2 }
 }

\NewDocumentCommand{\readdata}{m}
 {
  \konewka_read_data:n { #1 }
 }

\DeclareExpandableDocumentCommand{\getdata}{mm}
 {
  \konewka_item:nn { #1 } { #2 }
 }

\NewDocumentCommand{\listIDs}{}
 {% just an example
  \seq_use:Nn \g_konewka_id_seq { ,~ }
 }

\NewDocumentCommand{\name}{m}
 {
  \konewka_if_key:nTF { #1 }
   {
    \konewka_item:nn { #1 } { fname }
    \c_space_tl
    \konewka_item:nn { #1 } { lname }
   }
   {
    \texttt{#1}
   }
 }

%%% variables

% we need a colon with the appropriate category code    
\tl_const:Nx \c_konewka_colon_tl { \tl_to_str:n {:} }
% other variables
\seq_new:N \g_konewka_id_seq

\tl_new:N \l__konewka_id_tl
\seq_new:N \l__konewka_data_temp_seq
\seq_new:N \l__konewka_field_temp_seq
\ior_new:N \g__konewka_read_data_stream

%%% variants of kernel functions
\cs_generate_variant:Nn \seq_set_split:Nnn { NV , NVV }
\cs_generate_variant:Nn \prop_gput:Nnn { cxx }

%%% our functions

% check if a key is present in the database
\prg_new_conditional:Nnn \konewka_if_key:n { p,T,F,TF }
 {
  \prop_if_exist:cTF { g_konewka_data_#1_prop }
   {
    \prg_return_true:
   }
   {
    \prg_return_false:
   }
 }

% add the new id to a sequence for possible later usage
\cs_new_protected:Nn \konewka_add_id:n
 {
  \seq_gput_right:Nn \g_konewka_id_seq { #1 }
 }
\cs_generate_variant:Nn \konewka_add_id:n { V }

% the inner function for \storedata
\cs_new_protected:Nn \konewka_store_data:nn
 {
  % create a property list for an ID
  \prop_new:c { g_konewka_data_#1_prop }
  % split the second argument at semicolons
  \seq_set_split:Nnn \l__konewka_data_temp_seq { ; } { #2 }
  % populate the property list
  \__konewka_process_entry:n { #1 }
 }

% the inner function for \readdata
\cs_new_protected:Nn \konewka_read_data:n
 {
  \ior_open:Nn \g__konewka_read_data_stream { #1 }
  \ior_map_inline:Nn \g__konewka_read_data_stream
   {
    % split a line into fields
    \seq_set_split:Nnn \l__konewka_data_temp_seq { ; } { ##1 }
    % retrieve the first field (ID)
    \seq_pop_left:NN \l__konewka_data_temp_seq \l__konewka_id_tl
    % split at colon and set the ID to the second part
    \seq_set_split:NVV \l__konewka_data_field_seq \c_konewka_colon_tl \l__konewka_id_tl
    \tl_set:Nx \l__konewka_id_tl { \seq_item:Nn \l__konewka_data_field_seq { 2 } }
    % add the id to the list
    \konewka_add_id:V \l__konewka_id_tl
    % populate the property list
    \__konewka_process_entry:V \l__konewka_id_tl
   }
 }

% syntactic sugar
\cs_new:Npn \konewka_item:nn #1 #2
 {% just retrieve the property from the appropriate property list
  \prop_item:cn { g_konewka_data_#1_prop } { #2 }
 }

% auxiliary function
\cs_new_protected:Nn \__konewka_process_entry:n
 {
  \seq_map_inline:Nn \l__konewka_data_temp_seq
   {
    \seq_set_split:NVn \l__konewka_data_field_seq \c_konewka_colon_tl { ##1 }
    \prop_gput:cxx { g_konewka_data_#1_prop }
     { \seq_item:Nn \l__konewka_data_field_seq { 1 } }
     { \seq_item:Nn \l__konewka_data_field_seq { 2 } }
   }
 }
\cs_generate_variant:Nn \__konewka_process_entry:n { V }

\ExplSyntaxOff

\readdata{\jobname.csv}
\storedata{uthor1}{fname: Algernon; lname: Uthor; mail: [email protected]}
\storedata{riter1}{fname: Walter; lname: Riter; mail: [email protected]}

\begin{document}

\begin{tabular}{cccc}
Id & fname & lname & mail \\
\hline
\texttt{john1} & \getdata{john1}{fname} & \getdata{john1}{lname} & \getdata{john1}{mail} \\
\texttt{harry1} & \getdata{harry1}{fname} & \getdata{harry1}{lname} & \getdata{harry1}{mail} \\
\texttt{uthor1} & \getdata{uthor1}{fname} & \getdata{uthor1}{lname} & \getdata{uthor1}{mail} \\
\texttt{riter1} & \getdata{riter1}{fname} & \getdata{riter1}{lname} & \getdata{riter1}{mail} \\
\end{tabular}

\medskip

The IDs are: \listIDs

\medskip

Print names: ``\name{john1}'' and ``\name{santa}''

\end{document}

Bildbeschreibung hier eingeben

verwandte Informationen