version 1.1, 2009/03/19 16:17:27 |
version 1.4, 2009/03/20 22:01:07 |
|
|
|
|
#include "term.h" |
#include "term.h" |
|
|
|
#ifdef __linux__ |
|
extern size_t strlcpy(char *, const char *, size_t); |
|
extern size_t strlcat(char *, const char *, size_t); |
|
#endif |
|
|
static struct termp *termp_alloc(enum termenc); |
static struct termp *termp_alloc(enum termenc); |
static void termp_free(struct termp *); |
static void termp_free(struct termp *); |
static void termp_body(struct termp *, struct termpair *, |
static void termp_body(struct termp *, struct termpair *, |
Line 76 terminal_run(void *arg, const struct mdoc *mdoc) |
|
Line 81 terminal_run(void *arg, const struct mdoc *mdoc) |
|
p = (struct termp *)arg; |
p = (struct termp *)arg; |
|
|
if (NULL == p->symtab) |
if (NULL == p->symtab) |
p->symtab = ascii2htab(); |
p->symtab = term_ascii2htab(); |
|
|
termp_head(p, mdoc_meta(mdoc)); |
termp_head(p, mdoc_meta(mdoc)); |
termp_body(p, NULL, mdoc_meta(mdoc), mdoc_node(mdoc)); |
termp_body(p, NULL, mdoc_meta(mdoc), mdoc_node(mdoc)); |
Line 101 termp_free(struct termp *p) |
|
Line 106 termp_free(struct termp *p) |
|
if (p->buf) |
if (p->buf) |
free(p->buf); |
free(p->buf); |
if (TERMENC_ASCII == p->enc && p->symtab) |
if (TERMENC_ASCII == p->enc && p->symtab) |
asciifree(p->symtab); |
term_asciifree(p->symtab); |
|
|
free(p); |
free(p); |
} |
} |
Line 156 termp_alloc(enum termenc enc) |
|
Line 161 termp_alloc(enum termenc enc) |
|
* possible). |
* possible). |
*/ |
*/ |
void |
void |
flushln(struct termp *p) |
term_flushln(struct termp *p) |
{ |
{ |
int i, j; |
int i, j; |
size_t vsz, vis, maxvis, mmax, bp; |
size_t vsz, vis, maxvis, mmax, bp; |
Line 217 flushln(struct termp *p) |
|
Line 222 flushln(struct termp *p) |
|
for (j = 0; j < (int)p->offset; j++) |
for (j = 0; j < (int)p->offset; j++) |
putchar(' '); |
putchar(' '); |
vis = 0; |
vis = 0; |
} else if (vis + vsz > bp) |
} |
warnx("word breaks right margin"); |
} else if (vis && vis + vsz > bp) { |
|
putchar('\n'); |
/* TODO: hyphenate. */ |
for (j = 0; j < (int)p->rmargin; j++) |
|
putchar(' '); |
} else { |
vis = p->rmargin - p->offset; |
if (vis && vis + vsz > bp) { |
|
putchar('\n'); |
|
for (j = 0; j < (int)p->rmargin; j++) |
|
putchar(' '); |
|
vis = p->rmargin - p->offset; |
|
} else if (vis + vsz > bp) |
|
warnx("word breaks right margin"); |
|
|
|
/* TODO: hyphenate. */ |
|
} |
} |
|
|
/* |
/* |
Line 289 flushln(struct termp *p) |
|
Line 285 flushln(struct termp *p) |
|
* assertion. |
* assertion. |
*/ |
*/ |
void |
void |
newln(struct termp *p) |
term_newln(struct termp *p) |
{ |
{ |
|
|
p->flags |= TERMP_NOSPACE; |
p->flags |= TERMP_NOSPACE; |
Line 297 newln(struct termp *p) |
|
Line 293 newln(struct termp *p) |
|
p->flags &= ~TERMP_NOLPAD; |
p->flags &= ~TERMP_NOLPAD; |
return; |
return; |
} |
} |
flushln(p); |
term_flushln(p); |
p->flags &= ~TERMP_NOLPAD; |
p->flags &= ~TERMP_NOLPAD; |
} |
} |
|
|
Line 309 newln(struct termp *p) |
|
Line 305 newln(struct termp *p) |
|
* assertion. |
* assertion. |
*/ |
*/ |
void |
void |
vspace(struct termp *p) |
term_vspace(struct termp *p) |
{ |
{ |
|
|
newln(p); |
term_newln(p); |
putchar('\n'); |
putchar('\n'); |
} |
} |
|
|
Line 324 vspace(struct termp *p) |
|
Line 320 vspace(struct termp *p) |
|
* the word and put it verbatim into the output buffer. |
* the word and put it verbatim into the output buffer. |
*/ |
*/ |
void |
void |
word(struct termp *p, const char *word) |
term_word(struct termp *p, const char *word) |
{ |
{ |
int i, j, len; |
int i, j, len; |
|
|
|
len = (int)strlen(word); |
|
|
if (p->flags & TERMP_LITERAL) { |
if (p->flags & TERMP_LITERAL) { |
termp_pword(p, word, (int)strlen(word)); |
termp_pword(p, word, len); |
return; |
return; |
} |
} |
|
|
if (0 == (len = (int)strlen(word))) |
|
errx(1, "blank line not in literal context"); |
|
|
|
if (mdoc_isdelim(word)) { |
if (mdoc_isdelim(word)) { |
if ( ! (p->flags & TERMP_IGNDELIM)) |
if ( ! (p->flags & TERMP_IGNDELIM)) |
p->flags |= TERMP_NOSPACE; |
p->flags |= TERMP_NOSPACE; |
Line 368 word(struct termp *p, const char *word) |
|
Line 363 word(struct termp *p, const char *word) |
|
} |
} |
|
|
|
|
|
static void |
|
termp_body(struct termp *p, struct termpair *ppair, |
|
const struct mdoc_meta *meta, |
|
const struct mdoc_node *node) |
|
{ |
|
|
|
term_node(p, ppair, meta, node); |
|
if (node->next) |
|
termp_body(p, ppair, meta, node->next); |
|
} |
|
|
|
|
/* |
/* |
* This is the main function for printing out nodes. It's constituted |
* This is the main function for printing out nodes. It's constituted |
* of PRE and POST functions, which correspond to prefix and infix |
* of PRE and POST functions, which correspond to prefix and infix |
* processing. The termpair structure allows data to persist between |
* processing. The termpair structure allows data to persist between |
* prefix and postfix invocations. |
* prefix and postfix invocations. |
*/ |
*/ |
static void |
void |
termp_body(struct termp *p, struct termpair *ppair, |
term_node(struct termp *p, struct termpair *ppair, |
const struct mdoc_meta *meta, |
const struct mdoc_meta *meta, |
const struct mdoc_node *node) |
const struct mdoc_node *node) |
{ |
{ |
Line 400 termp_body(struct termp *p, struct termpair *ppair, |
|
Line 407 termp_body(struct termp *p, struct termpair *ppair, |
|
if ( ! (*termacts[node->tok].pre)(p, &pair, meta, node)) |
if ( ! (*termacts[node->tok].pre)(p, &pair, meta, node)) |
dochild = 0; |
dochild = 0; |
} else /* MDOC_TEXT == node->type */ |
} else /* MDOC_TEXT == node->type */ |
word(p, node->string); |
term_word(p, node->string); |
|
|
/* Children. */ |
/* Children. */ |
|
|
Line 418 termp_body(struct termp *p, struct termpair *ppair, |
|
Line 425 termp_body(struct termp *p, struct termpair *ppair, |
|
if (MDOC_TEXT != node->type) |
if (MDOC_TEXT != node->type) |
if (termacts[node->tok].post) |
if (termacts[node->tok].post) |
(*termacts[node->tok].post)(p, &pair, meta, node); |
(*termacts[node->tok].post)(p, &pair, meta, node); |
|
|
/* Siblings. */ |
|
|
|
if (node->next) |
|
termp_body(p, ppair, meta, node->next); |
|
} |
} |
|
|
|
|
Line 455 termp_foot(struct termp *p, const struct mdoc_meta *me |
|
Line 457 termp_foot(struct termp *p, const struct mdoc_meta *me |
|
* OS MDOCDATE |
* OS MDOCDATE |
*/ |
*/ |
|
|
vspace(p); |
term_vspace(p); |
|
|
p->flags |= TERMP_NOSPACE | TERMP_NOBREAK; |
p->flags |= TERMP_NOSPACE | TERMP_NOBREAK; |
p->rmargin = p->maxrmargin - strlen(buf); |
p->rmargin = p->maxrmargin - strlen(buf); |
p->offset = 0; |
p->offset = 0; |
|
|
word(p, os); |
term_word(p, os); |
flushln(p); |
term_flushln(p); |
|
|
p->flags |= TERMP_NOLPAD | TERMP_NOSPACE; |
p->flags |= TERMP_NOLPAD | TERMP_NOSPACE; |
p->offset = p->rmargin; |
p->offset = p->rmargin; |
p->rmargin = p->maxrmargin; |
p->rmargin = p->maxrmargin; |
p->flags &= ~TERMP_NOBREAK; |
p->flags &= ~TERMP_NOBREAK; |
|
|
word(p, buf); |
term_word(p, buf); |
flushln(p); |
term_flushln(p); |
|
|
free(buf); |
free(buf); |
free(os); |
free(os); |
Line 519 termp_head(struct termp *p, const struct mdoc_meta *me |
|
Line 521 termp_head(struct termp *p, const struct mdoc_meta *me |
|
p->rmargin = (p->maxrmargin - strlen(buf)) / 2; |
p->rmargin = (p->maxrmargin - strlen(buf)) / 2; |
p->flags |= TERMP_NOBREAK | TERMP_NOSPACE; |
p->flags |= TERMP_NOBREAK | TERMP_NOSPACE; |
|
|
word(p, title); |
term_word(p, title); |
flushln(p); |
term_flushln(p); |
|
|
p->flags |= TERMP_NOLPAD | TERMP_NOSPACE; |
p->flags |= TERMP_NOLPAD | TERMP_NOSPACE; |
p->offset = p->rmargin; |
p->offset = p->rmargin; |
p->rmargin = p->maxrmargin - strlen(title); |
p->rmargin = p->maxrmargin - strlen(title); |
|
|
word(p, buf); |
term_word(p, buf); |
flushln(p); |
term_flushln(p); |
|
|
p->offset = p->rmargin; |
p->offset = p->rmargin; |
p->rmargin = p->maxrmargin; |
p->rmargin = p->maxrmargin; |
p->flags &= ~TERMP_NOBREAK; |
p->flags &= ~TERMP_NOBREAK; |
p->flags |= TERMP_NOLPAD | TERMP_NOSPACE; |
p->flags |= TERMP_NOLPAD | TERMP_NOSPACE; |
|
|
word(p, title); |
term_word(p, title); |
flushln(p); |
term_flushln(p); |
|
|
p->rmargin = p->maxrmargin; |
p->rmargin = p->maxrmargin; |
p->offset = 0; |
p->offset = 0; |
Line 557 termp_nescape(struct termp *p, const char *word, size_ |
|
Line 559 termp_nescape(struct termp *p, const char *word, size_ |
|
const char *rhs; |
const char *rhs; |
size_t sz; |
size_t sz; |
|
|
if (NULL == (rhs = a2ascii(p->symtab, word, len, &sz))) |
if (NULL == (rhs = term_a2ascii(p->symtab, word, len, &sz))) |
return; |
return; |
termp_stringa(p, rhs, sz); |
termp_stringa(p, rhs, sz); |
} |
} |
Line 632 termp_pword(struct termp *p, const char *word, int len |
|
Line 634 termp_pword(struct termp *p, const char *word, int len |
|
{ |
{ |
int i; |
int i; |
|
|
if ( ! (TERMP_NOSPACE & p->flags) && |
if ( ! (TERMP_NOSPACE & p->flags)) |
! (TERMP_LITERAL & p->flags)) |
|
termp_chara(p, ' '); |
termp_chara(p, ' '); |
|
|
if ( ! (p->flags & TERMP_NONOSPACE)) |
if ( ! (p->flags & TERMP_NONOSPACE)) |