]> git.cameronkatri.com Git - mandoc.git/blobdiff - mdoc_markdown.c
When checking the validity of cross references with -Tlint,
[mandoc.git] / mdoc_markdown.c
index 6f80d70c417acb23e52250772145cb5b98a9f25d..0b0f184821e5bf5990f1eb1a6f9d6a274f41764e 100644 (file)
@@ -1,4 +1,4 @@
-/*     $Id: mdoc_markdown.c,v 1.15 2017/03/11 12:35:45 schwarze Exp $ */
+/*     $Id: mdoc_markdown.c,v 1.23 2017/06/14 01:31:26 schwarze Exp $ */
 /*
  * Copyright (c) 2017 Ingo Schwarze <schwarze@openbsd.org>
  *
@@ -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. */
@@ -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;
@@ -588,6 +596,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 +646,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 +1317,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;
 }