# tex4ht - make4ht: How to create fixed width table columns for odt and docx files

I'd like to find out whether tex4ht and make4ht can be customized to allow for very precise table construction in odt files, specifically, manually specified column widths (p{x dim}). This question is similar to but extends to odt/docx compilation:

Over my time with tex4ht implementations, I've had solutions come from:

The following MWE compiles fine with xelatex and make4ht, but fails to actually implement the parameter that I'd like to control (p{x dim}).

\documentclass{article}

\begin{document}

Test

\begin{tabular}{l p{1 cm} }
A1 & B1 \\
A2 & B2 \\
A3 & B3 \\
\end{tabular}

\begin{tabular}{ l p{3cm}}
\hline
Outer column & Detail column\\
\hline

a &
\begin{tabular}{c c }
A1 & B1 \\
A2 & B2 \\
A3 & B3 \\
\end{tabular}
\\
\hline
b
&
\begin{tabular}{c c }
A1 & B1 \\
A2 & B2 \\
A3 & B3 \\
\end{tabular}
\\
\hline
d & etc \\
\hline
\end{tabular}

\end{document}


I think the make4ht makefile has great potential, but when I unzip my successfully created word file I'm unable to track down the tables in xml that I'm hoping to control. My thinking was to write a lua function in the make file to replace the xml string defining the table, but this relied on table creation to be done in a single place, and the preservation of an annotation making the p width request that could be parsed out of a comment or something.

Any thoughts, suggestions, or starting points I might explore to add this control capability to odt/docx column widths?

• I was able to save the column width to the ODT file, but it doesn't seem to change the appearance in LO. – michal.h21 Jul 9 at 18:15

The following code saves the column styles with column widths:

\Preamble{xhtml}
\catcode\:=11
\Configure{tabular}
{\ifvmode \IgnorePar\fi \EndP \halignTB{tabular}%
\putVBorder
%
}
{\HCode{</table:table>}}
{\ifTag{vis-\TableNo-\HRow}%
{\special{t4ht@[}\gdef\end:box{\special{t4ht@]}}}%
{\global\let\end:box\empty}%
%
\HCode{<table:table-row \Hnewline
\ifTag{vis-\TableNo-\HRow}{table:visibility="collapse" }{}
%
table:style-name="TBL-\TableNo-\HRow-}%
\halignTR
\HCode{">}}
{\HCode{</table:table-row>}\end:box
%
}
{\HCode{<table:table-cell \Hnewline}%
\ifnum \HMultispan>1
\HCode{table:number-columns-spanned="\HMultispan"\Hnewline}%
\bgroup
\def\:temp{\ifnum \HMultispan>1
\HCode{<table:covered-table-cell/>}%
\expandafter\:temp
\fi}%
\egroup
\fi
%
\HCode{ table:style-name="TBL-\TableNo-\HRow-\HCol">}%
\edef\Aligh:Wrap{\halignTD}%
\if !\Aligh:Wrap!\let\not:Pcell=\:gobble
\save:table:width%
\else \let\not:Pcell\empty \fi
\not:Pcell{\HCode{<text:p
\Hnewline  text:style-name="}\cell:sty
\HCode{"
>}}%
\par  \ShowPar
%
\PushStack\Table:Stck\TableNo
}
{\IgnorePar \EndP
\PopStack\Table:Stck\TableNo
%
\csname not:Pcell\endcsname{\HCode{</text:p>}}%
\HCode{</table:table-cell>}}

\def\save:table:width{%
\edef\current:column{TBL-\TableNo -\ar:cnt}
\ifx\HColWidth\relax\else
\ifcsname used\current:column\endcsname\else
\typeout{width:\HColWidth, \current:column}
\expandafter\xdef\csname used\current:column\endcsname{yes}
\OOstyles{%
<style:style
style:name="\current:column"
style:family="table-column">
<style:table-column-properties style:column-width="\the\dimexpr\HColWidth\relax" />
</style:style>
}
\fi
\fi
}
\catcode\:=12
\begin{document}
\EndPreamble


The \Configure{tabular} part comes from the ooffice.4ht and contains configuration for tables. I've changed only the following lines, introducing the \save:table:width macro:

\if !\Aligh:Wrap!\let\not:Pcell=\:gobble
\save:table:width%
\else \let\not:Pcell\empty \fi


This macro is defined in the following way:

\def\save:table:width{%
\edef\current:column{TBL-\TableNo -\ar:cnt}
\ifx\HColWidth\relax\else
\ifcsname used\current:column\endcsname\else
\typeout{width:\HColWidth, \current:column}
\expandafter\xdef\csname used\current:column\endcsname{yes}
\OOstyles{%
<style:style
style:name="\current:column"
style:family="table-column">
<style:table-column-properties style:column-width="\the\dimexpr\HColWidth\relax" />
</style:style>
}
\fi
\fi
}


The \current:column macro contains the current column name, \HColWidth contains the width passed to the p column specification. The width is tested for existence, another check is made to prevent multiple insertion of the style definition, as \save:table:width is executed for each cell with fixed width. If it is executed for the first time, it inserts the width to document styles using the \OOstyles command. The \the\dimexpr\HColWidth\relax command is used to convert the original size specified in the document to points, as ODF doesn't support all units as TeX.

This is the code introduced in styles.xml file for the document:

 <style:style style:name="TBL-1-2" style:family="table-column"> <style:table-column-properties style:column-width="28.45274pt" /> </style:style>


It nevertheless doesn't make any difference in the rendered file in LO, so something is probably missing. The documentation for OpenDocument Format doesn't seem to be much helpful in this case, so if anybody knows what the issue is, I will be more than happy to fix it.

• During some debugging I noticed that it looks like the column width parameter in the styles.xml file are saved in hex format. Is there any reason that would make a difference? – EngBIRD Aug 31 at 3:06
• @EngBIRD I don't think this should happen, as it would need explicit conversion to the hex format. – michal.h21 Aug 31 at 13:57
• Sorry for the ambiguity in my comment. During the aforementioned debugging I was actually comparing two identical manually created files whose only difference was a different column width. Comparing the source xml resulted in the observation that only a hex number had changed between the two archives. Since these weren't tex based, I meant to ask whether this number saved to the file should perhaps be explicitly written as a hex number to get the program to use it. – EngBIRD Aug 31 at 17:57
• @EngBIRD ah, I understand it now. I think the value should be decimal, see datypic.com/sc/odf/a-style_column-width.html. – michal.h21 Aug 31 at 19:17