Como posso disponibilizar um comando dentro do argumento de outro comando?

Como posso disponibilizar um comando dentro do argumento de outro comando?

Quando defino um ambiente com \newenvironment, posso usar newcommanddentro da parte "before", para disponibilizar comandos para o código dentro do ambiente.

Isso é possível com comandos simples? Em outras palavras, posso fazer um comando tal que no argumento o usuário possa usar uma macro que não esteja definida externamente?

Exemplo: suponha que eu queira codificar um comando \setpara compor definições de conjuntos matemáticos e quero que um \suchthatcomando seja usado internamente, como em:

\set{x\in X \suchthat x > 42}

Isso é fácil, mas gostaria que o \suchthatcomando estivesse disponível apenas dentro de um argumento \set.

Responder1

Você pode definir um comando como

\newcommand\set[1]{%%
   \begingroup
     \def\suchthat{... some definition...}%%
     ... other macro content ....
    \endgroup}

E isso vai \suchthatdisponibilizar dentro da macro.

Você poderia ter feito isso com \bgroupe \egroup, mas isso cria uma subfórmula com consequências sobre como o espaçamento é tratado se usado no modo matemático. O \begingroupe \endgroupaqui localiza a definição de novas macros. Você pode usar qualquer um dos seguintes para definir um comando local, \def, \edefe \newcommand.

Seguindo a sugestão de @barbarabeeto você poderia fazer algo assim no seu preâmbulo:

\makeatletter
\def\ae@suchthat{... definition of such that ...}
\newcommand\aset[1]{%%
  \let\suchthat\ae@suchthat
    the body of the macro: #1
  \let\suchthat\undefined
}
\makeatother

Isto é muito melhor. Além dos motivos sugeridos por barbarabeeto, isso também permitiria que sua macro --- caso você desejasse --- defina ou defina valores que você pode querer acessar posteriormente no documento. Com esta \begingroup/\endgroupabordagem, estes teriam de ser globalizados, o que pode não ser o que desejaríamos.

Uma abordagem híbrida poderia parecer

\makeatletter
\def\ae@suchthat{... definition of such that ...}
\newcommand\aset[1]{%%
  \begingroup
    \let\suchthat\ae@suchthat
      the body of the macro: #1
  \endgroup
}
\makeatother

Responder2

A. As sugestões de Ellett são boas, mas existem algumas sutilezas relacionadas com esta abordagem.

  1. Localizar a definição com \bgroupe \egroupé ruim, porque a \setmacro é claramente usada no modo matemático. Tal construção constituiria uma subfórmula, com a consequência de que os espaços ficam congelados e não participam do estiramento e encolhimento da linha; usando \begingroupe \endgroupnão sofre deste problema.

  2. Uma definição padrão de \suchthatdeve ser fornecida de qualquer maneira, porque você pode querer \suchthatinserir um título de seção.

  3. Ambos os comandos devem ser robustos, pelo mesmo motivo.

Aqui está uma implementação.

\documentclass{article}
\usepackage{etoolbox}

\makeatletter
\newrobustcmd{\suchthat}{%
  \@latex@error{Use \noexpand\suchthat only in \string\set}
    {You are allowed to use \noexpand\suchthat only in the\MessageBreak
     argument of \string\set}%
}
\newcommand\giga@suchthat{\mid}
\newrobustcmd{\set}[1]{%
  \begingroup
  \let\suchthat\giga@suchthat
  \{\,#1\,\}%
  \endgroup
}
\makeatother

\begin{document}

\tableofcontents

\section{The set $\set{x\in X \suchthat x>42}$}

Let's study $\set{x\in X \suchthat x>42}$.

\suchthat

\end{document}

A saída no terminal:

! LaTeX Error: Use \suchthat only in \set.

See the LaTeX manual or LaTeX Companion for explanation.
Type  H <return>  for immediate help.
 ...                                              

l.27 \suchthat

? h
You are allowed to use \suchthat only in the
argument of \set

A saída

insira a descrição da imagem aqui

informação relacionada