=================================================================== RCS file: /cvs/mandoc/mdoc_markdown.c,v retrieving revision 1.15 retrieving revision 1.25 diff -u -p -r1.15 -r1.25 --- mandoc/mdoc_markdown.c 2017/03/11 12:35:45 1.15 +++ mandoc/mdoc_markdown.c 2018/08/16 13:54:06 1.25 @@ -1,6 +1,6 @@ -/* $Id: mdoc_markdown.c,v 1.15 2017/03/11 12:35:45 schwarze Exp $ */ +/* $Id: mdoc_markdown.c,v 1.25 2018/08/16 13:54:06 schwarze Exp $ */ /* - * Copyright (c) 2017 Ingo Schwarze + * Copyright (c) 2017, 2018 Ingo Schwarze * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -103,8 +103,7 @@ static void md_post_Pf(struct roff_node *); static void md_post_Vt(struct roff_node *); static void md_post__T(struct roff_node *); -static const struct md_act md_acts[MDOC_MAX + 1] = { - { NULL, md_pre_Ap, NULL, NULL, NULL }, /* Ap */ +static const struct md_act __md_acts[MDOC_MAX - MDOC_Dd] = { { NULL, NULL, NULL, NULL, NULL }, /* Dd */ { NULL, NULL, NULL, NULL, NULL }, /* Dt */ { NULL, NULL, NULL, NULL, NULL }, /* Os */ @@ -120,6 +119,7 @@ static const struct md_act md_acts[MDOC_MAX + 1] = { { NULL, md_pre_It, md_post_It, NULL, NULL }, /* It */ { NULL, md_pre_raw, md_post_raw, "*", "*" }, /* Ad */ { NULL, md_pre_An, NULL, NULL, NULL }, /* An */ + { NULL, md_pre_Ap, NULL, NULL, NULL }, /* Ap */ { NULL, md_pre_raw, md_post_raw, "*", "*" }, /* Ar */ { NULL, md_pre_raw, md_post_raw, "**", "**" }, /* Cd */ { NULL, md_pre_raw, md_post_raw, "**", "**" }, /* Cm */ @@ -222,13 +222,10 @@ static const struct md_act md_acts[MDOC_MAX + 1] = { { md_cond_body, md_pre_En, md_post_En, NULL, NULL }, /* En */ { NULL, NULL, NULL, NULL, NULL }, /* Dx */ { NULL, NULL, md_post_pc, NULL, NULL }, /* %Q */ - { NULL, md_pre_br, NULL, NULL, NULL }, /* br */ - { NULL, md_pre_Pp, NULL, NULL, NULL }, /* sp */ { NULL, md_pre_Lk, md_post_pc, NULL, NULL }, /* %U */ { NULL, NULL, NULL, NULL, NULL }, /* Ta */ - { NULL, NULL, NULL, NULL, NULL }, /* ll */ - { NULL, NULL, NULL, NULL, NULL }, /* ROOT */ }; +static const struct md_act *const md_acts = __md_acts - MDOC_Dd; static int outflags; #define MD_spc (1 << 0) /* Blank character before next word. */ @@ -297,7 +294,7 @@ md_node(struct roff_node *n) const struct md_act *act; int cond, process_children; - if (n->flags & NODE_NOPRT) + if (n->type == ROFFT_COMMENT || n->flags & NODE_NOPRT) return; if (outflags & MD_nonl) @@ -310,8 +307,7 @@ md_node(struct roff_node *n) process_children = 1; n->flags &= ~NODE_ENDED; - switch (n->type) { - case ROFFT_TEXT: + if (n->type == ROFFT_TEXT) { if (n->flags & NODE_DELIMC) outflags &= ~(MD_spc | MD_spc_force); else if (outflags & MD_Sm) @@ -321,14 +317,25 @@ md_node(struct roff_node *n) outflags &= ~(MD_spc | MD_spc_force); else if (outflags & MD_Sm) outflags |= MD_spc; - break; - default: + } else if (n->tok < ROFF_MAX) { + switch (n->tok) { + case ROFF_br: + process_children = md_pre_br(n); + break; + case ROFF_sp: + process_children = md_pre_Pp(n); + break; + default: + process_children = 0; + break; + } + } else { + assert(n->tok >= MDOC_Dd && n->tok < MDOC_MAX); act = md_acts + n->tok; cond = act->cond == NULL || (*act->cond)(n); if (cond && act->pre != NULL && (n->end == ENDBODY_NOT || n->child != NULL)) process_children = (*act->pre)(n); - break; } if (process_children && n->child != NULL) @@ -486,7 +493,7 @@ md_word(const char *s) { const char *seq, *prevfont, *currfont, *nextfont; char c; - int bs, sz, uc; + int bs, sz, uc, breakline; /* No spacing before closing delimiters. */ if (s[0] != '\0' && s[1] == '\0' && @@ -503,6 +510,7 @@ md_word(const char *s) if ((s[0] == '(' || s[0] == '[') && s[1] == '\0') outflags &= ~MD_spc; + breakline = 0; prevfont = currfont = ""; while ((c = *s++) != '\0') { bs = 0; @@ -572,6 +580,9 @@ md_word(const char *s) case ESCAPE_SPECIAL: uc = mchars_spec2cp(seq, sz); break; + case ESCAPE_DEVICE: + md_rawword("markdown"); + continue; case ESCAPE_FONTBOLD: nextfont = "**"; break; @@ -588,6 +599,9 @@ md_word(const char *s) case ESCAPE_FONTPREV: nextfont = prevfont; break; + case ESCAPE_BREAK: + breakline = 1; + break; case ESCAPE_NOSPACE: case ESCAPE_SKIPCHAR: case ESCAPE_OVERSTRIKE: @@ -635,6 +649,13 @@ md_word(const char *s) if (bs) putchar('\\'); md_char(c); + if (breakline && + (*s == '\0' || *s == ' ' || *s == ASCII_NBRSP)) { + printf(" \n"); + breakline = 0; + while (*s == ' ' || *s == ASCII_NBRSP) + s++; + } } if (*currfont != '\0') { outflags &= ~MD_spc; @@ -1299,23 +1320,40 @@ md_uri(const char *s) static int md_pre_Lk(struct roff_node *n) { - const struct roff_node *link, *descr; + const struct roff_node *link, *descr, *punct; if ((link = n->child) == NULL) return 0; - descr = link->next == NULL ? link : link->next; + /* Find beginning of trailing punctuation. */ + punct = n->last; + while (punct != link && punct->flags & NODE_DELIMC) + punct = punct->prev; + punct = punct->next; + + /* Link text. */ + descr = link->next; + if (descr == punct) + descr = link; /* no text */ md_rawword("["); outflags &= ~MD_spc; do { md_word(descr->string); - descr = link->next == NULL ? NULL : descr->next; - } while (descr != NULL); + descr = descr->next; + } while (descr != punct); outflags &= ~MD_spc; + + /* Link target. */ md_rawword("]("); md_uri(link->string); outflags &= ~MD_spc; md_rawword(")"); + + /* Trailing punctuation. */ + while (punct != NULL) { + md_word(punct->string); + punct = punct->next; + } return 0; }