Welcome to little lamb

Code » md4c » commit b2eacfd

Add INDENT extension so lines prefixed with : get..

author Olivier Brunel
2022-12-31 22:26:40 UTC
committer Olivier Brunel
2023-07-19 11:55:00 UTC
parent 6b58ae194c3cd6a9b6d7f81597d5eea559961156

Add INDENT extension so lines prefixed with : get..

..indented. Because sometimes it's wanted to have some indentation (that
doesn't come from a blockquote). Think options list in a man page.

src/md4c.c +44 -9
src/md4c.h +4 -0

diff --git a/src/md4c.c b/src/md4c.c
index 43d7655..dc5bc62 100644
--- a/src/md4c.c
+++ b/src/md4c.c
@@ -4916,7 +4916,8 @@ md_process_all_blocks(MD_CTX* ctx)
             if(block->flags & MD_BLOCK_CONTAINER_CLOSER) {
                 MD_LEAVE_BLOCK(block->type, &det);
 
-                if(block->type == MD_BLOCK_UL || block->type == MD_BLOCK_OL || block->type == MD_BLOCK_QUOTE)
+                if(block->type == MD_BLOCK_UL || block->type == MD_BLOCK_OL
+                        || block->type == MD_BLOCK_QUOTE || block->type == MD_BLOCK_INDENT)
                     ctx->n_containers--;
             }
 
@@ -4926,7 +4927,7 @@ md_process_all_blocks(MD_CTX* ctx)
                 if(block->type == MD_BLOCK_UL || block->type == MD_BLOCK_OL) {
                     ctx->containers[ctx->n_containers].is_loose = (block->flags & MD_BLOCK_LOOSE_LIST);
                     ctx->n_containers++;
-                } else if(block->type == MD_BLOCK_QUOTE) {
+                } else if(block->type == MD_BLOCK_QUOTE || block->type == MD_BLOCK_INDENT) {
                     /* This causes that any text in a block quote, even if
                      * nested inside a tight list item, is wrapped with
                      * <p>...</p>. */
@@ -5584,6 +5585,9 @@ md_is_container_compatible(const MD_CONTAINER* pivot, const MD_CONTAINER* contai
     if(container->ch == _T('>'))
         return FALSE;
 
+    if(container->ch == _T(':'))
+        return FALSE;
+
     if(container->ch != pivot->ch)
         return FALSE;
     if(container->mark_indent > pivot->contents_indent)
@@ -5651,6 +5655,10 @@ md_enter_child_containers(MD_CTX* ctx, int n_children)
                 MD_CHECK(md_push_container_bytes(ctx, MD_BLOCK_QUOTE, 0, 0, MD_BLOCK_CONTAINER_OPENER));
                 break;
 
+            case _T(':'):
+                MD_CHECK(md_push_container_bytes(ctx, MD_BLOCK_INDENT, 0, 0, MD_BLOCK_CONTAINER_OPENER));
+                break;
+
             default:
                 MD_UNREACHABLE();
                 break;
@@ -5692,6 +5700,11 @@ md_leave_child_containers(MD_CTX* ctx, int n_keep)
                                 0, MD_BLOCK_CONTAINER_CLOSER));
                 break;
 
+            case _T(':'):
+                MD_CHECK(md_push_container_bytes(ctx, MD_BLOCK_INDENT, 0,
+                                0, MD_BLOCK_CONTAINER_CLOSER));
+                break;
+
             default:
                 MD_UNREACHABLE();
                 break;
@@ -5725,6 +5738,18 @@ md_is_container_mark(MD_CTX* ctx, unsigned indent, OFF beg, OFF* p_end, MD_CONTA
         return TRUE;
     }
 
+    /* Check for indent mark. */
+    if(CH(off) == _T(':')) {
+        off++;
+        p_container->ch = _T(':');
+        p_container->is_loose = FALSE;
+        p_container->is_task = FALSE;
+        p_container->mark_indent = indent;
+        p_container->contents_indent = indent + 1;
+        *p_end = off;
+        return TRUE;
+    }
+
     /* Check for list item bullet mark. */
     if(ISANYOF(off, _T("-+*"))  &&  (off+1 >= ctx->size || ISBLANK(off+1) || ISNEWLINE(off+1))) {
         p_container->ch = CH(off);
@@ -5807,8 +5832,11 @@ md_analyze_line(MD_CTX* ctx, OFF beg, OFF* p_end,
     while(n_parents < ctx->n_containers) {
         MD_CONTAINER* c = &ctx->containers[n_parents];
 
-        if(c->ch == _T('>')  &&  line->indent < ctx->code_indent_offset  &&
-            off < ctx->size  &&  CH(off) == _T('>'))
+        if((c->ch == _T('>')  &&  line->indent < ctx->code_indent_offset  &&
+             off < ctx->size  &&  CH(off) == _T('>'))
+                ||
+           (c->ch == _T(':')  &&  line->indent < ctx->code_indent_offset  &&
+             off < ctx->size  &&  CH(off) == _T(':')))
         {
             /* Block quote mark. */
             off++;
@@ -5822,7 +5850,8 @@ md_analyze_line(MD_CTX* ctx, OFF beg, OFF* p_end,
 
             line->beg = off;
 
-        } else if(c->ch != _T('>')  &&  line->indent >= c->contents_indent) {
+        } else if(c->ch != _T('>')  &&  c->ch != _T(':')
+                &&  line->indent >= c->contents_indent) {
             /* List. */
             line->indent -= c->contents_indent;
         } else {
@@ -5836,7 +5865,9 @@ md_analyze_line(MD_CTX* ctx, OFF beg, OFF* p_end,
         /* Blank line does not need any real indentation to be nested inside
          * a list. */
         if(n_brothers + n_children == 0) {
-            while(n_parents < ctx->n_containers  &&  ctx->containers[n_parents].ch != _T('>'))
+            while(n_parents < ctx->n_containers
+                    &&  ctx->containers[n_parents].ch != _T('>')
+                    &&  ctx->containers[n_parents].ch != _T(':'))
                 n_parents++;
         }
     }
@@ -5911,7 +5942,8 @@ md_analyze_line(MD_CTX* ctx, OFF beg, OFF* p_end,
                 line->type = MD_LINE_BLANK;
                 ctx->last_line_has_list_loosening_effect = (n_parents > 0  &&
                         n_brothers + n_children == 0  &&
-                        ctx->containers[n_parents-1].ch != _T('>'));
+                        ctx->containers[n_parents-1].ch != _T('>') &&
+                        ctx->containers[n_parents-1].ch != _T(':'));
 
     #if 1
                 /* See https://github.com/mity/md4c/issues/6
@@ -5926,6 +5958,7 @@ md_analyze_line(MD_CTX* ctx, OFF beg, OFF* p_end,
                  * item can begin with at most one blank line."
                  */
                 if(n_parents > 0  &&  ctx->containers[n_parents-1].ch != _T('>')  &&
+                   ctx->containers[n_parents-1].ch != _T(':') &&
                    n_brothers + n_children == 0  &&  ctx->current_block == NULL  &&
                    ctx->n_block_bytes > (int) sizeof(MD_BLOCK))
                 {
@@ -5945,6 +5978,7 @@ md_analyze_line(MD_CTX* ctx, OFF beg, OFF* p_end,
             ctx->last_line_has_list_loosening_effect = FALSE;
             if(ctx->last_list_item_starts_with_two_blank_lines) {
                 if(n_parents > 0  &&  ctx->containers[n_parents-1].ch != _T('>')  &&
+                   ctx->containers[n_parents-1].ch != _T(':') &&
                    n_brothers + n_children == 0  &&  ctx->current_block == NULL  &&
                    ctx->n_block_bytes > (int) sizeof(MD_BLOCK))
                 {
@@ -6036,7 +6070,8 @@ md_analyze_line(MD_CTX* ctx, OFF beg, OFF* p_end,
            md_is_container_mark(ctx, line->indent, off, &off, &container))
         {
             if(pivot_line->type == MD_LINE_TEXT  &&  n_parents == ctx->n_containers  &&
-                        (off >= ctx->size || ISNEWLINE(off))  &&  container.ch != _T('>'))
+                        (off >= ctx->size || ISNEWLINE(off))  &&  container.ch != _T('>')
+                        &&  container.ch != _T(':'))
             {
                 /* Noop. List mark followed by a blank line cannot interrupt a paragraph. */
             } else if(pivot_line->type == MD_LINE_TEXT  &&  n_parents == ctx->n_containers  &&
@@ -6234,7 +6269,7 @@ md_analyze_line(MD_CTX* ctx, OFF beg, OFF* p_end,
     /* If we belong to a list after seeing a blank line, the list is loose. */
     if(prev_line_has_list_loosening_effect  &&  line->type != MD_LINE_BLANK  &&  n_parents + n_brothers > 0) {
         MD_CONTAINER* c = &ctx->containers[n_parents + n_brothers - 1];
-        if(c->ch != _T('>')) {
+        if(c->ch != _T('>')  && c->ch != _T(':')) {
             MD_BLOCK* block = (MD_BLOCK*) (((char*)ctx->block_bytes) + c->block_byte_off);
             block->flags |= MD_BLOCK_LOOSE_LIST;
         }
diff --git a/src/md4c.h b/src/md4c.h
index 95f78f9..501aab5 100644
--- a/src/md4c.h
+++ b/src/md4c.h
@@ -58,6 +58,9 @@ typedef enum MD_BLOCKTYPE {
     /* <blockquote>...</blockquote> */
     MD_BLOCK_QUOTE,
 
+    /* indented block */
+    MD_BLOCK_INDENT,
+
     /* <ul>...</ul>
      * Detail: Structure MD_BLOCK_UL_DETAIL. */
     MD_BLOCK_UL,
@@ -316,6 +319,7 @@ typedef struct MD_SPAN_WIKILINK {
 #define MD_FLAG_LATEXMATHSPANS              0x1000  /* Enable $ and $$ containing LaTeX equations. */
 #define MD_FLAG_WIKILINKS                   0x2000  /* Enable wiki links extension. */
 #define MD_FLAG_UNDERLINE                   0x4000  /* Enable underline extension (and disables '_' for normal emphasis). */
+#define MD_FLAG_INDENT                      0x80000 /* Enable indent extension */
 
 #define MD_FLAG_PERMISSIVEAUTOLINKS         (MD_FLAG_PERMISSIVEEMAILAUTOLINKS | MD_FLAG_PERMISSIVEURLAUTOLINKS | MD_FLAG_PERMISSIVEWWWAUTOLINKS)
 #define MD_FLAG_NOHTML                      (MD_FLAG_NOHTMLBLOCKS | MD_FLAG_NOHTMLSPANS)