为了我自己的需要,我正在编写一个包含一些环境定义的包。我还希望一些命令仅在这些环境中可用。所以我在环境定义中定义了这些命令。
我的 .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
一对在包内,对最终用户来说有点隐藏。“命名空间”或宏的概念@
在包中相当常见。