version 1.77, 2018/12/13 11:55:47 |
version 1.84, 2021/10/17 20:48:28 |
|
|
/* $Id$ */ |
/* $Id$ */ |
/* |
/* |
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> |
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> |
* Copyright (c) 2011,2014,2015,2017,2018 Ingo Schwarze <schwarze@openbsd.org> |
* Copyright (c) 2011, 2014, 2015, 2017, 2018, 2019, 2021 |
|
* Ingo Schwarze <schwarze@openbsd.org> |
* |
* |
* Permission to use, copy, modify, and distribute this software for any |
* Permission to use, copy, modify, and distribute this software for any |
* purpose with or without fee is hereby granted, provided that the above |
* purpose with or without fee is hereby granted, provided that the above |
|
|
#include <assert.h> |
#include <assert.h> |
#include <ctype.h> |
#include <ctype.h> |
#include <stdint.h> |
#include <stdint.h> |
|
#include <stdio.h> |
#include <stdlib.h> |
#include <stdlib.h> |
#include <string.h> |
#include <string.h> |
#include <time.h> |
#include <time.h> |
|
|
#include "mandoc_aux.h" |
#include "mandoc_aux.h" |
|
#include "mandoc.h" |
#include "tbl.h" |
#include "tbl.h" |
#include "out.h" |
#include "out.h" |
|
|
Line 146 tblcalc(struct rofftbl *tbl, const struct tbl_span *sp |
|
Line 149 tblcalc(struct rofftbl *tbl, const struct tbl_span *sp |
|
* to data cells in the data section. |
* to data cells in the data section. |
*/ |
*/ |
|
|
gp = &first_group; |
|
for (dp = sp->first; dp != NULL; dp = dp->next) { |
for (dp = sp->first; dp != NULL; dp = dp->next) { |
icol = dp->layout->col; |
icol = dp->layout->col; |
while (icol > maxcol) |
while (maxcol < icol + dp->hspans) |
tbl->cols[++maxcol].spacing = SIZE_MAX; |
tbl->cols[++maxcol].spacing = SIZE_MAX; |
col = tbl->cols + icol; |
col = tbl->cols + icol; |
col->flags |= dp->layout->flags; |
col->flags |= dp->layout->flags; |
Line 187 tblcalc(struct rofftbl *tbl, const struct tbl_span *sp |
|
Line 189 tblcalc(struct rofftbl *tbl, const struct tbl_span *sp |
|
continue; |
continue; |
|
|
/* |
/* |
* Build an ordered, singly linked list |
* Build a singly linked list |
* of all groups of columns joined by spans, |
* of all groups of columns joined by spans, |
* recording the minimum width for each group. |
* recording the minimum width for each group. |
*/ |
*/ |
|
|
while (*gp != NULL && ((*gp)->startcol < icol || |
gp = &first_group; |
(*gp)->endcol < icol + dp->hspans)) |
while (*gp != NULL && ((*gp)->startcol != icol || |
|
(*gp)->endcol != icol + dp->hspans)) |
gp = &(*gp)->next; |
gp = &(*gp)->next; |
if (*gp == NULL || (*gp)->startcol > icol || |
if (*gp == NULL) { |
(*gp)->endcol > icol + dp->hspans) { |
|
g = mandoc_malloc(sizeof(*g)); |
g = mandoc_malloc(sizeof(*g)); |
g->next = *gp; |
g->next = *gp; |
g->wanted = width; |
g->wanted = width; |
Line 209 tblcalc(struct rofftbl *tbl, const struct tbl_span *sp |
|
Line 211 tblcalc(struct rofftbl *tbl, const struct tbl_span *sp |
|
} |
} |
|
|
/* |
/* |
* Column spacings are needed for span width calculations, |
* The minimum width of columns explicitly specified |
* so set the default values now. |
* in the layout is 1n. |
*/ |
*/ |
|
|
for (icol = 0; icol <= maxcol; icol++) |
if (maxcol < sp_first->opts->cols - 1) |
if (tbl->cols[icol].spacing == SIZE_MAX || icol == maxcol) |
maxcol = sp_first->opts->cols - 1; |
tbl->cols[icol].spacing = 3; |
for (icol = 0; icol <= maxcol; icol++) { |
|
col = tbl->cols + icol; |
|
if (col->width < 1) |
|
col->width = 1; |
|
|
|
/* |
|
* Column spacings are needed for span width |
|
* calculations, so set the default values now. |
|
*/ |
|
|
|
if (col->spacing == SIZE_MAX || icol == maxcol) |
|
col->spacing = 3; |
|
} |
|
|
/* |
/* |
* Replace the minimum widths with the missing widths, |
* Replace the minimum widths with the missing widths, |
* and dismiss groups that are already wide enough. |
* and dismiss groups that are already wide enough. |
Line 263 tblcalc(struct rofftbl *tbl, const struct tbl_span *sp |
|
Line 277 tblcalc(struct rofftbl *tbl, const struct tbl_span *sp |
|
|
|
min1 = min2 = SIZE_MAX; |
min1 = min2 = SIZE_MAX; |
for (icol = 0; icol <= maxcol; icol++) { |
for (icol = 0; icol <= maxcol; icol++) { |
if (min1 > colwidth[icol]) { |
width = colwidth[icol]; |
|
if (min1 > width) { |
min2 = min1; |
min2 = min1; |
min1 = colwidth[icol]; |
min1 = width; |
} else if (min1 < colwidth[icol] && |
} else if (min1 < width && min2 > width) |
min2 > colwidth[icol]) |
min2 = width; |
min2 = colwidth[icol]; |
|
} |
} |
|
|
/* |
/* |
Line 281 tblcalc(struct rofftbl *tbl, const struct tbl_span *sp |
|
Line 295 tblcalc(struct rofftbl *tbl, const struct tbl_span *sp |
|
for (g = first_group; g != NULL; g = g->next) { |
for (g = first_group; g != NULL; g = g->next) { |
necol = 0; |
necol = 0; |
for (icol = g->startcol; icol <= g->endcol; icol++) |
for (icol = g->startcol; icol <= g->endcol; icol++) |
if (tbl->cols[icol].width == min1) |
if (colwidth[icol] == min1) |
necol++; |
necol++; |
if (necol == 0) |
if (necol == 0) |
continue; |
continue; |
Line 290 tblcalc(struct rofftbl *tbl, const struct tbl_span *sp |
|
Line 304 tblcalc(struct rofftbl *tbl, const struct tbl_span *sp |
|
width = min2; |
width = min2; |
if (wanted > width) |
if (wanted > width) |
wanted = width; |
wanted = width; |
for (icol = g->startcol; icol <= g->endcol; icol++) |
|
if (colwidth[icol] == min1 || |
|
(colwidth[icol] < min2 && |
|
colwidth[icol] > width)) |
|
colwidth[icol] = width; |
|
} |
} |
|
|
/* Record the effect of the widening on the group list. */ |
/* Record the effect of the widening. */ |
|
|
gp = &first_group; |
gp = &first_group; |
while ((g = *gp) != NULL) { |
while ((g = *gp) != NULL) { |
done = 0; |
done = 0; |
for (icol = g->startcol; icol <= g->endcol; icol++) { |
for (icol = g->startcol; icol <= g->endcol; icol++) { |
if (colwidth[icol] != wanted || |
if (colwidth[icol] != min1) |
tbl->cols[icol].width == wanted) |
|
continue; |
continue; |
if (g->wanted <= wanted - min1) { |
if (g->wanted <= wanted - min1) { |
|
tbl->cols[icol].width += g->wanted; |
done = 1; |
done = 1; |
break; |
break; |
} |
} |
|
tbl->cols[icol].width = wanted; |
g->wanted -= wanted - min1; |
g->wanted -= wanted - min1; |
} |
} |
if (done) { |
if (done) { |
Line 318 tblcalc(struct rofftbl *tbl, const struct tbl_span *sp |
|
Line 328 tblcalc(struct rofftbl *tbl, const struct tbl_span *sp |
|
} else |
} else |
gp = &(*gp)->next; |
gp = &(*gp)->next; |
} |
} |
|
|
/* Record the effect of the widening on the columns. */ |
|
|
|
for (icol = 0; icol <= maxcol; icol++) |
|
if (colwidth[icol] == wanted) |
|
tbl->cols[icol].width = wanted; |
|
} |
} |
free(colwidth); |
free(colwidth); |
|
|
Line 340 tblcalc(struct rofftbl *tbl, const struct tbl_span *sp |
|
Line 344 tblcalc(struct rofftbl *tbl, const struct tbl_span *sp |
|
col = tbl->cols + icol; |
col = tbl->cols + icol; |
if (col->width > col->nwidth) |
if (col->width > col->nwidth) |
col->decimal += (col->width - col->nwidth) / 2; |
col->decimal += (col->width - col->nwidth) / 2; |
else |
|
col->width = col->nwidth; |
|
if (col->flags & TBL_CELL_EQUAL) { |
if (col->flags & TBL_CELL_EQUAL) { |
necol++; |
necol++; |
if (ewidth < col->width) |
if (ewidth < col->width) |
Line 549 tblcalc_number(struct rofftbl *tbl, struct roffcol *co |
|
Line 551 tblcalc_number(struct rofftbl *tbl, struct roffcol *co |
|
|
|
if (totsz > col->nwidth) |
if (totsz > col->nwidth) |
col->nwidth = totsz; |
col->nwidth = totsz; |
|
if (col->nwidth > col->width) |
|
col->width = col->nwidth; |
|
fprintf(stderr, "N=%zu D=%zu I=%zu T=%zu %s\n", |
|
col->nwidth, col->decimal, intsz, totsz, dp->string); |
return totsz; |
return totsz; |
} |
} |