mandoc 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (128) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +7 -0
  3. data/COPYING +674 -0
  4. data/README.md +117 -0
  5. data/ext/mandoc/extconf.rb +59 -0
  6. data/ext/mandoc/rb_mandoc.c +548 -0
  7. data/ext/mandoc/rb_mandoc.h +22 -0
  8. data/lib/mandoc/version.rb +19 -0
  9. data/lib/mandoc.rb +26 -0
  10. data/mandoc-1.14.6/LICENSE +55 -0
  11. data/mandoc-1.14.6/arch.c +54 -0
  12. data/mandoc-1.14.6/att.c +49 -0
  13. data/mandoc-1.14.6/catman.c +260 -0
  14. data/mandoc-1.14.6/cgi.c +1279 -0
  15. data/mandoc-1.14.6/chars.c +507 -0
  16. data/mandoc-1.14.6/compat_err.c +103 -0
  17. data/mandoc-1.14.6/compat_fts.c +696 -0
  18. data/mandoc-1.14.6/compat_fts.h +106 -0
  19. data/mandoc-1.14.6/compat_getline.c +59 -0
  20. data/mandoc-1.14.6/compat_getsubopt.c +87 -0
  21. data/mandoc-1.14.6/compat_isblank.c +23 -0
  22. data/mandoc-1.14.6/compat_mkdtemp.c +50 -0
  23. data/mandoc-1.14.6/compat_mkstemps.c +63 -0
  24. data/mandoc-1.14.6/compat_ohash.c +330 -0
  25. data/mandoc-1.14.6/compat_ohash.h +72 -0
  26. data/mandoc-1.14.6/compat_progname.c +31 -0
  27. data/mandoc-1.14.6/compat_reallocarray.c +40 -0
  28. data/mandoc-1.14.6/compat_recallocarray.c +99 -0
  29. data/mandoc-1.14.6/compat_strcasestr.c +64 -0
  30. data/mandoc-1.14.6/compat_stringlist.c +135 -0
  31. data/mandoc-1.14.6/compat_stringlist.h +48 -0
  32. data/mandoc-1.14.6/compat_strlcat.c +57 -0
  33. data/mandoc-1.14.6/compat_strlcpy.c +52 -0
  34. data/mandoc-1.14.6/compat_strndup.c +42 -0
  35. data/mandoc-1.14.6/compat_strsep.c +70 -0
  36. data/mandoc-1.14.6/compat_strtonum.c +67 -0
  37. data/mandoc-1.14.6/compat_vasprintf.c +47 -0
  38. data/mandoc-1.14.6/config.h +52 -0
  39. data/mandoc-1.14.6/dba.c +508 -0
  40. data/mandoc-1.14.6/dba.h +50 -0
  41. data/mandoc-1.14.6/dba_array.c +190 -0
  42. data/mandoc-1.14.6/dba_array.h +47 -0
  43. data/mandoc-1.14.6/dba_read.c +74 -0
  44. data/mandoc-1.14.6/dba_write.c +127 -0
  45. data/mandoc-1.14.6/dba_write.h +30 -0
  46. data/mandoc-1.14.6/dbm.c +480 -0
  47. data/mandoc-1.14.6/dbm.h +68 -0
  48. data/mandoc-1.14.6/dbm_map.c +194 -0
  49. data/mandoc-1.14.6/dbm_map.h +29 -0
  50. data/mandoc-1.14.6/demandoc.c +260 -0
  51. data/mandoc-1.14.6/eqn.c +1132 -0
  52. data/mandoc-1.14.6/eqn.h +72 -0
  53. data/mandoc-1.14.6/eqn_html.c +246 -0
  54. data/mandoc-1.14.6/eqn_parse.h +48 -0
  55. data/mandoc-1.14.6/eqn_term.c +174 -0
  56. data/mandoc-1.14.6/html.c +1102 -0
  57. data/mandoc-1.14.6/html.h +142 -0
  58. data/mandoc-1.14.6/lib.c +35 -0
  59. data/mandoc-1.14.6/libman.h +42 -0
  60. data/mandoc-1.14.6/libmandoc.h +85 -0
  61. data/mandoc-1.14.6/libmdoc.h +87 -0
  62. data/mandoc-1.14.6/main.c +1375 -0
  63. data/mandoc-1.14.6/main.h +53 -0
  64. data/mandoc-1.14.6/man.c +345 -0
  65. data/mandoc-1.14.6/man.h +21 -0
  66. data/mandoc-1.14.6/man_html.c +640 -0
  67. data/mandoc-1.14.6/man_macro.c +470 -0
  68. data/mandoc-1.14.6/man_term.c +1143 -0
  69. data/mandoc-1.14.6/man_validate.c +660 -0
  70. data/mandoc-1.14.6/manconf.h +58 -0
  71. data/mandoc-1.14.6/mandoc.c +669 -0
  72. data/mandoc-1.14.6/mandoc.h +329 -0
  73. data/mandoc-1.14.6/mandoc_aux.c +118 -0
  74. data/mandoc-1.14.6/mandoc_aux.h +27 -0
  75. data/mandoc-1.14.6/mandoc_msg.c +375 -0
  76. data/mandoc-1.14.6/mandoc_ohash.c +65 -0
  77. data/mandoc-1.14.6/mandoc_ohash.h +23 -0
  78. data/mandoc-1.14.6/mandoc_parse.h +44 -0
  79. data/mandoc-1.14.6/mandoc_xr.c +123 -0
  80. data/mandoc-1.14.6/mandoc_xr.h +31 -0
  81. data/mandoc-1.14.6/mandocd.c +282 -0
  82. data/mandoc-1.14.6/mandocdb.c +2448 -0
  83. data/mandoc-1.14.6/manpath.c +363 -0
  84. data/mandoc-1.14.6/mansearch.c +851 -0
  85. data/mandoc-1.14.6/mansearch.h +118 -0
  86. data/mandoc-1.14.6/mdoc.c +433 -0
  87. data/mandoc-1.14.6/mdoc.h +158 -0
  88. data/mandoc-1.14.6/mdoc_argv.c +682 -0
  89. data/mandoc-1.14.6/mdoc_html.c +1762 -0
  90. data/mandoc-1.14.6/mdoc_macro.c +1600 -0
  91. data/mandoc-1.14.6/mdoc_man.c +1850 -0
  92. data/mandoc-1.14.6/mdoc_markdown.c +1610 -0
  93. data/mandoc-1.14.6/mdoc_state.c +256 -0
  94. data/mandoc-1.14.6/mdoc_term.c +1964 -0
  95. data/mandoc-1.14.6/mdoc_validate.c +3062 -0
  96. data/mandoc-1.14.6/msec.c +37 -0
  97. data/mandoc-1.14.6/out.c +544 -0
  98. data/mandoc-1.14.6/out.h +70 -0
  99. data/mandoc-1.14.6/preconv.c +179 -0
  100. data/mandoc-1.14.6/read.c +732 -0
  101. data/mandoc-1.14.6/roff.c +4390 -0
  102. data/mandoc-1.14.6/roff.h +561 -0
  103. data/mandoc-1.14.6/roff_html.c +119 -0
  104. data/mandoc-1.14.6/roff_int.h +94 -0
  105. data/mandoc-1.14.6/roff_term.c +266 -0
  106. data/mandoc-1.14.6/roff_validate.c +151 -0
  107. data/mandoc-1.14.6/soelim.c +182 -0
  108. data/mandoc-1.14.6/st.c +82 -0
  109. data/mandoc-1.14.6/tag.c +327 -0
  110. data/mandoc-1.14.6/tag.h +35 -0
  111. data/mandoc-1.14.6/tbl.c +183 -0
  112. data/mandoc-1.14.6/tbl.h +121 -0
  113. data/mandoc-1.14.6/tbl_data.c +323 -0
  114. data/mandoc-1.14.6/tbl_html.c +293 -0
  115. data/mandoc-1.14.6/tbl_int.h +47 -0
  116. data/mandoc-1.14.6/tbl_layout.c +376 -0
  117. data/mandoc-1.14.6/tbl_opts.c +173 -0
  118. data/mandoc-1.14.6/tbl_parse.h +30 -0
  119. data/mandoc-1.14.6/tbl_term.c +948 -0
  120. data/mandoc-1.14.6/term.c +1113 -0
  121. data/mandoc-1.14.6/term.h +158 -0
  122. data/mandoc-1.14.6/term_ascii.c +424 -0
  123. data/mandoc-1.14.6/term_ps.c +1362 -0
  124. data/mandoc-1.14.6/term_tab.c +130 -0
  125. data/mandoc-1.14.6/term_tag.c +227 -0
  126. data/mandoc-1.14.6/term_tag.h +34 -0
  127. data/mandoc-1.14.6/tree.c +536 -0
  128. metadata +170 -0
@@ -0,0 +1,37 @@
1
+ /* $Id: msec.c,v 1.16 2018/12/14 01:18:26 schwarze Exp $ */
2
+ /*
3
+ * Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv>
4
+ *
5
+ * Permission to use, copy, modify, and distribute this software for any
6
+ * purpose with or without fee is hereby granted, provided that the above
7
+ * copyright notice and this permission notice appear in all copies.
8
+ *
9
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16
+ */
17
+ #include "config.h"
18
+
19
+ #include <sys/types.h>
20
+
21
+ #include <stdio.h>
22
+ #include <string.h>
23
+
24
+ #include "mandoc.h"
25
+ #include "libmandoc.h"
26
+
27
+ #define LINE(x, y) \
28
+ if (0 == strcmp(p, x)) return(y);
29
+
30
+ const char *
31
+ mandoc_a2msec(const char *p)
32
+ {
33
+
34
+ #include "msec.in"
35
+
36
+ return NULL;
37
+ }
@@ -0,0 +1,544 @@
1
+ /* $Id: out.c,v 1.82 2021/09/07 17:07:58 schwarze Exp $ */
2
+ /*
3
+ * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
4
+ * Copyright (c) 2011, 2014, 2015, 2017, 2018, 2019, 2021
5
+ * Ingo Schwarze <schwarze@openbsd.org>
6
+ *
7
+ * Permission to use, copy, modify, and distribute this software for any
8
+ * purpose with or without fee is hereby granted, provided that the above
9
+ * copyright notice and this permission notice appear in all copies.
10
+ *
11
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18
+ */
19
+ #include "config.h"
20
+
21
+ #include <sys/types.h>
22
+
23
+ #include <assert.h>
24
+ #include <ctype.h>
25
+ #include <stdint.h>
26
+ #include <stdio.h>
27
+ #include <stdlib.h>
28
+ #include <string.h>
29
+ #include <time.h>
30
+
31
+ #include "mandoc_aux.h"
32
+ #include "mandoc.h"
33
+ #include "tbl.h"
34
+ #include "out.h"
35
+
36
+ struct tbl_colgroup {
37
+ struct tbl_colgroup *next;
38
+ size_t wanted;
39
+ int startcol;
40
+ int endcol;
41
+ };
42
+
43
+ static size_t tblcalc_data(struct rofftbl *, struct roffcol *,
44
+ const struct tbl_opts *, const struct tbl_dat *,
45
+ size_t);
46
+ static size_t tblcalc_literal(struct rofftbl *, struct roffcol *,
47
+ const struct tbl_dat *, size_t);
48
+ static size_t tblcalc_number(struct rofftbl *, struct roffcol *,
49
+ const struct tbl_opts *, const struct tbl_dat *);
50
+
51
+
52
+ /*
53
+ * Parse the *src string and store a scaling unit into *dst.
54
+ * If the string doesn't specify the unit, use the default.
55
+ * If no default is specified, fail.
56
+ * Return a pointer to the byte after the last byte used,
57
+ * or NULL on total failure.
58
+ */
59
+ const char *
60
+ a2roffsu(const char *src, struct roffsu *dst, enum roffscale def)
61
+ {
62
+ char *endptr;
63
+
64
+ dst->unit = def == SCALE_MAX ? SCALE_BU : def;
65
+ dst->scale = strtod(src, &endptr);
66
+ if (endptr == src)
67
+ return NULL;
68
+
69
+ switch (*endptr++) {
70
+ case 'c':
71
+ dst->unit = SCALE_CM;
72
+ break;
73
+ case 'i':
74
+ dst->unit = SCALE_IN;
75
+ break;
76
+ case 'f':
77
+ dst->unit = SCALE_FS;
78
+ break;
79
+ case 'M':
80
+ dst->unit = SCALE_MM;
81
+ break;
82
+ case 'm':
83
+ dst->unit = SCALE_EM;
84
+ break;
85
+ case 'n':
86
+ dst->unit = SCALE_EN;
87
+ break;
88
+ case 'P':
89
+ dst->unit = SCALE_PC;
90
+ break;
91
+ case 'p':
92
+ dst->unit = SCALE_PT;
93
+ break;
94
+ case 'u':
95
+ dst->unit = SCALE_BU;
96
+ break;
97
+ case 'v':
98
+ dst->unit = SCALE_VS;
99
+ break;
100
+ default:
101
+ endptr--;
102
+ if (SCALE_MAX == def)
103
+ return NULL;
104
+ dst->unit = def;
105
+ break;
106
+ }
107
+ return endptr;
108
+ }
109
+
110
+ /*
111
+ * Calculate the abstract widths and decimal positions of columns in a
112
+ * table. This routine allocates the columns structures then runs over
113
+ * all rows and cells in the table. The function pointers in "tbl" are
114
+ * used for the actual width calculations.
115
+ */
116
+ void
117
+ tblcalc(struct rofftbl *tbl, const struct tbl_span *sp_first,
118
+ size_t offset, size_t rmargin)
119
+ {
120
+ struct roffsu su;
121
+ const struct tbl_opts *opts;
122
+ const struct tbl_span *sp;
123
+ const struct tbl_dat *dp;
124
+ struct roffcol *col;
125
+ struct tbl_colgroup *first_group, **gp, *g;
126
+ size_t ewidth, min1, min2, wanted, width, xwidth;
127
+ int done, icol, maxcol, necol, nxcol, quirkcol;
128
+
129
+ /*
130
+ * Allocate the master column specifiers. These will hold the
131
+ * widths and decimal positions for all cells in the column. It
132
+ * must be freed and nullified by the caller.
133
+ */
134
+
135
+ assert(tbl->cols == NULL);
136
+ tbl->cols = mandoc_calloc((size_t)sp_first->opts->cols,
137
+ sizeof(struct roffcol));
138
+ opts = sp_first->opts;
139
+
140
+ maxcol = -1;
141
+ first_group = NULL;
142
+ for (sp = sp_first; sp != NULL; sp = sp->next) {
143
+ if (sp->pos != TBL_SPAN_DATA)
144
+ continue;
145
+
146
+ /*
147
+ * Account for the data cells in the layout, matching it
148
+ * to data cells in the data section.
149
+ */
150
+
151
+ gp = &first_group;
152
+ for (dp = sp->first; dp != NULL; dp = dp->next) {
153
+ icol = dp->layout->col;
154
+ while (maxcol < icol + dp->hspans)
155
+ tbl->cols[++maxcol].spacing = SIZE_MAX;
156
+ col = tbl->cols + icol;
157
+ col->flags |= dp->layout->flags;
158
+ if (dp->layout->flags & TBL_CELL_WIGN)
159
+ continue;
160
+
161
+ /* Handle explicit width specifications. */
162
+
163
+ if (dp->layout->wstr != NULL &&
164
+ dp->layout->width == 0 &&
165
+ a2roffsu(dp->layout->wstr, &su, SCALE_EN)
166
+ != NULL)
167
+ dp->layout->width =
168
+ (*tbl->sulen)(&su, tbl->arg);
169
+ if (col->width < dp->layout->width)
170
+ col->width = dp->layout->width;
171
+ if (dp->layout->spacing != SIZE_MAX &&
172
+ (col->spacing == SIZE_MAX ||
173
+ col->spacing < dp->layout->spacing))
174
+ col->spacing = dp->layout->spacing;
175
+
176
+ /*
177
+ * Calculate an automatic width.
178
+ * Except for spanning cells, apply it.
179
+ */
180
+
181
+ width = tblcalc_data(tbl,
182
+ dp->hspans == 0 ? col : NULL,
183
+ opts, dp,
184
+ dp->block == 0 ? 0 :
185
+ dp->layout->width ? dp->layout->width :
186
+ rmargin ? (rmargin + sp->opts->cols / 2)
187
+ / (sp->opts->cols + 1) : 0);
188
+ if (dp->hspans == 0)
189
+ continue;
190
+
191
+ /*
192
+ * Build an ordered, singly linked list
193
+ * of all groups of columns joined by spans,
194
+ * recording the minimum width for each group.
195
+ */
196
+
197
+ while (*gp != NULL && ((*gp)->startcol < icol ||
198
+ (*gp)->endcol < icol + dp->hspans))
199
+ gp = &(*gp)->next;
200
+ if (*gp == NULL || (*gp)->startcol > icol ||
201
+ (*gp)->endcol > icol + dp->hspans) {
202
+ g = mandoc_malloc(sizeof(*g));
203
+ g->next = *gp;
204
+ g->wanted = width;
205
+ g->startcol = icol;
206
+ g->endcol = icol + dp->hspans;
207
+ *gp = g;
208
+ } else if ((*gp)->wanted < width)
209
+ (*gp)->wanted = width;
210
+ }
211
+ }
212
+
213
+ /*
214
+ * The minimum width of columns explicitly specified
215
+ * in the layout is 1n.
216
+ */
217
+
218
+ if (maxcol < sp_first->opts->cols - 1)
219
+ maxcol = sp_first->opts->cols - 1;
220
+ for (icol = 0; icol <= maxcol; icol++) {
221
+ col = tbl->cols + icol;
222
+ if (col->width < 1)
223
+ col->width = 1;
224
+
225
+ /*
226
+ * Column spacings are needed for span width
227
+ * calculations, so set the default values now.
228
+ */
229
+
230
+ if (col->spacing == SIZE_MAX || icol == maxcol)
231
+ col->spacing = 3;
232
+ }
233
+
234
+ /*
235
+ * Replace the minimum widths with the missing widths,
236
+ * and dismiss groups that are already wide enough.
237
+ */
238
+
239
+ gp = &first_group;
240
+ while ((g = *gp) != NULL) {
241
+ done = 0;
242
+ for (icol = g->startcol; icol <= g->endcol; icol++) {
243
+ width = tbl->cols[icol].width;
244
+ if (icol < g->endcol)
245
+ width += tbl->cols[icol].spacing;
246
+ if (g->wanted <= width) {
247
+ done = 1;
248
+ break;
249
+ } else
250
+ (*gp)->wanted -= width;
251
+ }
252
+ if (done) {
253
+ *gp = g->next;
254
+ free(g);
255
+ } else
256
+ gp = &(*gp)->next;
257
+ }
258
+
259
+ while (first_group != NULL) {
260
+
261
+ /*
262
+ * Find the smallest and second smallest column width
263
+ * among the columns which may need expamsion.
264
+ */
265
+
266
+ min1 = min2 = SIZE_MAX;
267
+ for (icol = 0; icol <= maxcol; icol++) {
268
+ width = tbl->cols[icol].width;
269
+ if (min1 > width) {
270
+ min2 = min1;
271
+ min1 = width;
272
+ } else if (min1 < width && min2 > width)
273
+ min2 = width;
274
+ }
275
+
276
+ /*
277
+ * Find the minimum wanted width
278
+ * for any one of the narrowest columns,
279
+ * and mark the columns wanting that width.
280
+ */
281
+
282
+ wanted = min2;
283
+ for (g = first_group; g != NULL; g = g->next) {
284
+ necol = 0;
285
+ for (icol = g->startcol; icol <= g->endcol; icol++)
286
+ if (tbl->cols[icol].width == min1)
287
+ necol++;
288
+ if (necol == 0)
289
+ continue;
290
+ width = min1 + (g->wanted - 1) / necol + 1;
291
+ if (width > min2)
292
+ width = min2;
293
+ if (wanted > width)
294
+ wanted = width;
295
+ }
296
+
297
+ /* Record the effect of the widening. */
298
+
299
+ gp = &first_group;
300
+ while ((g = *gp) != NULL) {
301
+ done = 0;
302
+ for (icol = g->startcol; icol <= g->endcol; icol++) {
303
+ if (tbl->cols[icol].width != min1)
304
+ continue;
305
+ if (g->wanted <= wanted - min1) {
306
+ tbl->cols[icol].width += g->wanted;
307
+ done = 1;
308
+ break;
309
+ }
310
+ tbl->cols[icol].width = wanted;
311
+ g->wanted -= wanted - min1;
312
+ }
313
+ if (done) {
314
+ *gp = g->next;
315
+ free(g);
316
+ } else
317
+ gp = &(*gp)->next;
318
+ }
319
+ }
320
+
321
+ /*
322
+ * Align numbers with text.
323
+ * Count columns to equalize and columns to maximize.
324
+ * Find maximum width of the columns to equalize.
325
+ * Find total width of the columns *not* to maximize.
326
+ */
327
+
328
+ necol = nxcol = 0;
329
+ ewidth = xwidth = 0;
330
+ for (icol = 0; icol <= maxcol; icol++) {
331
+ col = tbl->cols + icol;
332
+ if (col->width > col->nwidth)
333
+ col->decimal += (col->width - col->nwidth) / 2;
334
+ if (col->flags & TBL_CELL_EQUAL) {
335
+ necol++;
336
+ if (ewidth < col->width)
337
+ ewidth = col->width;
338
+ }
339
+ if (col->flags & TBL_CELL_WMAX)
340
+ nxcol++;
341
+ else
342
+ xwidth += col->width;
343
+ }
344
+
345
+ /*
346
+ * Equalize columns, if requested for any of them.
347
+ * Update total width of the columns not to maximize.
348
+ */
349
+
350
+ if (necol) {
351
+ for (icol = 0; icol <= maxcol; icol++) {
352
+ col = tbl->cols + icol;
353
+ if ( ! (col->flags & TBL_CELL_EQUAL))
354
+ continue;
355
+ if (col->width == ewidth)
356
+ continue;
357
+ if (nxcol && rmargin)
358
+ xwidth += ewidth - col->width;
359
+ col->width = ewidth;
360
+ }
361
+ }
362
+
363
+ /*
364
+ * If there are any columns to maximize, find the total
365
+ * available width, deducting 3n margins between columns.
366
+ * Distribute the available width evenly.
367
+ */
368
+
369
+ if (nxcol && rmargin) {
370
+ xwidth += 3*maxcol +
371
+ (opts->opts & (TBL_OPT_BOX | TBL_OPT_DBOX) ?
372
+ 2 : !!opts->lvert + !!opts->rvert);
373
+ if (rmargin <= offset + xwidth)
374
+ return;
375
+ xwidth = rmargin - offset - xwidth;
376
+
377
+ /*
378
+ * Emulate a bug in GNU tbl width calculation that
379
+ * manifests itself for large numbers of x-columns.
380
+ * Emulating it for 5 x-columns gives identical
381
+ * behaviour for up to 6 x-columns.
382
+ */
383
+
384
+ if (nxcol == 5) {
385
+ quirkcol = xwidth % nxcol + 2;
386
+ if (quirkcol != 3 && quirkcol != 4)
387
+ quirkcol = -1;
388
+ } else
389
+ quirkcol = -1;
390
+
391
+ necol = 0;
392
+ ewidth = 0;
393
+ for (icol = 0; icol <= maxcol; icol++) {
394
+ col = tbl->cols + icol;
395
+ if ( ! (col->flags & TBL_CELL_WMAX))
396
+ continue;
397
+ col->width = (double)xwidth * ++necol / nxcol
398
+ - ewidth + 0.4995;
399
+ if (necol == quirkcol)
400
+ col->width--;
401
+ ewidth += col->width;
402
+ }
403
+ }
404
+ }
405
+
406
+ static size_t
407
+ tblcalc_data(struct rofftbl *tbl, struct roffcol *col,
408
+ const struct tbl_opts *opts, const struct tbl_dat *dp, size_t mw)
409
+ {
410
+ size_t sz;
411
+
412
+ /* Branch down into data sub-types. */
413
+
414
+ switch (dp->layout->pos) {
415
+ case TBL_CELL_HORIZ:
416
+ case TBL_CELL_DHORIZ:
417
+ sz = (*tbl->len)(1, tbl->arg);
418
+ if (col != NULL && col->width < sz)
419
+ col->width = sz;
420
+ return sz;
421
+ case TBL_CELL_LONG:
422
+ case TBL_CELL_CENTRE:
423
+ case TBL_CELL_LEFT:
424
+ case TBL_CELL_RIGHT:
425
+ return tblcalc_literal(tbl, col, dp, mw);
426
+ case TBL_CELL_NUMBER:
427
+ return tblcalc_number(tbl, col, opts, dp);
428
+ case TBL_CELL_DOWN:
429
+ return 0;
430
+ default:
431
+ abort();
432
+ }
433
+ }
434
+
435
+ static size_t
436
+ tblcalc_literal(struct rofftbl *tbl, struct roffcol *col,
437
+ const struct tbl_dat *dp, size_t mw)
438
+ {
439
+ const char *str; /* Beginning of the first line. */
440
+ const char *beg; /* Beginning of the current line. */
441
+ char *end; /* End of the current line. */
442
+ size_t lsz; /* Length of the current line. */
443
+ size_t wsz; /* Length of the current word. */
444
+ size_t msz; /* Length of the longest line. */
445
+
446
+ if (dp->string == NULL || *dp->string == '\0')
447
+ return 0;
448
+ str = mw ? mandoc_strdup(dp->string) : dp->string;
449
+ msz = lsz = 0;
450
+ for (beg = str; beg != NULL && *beg != '\0'; beg = end) {
451
+ end = mw ? strchr(beg, ' ') : NULL;
452
+ if (end != NULL) {
453
+ *end++ = '\0';
454
+ while (*end == ' ')
455
+ end++;
456
+ }
457
+ wsz = (*tbl->slen)(beg, tbl->arg);
458
+ if (mw && lsz && lsz + 1 + wsz <= mw)
459
+ lsz += 1 + wsz;
460
+ else
461
+ lsz = wsz;
462
+ if (msz < lsz)
463
+ msz = lsz;
464
+ }
465
+ if (mw)
466
+ free((void *)str);
467
+ if (col != NULL && col->width < msz)
468
+ col->width = msz;
469
+ return msz;
470
+ }
471
+
472
+ static size_t
473
+ tblcalc_number(struct rofftbl *tbl, struct roffcol *col,
474
+ const struct tbl_opts *opts, const struct tbl_dat *dp)
475
+ {
476
+ const char *cp, *lastdigit, *lastpoint;
477
+ size_t intsz, totsz;
478
+ char buf[2];
479
+
480
+ if (dp->string == NULL || *dp->string == '\0')
481
+ return 0;
482
+
483
+ totsz = (*tbl->slen)(dp->string, tbl->arg);
484
+ if (col == NULL)
485
+ return totsz;
486
+
487
+ /*
488
+ * Find the last digit and
489
+ * the last decimal point that is adjacent to a digit.
490
+ * The alignment indicator "\&" overrides everything.
491
+ */
492
+
493
+ lastdigit = lastpoint = NULL;
494
+ for (cp = dp->string; cp[0] != '\0'; cp++) {
495
+ if (cp[0] == '\\' && cp[1] == '&') {
496
+ lastdigit = lastpoint = cp;
497
+ break;
498
+ } else if (cp[0] == opts->decimal &&
499
+ (isdigit((unsigned char)cp[1]) ||
500
+ (cp > dp->string && isdigit((unsigned char)cp[-1]))))
501
+ lastpoint = cp;
502
+ else if (isdigit((unsigned char)cp[0]))
503
+ lastdigit = cp;
504
+ }
505
+
506
+ /* Not a number, treat as a literal string. */
507
+
508
+ if (lastdigit == NULL) {
509
+ if (col != NULL && col->width < totsz)
510
+ col->width = totsz;
511
+ return totsz;
512
+ }
513
+
514
+ /* Measure the width of the integer part. */
515
+
516
+ if (lastpoint == NULL)
517
+ lastpoint = lastdigit + 1;
518
+ intsz = 0;
519
+ buf[1] = '\0';
520
+ for (cp = dp->string; cp < lastpoint; cp++) {
521
+ buf[0] = cp[0];
522
+ intsz += (*tbl->slen)(buf, tbl->arg);
523
+ }
524
+
525
+ /*
526
+ * If this number has more integer digits than all numbers
527
+ * seen on earlier lines, shift them all to the right.
528
+ * If it has fewer, shift this number to the right.
529
+ */
530
+
531
+ if (intsz > col->decimal) {
532
+ col->nwidth += intsz - col->decimal;
533
+ col->decimal = intsz;
534
+ } else
535
+ totsz += col->decimal - intsz;
536
+
537
+ /* Update the maximum total width seen so far. */
538
+
539
+ if (totsz > col->nwidth)
540
+ col->nwidth = totsz;
541
+ if (col->nwidth > col->width)
542
+ col->width = col->nwidth;
543
+ return totsz;
544
+ }
@@ -0,0 +1,70 @@
1
+ /* $Id: out.h,v 1.34 2020/04/03 11:35:01 schwarze Exp $ */
2
+ /*
3
+ * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
4
+ * Copyright (c) 2014, 2017, 2018 Ingo Schwarze <schwarze@openbsd.org>
5
+ *
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.
9
+ *
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.
17
+ *
18
+ * Utilities for use by multiple mandoc(1) formatters.
19
+ */
20
+
21
+ enum roffscale {
22
+ SCALE_CM, /* centimeters (c) */
23
+ SCALE_IN, /* inches (i) */
24
+ SCALE_PC, /* pica (P) */
25
+ SCALE_PT, /* points (p) */
26
+ SCALE_EM, /* ems (m) */
27
+ SCALE_MM, /* mini-ems (M) */
28
+ SCALE_EN, /* ens (n) */
29
+ SCALE_BU, /* default horizontal (u) */
30
+ SCALE_VS, /* default vertical (v) */
31
+ SCALE_FS, /* syn. for u (f) */
32
+ SCALE_MAX
33
+ };
34
+
35
+ struct roffcol {
36
+ size_t width; /* width of cell */
37
+ size_t nwidth; /* max. width of number in cell */
38
+ size_t decimal; /* decimal position in cell */
39
+ size_t spacing; /* spacing after the column */
40
+ int flags; /* layout flags, see tbl_cell */
41
+ };
42
+
43
+ struct roffsu {
44
+ enum roffscale unit;
45
+ double scale;
46
+ };
47
+
48
+ typedef size_t (*tbl_sulen)(const struct roffsu *, void *);
49
+ typedef size_t (*tbl_strlen)(const char *, void *);
50
+ typedef size_t (*tbl_len)(size_t, void *);
51
+
52
+ struct rofftbl {
53
+ tbl_sulen sulen; /* calculate scaling unit length */
54
+ tbl_strlen slen; /* calculate string length */
55
+ tbl_len len; /* produce width of empty space */
56
+ struct roffcol *cols; /* master column specifiers */
57
+ void *arg; /* passed to sulen, slen, and len */
58
+ };
59
+
60
+ #define SCALE_HS_INIT(p, v) \
61
+ do { (p)->unit = SCALE_EN; \
62
+ (p)->scale = (v); } \
63
+ while (/* CONSTCOND */ 0)
64
+
65
+
66
+ struct tbl_span;
67
+
68
+ const char *a2roffsu(const char *, struct roffsu *, enum roffscale);
69
+ void tblcalc(struct rofftbl *,
70
+ const struct tbl_span *, size_t, size_t);