Skip to content

Commit

Permalink
Add wiki formatting variant.
Browse files Browse the repository at this point in the history
  • Loading branch information
andre-d authored and spladug committed Sep 6, 2012
1 parent 21e9ecf commit fba2891
Show file tree
Hide file tree
Showing 3 changed files with 266 additions and 37 deletions.
146 changes: 139 additions & 7 deletions html/html.c
Original file line number Diff line number Diff line change
Expand Up @@ -222,10 +222,15 @@ rndr_header(struct buf *ob, const struct buf *text, int level, void *opaque)
if (ob->size)
bufputc(ob, '\n');

if (options->flags & HTML_TOC)
bufprintf(ob, "<h%d id=\"toc_%d\">", level, options->toc_data.header_count++);
else
if (options->flags & HTML_TOC) {
bufprintf(ob, "<h%d id=\"", level);
if (options->toc_id_prefix) {
bufprintf(ob, options->toc_id_prefix);
}
bufprintf(ob, "toc_%d\">", options->toc_data.header_count++);
} else {
bufprintf(ob, "<h%d>", level);
}

if (text) bufput(ob, text->data, text->size);
bufprintf(ob, "</h%d>\n", level);
Expand Down Expand Up @@ -382,10 +387,121 @@ rndr_image(struct buf *ob, const struct buf *link, const struct buf *title, cons
return 1;
}

int
static void
rndr_html_tag(struct buf *ob, const struct buf *text, void *opaque,
char* tagname, char** whitelist, int tagtype)
{
size_t i, x, z, in_str = 0, seen_equals = 0, done, reset;
struct buf *attr = bufnew(16);
char c;

bufputc(ob, '<');

i = 1 + strlen(tagname);

if(tagtype == HTML_TAG_CLOSE) {
bufputc(ob, '/');
i += 1;
}

bufputs(ob, tagname);

if(tagtype != HTML_TAG_CLOSE) {
for(;i < text->size;i++) {
c = text->data[i];
done = 0;
reset = 0;

switch(c) {
case '>':
if(seen_equals && !in_str) {
done = 1;
reset = 1;
} else {
reset = 1;
}
break;
case '\'':
case '"':
if(!in_str)
in_str = c;
else if(in_str == c)
in_str = !in_str;
break;
default:
if(!in_str) {
switch(c) {
case ' ':
if(seen_equals) {
done = 1;
reset = 1;
} else
reset = 1;
break;
case '=':
if(seen_equals) {
reset = 1;
} else {
for(z=0; whitelist[z]; z++) {
if(strlen(whitelist[z]) != attr->size)
continue;
for(x=0;x < attr->size; x++) {
if(tolower(whitelist[z][x]) != tolower(attr->data[x]))
break;
}
if(x == attr->size)
seen_equals = 1;
}
if(!seen_equals)
reset = 1;
}
break;
}
}
}

if(done) {
bufputc(ob, ' ');
bufput(ob, attr->data, attr->size);
}

if(reset) {
seen_equals = 0;
in_str = 0;
bufreset(attr);
} else {
bufputc(attr, c);
}
}
}

bufrelease(attr);

bufputc(ob, '>');

}

static int
rndr_raw_html(struct buf *ob, const struct buf *text, void *opaque)
{
struct html_renderopt *options = opaque;
char** whitelist = options->html_element_whitelist;
int i, tagtype;


/* Items on the whitelist ignore all other flags and just output */
if (((options->flags & HTML_ALLOW_ELEMENT_WHITELIST) != 0) && whitelist) {
for(i = 0; whitelist[i]; i++) {
tagtype = sdhtml_is_tag(text->data, text->size, whitelist[i]);
if(tagtype != HTML_TAG_NONE) {
rndr_html_tag(ob, text, opaque,
whitelist[i],
options->html_attr_whitelist,
tagtype);
return 1;
}
}
}

/* HTML_ESCAPE overrides SKIP_HTML, SKIP_STYLE, SKIP_LINKS and SKIP_IMAGES
* It doens't see if there are any valid tags, just escape all of them. */
Expand Down Expand Up @@ -516,7 +632,13 @@ toc_header(struct buf *ob, const struct buf *text, int level, void *opaque)
BUFPUTSL(ob,"</li>\n<li>\n");
}

bufprintf(ob, "<a href=\"#toc_%d\">", options->toc_data.header_count++);
bufprintf(ob, "<a href=\"#");

if (options->toc_id_prefix) {
bufprintf(ob, options->toc_id_prefix);
}

bufprintf(ob, "toc_%d\">", options->toc_data.header_count++);
if (text)
escape_html(ob, text->data, text->size);
BUFPUTSL(ob, "</a>\n");
Expand All @@ -530,6 +652,14 @@ toc_link(struct buf *ob, const struct buf *link, const struct buf *title, const
return 1;
}

static void
reset_toc(struct buf *ob, void *opaque)
{
struct html_renderopt *options = opaque;

memset(&(options->toc_data), 0, sizeof(options->toc_data));
}

static void
toc_finalize(struct buf *ob, void *opaque)
{
Expand All @@ -539,6 +669,8 @@ toc_finalize(struct buf *ob, void *opaque)
BUFPUTSL(ob, "</li>\n</ul>\n");
options->toc_data.current_level--;
}

reset_toc(ob, opaque);
}

void
Expand Down Expand Up @@ -577,7 +709,7 @@ sdhtml_toc_renderer(struct sd_callbacks *callbacks, struct html_renderopt *optio
};

memset(options, 0x0, sizeof(struct html_renderopt));
options->flags = HTML_TOC;
options->flags = HTML_TOC | HTML_SKIP_HTML;

memcpy(callbacks, &cb_default, sizeof(struct sd_callbacks));
}
Expand Down Expand Up @@ -614,7 +746,7 @@ sdhtml_renderer(struct sd_callbacks *callbacks, struct html_renderopt *options,
rndr_normal_text,

NULL,
NULL,
reset_toc,
};

/* Prepare the options pointer */
Expand Down
6 changes: 6 additions & 0 deletions html/html.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,12 @@ struct html_renderopt {
int level_offset;
} toc_data;

char* toc_id_prefix;

unsigned int flags;

char** html_element_whitelist;
char** html_attr_whitelist;

/* extra callbacks */
void (*link_attributes)(struct buf *ob, const struct buf *url, void *self);
Expand All @@ -49,6 +54,7 @@ typedef enum {
HTML_HARD_WRAP = (1 << 7),
HTML_USE_XHTML = (1 << 8),
HTML_ESCAPE = (1 << 9),
HTML_ALLOW_ELEMENT_WHITELIST = (1 << 10),
} html_render_mode;

typedef enum {
Expand Down
Loading

0 comments on commit fba2891

Please sign in to comment.