Make lstlisting work with tex4ht in table with fixed column width

column widthtablestex4ht

I am generating a table with fixed width with p specifications. In one column I need to put some text which is meant to be verbatim and can be few lines long so it will have to also automatically wrap in the column since it is p.

verbatim environment do not work. They do not wrap to fit column width. I tried also putting them in minipage of same width as the column. but still it did not wrap. So I gave up on using verbatim for this.

The only thing that worked well is to use listings. Now the text will wrap to fit column width and it is verbatim in some sense.

The only problem left to solve is to make this work with tex4ht.

It does not wrap in HTML and the whole listing content show on one line making the table very wide even for HTML. If I remove the listing environment, then it will wrap ofcourse, but then the text is no longer verbatim. it is an ordinary text, which will cause problems.

Even though I made sure I am using p and also using p-width option with make4ht.

How to make listing work in tex4ht the same as with PDF? The text has to be either vebratim or listing since its content can have characters which will cause trouble otherwise.

Here is a MWE.

\documentclass[12pt]{book}
\usepackage{longtable}
\usepackage{fancyvrb}
\usepackage{listings}
\lstset{
basicstyle=\footnotesize,
breaklines=true
}   
\begin{document}
\begin{tabular}[c]{|p{0.4in}|p{0.4in}|p{0.4in}|p{2.2in}|p{2.2in}|}\hline
1&66&203&-2 (exception)\newline
\begin{lstlisting}
Exception raised: RuntimeError >> ECL says: THROW: The catch RAT-ERR is undefined.
\end{lstlisting}
& 1 (pass) \\\hline
\end{tabular}    
\end{document}

This all works ok in pdf.

enter image description here

Compiled to HTML gives

   make4ht -a debug foo.tex "htm,p-width"

enter image description here

So it did not wrap.

I looked at other related questions and I see no solution to using listing like this inside table with tex4ht and keeping column width fixed.

tex4ht: How to create fixed width table columns

using mathml in htlatex makes it lose the table p-width specification in generated html

Any workaround?

Using TL 2021

Update

I tried the solution given, but for larger example it does not seem to wrap. I still get very wide columns in HTML. Here is another example to show.

\documentclass[11pt]{article} 
\usepackage{longtable}
\usepackage{listings}
\lstset{
basicstyle=\footnotesize,
breaklines=true
}        
\begin{document}
       
\begin{longtable}[c]{|p{0.4in}|p{0.4in}|p{0.4in}|p{2.2in}|p{2.2in}|}\hline
1&5&193&0 (not solved)& 1 (pass) \\ 
2&10&466&0 (not solved)& 1 (pass) \\ 
39&33&320&-2 (exception)\newline 
\begin{lstlisting}
Exception raised: TypeError >> An error occurred running a Giac command:INPUT:sage2:=int(sage0,sageVARx):;OUTPUT:Warning, integration of abs or sign assumes constant sign by intervals (correct if the argument is real):Check [abs(t_
\end{lstlisting}
& 1 (pass) \\ 
40&33&841&0 (not solved)& 1 (pass) \\ 
45&33&1954&-2 (exception)\newline 
\begin{lstlisting}
Exception raised: TypeError >> An error occurred running a Giac command:INPUT:sage2:=int(sage0,sageVARx):;OUTPUT:index.cc index_m i_lex_is_greater Error: Bad Argument Value
\end{lstlisting}
& 1 (pass) \\ \hline
\end{longtable}    
                       
\end{document}

Compiled using

 make4ht -a debug -c a.cfg foo.tex "htm,mathjax,p-width"

Where a.cfg is

\Preamble{xhtml}
\Css{table .lstlisting{ white-space: pre-wrap; }}
\begin{document}
\EndPreamble

gives using Brave browser the following

enter image description here

Which is the same as before. So pre-wrap; had no effect.

On FireFox browser it does a little better

enter image description here

And on Chrome browser it gives same as Brave. And on Edge browser also same as Brave. So FireFox browser did the best job. But in all cases it does not wrap as in PDF. I needed the columns to be same width and for the verbatim text to wrap. May be this is not possible?

Compare to the PDF

enter image description here

Update

Found a way to do this in HTML directly. So now just need to figure how to translate this into tex4ht .cfg. This is how to it in HTML.

<!DOCTYPE html> 
<html lang='en-US' xml:lang='en-US'> 
<head><title></title> 
<meta charset='utf-8' /> 
<style>
td { border: 1px solid #000; padding: 5px; max-width: 2.3in;  white-space: wrap; overflow: hidden;}

pre {
            overflow-x: auto;
            white-space: pre-wrap;
            white-space: -moz-pre-wrap;
            white-space: -pre-wrap;
            white-space: -o-pre-wrap;
            word-wrap: break-word;
         }
         
</style>
</head><body>
<table>
    <tr>
        <td> 1</td>
        <td> 5</td>        
        <td> 193</td>        
        <td> 0 (not solved)</td>    
        <td> 1 (pass)</td>     
    </tr>        
    <tr>
        <td> 1</td>
        <td> 5</td>        
        <td> 193</td>        
        <td> -2 (exception) <pre>Exception raised: TypeError >> An error occurred running a Giac command:INPUT:sage2:=int(sage0,sageVARx):;OUTPUT:Warning, integration of abs or sign assumes constant sign by intervals (correct if the argument is real):Check [abs(t_ </pre> </td>
        <td> 1 (pass)</td>         
     </tr> 
    <tr>
        <td> 1</td>
        <td> 5</td>        
        <td> 193</td>        
        <td> -2 (exception) <pre>Exception raised: TypeError >> An error occurred running a Giac command:INPUT:sage2:=int(sage0,sageVARx):;OUTPUT:Warning, integration of abs or sign assumes constant sign by intervals (correct if the argument is real):Check [abs(t_ </pre> </td>
        <td> -2 (exception) <pre>Exception raised: TypeError >> An error occurred running a Giac command:INPUT:sage2:=int(sage0,sageVARx):;OUTPUT:Warning, integration of abs or sign assumes constant sign by intervals (correct if the argument is real):Check [abs(t_ </pre> </td>
     </tr>      
</table>
</body> 
</html>

Which gives

enter image description here

Which is what I want. Fixed width table with verbatim wrapped also.

Update March 15, 2022

I found small problem with the solution given. When addition \caption it no longer works!

Here is MWE

\documentclass[12pt]{article}
\usepackage{longtable}
\usepackage{listings}
\lstset{
basicstyle=\footnotesize,
breaklines=true
}        

\begin{document}
       
\begin{longtable}[c]{|p{0.4in}|p{0.4in}|p{0.4in}|p{2.2in}|p{2.2in}|}\hline
\# &test file \#&integral \#&Giac 1.7.0 via sagemath 9.5&Giac 1.7.0 via sagemath 9.3 \\ \hline 
39&33&320&-2 (exception)
\begin{lstlisting}
Exception raised: TypeError >> An error occurred running a Giac command:INPUT:sage2:=int(sage0,sageVARx):;OUTPUT:Warning, integration of abs or sign assumes constant sign by intervals (correct if the argument is real):Check [abs(t_
\end{lstlisting}
& 1 (pass) \\ \hline
\end{longtable}    


\begin{longtable}[c]{|p{0.4in}|p{0.4in}|p{0.4in}|p{2.2in}|p{2.2in}|}\hline
\caption{Summary of regression test}\\
39&33&320&-2 (exception)
\begin{lstlisting}
Exception raised: TypeError >> An error occurred running a Giac command:INPUT:sage2:=int(sage0,sageVARx):;OUTPUT:Warning, integration of abs or sign assumes constant sign by intervals (correct if the argument is real):Check [abs(t_
\end{lstlisting}
& 1 (pass)\\ \hline
\end{longtable}    
                       
\end{document}

The above is compiled with

make4ht -a debug -c mycfg.cfg foo.tex "htm,mathjax,p-width"

Where mycfg.cfg is

\Preamble{xhtml}
\Css{table .lstlisting{
  white-space: pre-wrap;
  word-break: break-all;
}}

\makeatletter
% use normal space in listings
\def\lst@outputspace{\HCode{ }}
\Css{.lstlisting .label{margin-right:0em; }}
\makeatother

\begin{document}
\EndPreamble

Gives the HTML

enter image description here

The second table above lost the column width due to adding \caption
Is there a workaround this?

Update March 24, 2022

I found a small problem with the proposed solution. It adds an extra newline in the generated listing in the web page. This newline is not present in the input. This seems to be due to using white-space: pre-wrap; but this is need to force the wrapping for column width.

Can this wrapping to column width be done without introducing extra new lines? Here is MWE

\documentclass[12pt]{book}    
\usepackage{longtable}
\usepackage{listings}    
\lstset{
basicstyle=\ttfamily\small,
breaklines=true
}         
\begin{document}
\begin{tabular}[c]{|p{0.4in}|p{0.4in}|p{0.4in}|p{2.2in}|p{2.2in}|}\hline
1&66&203&-2 (exception)\newline
\begin{lstlisting}
Exception raised: RuntimeError >> ECL says: THROW: The catch RAT-ERR is undefined.
second line
  third line
\end{lstlisting}
& 1 (pass) \\\hline
\end{tabular}  
\end{document}

Compiled using

make4ht  -ulm default -a debug -c ./nma_mathjax.cfg foo2.tex "mathjax,htm"

Where nma_mathjax.cfg is exactly the one given in the answer below. Here it is again:

\Preamble{xhtml,p-width}

\Css{table .lstlisting{
  white-space: pre-wrap;
  word-break: break-all;
}}

\makeatletter
% use normal space in listings
\def\lst@outputspace{\HCode{ }}
\Css{.lstlisting .label{margin-right:0em; }}
\makeatother

\begin{document}
\EndPreamble

The HTML shows the lone lines do wrap correctly, but there are new lines added:

enter image description here

Best Answer

Edit:

here is a full config file with recent changes in Listings. They will be available only in TL 2022:

\Preamble{xhtml}

%%%%%%%%%%%%%%%%%%%%%%
%see https://tex.stackexchange.com/questions/637695/how-to-add-frame-and-background-color-with-listing-when-used-with-text4ht
%thanks to michal.h21

\makeatletter
\catcode`\:=11
\lst@AddToHook{Init}{%
\bgroup%
  % handle backround color and border in listings
  \ifx\lst@fillcolor\@empty\else%
    \lst@fillcolor%
    \extractcolorspec{.}\html@fillcolor%
    \expandafter\convertcolorspec\html@fillcolor{HTML}\html@fillcolor%
    \Css{\#listing-\listingN{background-color:\#\html@fillcolor;}}%
  \fi%
  \ifx\lst@rulecolor\@empty\else%
    \lst@rulecolor%
    \extractcolorspec{.}\html@rulecolor%
    \expandafter\convertcolorspec\html@rulecolor{HTML}\html@rulecolor%
    \Css{\#listing-\listingN{border: 1px solid \#\html@rulecolor;}}%
  \fi%
\egroup%
}

\ConfigureEnv{lstlisting}
   {\ifvmode \IgnorePar\fi \EndP
    \gHAdvance\listingN by 1
    \HCode{<!--l. \the\inputlineno-->}%
    \gdef\start:LstLn{%
       \HCode{<pre class="lstlisting" id="listing-\listingN">}%
       \gdef\start:LstLn{\HCode{\Hnewline}}}
    \bgroup%
    % we put the closing </div> here in order to support floating listings
    % https://tex.stackexchange.com/a/615703/2891
    \pend:def\lst@DeInit{\ifvmode\IgnorePar\fi\EndP\HCode{</pre>}}%
       \Configure{listings}
         {{\everypar{}\leavevmode}}
         {{\everypar{}\leavevmode}}
         {\start:LstLn \HCode{<span class="label">}}
         {\HCode{</span>}}%
   }
   {\egroup\par}
   {} {}
\Css{pre.lstlisting, pre.lstinputlisting{font-family: monospace,monospace; white-space: pre-wrap;
                    margin-top:0.5em; margin-bottom:0.5em;
                   }}


\Configure{lstinputlisting}
   {\ifvmode \IgnorePar\fi \EndP
    \HCode{<!--l. \the\inputlineno-->}%
    \gHAdvance\listingN by 1%
    \HCode{<pre class="lstinputlisting" id="listing-\listingN">}%
    \bgroup\ttfamily%\special{t4ht@(}%
       \Configure{listings}%
         {{\everypar{}\leavevmode}}%
         {{\everypar{}\leavevmode}}%
         {\HCode{\Hnewline<span class="label">}}%
         {\HCode{</span>}}%
   }
   {%\special{t4ht@)}
    \egroup%
    \ifvmode \IgnorePar\fi \EndP  \HCode{</pre>}\par}%
\Css{}
\makeatother
\catcode`\:=12
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%see https://tex.stackexchange.com/questions/634005/how-to-make-lstlisting-work-with-tex4ht-in-table-with-fixed-column-width
%to support listlisting in table so it wraps. added Feb 16, 2022

\Css{table .lstlisting{
  white-space: pre-wrap;
  word-break: break-all;
}}
\makeatletter
% use normal space in listings
\def\lst@outputspace{\HCode{ }}
\Css{.lstlisting .label{margin-right:0em; }}
\makeatother

\begin{document}
\EndPreamble

I've found that TeX4ht used non breaking spaces in listings, which prevented line breaking. You also need to declare some CSS to enable line breaking in listings:

\Preamble{xhtml}
\Css{table .lstlisting{
  white-space: pre-wrap;
  word-break: break-all;
}}

\makeatletter
% use normal space in listings
\def\lst@outputspace{\HCode{ }}
\Css{.lstlisting .label{margin-right:0em; }}
\makeatother

\begin{document}
\EndPreamble

enter image description here

Related Question