No caso geral (enfiar alguma coisa no meio de um comando existente), isso é difícil. No entanto, a necessidade usual de adicionar algum código no início ou no final de um comando existente é conceitualmente bastante fácil. Suponha que se queira definir uma versão de um comando que faça uma pequena extensão de sua definição original: naturalmente, escreveríamos:
No entanto, isso não funcionaria: uma solicitação de\renewcommand{\splat}{\mumble\splat}
\splat
executaria
\mumble
e, em seguida, solicitaria novamente o \splat
; seria uma ‘repetição sem fim’ que, rapidamente, esgotaria a memória do TeX.
Felizmente, o comando primitivo \let
do TeX vem em nosso socorro; ele nos permite tirar um “retrato” do estado atual de um comando, o qual pode ser usado na redefinição do comando. Então:
faz a alteração necessária de forma segura. Adicionar coisas no final de um comando funciona de forma semelhante.\let\OldSmooth\smooth \renewcommand{\smooth}{\mumble\OldSmooth}
Se \smooth
aceitar argumentos, é preciso passá-los adiante:
\let\OldSmooth\smooth \renewcommand{\smooth}[2]{\mumble\OldSmooth{#1}{#2}}
A situação é ainda mais difícil se \smooth
puder receber um argumento opcional; a estrutura do comando é tão complexa que o simples comando \let
não vai reter os detalhes necessários. Neste caso, precisaremos do pacote letltxmacro, que conhece todos os tipos de comando do LaTeX e sabe como replicá-los. Suponha que tenhamos um comando definido como:
com um argumento opcional (substituído por\newcommand{\rough}[1][\default]{...}
\default
, se não estiver presente) e um argumento comum. Neste caso, nós o copiamos usando
e, depois, repetimos a técnica que tínhamos acima, com uma extensão:\LetLtxMacro{\NewRough}{\rough}
Aqui, vemos que (por razões entediantes de fazer corresponderem os argumentos) é necessário que o argumento opcional que está sendo passado seja colocado entre chaves.\renewcommand{\rough}[1][\newdef]% {\mumble\OldRough[{#1}]{#2}}
O caso geral pode ser alcançado de duas maneiras. Primeiro, pode-se usar o comando \CheckCommand
do
LaTeX , que compara um comando existente com a definição que você atribuiu a ele e emite um aviso se os dois não corresponderem. Portanto, a utilização é:
Esta técnica é obviamente um pouco trabalhosa, mas se o comando original vier de uma fonte que possa ser alterada sob o controle de outra pessoa, ela pelo menos te avisa que o seu “patch” corre o risco de dar errado.\CheckCommand{\complex}{
‹definição original›}
\renewcommand{\complex}{
‹nova definição›}
Alternativamente, os usuários do LaTeX podem usar um dos seguintes pacotes: patchcmd, ted ou etoolbox.
O pacote patchcmd lida com uma tarefa um pouco mais simples, restringindo o conjunto de comandos que você pode emendar; você não pode alterar nenhum comando que tenha um argumento opcional, embora ele lide com o caso de comandos definidos com \DeclareRobustCommand
. O pacote define um comando \patchcommand
que recebe três argumentos: o comando a ser alterado, coisas que vão entrar na frente de sua definição, e coisas para ficar no final de sua definição. Então, depois de
nós teremos uma nova versão de\def\b{b} \patchcmd\b{a}{c}
\b
definida como “abc”.
O pacote ted é um ‘editor de lista simbólico’ e fornece um comando \substitute
que emenda o conteúdo de uma macro e coloca o resultado em uma lista de token, ou (na forma \Substitute*
) usa o resultado para (re)definir uma macro. O exemplo a seguir define uma macro simples e, em seguida, altera sua definição:
Agora, a definição da macro é:\newcommand{\myfont}% {\Large\sffamily\selectfont} \Substitute*[\renewcommand{\myfont}]{\myfont}% {\Large\sffamily}{\huge\itshape}
\huge\itshape\selectfont
O pacote também oferece um comando \ShowTokens
, que mostra o conteúdo de seu argumento, um token por linha, com detalhes do código da categoria do token etc. Ele é recomendado como ferramenta de depuração.
O pacote etoolbox (que dá ao usuário acesso aos recursos de programação do e-TeX) fornece um comando \patchcmd
que é muito parecido com o \Substitute
, exceto pelo fato de que ele substitui uma única instância do(s) token(s) em seu padrão de pesquisa. Como nem todos os comandos podem ser emendados dessa maneira, o \patchcmd
recebe argumentos extras para casos de sucesso e fracasso. O pacote também fornece comandos que incluem algo no início (\pretocmd
) ou no final (\apptocmd
) da definição de um comando. Nem todos os comandos podem ser emendados dessa maneira; o pacote fornece um comando
\ifpatchable
que verifica os pré-requisitos e verifica se o corpo do comando de destino realmente inclui o ‘patch’ que você deseja usar. (O comando \ifpatchable*
não faz a verificação do ‘patch’.)
O pacote regexpatch trata de casos que são inacessíveis com o etoolbox; ele usa o pacote de expressão regular (pattern-matching) l3regex da distribuição LaTeX3 para encontrar o código que você precisa alterar. O pacote também “sabe” dos comandos robustos e do biblatex.
Finalmente, vamos falar brevemente sobre um pacote que é (praticamente) utilizável, mas não é muito recomendável. O Patch lhe dá um mecanismo engenhoso (e difícil de entender); ele vem como um arquivo de macro documentada à moda antiga do LaTeX, que não pode mais ser processado para produzir documentação formatada etc.. Felizmente, o arquivo (patch.doc) pode ser inserido diretamente, e a “documentação" pode ser encontrada fazendo a leitura da origem do pacote. Grosso modo, dá-se ao comando um conjunto de instruções análogas a substituições sed e regenera o comando assim emendado. A menos que você não possa fazer seu trabalho de outra maneira, o patch deve ser evitado.
This answer last edited: 2012-12-21
This question on the Web: http://latex.net.br/faq/FAQ-patch.html
Do you have any question? Ask on: latex.net.br - we love qood questions!