Skip to content

Commit d533e71

Browse files
working on adding complex table support (#402)
* working on adding complex table support Signed-off-by: Peter Staar <[email protected]> * refactored the code Signed-off-by: Peter Staar <[email protected]> * updated the latex gt Signed-off-by: Peter Staar <[email protected]> --------- Signed-off-by: Peter Staar <[email protected]>
1 parent ceba212 commit d533e71

File tree

8 files changed

+236
-89
lines changed

8 files changed

+236
-89
lines changed

docling_core/transforms/serializer/latex.py

Lines changed: 133 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,9 @@ class LaTeXParams(CommonParams):
9292
r"\usepackage{hyperref} % hyperlinks",
9393
r"\usepackage{url} % simple URL typesetting",
9494
r"\usepackage{booktabs} % professional-quality tables",
95+
r"\usepackage{array} % extended column defs",
96+
r"\usepackage{multirow} % multirow cells",
97+
r"\usepackage{makecell} % line breaks in cells",
9598
r"\usepackage{amsfonts} % blackboard math symbols",
9699
r"\usepackage{nicefrac} % compact symbols for 1/2, etc.",
97100
r"\usepackage{microtype} % microtypography",
@@ -291,57 +294,152 @@ def serialize(
291294
params = LaTeXParams(**kwargs)
292295
res_parts: list[SerializationResult] = []
293296

294-
# Build table body
295-
body_rows: list[list[str]] = []
297+
def _wrap_plain_cell_text(text: str) -> str:
298+
# For plain strings: escape, support explicit newlines using makecell
299+
if not text:
300+
return ""
301+
t = _escape_latex(text) if params.escape_latex else text
302+
if "\n" in t:
303+
lines = [ln.strip() for ln in t.splitlines()]
304+
return r"\makecell[l]{" + r"\\".join(lines) + "}"
305+
return t
306+
307+
def _wrap_rich_cell_content(content: str) -> str:
308+
# If content contains block environments, wrap in a minipage for safety
309+
block_markers = [
310+
r"\begin{itemize}",
311+
r"\begin{enumerate}",
312+
r"\begin{verbatim}",
313+
r"\begin{figure}",
314+
r"\section{",
315+
r"\subsection{",
316+
r"\subsubsection{",
317+
r"\begin{tabular}",
318+
]
319+
if any(m in content for m in block_markers) or "\n\n" in content:
320+
return (
321+
r"\begin{minipage}[t]{\linewidth}"
322+
+ "\n"
323+
+ content
324+
+ "\n"
325+
+ r"\end{minipage}"
326+
)
327+
# single-line or inline-safe rich content
328+
return content
329+
330+
# Build table body with span-aware rendering
331+
table_text = ""
296332
if item.self_ref not in doc_serializer.get_excluded_refs(**kwargs):
297333
if params.include_annotations:
298334
ann_res = doc_serializer.serialize_annotations(item=item, **kwargs)
299335
if ann_res.text:
300336
res_parts.append(ann_res)
301-
for row in item.data.grid:
302-
body_row: list[str] = []
303-
for cell in row:
304-
if isinstance(cell, RichTableCell):
305-
cell_text = doc_serializer.serialize(
306-
item=cell.ref.resolve(doc=doc), **kwargs
307-
).text
308-
else:
309-
cell_text = (
310-
_escape_latex(cell.text)
311-
if params.escape_latex
312-
else cell.text
337+
338+
grid = item.data.grid
339+
if grid:
340+
nrows = len(grid)
341+
ncols = max(len(r) for r in grid)
342+
343+
# booktabs-friendly, no vertical rules
344+
colspec = "".join(["l" for _ in range(ncols)])
345+
lines: list[str] = [f"\\begin{{tabular}}{{{colspec}}}", r"\toprule"]
346+
347+
# Detect header row to add midrule (any cell with column_header)
348+
header_row_idx: Optional[int] = None
349+
if any(c.column_header for c in grid[0]):
350+
header_row_idx = 0
351+
352+
for i in range(nrows):
353+
row_tokens: list[str] = []
354+
j = 0
355+
while j < ncols:
356+
cell = grid[i][j]
357+
# Skip over grid gaps
358+
if cell is None:
359+
j += 1
360+
continue
361+
362+
start_row = cell.start_row_offset_idx
363+
start_col = cell.start_col_offset_idx
364+
rowspan = getattr(
365+
cell,
366+
"row_span",
367+
max(1, cell.end_row_offset_idx - cell.start_row_offset_idx),
368+
)
369+
colspan = getattr(
370+
cell,
371+
"col_span",
372+
max(1, cell.end_col_offset_idx - cell.start_col_offset_idx),
313373
)
314-
body_row.append(cell_text.replace("\n", " "))
315-
body_rows.append(body_row)
316374

317-
# Convert to LaTeX tabular (without span support for now)
318-
table_text = ""
319-
if body_rows:
320-
ncols = max(len(r) for r in body_rows)
321-
colspec = "|" + "|".join(["l"] * ncols) + "|"
322-
lines = [f"\\begin{{tabular}}{{{colspec}}}", "\\hline"]
323-
# Use a distinct variable name to avoid shadowing the earlier
324-
# 'row' (which iterates over TableCell lists) and confusing type inference
325-
for str_row in body_rows:
326-
line = " & ".join(str_row) + r" \\ \hline"
327-
lines.append(line)
328-
lines.append("\\end{tabular}")
329-
table_text = "\n".join(lines)
375+
is_start = (start_row == i) and (start_col == j)
376+
377+
if is_start:
378+
# Render content
379+
if isinstance(cell, RichTableCell):
380+
content = doc_serializer.serialize(
381+
item=cell.ref.resolve(doc=doc), **kwargs
382+
).text
383+
content = _wrap_rich_cell_content(content)
384+
else:
385+
content = _wrap_plain_cell_text(cell.text)
386+
387+
token = content
388+
if rowspan > 1 and colspan > 1:
389+
token = rf"\multicolumn{{{colspan}}}{{l}}{{\multirow{{{rowspan}}}{{*}}{{{content}}}}}"
390+
elif colspan > 1:
391+
token = rf"\multicolumn{{{colspan}}}{{l}}{{{content}}}"
392+
elif rowspan > 1:
393+
token = rf"\multirow{{{rowspan}}}{{*}}{{{content}}}"
394+
395+
row_tokens.append(token)
396+
j += max(1, colspan)
397+
else:
398+
# Covered by a span from above or left
399+
# Only emit placeholders for continuation of multirow blocks starting at this column
400+
# so that column count remains correct.
401+
origin_row = start_row
402+
origin_col = start_col
403+
# Continuation of multirow coming from above at same column
404+
if (origin_col == j) and (origin_row < i) and (rowspan > 1):
405+
if colspan > 1:
406+
row_tokens.append(
407+
rf"\multicolumn{{{colspan}}}{{l}}{{}}"
408+
)
409+
j += colspan
410+
else:
411+
row_tokens.append("")
412+
j += 1
413+
else:
414+
# Covered by multicolumn from left in same row, skip silently
415+
j += 1
416+
417+
line = " & ".join(row_tokens) + r" \\" # end of row
418+
# Add header midrule after header row if applicable
419+
if header_row_idx is not None and i == header_row_idx:
420+
lines.append(line)
421+
lines.append(r"\midrule")
422+
else:
423+
lines.append(line)
424+
425+
lines.append(r"\bottomrule")
426+
lines.append("\\end{tabular}")
427+
table_text = "\n".join(lines)
330428

331429
cap_res = doc_serializer.serialize_captions(item=item, **kwargs)
332430
cap_text = cap_res.text
333431

334432
# Wrap in table environment when we have either content or caption
335433
if table_text or cap_text:
336-
content = []
337-
content.append("\\begin{table}[h]")
434+
env_lines: list[str] = []
435+
env_lines.append("\\begin{table}[h]")
338436
if cap_text:
339-
content.append(f"\\caption{{{cap_text}}}")
437+
env_lines.append(f"\\caption{{{cap_text}}}")
340438
if table_text:
341-
content.append(table_text)
342-
content.append("\\end{table}")
439+
env_lines.append(table_text)
440+
env_lines.append("\\end{table}")
343441
res_parts.append(
344-
create_ser_result(text="\n".join(content), span_source=item)
442+
create_ser_result(text="\n".join(env_lines), span_source=item)
345443
)
346444

347445
return create_ser_result(

test/data/doc/2408.09869v3_enriched.gt.tex

Lines changed: 53 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
\usepackage{hyperref} % hyperlinks
66
\usepackage{url} % simple URL typesetting
77
\usepackage{booktabs} % professional-quality tables
8+
\usepackage{array} % extended column defs
9+
\usepackage{multirow} % multirow cells
10+
\usepackage{makecell} % line breaks in cells
811
\usepackage{amsfonts} % blackboard math symbols
912
\usepackage{nicefrac} % compact symbols for 1/2, etc.
1013
\usepackage{microtype} % microtypography
@@ -128,12 +131,14 @@ \section{4 Performance}
128131

129132
\begin{table}[h]
130133
\caption{Table 1: Runtime characteristics of Docling with the standard model pipeline and settings, on our test dataset of 225 pages, on two different systems. OCR is disabled. We show the time-to-solution (TTS), computed throughput in pages per second, and the peak memory used (resident set size) for both the Docling-native PDF backend and for the pypdfium backend, using 4 and 16 threads.}
131-
\begin{tabular}{|l|l|l|l|l|l|l|l|}
132-
\hline
133-
CPU & Thread budget & native backend & native backend & native backend & pypdfium backend & pypdfium backend & pypdfium backend \\ \hline
134-
& & TTS & Pages/s & Mem & TTS & Pages/s & Mem \\ \hline
135-
Apple M3 Max & 4 & 177 s 167 s & 1.27 1.34 & 6.20 GB & 103 s 92 s & 2.18 2.45 & 2.56 GB \\ \hline
136-
(16 cores) Intel(R) Xeon E5-2690 & 16 4 16 & 375 s 244 s & 0.60 0.92 & 6.16 GB & 239 s 143 s & 0.94 1.57 & 2.42 GB \\ \hline
134+
\begin{tabular}{llllllll}
135+
\toprule
136+
CPU & Thread budget & \multicolumn{3}{l}{native backend} & \multicolumn{3}{l}{pypdfium backend} \\
137+
\midrule
138+
& & TTS & Pages/s & Mem & TTS & Pages/s & Mem \\
139+
Apple M3 Max & 4 & 177 s 167 s & 1.27 1.34 & 6.20 GB & 103 s 92 s & 2.18 2.45 & 2.56 GB \\
140+
(16 cores) Intel(R) Xeon E5-2690 & 16 4 16 & 375 s 244 s & 0.60 0.92 & 6.16 GB & 239 s 143 s & 0.94 1.57 & 2.42 GB \\
141+
\bottomrule
137142
\end{tabular}
138143
\end{table}
139144

@@ -276,10 +281,12 @@ \section{ACMReference Format:}
276281
Table 2: Prediction performance ([email protected]) of object detection networks on DocLayNet test set. The MRCNN (Mask R-CNN) and FRCNN (Faster R-CNN) models with ResNet-50 or ResNet-101 backbone were trained based on the network architectures from the detectron2 model zoo (Mask R-CNN R50, R101-FPN 3x, Faster R-CNN R101-FPN 3x), with default configurations. The YOLO implementation utilized was YOLOv5x6 [13]. All models were initialised using pre-trained weights from the COCO 2017 dataset.
277282

278283
\begin{table}[h]
279-
\begin{tabular}{|l|l|l|l|l|}
280-
\hline
281-
& human & MRCNN R50 R101 & FRCNN R101 & YOLO v5x6 \\ \hline
282-
Caption Footnote Formula List-item Page-footer Page-header Picture Section-header Table Text Title All & 84-89 83-91 83-85 87-88 93-94 85-89 69-71 83-84 77-81 84-86 & 68.4 71.5 70.9 60.1 63.4 81.2 80.8 61.6 59.3 71.9 70.0 71.7 72.7 67.6 69.3 82.2 82.9 85.8 76.7 80.4 72.4 73.5 & 70.1 73.7 63.5 81.0 58.9 72.0 72.0 68.4 82.2 85.4 79.9 73.4 & 77.7 77.2 66.2 86.2 61.1 67.9 74.6 86.3 88.1 82.7 76.8 \\ \hline
284+
\begin{tabular}{lllll}
285+
\toprule
286+
& human & MRCNN R50 R101 & FRCNN R101 & YOLO v5x6 \\
287+
\midrule
288+
Caption Footnote Formula List-item Page-footer Page-header Picture Section-header Table Text Title All & 84-89 83-91 83-85 87-88 93-94 85-89 69-71 83-84 77-81 84-86 & 68.4 71.5 70.9 60.1 63.4 81.2 80.8 61.6 59.3 71.9 70.0 71.7 72.7 67.6 69.3 82.2 82.9 85.8 76.7 80.4 72.4 73.5 & 70.1 73.7 63.5 81.0 58.9 72.0 72.0 68.4 82.2 85.4 79.9 73.4 & 77.7 77.2 66.2 86.2 61.1 67.9 74.6 86.3 88.1 82.7 76.8 \\
289+
\bottomrule
283290
\end{tabular}
284291
\end{table}
285292

@@ -356,22 +363,24 @@ \section{Baselines for Object Detection}
356363
\end{figure}
357364

358365
\begin{table}[h]
359-
\begin{tabular}{|l|l|l|l|l|l|l|l|l|l|l|l|}
360-
\hline
361-
class label & Count & \% of Total & \% of Total & \% of Total & triple inter-annotator mAP @ 0.5-0.95 (\%) & triple inter-annotator mAP @ 0.5-0.95 (\%) & triple inter-annotator mAP @ 0.5-0.95 (\%) & triple inter-annotator mAP @ 0.5-0.95 (\%) & triple inter-annotator mAP @ 0.5-0.95 (\%) & triple inter-annotator mAP @ 0.5-0.95 (\%) & triple inter-annotator mAP @ 0.5-0.95 (\%) \\ \hline
362-
class label & Count & Train & Test & Val & All & Fin & Man & Sci & Law & Pat & Ten \\ \hline
363-
Caption & 22524 & 2.04 & 1.77 & 2.32 & 84-89 & 40-61 & 86-92 & 94-99 & 95-99 & 69-78 & n/a \\ \hline
364-
Footnote & 6318 & 0.60 & 0.31 & 0.58 & 83-91 & n/a & 100 & 62-88 & 85-94 & n/a & 82-97 \\ \hline
365-
Formula & 25027 & 2.25 & 1.90 & 2.96 & 83-85 & n/a & n/a & 84-87 & 86-96 & n/a & n/a \\ \hline
366-
List-item & 185660 & 17.19 & 13.34 & 15.82 & 87-88 & 74-83 & 90-92 & 97-97 & 81-85 & 75-88 & 93-95 \\ \hline
367-
Page-footer & 70878 & 6.51 & 5.58 & 6.00 & 93-94 & 88-90 & 95-96 & 100 & 92-97 & 100 & 96-98 \\ \hline
368-
Page-header & 58022 & 5.10 & 6.70 & 5.06 & 85-89 & 66-76 & 90-94 & 98-100 & 91-92 & 97-99 & 81-86 \\ \hline
369-
Picture & 45976 & 4.21 & 2.78 & 5.31 & 69-71 & 56-59 & 82-86 & 69-82 & 80-95 & 66-71 & 59-76 \\ \hline
370-
Section-header & 142884 & 12.60 & 15.77 & 12.85 & 83-84 & 76-81 & 90-92 & 94-95 & 87-94 & 69-73 & 78-86 \\ \hline
371-
Table & 34733 & 3.20 & 2.27 & 3.60 & 77-81 & 75-80 & 83-86 & 98-99 & 58-80 & 79-84 & 70-85 \\ \hline
372-
Text & 510377 & 45.82 & 49.28 & 45.00 & 84-86 & 81-86 & 88-93 & 89-93 & 87-92 & 71-79 & 87-95 \\ \hline
373-
Title & 5071 & 0.47 & 0.30 & 0.50 & 60-72 & 24-63 & 50-63 & 94-100 & 82-96 & 68-79 & 24-56 \\ \hline
374-
Total & 1107470 & 941123 & 99816 & 66531 & 82-83 & 71-74 & 79-81 & 89-94 & 86-91 & 71-76 & 68-85 \\ \hline
366+
\begin{tabular}{llllllllllll}
367+
\toprule
368+
\multirow{2}{*}{class label} & \multirow{2}{*}{Count} & \multicolumn{3}{l}{\% of Total} & \multicolumn{7}{l}{triple inter-annotator mAP @ 0.5-0.95 (\%)} \\
369+
\midrule
370+
& & Train & Test & Val & All & Fin & Man & Sci & Law & Pat & Ten \\
371+
Caption & 22524 & 2.04 & 1.77 & 2.32 & 84-89 & 40-61 & 86-92 & 94-99 & 95-99 & 69-78 & n/a \\
372+
Footnote & 6318 & 0.60 & 0.31 & 0.58 & 83-91 & n/a & 100 & 62-88 & 85-94 & n/a & 82-97 \\
373+
Formula & 25027 & 2.25 & 1.90 & 2.96 & 83-85 & n/a & n/a & 84-87 & 86-96 & n/a & n/a \\
374+
List-item & 185660 & 17.19 & 13.34 & 15.82 & 87-88 & 74-83 & 90-92 & 97-97 & 81-85 & 75-88 & 93-95 \\
375+
Page-footer & 70878 & 6.51 & 5.58 & 6.00 & 93-94 & 88-90 & 95-96 & 100 & 92-97 & 100 & 96-98 \\
376+
Page-header & 58022 & 5.10 & 6.70 & 5.06 & 85-89 & 66-76 & 90-94 & 98-100 & 91-92 & 97-99 & 81-86 \\
377+
Picture & 45976 & 4.21 & 2.78 & 5.31 & 69-71 & 56-59 & 82-86 & 69-82 & 80-95 & 66-71 & 59-76 \\
378+
Section-header & 142884 & 12.60 & 15.77 & 12.85 & 83-84 & 76-81 & 90-92 & 94-95 & 87-94 & 69-73 & 78-86 \\
379+
Table & 34733 & 3.20 & 2.27 & 3.60 & 77-81 & 75-80 & 83-86 & 98-99 & 58-80 & 79-84 & 70-85 \\
380+
Text & 510377 & 45.82 & 49.28 & 45.00 & 84-86 & 81-86 & 88-93 & 89-93 & 87-92 & 71-79 & 87-95 \\
381+
Title & 5071 & 0.47 & 0.30 & 0.50 & 60-72 & 24-63 & 50-63 & 94-100 & 82-96 & 68-79 & 24-56 \\
382+
Total & 1107470 & 941123 & 99816 & 66531 & 82-83 & 71-74 & 79-81 & 89-94 & 86-91 & 71-76 & 68-85 \\
383+
\bottomrule
375384
\end{tabular}
376385
\end{table}
377386

@@ -392,22 +401,24 @@ \section{Baselines for Object Detection}
392401
\end{figure}
393402

394403
\begin{table}[h]
395-
\begin{tabular}{|l|l|l|l|l|l|l|l|l|l|l|l|}
396-
\hline
397-
& & \% of Total & \% of Total & \% of Total & triple inter- annotator mAP @ 0.5-0.95 (\%) & triple inter- annotator mAP @ 0.5-0.95 (\%) & triple inter- annotator mAP @ 0.5-0.95 (\%) & triple inter- annotator mAP @ 0.5-0.95 (\%) & triple inter- annotator mAP @ 0.5-0.95 (\%) & triple inter- annotator mAP @ 0.5-0.95 (\%) & triple inter- annotator mAP @ 0.5-0.95 (\%) \\ \hline
398-
class label & Count & Train & Test & Val & All & Fin & Man & Sci & Law & Pat & Ten \\ \hline
399-
Caption & 22524 & 2.04 & 1.77 & 2.32 & 84-89 & 40-61 & 86-92 & 94-99 & 95-99 & 69-78 & n/a \\ \hline
400-
Footnote & 6318 & 0.60 & 0.31 & 0.58 & 83-91 & n/a & 100 & 62-88 & 85-94 & n/a & 82-97 \\ \hline
401-
Formula & 25027 & 2.25 & 1.90 & 2.96 & 83-85 & n/a & n/a & 84-87 & 86-96 & n/a & n/a \\ \hline
402-
List-item & 185660 & 17.19 & 13.34 & 15.82 & 87-88 & 74-83 & 90-92 & 97-97 & 81-85 & 75-88 & 93-95 \\ \hline
403-
Page- footer & 70878 & 6.51 & 5.58 & 6.00 & 93-94 & 88-90 & 95-96 & 100 & 92-97 & 100 & 96-98 \\ \hline
404-
Page- header & 58022 & 5.10 & 6.70 & 5.06 & 85-89 & 66-76 & 90-94 & 98-100 & 91-92 & 97-99 & 81-86 \\ \hline
405-
Picture & 45976 & 4.21 & 2.78 & 5.31 & 69-71 & 56-59 & 82-86 & 69-82 & 80-95 & 66-71 & 59-76 \\ \hline
406-
Section- header & 142884 & 12.60 & 15.77 & 12.85 & 83-84 & 76-81 & 90-92 & 94-95 & 87-94 & 69-73 & 78-86 \\ \hline
407-
Table & 34733 & 3.20 & 2.27 & 3.60 & 77-81 & 75-80 & 83-86 & 98-99 & 58-80 & 79-84 & 70-85 \\ \hline
408-
Text & 510377 & 45.82 & 49.28 & 45.00 & 84-86 & 81-86 & 88-93 & 89-93 & 87-92 & 71-79 & 87-95 \\ \hline
409-
Title & 5071 & 0.47 & 0.30 & 0.50 & 60-72 & 24-63 & 50-63 & 94-100 & 82-96 & 68-79 & 24-56 \\ \hline
410-
Total & 1107470 & 941123 & 99816 & 66531 & 82-83 & 71-74 & 79-81 & 89-94 & 86-91 & 71-76 & 68-85 \\ \hline
404+
\begin{tabular}{llllllllllll}
405+
\toprule
406+
& & \% of Total & \% of Total & \% of Total & triple inter- annotator mAP @ 0.5-0.95 (\%) & triple inter- annotator mAP @ 0.5-0.95 (\%) & triple inter- annotator mAP @ 0.5-0.95 (\%) & triple inter- annotator mAP @ 0.5-0.95 (\%) & triple inter- annotator mAP @ 0.5-0.95 (\%) & triple inter- annotator mAP @ 0.5-0.95 (\%) & triple inter- annotator mAP @ 0.5-0.95 (\%) \\
407+
\midrule
408+
class label & Count & Train & Test & Val & All & Fin & Man & Sci & Law & Pat & Ten \\
409+
Caption & 22524 & 2.04 & 1.77 & 2.32 & 84-89 & 40-61 & 86-92 & 94-99 & 95-99 & 69-78 & n/a \\
410+
Footnote & 6318 & 0.60 & 0.31 & 0.58 & 83-91 & n/a & 100 & 62-88 & 85-94 & n/a & 82-97 \\
411+
Formula & 25027 & 2.25 & 1.90 & 2.96 & 83-85 & n/a & n/a & 84-87 & 86-96 & n/a & n/a \\
412+
List-item & 185660 & 17.19 & 13.34 & 15.82 & 87-88 & 74-83 & 90-92 & 97-97 & 81-85 & 75-88 & 93-95 \\
413+
Page- footer & 70878 & 6.51 & 5.58 & 6.00 & 93-94 & 88-90 & 95-96 & 100 & 92-97 & 100 & 96-98 \\
414+
Page- header & 58022 & 5.10 & 6.70 & 5.06 & 85-89 & 66-76 & 90-94 & 98-100 & 91-92 & 97-99 & 81-86 \\
415+
Picture & 45976 & 4.21 & 2.78 & 5.31 & 69-71 & 56-59 & 82-86 & 69-82 & 80-95 & 66-71 & 59-76 \\
416+
Section- header & 142884 & 12.60 & 15.77 & 12.85 & 83-84 & 76-81 & 90-92 & 94-95 & 87-94 & 69-73 & 78-86 \\
417+
Table & 34733 & 3.20 & 2.27 & 3.60 & 77-81 & 75-80 & 83-86 & 98-99 & 58-80 & 79-84 & 70-85 \\
418+
Text & 510377 & 45.82 & 49.28 & 45.00 & 84-86 & 81-86 & 88-93 & 89-93 & 87-92 & 71-79 & 87-95 \\
419+
Title & 5071 & 0.47 & 0.30 & 0.50 & 60-72 & 24-63 & 50-63 & 94-100 & 82-96 & 68-79 & 24-56 \\
420+
Total & 1107470 & 941123 & 99816 & 66531 & 82-83 & 71-74 & 79-81 & 89-94 & 86-91 & 71-76 & 68-85 \\
421+
\bottomrule
411422
\end{tabular}
412423
\end{table}
413424

test/data/doc/activities.gt.tex

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
\usepackage{hyperref} % hyperlinks
66
\usepackage{url} % simple URL typesetting
77
\usepackage{booktabs} % professional-quality tables
8+
\usepackage{array} % extended column defs
9+
\usepackage{multirow} % multirow cells
10+
\usepackage{makecell} % line breaks in cells
811
\usepackage{amsfonts} % blackboard math symbols
912
\usepackage{nicefrac} % compact symbols for 1/2, etc.
1013
\usepackage{microtype} % microtypography

0 commit comments

Comments
 (0)