csname이 정의되지 않은 경우 원래 인수를 반환합니다.

csname이 정의되지 않은 경우 원래 인수를 반환합니다.

어떤 경우 에는 #1. 그런 다음 다음을 정의합니다.#2\csname base:#1:#2\endcsname

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

그리고 그 이후

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

\dataid를 가진 사용자 정보를 2차원 배열로 볼 수 있습니다 #1. 이제 사용자 ID를 찾을 수 없을 때 원래 입력이 인쇄되는지 확인하고 싶습니다. 즉, 사용자가 john있고 elvis전체 정보를 가지고 있다고 가정합니다 . 그러면 \name{elvis}다음과 같이 인쇄됩니다 Elvis Presley. 이제 정의되지 않은 #1경우 인쇄 하고 싶습니다 . 즉, 산타가 내 사용자 기반에 없기 때문에 인쇄할 것입니다 . 나는 함께 일하려고 노력했다\csname base:#1:#2\name{santa}santa

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

하지만 작동시킬 수 없었습니다. 어떻게 해야 하나요?

답변1

자신이 무엇을 하고 있는지 확인하는 것이 더 쉬울 것이며 이에 대해 완전한 답변을 제공하는 가장 좋은 방법은최소 작업 예(MWE), 하지만 이를 무시하면...

가장 간단한 해결책은 다음 \data과 같이 재정의하는 것입니다.

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

그러나 나는 이것이 지금 당신이 원하는 것이 아닐 것이라고 생각 \name{santa}합니다 santa santa. 대신에 다음과 같이 정의하고 싶을 수도 있습니다.

\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}

이제 원래 \data명령을 사용 \name{santa}하면 단일 santa.

답변2

\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}

여기에 이미지 설명을 입력하세요

"산타"를 한 번만 인쇄하는 것도 가능하지만 \name낮은 수준의 검사 사용에 대한 정의도 복잡해집니다.


제가 제안한 구현을 사용했다면 expl3몇 가지 수정만으로 \name필요한 속성을 가진 매크로가 제공될 것입니다.

\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}

여기에 이미지 설명을 입력하세요

관련 정보