1 /* $Vendor-Id: term_ascii.c,v 1.11 2011/01/02 12:21:07 kristaps Exp $ */ 2 /* 3 * Copyright (c) 2010 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 #ifdef HAVE_CONFIG_H 18 #include "config.h" 19 #endif 20 21 #include <sys/types.h> 22 23 #include <assert.h> 24 #include <stdint.h> 25 #include <stdio.h> 26 #include <stdlib.h> 27 #include <unistd.h> 28 29 #include "mandoc.h" 30 #include "out.h" 31 #include "term.h" 32 #include "main.h" 33 34 static double ascii_hspan(const struct termp *, 35 const struct roffsu *); 36 static size_t ascii_width(const struct termp *, char); 37 static void ascii_advance(struct termp *, size_t); 38 static void ascii_begin(struct termp *); 39 static void ascii_end(struct termp *); 40 static void ascii_endline(struct termp *); 41 static void ascii_letter(struct termp *, char); 42 43 44 void * 45 ascii_alloc(char *outopts) 46 { 47 struct termp *p; 48 const char *toks[2]; 49 char *v; 50 51 if (NULL == (p = term_alloc(TERMENC_ASCII))) 52 return(NULL); 53 54 p->tabwidth = 5; 55 p->defrmargin = 78; 56 57 p->advance = ascii_advance; 58 p->begin = ascii_begin; 59 p->end = ascii_end; 60 p->endline = ascii_endline; 61 p->hspan = ascii_hspan; 62 p->letter = ascii_letter; 63 p->type = TERMTYPE_CHAR; 64 p->width = ascii_width; 65 66 toks[0] = "width"; 67 toks[1] = NULL; 68 69 while (outopts && *outopts) 70 switch (getsubopt(&outopts, UNCONST(toks), &v)) { 71 case (0): 72 p->defrmargin = (size_t)atoi(v); 73 break; 74 default: 75 break; 76 } 77 78 /* Enforce a lower boundary. */ 79 if (p->defrmargin < 58) 80 p->defrmargin = 58; 81 82 return(p); 83 } 84 85 86 /* ARGSUSED */ 87 static size_t 88 ascii_width(const struct termp *p, char c) 89 { 90 91 return(1); 92 } 93 94 95 void 96 ascii_free(void *arg) 97 { 98 99 term_free((struct termp *)arg); 100 } 101 102 103 /* ARGSUSED */ 104 static void 105 ascii_letter(struct termp *p, char c) 106 { 107 108 /* LINTED */ 109 putchar(c); 110 } 111 112 113 static void 114 ascii_begin(struct termp *p) 115 { 116 117 (*p->headf)(p, p->argf); 118 } 119 120 121 static void 122 ascii_end(struct termp *p) 123 { 124 125 (*p->footf)(p, p->argf); 126 } 127 128 129 /* ARGSUSED */ 130 static void 131 ascii_endline(struct termp *p) 132 { 133 134 putchar('\n'); 135 } 136 137 138 /* ARGSUSED */ 139 static void 140 ascii_advance(struct termp *p, size_t len) 141 { 142 size_t i; 143 144 /* Just print whitespace on the terminal. */ 145 for (i = 0; i < len; i++) 146 putchar(' '); 147 } 148 149 150 /* ARGSUSED */ 151 static double 152 ascii_hspan(const struct termp *p, const struct roffsu *su) 153 { 154 double r; 155 156 /* 157 * Approximate based on character width. These are generated 158 * entirely by eyeballing the screen, but appear to be correct. 159 */ 160 161 switch (su->unit) { 162 case (SCALE_CM): 163 r = 4 * su->scale; 164 break; 165 case (SCALE_IN): 166 r = 10 * su->scale; 167 break; 168 case (SCALE_PC): 169 r = (10 * su->scale) / 6; 170 break; 171 case (SCALE_PT): 172 r = (10 * su->scale) / 72; 173 break; 174 case (SCALE_MM): 175 r = su->scale / 1000; 176 break; 177 case (SCALE_VS): 178 r = su->scale * 2 - 1; 179 break; 180 default: 181 r = su->scale; 182 break; 183 } 184 185 return(r); 186 } 187 188