Return to term_ascii.c CVS log | Up to [cvsweb.bsd.lv] / mandoc |
version 1.6, 2010/06/25 19:50:23 | version 1.15, 2011/05/17 22:32:45 | ||
---|---|---|---|
|
|
||
/* $Id$ */ | /* $Id$ */ | ||
/* | /* | ||
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@bsd.lv> | * Copyright (c) 2010 Kristaps Dzonsons <kristaps@bsd.lv> | ||
* | * | ||
* Permission to use, copy, modify, and distribute this software for any | * Permission to use, copy, modify, and distribute this software for any | ||
* purpose with or without fee is hereby granted, provided that the above | * purpose with or without fee is hereby granted, provided that the above | ||
|
|
||
#include <sys/types.h> | #include <sys/types.h> | ||
#include <assert.h> | #include <assert.h> | ||
#ifdef USE_WCHAR | |||
# include <locale.h> | |||
#endif | |||
#include <stdint.h> | #include <stdint.h> | ||
#include <stdio.h> | #include <stdio.h> | ||
#include <stdlib.h> | #include <stdlib.h> | ||
#include <unistd.h> | #include <unistd.h> | ||
#ifdef USE_WCHAR | |||
# include <wchar.h> | |||
#endif | |||
#include "mandoc.h" | |||
#include "out.h" | #include "out.h" | ||
#include "term.h" | #include "term.h" | ||
#include "main.h" | #include "main.h" | ||
static void ascii_endline(struct termp *); | #if ! defined(__STDC_ISO_10646__) | ||
static void ascii_letter(struct termp *, char); | # undef USE_WCHAR | ||
static void ascii_begin(struct termp *); | #endif | ||
static struct termp *ascii_init(enum termenc, char *); | |||
static double ascii_hspan(const struct termp *, | |||
const struct roffsu *); | |||
static size_t ascii_width(const struct termp *, int); | |||
static void ascii_advance(struct termp *, size_t); | static void ascii_advance(struct termp *, size_t); | ||
static void ascii_begin(struct termp *); | |||
static void ascii_end(struct termp *); | static void ascii_end(struct termp *); | ||
static size_t ascii_width(const struct termp *, char); | static void ascii_endline(struct termp *); | ||
static void ascii_letter(struct termp *, int); | |||
#ifdef USE_WCHAR | |||
static void locale_advance(struct termp *, size_t); | |||
static void locale_endline(struct termp *); | |||
static void locale_letter(struct termp *, int); | |||
static size_t locale_width(const struct termp *, int); | |||
#endif | |||
void * | static struct termp * | ||
ascii_alloc(char *outopts) | ascii_init(enum termenc enc, char *outopts) | ||
{ | { | ||
struct termp *p; | |||
const char *toks[2]; | const char *toks[2]; | ||
char *v; | char *v; | ||
struct termp *p; | |||
if (NULL == (p = term_alloc(TERMENC_ASCII))) | p = mandoc_calloc(1, sizeof(struct termp)); | ||
return(NULL); | p->enc = enc; | ||
p->tabwidth = 5; | p->tabwidth = 5; | ||
p->defrmargin = 78; | p->defrmargin = 78; | ||
p->type = TERMTYPE_CHAR; | |||
p->letter = ascii_letter; | |||
p->begin = ascii_begin; | p->begin = ascii_begin; | ||
p->end = ascii_end; | p->end = ascii_end; | ||
p->endline = ascii_endline; | p->hspan = ascii_hspan; | ||
p->type = TERMTYPE_CHAR; | |||
p->enc = TERMENC_ASCII; | |||
p->advance = ascii_advance; | p->advance = ascii_advance; | ||
p->endline = ascii_endline; | |||
p->letter = ascii_letter; | |||
p->width = ascii_width; | p->width = ascii_width; | ||
#if defined (USE_WCHAR) | |||
if (TERMENC_LOCALE == enc) | |||
if (setlocale(LC_ALL, "") && MB_CUR_MAX > 1) { | |||
p->enc = enc; | |||
p->advance = locale_advance; | |||
p->endline = locale_endline; | |||
p->letter = locale_letter; | |||
p->width = locale_width; | |||
} | |||
#endif | |||
toks[0] = "width"; | toks[0] = "width"; | ||
toks[1] = NULL; | toks[1] = NULL; | ||
|
|
||
return(p); | return(p); | ||
} | } | ||
void * | |||
ascii_alloc(char *outopts) | |||
{ | |||
return(ascii_init(TERMENC_ASCII, outopts)); | |||
} | |||
void * | |||
locale_alloc(char *outopts) | |||
{ | |||
return(ascii_init(TERMENC_LOCALE, outopts)); | |||
} | |||
/* ARGSUSED */ | /* ARGSUSED */ | ||
static size_t | static size_t | ||
ascii_width(const struct termp *p, char c) | ascii_width(const struct termp *p, int c) | ||
{ | { | ||
return(1); | return(1); | ||
} | } | ||
void | void | ||
ascii_free(void *arg) | ascii_free(void *arg) | ||
{ | { | ||
|
|
||
term_free((struct termp *)arg); | term_free((struct termp *)arg); | ||
} | } | ||
/* ARGSUSED */ | /* ARGSUSED */ | ||
static void | static void | ||
ascii_letter(struct termp *p, char c) | ascii_letter(struct termp *p, int c) | ||
{ | { | ||
putchar(c); | putchar(c); | ||
} | } | ||
static void | static void | ||
ascii_begin(struct termp *p) | ascii_begin(struct termp *p) | ||
{ | { | ||
|
|
||
(*p->headf)(p, p->argf); | (*p->headf)(p, p->argf); | ||
} | } | ||
static void | static void | ||
ascii_end(struct termp *p) | ascii_end(struct termp *p) | ||
{ | { | ||
|
|
||
(*p->footf)(p, p->argf); | (*p->footf)(p, p->argf); | ||
} | } | ||
/* ARGSUSED */ | /* ARGSUSED */ | ||
static void | static void | ||
ascii_endline(struct termp *p) | ascii_endline(struct termp *p) | ||
|
|
||
putchar('\n'); | putchar('\n'); | ||
} | } | ||
/* ARGSUSED */ | /* ARGSUSED */ | ||
static void | static void | ||
ascii_advance(struct termp *p, size_t len) | ascii_advance(struct termp *p, size_t len) | ||
{ | { | ||
size_t i; | size_t i; | ||
/* Just print whitespace on the terminal. */ | |||
for (i = 0; i < len; i++) | for (i = 0; i < len; i++) | ||
putchar(' '); | putchar(' '); | ||
} | } | ||
/* ARGSUSED */ | |||
static double | |||
ascii_hspan(const struct termp *p, const struct roffsu *su) | |||
{ | |||
double r; | |||
/* | |||
* Approximate based on character width. These are generated | |||
* entirely by eyeballing the screen, but appear to be correct. | |||
*/ | |||
switch (su->unit) { | |||
case (SCALE_CM): | |||
r = 4 * su->scale; | |||
break; | |||
case (SCALE_IN): | |||
r = 10 * su->scale; | |||
break; | |||
case (SCALE_PC): | |||
r = (10 * su->scale) / 6; | |||
break; | |||
case (SCALE_PT): | |||
r = (10 * su->scale) / 72; | |||
break; | |||
case (SCALE_MM): | |||
r = su->scale / 1000; | |||
break; | |||
case (SCALE_VS): | |||
r = su->scale * 2 - 1; | |||
break; | |||
default: | |||
r = su->scale; | |||
break; | |||
} | |||
return(r); | |||
} | |||
#ifdef USE_WCHAR | |||
/* ARGSUSED */ | |||
static size_t | |||
locale_width(const struct termp *p, int c) | |||
{ | |||
int rc; | |||
return((rc = wcwidth(c)) < 0 ? 0 : rc); | |||
} | |||
/* ARGSUSED */ | |||
static void | |||
locale_advance(struct termp *p, size_t len) | |||
{ | |||
size_t i; | |||
for (i = 0; i < len; i++) | |||
putwchar(L' '); | |||
} | |||
/* ARGSUSED */ | |||
static void | |||
locale_endline(struct termp *p) | |||
{ | |||
putwchar(L'\n'); | |||
} | |||
/* ARGSUSED */ | |||
static void | |||
locale_letter(struct termp *p, int c) | |||
{ | |||
putwchar(c); | |||
} | |||
#endif |