Lendo apenas uma certa parte do argumento de um novo comando

Lendo apenas uma certa parte do argumento de um novo comando

Estou usando o pacote glossaries-extra para minha lista de símbolos. Por alguma razão não relevante aqui eu defini um novo comando

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

de modo que minhas entradas no glossário estejam no formato:

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

Gostaria de "transferi-los" para o modelo de tese da minha universidade, onde eles não usam o pacote glossários, mas definem um ambiente onde os símbolos devem ser inseridos como:

\begin{symbols}

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

\end{symbols}

Este é simplesmente um ambiente de tabulação, ele imprime diretamente tudo o que você escreve nos argumentos do comando \sym. Então meu plano era definir algo como

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

Isso funciona, exceto que o uso do pacote glossários de alguma forma atrapalha outra parte do arquivo de estilo da universidade. Por isso gostaria de definir

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

No entanto, não quero ter "descrição={Conjunto de campos vetoriais suaves}" para o segundo argumento, quero ter "Conjunto de campos vetoriais suaves". Existe uma maneira de extrair apenas a parte "Conjunto de campos vetoriais suaves" do segundo argumento de \symb?

Solução: Uma versão simplificada da solução cat de @Schrödinger está funcionando para mim:

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

Responder1

Com o código a seguir, a rotina redefinida \symbatua da seguinte forma:

Os argumentos são passados ​​​​para \glsxtrnewsymbolintocados/como estão.

Os argumentos são passados \sym​​após extrair a descrição \symbdo argumento opcional da seguinte maneira:

Caso esse argumento não contenha a frase inicial "descrição=", ele é passado como está. (Tokens de espaço ao redor da frase inteira e/ou um token de espaço entre "descrição" e "=" são levados em consideração.)

Caso esse argumento contenha a frase inicial "descrição =", essa frase será removida.

  • Caso o restante consista apenas em tokens espaciais ou nada, o resultado da extração estará vazio/não consistirá em nenhum token.
  • Caso o restante consista em um único argumento não delimitado, ou seja, de um único token sem chaves ou de um conjunto de tokens aninhados entre colchetes, um nível de colchetes em torno de todo o restante será removido se estiver presente, então o espaço -tokens em torno de todo o restante serão removidos.
  • Caso o restante consista em algo diferente de apenas um único argumento não delimitado, nenhuma chave será removida, mas os espaços ao redor de todo o restante serão removidos.

Como \syme \glsxtrnewsymbolnão estão disponíveis para mim, forneci "definições fictícias" que nada fazem além de entregar seus argumentos de forma destokenizada, aninhadas entre colchetes angulares.

Fiz tudo isso de improviso, então não há garantias. ;-)

Observe também meu comentário sobre sua rotina não redefinida \symbe sobre aninhar material arbitrário entre chaves {e }ao passá-lo para outra macro onde forma um argumento opcional.

Todo o “mecanismo” é implementado sem usar nada \if......... Portanto, o mecanismo não será confundido por macro-argumentos que contenham unmatched or or .\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}

insira a descrição da imagem aqui

Responder2

Isso é algo que faz isso. Obviamente não tenho o seu \symcomando, então uso algo que mostra que acertou os argumentos.

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

insira a descrição da imagem aqui

Isto pressupõe que, sempre que o primeiro argumento não for vazio, ele contém um =sinal. Você pode torná-lo imune a isso, mas eu recomendaria usar algum sistema de gerenciamento de chaves. Por exemplo, se você já estiver carregando pgfserá muito simples.

informação relacionada