From ee03ca4a8599ee896727c32a0012b4753e1da4a7 Mon Sep 17 00:00:00 2001 From: Nathan Toone Date: Thu, 23 Jul 2015 22:28:59 -0600 Subject: [PATCH] Add support for admonitions --- MarkdownTest | 2 +- html.c | 9 ++++++++- latex.c | 3 +++ libMultiMarkdown.h | 3 +++ lyx.c | 15 ++++++++++++--- lyxbeamer.c | 1 + memoir.c | 2 ++ odf.c | 3 +++ parser.leg | 34 ++++++++++++++++++++++++++++++++++ 9 files changed, 67 insertions(+), 5 deletions(-) diff --git a/MarkdownTest b/MarkdownTest index 57d9e9f..4f038c6 160000 --- a/MarkdownTest +++ b/MarkdownTest @@ -1 +1 @@ -Subproject commit 57d9e9fb16aff7f7e1a96d6fd0d970a01a578ecf +Subproject commit 4f038c642407347693b1efd08b41664459353512 diff --git a/html.c b/html.c index aa833bb..30c21d6 100644 --- a/html.c +++ b/html.c @@ -739,14 +739,20 @@ void print_html_node(GString *out, node *n, scratch_pad *scratch) { case HTML: g_string_append_printf(out, "%s", n->str); break; + case ADMONITION: case DEFLIST: pad(out,2, scratch); scratch->padded = 1; - g_string_append_printf(out, "
\n"); + if (n->key == ADMONITION) { + g_string_append_printf(out, "
\n", n->str); + } else { + g_string_append_printf(out, "
\n"); + } print_html_node_tree(out, n->children, scratch); g_string_append_printf(out, "
"); scratch->padded = 0; break; + case ADMONITIONTITLE: case TERM: pad(out,1, scratch); g_string_append_printf(out, "
"); @@ -754,6 +760,7 @@ void print_html_node(GString *out, node *n, scratch_pad *scratch) { g_string_append_printf(out, "
\n"); scratch->padded = 1; break; + case ADMONITIONCONTENT: case DEFINITION: pad(out,1, scratch); scratch->padded = 1; diff --git a/latex.c b/latex.c index 16e7d0c..8836ddf 100644 --- a/latex.c +++ b/latex.c @@ -804,6 +804,7 @@ void print_latex_node(GString *out, node *n, scratch_pad *scratch) { scratch->padded = 0; } break; + case ADMONITION: case DEFLIST: pad(out,2, scratch); g_string_append_printf(out, "\\begin{description}"); @@ -813,6 +814,7 @@ void print_latex_node(GString *out, node *n, scratch_pad *scratch) { g_string_append_printf(out, "\\end{description}"); scratch->padded = 0; break; + case ADMONITIONTITLE: case TERM: pad(out,2, scratch); g_string_append_printf(out, "\\item["); @@ -820,6 +822,7 @@ void print_latex_node(GString *out, node *n, scratch_pad *scratch) { g_string_append_printf(out, "]"); scratch->padded = 0; break; + case ADMONITIONCONTENT: case DEFINITION: pad(out, 2, scratch); scratch->padded = 2; diff --git a/libMultiMarkdown.h b/libMultiMarkdown.h index 338edb7..55541e4 100644 --- a/libMultiMarkdown.h +++ b/libMultiMarkdown.h @@ -150,6 +150,9 @@ enum keys { ABBRSTART, ABBRSTOP, TOC, + ADMONITION, + ADMONITIONTITLE, + ADMONITIONCONTENT, KEY_COUNTER /* This *MUST* be the last item in the list */ }; diff --git a/lyx.c b/lyx.c index e2cab61..015d121 100644 --- a/lyx.c +++ b/lyx.c @@ -120,6 +120,9 @@ GString *used_abbreviations; "ABBR", "ABBRSTART", "ABBRSTOP", + "ADMONITION", + "ADMONITIONTITLE", + "ADMONITIONCONTENT", "KEY_COUNTER" }; @@ -848,8 +851,9 @@ void print_lyx_node(GString *out, node *n, scratch_pad *scratch, bool no_newline break; case BULLETLIST: case ORDEREDLIST: + case ADMONITION: case DEFLIST: - if (n->key == DEFLIST){ + if (n->key == DEFLIST || n->key == ADMONITION){ scratch->lyx_definition_hit = TRUE; scratch->lyx_definition_open = FALSE; } @@ -883,8 +887,11 @@ void print_lyx_node(GString *out, node *n, scratch_pad *scratch, bool no_newline print_lyx_node(out,temp_node,scratch,no_newline); /* now process any other content, including additional lists */ temp_node = temp_node-> next; - while ((temp_node != NULL) && (temp_node->key != BULLETLIST) - && (temp_node->key != ORDEREDLIST) && (temp_node->key != DEFLIST)){ + while ((temp_node != NULL) + && (temp_node->key != BULLETLIST) + && (temp_node->key != ORDEREDLIST) + && (temp_node->key != DEFLIST) + && (temp_node->key != ADMONITION)){ i++; if (i == 1){ g_string_append(out,"\n\\begin_deeper\n"); @@ -1504,6 +1511,7 @@ void print_lyx_node(GString *out, node *n, scratch_pad *scratch, bool no_newline g_string_append(out,"\n\n\\end_layout\n\\end_inset\n"); } break; + case ADMONITIONTITLE: case TERM: scratch->lyx_definition_open = FALSE; /* and it is closed */ old_type = scratch->lyx_para_type; @@ -1532,6 +1540,7 @@ void print_lyx_node(GString *out, node *n, scratch_pad *scratch, bool no_newline g_string_free(temp_str,TRUE); scratch->lyx_para_type = old_type; break; + case ADMONITIONCONTENT: case DEFINITION: if (!scratch -> lyx_definition_hit){ g_string_append(out,"\n\\series default\n"); /* close bolding */ diff --git a/lyxbeamer.c b/lyxbeamer.c index e40d357..1d378dc 100644 --- a/lyxbeamer.c +++ b/lyxbeamer.c @@ -61,6 +61,7 @@ void print_lyxbeamer_node(GString *out, node *n, scratch_pad *scratch, bool no_n case BULLETLIST: case ORDEREDLIST: scratch -> lyx_beamerbullet = TRUE; + case ADMONITION: case DEFLIST: old_type = scratch->lyx_para_type; scratch->lyx_para_type = n->key; diff --git a/memoir.c b/memoir.c index eae547a..65b31c0 100644 --- a/memoir.c +++ b/memoir.c @@ -58,6 +58,7 @@ void print_memoir_node(GString *out, node *n, scratch_pad *scratch) { case HEADINGSECTION: print_memoir_node_tree(out, n->children, scratch); break; + case ADMONITION: case DEFLIST: pad(out, 2, scratch); g_string_append_printf(out, "\\begin{description}"); @@ -67,6 +68,7 @@ void print_memoir_node(GString *out, node *n, scratch_pad *scratch) { g_string_append_printf(out, "\\end{description}"); scratch->padded = 0; break; + case ADMONITIONCONTENT: case DEFINITION: pad(out, 2, scratch); scratch->padded = 2; diff --git a/odf.c b/odf.c index a36db0e..e55eb99 100644 --- a/odf.c +++ b/odf.c @@ -710,9 +710,11 @@ void print_odf_node(GString *out, node *n, scratch_pad *scratch) { g_string_append_printf(out, "%s", &n->str[4]); } break; + case ADMONITION: case DEFLIST: print_odf_node_tree(out, n->children, scratch); break; + case ADMONITIONTITLE: case TERM: pad(out,1, scratch); g_string_append_printf(out, ""); @@ -720,6 +722,7 @@ void print_odf_node(GString *out, node *n, scratch_pad *scratch) { g_string_append_printf(out, "\n"); scratch->padded = 1; break; + case ADMONITIONCONTENT: case DEFINITION: old_type = scratch->odf_para_type; scratch->odf_para_type = DEFINITION; diff --git a/parser.leg b/parser.leg index 5620017..81c0dca 100644 --- a/parser.leg +++ b/parser.leg @@ -116,6 +116,7 @@ Block = BlankLine* | &{ !ext(EXT_COMPATIBILITY) } Fenced | Verbatim | &{ !ext(EXT_COMPATIBILITY) } DefinitionList + | &{ !ext(EXT_COMPATIBILITY) } Admonition | &{ !ext(EXT_COMPATIBILITY) } Glossary | Note | LinkReference @@ -139,6 +140,7 @@ HeadingSectionBlock = BlankLine* !Heading | &{ !ext(EXT_COMPATIBILITY) } Fenced | Verbatim | &{ !ext(EXT_COMPATIBILITY) } DefinitionList + | &{ !ext(EXT_COMPATIBILITY) } Admonition | &{ !ext(EXT_COMPATIBILITY) } Glossary | Note | LinkReference @@ -862,6 +864,38 @@ Definition = (a:StartList b:StartList $$ = list(DEFINITION,raw); } +Admonition = AdmonitionMark Sp a:AdmonitionName Sp b:AdmonitionTitle Newline c:AdmonitionContent { + a->children = b; + b->next = c; + $$ = a; + } + +AdmonitionMark = '!!!' + +AdmonitionEnd = Sp AdmonitionMark? + +AdmonitionName = < AlphanumericAscii (AlphanumericAscii | '-' | '_')* > { $$ = str(yytext); $$->key = ADMONITION; } + +AdmonitionTitle = a:StartList ( (QuotedValue AdmonitionEnd { a = cons(str(yytext), a); }) | (AdmonitionEnd { + a = cons(str(yytext), a); + for (int idx = 0; a->str[idx]; idx++) { + if (idx == 0) a->str[idx] = toupper(a->str[idx]); + if (a->str[idx] == '_') a->str[idx] = ' '; + } + }) ) { $$ = mk_list(ADMONITIONTITLE, a); } + +AdmonitionContent = (a:StartList b:StartList + (BlankLine { b = cons(mk_str("\n"),b); } )? + (IndentedLine { a = cons($$, a); })+ + ( BlankLine { a = cons(mk_str("\n"), a); } + (IndentedLine { a = cons($$, a); })+ { a = cons(mk_str("\n"), a); } + )* ) { + if (b != NULL) { a = cons(b,a);} + node *raw = mk_str_from_list(a, false); + raw->key = RAW; + $$ = list(ADMONITIONCONTENT, raw); + } + Bullet = !HorizontalRule NonindentSpace ('+' | '*' | '-') Spacechar+ BulletNoSpace = !HorizontalRule NonindentSpace ('+' | '*' | '-')