函数/宏/命令作为标签

函数/宏/命令作为标签

我想将函数实现为标签。目前,此代码可以正常工作:

在 equations_folder/equations.tex 中

\EQUATION{miqp-obj}
\begin{equation}
  \label{eq:miqp-obj}
  \min_{\mathbf{x}}C = \frac{1}{2} \mathbf{x}^{T}Q\mathbf{x}+\mathbf{c}^{T}\mathbf{x} 
\end{equation}
\ENDEQUATION
 
\bigskip % use this to make a space between equations

\EQUATION{miqp-cons}
\begin{equation}
  \label{eq:miqp-cons}
  A\mathbf{x} \preceq \mathbf{b},
\end{equation}
\ENDEQUATION

使用 format.cls

\newcommand{\inputeq}[2]{% #1 = file, #2 = eq name
    \long\def\EQUATION ##1#2 {}%
    \input{#1}
}
\let\ENDEQUATION\endinput

从我的 main.tex

    \inputeq{equations/equations}{{miqp-obj}}
    \inputeq{equations/equations}{{miqp-cons}}

问题是,miqp-obj打印了。我可以通过将上面的代码编辑为:\inputeq{equations/equations}{miqp-obj}和来修复它\EQUATION miqp-obj,但标签会丢失括号。有人能帮我修改代码吗.cls

我读了但不能满足我的需要。

__

补充:最初,我想实现bibtex-like一个功能,即我们可以从单个集中文件中引用我们的方程式。如果您能帮我解决这个问题,但又不回答主要问题,请随意回答。这是因为我想为我的研究小组制定一个标准的方程式命名,每个人都应该只引用这个文件或首先为其做出贡献。

__

编辑:遗憾的是,上述代码仅在我仅引用一个方程式时才有效。解决多重引用的方法是使用:

\EQUATION miqp-obj
\begin{equation}
  \label{eq:miqp-obj}
  \min_{\mathbf{x}}C = \frac{1}{2} \mathbf{x}^{T}Q\mathbf{x}+\mathbf{c}^{T}\mathbf{x} 
\end{equation}
\ENDEQUATION

问题是,\EQUATION成为一个具有任意多个输入的命令。

答案1

似乎你有一个⟨.tex-file⟩带有一系列东西的命令,你希望一个命令来传递那个东西,其中\EQUATION{⟨tag⟩}...\ENDEQUATION\inputeq{⟨.tex-file⟩}{⟨tag⟩}\EQUATION...\ENDEQUATION⟨标签⟩是匹配的。

换句话说:

  • s的星座⟨.tex-file⟩形成了一个方程式数据库。
  • \EQUATION{⟨tag⟩}...\ENDEQUATION-thingies 形成该数据库的条目。
  • ⟨tag⟩是该数据库条目的主键/唯一标识符。

只要你愿意遵守惯例

  • 对于\EQUATION...\ENDEQUATION-thingies ,在整个文档中所有命令使用的内容⟨tag⟩都只使用一次,不会重复使用,⟨.tex-file⟩\inputeq
  • a⟨.tex-file⟩ 仅包含嵌套在\EQUATION{⟨tag⟩}...\ENDEQUATION

,可以用一个“穷人的方法”\EQUATION来定义一个无界参数,后面跟着一个\ENDEQUATION有界参数。

在下面的例子中,我使用了一些技巧来从 -delimited 参数中删除前导空格标记\ENDEQUATION,并防止删除可能围绕整个\ENDEQUATION-delimited 参数的花括号。

以下示例提供了一个命令

\inputeq{⟨.tex-file⟩}{⟨tag⟩}

该命令的“无星号”变体旨在引入具有方程编号和交叉引用标签的方程,以便在使用 hyperref 包时通过\ref{...}/ /etc 进行交叉引用会产生指向文档中相应位置的超链接。\pageref{...}

“加星号”的变体不会产生交叉引用标签,而是用于重复/引用通过“不加星号”的变体引入的等式。\inputeq*{⟨.tex-file⟩}{⟨tag⟩}

仅当“无星号”变体与相同的变体一起使用时,才可使用“带星号”变体⟨.tex 文件⟩-参数和相同⟨标签⟩-argument 也应位于同一文档中。否则,您会得到未定义引用错误。

% Compile with LaTeX.
%
% Just to make sure you have an external .tex-file   equations.tex   which
% can be used as   <.tex-file>  when applying 
%   \inputeq{<.tex-file>}{<tag>}%
% let's create a file   equations.tex   in the current directory via the
% filecontents*-environment:

\begin{filecontents*}{equations.tex}
\EQUATION{miqp-obj}
  \min_{\mathbf{x}}C = \frac{1}{2} \mathbf{x}^{T}Q\mathbf{x}+\mathbf{c}^{T}\mathbf{x} 
\ENDEQUATION
% 
% !!!! Nothing processable by TeX outside \EQUATION..\ENDEQUATION  !!!!!
%
\EQUATION{miqp-cons}
  A\mathbf{x} \preceq \mathbf{b},
\ENDEQUATION
\end{filecontents*}

% Between \makeatletter..\makeatother let's define "mechanisms"
%  - \EQUATION{<tag>}...\ENDEQUATION
%  - \inputeq{<.tex-file>}{<tag>}
%
\makeatletter
\RequirePackage{refcount}%
%%=============================================================================
%% PARAPHERNALIA:
%% \UD@firstoftwo, \UD@secondoftwo, \UD@PassFirstToSecond, \UD@Exchange,
%% \UD@stopromannumeral, \UD@CheckWhetherNull,
%% \UD@CheckWhetherLeadingExplicitSpace,
%% \UD@Stringify, \UD@checkstringsubsetof,
%%=============================================================================
\newcommand\UD@firstoftwo[2]{#1}%
\newcommand\UD@secondoftwo[2]{#2}%
\newcommand\UD@Exchange[2]{#2#1}%
\@ifdefinable\UD@removespace{\UD@Exchange{ }{\def\UD@removespace}{}}%
\@ifdefinable\UD@stopromannumeral{\chardef\UD@stopromannumeral=`\^^00}%
%%-----------------------------------------------------------------------------
%% Check whether argument is empty:
%%.............................................................................
%% \UD@CheckWhetherNull{<Argument which is to be checked>}%
%%                     {<Tokens to be delivered in case that argument
%%                       which is to be checked is empty>}%
%%                     {<Tokens to be delivered in case that argument
%%                       which is to be checked is not empty>}%
%%
%% The gist of this macro comes from Robert R. Schneck's \ifempty-macro:
%% <https://groups.google.com/forum/#!original/comp.text.tex/kuOEIQIrElc/lUg37FmhA74J>
\newcommand\UD@CheckWhetherNull[1]{%
  \romannumeral\expandafter\UD@secondoftwo\string{\expandafter
  \UD@secondoftwo\expandafter{\expandafter{\string#1}\expandafter
  \UD@secondoftwo\string}\expandafter\UD@firstoftwo\expandafter{\expandafter
  \UD@secondoftwo\string}\expandafter\UD@stopromannumeral\UD@secondoftwo}{%
  \expandafter\UD@stopromannumeral\UD@firstoftwo}%
}%
%%-----------------------------------------------------------------------------
%% Check whether brace-balanced argument starts with a space-token
%%.............................................................................
%% \UD@CheckWhetherLeadingExplicitSpace{<Argument which is to be checked>}%
%%                                     {<Tokens to be delivered in case <argument
%%                                       which is to be checked> does have a
%%                                       leading explicit space-token>}%
%%                                     {<Tokens to be delivered in case <argument
%%                                       which is to be checked> does not have a
%%                                       a leading explicit space-token>}%
\newcommand\UD@CheckWhetherLeadingExplicitSpace[1]{%
  \romannumeral\UD@CheckWhetherNull{#1}%
  {\expandafter\UD@stopromannumeral\UD@secondoftwo}%
  {%
    % Let's nest things into \UD@firstoftwo{...}{} to make sure they are nested in braces
    % and thus do not disturb when the test is carried out within \halign/\valign:
    \expandafter\UD@firstoftwo\expandafter{%
      \expandafter\expandafter\expandafter\UD@stopromannumeral
      \romannumeral\expandafter\UD@secondoftwo
      \string{\UD@CheckWhetherLeadingExplicitSpaceB.#1 }{}%
    }{}%
  }%
}%
\@ifdefinable\UD@CheckWhetherLeadingExplicitSpaceB{%
  \long\def\UD@CheckWhetherLeadingExplicitSpaceB#1 {%
    \expandafter\UD@CheckWhetherNull\expandafter{\UD@firstoftwo{}#1}%
    {\UD@Exchange{\UD@firstoftwo}}{\UD@Exchange{\UD@secondoftwo}}%
    {\expandafter\expandafter\expandafter\UD@stopromannumeral
     \expandafter\expandafter\expandafter}%
     \expandafter\UD@secondoftwo\expandafter{\string}%
  }%
}%
%%-----------------------------------------------------------------------------
%% Remove all leading spaces:
\newcommand\UD@RemoveAllLeadingSpaces[1]{%
  \romannumeral\UD@RemoveAllLeadingSpacesLoop{#1}%
}%
\newcommand\UD@RemoveAllLeadingSpacesLoop[1]{%
  \UD@CheckWhetherLeadingExplicitSpace{#1}{%
    \expandafter\UD@RemoveAllLeadingSpacesLoop\expandafter{\UD@removespace#1}%
  }{\UD@stopromannumeral#1}%
}%
%%=============================================================================
%% \inputeq{<.tex-file>}{<tag>}
%%.............................................................................
\newcommand*\TAGPHRASE{}%
\newcommand*\CrossRefFork{}%
\newcommand\inputeq{%
  \@ifstar{\global\let\CrossRefFork\UD@secondoftwo\Innerinputeq}%
          {\global\let\CrossRefFork\UD@firstoftwo\Innerinputeq}%
}%
\newcommand\Innerinputeq[2]{%
  \xdef\TAGPHRASE{\unexpanded{#2}}%
  \input{#1}%
}%
%%=============================================================================
%% \EQUATION{<TAG>}...\ENDEQUATION
%%.............................................................................
\newcounter{equationduplicates}%
\def\theHequationduplicates{someduplicate.\number\value{equationduplicates}}%
\newcommand*\EQUATION[1]{%
  \InnerEQUATION{#1} %Prepend a space to ensure surrounding brases aren't stripped off.
}%
\@ifdefinable\InnerEQUATION{%
  \long\def\InnerEQUATION#1#2\ENDEQUATION{%
     \begingroup
     \edef\tempa{\unexpanded{#1}}%
     \expandafter\endgroup
     \ifx\tempa\TAGPHRASE\expandafter\UD@secondoftwo\else\expandafter\UD@firstoftwo\fi{}{%
       \begingroup
       \CrossRefFork{}{%
          \def\theequation{\getrefnumber{eq:#1}}%
          \refstepcounter{equationduplicates}%
          \let\theHequation\theHequationduplicates
       }%
       \begin{equation}\CrossRefFork{\label{eq:#1}}{}%
       \UD@RemoveAllLeadingSpacesLoop{#2}%
       \end{equation}%
       \CrossRefFork{}{\global\advance\c@equation by -1\relax}%
       \endgroup
     }%
  }%
}%
\makeatother

% Now let's create a nice document:

\documentclass{article}

\AtBeginDocument{%
  % Let's number equations within sections
  \def\theequation{\thesection.\arabic{equation}}%
  \csname @addtoreset\endcsname{equation}{section}%
}%

\usepackage{hyperref}

\begin{document}

\section{Referencing:}

\noindent Reference to equation \verb|miqp-obj|: \ref{eq:miqp-obj}

\noindent Reference to equation \verb|miqp-cons|: \ref{eq:miqp-cons}

\noindent\hrule\hfill

\section{Repeating:}

These are just repetitions not hyperlinked by cross-referencing-commands:

\inputeq*{equations.tex}{miqp-cons}

\inputeq*{equations.tex}{miqp-obj}

\noindent\hrule\hfill

\section{Originals:}

These are the "originals"/the targets for hyperlinks created by cross-referencing-commands:

\inputeq{equations.tex}{miqp-obj}

\inputeq{equations.tex}{miqp-cons}

\noindent\hrule\hfill

\section{Repeating again:}

These are just repetitions not hyperlinked by cross-referencing-commands:

\inputeq*{equations.tex}{miqp-obj}

\inputeq*{equations.tex}{miqp-cons}

\section{Another section}
\begin{equation}
x^2+y^2=z^2
\end{equation}

\end{document}

上面的例子创建了一个文本文件方程式.tex内容如下:

\EQUATION{miqp-obj}
  \min_{\mathbf{x}}C = \frac{1}{2} \mathbf{x}^{T}Q\mathbf{x}+\mathbf{c}^{T}\mathbf{x} 
\ENDEQUATION
% 
% !!!! Nothing processable by TeX outside \EQUATION..\ENDEQUATION  !!!!!
%
\EQUATION{miqp-cons}
  A\mathbf{x} \preceq \mathbf{b},
\ENDEQUATION

在上面的例子中,该文件被用作⟨.tex 文件⟩ 使用 -命令。\inputeq{⟨.tex-file⟩}{⟨tag⟩}

生成的.pdf 文件如下所示:

在此处输入图片描述

一些陷阱:

  • ⟨.tex 文件⟩包含“命名方程式”数据库条目的必须遵守以下约定:所有可由 TeX 处理的材料都嵌套在 之间。\EQUATION{⟨tag⟩}...\ENDEQUATION
  • 作为⟨标签⟩还用于创建交叉引用标签,没有两个\EQUATION(跨不同的 equation.tex 文件!)可以使用相同的⟨标签⟩
    换句话说: ⟨标签⟩是数据库的主键,由所有⟨.tex 文件⟩\inputeq通过您的文档中使用。
  • 如果许多人参与维护包含方程式数据库的 .tex 文件,其中一些人可能不太熟悉 TeX,确保上述“手工和眼睛”可能是一个问题。
    因此,我强烈建议通过专业的数据库管理系统(例如 MariaDB 或 MySQL)维护数据库,而不是为此目的使用“手动”维护的 .tex 文件。
  • 介于两者之间的内容将作为宏参数进行处理。因此,介于两者之间的内容您不能使用命令/环境,例如或,这些命令/环境依赖于临时更改 catcode-régime,并让内容在更改后的 catcode-régime 下从 .tex-input-file 中读取和标记。\EQUATION{⟨tag⟩}...\ENDEQUATION\EQUATION{⟨tag⟩}...\ENDEQUATION\verbverbatim
  • 嵌套可能不会按预期进行。\EQUATION{⟨tag⟩}...\ENDEQUATION
  • 我怀疑这个陷阱列表是否完整。;-)

答案2

您可以加载文件并填充属性列表:

\begin{filecontents*}{\jobname-equations}
\EQUATION{miqp-obj}{
  \min_{\mathbf{x}}C = \frac{1}{2} \mathbf{x}^{T}Q\mathbf{x}+\mathbf{c}^{T}\mathbf{x} 
}
 
\EQUATION{miqp-cons}{
  A\mathbf{x} \preceq \mathbf{b},
}
\end{filecontents*}

\documentclass{article}
\usepackage{amsmath}

\ExplSyntaxOn

\prop_new:N \g_yassirroni_equations_prop

\NewDocumentCommand{\EQUATION}{mm}
 {
  \prop_gput:Nnn \g_yassirroni_equations_prop { #1 }
   {
    \begin{equation}\label{eq:#1}#2\end{equation}
   }
 }

\NewDocumentCommand{\useequation}{m}
 {
  \prop_item:Nn \g_yassirroni_equations_prop { #1 }
 }

\ExplSyntaxOff

\input{\jobname-equations} % use your own file name

\begin{document}

Here we set the first equation
\useequation{miqp-obj}
and now also the second one
\useequation{miqp-cons}
Let's see whether references work: \eqref{eq:miqp-obj} and \eqref{eq:miqp-cons}.

\end{document}

这里我使用它filecontents*只是为了让示例独立起来。

在此处输入图片描述

然而,我怀疑这是否会简化工作流程。

相关内容