
Quando defino um ambiente com \newenvironment
, posso usar newcommand
dentro 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 \set
para compor definições de conjuntos matemáticos e quero que um \suchthat
comando seja usado internamente, como em:
\set{x\in X \suchthat x > 42}
Isso é fácil, mas gostaria que o \suchthat
comando 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 \suchthat
disponibilizar dentro da macro.
Você poderia ter feito isso com \bgroup
e \egroup
, mas isso cria uma subfórmula com consequências sobre como o espaçamento é tratado se usado no modo matemático. O \begingroup
e \endgroup
aqui localiza a definição de novas macros. Você pode usar qualquer um dos seguintes para definir um comando local, \def
, \edef
e \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/\endgroup
abordagem, 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.
Localizar a definição com
\bgroup
e\egroup
é ruim, porque a\set
macro é 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\begingroup
e\endgroup
não sofre deste problema.Uma definição padrão de
\suchthat
deve ser fornecida de qualquer maneira, porque você pode querer\suchthat
inserir um título de seção.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