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
diff --git a/html/html.c b/html/html.c
index 7f08ee8e..803eaf5d 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)
{
@@ -169,6 +170,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)
{
@@ -214,11 +227,23 @@ 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->flags & HTML_OUTLINE)
+ {
+ if(options->outline_data.current_level >= level)
+ {
+ BUFPUTSL(ob, "");
+ options->outline_data.open_section_count--;
+ }
+ bufprintf(ob, "\n", 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++);
@@ -486,6 +511,21 @@ 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;
+
+ if (options->flags & HTML_OUTLINE) {
+ for(i = 0; i < options->outline_data.open_section_count; i++)
+ {
+ BUFPUTSL(ob, "\n\n");
+ }
+ }
+}
+
+
static void
toc_header(struct buf *ob, const struct buf *text, int level, void *opaque)
{
@@ -564,6 +604,7 @@ sdhtml_toc_renderer(struct sd_callbacks *callbacks, struct html_renderopt *optio
toc_link,
NULL,
rndr_triple_emphasis,
+ rndr_ins,
rndr_strikethrough,
rndr_superscript,
@@ -572,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));
@@ -605,6 +648,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,
@@ -613,6 +657,8 @@ sdhtml_renderer(struct sd_callbacks *callbacks, struct html_renderopt *options,
NULL,
NULL,
+
+ NULL, //rndr_finalize,
};
/* Prepare the options pointer */
@@ -622,6 +668,14 @@ sdhtml_renderer(struct sd_callbacks *callbacks, struct html_renderopt *options,
/* 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 4c8810d4..f2556fac 100644
--- a/html/html.h
+++ b/html/html.h
@@ -34,6 +34,11 @@ struct html_renderopt {
unsigned int flags;
+ struct {
+ int current_level;
+ int open_section_count;
+ } outline_data;
+
/* extra callbacks */
void (*link_attributes)(struct buf *ob, const struct buf *url, void *self);
};
@@ -49,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 260483d6..207b0647 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)
@@ -2515,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 6f6553ec..910b2fa8 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);
@@ -97,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;