6

I have lots of LaTeX text duplication in my files, since the file has to compile with pdflatex and tex4ht and text4ht does not support all packages, So my files are littered with things like this all over the place

\ifdefined\HCode
  \begin{A}        
       same stuff
  \end{A}
\else
  \begin{B}
      same stuff
  \end{B}
\fi

Where the difference between the two cases in just the environment, where the stuff inside is the same. So I have to copy paste same stuff in two places and remember if I change it in one place, to change it in the other place.

I can't write the above as

\ifdefined\HCode
  \begin{A}        
\else
  \begin{B}
 \fi
       same stuff
\ifdefined\HCode
  \end{A}        
\else
  \end{B}
\fi

Since this will not compile in general. What I'd like to do, which seems to be impossible, is to define what is called a variable in normal programming languages and assign to the variable whatever latex text I want, telling Latex not to process it or look at it, but just hold to it as literal, and then replace the variable inside the environment, like this

\def\myVariable{  whatever I want goes here } %tell Latex not to look at it

Now I can write

\ifdefined\HCode
  \begin{A}        
       \myVariable
  \end{A}
\else
  \begin{B}
      \myVariable
  \end{B}
\fi

Now the code is not duplicated. But I do not know how to do the above.

This has to be done inside the document, not in preamble. So I can allocate the variable next to where it is used.

Here is a MWE

\documentclass[12pt]{book}% 
\usepackage{amsmath}
\usepackage{breqn}

\begin{document}    
\ifdefined\HCode
\begin{equation}
  3\frac{d^{2}y}{dt^{2}}+2\frac{dy}{dt}+y\left(  t\right) = u(t)
\end{equation}
\else
\begin{dmath*}
  3\frac{d^{2}y}{dt^{2}}+2\frac{dy}{dt}+y\left(  t\right) = u(t)
\end{dmath*}
\fi 
\end{document} 

I tried: \let and \def, these did not work. I tried \newcommand

\documentclass[12pt]{book}% 
\usepackage{amsmath}
\usepackage{breqn}
\begin{document}
\newcommand{\variable}{3\frac{d^{2}y}{dt^{2}}+2\frac{dy}{dt}+y\left(  t\right) = u(t)}
\ifdefined\HCode
\begin{equation}
  \variable
\end{equation}
\else
\begin{dmath*}
  \variable
\end{dmath*}
\fi 
\end{document} 

But it gave an error Undefined control sequence. \variable

ps. The above error was due to a typo. Please ignore. Typo corrected.

question is: How to change the above, so not to duplicate the code used in both places?

  • 1
    The unknown command sequence is rather \3 instead of \variable. – Heiko Oberdiek May 24 '16 at 4:32
  • I think you need another input format and three processors to get the three different ouotputs.Maybe pandoc can do all of them at once. – Johannes_B May 24 '16 at 6:27
  • Note that the tex error message would not have been Undefined control sequence. \variable it would have shown that \3 was undefined and \variable was the location of the error. If your editor is only showing you a mangled form of the error message then complain to its developers. – David Carlisle May 24 '16 at 8:29
  • @DavidCarlisle the error message was Undefined control sequence. \variable, that is why I did not notice that I had \3 there. Here is screen shot fyi, !Mathematica graphics may be then this is an issue with texstudio – Nasser May 24 '16 at 8:38
  • @Nasser No. As I say that is not the tex error message, that is your editor showing you the start of a message, and the end of the message, and omitting the important part that says which command is undefined. Look at tex's console output or log file. – David Carlisle May 24 '16 at 10:27
3

Not exactly as you suggested, but \newif is a simple solution. Your A and B environments replaced by exemplary theorem-like ones.

Edit: enlarged, according to suggestion from comment. The old picture left.

   \documentclass{article}

\usepackage{amsmath}

\begin{document}
\def\myVariable{  whatever I want goes here } %tell Latex not to look at it

Now I can write

\newif\ifHcode

\newtheorem{thm}{Theorem}
\newtheorem{lem}{Lemma}

%\ifdefined\HCode
\def\usemyVariable{
\ifHcode
  \begin{thm}        
       \myVariable
  \end{thm}
\else
  \begin{lem}
      \myVariable
  \end{lem}
\fi
}

\usemyVariable

\Hcodetrue

\usemyVariable

\def\myVariable{3\frac{d^{2}y}{dt^{2}}+2\frac{dy}{dt}+y\left( t\right) = u(t)}

\def\usemyVariable{
\ifHcode
\begin{equation}
  \myVariable
\end{equation}
\else
\begin{displaymath}
  \myVariable
\end{displaymath}
\fi 
}

\usemyVariable

\Hcodefalse

\usemyVariable



\end{document}

enter image description here

| improve this answer | |
6

Keep the tests out of your document body:

\documentclass[12pt]{book}% 
\usepackage{amsmath}

\ifdefined\HCode
\newenvironment{myequation}
{\begin{equation}}{\end{equation}\ignorespacesafterend}
\else
\usepackage{breqn}
\newenvironment{myequation}
{\begin{dmath*}}{\end{dmath*}\ignorespacesafterend}
\fi

\begin{document}    


\begin{myequation}
  3\frac{d^{2}y}{dt^{2}}+2\frac{dy}{dt}+y\left(  t\right) = u(t)
\end{myequation}

\end{document} 
| improve this answer | |
0

Annotation 1 -- about "variables" that get initialized somewhere within the document-environment's body but are used from the beginning of the document-environment's body:

Use the LaTeX2e-kernel's infrastructure for defining the \label..\ref- mechanism and define your own -- references will be resolved after the second LaTeX-run:

\documentclass[a4paper]{article}

\makeatletter
% !! In case you wish to use the hyperref-package, have the things
% !! between \makeatletter..\makeatother done _before_ loading the
% !! hyperref package.
\let\MySaved@setref=\@setref
\let\MySaved@newl@bel=\@newl@bel
\AtEndDocument{\let\MySaved@newl@bel=\@testdef}%
\newcommand\@currentphraselabel{}%
\newcommand\phraselabel[2]{%
  \@bsphack
  \protected@edef\@currentphraselabel{#2}%
  \protected@write\@auxout{}{\string\newphraselabel{#1}{\@currentphraselabel}}%
  \@esphack
}%
\newcommand*\newphraselabel{\MySaved@newl@bel{MyVar}}%
\DeclareRobustCommand\phraseref[1]{%
  \expandafter\MySaved@setref\csname MyVar@#1\endcsname\@firstofone{#1}%
}%
\makeatother

%\usepackage{hyperref}

\begin{document}

This is the value of myVariable: \phraseref{myVariable}.

This is when myVariable gets initialized.
\phraselabel{myVariable}{MyVariable's value}%

This is again the value of myVariable: \phraseref{myVariable}.

\end{document}

Annotation 2 -- about forking when using environments:

Define the environment to fork depending on HCode being defined:

\documentclass[a4paper]{article}

\makeatletter
\newcommand\AtIfDefindeHCode{%
  \ifdefined\HCode\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
}%
\newcommand\envA{This is start of env in case HCode defined.}
\@ifundefined{endenvA}%
             {\def\endenvA{This is end of env in case HCode defined.}}%
             {\newcommand\endenvA{}}% <- trigger the error-message
\newcommand\envB{This is start of env in case HCode undefined.}
\@ifundefined{endenvB}%
              {\def\endenvB{This is end of env in case HCode undefined.}}%
              {\newcommand\endenvB{}}% <- trigger the error-message
\newenvironment{AorB}%
              {\AtIfDefindeHCode{\envA}{\envB}}%
              {\AtIfDefindeHCode{\endenvA}{\endenvB}}%
\makeatother

\begin{document}

\def\HCode{defined}%
\begin{AorB}
Some text in AorB.
\end{AorB}

\let\HCode=\BIZarrEaNDThereFOreHOpeFullyUnDEFiNED
\begin{AorB}
Some text in AorB.
\end{AorB}

\end{document}

Ulrich Diez

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.