newcommand 인수의 특정 부분만 읽기

newcommand 인수의 특정 부분만 읽기

내 기호 목록에 Glossaries-extra 패키지를 사용하고 있습니다. 여기에 관련이없는 어떤 이유로 새 명령을 정의했습니다

\newcommand{\symb}[3][]{%
\glsxtrnewsymbol[#1]{#2}{#3}%
 }

내 용어집 항목의 형식은 다음과 같습니다.

\symb[description={Set of Smooth Vector Fields}]{vfs}{\ensuremath{\mathfrak{X}}}

나는 이것을 용어집 패키지를 사용하지 않고 대신 다음과 같이 기호를 입력해야 하는 환경을 정의하는 대학의 논문 템플릿으로 "전송"하고 싶습니다.

\begin{symbols}

\sym{\ensuremath{\mathfrak{X}}}{Set of Smooth Vector Fields}

\end{symbols}

이것은 단순한 탭 환경으로, \sym 명령의 인수에 적어둔 내용을 직접 인쇄합니다. 그래서 내 계획은 다음과 같이 정의하는 것이 었습니다.

\renewcommand{\symb}[3][]{%
\glsxtrnewsymbol[#1]{#2}{#3}%
\sym{#3}{\glsdesc{#2}}%
}

이것은 용어집 패키지를 사용하는 것이 대학 스타일 파일의 다른 부분을 어지럽히는 것을 제외하고는 작동합니다. 그렇기 때문에 나는 이렇게 정의하고 싶다.

 \renewcommand{\symb}[3][]{%
            \sym{#3}{#1}%
    }

그러나 두 번째 인수에 대해 "설명={부드러운 벡터 필드 세트}"를 갖고 싶지 않고 "부드러운 벡터 필드 세트"를 갖고 싶습니다. \symb의 두 번째 인수에서 "매끄러운 벡터 필드 집합" 부분만 추출하는 방법이 있나요?

해결책: @Schrödinger의 고양이 솔루션의 단순화된 버전이 저에게 효과적입니다.

\newcommand{\symb}[3][]{%
\def\mysplit##1=##2{\sym{#3}{##2}}%
\expandafter\mysplit#1%
}

답변1

다음 코드를 사용하면 재정의된 루틴이 \symb다음과 같이 작동합니다.

\glsxtrnewsymbol인수 는 그대로 전달됩니다 .

다음과 같이 의 선택적 인수 \sym에서 설명을 추출한 후 인수가 전달됩니다 .\symb

해당 인수에 선행 문구 "description="이 포함되어 있지 않은 경우 그대로 전달됩니다. (전체 문구를 둘러싼 공백 토큰 및/또는 "설명"과 "=" 사이의 공백 토큰이 고려됩니다.)

인수에 "description="이라는 문구가 포함된 경우 해당 문구가 제거됩니다.

  • 나머지가 공간 토큰으로만 구성되거나 아무것도 구성되지 않은 경우 추출 결과는 비어 있거나 토큰으로 전혀 구성되지 않습니다.
  • 나머지가 구분되지 않은 단일 인수로 구성된 경우, 즉 단일 비중괄호 토큰 또는 중괄호 안에 중첩된 토큰 세트 중 하나인 경우 전체 나머지를 둘러싸는 한 수준의 중괄호가 있으면 제거되고 공백이 제거됩니다. -나머지 전체를 둘러싼 토큰이 제거됩니다.
  • 나머지가 구분되지 않은 단일 인수가 아닌 다른 것으로 구성된 경우 중괄호는 제거되지 않지만 전체 나머지를 둘러싼 공백은 제거됩니다.

\sym및 는 나에게 제공되지 않기 때문에 \glsxtrnewsymbol나는 꺾쇠 괄호 안에 중첩된 토큰화되지 않은 방식으로 주장을 전달하는 것 외에는 아무것도 수행하지 않는 "더미 정의"를 제공했습니다.

나는 이 모든 것을 즉각적으로 수행했기 때문에 보증이 없습니다. ;-)

재정의되지 않은 \symb-루틴과 중괄호 안에 임의의 자료를 중첩 {하고 }선택적 인수를 형성하는 다른 매크로에 전달할 때의 내 의견도 확인하세요.

전체 "메커니즘"은 전혀 사용하지 않고 구현됩니다 \if..... \else... \fi. 따라서 메커니즘은 일치하지 않는 \if또는 \else또는 을 포함하는 매크로 인수로 인해 혼동되지 않습니다 \fi.

\documentclass{article}
\makeatletter
%%=============================================================================
%% Check whether argument is empty:
%%=============================================================================
%% \UD@CheckWhetherNull{<Argument which is to be checked>}%
%%                     {<Tokens to be delivered in case that argument
%%                       which is to be checked is empty>}%
%%                     {<Tokens to be delivered in case that argument
%%                       which is to be checked is not empty>}%
%%
%% Due to \romannumeral0-expansion the result is delivered after two
%% expansion-steps/after two "hits" by \expandafter.
%%
%% The gist of this macro comes from Robert R. Schneck's \ifempty-macro:
%% <https://groups.google.com/forum/#!original/comp.text.tex/kuOEIQIrElc/lUg37FmhA74J>
%%
\newcommand\UD@CheckWhetherNull[1]{%
  \romannumeral0\expandafter\@secondoftwo\string{\expandafter
  \@secondoftwo\expandafter{\expandafter{\string#1}\expandafter
  \@secondoftwo\string}\expandafter\@firstoftwo\expandafter{\expandafter
  \@secondoftwo\string}\@firstoftwo\expandafter{} \@secondoftwo}%
  {\@firstoftwo\expandafter{} \@firstoftwo}%
}%
%%=============================================================================
%% Check whether argument is blank (empty or only spaces):
%%=============================================================================
%% -- Take advantage of the fact that TeX discards space tokens when
%%    "fetching" _un_delimited arguments: --
%% \UD@CheckWhetherBlank{<Argument which is to be checked>}%
%%                      {<Tokens to be delivered in case that
%%                        argument which is to be checked is blank>}%
%%                      {<Tokens to be delivered in case that argument
%%                        which is to be checked is not blank}%
\newcommand\UD@CheckWhetherBlank[1]{%
  \romannumeral\expandafter\expandafter\expandafter\@secondoftwo
  \expandafter\UD@CheckWhetherNull\expandafter{\@firstoftwo#1{}.}%
}%
%%=============================================================================
%% Exchange two arguments. (From each argument an outermost level of 
%% surrounding braces will be removed if present.)
%%=============================================================================
\newcommand\UD@Exchange[2]{#2#1}%
%%=============================================================================
%% Check whether argument's leading tokens form a specific 
%% token-sequence that does not contain explicit character tokens of 
%% category code 1 or 2:
%%=============================================================================
%% \UD@CheckWhetherLeadingTokens{<argument which is to be checked>}%
%%                              {<a <token sequence> without explicit 
%%                                character tokens of category code
%%                                1 or 2>}%
%%                              {a <single non-space token> that does 
%%                                _not_ occur in <token sequence> >}%
%%                              {<internal token-check-macro>}%
%%                              {<tokens to be delivered in case
%%                                <argument which is to be checked> has
%%                                <token sequence> as leading tokens>}%
%%                              {<tokens to be delivered in case 
%%                                <argument which is to be checked>
%%                                does not have <token sequence> as
%%                                leading tokens>}%
\newcommand\UD@CheckWhetherLeadingTokens[4]{%
  \romannumeral0\UD@CheckWhetherNull{#1}%
  {\UD@Exchange{ }\expandafter\@secondoftwo}%
  {\expandafter\@secondoftwo\string{\expandafter
   \UD@@CheckWhetherLeadingTokens#4#3#1#2}{}}%
}%
\newcommand\UD@@CheckWhetherLeadingTokens[1]{%
  \expandafter\UD@CheckWhetherNull\expandafter{\@firstoftwo{}#1}%
  {\UD@Exchange{\@firstoftwo}}{\UD@Exchange{\@secondoftwo}}%
  {\UD@Exchange{ }{\expandafter\expandafter\expandafter\expandafter
   \expandafter\expandafter\expandafter}\expandafter\expandafter
   \expandafter}\expandafter\@secondoftwo\expandafter{\string}%
}%
%%=============================================================================
%% \UD@internaltokencheckdefiner{<internal token-check-macro>}%
%%                              {<token sequence>}%
%% Defines <internal token-check-macro> to snap everything 
%% until reaching <token sequence>-sequence and spit that out
%% nested in braces.
%%=============================================================================
\newcommand\UD@internaltokencheckdefiner[2]{%
  \@ifdefinable#1{\long\def#1##1#2{{##1}}}%
}%
%%=============================================================================
\UD@internaltokencheckdefiner{\UD@ExtractDescriptionEqual}{description=}%
\UD@internaltokencheckdefiner{\UD@ExtractDescriptionSpaceEqual}{description =}%
\UD@internaltokencheckdefiner{\UD@ExtractDescriptionEqualSpace}{description= }%
\UD@internaltokencheckdefiner{\UD@ExtractDescriptionSpaceEqualSpace}{description = }%
\UD@internaltokencheckdefiner{\UD@ExtractSpaceDescriptionEqual}{ description=}%
\UD@internaltokencheckdefiner{\UD@ExtractSpaceDescriptionSpaceEqual}{ description =}%
\UD@internaltokencheckdefiner{\UD@ExtractSpaceDescriptionEqualSpace}{ description= }%
\UD@internaltokencheckdefiner{\UD@ExtractSpaceDescriptionSpaceEqualSpace}{ description = }%
\UD@internaltokencheckdefiner{\UD@ExtractSpace}{ }%
%%=============================================================================
%% Trim all leading and trailing spaces:
%%=============================================================================
\newcommand\UD@RemoveSpaces[1]{%
   \romannumeral0\@firstofone{\UD@TrimTrailSpaceLoop{#1}.#1\UD@Bizarre} \UD@Bizarre\relax\UD@Bizarre
}%
\@ifdefinable\UD@TrimTrailSpaceLoop{%
  \long\def\UD@TrimTrailSpaceLoop#1#2 \UD@Bizarre#3\relax\UD@Bizarre{%
     \UD@CheckWhetherNull{#3}{%
       \UD@TrimLeadSpaceLoop{#1}%
     }{%
       \@firstofone{\expandafter\UD@TrimTrailSpaceLoop\expandafter{\@gobble#2}#2\UD@Bizarre} \UD@Bizarre\relax\UD@Bizarre
     }%
  }%
}%
\@ifdefinable\UD@gobblespace{%
  \@firstofone{\def\UD@gobblespace} {}%
}%
\newcommand\UD@TrimLeadSpaceLoop[1]{%
  \UD@CheckWhetherLeadingTokens{#1}{ }{.}{\UD@ExtractSpace}{\expandafter\UD@TrimLeadSpaceLoop\expandafter{\UD@gobblespace#1}}{ #1}%
}%
%%=============================================================================
%% Extract description:
%%=============================================================================    
\newcommand\UD@ExtractDescription[1]{%
  \romannumeral0%
  \UD@CheckWhetherLeadingTokens{#1}{ description = }{.}{\UD@ExtractSpaceDescriptionSpaceEqualSpace}{%
    \expandafter\UD@ExtractDescriptionCheckArgAmount\expandafter{\UD@ExtractSpaceDescriptionSpaceEqualSpace#1}%
  }{%
    \UD@CheckWhetherLeadingTokens{#1}{ description= }{.}{\UD@ExtractSpaceDescriptionEqualSpace}{%
      \expandafter\UD@ExtractDescriptionCheckArgAmount\expandafter{\UD@ExtractSpaceDescriptionEqualSpace#1}%
    }{%
      \UD@CheckWhetherLeadingTokens{#1}{ description =}{.}{\UD@ExtractSpaceDescriptionSpaceEqual}{%
        \expandafter\UD@ExtractDescriptionCheckArgAmount\expandafter{\UD@ExtractSpaceDescriptionSpaceEqual#1}%
      }{%
        \UD@CheckWhetherLeadingTokens{#1}{ description=}{.}{\UD@ExtractSpaceDescriptionEqual}{%
          \expandafter\UD@ExtractDescriptionCheckArgAmount\expandafter{\UD@ExtractSpaceDescriptionEqual#1}%
        }{%
          \UD@CheckWhetherLeadingTokens{#1}{description = }{.}{\UD@ExtractDescriptionSpaceEqualSpace}{%
            \expandafter\UD@ExtractDescriptionCheckArgAmount\expandafter{\UD@ExtractDescriptionSpaceEqualSpace#1}%
          }{%
            \UD@CheckWhetherLeadingTokens{#1}{description= }{.}{\UD@ExtractDescriptionEqualSpace}{%
              \expandafter\UD@ExtractDescriptionCheckArgAmount\expandafter{\UD@ExtractDescriptionEqualSpace#1}%
            }{%
              \UD@CheckWhetherLeadingTokens{#1}{description =}{.}{\UD@ExtractDescriptionSpaceEqual}{%
                \expandafter\UD@ExtractDescriptionCheckArgAmount\expandafter{\UD@ExtractDescriptionSpaceEqual#1}%
              }{%
                \UD@CheckWhetherLeadingTokens{#1}{description=}{.}{\UD@ExtractDescriptionEqual}{%
                  \expandafter\UD@ExtractDescriptionCheckArgAmount\expandafter{\UD@ExtractDescriptionEqual#1}%
                }{ #1}%
              }%
            }%
          }%
        }%
      }%
    }%
  }%
}%
\newcommand\UD@ExtractDescriptionCheckArgAmount[1]{%
  \expandafter\UD@CheckWhetherBlank\expandafter{\@gobble#1}{ }{%
    \expandafter\UD@CheckWhetherBlank\expandafter{\@gobbletwo#1}{%
       \UD@Exchange{ }{\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter}%
       \expandafter\UD@RemoveSpaces\expandafter{\@secondoftwo#1}%
    }{%
      \UD@Exchange{ }{\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter}%
      \expandafter\UD@RemoveSpaces\expandafter{\@firstoftwo{}#1}%
    }%
  }%
}%
%%=============================================================================
%% Your definition of \symb with a modification:
%% When passing arbitrary arguments as optional arguments, I strongly recommend 
%% nesting them in braces for ensuring that nesting of square brackets won't 
%% lead to problems:
%%=============================================================================
\newcommand{\symb}[3][]{%
  \glsxtrnewsymbol[{#1}]{#2}{#3}%  <- Here the content of #1 is arbitrary.
}%                              %     Problems due to nested square brackets
                                %     might occur in case #1 contains
                                %     [ or ]. 
                                %     Some day someone might do something like
                                %     \symb[{description=optional\macro[macro's optional]}]{...}{...}.
                                %     Therefore nest #1 in braces.
                                %     These braces will be removed by LaTeX 
                                %     when processing \glsxtrnewsymbol's 
                                %     optional argument.
                                %     They prevent confusion when it comes
                                %     to nesting optional arguments within
                                %     optional arguments.
%%=============================================================================
%% Redefinition of  \symb:
%%=============================================================================
\renewcommand{\symb}[3][]{%
  \romannumeral0%
  \expandafter\expandafter\expandafter\UD@Exchange
  \expandafter\expandafter\expandafter{%
  \expandafter\expandafter\expandafter{\UD@ExtractDescription{#1}}}{ \sym{#3}}%
  \glsxtrnewsymbol[{#1}]{#2}{#3}%
}%
%%=============================================================================
%% Dummy-definition for \glsxtrnewsymbol which displays the arguments verbatim
%%=============================================================================
\newcommand\glsxtrnewsymbol[3][]{%
  \par\noindent
  \texttt{\string\glsxtrnewsymbol}'s optional argument: $\langle$\texttt{\detokenize{#1}}$\rangle$
  \par\noindent
  \texttt{\string\glsxtrnewsymbol}'s mandatory argument 1: $\langle$\texttt{\detokenize{#2}}$\rangle$
  \par\noindent
  \texttt{\string\glsxtrnewsymbol}'s mandatory argument 2: $\langle$\texttt{\detokenize{#3}}$\rangle$
  \par
}%
%%=============================================================================
%% Dummy-definition for \sym which displaysthe arguments verbatim
%%=============================================================================
\newcommand\sym[2]{%
  \par\noindent
  \texttt{\string\sym}'s mandatory argument 1: $\langle$\texttt{\detokenize{#1}}$\rangle$
  \par\noindent
  \texttt{\string\sym}'s mandatory argument 2: $\langle$\texttt{\detokenize{#2}}$\rangle$
  \par
}%
\makeatother


\begin{document}
\vspace*{-1in}%
\noindent
\texttt{\detokenize{\symb[description={Set of Smooth Vector Fields}]{vfs}{\ensuremath{\mathfrak{X}}}}}:

\smallskip

\symb[description={Set of Smooth Vector Fields}]{vfs}{\ensuremath{\mathfrak{X}}}

\bigskip

\noindent\null\hrulefill\null

\bigskip

\noindent
\texttt{\detokenize{\symb[ description = { Set of Smooth Vector Fields } ]{vfs}{\ensuremath{\mathfrak{X}}}}}:

\smallskip

\symb[ description = { Set of Smooth Vector Fields } ]{vfs}{\ensuremath{\mathfrak{X}}}

\bigskip

\noindent\null\hrulefill\null

\bigskip

\noindent
\texttt{\detokenize{\symb[description = Set of Smooth Vector Fields ]{vfs}{\ensuremath{\mathfrak{X}}}}}:

\smallskip

\symb[description = Set of Smooth Vector Fields ]{vfs}{\ensuremath{\mathfrak{X}}}

\bigskip

\noindent\null\hrulefill\null

\bigskip

\noindent
\texttt{\detokenize{\symb{vfs}{\ensuremath{\mathfrak{X}}}}}:

\smallskip

\symb{vfs}{\ensuremath{\mathfrak{X}}}

\bigskip

\noindent\null\hrulefill\null

\bigskip

\noindent
\texttt{\detokenize{\symb[whatsoever]{vfs}{\ensuremath{\mathfrak{X}}}}}:

\smallskip

\symb[whatsoever]{vfs}{\ensuremath{\mathfrak{X}}}

\end{document}

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

답변2

이것은 그런 일을 하는 것입니다. 분명히 나는 ​​당신의 명령을 가지고 있지 않기 \sym때문에 그것이 올바른 주장을 가지고 있음을 보여주는 무언가를 사용합니다.

\documentclass{article}
\usepackage{amsfonts}
\def\forgetit{}
\newcommand{\symb}[3][]{%
\glsxtrnewsymbol[#1]{#2}{#3}%
}
\newcommand{\sym}[2]{first argument=\ensuremath{#1},second argument=#2}
\renewcommand{\symb}[3][\forgetit]{%
\def\mysplit##1=##2;{\def\mylast{##2}}%
\ifx#1\forgetit
\sym{#3}{empty}%
\else
\expandafter\mysplit#1;%
\sym{#3}{\mylast}%
\fi
}
\begin{document}
\symb[description={Set of Smooth Vector Fields}]{vfs}{\ensuremath{\mathfrak{X}}}

\symb{vfs}{\ensuremath{\mathfrak{X}}}
\end{document}

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

이는 첫 번째 인수가 비어 있지 않을 때마다 부호가 포함되어 있다고 가정합니다 =. 이에 대한 면역성을 갖도록 할 수 있지만, 그런 다음 몇 가지 키 관리 시스템을 사용하는 것이 좋습니다. 예를 들어 이미 로드 중이라면 pgf매우 간단합니다.

관련 정보