diff options
-rw-r--r-- | html.c | 8 | ||||
-rw-r--r-- | libmandoc.h | 21 | ||||
-rw-r--r-- | libmdoc.h | 20 | ||||
-rw-r--r-- | mandoc.c | 50 | ||||
-rw-r--r-- | mandoc.h | 18 | ||||
-rw-r--r-- | mdoc.c | 44 | ||||
-rw-r--r-- | mdoc.h | 2 | ||||
-rw-r--r-- | mdoc_argv.c | 4 | ||||
-rw-r--r-- | mdoc_html.c | 25 | ||||
-rw-r--r-- | mdoc_macro.c | 71 | ||||
-rw-r--r-- | mdoc_term.c | 32 | ||||
-rw-r--r-- | term.c | 7 |
12 files changed, 172 insertions, 130 deletions
@@ -508,15 +508,10 @@ print_doctype(struct html *h) name, doctype, dtd); } - void print_text(struct html *h, const char *word) { - if (DELIM_CLOSE == mandoc_isdelim(word)) - if ( ! (HTML_IGNDELIM & h->flags)) - h->flags |= HTML_NOSPACE; - if ( ! (HTML_NOSPACE & h->flags)) { /* Manage keeps! */ if ( ! (HTML_KEEP & h->flags)) { @@ -544,9 +539,6 @@ print_text(struct html *h, const char *word) } h->flags &= ~HTML_IGNDELIM; - - if (DELIM_OPEN == mandoc_isdelim(word)) - h->flags |= HTML_NOSPACE; } diff --git a/libmandoc.h b/libmandoc.h index c11232d9..a8e6c4ae 100644 --- a/libmandoc.h +++ b/libmandoc.h @@ -29,17 +29,15 @@ enum rofferr { ROFF_ERR /* badness: puke and stop */ }; -/* - * Available registers (set in libroff, accessed elsewhere). - */ enum regs { - REG_nS = 0, + REG_nS = 0, /* nS register */ REG__MAX }; /* * A register (struct reg) can consist of many types: this consists of - * normalised types from the original string form. + * normalised types from the original string form. For the time being, + * there's only an unsigned integer type. */ union regval { unsigned u; /* unsigned integer */ @@ -76,9 +74,9 @@ void mandoc_msg(enum mandocerr, struct mparse *, void mandoc_vmsg(enum mandocerr, struct mparse *, int, int, const char *, ...); int mandoc_special(char *); -char *mandoc_strdup(const char *); -char *mandoc_getarg(struct mparse *, char **, int, int *); -char *mandoc_normdate(struct mparse *, char *, int, int); +char *mandoc_strdup(const char *); +char *mandoc_getarg(struct mparse *, char **, int, int *); +char *mandoc_normdate(struct mparse *, char *, int, int); int mandoc_eos(const char *, size_t, int); int mandoc_hyph(const char *, const char *); @@ -103,11 +101,10 @@ struct roff *roff_alloc(struct regset *, struct mparse *); void roff_reset(struct roff *); enum rofferr roff_parseln(struct roff *, int, char **, size_t *, int, int *); -void roff_endparse(struct roff *); - -const struct tbl_span *roff_span(const struct roff *); -const struct eqn *roff_eqn(const struct roff *); +void roff_endparse(struct roff *); +const struct tbl_span *roff_span(const struct roff *); +const struct eqn *roff_eqn(const struct roff *); __END_DECLS @@ -80,6 +80,23 @@ enum margverr { ARGV_WORD }; +/* + * A punctuation delimiter is opening, closing, or "middle mark" + * punctuation. These govern spacing. + * Opening punctuation (e.g., the opening parenthesis) suppresses the + * following space; closing punctuation (e.g., the closing parenthesis) + * suppresses the leading space; middle punctuation (e.g., the vertical + * bar) can do either. The middle punctuation delimiter bends the rules + * depending on usage. + */ +enum mdelim { + DELIM_NONE = 0, + DELIM_OPEN, + DELIM_MIDDLE, + DELIM_CLOSE, + DELIM_MAX +}; + extern const struct mdoc_macro *const mdoc_macros; __BEGIN_DECLS @@ -126,6 +143,9 @@ enum margserr mdoc_zargs(struct mdoc *, int, int mdoc_macroend(struct mdoc *); +#define DELIMSZ 6 /* hint: max possible size of a delimiter */ +enum mdelim mdoc_isdelim(const char *); + __END_DECLS #endif /*!LIBMDOC_H*/ @@ -506,53 +506,3 @@ mandoc_hyph(const char *start, const char *c) return(1); } -/* - * Check if a string is a punctuation delimiter. This only applies to - * mdoc(7) documents, but as it's used in both front-ends and back-ends, - * it needs to go here (instead of, say, in libmdoc.h). - */ -enum mdelim -mandoc_isdelim(const char *p) -{ - - if ('\0' == p[0]) - return(DELIM_NONE); - - if ('\0' == p[1]) - switch (p[0]) { - case('('): - /* FALLTHROUGH */ - case('['): - return(DELIM_OPEN); - case('|'): - return(DELIM_MIDDLE); - case('.'): - /* FALLTHROUGH */ - case(','): - /* FALLTHROUGH */ - case(';'): - /* FALLTHROUGH */ - case(':'): - /* FALLTHROUGH */ - case('?'): - /* FALLTHROUGH */ - case('!'): - /* FALLTHROUGH */ - case(')'): - /* FALLTHROUGH */ - case(']'): - return(DELIM_CLOSE); - default: - return(DELIM_NONE); - } - - if ('\\' != p[0]) - return(DELIM_NONE); - - if (0 == strcmp(p + 1, ".")) - return(DELIM_CLOSE); - if (0 == strcmp(p + 1, "*(Ba")) - return(DELIM_MIDDLE); - - return(DELIM_NONE); -} @@ -278,22 +278,6 @@ struct eqn { }; /* - * A punctuation delimiter, used only in mdoc(7) documents, is opening, - * closing, or "middle mark" punctuation. These govern spacing. - * Opening punctuation (e.g., the opening parenthesis) suppresses the - * following space; closing punctuation (e.g., the closing parenthesis) - * suppresses the leading space; middle punctuation (e.g., the vertical - * bar) can do either. The middle punctuation delimiter bends the rules - * depending on usage. - */ -enum mdelim { - DELIM_NONE = 0, - DELIM_OPEN, - DELIM_MIDDLE, - DELIM_CLOSE -}; - -/* * The type of parse sequence. This value is usually passed via the * mandoc(1) command line of -man and -mdoc. It's almost exclusively * -mandoc but the others have been retained for compatibility. @@ -323,8 +307,6 @@ void mparse_result(struct mparse *, struct mdoc **, struct man **); void *mandoc_calloc(size_t, size_t); void *mandoc_malloc(size_t); void *mandoc_realloc(void *, size_t); -#define DELIMSZ 6 /* hint: max possible size of a delimiter */ -enum mdelim mandoc_isdelim(const char *); __END_DECLS @@ -911,4 +911,48 @@ err: /* Error out. */ return(0); } +enum mdelim +mdoc_isdelim(const char *p) +{ + + if ('\0' == p[0]) + return(DELIM_NONE); + + if ('\0' == p[1]) + switch (p[0]) { + case('('): + /* FALLTHROUGH */ + case('['): + return(DELIM_OPEN); + case('|'): + return(DELIM_MIDDLE); + case('.'): + /* FALLTHROUGH */ + case(','): + /* FALLTHROUGH */ + case(';'): + /* FALLTHROUGH */ + case(':'): + /* FALLTHROUGH */ + case('?'): + /* FALLTHROUGH */ + case('!'): + /* FALLTHROUGH */ + case(')'): + /* FALLTHROUGH */ + case(']'): + return(DELIM_CLOSE); + default: + return(DELIM_NONE); + } + + if ('\\' != p[0]) + return(DELIM_NONE); + if (0 == strcmp(p + 1, ".")) + return(DELIM_CLOSE); + if (0 == strcmp(p + 1, "*(Ba")) + return(DELIM_MIDDLE); + + return(DELIM_NONE); +} @@ -357,6 +357,8 @@ struct mdoc_node { #define MDOC_LINE (1 << 3) /* first macro/text on line */ #define MDOC_SYNPRETTY (1 << 4) /* SYNOPSIS-style formatting */ #define MDOC_ENDED (1 << 5) /* rendering has been ended */ +#define MDOC_DELIMO (1 << 6) +#define MDOC_DELIMC (1 << 7) enum mdoc_type type; /* AST node type */ enum mdoc_sec sec; /* current named section */ union mdoc_data *norm; /* normalised args */ diff --git a/mdoc_argv.c b/mdoc_argv.c index 38e91639..e5c06db8 100644 --- a/mdoc_argv.c +++ b/mdoc_argv.c @@ -557,7 +557,7 @@ args_checkpunct(struct mdoc *m, const char *buf, int i, int ln, int fl) return(0); dbuf[j] = '\0'; - if (DELIM_CLOSE != mandoc_isdelim(dbuf)) + if (DELIM_CLOSE != mdoc_isdelim(dbuf)) return(0); while (' ' == buf[i]) @@ -574,7 +574,7 @@ args_checkpunct(struct mdoc *m, const char *buf, int i, int ln, int fl) return(0); dbuf[j] = '\0'; - d = mandoc_isdelim(dbuf); + d = mdoc_isdelim(dbuf); if (DELIM_NONE == d || DELIM_OPEN == d) return(0); diff --git a/mdoc_html.c b/mdoc_html.c index 19bf848e..1dc7ecbd 100644 --- a/mdoc_html.c +++ b/mdoc_html.c @@ -431,7 +431,11 @@ print_mdoc_node(MDOC_ARGS) if (' ' == *n->string && MDOC_LINE & n->flags) if ( ! (HTML_LITERAL & h->flags)) print_otag(h, TAG_BR, 0, NULL); + if (MDOC_DELIMC & n->flags) + h->flags |= HTML_NOSPACE; print_text(h, n->string); + if (MDOC_DELIMO & n->flags) + h->flags |= HTML_NOSPACE; return; case (MDOC_EQN): PAIR_CLASS_INIT(&tag, "eqn"); @@ -1381,12 +1385,16 @@ mdoc_fa_pre(MDOC_ARGS) t = print_otag(h, TAG_I, 1, &tag); print_text(h, nn->string); print_tagq(h, t); - if (nn->next) + if (nn->next) { + h->flags |= HTML_NOSPACE; print_text(h, ","); + } } - if (n->child && n->next && n->next->tok == MDOC_Fa) + if (n->child && n->next && n->next->tok == MDOC_Fa) { + h->flags |= HTML_NOSPACE; print_text(h, ","); + } return(0); } @@ -1514,13 +1522,19 @@ mdoc_fn_pre(MDOC_ARGS) t = print_otag(h, TAG_I, i, tag); print_text(h, nn->string); print_tagq(h, t); - if (nn->next) + if (nn->next) { + h->flags |= HTML_NOSPACE; print_text(h, ","); + } } + h->flags |= HTML_NOSPACE; print_text(h, ")"); - if (MDOC_SYNPRETTY & n->flags) + + if (MDOC_SYNPRETTY & n->flags) { + h->flags |= HTML_NOSPACE; print_text(h, ";"); + } return(0); } @@ -1671,7 +1685,9 @@ mdoc_fo_post(MDOC_ARGS) if (MDOC_BODY != n->type) return; + h->flags |= HTML_NOSPACE; print_text(h, ")"); + h->flags |= HTML_NOSPACE; print_text(h, ";"); } @@ -2032,6 +2048,7 @@ mdoc__x_post(MDOC_ARGS) if (NULL == n->parent || MDOC_Rs != n->parent->tok) return; + h->flags |= HTML_NOSPACE; print_text(h, n->next ? "," : "."); } diff --git a/mdoc_macro.c b/mdoc_macro.c index aee2cad3..f012cfc7 100644 --- a/mdoc_macro.c +++ b/mdoc_macro.c @@ -50,6 +50,8 @@ static int in_line(MACRO_PROT_ARGS); static int obsolete(MACRO_PROT_ARGS); static int phrase_ta(MACRO_PROT_ARGS); +static int dword(struct mdoc *, int, int, + const char *, enum mdelim); static int append_delims(struct mdoc *, int, int *, char *); static enum mdoct lookup(enum mdoct, const char *); @@ -580,6 +582,28 @@ rew_sub(enum mdoc_type t, struct mdoc *m, return(1); } +/* + * Allocate a word and check whether it's punctuation or not. + * Punctuation consists of those tokens found in mdoc_isdelim(). + */ +static int +dword(struct mdoc *m, int line, + int col, const char *p, enum mdelim d) +{ + + if (DELIM_MAX == d) + d = mdoc_isdelim(p); + + if ( ! mdoc_word_alloc(m, line, col, p)) + return(0); + + if (DELIM_OPEN == d) + m->last->flags |= MDOC_DELIMO; + else if (DELIM_CLOSE == d) + m->last->flags |= MDOC_DELIMC; + + return(1); +} static int append_delims(struct mdoc *m, int line, int *pos, char *buf) @@ -600,9 +624,7 @@ append_delims(struct mdoc *m, int line, int *pos, char *buf) else if (ARGS_EOLN == ac) break; - assert(DELIM_NONE != mandoc_isdelim(p)); - if ( ! mdoc_word_alloc(m, line, la, p)) - return(0); + dword(m, line, la, p, DELIM_MAX); /* * If we encounter end-of-sentence symbols, then trigger @@ -746,7 +768,7 @@ blk_exp_close(MACRO_PROT_ARGS) ntok = ARGS_QWORD == ac ? MDOC_MAX : lookup(tok, p); if (MDOC_MAX == ntok) { - if ( ! mdoc_word_alloc(m, line, lastarg, p)) + if ( ! dword(m, line, lastarg, p, DELIM_MAX)) return(0); continue; } @@ -870,7 +892,7 @@ in_line(MACRO_PROT_ARGS) * the word. */ - d = ARGS_QWORD == ac ? DELIM_NONE : mandoc_isdelim(p); + d = ARGS_QWORD == ac ? DELIM_NONE : mdoc_isdelim(p); if (DELIM_NONE != d) { /* @@ -905,7 +927,8 @@ in_line(MACRO_PROT_ARGS) if (DELIM_NONE == d) cnt++; - if ( ! mdoc_word_alloc(m, line, la, p)) + + if ( ! dword(m, line, la, p, d)) return(0); /* @@ -1060,8 +1083,8 @@ blk_full(MACRO_PROT_ARGS) ARGS_PHRASE != ac && ARGS_PPHRASE != ac && ARGS_QWORD != ac && - DELIM_OPEN == mandoc_isdelim(p)) { - if ( ! mdoc_word_alloc(m, line, la, p)) + DELIM_OPEN == mdoc_isdelim(p)) { + if ( ! dword(m, line, la, p, DELIM_OPEN)) return(0); continue; } @@ -1113,7 +1136,7 @@ blk_full(MACRO_PROT_ARGS) ntok = ARGS_QWORD == ac ? MDOC_MAX : lookup(tok, p); if (MDOC_MAX == ntok) { - if ( ! mdoc_word_alloc(m, line, la, p)) + if ( ! dword(m, line, la, p, DELIM_MAX)) return(0); continue; } @@ -1223,8 +1246,8 @@ blk_part_imp(MACRO_PROT_ARGS) break; if (NULL == body && ARGS_QWORD != ac && - DELIM_OPEN == mandoc_isdelim(p)) { - if ( ! mdoc_word_alloc(m, line, la, p)) + DELIM_OPEN == mdoc_isdelim(p)) { + if ( ! dword(m, line, la, p, DELIM_OPEN)) return(0); continue; } @@ -1238,7 +1261,7 @@ blk_part_imp(MACRO_PROT_ARGS) ntok = ARGS_QWORD == ac ? MDOC_MAX : lookup(tok, p); if (MDOC_MAX == ntok) { - if ( ! mdoc_word_alloc(m, line, la, p)) + if ( ! dword(m, line, la, p, DELIM_MAX)) return(0); continue; } @@ -1354,9 +1377,9 @@ blk_part_exp(MACRO_PROT_ARGS) /* Flush out leading punctuation. */ if (NULL == head && ARGS_QWORD != ac && - DELIM_OPEN == mandoc_isdelim(p)) { + DELIM_OPEN == mdoc_isdelim(p)) { assert(NULL == body); - if ( ! mdoc_word_alloc(m, line, la, p)) + if ( ! dword(m, line, la, p, DELIM_OPEN)) return(0); continue; } @@ -1377,7 +1400,7 @@ blk_part_exp(MACRO_PROT_ARGS) assert(head); /* No check whether it's a macro! */ if (MDOC_Eo == tok) - if ( ! mdoc_word_alloc(m, line, la, p)) + if ( ! dword(m, line, la, p, DELIM_MAX)) return(0); if ( ! rew_sub(MDOC_HEAD, m, tok, line, ppos)) @@ -1395,7 +1418,7 @@ blk_part_exp(MACRO_PROT_ARGS) ntok = ARGS_QWORD == ac ? MDOC_MAX : lookup(tok, p); if (MDOC_MAX == ntok) { - if ( ! mdoc_word_alloc(m, line, la, p)) + if ( ! dword(m, line, la, p, DELIM_MAX)) return(0); continue; } @@ -1500,9 +1523,9 @@ in_line_argn(MACRO_PROT_ARGS) break; if ( ! (MDOC_IGNDELIM & mdoc_macros[tok].flags) && - ARGS_QWORD != ac && - 0 == j && DELIM_OPEN == mandoc_isdelim(p)) { - if ( ! mdoc_word_alloc(m, line, la, p)) + ARGS_QWORD != ac && 0 == j && + DELIM_OPEN == mdoc_isdelim(p)) { + if ( ! dword(m, line, la, p, DELIM_OPEN)) return(0); continue; } else if (0 == j) @@ -1530,7 +1553,7 @@ in_line_argn(MACRO_PROT_ARGS) if ( ! (MDOC_IGNDELIM & mdoc_macros[tok].flags) && ARGS_QWORD != ac && ! flushed && - DELIM_NONE != mandoc_isdelim(p)) { + DELIM_NONE != mdoc_isdelim(p)) { if ( ! rew_elem(m, tok)) return(0); flushed = 1; @@ -1552,7 +1575,7 @@ in_line_argn(MACRO_PROT_ARGS) } #endif - if ( ! mdoc_word_alloc(m, line, la, p)) + if ( ! dword(m, line, la, p, DELIM_MAX)) return(0); j++; } @@ -1623,7 +1646,7 @@ in_line_eoln(MACRO_PROT_ARGS) ntok = ARGS_QWORD == ac ? MDOC_MAX : lookup(tok, p); if (MDOC_MAX == ntok) { - if ( ! mdoc_word_alloc(m, line, la, p)) + if ( ! dword(m, line, la, p, DELIM_MAX)) return(0); continue; } @@ -1703,7 +1726,7 @@ phrase(struct mdoc *m, int line, int ppos, char *buf) ntok = ARGS_QWORD == ac ? MDOC_MAX : lookup_raw(p); if (MDOC_MAX == ntok) { - if ( ! mdoc_word_alloc(m, line, la, p)) + if ( ! dword(m, line, la, p, DELIM_MAX)) return(0); continue; } @@ -1748,7 +1771,7 @@ phrase_ta(MACRO_PROT_ARGS) ntok = ARGS_QWORD == ac ? MDOC_MAX : lookup_raw(p); if (MDOC_MAX == ntok) { - if ( ! mdoc_word_alloc(m, line, la, p)) + if ( ! dword(m, line, la, p, DELIM_MAX)) return(0); continue; } diff --git a/mdoc_term.c b/mdoc_term.c index 16bfcd4a..47d121c3 100644 --- a/mdoc_term.c +++ b/mdoc_term.c @@ -351,7 +351,11 @@ print_mdoc_node(DECL_ARGS) case (MDOC_TEXT): if (' ' == *n->string && MDOC_LINE & n->flags) term_newln(p); + if (MDOC_DELIMC & n->flags) + p->flags |= TERMP_NOSPACE; term_word(p, n->string); + if (MDOC_DELIMO & n->flags) + p->flags |= TERMP_NOSPACE; break; case (MDOC_EQN): term_word(p, n->eqn->data); @@ -1302,7 +1306,9 @@ termp_xr_pre(DECL_ARGS) return(0); p->flags |= TERMP_NOSPACE; term_word(p, "("); + p->flags |= TERMP_NOSPACE; term_word(p, nn->string); + p->flags |= TERMP_NOSPACE; term_word(p, ")"); return(0); @@ -1532,20 +1538,26 @@ termp_fn_pre(DECL_ARGS) p->flags |= TERMP_NOSPACE; term_word(p, "("); + p->flags |= TERMP_NOSPACE; for (nn = n->child->next; nn; nn = nn->next) { term_fontpush(p, TERMFONT_UNDER); term_word(p, nn->string); term_fontpop(p); - if (nn->next) + if (nn->next) { + p->flags |= TERMP_NOSPACE; term_word(p, ","); + } } + p->flags |= TERMP_NOSPACE; term_word(p, ")"); - if (MDOC_SYNPRETTY & n->flags) + if (MDOC_SYNPRETTY & n->flags) { + p->flags |= TERMP_NOSPACE; term_word(p, ";"); + } return(0); } @@ -1567,12 +1579,16 @@ termp_fa_pre(DECL_ARGS) term_word(p, nn->string); term_fontpop(p); - if (nn->next) + if (nn->next) { + p->flags |= TERMP_NOSPACE; term_word(p, ","); + } } - if (n->child && n->next && n->next->tok == MDOC_Fa) + if (n->child && n->next && n->next->tok == MDOC_Fa) { + p->flags |= TERMP_NOSPACE; term_word(p, ","); + } return(0); } @@ -2007,6 +2023,7 @@ termp_fo_pre(DECL_ARGS) } else if (MDOC_BODY == n->type) { p->flags |= TERMP_NOSPACE; term_word(p, "("); + p->flags |= TERMP_NOSPACE; return(1); } @@ -2030,10 +2047,13 @@ termp_fo_post(DECL_ARGS) if (MDOC_BODY != n->type) return; + p->flags |= TERMP_NOSPACE; term_word(p, ")"); - if (MDOC_SYNPRETTY & n->flags) + if (MDOC_SYNPRETTY & n->flags) { + p->flags |= TERMP_NOSPACE; term_word(p, ";"); + } } @@ -2107,6 +2127,7 @@ termp____post(DECL_ARGS) if (NULL == n->parent || MDOC_Rs != n->parent->tok) return; + p->flags |= TERMP_NOSPACE; if (NULL == n->next) { term_word(p, "."); p->flags |= TERMP_SENTENCE; @@ -2143,6 +2164,7 @@ termp_lk_pre(DECL_ARGS) term_fontpop(p); + p->flags |= TERMP_NOSPACE; term_word(p, ":"); term_fontpush(p, TERMFONT_BOLD); @@ -462,10 +462,6 @@ term_word(struct termp *p, const char *word) sv = word; - if (DELIM_CLOSE == mandoc_isdelim(word)) - if ( ! (TERMP_IGNDELIM & p->flags)) - p->flags |= TERMP_NOSPACE; - if ( ! (TERMP_NOSPACE & p->flags)) { if ( ! (TERMP_KEEP & p->flags)) { if (TERMP_PREKEEP & p->flags) @@ -526,9 +522,6 @@ term_word(struct termp *p, const char *word) if (DECO_NOSPACE == deco && '\0' == *word) p->flags |= TERMP_NOSPACE; } - - if (DELIM_OPEN == mandoc_isdelim(sv)) - p->flags |= TERMP_NOSPACE; } |