# Include MATLAB code listing compiled into HTML with correct colors

I am compiling a LaTeX file my_document.tex into an HTML page my_document.html using htlatex with the following command:

htlatex my_document.tex "xhtml,mathml-" " -cmozhtf"


I have a MATLAB code file main.m that I want to include in my_document.html with formatting that matches the MATLAB editor. When compiling with pdflatex, I use the following:

\documentclass{article}

\usepackage{listings}
\usepackage[numbered]{matlab-prettifier}

\lstset{
style=Matlab-editor
}

\begin{document}
\lstinputlisting{main.m}
\end{document}


Compiling the above code with htlatex, however, creates output that is black-and-white. Our current approach is to use m2tex to translate the .m file into a .tex file, but this makes the process of updating the HTML files more complicated because it adds a step, so I'm trying to find a way to simplify the process. I've included one approach as an answer, below, but am looking for other suggestions.

EDIT: Here is an example MATLAB file, main.m:

% This is a comment
var = "this is a string";

for i = 1:5
doThing(i)
end

disp this_is_some_text

function doThing(i)
fprintf('Number %d\n', i)
end


In the MATLAB code editor, main.m looks like the following screenshot, so the goal is to make the HTML output match this as well:

• Can you please add also the matlab code to your question? I cannot test it without that. Jan 29 at 12:06
• The particular choice of MATLAB code is not important, but I added an example that includes most of the important components of MATLAB code (comments, keywords, strings, etc.) Jan 30 at 9:28

Working with colors is a bit complicated with TeX4ht. Stuff like \textcolor works, but colors that are set by \color cannot be supported out of the box. You need to add some HTML tags with color information yourself.

For listings, we can use hooks provided by the package to insert some elements around each keyword. We can get the current color and insert CSS instructions.

Try this configuration file, config.cfg:

\Preamble{xhtml}
\makeatletter

% get current color in the CSS form
\extractcolorspec{.}\html@color%
\expandafter\convertcolorspec\html@color{HTML}\html@color%
\HCode{<span style="color:\#\html@color">}}% init

\begin{document}
\EndPreamble


In the OutputBox hook, we define the \html@color macro. It holds the current color suitable for CSS thanks to \extractcolorspec and \convertcolorspec commands. We insert it to the HTML output thanks to  \lst@AddToHook{PostOutput}{\HCode{</span>}} command. In the PostOutput hook, we insert the closing </span> tag.

Here is a MWE:

\documentclass{article}
\usepackage{xcolor}

\usepackage{listings}
\usepackage[numbered]{matlab-prettifier}

\lstset{
style=Matlab-editor
}

\begin{document}

Listings environment:

\begin{lstlisting}
function y = f(x)
% comment
y = x^2
disp('1hll')
[t, x] = ode45(@f, [0, 1], 0)
end
\end{lstlisting}

Included mathlab:

\lstinputlisting{main.m}
\end{document}


Compile using (don't use htlatex, it is deprecated):

make4ht -c config.cfg -m draft my_document.tex


This is the result:

One last thing. I've found a bug in the configuration file for the Color package, color.4ht. It prevents the correct conversion of colors. Here is the correct version:

% color.4ht (2022-02-01-17:18), generated from tex4ht-4ht.tex
% Copyright 1997-2009 Eitan M. Gurari
% Copyright 2009-2022 TeX Users Group
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either
% version 1.3c of this license or (at your option) any
% later version. The latest version of this license is in
%   http://www.latex-project.org/lppl.txt
% and version 1.3c or later is part of all distributions
% of LaTeX version 2005/12/01 or later.
%
% This work has the LPPL maintenance status "maintained".
%
% The Current Maintainer of this work
% is the TeX4ht Project <http://tug.org/tex4ht>.
%
% If you modify this program, changing the
% version identification would be appreciated.
\immediate\write-1{version 2022-02-01-17:18}

\expandafter\ifx \csname color:def\endcsname\relax
\let\color:def\def
\else  \expandafter\endinput\fi
\let\:temp\begingroup
\HLet\color@setgroup\:temp
\def\HColor{\:warning{\string\Hcode{...}{...} is deprecated; Use
\string\Configure{HColor}{...}{...}}\Configure{HColor}}
\NewConfigure{HColor}[2]{\if !#1!\if!#2!\let\HColor\relax \else \edef\HColor{#2}\fi
\else
\expandafter\edef\csname CLR:#1\endcsname{#2}\fi}
\def\:temp#1#2#3{%
\@ifundefined{color@#2}%
{\c@lor@error{model #2'}}%
{\@ifundefined{\string\color @#1}{}%
{\PackageInfo{color}{Redefining color #1}}%
\csname color@#2\expandafter\endcsname
\csname\string\color @#1\endcsname{#3}}}
\ifx \definecolor\:temp
\pend:defIII\definecolor{%
\expandafter\ifx\csname HColor:##2\endcsname\relax\else
\csname HColor:##2\endcsname ##3 //%
\edef\:temp{{HColor}{##1}{\HColor}}%
\expandafter\Configure\:temp
\fi}
\fi

\NewConfigure{color}{1}
\def\:tempc#1#2#3{\protect\leavevmode{\protect\a:textcolor
\color#1{#2}#3\protect\b:textcolor}}
\HLet\@textcolor=\:tempc
\NewConfigure{textcolor}{2}
\def\pagecolor{%
\begingroup \a:pagecolor
\let\ignorespaces\endgroup
\let\set@color\set@page@color
\color}
\NewConfigure{pagecolor}{1}
\def\:tempa[#1]#2{\a:color{#1 #2}\o:@undeclaredcolor:[#1]{#2}}
\HLet\@undeclaredcolor\:tempa
\pend:defI\@declaredcolor{\a:color{##1}}
\NewConfigure{SetHColor}[2]{{%
\expandafter\let\expandafter\:temp \csname CLR:#2\endcsname
\ifx \:temp\relax
\edef\:temp{#2 //}\expandafter\get:HColor\:temp
\ifx \HColor\relax
\expandafter\ifx \csname get!HColor\endcsname\relax \else
\edef\:temp{#2!//}\expandafter\csname get!HColor\expandafter\endcsname\:temp
\fi
%
\fi
\else             \let\HColor=\:temp \fi
\ifx \HColor\relax
\:warning{missing \string\Configure{HColor}{#2}{...}
(in LaTeX: \csname\string\color @#2\endcsname)}%
\expandafter\global\expandafter\let\csname CLR:#2\endcsname\empty
\else #1\fi }}
\def\get:HColor#1 #2//{%
\if\relax#2\relax
% \expandafter\ifx \csname HColor:#1\endcsname\relax
\let\HColor=\relax
\expandafter\ifx \csname\string\color @#1\endcsname \relax\else
\expandafter\ifx \csname colortyp:\endcsname\relax \else
\csname colortyp:\expandafter\expandafter\expandafter\endcsname
\csname\string\color @#1\expandafter\endcsname
\space . //%
\fi \fi
%
\else
\csname HColor:#1\endcsname #2 //%
\fi
}
\def\c:HColor:gray:{\def\HColor:gray##1 ##2//}
\Configure{HColor:gray}{\Configure{HColor}{}{}}
\def\c:HColor:rgb:{\def\HColor:rgb##1,##2,##3 ##4//}
\Configure{HColor:rgb}{\Configure{HColor}{}{}}
\def\c:HColor:cmyk:{\def\HColor:cmyk##1,##2,##3,##4 ##5//}
\Configure{HColor:cmyk}{\Configure{HColor}{}{}}

\long\def\:temp#1#2#3{%
\ifcolors@
\def\:temp{#1}\def\:tempa{\relax}\ifx\:temp\:tempa
\a:colorbox \else \a:fcolorbox \fi
\fi
{#1{\leavevmode #2{\set@color#3}}}%
\ifcolors@
\def\:temp{#1}\def\:tempa{\relax}\ifx\:temp\:tempa
\b:colorbox \else \b:fcolorbox \fi
\fi
}
\HLet\color@b@x\:temp
\NewConfigure{colorbox}{2}
\NewConfigure{fcolorbox}{2}

\Hinput{color}
\endinput

• Thanks for the detailed answer! How and where do I include the corrected version of color.4ht? Feb 3 at 4:52
• Never mind, I found it. It is located in C:\texlive\2021\texmf-dist\tex\generic\tex4ht on my system. Feb 3 at 6:33
• Have you submitted a bug report or pull request for the change to color.4ht so that the distributed version will have the fix? Feb 3 at 6:36
• There's one minor flaw in the HTML output. The text this_is_some_text should be purple since it is a string. Personally, I'm fine with it as-is because I tend to rewrite lines like disp this_is_some_text as disp('this_is_some_text'). Feb 3 at 6:40
• Similarly, the second line of "Included mathlab" should have purple text for "this is a string". Feb 3 at 7:18

When the following .tex file is compiled with htlatex, the code in the lstlisting environment is formatted pretty well, but the code that is imported with lstinputlisting is still black and white.

\documentclass{article}

\usepackage{color}
\usepackage{listings}
\usepackage[T1]{fontenc}
\usepackage[numbered]{matlab-prettifier} % Pretty print Matlab code

% Set the styles for different categories of code to arbitrary and distinct styles.
\lstset{
style=Matlab-editor,
basicstyle=\ttfamily,            % Appears as class=ectt-1000 in HTML
keywordstyle=\rmfamily\bfseries, % Appears as class=ecbx-1000 in HTML
commentstyle=\sffamily,          % Appears as class=ecss-1000 in HTML
stringstyle=\sffamily\slshape    % Appears as class=ecsi-1000 and tcsi-1000 in HTML
}

\begin{document}

% Set the font-family and color in the CSS based on the class associated with
% each span of text. The values "ectt-1000", etc., were found by inspecting
% the compiled HTML page in Google Chrome.
% Note: The \Css command only works when compiling with htlatex.
\Css{div.lstlisting .ectt-1000 {font-family: monospace;color:black}}   % Basic
\Css{div.lstlisting .ecss-1000 {font-family: monospace;color:green}}   % Comments
\Css{div.lstlisting .ecbx-1000 {font-family: monospace;color:blue}}    % Keywords
\Css{div.lstlisting .tcsi-1000 {font-family: monospace;color:purple}}  % String (delimiter)
\Css{div.lstlisting .ecsi-1000 {font-family: monospace;color:purple}}  % String (interior)

% Code in the lstlisting environment is rendered reasonable well.
\begin{lstlisting}
function y = f(x)
% comment
y = x^2
disp('1hll')
[t, x] = ode45(@f, [0, 1], 0)
end
\end{lstlisting}

% Code from lstinputlisting is still black and white.
\lstinputlisting{Matlab2tex_1_2/f.m}

\end{document}


This approach feels very hack-y and I don't understand the \Css` commands very well.