如何在另一个环境中重用命令

如何在另一个环境中重用命令

为了我自己的需要,我正在编写一个包含一些环境定义的包。我还希望一些命令仅在这些环境中可用。所以我在环境定义中定义了这些命令。

我的 .sty 文件如下所示

\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{mypackage}[version 0.1]
\newenvironment{myenvirA}[1]
{
   \newcommand{\mycommandA}[1]
    { %
    %... do something
    }%
   % here, the "before" part of code 
}
{
   % here, the "after" part of code 
}


\newenvironment{myenvirB}[1]
{
   \newcommand{\mycommandB}[1]
    { %
    %.. do something
    }%
}
{
}

现在,假设我想在区块\mycommandA内部提供myenvirB。当然,我可以复制/粘贴,但这是糟糕的编程(容易出错)。

问题:Latex 是否提供了处理这种情况的方法?

如果不行,我可以把命令定义放在一个文件中吗\input?(这样我只需要定义一次)。一旦包安装在我的 Latex 树中,这会起作用吗?

抱歉,不清楚,如果这看起来是重复的,请指出其他问题。虽然找不到,但这个可能相关(?)。但我不清楚答案是否适用于我的问题。

编辑忘记了一些信息:命令必须能够访问环境参数。因此 Phelype Oleinik 给出的想法行不通(除非有什么我不知道的技巧?)。

这是一个 MVCE:

主要.tex:

\documentclass{article}
\usepackage{mypackage}
\begin{document}
\begin{envirA}{4}
\mycommandA{3}
\end{envirA}    
\begin{envirB}{4}
\mycommandB{3}
\end{envirB}  
\end{document}

我的包.sty:

\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{mypackage}[version 0.1]
\RequirePackage{tikz}

\newenvironment{envirA}[1]
{
    \newcommand{\mycommandA}[1]
    { 
        \draw (1,0) -- (##1,#1);
    }       
    \begin{tikzpicture}
    \draw (0,0) -- (#1,1);
}
{
    \end{tikzpicture}
}

\newenvironment{envirB}[1]
{
    \newcommand{\mycommandB}[1]
    { 
        \draw (0,1) -- (##1,#1);
    }       
    \begin{tikzpicture}
    \draw (0,0) -- (#1,1);
}
{
    \end{tikzpicture}
}
\endinput 

答案1

\mycommandA我猜测in的定义myenvirA(我不会使用数字,因为数字在命令名称中是非法的)取决于传递给环境的参数,否则问题很容易解决,只需\mycommandA直接定义即可。

\newcommand{\temporarycommandname}{} % initialize
\newenvironment{myenvirA}[1]
 {%
  \renewcommand{\temporarycommandname}[1]{something with #1 and ##1}%
  \global\let\mycommandA\temporarycommandname
  % whatever else
 }
 {%
  % the end part
 }

执行后, Now\mycommandA可在任何地方使用。当然,进一步调用会改变 的含义。\begin{myenvirA}myenvirA\mycommandA

如果您希望\mycommandA在第一次调用时仅定义一次,myenvirA并且不会被环境的后续调用所修改,请执行

\newcommand{\temporarycommandname}{} % initialize
\newenvironment{myenvirA}[1]
 {%
  \ifdefined\mycommandA\else
    \renewcommand{\temporarycommandname}[1]{something with #1 and ##1}%
    \global\let\mycommandA\temporarycommandname
  \fi
  % whatever else
 }
 {%
  % the end part
 }

答案2

您不能从定义宏的另一个环境中获取宏定义,因为该环境必然为该宏提供有限的范围(因为它是分组的)。

% \mycommand does not exist here
\begin{myenvironment}
  % _Local_ definition of \mycommand
  \newcommand{\mycommand}{<cmd definition>}
  % \mycommand exists here
  % ...
\end{myenvironment}
% \mycommand does not exist here

也许有办法做到这一点,但不值得付出努力。您应该将宏定义为全局可用,或者\input每次需要时通过外部文件读取它(如果正确安装在您的安装文件夹中)。后一种选择会减慢编译速度。

你必须问自己的问题是,为什么你希望定义仅在本地环境中可用。你想节省内存吗?几十年前,这会是一个问题,但现在不再是了。你认为它会提供一个更干净的包吗?如果是这样,最好通过在包的每个宏前面加上 来定义一个“命名空间” mypackage\@mypackage@这样你的宏将看起来像

\@mypackage@mycommandA
\@mypackage@mycommandB
...

宏中的符号@无需正式声明即可使用\makeatletter...\makeatother一对在包内,对最终用户来说有点隐藏。“命名空间”或宏的概念@在包中相当常见。

相关内容