From 3e6d7001c4058b93281645e72ad1e223280b8589 Mon Sep 17 00:00:00 2001 From: Martin Alt Date: Tue, 27 Oct 2015 22:11:12 +0100 Subject: [PATCH] Added support for pandoc's fenced code blocks Code blocks can be started using three or more ~ characters and stopped by the same or higher number of ~s. Additionally, pandoc attributes can be specified. They are ignored in mdp, but may be used to get much nicer output when converting the md file to html or pdf using pandoc. For Example: ~~~~ {.bash .linenumbers} ls $HOME # this is a comment ~~~~ See http://pandoc.org/demo/example9/pandocs-markdown.html --- include/markdown.h | 1 + include/parser.h | 1 + sample.md | 26 ++++++++++++++++++++++++++ src/parser.c | 34 ++++++++++++++++++++++++++++++++++ src/viewer.c | 6 ++++-- 5 files changed, 66 insertions(+), 2 deletions(-) diff --git a/include/markdown.h b/include/markdown.h index b338154..3a85947 100644 --- a/include/markdown.h +++ b/include/markdown.h @@ -47,6 +47,7 @@ enum line_bitmask { IS_H2_ATX, IS_QUOTE, IS_CODE, + IS_TILDE_CODE, IS_HR, IS_UNORDERED_LIST_1, IS_UNORDERED_LIST_2, diff --git a/include/parser.h b/include/parser.h index 4140389..7a18377 100644 --- a/include/parser.h +++ b/include/parser.h @@ -57,5 +57,6 @@ int next_nonblank(cstring_t *text, int i); int prev_blank(cstring_t *text, int i); int next_blank(cstring_t *text, int i); int next_word(cstring_t *text, int i); +int next_nontilde(cstring_t *text, int i); #endif // !defined( PARSER_H ) diff --git a/sample.md b/sample.md index 3e3d62e..8f6b053 100644 --- a/sample.md +++ b/sample.md @@ -102,6 +102,32 @@ becomes -> # Supported markdown formatting <- +You can also use [pandoc](http://pandoc.org/demo/example9/pandocs-markdown.html)'s fenced code block extension. +Use at least three ~ chars to open and at least as many or +more ~ for closing. + +~~~~~ +~~~ +int main(int argc, char \*argv[]) { + printf("%s\\n", "Hello world!"); +} +~~~ +~~~~~~~ + +becomes + +~~~ +int main(int argc, char \*argv[]) { + printf("%s\\n", "Hello world!"); +} +~~~ + +Pandoc attributes (like ".numberlines" etc.) will be ignored + +------------------------------------------------- + +-> # Supported markdown formatting <- + Quotes are auto-detected by preceding *>*. Multiple *>* are interpreted as nested quotes. diff --git a/src/parser.c b/src/parser.c index 362a908..d81a2cb 100644 --- a/src/parser.c +++ b/src/parser.c @@ -89,6 +89,9 @@ deck_t *markdown_load(FILE *input) { slide = next_slide(slide); sc++; + } else if(CHECK_BIT(bits, IS_TILDE_CODE) && CHECK_BIT(bits, IS_EMPTY)) { + // remove tilde code markers + (text->reset)(text); } else { // if slide ! has line @@ -319,6 +322,7 @@ int markdown_analyse(cstring_t *text, int prev) { // the program remembers their value on every function calls static int unordered_list_level = 0; static int unordered_list_level_offset[] = {-1, -1, -1, -1}; + static int num_tilde_characters = 0; int i = 0; // increment int bits = 0; // markdown bits @@ -340,6 +344,27 @@ int markdown_analyse(cstring_t *text, int prev) { // count leading spaces offset = next_nonblank(text, 0); + // IS_TILDE_CODE + if (wcsncmp(text->value, L"~~~", 3) == 0) { + int tildes_in_line = next_nontilde(text, 0); + if (tildes_in_line >= num_tilde_characters) { + if (num_tilde_characters > 0) { + num_tilde_characters = 0; + } else { + num_tilde_characters = tildes_in_line; + } + SET_BIT(bits, IS_EMPTY); + SET_BIT(bits, IS_TILDE_CODE); + return bits; + } + } + + if (num_tilde_characters > 0) { + SET_BIT(bits, IS_CODE); + SET_BIT(bits, IS_TILDE_CODE); + return bits; + } + // IS_STOP if((offset < CODE_INDENT || !CHECK_BIT(prev, IS_CODE)) && (!wcsncmp(&text->value[offset], L"
", 4) || @@ -622,6 +647,7 @@ int next_nonblank(cstring_t *text, int i) { return i; } + int prev_blank(cstring_t *text, int i) { while ((i > 0) && !iswspace((text->value)[i])) i--; @@ -639,3 +665,11 @@ int next_blank(cstring_t *text, int i) { int next_word(cstring_t *text, int i) { return next_nonblank(text, next_blank(text, i)); } + +int next_nontilde(cstring_t *text, int i) { + while ((i < text->size) && text->value[i] == L'~') + i++; + + return i; +} + diff --git a/src/viewer.c b/src/viewer.c index 13874d8..0021e79 100644 --- a/src/viewer.c +++ b/src/viewer.c @@ -577,8 +577,10 @@ void add_line(WINDOW *window, int y, int x, line_t *line, int max_cols, int colo // IS_CODE if(CHECK_BIT(line->bits, IS_CODE)) { - // set static offset for code - offset = CODE_INDENT; + if (!CHECK_BIT(line->bits, IS_TILDE_CODE)) { + // set static offset for code + offset = CODE_INDENT; + } // reverse color for code blocks if(colors) -- 2.20.1