Annotation of mandoc/term_ascii.c, Revision 1.27
1.27 ! schwarze 1: /* $Id: term_ascii.c,v 1.26 2014/07/27 21:52:16 schwarze Exp $ */
1.1 kristaps 2: /*
1.18 schwarze 3: * Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
1.23 schwarze 4: * Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org>
1.1 kristaps 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: #ifdef HAVE_CONFIG_H
19: #include "config.h"
20: #endif
21:
22: #include <sys/types.h>
23:
1.15 kristaps 24: #ifdef USE_WCHAR
25: # include <locale.h>
26: #endif
1.1 kristaps 27: #include <stdint.h>
28: #include <stdio.h>
29: #include <stdlib.h>
1.2 kristaps 30: #include <unistd.h>
1.15 kristaps 31: #ifdef USE_WCHAR
32: # include <wchar.h>
33: #endif
1.1 kristaps 34:
1.11 kristaps 35: #include "mandoc.h"
1.22 schwarze 36: #include "mandoc_aux.h"
1.1 kristaps 37: #include "out.h"
38: #include "term.h"
39: #include "main.h"
40:
1.16 kristaps 41: /*
42: * Sadly, this doesn't seem to be defined on systems even when they
43: * support it. For the time being, remove it and let those compiling
44: * the software decide for themselves what to use.
45: */
46: #if 0
1.15 kristaps 47: #if ! defined(__STDC_ISO_10646__)
48: # undef USE_WCHAR
1.16 kristaps 49: #endif
1.15 kristaps 50: #endif
51:
1.14 kristaps 52: static struct termp *ascii_init(enum termenc, char *);
1.8 kristaps 53: static double ascii_hspan(const struct termp *,
1.7 kristaps 54: const struct roffsu *);
1.13 kristaps 55: static size_t ascii_width(const struct termp *, int);
1.7 kristaps 56: static void ascii_advance(struct termp *, size_t);
57: static void ascii_begin(struct termp *);
58: static void ascii_end(struct termp *);
1.1 kristaps 59: static void ascii_endline(struct termp *);
1.13 kristaps 60: static void ascii_letter(struct termp *, int);
1.24 schwarze 61: static void ascii_setwidth(struct termp *, int, size_t);
1.1 kristaps 62:
1.15 kristaps 63: #ifdef USE_WCHAR
64: static void locale_advance(struct termp *, size_t);
65: static void locale_endline(struct termp *);
66: static void locale_letter(struct termp *, int);
67: static size_t locale_width(const struct termp *, int);
68: #endif
69:
1.25 schwarze 70:
1.14 kristaps 71: static struct termp *
72: ascii_init(enum termenc enc, char *outopts)
1.1 kristaps 73: {
1.20 schwarze 74: const char *toks[4];
1.1 kristaps 75: char *v;
1.14 kristaps 76: struct termp *p;
1.1 kristaps 77:
1.14 kristaps 78: p = mandoc_calloc(1, sizeof(struct termp));
1.1 kristaps 79:
1.5 kristaps 80: p->tabwidth = 5;
1.23 schwarze 81: p->defrmargin = p->lastrmargin = 78;
1.5 kristaps 82:
1.1 kristaps 83: p->begin = ascii_begin;
84: p->end = ascii_end;
1.15 kristaps 85: p->hspan = ascii_hspan;
86: p->type = TERMTYPE_CHAR;
87:
88: p->enc = TERMENC_ASCII;
89: p->advance = ascii_advance;
1.1 kristaps 90: p->endline = ascii_endline;
1.7 kristaps 91: p->letter = ascii_letter;
1.23 schwarze 92: p->setwidth = ascii_setwidth;
1.5 kristaps 93: p->width = ascii_width;
1.1 kristaps 94:
1.17 kristaps 95: #ifdef USE_WCHAR
96: if (TERMENC_ASCII != enc) {
97: v = TERMENC_LOCALE == enc ?
1.25 schwarze 98: setlocale(LC_ALL, "") :
99: setlocale(LC_CTYPE, "en_US.UTF-8");
1.17 kristaps 100: if (NULL != v && MB_CUR_MAX > 1) {
1.15 kristaps 101: p->enc = enc;
102: p->advance = locale_advance;
103: p->endline = locale_endline;
104: p->letter = locale_letter;
105: p->width = locale_width;
106: }
1.17 kristaps 107: }
1.15 kristaps 108: #endif
109:
1.19 schwarze 110: toks[0] = "indent";
111: toks[1] = "width";
1.20 schwarze 112: toks[2] = "mdoc";
113: toks[3] = NULL;
1.1 kristaps 114:
115: while (outopts && *outopts)
116: switch (getsubopt(&outopts, UNCONST(toks), &v)) {
1.25 schwarze 117: case 0:
1.19 schwarze 118: p->defindent = (size_t)atoi(v);
119: break;
1.25 schwarze 120: case 1:
1.1 kristaps 121: p->defrmargin = (size_t)atoi(v);
1.20 schwarze 122: break;
1.25 schwarze 123: case 2:
1.20 schwarze 124: /*
125: * Temporary, undocumented mode
126: * to imitate mdoc(7) output style.
127: */
128: p->mdocstyle = 1;
129: p->defindent = 5;
1.1 kristaps 130: break;
131: default:
132: break;
133: }
134:
135: /* Enforce a lower boundary. */
136: if (p->defrmargin < 58)
137: p->defrmargin = 58;
138:
139: return(p);
1.5 kristaps 140: }
141:
1.14 kristaps 142: void *
143: ascii_alloc(char *outopts)
144: {
145:
146: return(ascii_init(TERMENC_ASCII, outopts));
147: }
1.17 kristaps 148:
149: void *
150: utf8_alloc(char *outopts)
151: {
152:
153: return(ascii_init(TERMENC_UTF8, outopts));
154: }
155:
1.14 kristaps 156: void *
157: locale_alloc(char *outopts)
158: {
159:
160: return(ascii_init(TERMENC_LOCALE, outopts));
1.23 schwarze 161: }
162:
163: static void
1.24 schwarze 164: ascii_setwidth(struct termp *p, int iop, size_t width)
1.23 schwarze 165: {
166:
1.24 schwarze 167: p->rmargin = p->defrmargin;
168: if (0 < iop)
169: p->defrmargin += width;
170: else if (0 > iop)
171: p->defrmargin -= width;
172: else
173: p->defrmargin = width ? width : p->lastrmargin;
174: p->lastrmargin = p->rmargin;
175: p->rmargin = p->maxrmargin = p->defrmargin;
1.14 kristaps 176: }
1.5 kristaps 177:
178: static size_t
1.13 kristaps 179: ascii_width(const struct termp *p, int c)
1.5 kristaps 180: {
181:
182: return(1);
1.1 kristaps 183: }
184:
185: void
186: ascii_free(void *arg)
187: {
188:
189: term_free((struct termp *)arg);
190: }
191:
192: static void
1.13 kristaps 193: ascii_letter(struct termp *p, int c)
1.1 kristaps 194: {
1.25 schwarze 195:
1.1 kristaps 196: putchar(c);
197: }
198:
199: static void
200: ascii_begin(struct termp *p)
201: {
202:
203: (*p->headf)(p, p->argf);
204: }
205:
206: static void
207: ascii_end(struct termp *p)
208: {
209:
210: (*p->footf)(p, p->argf);
211: }
212:
213: static void
214: ascii_endline(struct termp *p)
215: {
216:
217: putchar('\n');
218: }
219:
220: static void
221: ascii_advance(struct termp *p, size_t len)
222: {
1.25 schwarze 223: size_t i;
1.1 kristaps 224:
225: for (i = 0; i < len; i++)
226: putchar(' ');
227: }
1.7 kristaps 228:
1.8 kristaps 229: static double
1.7 kristaps 230: ascii_hspan(const struct termp *p, const struct roffsu *su)
231: {
232: double r;
233:
234: /*
235: * Approximate based on character width. These are generated
236: * entirely by eyeballing the screen, but appear to be correct.
237: */
238:
239: switch (su->unit) {
1.25 schwarze 240: case SCALE_CM:
1.27 ! schwarze 241: r = su->scale * 4.0;
1.7 kristaps 242: break;
1.25 schwarze 243: case SCALE_IN:
1.27 ! schwarze 244: r = su->scale * 10.0;
1.7 kristaps 245: break;
1.25 schwarze 246: case SCALE_PC:
1.27 ! schwarze 247: r = (su->scale * 10.0) / 6.0;
1.7 kristaps 248: break;
1.25 schwarze 249: case SCALE_PT:
1.27 ! schwarze 250: r = (su->scale * 10.0) / 72.0;
1.7 kristaps 251: break;
1.25 schwarze 252: case SCALE_MM:
1.27 ! schwarze 253: r = su->scale / 1000.0;
1.7 kristaps 254: break;
1.25 schwarze 255: case SCALE_VS:
1.27 ! schwarze 256: r = su->scale * 2.0 - 1.0;
1.7 kristaps 257: break;
258: default:
259: r = su->scale;
260: break;
261: }
262:
1.8 kristaps 263: return(r);
1.7 kristaps 264: }
265:
1.15 kristaps 266: #ifdef USE_WCHAR
267: static size_t
268: locale_width(const struct termp *p, int c)
269: {
270: int rc;
271:
1.26 schwarze 272: if (c == ASCII_NBRSP)
273: c = ' ';
274: rc = wcwidth(c);
275: if (rc < 0)
276: rc = 0;
277: return(rc);
1.15 kristaps 278: }
279:
280: static void
281: locale_advance(struct termp *p, size_t len)
282: {
1.25 schwarze 283: size_t i;
1.15 kristaps 284:
285: for (i = 0; i < len; i++)
286: putwchar(L' ');
287: }
288:
289: static void
290: locale_endline(struct termp *p)
291: {
292:
293: putwchar(L'\n');
294: }
295:
296: static void
297: locale_letter(struct termp *p, int c)
298: {
1.25 schwarze 299:
1.15 kristaps 300: putwchar(c);
301: }
302: #endif
CVSweb