Seems you have a ⟨.tex-file⟩
with a sequence of \EQUATION{⟨tag⟩}...\ENDEQUATION
-thingies and you wish a command \inputeq{⟨.tex-file⟩}{⟨tag⟩}
to deliver that one \EQUATION...\ENDEQUATION
-thingie where ⟨tag⟩ is matching.
In other words:
- Constellations of
⟨.tex-file⟩
s form a database of equations.
\EQUATION{⟨tag⟩}...\ENDEQUATION
-thingies form entries of that database.
⟨tag⟩
is a primary-key/a unique identifier for an entry of that database.
As long as you are okay with obeying the conventions that
- with
\EQUATION...\ENDEQUATION
-thingies the same ⟨tag⟩
is used only once/is not used repeatedly across all ⟨.tex-file⟩
s used by \inputeq
-commands within the whole document,
- a
⟨.tex-file⟩
contains only material nested between \EQUATION{⟨tag⟩}...\ENDEQUATION
, a "poorman's approach" could be defining \EQUATION
in terms of an undelimited argument trailed by an \ENDEQUATION
-delimited argument.
In the following example I did some trickery for removing leading space-tokens from the \ENDEQUATION
-delimited argument and for preventing the removal of curly braces that might surround the entire \ENDEQUATION
-delimited argument.
The following example provides a command
\inputeq{⟨.tex-file⟩}{⟨tag⟩}
The "unstarred" variant of that command is intended to introduce an equation with equation-number and cross-referencing-label so that cross-referencing via \ref{...}
/\pageref{...}
/etc while using the hyperref-package yields a hyperlink to the corresponding place in the document.
The "starred" variant, i.e., \inputeq*{⟨.tex-file⟩}{⟨tag⟩}
does not produce a cross-referencing label and is intended for repeating/quoting an equation introduced via the "unstarred" variant.
The "starred" variant can only be used if the "unstarred" variant is used with the same ⟨.tex-file⟩-argument and the same ⟨tag⟩-argument in the same document, too. Otherwise you get undefined-reference-errors.
% 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}
The example above creates a text-file equations.tex with the following content:
\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
In the example above that file is used as ⟨.tex-file⟩ with
\inputeq{⟨.tex-file⟩}{⟨tag⟩}
-commands.
The resulting .pdf-file looks like this:

Some of the pitfalls:
- ⟨.tex-files⟩ containing database-entries for "named equations" must obey the convention that all material processable by TeX is nested between
\EQUATION{⟨tag⟩}...\ENDEQUATION
.
- As the ⟨tag⟩ also is used for creating the cross-referencing-label no two
\EQUATION
s (across different equation.tex-files!!!) may use the same ⟨tag⟩.
In other words: ⟨tag⟩ is to be a primary-key of the database that is formed by all ⟨.tex-files⟩ used via \inputeq
within your document.
- If many people are involved in maintaining the .tex-files containing equation-databases, some of these people probably not being all too familiar with TeX, ensuring the above "by hand and eyes" might be a problem.
Therefore I strongly recommend maintaining databases via professional database-management-systems, e.g., MariaDB or MySQL, instead of using "manually"-maintained .tex-files for this purpose.
- Things between
\EQUATION{⟨tag⟩}...\ENDEQUATION
are processed as macro-arguments. Therefore between \EQUATION{⟨tag⟩}...\ENDEQUATION
you can't use commands/environments like \verb
or verbatim
where it is relied on temporarily changing the catcode-régime and having things read and tokenized from .tex-input-file under that changed catcode-régime.
- Nesting
\EQUATION{⟨tag⟩}...\ENDEQUATION
might not turn out as intended.
- I doubt that this list of pitfalls is complete. ;-)
\EQUATION{<name of equation>}
. Why does that database contain things like\bigskip
outside "named" areas? How to handle the case of the same tag being used twice, e.g.\EQUATION{foobar}..\ENDEQUATION
occurring twice/several times within equations.tex, i.e., the tag not really being a primary key of the database?