diff options
-rw-r--r-- | mandoc.1 | 43 | ||||
-rw-r--r-- | mdoc.h | 2 | ||||
-rw-r--r-- | private.h | 1 | ||||
-rw-r--r-- | term.c | 47 | ||||
-rw-r--r-- | terminal.c | 163 | ||||
-rw-r--r-- | validate.c | 2 |
6 files changed, 186 insertions, 72 deletions
@@ -88,6 +88,45 @@ were provided. .Pp .Ex -std mandoc .\" SUB-SECTION +.Ss Reserved Words +The reserved words described in +.Xr mdoc 7 +are handled according to the following rules: +.Bl -enum -offset XXX +.It +Opening delimiters +.Po +.Sq \&( , +.Sq \&[ , +and +.Sq \&{ +.Pc are not followed by whitespace. +.It +Closing delimiters +.Po +.Sq \&. , +.Sq \&, , +.Sq \&; , +.Sq \&: , +.Sq \&? , +.Sq \&! , +.Sq \&) , +.Sq \&] +and +.Sq \&} +.Pc are not preceeded by whitespace. +.El +.\" PARAGRAPH +.Pp +Note that reserved words may occur in streams of text, so the following: +.Bd -literal -offset XXXX +this self is not that of the waking , empirically real man +.Ed +.\" PARAGRAPH +.Pp +\&...correctly adjusts the comma spacing to +.Qq this self is not that of the waking , empirically real man . +.\" SUB-SECTION .Ss Output Formats The .Nm @@ -160,10 +199,6 @@ displays types are synonyms, as are \-filled and \-ragged. The .Sq \&Xo/Xc pair isn't supported. -.It -The -.Sq \&Sm -macro has no effect, yet. .El .Pp Other macros still aren't supported by virtue of nobody complaining @@ -322,8 +322,6 @@ const char *mdoc_a2att(const char *); const char *mdoc_a2lib(const char *); const char *mdoc_a2st(const char *); -int mdoc_isdelim(const char *); - __END_DECLS #endif /*!MDOC_H*/ @@ -117,6 +117,7 @@ void *mdoc_tokhash_alloc(void); int mdoc_tokhash_find(const void *, const char *); void mdoc_tokhash_free(void *); int mdoc_iscdelim(char); +int mdoc_isdelim(const char *); size_t mdoc_isescape(const char *); enum mdoc_sec mdoc_atosec(const char *); time_t mdoc_atotime(const char *); @@ -55,7 +55,7 @@ #define TTYPE_DIAG 18 #define TTYPE_LINK_ANCHOR 19 #define TTYPE_LINK_TEXT 20 -#define TTYPE_REF_TITLE 21 +#define TTYPE_REF_JOURNAL 21 #define TTYPE_NMAX 22 /* @@ -88,7 +88,7 @@ const int ttypes[TTYPE_NMAX] = { TERMP_BOLD, /* TTYPE_DIAG */ TERMP_UNDER, /* TTYPE_LINK_ANCHOR */ TERMP_BOLD, /* TTYPE_LINK_TEXT */ - TERMP_UNDER /* TTYPE_REF_TITLE */ + TERMP_UNDER /* TTYPE_REF_JOURNAL */ }; static int arg_hasattr(int, const struct mdoc_node *); @@ -118,6 +118,7 @@ static void name##_post(DECL_ARGS) DECL_PRE(name); \ DECL_POST(name); +DECL_PREPOST(termp__t); DECL_PREPOST(termp_aq); DECL_PREPOST(termp_bd); DECL_PREPOST(termp_bq); @@ -140,7 +141,7 @@ DECL_PREPOST(termp_ss); DECL_PREPOST(termp_sq); DECL_PREPOST(termp_vt); -DECL_PRE(termp__t); +DECL_PRE(termp__j); DECL_PRE(termp_ap); DECL_PRE(termp_ar); DECL_PRE(termp_at); @@ -227,12 +228,12 @@ const struct termact __termacts[MDOC_MAX] = { { NULL, termp____post }, /* %B */ { NULL, termp____post }, /* %D */ { NULL, termp____post }, /* %I */ - { NULL, termp____post }, /* %J */ + { termp__j_pre, termp____post }, /* %J */ { NULL, termp____post }, /* %N */ { NULL, termp____post }, /* %O */ { NULL, termp____post }, /* %P */ { NULL, termp____post }, /* %R */ - { termp__t_pre, termp____post }, /* %T */ + { termp__t_pre, termp__t_post }, /* %T */ { NULL, termp____post }, /* %V */ { NULL, NULL }, /* Ac */ { termp_aq_pre, termp_aq_post }, /* Ao */ @@ -1803,16 +1804,14 @@ static int termp_sm_pre(DECL_ARGS) { -#if notyet - assert(node->child); - if (0 == strcmp("off", node->child->data.text.string)) { + if (NULL == node->child || MDOC_TEXT != node->child->type) + errx(1, "expected boolean line argument"); + + if (0 == strcmp("on", node->child->string)) { p->flags &= ~TERMP_NONOSPACE; p->flags &= ~TERMP_NOSPACE; - } else { + } else p->flags |= TERMP_NONOSPACE; - p->flags |= TERMP_NOSPACE; - } -#endif return(0); } @@ -1832,16 +1831,38 @@ termp_ap_pre(DECL_ARGS) /* ARGSUSED */ static int +termp__j_pre(DECL_ARGS) +{ + + TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_REF_JOURNAL]); + return(1); +} + + +/* ARGSUSED */ +static int termp__t_pre(DECL_ARGS) { - TERMPAIR_SETFLAG(p, pair, ttypes[TTYPE_REF_TITLE]); + term_word(p, "\""); + p->flags |= TERMP_NOSPACE; return(1); } /* ARGSUSED */ static void +termp__t_post(DECL_ARGS) +{ + + p->flags |= TERMP_NOSPACE; + term_word(p, "\""); + termp____post(p, pair, meta, node); +} + + +/* ARGSUSED */ +static void termp____post(DECL_ARGS) { @@ -29,23 +29,25 @@ 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 void termp_free(struct termp *); -static void termp_body(struct termp *, struct termpair *, +static struct termp *term_alloc(enum termenc); +static void term_free(struct termp *); +static void term_body(struct termp *, struct termpair *, const struct mdoc_meta *, const struct mdoc_node *); -static void termp_head(struct termp *, +static void term_head(struct termp *, const struct mdoc_meta *); -static void termp_foot(struct termp *, +static void term_foot(struct termp *, const struct mdoc_meta *); -static void termp_pword(struct termp *, const char *, int); -static void termp_pescape(struct termp *, +static void term_pword(struct termp *, const char *, int); +static void term_pescape(struct termp *, const char *, int *, int); -static void termp_nescape(struct termp *, +static void term_nescape(struct termp *, const char *, size_t); -static void termp_chara(struct termp *, char); -static void termp_stringa(struct termp *, +static void term_chara(struct termp *, char); +static void term_stringa(struct termp *, const char *, size_t); +static int term_isopendelim(const char *, size_t); +static int term_isclosedelim(const char *, size_t); static void sanity(const struct mdoc_node *); /* XXX */ @@ -53,7 +55,7 @@ void * latin1_alloc(void) { - return(termp_alloc(TERMENC_LATIN1)); + return(term_alloc(TERMENC_LATIN1)); } @@ -61,7 +63,7 @@ void * utf8_alloc(void) { - return(termp_alloc(TERMENC_UTF8)); + return(term_alloc(TERMENC_UTF8)); } @@ -69,7 +71,7 @@ void * ascii_alloc(void) { - return(termp_alloc(TERMENC_ASCII)); + return(term_alloc(TERMENC_ASCII)); } @@ -83,9 +85,9 @@ terminal_run(void *arg, const struct mdoc *mdoc) if (NULL == p->symtab) p->symtab = term_ascii2htab(); - termp_head(p, mdoc_meta(mdoc)); - termp_body(p, NULL, mdoc_meta(mdoc), mdoc_node(mdoc)); - termp_foot(p, mdoc_meta(mdoc)); + term_head(p, mdoc_meta(mdoc)); + term_body(p, NULL, mdoc_meta(mdoc), mdoc_node(mdoc)); + term_foot(p, mdoc_meta(mdoc)); return(1); } @@ -95,12 +97,12 @@ void terminal_free(void *arg) { - termp_free((struct termp *)arg); + term_free((struct termp *)arg); } static void -termp_free(struct termp *p) +term_free(struct termp *p) { if (p->buf) @@ -113,7 +115,7 @@ termp_free(struct termp *p) static struct termp * -termp_alloc(enum termenc enc) +term_alloc(enum termenc enc) { struct termp *p; @@ -126,6 +128,62 @@ termp_alloc(enum termenc enc) } +static int +term_isclosedelim(const char *p, size_t len) +{ + + if (1 != len) + return(0); + + switch (*p) { + case('.'): + /* FALLTHROUGH */ + case(','): + /* FALLTHROUGH */ + case(';'): + /* FALLTHROUGH */ + case(':'): + /* FALLTHROUGH */ + case('?'): + /* FALLTHROUGH */ + case('!'): + /* FALLTHROUGH */ + case(')'): + /* FALLTHROUGH */ + case(']'): + /* FALLTHROUGH */ + case('}'): + return(1); + default: + break; + } + + return(0); +} + + +static int +term_isopendelim(const char *p, size_t len) +{ + + if (1 != len) + return(0); + + switch (*p) { + case('('): + /* FALLTHROUGH */ + case('['): + /* FALLTHROUGH */ + case('{'): + return(1); + default: + break; + } + + return(0); +} + + /* * Flush a line of text. A "line" is loosely defined as being something * that should be followed by a newline, regardless of whether it's @@ -327,16 +385,10 @@ term_word(struct termp *p, const char *word) len = (int)strlen(word); if (p->flags & TERMP_LITERAL) { - termp_pword(p, word, len); + term_pword(p, word, len); return; } - if (mdoc_isdelim(word)) { - if ( ! (p->flags & TERMP_IGNDELIM)) - p->flags |= TERMP_NOSPACE; - p->flags &= ~TERMP_IGNDELIM; - } - /* LINTED */ for (j = i = 0; i < len; i++) { if (' ' != word[i]) { @@ -353,25 +405,25 @@ term_word(struct termp *p, const char *word) if (0 == j) continue; assert(i >= j); - termp_pword(p, &word[i - j], j); + term_pword(p, &word[i - j], j); j = 0; } if (j > 0) { assert(i >= j); - termp_pword(p, &word[i - j], j); + term_pword(p, &word[i - j], j); } } static void -termp_body(struct termp *p, struct termpair *ppair, +term_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); + term_body(p, ppair, meta, node->next); } @@ -415,7 +467,7 @@ term_node(struct termp *p, struct termpair *ppair, p->flags |= pair.flag; if (dochild && node->child) - termp_body(p, &pair, meta, node->child); + term_body(p, &pair, meta, node->child); if (TERMPAIR_FLAG & pair.type) p->flags &= ~pair.flag; @@ -429,7 +481,7 @@ term_node(struct termp *p, struct termpair *ppair, static void -termp_foot(struct termp *p, const struct mdoc_meta *meta) +term_foot(struct termp *p, const struct mdoc_meta *meta) { struct tm *tm; char *buf, *os; @@ -480,7 +532,7 @@ termp_foot(struct termp *p, const struct mdoc_meta *meta) static void -termp_head(struct termp *p, const struct mdoc_meta *meta) +term_head(struct termp *p, const struct mdoc_meta *meta) { char *buf, *title; @@ -554,14 +606,14 @@ termp_head(struct termp *p, const struct mdoc_meta *meta) * output buffer by way of the symbol table. */ static void -termp_nescape(struct termp *p, const char *word, size_t len) +term_nescape(struct termp *p, const char *word, size_t len) { const char *rhs; size_t sz; if (NULL == (rhs = term_a2ascii(p->symtab, word, len, &sz))) return; - termp_stringa(p, rhs, sz); + term_stringa(p, rhs, sz); } @@ -571,7 +623,7 @@ termp_nescape(struct termp *p, const char *word, size_t len) * the escape sequence (we assert upon badly-formed escape sequences). */ static void -termp_pescape(struct termp *p, const char *word, int *i, int len) +term_pescape(struct termp *p, const char *word, int *i, int len) { int j; @@ -583,7 +635,7 @@ termp_pescape(struct termp *p, const char *word, int *i, int len) if (*i + 1 >= len) return; - termp_nescape(p, &word[*i], 2); + term_nescape(p, &word[*i], 2); (*i)++; return; @@ -598,18 +650,18 @@ termp_pescape(struct termp *p, const char *word, int *i, int len) if (*i + 1 >= len) return; - termp_nescape(p, &word[*i], 2); + term_nescape(p, &word[*i], 2); (*i)++; return; case ('['): break; default: - termp_nescape(p, &word[*i], 1); + term_nescape(p, &word[*i], 1); return; } } else if ('[' != word[*i]) { - termp_nescape(p, &word[*i], 1); + term_nescape(p, &word[*i], 1); return; } @@ -620,7 +672,7 @@ termp_pescape(struct termp *p, const char *word, int *i, int len) if (0 == word[*i]) return; - termp_nescape(p, &word[*i - j], (size_t)j); + term_nescape(p, &word[*i - j], (size_t)j); } @@ -630,12 +682,16 @@ termp_pescape(struct termp *p, const char *word, int *i, int len) * handles word styling. */ static void -termp_pword(struct termp *p, const char *word, int len) +term_pword(struct termp *p, const char *word, int len) { int i; + if (term_isclosedelim(word, len)) + if ( ! (TERMP_IGNDELIM & p->flags)) + p->flags |= TERMP_NOSPACE; + if ( ! (TERMP_NOSPACE & p->flags)) - termp_chara(p, ' '); + term_chara(p, ' '); if ( ! (p->flags & TERMP_NONOSPACE)) p->flags &= ~TERMP_NOSPACE; @@ -647,33 +703,36 @@ termp_pword(struct termp *p, const char *word, int len) for (i = 0; i < len; i++) { if ('\\' == word[i]) { - termp_pescape(p, word, &i, len); + term_pescape(p, word, &i, len); continue; } if (TERMP_STYLE & p->flags) { if (TERMP_BOLD & p->flags) { - termp_chara(p, word[i]); - termp_chara(p, 8); + term_chara(p, word[i]); + term_chara(p, 8); } if (TERMP_UNDER & p->flags) { - termp_chara(p, '_'); - termp_chara(p, 8); + term_chara(p, '_'); + term_chara(p, 8); } } - termp_chara(p, word[i]); + term_chara(p, word[i]); } + + if (term_isopendelim(word, len)) + p->flags |= TERMP_NOSPACE; } /* - * Like termp_chara() but for arbitrary-length buffers. Resize the + * Like term_chara() but for arbitrary-length buffers. Resize the * buffer by a factor of two (if the buffer is less than that) or the * buffer's size. */ static void -termp_stringa(struct termp *p, const char *c, size_t sz) +term_stringa(struct termp *p, const char *c, size_t sz) { size_t s; @@ -702,7 +761,7 @@ termp_stringa(struct termp *p, const char *c, size_t sz) * size. */ static void -termp_chara(struct termp *p, char c) +term_chara(struct termp *p, char c) { size_t s; @@ -265,7 +265,7 @@ const struct valids mdoc_valids[MDOC_MAX] = { { NULL, posts_wline }, /* Dq */ { NULL, NULL }, /* Ec */ { NULL, NULL }, /* Ef */ - { NULL, posts_text }, /* Em */ + { NULL, NULL }, /* Em */ { NULL, NULL }, /* Eo */ { NULL, NULL }, /* Fx */ { NULL, posts_text }, /* Ms */ |