2

I'm trying to generate a LaTeX jinja template for a table split over multiple pages which will be populated with automatically generated LaTeX. To achieve this, I use the longtable environment, however, when a cell contains a word with too many characters, it is not correctly wrapped. Here is the relevant snippet of code for the table (with dummy content):

\def\arraystretch{1.2}

\begin{document}

\begin{longtable}{p{0.1\linewidth} p{0.2\linewidth} p{0.7\linewidth} } # & question & answer \ \arrayrulecolor{brand_dark} \hline \endhead

\rowcolor{brand_light} \multicolumn{3}{l}{tXRcRDxdKJOJHbSAAZeOCcoEPlpNzymLx} \ \rowcolor{white} LRenA & \begin{minipage}[t]{\linewidth} \begin{flushleft}KMtMfYwfHkGLLbaZFAfRtTFj\end{flushleft} \end{minipage} & \hspace{0pt} \begin{minipage}[t]{\dimexpr \linewidth - 0pt} \begin{flushleft} udrPJNdJGqOLzgGJjs \end{flushleft} \end{minipage}

\

\rowcolor{light-grey} ZCKhv & \begin{minipage}[t]{\linewidth} \begin{flushleft}hnjtmbuJPwyvBkbGjKJMEojGlUHREvvzwKwSSQeOEU\end{flushleft} \end{minipage} & \hspace{0pt} \begin{minipage}[t]{\dimexpr \linewidth - 0pt} \begin{flushleft} NmEwyZowJszdELsNktHfOvSaSNmIqIDHqabyKtNzuUgReEauJpiwjppdQWrHqorhMBgopxsROQEHPs \end{flushleft} \end{minipage}

\ \rowcolor{white} DPzyJ & \begin{minipage}[t]{\linewidth} \begin{flushleft}ikHnifxdnsPJNGEqvwTWjvHZ\end{flushleft} \end{minipage} & \hspace{0pt} \begin{minipage}[t]{\dimexpr \linewidth - 0pt} \begin{flushleft} BRiTGeOBvY \end{flushleft} \end{minipage}

\

\rowcolor{light-grey} LYYiI & \begin{minipage}[t]{\linewidth} \begin{flushleft}ALdgFWrSKqcNpBEeDvtnZX\end{flushleft} \end{minipage} & \hspace{0pt} \begin{minipage}[t]{\dimexpr \linewidth - 0pt} \begin{flushleft} UtyYPYhXSSmSUzgnO \end{flushleft} \end{minipage}

\ \rowcolor{white} plBsz & \begin{minipage}[t]{\linewidth} \begin{flushleft}VckBeukgwVihwVXtYbAPqgzd\end{flushleft} \end{minipage} & \hspace{0pt} \begin{minipage}[t]{\dimexpr \linewidth - 0pt} \begin{flushleft} VTEQmsYvTjinhubaqZDqVXSEdtmZVpwuYlLAIWGQbQmcRLnfhISiIdIpmhEEbGPMqoWCroWOHqJuMvCCEgtWqganBlBoJomZLvQQpSArshkAUXscRwLUyWbslXqMmEgUgdLvxnGnNcvMZgnRii \end{flushleft} \end{minipage}

\end{longtable}

\end{document}

The results in the following table:

longtable with incorrectly wrapped cells

Not that the content of the middle and right-most cells is encapsulated in a mini page as in general, it can contain newlines as well as arbitrarily nested itemize, enumerate, flushleft, flushright and center environments and uses of \emph, \textbf and \color.

What would be the best way of making this sort of text wrap correctly?

  • 2
    If it were actual words in the cells, there would also be proper line breaks. So, maybe what you are really looking for is just a way how to break long strings anywhere? – Jasper Habicht Apr 09 '21 at 16:27
  • 1
    Off-topic: Since you load xcolor with the option table, the instruction \usepackage{colortbl} is redundant. – Mico Apr 09 '21 at 16:39
  • @Mico Thank you, I've removed it :) – Julian Sutherland Apr 09 '21 at 21:51
  • @JasperHabicht Yes, most of the time these boxes will be filled with natural language, however, there can be long URLs, italicised and bolded text, as well as itemize and enumerate environments that do not seem to work with any of these solutions... – Julian Sutherland Apr 09 '21 at 22:14
  • 1
    you have posted a lot of code but almost none of it is related to your issue which is is that hnjtmbuJPwyvBkbGjKJMEojGlUHREvvzwKwSSQeOEU does not line break using English hyphenation patterns. You could have just posted a paragraph with these strings without any table or packages in the example which would have made it much easier for people to provide a focussed example. – David Carlisle Apr 10 '21 at 12:52
  • @DavidCarlisle Yes indeed, my apologies, I've edited the post, leaving only the relevant snippet I think. Thank you very much for pointing this out. – Julian Sutherland Apr 10 '21 at 23:00

2 Answers2

4

There are several issues with the longtable, beside the fact that the linebreaks aren't very good. For one, the overall width of the longtable is currently exceeds \textwidth by 6\tabcolsep, or about half an inch/more than a centimeter.

To force line breaks in long strings to occur at the end of each line (and, in the process, to suspend ordinary hyphenation rules which might otherwise kick in), I suggest you load the seqsplit package and employ its \seqsplit macro where needed.

The fact that the long strings may or may not occur inside minipage, center, flushright, etc environments does not imply that you couldn't use \seqsplit directives if and where needed.

enter image description here

\documentclass{article}

\usepackage[dvipsnames,table]{xcolor}

\usepackage{alltt} \usepackage{amssymb} \usepackage{array} %%%\usepackage{colortbl} % rendundant \usepackage{datetime} \usepackage{enumitem} \usepackage{everypage} \usepackage{fancyhdr}

\usepackage{fontspec} \setmainfont{Comfortaa-Bold}

\usepackage[landscape, margin=1in]{geometry} \usepackage{longtable} \usepackage{pdflscape} \usepackage{tikzpagenodes}

\usetikzlibrary{calc} \usetikzlibrary{positioning}

\definecolor{light-grey}{RGB}{243, 243, 243} \definecolor{brand_dark}{RGB}{28, 69, 135} \definecolor{brand_light}{RGB}{201, 218, 248}

\newcommand{\Company}{Company} \newcommand{\CompanyURL}{company.com} \newcommand{\Index}{QA}

\newcommand{\monthyear}{\ifcase \month \or January\or February\or March\or % April\or May \or June\or July\or August\or September\or October\or November\or % December\fi, \number \year}

% Turn on the style \pagestyle{fancy} % Clear the header and footer % \fancyhead{} \fancyfoot{} \renewcommand{\headrulewidth}{0pt} % Set the right side of the footer to be the page number \fancyfoot[R]{\color{brand_dark}Page \thepage} \fancyfoot[L]{\color{brand_dark}{\monthyear}}

\AddEverypageHook{\begin{tikzpicture}[remember picture,overlay] \fill[brand_dark] (current page.north west) rectangle ($ (current page header area.north -| current page.east) + (0,0.5) $); \node [above right = 0.5cm and -2cm of current page header area.north west] {\color{white} \Company ; | , \Index , 2021 }; \node [above left = 0.6cm and -2cm of current page header area.north east] {\color{white} \CompanyURL}; \end{tikzpicture}}

\def\arraystretch{1.2}

\usepackage{hyperref} \hypersetup{colorlinks=true, linkcolor=blue, filecolor=magenta, urlcolor=cyan}

% new: \usepackage{seqsplit} \newcolumntype{P}[1]{>{\raggedright\arraybackslash}p{\dimexpr#1\linewidth-2\tabcolsep}}

\begin{document}

\begin{longtable}{ P{0.1} P{0.2} P{0.7} }

# & question & answer \ \arrayrulecolor{brand_dark} \hline \endhead

\hline \endlastfoot

\rowcolor{brand_light} \multicolumn{3}{l}{tXRcRDxdKJOJHbSAAZeOCcoEPlpNzymLx} \[0.1ex]

\rowcolor{white} LRenA & \seqsplit{KMtMfYwfHkGLLbaZFAfRtTFj} & udrPJNdJGqOLzgGJjs \

\rowcolor{light-grey} ZCKhv & \seqsplit{hnjtmbuJPwyvBkbGjKJMEojGlUHREvvzwKwSSQeOEU} & \seqsplit{NmEwyZowJszdELsNktHfOvSaSNmIqIDHqabyKtNzuUgReEauJpiwjppdQWrHqorhMBgopxsROQEHPs} \

\rowcolor{white} DPzyJ & \seqsplit{ikHnifxdnsPJNGEqvwTWjvHZ} & BRiTGeOBvY \

\rowcolor{light-grey} LYYiI & \seqsplit{ALdgFWrSKqcNpBEeDvtnZX} & UtyYPYhXSSmSUzgnO \

\rowcolor{white} plBsz & \seqsplit{VckBeukgwVihwVXtYbAPqgzd} & \seqsplit{VTEQmsYvTjinhubaqZDqVXSEdtmZVpwuYlLAIWGQbQmcRLnfhISiIdIpmhEEbGPMqoWCroWOHqJuMvCCEgtWqganBlBoJomZLvQQpSArshkAUXscRwLUyWbslXqMmEgUgdLvxnGnNcvMZgnRii}

\end{longtable}

\end{document}

Mico
  • 506,678
  • "Second, the use of minipage environments seems unnecessary; " Unfortunately I don't think it is, this is intended as a template, with dummy information filling it, but the cells can, in general, contain itemize or enumerate environments, which of course contain line breaks. They can also contain bolded and italicized tests using the \textbf and \em macros, which also does not seem to render correctly when seqsplit is applied. – Julian Sutherland Apr 09 '21 at 21:50
  • 2
    @JulianSutherland - I think it would a good idea if you edited your query to provide more information about what exactly may end up in the cells. Incidentally, I'm still not convinced that one needs minipage wrappers to encase enumerate and itemize environments in p-type columns. Since your code loads the enumitem package, one can set up bespoke variants of itemize and enumerate environments that embed themselves transparently in minipage environments. Without more specific information about what may be in the cells, thoughit's not possibly to be more specific. – Mico Apr 10 '21 at 06:01
  • I've edited the post appropriately. I want to be able to nest enumerate and itemize environments arbitrarily, as well as top level newlines and use the macros \textbf, \emph and \color. Could you point me towards information on how to setup these bespoke variants of itemize and enumerate with the enumitem package? Thank you very much. – Julian Sutherland Apr 10 '21 at 23:02
  • I forgot I want to be able to nest flushleft, flushright and center environments to adjust the alignment of nested paragraphs. – Julian Sutherland Apr 10 '21 at 23:57
  • 1
    @JulianSutherland, than please show us, how you nest this environment so far, and whyt is in this environments. Also please make your document example minimal (from preamble remove all what is not related to problem with your table). So far your question is not entirely clear. – Zarko Apr 11 '21 at 02:03
  • 1
    @JulianSutherland - The best I can tell from your update, the fact that you may need long strings to line-break in arbitrary ways is merely one of several, possibly interrelated but so-far-not-entirely-clear formatting needs. That said, the presence of possibly nested minipage, enumerate, itemize, etc environments does not detract from the fact that \seqsplit should allow line breaks in long strings. I will update my answer accordingly. – Mico Apr 11 '21 at 02:38
  • @Mico Yes I agree, thank you very much, I've accepted your answer, algorithmically, it's a little annoying to have to wrap every word of sufficient length with \seqsplit, but it can be done! :)

    Also thank you very much for pointing me in the direction of eliminating minipages. It seems to be possible to do almost everything I want to do without them, and I think they were responsible for adding inappropriate spacing.

    – Julian Sutherland Apr 11 '21 at 23:19
0

As suplement to nice @Mico answer (+1). Just to show, that his solution enables to use lists in table. For formatting of lists is sensible to define new lists types adopted for use in (any) tables with prescribed columns widths (as you can find in many answers regarding lists in tables):

\documentclass{article}
\usepackage[landscape, margin=1in]{geometry}
\usepackage{pdflscape}

\usepackage{fontspec} %\setmainfont{Comfortaa-Bold}

\usepackage{alltt} \usepackage{amssymb} \usepackage[dvipsnames,table]{xcolor} \definecolor{light-grey}{RGB}{243, 243, 243} \definecolor{brand_dark}{RGB}{28, 69, 135} \definecolor{brand_light}{RGB}{201, 218, 248} \usepackage{array, longtable} \newcolumntype{P}[1]{>{\raggedright\arraybackslash}p{\dimexpr#1\linewidth-2\tabcolsep}} \renewcommand\arraystretch{1.2} \usepackage{enumitem} \newlist{tabenum}{enumerate}{1}% <-- defined new enumerate list \setlist[tabenum]{nosep, label=\textbf{\arabic.}, leftmargin=, before=\begin{minipage}[t]{\hsize}% \vspace{-0.6\baselineskip},% <--- after=\end{minipage}}

\newlist{tabitem}{itemize}{1}% &lt;-- defined new itemize list
\setlist[tabitem]{nosep,
                 leftmargin=*,
                 label=\textbullet,
                 before=\begin{minipage}[t]{\linewidth},    % &lt;---
                 after=\end{minipage}                       % &lt;---
                 }

\usepackage{datetime} \usepackage{everypage} \usepackage{fancyhdr}

\usepackage{pdflscape} \usepackage{tikzpagenodes} \usetikzlibrary{calc, positioning} % new: \usepackage{seqsplit}

\newcommand{\Company}{Company} \newcommand{\CompanyURL}{company.com} \newcommand{\Index}{QA}

\newcommand{\monthyear}{\ifcase \month \or January\or February\or March\or % April\or May \or June\or July\or August\or September\or October\or November\or % December\fi, \number \year}

% Turn on the style \pagestyle{fancy} % Clear the header and footer % \fancyhead{} \fancyfoot{} \renewcommand{\headrulewidth}{0pt} % Set the right side of the footer to be the page number \fancyfoot[R]{\color{brand_dark}Page \thepage} \fancyfoot[L]{\color{brand_dark}{\monthyear}} \AddEverypageHook{\begin{tikzpicture}[remember picture,overlay] \fill[brand_dark] (current page.north west) rectangle ($ (current page header area.north -| current page.east) + (0,0.5) $); \node [above right = 0.5cm and -2cm of current page header area.north west] {\color{white} \Company ; | , \Index , 2021 }; \node [above left = 0.6cm and -2cm of current page header area.north east] {\color{white} \CompanyURL}; \end{tikzpicture}}

\usepackage{hyperref} \hypersetup{colorlinks=true, linkcolor=blue, filecolor=magenta, urlcolor=cyan}

\begin{document} \begin{longtable}{ P{0.1} P{0.2} P{0.7} } # & question & answer \ \arrayrulecolor{brand_dark} \hline \endhead \hline \endlastfoot % table body \rowcolor{brand_light} \multicolumn{3}{l}{tXRcRDxdKJOJHbSAAZeOCcoEPlpNzymLx} \[0.1ex]

\rowcolor{white} LRenA & \seqsplit{KMtMfYwfHkGLLbaZFAfRtTFj} & udrPJNdJGqOLzgGJjs \

\rowcolor{light-grey} ZCKhv & \seqsplit{hnjtmbuJPwyvBkbGjKJMEojGlUHREvvzwKwSSQeOEU} & \seqsplit{NmEwyZowJszdELsNktHfOvSaSNmIqIDHqabyKtNzuUgReEauJpiwjppdQWrHqorhMBgopxsROQEHPs} \

\rowcolor{white} DPzyJ & \seqsplit{ikHnifxdnsPJNGEqvwTWjvHZ} & BRiTGeOBvY \

\rowcolor{light-grey} LYYiI & \seqsplit{ALdgFWrSKqcNpBEeDvtnZX} & UtyYPYhXSSmSUzgnO \

\rowcolor{white} plBsz & \seqsplit{VckBeukgwVihwVXtYbAPqgzd} & \seqsplit{VTEQmsYvTjinhubaqZDqVXSEdtmZVpwuYlLAIWGQbQmcRLnfhISiIdIpmhEEbGPMqoWCroWOHqJuMvCCEgtWqganBlBoJomZLvQQpSArshkAUXscRwLUyWbslXqMmEgUgdLvxnGnNcvMZgnRii}\

\rowcolor{light-grey} Item itemize & \begin{tabitem} \item \seqsplit{ALdgFWrSKqcNpBEeDvtnZX} \item \seqsplit{ikHnifxdnsPJNGEqvwTWjvHZ} \end{tabitem} & UtyYPYhXSSmSUzgnO \

\rowcolor{white} Item itemize + enumerate & some text before list \begin{tabitem} \item \seqsplit{ALdgFWrSKqcNpBEeDvtnZX} \item \seqsplit{ikHnifxdnsPJNGEqvwTWjvHZ} \end{tabitem} & \begin{tabenum} \item \seqsplit{VTEQmsYvTjinhubaqZDqVXSEdtmZVpwuYlLAIWGQbQmcRLnfhISiIdIpmhEEbGPMqoWCroWOHqJuMvCCEgtWqganBlBoJomZLvQQpSArshkAUXscRwLUyWbslXqMmEgUgdLvxnGnNcvMZgnRii} \item \seqsplit{ikHnifxdnsPJNGEqvwTWjvHZALdgFWrSKqcNpBEeDvtnZX} \end{tabenum}

\end{longtable}

\end{document}

enter image description here

Zarko
  • 296,517