7

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?

5
  • 1
    The unknown command sequence is rather \3 instead of \variable. May 24, 2016 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, 2016 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. May 24, 2016 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, 2016 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. May 24, 2016 at 10:27

3 Answers 3

4

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

0
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} 
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

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .