9
$\begingroup$

Background & Question

So if you're reading this you probably think Mathematica is pretty great - at least I do. The function Table by itself take someone pretty far and TableForm gives a clean presentation of the data. After processing my data I may want to write-up my finding. I prefer to write my documents in LaTeX, and Mathematica gives a great way to convert your work to LaTeX notation via TeXForm.

This is especially great when working with matrices or tables, because typing them by hand in LaTeX is pretty awful, especially if you may later find yourself editing them. But what if you want to get a bit fancy? For example, it is common that one may color coat values either by magnitude or direction (positive / negative); likewise, one may color-coat rows via groups.

Unfortunately, Mathematica does not automatically keep these color style options when TeXForm is invoked. Thus the crux of this question is:

QUESTION: How can I add color-styling to TeXForm output?


LaTeX Preliminaries

This is Mathematica StackExchange so a detailed discussion of LaTeX will be excluded. However, for bare-bone basics you will need at least the following two packages:

  • \usepackage{fontspec}
  • \usepackage{xcolor}

Specifying color of a font in a block can be done quite simply. For example, to add a vibrant blue:

{\addfontfeature{Color=0000FF99} Colored text goes here}

enter image description here


Approaches

Initially two approaches came to mind.

1.) Simply included the String of the desired LaTeX command when building the Table

2.) If TeXForm was a String use a combination of StringCases and Replace to replace the not styled LaTeX form with the styled version.


Example

A super simple Table

TableForm[{
{"one", Style["red", FontColor -> Red]}, 
{"two", Style["blue", FontColor -> Blue]}
}]

enter image description here

Get the TeXForm:

%//TeXForm

\begin{array}{cc}

\text{one} & \text{red} \

\text{two} & \text{blue} \

\end{array}

Unfortunately neither approach as described above work. For example, forego Style and just add the LaTeX command:

TableForm[{
  {"one", "{\addfontfeature{Color=FF0000}red}"},
  {"two", "{\addfontfeature{Color=0000FF}Blue}"}
  }]

Gives a warning about the unknown escape character \a so:

TableForm[{
  {"one", "{\\addfontfeature{Color=FF0000}red}"},
  {"two", "{\\addfontfeature{Color=0000FF}Blue}"}
  }]

No warning. But both give very bad LaTeX versions as Mathematica: obviously. Why? Because here we have to specify the LaTeX commands as a String, since characters like {,}, and \ have special meaning in Mathematica, especially when constructing lists. Therefore TeXForm takes our string thus converts it to be a string in LaTeX, which is not close to what we want e.g.

\begin{array}{cc}
 \text{one} & \text{$\{\backslash \backslash $addfontfeature$\{$Color=FF0000$\}$red$\}$} \\
 \text{two} & \text{$\{\backslash \backslash $addfontfeature$\{$Color=0000FF$\}$Blue$\}$} \\
\end{array}

Yuck.

TeXForm Documentation and Format

Mathematica's TeXForm documentation suggests that TeXForm can be modified via Format. Here is the only example provided.

bin[x, y] // TeXForm

\text{bin}(x,y)

Format[bin[x_, y_], TeXForm] := MatrixForm[{{x}, {y}}]
bin[x, y] // TeXForm

\left(

\begin{array}{c}

x \\

y

\end{array}

\right)

Thoughts?

$\endgroup$
7
$\begingroup$

Conversion to $\TeX$ uses various Style options:

Style["text", FontWeight -> "Bold", FontSlant -> "Italic"] // TeXForm
(* \pmb{\text{\textit{text}}} *)

but it seems that FontColor is not one of them:

Style["text", FontColor -> Red] // TeXForm
(* \text{text} *)

If we look at DownValues of System`Convert`TeXFormDump`maketex function, which is responsible for conversion, containing StyleBox:

Needs["GeneralUtilities`"]
Select[
    DownValues@System`Convert`TeXFormDump`maketex,
    !FreeQ[First@#, StyleBox] &
] // PrettyForm

we'll see that second definition from above list uses FontVariations, Underline, FontWeight and FontSlant option, but FontColor option is not used.


We can create a function taking Mathematica color specification and wrapping piece of $\TeX$ code with some $\TeX$ color changing commands, for example:

ClearAll[texColor]
texColor[color_RGBColor, texCode_String] := StringJoin[
    "{\\color[rgb]",
    ToString@Flatten[List @@ color][[;; 3]],
    " ",
    texCode,
    "}"
]

which gives:

texColor[Red, "some TeX"]
{\color[rgb]{1, 0, 0} some TeX}

texColor function can of course be adapted to arbitrary $\TeX$ color commands.

Now we can add a down-value to maketex, that will handle FontColor option of StyleBox and Cell expressions, using our texColor function:

ClearAll[texFormColorUsed]
texFormColorUsed[_] = False;
If[FreeQ[DownValues@System`Convert`TeXFormDump`maketex, Verbatim@#],
    PrependTo[DownValues@System`Convert`TeXFormDump`maketex, #]
]&[
    HoldPattern@System`Convert`TeXFormDump`maketex[
        box : (h : StyleBox | Cell)[__, opts : OptionsPattern[]] /;
            !TrueQ@texFormColorUsed[box]
    ] :>
        With[{color = OptionValue[h, FilterRules[{opts}, Options@h], FontColor]},
            Internal`InheritedBlock[{texFormColorUsed},
                texFormColorUsed[box] = True;
                texColor[color, System`Convert`TeXFormDump`MakeTeX@box]
            ] /; Head[color] === RGBColor
        ]
];

Now TeXForm gives:

Style[{"red1", Style["blue", FontColor -> Blue], "red2"}, FontColor -> Red] //
    TeXForm
{\color[rgb]{1, 0, 0} \{\text{red1},{\color[rgb]{0, 0, 1} \text{blue}},\text{red2}\}}

and for table from question:

{{"one", Style["red", FontColor -> Red]},
 {"two", Style["blue", FontColor -> Blue]}} // TableForm // TeXForm
\begin{array}{cc}
 \text{one} & {\color[rgb]{1, 0, 0} \text{red}} \\
 \text{two} & {\color[rgb]{0, 0, 1} \text{blue}} \\
\end{array}
$\endgroup$
  • 1
    $\begingroup$ The TeX converter is really due for an update ... $\endgroup$ – Szabolcs Sep 19 '16 at 12:53
  • 4
    $\begingroup$ @Szabolcs It sure is. Taking into account number of several years old bugs that are not fixed even if fixes are one-liners, I would call TeX conversion an unsupported feature. $\endgroup$ – jkuczm Sep 19 '16 at 12:59
  • $\begingroup$ @jkuczm I have a followup question. Your code above makes it clear how to sum \color with any other command. How can one swap the default for table? e.g. instead of an array, which is defaulted as a math environment, I may prefer ctable... $\endgroup$ – SumNeuron Sep 27 '16 at 3:15
  • $\begingroup$ @SumNeuron Take a look at TeXForm output in a tabular environment. In general, assumption that we're in $\TeX$ math mode is used extensively in TeXForm implementation, so anything other than post-processing of TeXForm of individual table elements, as done by TeXTableForm package, would be a lot of work. $\endgroup$ – jkuczm Sep 30 '16 at 9:18

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.