]> git.cameronkatri.com Git - mandoc.git/blobdiff - mdoc_markdown.c
.Bl -column never gets blank lines between rows
[mandoc.git] / mdoc_markdown.c
index f6fb7fdf2d0b037874e57f33274e10d7455ec46d..36b9605bbee4766405217da95dcdf98962f8ccca 100644 (file)
@@ -1,4 +1,4 @@
-/*     $Id: mdoc_markdown.c,v 1.6 2017/03/07 13:28:02 schwarze Exp $ */
+/*     $Id: mdoc_markdown.c,v 1.10 2017/03/08 15:08:36 schwarze Exp $ */
 /*
  * Copyright (c) 2017 Ingo Schwarze <schwarze@openbsd.org>
  *
@@ -247,6 +247,7 @@ static      int      escflags; /* Escape in generated markdown code: */
 #define        ESC_PAR  (1 << 3)  /* ")" when "(" is open. */
 #define        ESC_SQU  (1 << 4)  /* "]" when "[" is open. */
 #define        ESC_FON  (1 << 5)  /* "*" immediately after unrelated "*". */
+#define        ESC_EOL  (1 << 6)  /* " " at the and of a line. */
 
 static int      code_blocks, quote_blocks, list_blocks;
 static int      outcount;
@@ -374,37 +375,43 @@ md_stack(char c)
 static void
 md_preword(void)
 {
+       const char      *cp;
+
        /*
         * If a list block is nested inside a code block or a blockquote,
         * blank lines for paragraph breaks no longer work; instead,
         * they terminate the list.  Work around this markdown issue
         * by using mere line breaks instead.
         */
+
        if (list_blocks && outflags & MD_sp) {
                outflags &= ~MD_sp;
                outflags |= MD_br;
        }
 
-       /* End the old line if requested. */
+       /*
+        * End the old line if requested.
+        * Escape whitespace at the end of the markdown line
+        * such that it won't look like an output line break.
+        */
 
        if (outflags & MD_sp)
                putchar('\n');
        else if (outflags & MD_br) {
                putchar(' ');
                putchar(' ');
-#ifdef DEBUG
-               putchar(':');
-               putchar(':');
-               putchar(' ');
-               putchar(' ');
-#endif
-       }
+       } else if (outflags & MD_nl && escflags & ESC_EOL)
+               md_named("zwnj");
 
        /* Start a new line if necessary. */
 
        if (outflags & (MD_nl | MD_br | MD_sp)) {
                putchar('\n');
-               fputs(md_stack('\0'), stdout);
+               for (cp = md_stack('\0'); *cp != '\0'; cp++) {
+                       putchar(*cp);
+                       if (*cp == '>')
+                               putchar(' ');
+               }
                outflags &= ~(MD_nl | MD_br | MD_sp);
                escflags = ESC_BOL;
                outcount = 0;
@@ -437,7 +444,7 @@ md_rawword(const char *s)
 {
        md_preword();
 
-       if (*s == 0)
+       if (*s == '\0')
                return;
 
        if (escflags & ESC_FON) {
@@ -470,6 +477,10 @@ md_rawword(const char *s)
                }
                md_char(*s++);
        }
+       if (s[-1] == ' ')
+               escflags |= ESC_EOL;
+       else
+               escflags &= ~ESC_EOL;
 }
 
 /*
@@ -490,6 +501,9 @@ md_word(const char *s)
 
        md_preword();
 
+       if (*s == '\0')
+               return;
+
        /* No spacing after opening delimiters. */
        if ((s[0] == '(' || s[0] == '[') && s[1] == '\0')
                outflags &= ~MD_spc;
@@ -630,7 +644,10 @@ md_word(const char *s)
        if (*currfont != '\0') {
                outflags &= ~MD_spc;
                md_rawword(currfont);
-       }
+       } else if (s[-2] == ' ')
+               escflags |= ESC_EOL;
+       else
+               escflags &= ~ESC_EOL;
 }
 
 /*
@@ -640,7 +657,7 @@ static void
 md_named(const char *s)
 {
        printf("&%s;", s);
-       escflags &= ~ESC_FON;
+       escflags &= ~(ESC_FON | ESC_EOL);
        outcount++;
 }
 
@@ -957,21 +974,17 @@ md_pre_Eo(struct roff_node *n)
 static void
 md_post_Eo(struct roff_node *n)
 {
-       int      body, tail;
-
        if (n->end != ENDBODY_NOT) {
                outflags |= MD_spc;
                return;
        }
 
-       body = n->child != NULL || n->parent->head->child != NULL;
-       tail = n->parent->tail != NULL && n->parent->tail->child != NULL;
+       if (n->child == NULL && n->parent->head->child == NULL)
+               return;
 
-       if (body && tail)
+       if (n->parent->tail != NULL && n->parent->tail->child != NULL)
                outflags &= ~MD_spc;
-        else if ( ! (body || tail))
-               md_preword();
-        else if ( ! tail)
+        else
                outflags |= MD_spc;
 }
 
@@ -1138,7 +1151,8 @@ md_pre_It(struct roff_node *n)
 
        case ROFFT_HEAD:
                bln = n->parent->parent;
-               if (bln->norm->Bl.comp == 0)
+               if (bln->norm->Bl.comp == 0 &&
+                   bln->norm->Bl.type != LIST_column)
                        outflags |= MD_sp;
                outflags |= MD_nl;
 
@@ -1167,6 +1181,9 @@ md_pre_It(struct roff_node *n)
                        printf("%d.\t", ++bln->norm->Bl.count);
                        escflags &= ~ESC_FON;
                        break;
+               case LIST_column:
+                       outflags |= MD_br;
+                       return 0;
                default:
                        return 0;
                }