xref: /openbsd/usr.bin/mandoc/term_ascii.c (revision 2791bd1c)
1*2791bd1cSschwarze /*	$Id: term_ascii.c,v 1.4 2011/01/04 22:28:17 schwarze Exp $ */
2f95d589eSschwarze /*
3769ee804Sschwarze  * Copyright (c) 2010 Kristaps Dzonsons <kristaps@bsd.lv>
4f95d589eSschwarze  *
5f95d589eSschwarze  * Permission to use, copy, modify, and distribute this software for any
6f95d589eSschwarze  * purpose with or without fee is hereby granted, provided that the above
7f95d589eSschwarze  * copyright notice and this permission notice appear in all copies.
8f95d589eSschwarze  *
9f95d589eSschwarze  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10f95d589eSschwarze  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11f95d589eSschwarze  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12f95d589eSschwarze  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13f95d589eSschwarze  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14f95d589eSschwarze  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15f95d589eSschwarze  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16f95d589eSschwarze  */
17f95d589eSschwarze #include <sys/types.h>
18f95d589eSschwarze 
19f95d589eSschwarze #include <assert.h>
20f95d589eSschwarze #include <stdint.h>
21f95d589eSschwarze #include <stdio.h>
22f95d589eSschwarze #include <stdlib.h>
23f95d589eSschwarze #include <unistd.h>
24f95d589eSschwarze 
25*2791bd1cSschwarze #include "mandoc.h"
26f95d589eSschwarze #include "out.h"
27f95d589eSschwarze #include "term.h"
28f95d589eSschwarze #include "main.h"
29f95d589eSschwarze 
30769ee804Sschwarze static	double		  ascii_hspan(const struct termp *,
31769ee804Sschwarze 				const struct roffsu *);
32769ee804Sschwarze static	size_t		  ascii_width(const struct termp *, char);
33769ee804Sschwarze static	void		  ascii_advance(struct termp *, size_t);
34769ee804Sschwarze static	void		  ascii_begin(struct termp *);
35769ee804Sschwarze static	void		  ascii_end(struct termp *);
36f95d589eSschwarze static	void		  ascii_endline(struct termp *);
37f95d589eSschwarze static	void		  ascii_letter(struct termp *, char);
38f95d589eSschwarze 
39f95d589eSschwarze 
40f95d589eSschwarze void *
41f95d589eSschwarze ascii_alloc(char *outopts)
42f95d589eSschwarze {
43f95d589eSschwarze 	struct termp	*p;
44f95d589eSschwarze 	const char	*toks[2];
45f95d589eSschwarze 	char		*v;
46f95d589eSschwarze 
47f95d589eSschwarze 	if (NULL == (p = term_alloc(TERMENC_ASCII)))
48f95d589eSschwarze 		return(NULL);
49f95d589eSschwarze 
503ebeb861Sschwarze 	p->tabwidth = 5;
513ebeb861Sschwarze 	p->defrmargin = 78;
523ebeb861Sschwarze 
53769ee804Sschwarze 	p->advance = ascii_advance;
54f95d589eSschwarze 	p->begin = ascii_begin;
55f95d589eSschwarze 	p->end = ascii_end;
56f95d589eSschwarze 	p->endline = ascii_endline;
57769ee804Sschwarze 	p->hspan = ascii_hspan;
58769ee804Sschwarze 	p->letter = ascii_letter;
59769ee804Sschwarze 	p->type = TERMTYPE_CHAR;
603ebeb861Sschwarze 	p->width = ascii_width;
61f95d589eSschwarze 
62f95d589eSschwarze 	toks[0] = "width";
63f95d589eSschwarze 	toks[1] = NULL;
64f95d589eSschwarze 
65f95d589eSschwarze 	while (outopts && *outopts)
66f95d589eSschwarze 		switch (getsubopt(&outopts, UNCONST(toks), &v)) {
67f95d589eSschwarze 		case (0):
68f95d589eSschwarze 			p->defrmargin = (size_t)atoi(v);
69f95d589eSschwarze 			break;
70f95d589eSschwarze 		default:
71f95d589eSschwarze 			break;
72f95d589eSschwarze 		}
73f95d589eSschwarze 
74f95d589eSschwarze 	/* Enforce a lower boundary. */
75f95d589eSschwarze 	if (p->defrmargin < 58)
76f95d589eSschwarze 		p->defrmargin = 58;
77f95d589eSschwarze 
78f95d589eSschwarze 	return(p);
79f95d589eSschwarze }
80f95d589eSschwarze 
81f95d589eSschwarze 
82769ee804Sschwarze /* ARGSUSED */
833ebeb861Sschwarze static size_t
843ebeb861Sschwarze ascii_width(const struct termp *p, char c)
853ebeb861Sschwarze {
863ebeb861Sschwarze 
873ebeb861Sschwarze 	return(1);
883ebeb861Sschwarze }
893ebeb861Sschwarze 
903ebeb861Sschwarze 
91f95d589eSschwarze void
92f95d589eSschwarze ascii_free(void *arg)
93f95d589eSschwarze {
94f95d589eSschwarze 
95f95d589eSschwarze 	term_free((struct termp *)arg);
96f95d589eSschwarze }
97f95d589eSschwarze 
98f95d589eSschwarze 
99f95d589eSschwarze /* ARGSUSED */
100f95d589eSschwarze static void
101f95d589eSschwarze ascii_letter(struct termp *p, char c)
102f95d589eSschwarze {
103f95d589eSschwarze 
104f95d589eSschwarze 	putchar(c);
105f95d589eSschwarze }
106f95d589eSschwarze 
107f95d589eSschwarze 
108f95d589eSschwarze static void
109f95d589eSschwarze ascii_begin(struct termp *p)
110f95d589eSschwarze {
111f95d589eSschwarze 
112f95d589eSschwarze 	(*p->headf)(p, p->argf);
113f95d589eSschwarze }
114f95d589eSschwarze 
115f95d589eSschwarze 
116f95d589eSschwarze static void
117f95d589eSschwarze ascii_end(struct termp *p)
118f95d589eSschwarze {
119f95d589eSschwarze 
120f95d589eSschwarze 	(*p->footf)(p, p->argf);
121f95d589eSschwarze }
122f95d589eSschwarze 
123f95d589eSschwarze 
124f95d589eSschwarze /* ARGSUSED */
125f95d589eSschwarze static void
126f95d589eSschwarze ascii_endline(struct termp *p)
127f95d589eSschwarze {
128f95d589eSschwarze 
129f95d589eSschwarze 	putchar('\n');
130f95d589eSschwarze }
131f95d589eSschwarze 
132f95d589eSschwarze 
133f95d589eSschwarze /* ARGSUSED */
134f95d589eSschwarze static void
135f95d589eSschwarze ascii_advance(struct termp *p, size_t len)
136f95d589eSschwarze {
137f95d589eSschwarze 	size_t	 	i;
138f95d589eSschwarze 
139f95d589eSschwarze 	/* Just print whitespace on the terminal. */
140f95d589eSschwarze 	for (i = 0; i < len; i++)
141f95d589eSschwarze 		putchar(' ');
142f95d589eSschwarze }
143769ee804Sschwarze 
144769ee804Sschwarze 
145769ee804Sschwarze /* ARGSUSED */
146769ee804Sschwarze static double
147769ee804Sschwarze ascii_hspan(const struct termp *p, const struct roffsu *su)
148769ee804Sschwarze {
149769ee804Sschwarze 	double		 r;
150769ee804Sschwarze 
151769ee804Sschwarze 	/*
152769ee804Sschwarze 	 * Approximate based on character width.  These are generated
153769ee804Sschwarze 	 * entirely by eyeballing the screen, but appear to be correct.
154769ee804Sschwarze 	 */
155769ee804Sschwarze 
156769ee804Sschwarze 	switch (su->unit) {
157769ee804Sschwarze 	case (SCALE_CM):
158769ee804Sschwarze 		r = 4 * su->scale;
159769ee804Sschwarze 		break;
160769ee804Sschwarze 	case (SCALE_IN):
161769ee804Sschwarze 		r = 10 * su->scale;
162769ee804Sschwarze 		break;
163769ee804Sschwarze 	case (SCALE_PC):
164769ee804Sschwarze 		r = (10 * su->scale) / 6;
165769ee804Sschwarze 		break;
166769ee804Sschwarze 	case (SCALE_PT):
167769ee804Sschwarze 		r = (10 * su->scale) / 72;
168769ee804Sschwarze 		break;
169769ee804Sschwarze 	case (SCALE_MM):
170769ee804Sschwarze 		r = su->scale / 1000;
171769ee804Sschwarze 		break;
172769ee804Sschwarze 	case (SCALE_VS):
173769ee804Sschwarze 		r = su->scale * 2 - 1;
174769ee804Sschwarze 		break;
175769ee804Sschwarze 	default:
176769ee804Sschwarze 		r = su->scale;
177769ee804Sschwarze 		break;
178769ee804Sschwarze 	}
179769ee804Sschwarze 
180769ee804Sschwarze 	return(r);
181769ee804Sschwarze }
182769ee804Sschwarze 
183