From 65f8ae861f5855669ce4473e9c89a5a2003a89ac Mon Sep 17 00:00:00 2001 From: Kristaps Dzonsons Date: Sat, 7 Nov 2009 08:26:45 +0000 Subject: Initial abstraction of front-end decoration events (special characters, text decorations, etc.). --- out.c | 194 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- out.h | 14 ++++- 2 files changed, 206 insertions(+), 2 deletions(-) diff --git a/out.c b/out.c index e92a5842..307af614 100644 --- a/out.c +++ b/out.c @@ -1,4 +1,4 @@ -/* $Id: out.c,v 1.7 2009/10/22 18:59:00 kristaps Exp $ */ +/* $Id: out.c,v 1.8 2009/11/07 08:26:45 kristaps Exp $ */ /* * Copyright (c) 2009 Kristaps Dzonsons * @@ -166,3 +166,195 @@ time2a(time_t t, char *dst, size_t sz) (void)strftime(p, sz, "%Y", &tm); } + +/* Returns length of parsed string. */ +int +a2roffdeco(enum roffdeco *d, + const char **word, size_t *sz) +{ + int j, type, sv, t, lim; + const char *wp; + + *d = DECO_NONE; + + wp = *word; + type = 1; + + switch (*wp) { + case ('\0'): + return(0); + + case ('('): + wp++; + if ('\0' == *wp) + return(1); + if ('\0' == *(wp + 1)) + return(2); + + *d = DECO_SPECIAL; + *sz = 2; + *word = wp; + return(3); + + case ('*'): + wp++; + + switch (*wp) { + case ('\0'): + return(1); + + case ('('): + wp++; + if ('\0' == *wp) + return(2); + if ('\0' == *(wp + 1)) + return(3); + + *d = DECO_RESERVED; + *sz = 2; + *word = wp; + return(4); + + case ('['): + type = 0; + break; + + default: + *d = DECO_RESERVED; + *sz = 1; + *word = wp; + return(3); + } + break; + +#if 0 + case ('s'): + wp++; + + /* This closely follows mandoc_special(). */ + if ('\0' == *wp) + return(1); + + t = 0; + lim = 1; + + if (*wp == '\'') { + lim = 0; + t = 1; + ++wp; + } else if (*wp == '[') { + lim = 0; + t = 2; + ++wp; + } else if (*wp == '(') { + lim = 2; + t = 3; + ++wp; + } + + if (*wp == '+' || *wp == '-') + ++wp; + + if (*wp == '\'') { + if (t) { + *word = wp; + return; + } + lim = 0; + t = 1; + ++wp; + } else if (*wp == '[') { + if (t) { + *word = wp; + return; + } + lim = 0; + t = 2; + ++wp; + } else if (*wp == '(') { + if (t) { + *word = wp; + return; + } + lim = 2; + t = 3; + ++wp; + } + + if ( ! isdigit((u_char)*wp)) { + *word = --wp; + return; + } + + for (j = 0; isdigit((u_char)*wp); j++) { + if (lim && j >= lim) + break; + ++wp; + } + + if (t && t < 3) { + if (1 == t && *wp != '\'') { + *word = --wp; + return; + } + if (2 == t && *wp != ']') { + *word = --wp; + return; + } + ++wp; + } + *word = --wp; + return; +#endif + + case ('f'): + wp++; + + switch (*wp) { + case ('\0'): + return(1); + case ('3'): + /* FALLTHROUGH */ + case ('B'): + *d = DECO_BOLD; + break; + case ('2'): + /* FALLTHROUGH */ + case ('I'): + *d = DECO_ITALIC; + break; + case ('P'): + *d = DECO_PREVIOUS; + break; + case ('1'): + /* FALLTHROUGH */ + case ('R'): + *d = DECO_ROMAN; + break; + default: + break; + } + + return(2); + + case ('['): + break; + + default: + *d = DECO_SPECIAL; + *word = wp; + *sz = 1; + return(1); + } + + *word = ++wp; + for (j = 0; *wp && ']' != *wp; wp++, j++) + /* Loop... */ ; + + if ('\0' == *wp) + return(j + 1); + + *d = type ? DECO_SPECIAL : DECO_RESERVED; + *sz = j; + return (j + 2); +} diff --git a/out.h b/out.h index eb589afb..baebab08 100644 --- a/out.h +++ b/out.h @@ -1,4 +1,4 @@ -/* $Id: out.h,v 1.6 2009/10/22 18:55:33 kristaps Exp $ */ +/* $Id: out.h,v 1.7 2009/11/07 08:26:45 kristaps Exp $ */ /* * Copyright (c) 2009 Kristaps Dzonsons * @@ -35,6 +35,17 @@ enum roffscale { SCALE_MAX }; +enum roffdeco { + DECO_NONE, + DECO_SPECIAL, + DECO_RESERVED, + DECO_BOLD, + DECO_ITALIC, + DECO_ROMAN, + DECO_PREVIOUS, + DECO_MAX +}; + struct roffsu { enum roffscale unit; double scale; @@ -54,6 +65,7 @@ struct roffsu { int a2roffsu(const char *, struct roffsu *, enum roffscale); +int a2roffdeco(enum roffdeco *, const char **, size_t *); void time2a(time_t, char *, size_t); __END_DECLS -- cgit v1.2.3-56-ge451