From 179fa22dcb9035248917197542488590b504817a Mon Sep 17 00:00:00 2001 From: Alexandre Leray Date: Sun, 27 May 2012 15:08:57 +0200 Subject: [PATCH 1/7] Removed -Wl flag in MakeFile. It was not compiling. --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index baca6875..fb268c99 100644 --- a/Makefile +++ b/Makefile @@ -44,7 +44,7 @@ libsundown.so: libsundown.so.1 ln -f -s $^ $@ libsundown.so.1: $(SUNDOWN_SRC) - $(CC) $(LDFLAGS) -shared -Wl $^ -o $@ + $(CC) $(LDFLAGS) -shared $^ -o $@ # executables From 5c1b5e879520da7eee4a994acc2a59b55c57b326 Mon Sep 17 00:00:00 2001 From: Alexandre Leray Date: Sun, 27 May 2012 15:27:50 +0200 Subject: [PATCH 2/7] Added a tag extensions. It can be used by enabling the MKDEXT_INS option like this (example/sundown.c): markdown = sd_markdown_new(MKDEXT_INS, 16, &callbacks, &options) then, after compilation the following command line: echo "++ins++" | ./sundown results in:

ins

--- html/html.c | 14 ++++++++++++++ src/markdown.c | 8 ++++++-- src/markdown.h | 2 ++ 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/html/html.c b/html/html.c index 7f08ee8e..bc11d5de 100755 --- a/html/html.c +++ b/html/html.c @@ -169,6 +169,18 @@ rndr_codespan(struct buf *ob, const struct buf *text, void *opaque) return 1; } +static int +rndr_ins(struct buf *ob, const struct buf *text, void *opaque) +{ + if (!text || !text->size) + return 0; + + BUFPUTSL(ob, ""); + bufput(ob, text->data, text->size); + BUFPUTSL(ob, ""); + return 1; +} + static int rndr_strikethrough(struct buf *ob, const struct buf *text, void *opaque) { @@ -564,6 +576,7 @@ sdhtml_toc_renderer(struct sd_callbacks *callbacks, struct html_renderopt *optio toc_link, NULL, rndr_triple_emphasis, + rndr_ins, rndr_strikethrough, rndr_superscript, @@ -605,6 +618,7 @@ sdhtml_renderer(struct sd_callbacks *callbacks, struct html_renderopt *options, rndr_link, rndr_raw_html, rndr_triple_emphasis, + rndr_ins, rndr_strikethrough, rndr_superscript, diff --git a/src/markdown.c b/src/markdown.c index 260483d6..e43fc693 100644 --- a/src/markdown.c +++ b/src/markdown.c @@ -526,6 +526,7 @@ parse_emph2(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t size int r; render_method = (c == '~') ? rndr->cb.strikethrough : rndr->cb.double_emphasis; + render_method = (c == '+') ? rndr->cb.ins : render_method; if (!render_method) return 0; @@ -598,8 +599,9 @@ char_emphasis(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t of if (size > 2 && data[1] != c) { /* whitespace cannot follow an opening emphasis; + * ins only takes two characters '++' * strikethrough only takes two characters '~~' */ - if (c == '~' || _isspace(data[1]) || (ret = parse_emph1(ob, rndr, data + 1, size - 1, c)) == 0) + if (c == '+' || c == '~' || _isspace(data[1]) || (ret = parse_emph1(ob, rndr, data + 1, size - 1, c)) == 0) return 0; return ret + 1; @@ -613,7 +615,7 @@ char_emphasis(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t of } if (size > 4 && data[1] == c && data[2] == c && data[3] != c) { - if (c == '~' || _isspace(data[3]) || (ret = parse_emph3(ob, rndr, data + 3, size - 3, c)) == 0) + if (c == '+' || c == '~' || _isspace(data[3]) || (ret = parse_emph3(ob, rndr, data + 3, size - 3, c)) == 0) return 0; return ret + 3; @@ -2415,6 +2417,8 @@ sd_markdown_new( md->active_char['_'] = MD_CHAR_EMPHASIS; if (extensions & MKDEXT_STRIKETHROUGH) md->active_char['~'] = MD_CHAR_EMPHASIS; + if (extensions & MKDEXT_INS) + md->active_char['+'] = MD_CHAR_EMPHASIS; } if (md->cb.codespan) diff --git a/src/markdown.h b/src/markdown.h index 6f6553ec..936aa399 100644 --- a/src/markdown.h +++ b/src/markdown.h @@ -56,6 +56,7 @@ enum mkd_extensions { MKDEXT_FENCED_CODE = (1 << 2), MKDEXT_AUTOLINK = (1 << 3), MKDEXT_STRIKETHROUGH = (1 << 4), + MKDEXT_INS = (1 << 5), MKDEXT_SPACE_HEADERS = (1 << 6), MKDEXT_SUPERSCRIPT = (1 << 7), MKDEXT_LAX_SPACING = (1 << 8), @@ -87,6 +88,7 @@ struct sd_callbacks { int (*link)(struct buf *ob, const struct buf *link, const struct buf *title, const struct buf *content, void *opaque); int (*raw_html_tag)(struct buf *ob, const struct buf *tag, void *opaque); int (*triple_emphasis)(struct buf *ob, const struct buf *text, void *opaque); + int (*ins)(struct buf *ob, const struct buf *text, void *opaque); int (*strikethrough)(struct buf *ob, const struct buf *text, void *opaque); int (*superscript)(struct buf *ob, const struct buf *text, void *opaque); From bd8e9b5175cad6ce40c7e06ab95b254f09d163a6 Mon Sep 17 00:00:00 2001 From: Alexandre Leray Date: Fri, 22 Jun 2012 11:40:17 +0200 Subject: [PATCH 3/7] Started an extension to "outline" documents. This is a rewrite of the outline extension for Python-Markdown (http://git.constantvzw.org/?p=aa.mdx_outline.git;a=tree). Wraps the document logical sections (as implied by h1-h6 headings) in html5
tags. Big thank you to Pierre Marchand for helping me with this, and taking time showing me the basics of C99! --- html/html.c | 29 +++++++++++++++++++++++++++-- html/html.h | 2 ++ 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/html/html.c b/html/html.c index bc11d5de..c59c7e09 100755 --- a/html/html.c +++ b/html/html.c @@ -27,6 +27,7 @@ #define USE_XHTML(opt) (opt->flags & HTML_USE_XHTML) + int sdhtml_is_tag(const uint8_t *tag_data, size_t tag_size, const char *tagname) { @@ -226,11 +227,20 @@ rndr_linebreak(struct buf *ob, void *opaque) static void rndr_header(struct buf *ob, const struct buf *text, int level, void *opaque) -{ +{ struct html_renderopt *options = opaque; if (ob->size) bufputc(ob, '\n'); + + if(options->section_level == level) + { + BUFPUTSL(ob, "
"); + options->open_sections--; + } + BUFPUTSL(ob, "
"); + options->open_sections++; + options->section_level = level; if (options->flags & HTML_TOC) bufprintf(ob, "", level, options->toc_data.header_count++); @@ -498,6 +508,19 @@ rndr_normal_text(struct buf *ob, const struct buf *text, void *opaque) escape_html(ob, text->data, text->size); } +static void +rndr_finalize(struct buf *ob, void *opaque) +{ + struct html_renderopt *options = opaque; + int i; + + for(i = 0; i < options->open_sections; i++) + { + BUFPUTSL(ob, "\n
\n"); + } +} + + static void toc_header(struct buf *ob, const struct buf *text, int level, void *opaque) { @@ -626,12 +649,14 @@ sdhtml_renderer(struct sd_callbacks *callbacks, struct html_renderopt *options, rndr_normal_text, NULL, - NULL, + rndr_finalize, }; /* Prepare the options pointer */ memset(options, 0x0, sizeof(struct html_renderopt)); options->flags = render_flags; + options->open_sections = 0; + options->section_level = 0; /* Prepare the callbacks */ memcpy(callbacks, &cb_default, sizeof(struct sd_callbacks)); diff --git a/html/html.h b/html/html.h index 4c8810d4..5e63a58f 100644 --- a/html/html.h +++ b/html/html.h @@ -33,6 +33,8 @@ struct html_renderopt { } toc_data; unsigned int flags; + int section_level; + int open_sections; /* extra callbacks */ void (*link_attributes)(struct buf *ob, const struct buf *url, void *self); From 89f7987c83c5563d30bff8b27108c75f86b2b5f3 Mon Sep 17 00:00:00 2001 From: Alexandre Leray Date: Sun, 24 Jun 2012 17:56:19 +0200 Subject: [PATCH 4/7] Renamed some variables for clarity; --- html/html.c | 14 +++++++------- html/html.h | 7 +++++-- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/html/html.c b/html/html.c index c59c7e09..02282a75 100755 --- a/html/html.c +++ b/html/html.c @@ -233,14 +233,14 @@ rndr_header(struct buf *ob, const struct buf *text, int level, void *opaque) if (ob->size) bufputc(ob, '\n'); - if(options->section_level == level) + if(options->outline_data.current_level == level) { BUFPUTSL(ob, ""); - options->open_sections--; + options->outline_data.open_section_count--; } BUFPUTSL(ob, "
"); - options->open_sections++; - options->section_level = level; + options->outline_data.open_section_count++; + options->outline_data.current_level = level; if (options->flags & HTML_TOC) bufprintf(ob, "", level, options->toc_data.header_count++); @@ -514,7 +514,7 @@ rndr_finalize(struct buf *ob, void *opaque) struct html_renderopt *options = opaque; int i; - for(i = 0; i < options->open_sections; i++) + for(i = 0; i < options->outline_data.open_section_count; i++) { BUFPUTSL(ob, "\n
\n"); } @@ -655,8 +655,8 @@ sdhtml_renderer(struct sd_callbacks *callbacks, struct html_renderopt *options, /* Prepare the options pointer */ memset(options, 0x0, sizeof(struct html_renderopt)); options->flags = render_flags; - options->open_sections = 0; - options->section_level = 0; + options->outline_data.open_section_count = 0; + options->outline_data.current_level = 0; /* Prepare the callbacks */ memcpy(callbacks, &cb_default, sizeof(struct sd_callbacks)); diff --git a/html/html.h b/html/html.h index 5e63a58f..e361c84f 100644 --- a/html/html.h +++ b/html/html.h @@ -33,8 +33,11 @@ struct html_renderopt { } toc_data; unsigned int flags; - int section_level; - int open_sections; + + struct { + int current_level; + int open_section_count; + } outline_data; /* extra callbacks */ void (*link_attributes)(struct buf *ob, const struct buf *url, void *self); From 4e91935001e642f980ecb479f45d8f8fbf719544 Mon Sep 17 00:00:00 2001 From: Alexandre Leray Date: Sun, 24 Jun 2012 19:42:27 +0200 Subject: [PATCH 5/7] Made section outlining optional. One can enable it that way: sdhtml_renderer(&callbacks, &options, HTML_OUTLINE); --- html/html.c | 25 ++++++++++++++++++++----- html/html.h | 1 + src/markdown.c | 3 +++ src/markdown.h | 3 +++ 4 files changed, 27 insertions(+), 5 deletions(-) diff --git a/html/html.c b/html/html.c index 02282a75..504158cb 100755 --- a/html/html.c +++ b/html/html.c @@ -233,6 +233,8 @@ rndr_header(struct buf *ob, const struct buf *text, int level, void *opaque) if (ob->size) bufputc(ob, '\n'); + if (options->flags & HTML_OUTLINE) + { if(options->outline_data.current_level == level) { BUFPUTSL(ob, ""); @@ -241,6 +243,7 @@ rndr_header(struct buf *ob, const struct buf *text, int level, void *opaque) BUFPUTSL(ob, "
"); options->outline_data.open_section_count++; options->outline_data.current_level = level; + } if (options->flags & HTML_TOC) bufprintf(ob, "", level, options->toc_data.header_count++); @@ -511,13 +514,15 @@ rndr_normal_text(struct buf *ob, const struct buf *text, void *opaque) static void rndr_finalize(struct buf *ob, void *opaque) { - struct html_renderopt *options = opaque; - int i; + struct html_renderopt *options = opaque; + int i; + if (options->flags & HTML_OUTLINE) { for(i = 0; i < options->outline_data.open_section_count; i++) { BUFPUTSL(ob, "\n
\n"); } + } } @@ -608,6 +613,8 @@ sdhtml_toc_renderer(struct sd_callbacks *callbacks, struct html_renderopt *optio NULL, toc_finalize, + + NULL, }; memset(options, 0x0, sizeof(struct html_renderopt)); @@ -649,18 +656,26 @@ sdhtml_renderer(struct sd_callbacks *callbacks, struct html_renderopt *options, rndr_normal_text, NULL, - rndr_finalize, + NULL, + + NULL, //rndr_finalize, }; /* Prepare the options pointer */ memset(options, 0x0, sizeof(struct html_renderopt)); options->flags = render_flags; - options->outline_data.open_section_count = 0; - options->outline_data.current_level = 0; /* Prepare the callbacks */ memcpy(callbacks, &cb_default, sizeof(struct sd_callbacks)); + if (render_flags & HTML_OUTLINE) + { + callbacks->outline = rndr_finalize; + + options->outline_data.open_section_count = 0; + options->outline_data.current_level = 0; + } + if (render_flags & HTML_SKIP_IMAGES) callbacks->image = NULL; diff --git a/html/html.h b/html/html.h index e361c84f..f2556fac 100644 --- a/html/html.h +++ b/html/html.h @@ -54,6 +54,7 @@ typedef enum { HTML_HARD_WRAP = (1 << 7), HTML_USE_XHTML = (1 << 8), HTML_ESCAPE = (1 << 9), + HTML_OUTLINE = (1 << 10), } html_render_mode; typedef enum { diff --git a/src/markdown.c b/src/markdown.c index e43fc693..207b0647 100644 --- a/src/markdown.c +++ b/src/markdown.c @@ -2519,6 +2519,9 @@ sd_markdown_render(struct buf *ob, const uint8_t *document, size_t doc_size, str if (md->cb.doc_footer) md->cb.doc_footer(ob, md->opaque); + if (md->cb.outline) + md->cb.outline(ob, md->opaque); + /* clean-up */ bufrelease(text); free_link_refs(md->refs); diff --git a/src/markdown.h b/src/markdown.h index 936aa399..910b2fa8 100644 --- a/src/markdown.h +++ b/src/markdown.h @@ -99,6 +99,9 @@ struct sd_callbacks { /* header and footer */ void (*doc_header)(struct buf *ob, void *opaque); void (*doc_footer)(struct buf *ob, void *opaque); + + /* outliner */ + void (*outline)(struct buf *ob, void *opaque); }; struct sd_markdown; From 7463350792d5ece76553609e148f5cb23d7c152d Mon Sep 17 00:00:00 2001 From: Alexandre Leray Date: Sun, 24 Jun 2012 19:51:21 +0200 Subject: [PATCH 6/7] Fixed a bug in section outlining neesting section tags were not closed if current header level was lower than previous header level (eg. h1 following an h2). --- html/html.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/html/html.c b/html/html.c index 504158cb..08153d23 100755 --- a/html/html.c +++ b/html/html.c @@ -235,7 +235,7 @@ rndr_header(struct buf *ob, const struct buf *text, int level, void *opaque) if (options->flags & HTML_OUTLINE) { - if(options->outline_data.current_level == level) + if(options->outline_data.current_level >= level) { BUFPUTSL(ob, ""); options->outline_data.open_section_count--; From b8e8cfbb26e8170603eeb311c064d3447cf4dbc9 Mon Sep 17 00:00:00 2001 From: Alexandre Leray Date: Sun, 24 Jun 2012 19:54:33 +0200 Subject: [PATCH 7/7] Added section level as a class to section wrappers If the HTML_OUTLINE flag is enabled, documents like: # level 1 ## level 2 turn into:

level 1

level2

--- html/html.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/html/html.c b/html/html.c index 08153d23..803eaf5d 100755 --- a/html/html.c +++ b/html/html.c @@ -240,7 +240,7 @@ rndr_header(struct buf *ob, const struct buf *text, int level, void *opaque) BUFPUTSL(ob, ""); options->outline_data.open_section_count--; } - BUFPUTSL(ob, "
"); + bufprintf(ob, "
\n", level); options->outline_data.open_section_count++; options->outline_data.current_level = level; }