]>
git.cameronkatri.com Git - mandoc.git/blob - out.c
1 /* $Id: out.c,v 1.47 2014/03/23 11:25:26 schwarze Exp $ */
3 * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
4 * Copyright (c) 2011 Ingo Schwarze <schwarze@openbsd.org>
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22 #include <sys/types.h>
31 #include "mandoc_aux.h"
35 static void tblcalc_data(struct rofftbl
*, struct roffcol
*,
36 const struct tbl_opts
*, const struct tbl_dat
*);
37 static void tblcalc_literal(struct rofftbl
*, struct roffcol
*,
38 const struct tbl_dat
*);
39 static void tblcalc_number(struct rofftbl
*, struct roffcol
*,
40 const struct tbl_opts
*, const struct tbl_dat
*);
43 * Convert a `scaling unit' to a consistent form, or fail. Scaling
44 * units are documented in groff.7, mdoc.7, man.7.
47 a2roffsu(const char *src
, struct roffsu
*dst
, enum roffscale def
)
49 char buf
[BUFSIZ
], hasd
;
73 if ( ! isdigit((unsigned char)*src
)) {
84 if (BUFSIZ
== i
|| (*src
&& *(src
+ 1)))
112 if (SCALE_MAX
== def
)
129 /* FIXME: do this in the caller. */
130 if ((dst
->scale
= atof(buf
)) < 0)
137 * Calculate the abstract widths and decimal positions of columns in a
138 * table. This routine allocates the columns structures then runs over
139 * all rows and cells in the table. The function pointers in "tbl" are
140 * used for the actual width calculations.
143 tblcalc(struct rofftbl
*tbl
, const struct tbl_span
*sp
)
145 const struct tbl_dat
*dp
;
150 * Allocate the master column specifiers. These will hold the
151 * widths and decimal positions for all cells in the column. It
152 * must be freed and nullified by the caller.
155 assert(NULL
== tbl
->cols
);
156 tbl
->cols
= mandoc_calloc
157 ((size_t)sp
->opts
->cols
, sizeof(struct roffcol
));
159 for ( ; sp
; sp
= sp
->next
) {
160 if (TBL_SPAN_DATA
!= sp
->pos
)
164 * Account for the data cells in the layout, matching it
165 * to data cells in the data section.
167 for (dp
= sp
->first
; dp
; dp
= dp
->next
) {
168 /* Do not used spanned cells in the calculation. */
175 col
= &tbl
->cols
[dp
->layout
->head
->ident
];
176 tblcalc_data(tbl
, col
, sp
->opts
, dp
);
182 tblcalc_data(struct rofftbl
*tbl
, struct roffcol
*col
,
183 const struct tbl_opts
*opts
, const struct tbl_dat
*dp
)
187 /* Branch down into data sub-types. */
189 switch (dp
->layout
->pos
) {
190 case (TBL_CELL_HORIZ
):
192 case (TBL_CELL_DHORIZ
):
193 sz
= (*tbl
->len
)(1, tbl
->arg
);
197 case (TBL_CELL_LONG
):
199 case (TBL_CELL_CENTRE
):
201 case (TBL_CELL_LEFT
):
203 case (TBL_CELL_RIGHT
):
204 tblcalc_literal(tbl
, col
, dp
);
206 case (TBL_CELL_NUMBER
):
207 tblcalc_number(tbl
, col
, opts
, dp
);
209 case (TBL_CELL_DOWN
):
218 tblcalc_literal(struct rofftbl
*tbl
, struct roffcol
*col
,
219 const struct tbl_dat
*dp
)
224 str
= dp
->string
? dp
->string
: "";
225 sz
= (*tbl
->slen
)(str
, tbl
->arg
);
232 tblcalc_number(struct rofftbl
*tbl
, struct roffcol
*col
,
233 const struct tbl_opts
*opts
, const struct tbl_dat
*dp
)
236 size_t sz
, psz
, ssz
, d
;
242 * First calculate number width and decimal place (last + 1 for
243 * non-decimal numbers). If the stored decimal is subsequent to
244 * ours, make our size longer by that difference
245 * (right-"shifting"); similarly, if ours is subsequent the
246 * stored, then extend the stored size by the difference.
247 * Finally, re-assign the stored values.
250 str
= dp
->string
? dp
->string
: "";
251 sz
= (*tbl
->slen
)(str
, tbl
->arg
);
253 /* FIXME: TBL_DATA_HORIZ et al.? */
255 buf
[0] = opts
->decimal
;
258 psz
= (*tbl
->slen
)(buf
, tbl
->arg
);
260 if (NULL
!= (cp
= strrchr(str
, opts
->decimal
))) {
262 for (ssz
= 0, i
= 0; cp
!= &str
[i
]; i
++) {
264 ssz
+= (*tbl
->slen
)(buf
, tbl
->arg
);
270 /* Adjust the settings for this column. */
272 if (col
->decimal
> d
) {
273 sz
+= col
->decimal
- d
;
276 col
->width
+= d
- col
->decimal
;
280 if (d
> col
->decimal
)