1

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

Nasser
  • 20,220

1 Answers1

1

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

michal.h21
  • 50,697
  • Thanks, this is better. But why is the columns width in HTML still not the same as in PDF? Since the 4th and 5th columns are supposed to be 2.2 inch wide each. I know in HTML itself, it is possible to have the widths fixed. – Nasser Feb 16 '22 at 15:49
  • @Nasser the witdths are set correctly, it is just that the browser decides where to break line. I don't think that this is something what can be fixed :/ – michal.h21 Feb 16 '22 at 17:47
  • Thanks. I posted another example now. This had no effect at all on a larger example. This is a problem. I know in HTML itself it is possible to have fixed width columns. I've seen plenty of examples. But the wrapping is a problem. Then I have to find another way to format this not using table which will be hard. – Nasser Feb 16 '22 at 17:53
  • You are right. I tried 4 browsers, and Firefox does best job. But sill columns are not same width. But I am sure this can be when using Direct coding in HTML? – Nasser Feb 16 '22 at 18:00
  • Fyi. Just posted an example of doing this directly in HTML. So it is possible to do it. Just need to figure how to translate this into ,.cfg so it works with tex4ht. If you have suggestions. I will also try few things to see. – Nasser Feb 16 '22 at 18:34
  • 1
    @Nasser I think that I've found the solution. – michal.h21 Feb 16 '22 at 21:24
  • Great job Michal. Thanks. This goes long way to improve how the tables now look like in HTML. Here is one I just build with your fix. example before this was very hard to read since it was very very wide. – Nasser Feb 16 '22 at 21:44
  • hi Michal. I found small problem. Your fix works fine with longtable. But when I added \caption it no longer works! Why is adding \caption makes it not work? I will now post a MWE at the bottom of my question so you can see. It seems \caption gets in the way somehow. – Nasser Mar 15 '22 at 23:08
  • hi Michal. I found a workaround :). So no need to waste your time on this caption issue. It is working ok now. Thanks. – Nasser Mar 16 '22 at 06:28
  • @Nasser and what workaround did you find? and what was the problem? – michal.h21 Mar 16 '22 at 08:30
  • hi Michal. I kept playing around with it. The problem is when the caption is inside the long table then your fix did not work. So I changed to the following: \begin{table}\caption{...}\begin{longtable} .... \end{longtable}\end{table} and now it works. I get the caption OK and your fix now still works. It seems only when the caption is inside the longtable (as in the example I show above) then it does not work for some reason. – Nasser Mar 16 '22 at 08:38
  • Hi Michal. I found new issue with the solution. Please see update. It add new empty line in the listing. The wrapping of long line is working OK. But side-effect of adding new line before the next line is not desired. I found it is due to white-space: pre-wrap; Is there a way to keep the wrapping of long lines, but not add a new empty line between? Thanks. – Nasser Mar 24 '22 at 15:54
  • @Nasser I hope that it will be fixed with the fix in the second question I've just updated – michal.h21 Mar 24 '22 at 16:47
  • With your new changes (I am using the update you made in the other answer) actually wrraping is gone and new lines are still there? Just in case we are on same page, Please see this folder I've put the foo2.tex file and the my.cfg files there so you could try for yourself and see. The command I used is make4ht -ulm default -a debug -c my.cfg foo2.tex "mathjax,htm" I do not understand why it would work on your system and not mine,. May be there is some other difference? I am using TL 2021. If you like me to try anything else please let me know. – Nasser Mar 24 '22 at 17:10
  • @Nasser see the update – michal.h21 Mar 25 '22 at 11:01
  • Thanks. But I am afraid it does not work :( I've put all the files I used in this folder and used the command make4ht -ulm default -a debug -c my.cfg foo2.tex "mathjax,htm" Now the \lstinputlisting{file} does not work any more. It puts the whole file in one line. Also the long lines in the table using \begin{lstlisting} do not wrap. Please let me know if you like me to try anything else. I am using TL 2021. How come it works on your end but not with me? We must have different setup? – Nasser Mar 25 '22 at 12:00
  • @Nasser I think it is just matter of CSS now. I've updated my answer with CSS for lstinputlisting – michal.h21 Mar 25 '22 at 12:09
  • OK, no problem. I have one version that works for everything except it does not wrap long lines inside a table compared to PDF. I can live with this one limitation for now. Thanks again for all your help. – Nasser Mar 25 '22 at 12:21