7

My goal is to achieve colorings in the output document, that are similar to the syntax highlighting I use in my editor, so switching between the editing and viewing the document becomes easier on the eyes.

I figured I can use the color package to define some colors using \definecolor and then set the foreground and backgroundcolors using \color{fg} and \pagecolor{bg}, respectively.

What I'd like to do now, is assing certain colors to certain commands and environments. For simple commands like \emph I can do

\let\oldemph\emph
\renewcommand\emph[1]{{\color{emph}\oldemph{#1}}}

but I haven't figured out how to change the color of environments like align* and others.

Any help on how I could achieve this? Maybe theres even a generic way to do this, a package for semantic coloring like this would be cool.

EDIT: I managed to color environments using

\usepackage{etoolbox}
\AtBeginEnvironment{align*}{\color{equation}}
\AtBeginEnvironment{align}{\color{equation}}
\AtBeginEnvironment{equation*}{\color{equation}}
\AtBeginEnvironment{equation}{\color{equation}}

Inline-math can be colored using \everymath{\color{inlinemath}}, but this overrides the colors of the align* environment (not of the equation* environment though). How to fix this?

EDIT: If I'm correct, align*-environments switch between mathmode and non-mathmode to obtain the correct spacing. So if I use \everymath to set a color, it will be set inside align* environments, overriding what I did with \AtBeginEnvironment. For equation* it works, because there is only a single math block and \AtBeginEnvironment will put the color setting inside. The only way I can think of to fix this, would be somehow setting a color only for $...$, instead of using \everymath. Is this possible?

2
  • Does this helps? tex.stackexchange.com/q/96176/27635 Sep 25, 2013 at 18:40
  • @karlkoeller, the answer only explains how to color a single environment, not all of its kind. Anyway, etoolbox patches might be able to achieve what I'm looking for, though I never used that package before.
    – Christoph
    Sep 25, 2013 at 18:45

2 Answers 2

6

Update below: one way to deal with \intertext in this method.

Normally \everymath only regards inline, and there is \everydisplay for display math. But amsmath typesets things in a, hmm, complicated way. In particular using \everydisplay to add a \color command seems difficult (it works when amsmath is not loaded). Anyway, here is a work-around:

\documentclass{article}
\usepackage{amsmath}
\usepackage{color}
\usepackage{etoolbox}

\makeatletter
\AtBeginEnvironment{align*}{\let\SetColor\@gobble \color{display}}
\AtBeginEnvironment{align}{\let\SetColor\@gobble \color{display}}
\AtBeginEnvironment{equation*}{\let\SetColor\@gobble \color{display}}
\AtBeginEnvironment{equation}{\let\SetColor\@gobble \color{display}}
\makeatother

% maybe some other nice package has set-up things in \everymath!

\everymath\expandafter{\the\everymath\SetColor{inline}}

\definecolor{display}{rgb}{0,1,0}
\definecolor{inline}{rgb}{0,0,1}

\let\SetColor\color

\begin{document}

$xyz$

\begin{align*}
  E &= mc^2\\
  x^n+y^n&= z^n
\end{align*}

$$hello $$ %% for this we would need \everydisplay
%% but some interference with amsmath makes its use
%% a bit delicate.

\begin{equation}
  E = mc^2
\end{equation}

\end{document}

Output:

colored math

Update: adding to the code above in the preamble

\everydisplay\expandafter{\the\everydisplay\SetColor{display}}

will make the displayed hello also green. Note though that with amsmath this works only because its environments have been patched here to annihilate \SetColor. With amsmath, \everydisplay {\color{green}} causes an error. So here in align* the \SetColor does not do anything and it is the \color inserted at the begin of the environment which sets the color.


To deal with \intertext. One possibility.

\documentclass{article}
\usepackage{color}
\usepackage{amsmath}
\usepackage{etoolbox}

\makeatletter
\AtBeginEnvironment{align*}{\let\SetColor\@gobble \color{display}%
                            \Patchintertext}
\AtBeginEnvironment{align}{\let\SetColor\@gobble \color{display}\Patchintertext}
\AtBeginEnvironment{equation*}{\let\SetColor\@gobble \color{display}}
\AtBeginEnvironment{equation}{\let\SetColor\@gobble \color{display}}

\def\Patchintertext{\let\oldintertext@\intertext@
                    \def\intertext@{\oldintertext@\Patchintertext@}}
\def\Patchintertext@ {\let\oldintertext\intertext
                      \def\intertext ##1{\oldintertext
                      {\color{black}\let\SetColor\color ##1}}}
\makeatother


\everymath\expandafter{\the\everymath\SetColor{inline}}
\everydisplay\expandafter{\the\everydisplay\SetColor{display}}

\definecolor{display}{rgb}{.6,.6,.2}
\definecolor{inline}{rgb}{0,0,1}

\let\SetColor\color

\begin{document}

here is some text before with $xyz$ math inline,
\begin{align*}
  E &= mc^2\\
\intertext {this is some intertext with math $a^n+b^n=c^n$ inside,}
  x^n+y^n&= z^n\quad \text{(display)}
\end{align*}
and here is some more text after with again $A^B$ math inline.

$$this is some standard math display$$ 

\begin{equation}
  E = mc^2
\end{equation}

\end{document}

color certain B

3
  • This works great! There is only one problem left: \intertext inside an align* environment will be green and even $...$ inside the intertext will be green instead of blue.
    – Christoph
    Sep 25, 2013 at 22:31
  • patch intertext to work in a group (perhaps it does already, I don't know) and to reset there the color to black and \let\Setcolor\color to deal with the $..$ inside the intertext.
    – user4686
    Sep 28, 2013 at 7:19
  • I'm not sure how to do that, could you be a little more specific or provide a MWE?
    – Christoph
    Sep 29, 2013 at 18:02
4

Note that you're grouping the \color command to limit the scope. The same would be required for an environment. This translates to inserting the \color command inside the environment (possibly skipping any arguments passed to it (optional/mandatory). So yes, in general, this can be done, but it depends on the type of environment and/or it's structure.

For a generic environment that doesn't accept optional or mandatory arguments (this includes starred versions), you could just use

enter image description here

\documentclass{article}
\usepackage{etoolbox,xcolor}% http://ctan.org/pkg/{etoolbox,xcolor}
\newenvironment{myenv}
  {\itshape}
  {}
\begin{document}
Here is some text.

\begin{myenv}
Here is some more text.
\end{myenv}

Here is some text.

\appto{\myenv}{\color{red}}
\begin{myenv}
Here is some more text.
\end{myenv}

Here is some text.
\end{document}

The above appends code to the environment starting command (note that an environment myenv actually consists of the pair \myenv...\endmyenv). However, if your macro takes an optional command

\begin{myenv}[<something>]
  % <stuff>
\end{myenv}

then the above might work and might not... depending on how you've defined the conditioning on the optional argument. For example, the following does not work with the \appto approach from etoolbox:

\newenvironment{myenv}[1][\itshape]
  {#1}
  {}

Why? It all depends on how/when TeX reads an assesses the input.

enter image description here

\documentclass{article}
\usepackage{etoolbox,xcolor}% http://ctan.org/pkg/{etoolbox,xcolor}
\newenvironment{myenv}[1][\itshape]
  {#1}
  {}
\begin{document}
Here is some text.

\begin{myenv}
Here is some more text.
\end{myenv}

Here is some text.

\appto{\myenv}{\color{red}}
\begin{myenv}
Here is some more text.
\end{myenv}

Here is some text.

\begin{myenv}[\bfseries]
Here is some more text.
\end{myenv}

Here is some text.
\end{document}

As can be seen from the above example, [\bfseries] (the optional argument to myenv) is read as-is without even considering it an optional argument, since it prints [], in italics and bold (the second ]). The insertion via \appto interferes with the optional argument, so one has to insert it at a later point. For this one could use etoolbox's \AtBeginEnvironment, if needed, or create a pseudo-environment which wraps itself around the original one, passing the appropriate options/arguments and inserting the \color command at the appropriate location.

2
  • Using \AtBeginEnvironment pretty much solves this in an elegant way. But I still have a problem with the color I define with \everymath for $...$ being applied to align* as well, see my recent edit.
    – Christoph
    Sep 25, 2013 at 20:51
  • @ChristophPegel: Not exactly sure, but \everymath and author color may be relevant.
    – Werner
    Sep 25, 2013 at 21:18

You must log in to answer this question.

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