371584c2eae4cf827fd406ba26c14f021adaaa70Yuri Pankov/* $Id: out.c,v 1.62 2015/10/12 00:08:16 schwarze Exp $ */
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov * Copyright (c) 2011, 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * Permission to use, copy, modify, and distribute this software for any
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * purpose with or without fee is hereby granted, provided that the above
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * copyright notice and this permission notice appear in all copies.
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amorestatic void tblcalc_data(struct rofftbl *, struct roffcol *,
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore const struct tbl_opts *, const struct tbl_dat *);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amorestatic void tblcalc_literal(struct rofftbl *, struct roffcol *,
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore const struct tbl_dat *);
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amorestatic void tblcalc_number(struct rofftbl *, struct roffcol *,
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore const struct tbl_opts *, const struct tbl_dat *);
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov * Parse the *src string and store a scaling unit into *dst.
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov * If the string doesn't specify the unit, use the default.
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov * If no default is specified, fail.
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov * Return 2 on complete success, 1 when a conversion was done,
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov * but there was trailing garbage, and 0 on total failure.
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amorea2roffsu(const char *src, struct roffsu *dst, enum roffscale def)
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov switch (*endptr++) {
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov /* FALLTHROUGH */
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * Calculate the abstract widths and decimal positions of columns in a
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * table. This routine allocates the columns structures then runs over
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * all rows and cells in the table. The function pointers in "tbl" are
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * used for the actual width calculations.
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankovtblcalc(struct rofftbl *tbl, const struct tbl_span *sp,
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * Allocate the master column specifiers. These will hold the
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * widths and decimal positions for all cells in the column. It
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * must be freed and nullified by the caller.
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov tbl->cols = mandoc_calloc((size_t)sp->opts->cols,
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov sizeof(struct roffcol));
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * Account for the data cells in the layout, matching it
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * to data cells in the data section.
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore /* Do not used spanned cells in the calculation. */
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov * Count columns to equalize and columns to maximize.
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov * Find maximum width of the columns to equalize.
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov * Find total width of the columns *not* to maximize.
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov * Equalize columns, if requested for any of them.
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov * Update total width of the columns not to maximize.
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov * If there are any columns to maximize, find the total
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov * available width, deducting 3n margins between columns.
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov * Distribute the available width evenly.
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov * Emulate a bug in GNU tbl width calculation that
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov * manifests itself for large numbers of x-columns.
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov * Emulating it for 5 x-columns gives identical
260e9a87725c090ba5835b1f9f0b62fa2f96036fYuri Pankov * behaviour for up to 6 x-columns.
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amoretblcalc_data(struct rofftbl *tbl, struct roffcol *col,
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore const struct tbl_opts *opts, const struct tbl_dat *dp)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore /* Branch down into data sub-types. */
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amoretblcalc_literal(struct rofftbl *tbl, struct roffcol *col,
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amoretblcalc_number(struct rofftbl *tbl, struct roffcol *col,
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore const struct tbl_opts *opts, const struct tbl_dat *dp)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * First calculate number width and decimal place (last + 1 for
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * non-decimal numbers). If the stored decimal is subsequent to
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * ours, make our size longer by that difference
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * (right-"shifting"); similarly, if ours is subsequent the
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * stored, then extend the stored size by the difference.
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore * Finally, re-assign the stored values.
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore /* FIXME: TBL_DATA_HORIZ et al.? */
698f87a48e2e945bfe5493ce168e0d0ae1cedd5cGarrett D'Amore if (NULL != (cp = strrchr(str, opts->decimal))) {
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore /* Adjust the settings for this column. */