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