我想将函数实现为标签。目前,此代码可以正常工作:
在 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
\verb
verbatim
- 嵌套可能不会按预期进行。
\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*
只是为了让示例独立起来。
然而,我怀疑这是否会简化工作流程。