You can try the following version of color.4ht
:
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% color.4ht 2009-05-21-09:32 %
% Copyright (C) 1997--2009 Eitan M. Gurari %
% %
% 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".%
% %
% This Current Maintainer of this work %
% is Eitan M. Gurari. %
% %
% If you modify this program your changing its signature %
% with a directive of the following form will be %
% appreciated. %
% \message{signature} %
% %
% [email protected] %
% http://www.cse.ohio-state.edu/~gurari %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\immediate\write-1{version 2009-05-21-09:32}
\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\@undeclaredcolor[#1]#2{\a:color{#1 #2}%
\@ifundefined{color@#1}%
{\@latex@error{Undefined color model `#1'}\@ehd}%
{\csname color@#1\endcsname\current@color{#2}%
\set@color}%
\ignorespaces}
\pend:defI\@declaredcolor{\a:color{##1}}
\pend:defI\@declaredcolor{\ifdefined\end:def:color\end:def:color\else\aftergroup\b:textcolor\fi\a:textcolor\def\end:def:color{\b:textcolor}}
\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//{%
\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
I've added the following declaration:
\pend:defI\@declaredcolor{\ifdefined\end:def:color\end:def:color\else\aftergroup\b:textcolor\fi\a:textcolor\def\end:def:color{\b:textcolor}}
It prepends a code to the \@declaredcolor
command, which is used internally by \color
. What it does is a bit fragile in my opinion, which is the reason why it isn't used by default. The \end:def:color
command is executed if multiple \color
commands are used inside one TeX group. It inserts the closing tag for the previous \color
using \:textcolor
. The \a:textcolor
inserts opening tag and saves the current color to the CSS file. The last \color
command must be finished after the group is closed, using the \aftergroup
command.
See an example:
Why this is red \textcolor{red}{\cmark}
But not this one? {\color{red}\cmark\color{green}\xmark}
The generated HTML:
<!--l. 10--><p class="noindent" >Why this is red <span id="textcolor1"><span
class="pzdr-">✓</span></span>
</p><!--l. 12--><p class="indent" > But not this one? <span id="textcolor2"><span
class="pzdr-">✓</span></span><span id="textcolor3"><span
class="pzdr-">✗</span></span>
</p>
and CSS:
span#textcolor1{color:#FF0000}
span#textcolor2{color:#FF0000}
span#textcolor3{color:#00FF00}
And a picture:

This solution has one huge issue, the reason why it isn't used by default. This message is from tex4ht
sources, discussing this matter:
The \Verb!\color{red}! instruction might be problematic since it does not on its own determine the extent of the text to be colored. As
a result, its effect can cross logical boundaries. That is against the
philosophy of markup languages in general and of XML in particular.
It is possible to implement the \Verb!\color{...}! feature but I'm not sure it is desirable to do so. I think it is preferable to expect
users to use commands of the form \Verb!\textcolor{red}{...}! for code
fragments.
See this example:
\color{brown} Fist paragraph.
Second paragraph.
You would expect both paragraphs to be brown, but only first one will work correctly. The issue is that tag for color change will be inserted inside the first paragraph, but it will be implicitly closed at the paragraph end. The closing tag will be not inserted at all, as there is no group to be closed.