Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Updated version and fixed edgecase bug for longer markdown docs

  • Loading branch information...
commit bc3e8a330a71705f379665f27ca6a0e3bdaff36a 2 parents d6bd176 + c2f6a7f
benmills authored
View
5 README.mkd
@@ -39,7 +39,7 @@ var sys = require('sys');
var markdown = require('robotskirt');
fs.readFile('README.mkd', function (err, data) {
- markdown.toHtml(data, function (html) {
+ markdown.toHtml(data.toString(), function (html) {
sys.puts(html);
});
});
@@ -51,7 +51,8 @@ If you would like to parse your markdown synchronously you can use the `toHtmlSy
var html = markdown.toHtmlSync("*sync!*");
```
-Special Thanks
+Contributors
------------
* [Phinze](https://github.com/phinze)
+* [Tim Branyen](https://github.com/tbranyen)
View
10 example.js
@@ -11,8 +11,8 @@ markdown.toHtml("# async", function (html) {
sys.puts(markdown.toHtmlSync("# sync markdown parsing.."));
//Open a file and parse it
-//fs.readFile('README.mkd', function (err, data) {
- //markdown.toHtml(data, function (html) {
- //sys.puts(html);
- //});
-//});
+fs.readFile('README.mkd', function (err, data) {
+ markdown.toHtml(data.toString(), function (html) {
+ sys.puts(html);
+ });
+});
View
2  package.json
@@ -2,7 +2,7 @@
, "description": "A node wrapper for the awesome C markdown parsing library, upskirt."
, "tags": ["upskirt", "robot", "markdown", "mkd"]
, "author" : "Ben Mills <ben@bmdev.org>"
-, "version": "0.2.1"
+, "version": "0.2.2"
, "lib": "./build/default"
, "main": "./build/default/robotskirt"
, "scripts": { "publish": "node-waf configure build" }
View
1  src/array.h
@@ -21,7 +21,6 @@
#include <stdlib.h>
-
/********************
* TYPE DEFINITIONS *
********************/
View
BIN  src/array.o
Binary file not shown
View
36 src/buffer.c
@@ -23,6 +23,7 @@
*/
#define BUFFER_STDARG
+#define BUFFER_MAX_ALLOC_SIZE (1024 * 1024 * 16) //16mb
#include "buffer.h"
@@ -147,6 +148,25 @@ bufdup(const struct buf *src, size_t dupunit) {
#endif
return ret; }
+/* bufgrow • increasing the allocated size to the given value */
+int
+bufgrow(struct buf *buf, size_t neosz) {
+ size_t neoasz;
+ void *neodata;
+ if (!buf || !buf->unit || neosz > BUFFER_MAX_ALLOC_SIZE) return 0;
+ if (buf->asize >= neosz) return 1;
+ neoasz = buf->asize + buf->unit;
+ while (neoasz < neosz) neoasz += buf->unit;
+ neodata = realloc(buf->data, neoasz);
+ if (!neodata) return 0;
+#ifdef BUFFER_STATS
+ buffer_stat_alloc_bytes += (neoasz - buf->asize);
+#endif
+ buf->data = neodata;
+ buf->asize = neoasz;
+ return 1; }
+
+
/* bufnew • allocation of a new buffer */
struct buf *
bufnew(size_t unit) {
@@ -168,7 +188,7 @@ void
bufnullterm(struct buf *buf) {
if (!buf || !buf->unit) return;
if (buf->size < buf->asize && buf->data[buf->size] == 0) return;
- if (bufgrow(buf, buf->size + 1))
+ if (buf->size + 1 <= buf->asize || bufgrow(buf, buf->size + 1))
buf->data[buf->size] = 0; }
@@ -185,7 +205,9 @@ bufprintf(struct buf *buf, const char *fmt, ...) {
/* bufput • appends raw data to a buffer */
void
bufput(struct buf *buf, const void *data, size_t len) {
- if (!buf || !bufgrow(buf, buf->size + len)) return;
+ if (!buf) return;
+ if (buf->size + len > buf->asize && !bufgrow(buf, buf->size + len))
+ return;
memcpy(buf->data + buf->size, data, len);
buf->size += len; }
@@ -196,6 +218,16 @@ bufputs(struct buf *buf, const char *str) {
bufput(buf, str, strlen (str)); }
+/* bufputc • appends a single char to a buffer */
+void
+bufputc(struct buf *buf, char c) {
+ if (!buf) return;
+ if (buf->size + 1 > buf->asize && !bufgrow(buf, buf->size + 1))
+ return;
+ buf->data[buf->size] = c;
+ buf->size += 1; }
+
+
/* bufrelease • decrease the reference count and free the buffer if needed */
void
bufrelease(struct buf *buf) {
View
45 src/buffer.h
@@ -21,7 +21,13 @@
#include <stddef.h>
-#define BUFFER_MAX_ALLOC_SIZE (1024 * 1024 * 16) /* 16mb */
+#if defined(_MSC_VER)
+#define __attribute__(x)
+#define inline
+#define strncasecmp _strnicmp
+#define snprintf _snprintf
+#define va_copy(d,s) ((d) = (s))
+#endif
/********************
* TYPE DEFINITIONS *
@@ -73,7 +79,7 @@ bufcmp(const struct buf *, const struct buf *);
int
bufcmps(const struct buf *, const char *);
-/* bufprefix * compare the beggining of a buffer with a string */
+/* bufprefix * compare the beginning of a buffer with a string */
int
bufprefix(const struct buf *buf, const char *prefix);
@@ -82,6 +88,10 @@ struct buf *
bufdup(const struct buf *, size_t)
__attribute__ ((malloc));
+/* bufgrow • increasing the allocated size to the given value */
+int
+bufgrow(struct buf *, size_t);
+
/* bufnew • allocation of a new buffer */
struct buf *
bufnew(size_t)
@@ -104,6 +114,10 @@ bufput(struct buf *, const void*, size_t);
void
bufputs(struct buf *, const char*);
+/* bufputc • appends a single char to a buffer */
+void
+bufputc(struct buf *, char);
+
/* bufrelease • decrease the reference count and free the buffer if needed */
void
bufrelease(struct buf *);
@@ -135,33 +149,6 @@ vbufprintf(struct buf *, const char*, va_list);
#endif /* def BUFFER_STDARG */
-#include <stdlib.h>
-
-/* bufgrow • increasing the allocated size to the given value */
-static inline int
-bufgrow(struct buf *buf, size_t neosz) {
- size_t neoasz;
- void *neodata;
- if (!buf || !buf->unit || neosz > BUFFER_MAX_ALLOC_SIZE) return 0;
- if (buf->asize >= neosz) return 1;
- neoasz = buf->asize + buf->unit;
- while (neoasz < neosz) neoasz += buf->unit;
- neodata = realloc(buf->data, neoasz);
- if (!neodata) return 0;
-#ifdef BUFFER_STATS
- buffer_stat_alloc_bytes += (neoasz - buf->asize);
-#endif
- buf->data = (char*)neodata;
- buf->asize = neoasz;
- return 1; }
-
-/* bufputc • appends a single char to a buffer */
-static inline void
-bufputc(struct buf *buf, char c) {
- if (!buf || !bufgrow(buf, buf->size + 1)) return;
- buf->data[buf->size] = c;
- buf->size += 1; }
-
#endif /* ndef LITHIUM_BUFFER_H */
/* vim: set filetype=c: */
View
BIN  src/buffer.o
Binary file not shown
View
321 src/xhtml.c → src/html.c
@@ -16,25 +16,21 @@
*/
#include "markdown.h"
-#include "xhtml.h"
+#include "html.h"
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
-struct xhtml_renderopt {
+struct html_renderopt {
struct {
int header_count;
int current_level;
} toc_data;
- struct {
- int in_squote;
- int in_dquote;
- } quotes;
-
unsigned int flags;
+ const char *close_tag;
};
static inline void
@@ -49,9 +45,9 @@ put_scaped_char(struct buf *ob, char c)
}
}
-/* lus_attr_escape • copy the buffer entity-escaping '<', '>', '&' and '"' */
+/* attr_escape • copy the buffer entity-escaping '<', '>', '&' and '"' */
static void
-lus_attr_escape(struct buf *ob, const char *src, size_t size)
+attr_escape(struct buf *ob, const char *src, size_t size)
{
size_t i = 0, org;
while (i < size) {
@@ -109,12 +105,12 @@ is_html_tag(struct buf *tag, const char *tagname)
static int
rndr_autolink(struct buf *ob, struct buf *link, enum mkd_autolink type, void *opaque)
{
- struct xhtml_renderopt *options = opaque;
+ struct html_renderopt *options = opaque;
if (!link || !link->size)
return 0;
- if ((options->flags & XHTML_SAFELINK) != 0 &&
+ if ((options->flags & HTML_SAFELINK) != 0 &&
!is_safe_link(link->data, link->size) &&
type != MKDA_EMAIL)
return 0;
@@ -131,9 +127,9 @@ rndr_autolink(struct buf *ob, struct buf *link, enum mkd_autolink type, void *op
* want to print the `mailto:` prefix
*/
if (bufprefix(link, "mailto:") == 0) {
- lus_attr_escape(ob, link->data + 7, link->size - 7);
+ attr_escape(ob, link->data + 7, link->size - 7);
} else {
- lus_attr_escape(ob, link->data, link->size);
+ attr_escape(ob, link->data, link->size);
}
BUFPUTSL(ob, "</a>");
@@ -147,14 +143,24 @@ rndr_blockcode(struct buf *ob, struct buf *text, struct buf *lang, void *opaque)
if (ob->size) bufputc(ob, '\n');
if (lang && lang->size) {
- size_t i = 0;
+ size_t i, cls;
BUFPUTSL(ob, "<pre><code class=\"");
- for (i = 0; i < lang->size; ++i) {
- if (lang->data[i] == '.' && (i == 0 || isspace(lang->data[i - 1])))
- continue;
+ for (i = 0, cls = 0; i < lang->size; ++i, ++cls) {
+ while (i < lang->size && isspace(lang->data[i]))
+ i++;
+
+ if (i < lang->size) {
+ size_t org = i;
+ while (i < lang->size && !isspace(lang->data[i]))
+ i++;
+
+ if (lang->data[org] == '.')
+ org++;
- bufputc(ob, lang->data[i]);
+ if (cls) bufputc(ob, ' ');
+ attr_escape(ob, lang->data + org, i - org);
+ }
}
BUFPUTSL(ob, "\">");
@@ -162,7 +168,7 @@ rndr_blockcode(struct buf *ob, struct buf *text, struct buf *lang, void *opaque)
BUFPUTSL(ob, "<pre><code>");
if (text)
- lus_attr_escape(ob, text->data, text->size);
+ attr_escape(ob, text->data, text->size);
BUFPUTSL(ob, "</code></pre>\n");
}
@@ -194,21 +200,20 @@ rndr_blockcode_github(struct buf *ob, struct buf *text, struct buf *lang, void *
size_t i = 0;
BUFPUTSL(ob, "<pre lang=\"");
- for (; i < lang->size; ++i)
- if (isspace(lang->data[i]))
- break;
+ while (i < lang->size && !isspace(lang->data[i]))
+ i++;
if (lang->data[0] == '.')
- bufput(ob, lang->data + 1, i - 1);
+ attr_escape(ob, lang->data + 1, i - 1);
else
- bufput(ob, lang->data, i);
+ attr_escape(ob, lang->data, i);
BUFPUTSL(ob, "\"><code>");
} else
BUFPUTSL(ob, "<pre><code>");
if (text)
- lus_attr_escape(ob, text->data, text->size);
+ attr_escape(ob, text->data, text->size);
BUFPUTSL(ob, "</code></pre>\n");
}
@@ -225,7 +230,7 @@ static int
rndr_codespan(struct buf *ob, struct buf *text, void *opaque)
{
BUFPUTSL(ob, "<code>");
- if (text) lus_attr_escape(ob, text->data, text->size);
+ if (text) attr_escape(ob, text->data, text->size);
BUFPUTSL(ob, "</code>");
return 1;
}
@@ -268,16 +273,16 @@ rndr_emphasis(struct buf *ob, struct buf *text, void *opaque)
static void
rndr_header(struct buf *ob, struct buf *text, int level, void *opaque)
{
- struct xhtml_renderopt *options = opaque;
+ struct html_renderopt *options = opaque;
if (ob->size)
bufputc(ob, '\n');
- if (options->flags & XHTML_TOC) {
- bufprintf(ob, "<a name=\"toc_%d\"></a>", options->toc_data.header_count++);
- }
+ if (options->flags & HTML_TOC)
+ bufprintf(ob, "<h%d id=\"toc_%d\">", level, options->toc_data.header_count++);
+ else
+ bufprintf(ob, "<h%d>", level);
- bufprintf(ob, "<h%d>", level);
if (text) bufput(ob, text->data, text->size);
bufprintf(ob, "</h%d>\n", level);
}
@@ -285,16 +290,16 @@ rndr_header(struct buf *ob, struct buf *text, int level, void *opaque)
static int
rndr_link(struct buf *ob, struct buf *link, struct buf *title, struct buf *content, void *opaque)
{
- struct xhtml_renderopt *options = opaque;
+ struct html_renderopt *options = opaque;
- if ((options->flags & XHTML_SAFELINK) != 0 && !is_safe_link(link->data, link->size))
+ if ((options->flags & HTML_SAFELINK) != 0 && !is_safe_link(link->data, link->size))
return 0;
BUFPUTSL(ob, "<a href=\"");
- if (link && link->size) lus_attr_escape(ob, link->data, link->size);
+ if (link && link->size) bufput(ob, link->data, link->size);
if (title && title->size) {
BUFPUTSL(ob, "\" title=\"");
- lus_attr_escape(ob, title->data, title->size); }
+ attr_escape(ob, title->data, title->size); }
BUFPUTSL(ob, "\">");
if (content && content->size) bufput(ob, content->data, content->size);
BUFPUTSL(ob, "</a>");
@@ -324,7 +329,7 @@ rndr_listitem(struct buf *ob, struct buf *text, int flags, void *opaque)
static void
rndr_paragraph(struct buf *ob, struct buf *text, void *opaque)
{
- struct xhtml_renderopt *options = opaque;
+ struct html_renderopt *options = opaque;
size_t i = 0;
if (ob->size) bufputc(ob, '\n');
@@ -338,7 +343,7 @@ rndr_paragraph(struct buf *ob, struct buf *text, void *opaque)
return;
BUFPUTSL(ob, "<p>");
- if (options->flags & XHTML_HARD_WRAP) {
+ if (options->flags & HTML_HARD_WRAP) {
size_t org;
while (i < text->size) {
org = i;
@@ -351,17 +356,14 @@ rndr_paragraph(struct buf *ob, struct buf *text, void *opaque)
if (i >= text->size)
break;
- BUFPUTSL(ob, "<br/>\n");
+ BUFPUTSL(ob, "<br");
+ bufputs(ob, options->close_tag);
i++;
}
} else {
bufput(ob, &text->data[i], text->size - i);
}
BUFPUTSL(ob, "</p>\n");
-
- /* Close any open quotes at the end of the paragraph */
- options->quotes.in_squote = 0;
- options->quotes.in_dquote = 0;
}
static void
@@ -389,65 +391,61 @@ rndr_triple_emphasis(struct buf *ob, struct buf *text, void *opaque)
return 1;
}
-
-/**********************
- * XHTML 1.0 RENDERER *
- **********************/
-
static void
rndr_hrule(struct buf *ob, void *opaque)
{
+ struct html_renderopt *options = opaque;
if (ob->size) bufputc(ob, '\n');
- BUFPUTSL(ob, "<hr />\n");
+ BUFPUTSL(ob, "<hr");
+ bufputs(ob, options->close_tag);
}
static int
rndr_image(struct buf *ob, struct buf *link, struct buf *title, struct buf *alt, void *opaque)
{
+ struct html_renderopt *options = opaque;
if (!link || !link->size) return 0;
BUFPUTSL(ob, "<img src=\"");
- lus_attr_escape(ob, link->data, link->size);
+ attr_escape(ob, link->data, link->size);
BUFPUTSL(ob, "\" alt=\"");
if (alt && alt->size)
- lus_attr_escape(ob, alt->data, alt->size);
+ attr_escape(ob, alt->data, alt->size);
if (title && title->size) {
BUFPUTSL(ob, "\" title=\"");
- lus_attr_escape(ob, title->data, title->size); }
- BUFPUTSL(ob, "\" />");
+ attr_escape(ob, title->data, title->size); }
+
+ bufputc(ob, '"');
+ bufputs(ob, options->close_tag);
return 1;
}
static int
rndr_linebreak(struct buf *ob, void *opaque)
{
- BUFPUTSL(ob, "<br />\n");
+ struct html_renderopt *options = opaque;
+ BUFPUTSL(ob, "<br");
+ bufputs(ob, options->close_tag);
return 1;
}
static int
rndr_raw_html(struct buf *ob, struct buf *text, void *opaque)
{
- struct xhtml_renderopt *options = opaque;
- int escape_html = 0;
-
- if (options->flags & XHTML_SKIP_HTML)
- escape_html = 1;
+ struct html_renderopt *options = opaque;
- else if ((options->flags & XHTML_SKIP_STYLE) != 0 && is_html_tag(text, "style"))
- escape_html = 1;
+ if ((options->flags & HTML_SKIP_HTML) != 0)
+ return 1;
- else if ((options->flags & XHTML_SKIP_LINKS) != 0 && is_html_tag(text, "a"))
- escape_html = 1;
+ if ((options->flags & HTML_SKIP_STYLE) != 0 && is_html_tag(text, "style"))
+ return 1;
- else if ((options->flags & XHTML_SKIP_IMAGES) != 0 && is_html_tag(text, "img"))
- escape_html = 1;
+ if ((options->flags & HTML_SKIP_LINKS) != 0 && is_html_tag(text, "a"))
+ return 1;
+ if ((options->flags & HTML_SKIP_IMAGES) != 0 && is_html_tag(text, "img"))
+ return 1;
- if (escape_html)
- lus_attr_escape(ob, text->data, text->size);
- else
- bufput(ob, text->data, text->size);
-
+ bufput(ob, text->data, text->size);
return 1;
}
@@ -501,169 +499,32 @@ rndr_tablecell(struct buf *ob, struct buf *text, int align, void *opaque)
BUFPUTSL(ob, "</td>");
}
-static struct {
- char c0;
- const char *pattern;
- const char *entity;
- int skip;
-} smartypants_subs[] = {
- { '\'', "'s>", "&rsquo;", 0 },
- { '\'', "'t>", "&rsquo;", 0 },
- { '\'', "'re>", "&rsquo;", 0 },
- { '\'', "'ll>", "&rsquo;", 0 },
- { '\'', "'ve>", "&rsquo;", 0 },
- { '\'', "'m>", "&rsquo;", 0 },
- { '\'', "'d>", "&rsquo;", 0 },
- { '-', "--", "&mdash;", 1 },
- { '-', "<->", "&ndash;", 0 },
- { '.', "...", "&hellip;", 2 },
- { '.', ". . .", "&hellip;", 4 },
- { '(', "(c)", "&copy;", 2 },
- { '(', "(r)", "&reg;", 2 },
- { '(', "(tm)", "&trade;", 3 },
- { '3', "<3/4>", "&frac34;", 2 },
- { '3', "<3/4ths>", "&frac34;", 2 },
- { '1', "<1/2>", "&frac12;", 2 },
- { '1', "<1/4>", "&frac14;", 2 },
- { '1', "<1/4th>", "&frac14;", 2 },
- { '&', "&#0;", 0, 3 },
-};
-
-#define SUBS_COUNT (sizeof(smartypants_subs) / sizeof(smartypants_subs[0]))
-
-static inline int
-word_boundary(char c)
-{
- return isspace(c) || ispunct(c);
-}
-
-static int
-smartypants_cmpsub(const struct buf *buf, size_t start, const char *prefix)
-{
- size_t i;
-
- if (prefix[0] == '<') {
- if (start == 0 || !word_boundary(buf->data[start - 1]))
- return 0;
-
- prefix++;
- }
-
- for (i = start; i < buf->size; ++i) {
- char c, p;
-
- c = tolower(buf->data[i]);
- p = *prefix++;
-
- if (p == 0)
- return 1;
-
- if (p == '>')
- return word_boundary(c);
-
- if (c != p)
- return 0;
- }
-
- return (*prefix == '>');
-}
-
-static int
-smartypants_quotes(struct buf *ob, struct buf *text, size_t i, int is_open)
-{
- char ent[8];
-
- if (is_open && i + 1 < text->size && !word_boundary(text->data[i + 1]))
- return 0;
-
- if (!is_open && i > 0 && !word_boundary(text->data[i - 1]))
- return 0;
-
- snprintf(ent, sizeof(ent), "&%c%cquo;",
- is_open ? 'r' : 'l',
- text->data[i] == '\'' ? 's' : 'd');
-
- bufputs(ob, ent);
- return 1;
-}
-
static void
rndr_normal_text(struct buf *ob, struct buf *text, void *opaque)
{
if (text)
- lus_attr_escape(ob, text->data, text->size);
-}
-
-static void
-rndr_smartypants(struct buf *ob, struct buf *text, void *opaque)
-{
- struct xhtml_renderopt *options = opaque;
- size_t i;
-
- if (!text)
- return;
-
- for (i = 0; i < text->size; ++i) {
- size_t sub;
- char c = text->data[i];
-
- for (sub = 0; sub < SUBS_COUNT; ++sub) {
- if (c == smartypants_subs[sub].c0 &&
- smartypants_cmpsub(text, i, smartypants_subs[sub].pattern)) {
-
- if (smartypants_subs[sub].entity)
- bufputs(ob, smartypants_subs[sub].entity);
-
- i += smartypants_subs[sub].skip;
- break;
- }
- }
-
- if (sub < SUBS_COUNT)
- continue;
-
- switch (c) {
- case '\"':
- if (smartypants_quotes(ob, text, i, options->quotes.in_dquote)) {
- options->quotes.in_dquote = !options->quotes.in_dquote;
- continue;
- }
- break;
-
- case '\'':
- if (smartypants_quotes(ob, text, i, options->quotes.in_squote)) {
- options->quotes.in_squote = !options->quotes.in_squote;
- continue;
- }
- break;
- }
-
- /*
- * Copy raw character
- */
- put_scaped_char(ob, c);
- }
+ attr_escape(ob, text->data, text->size);
}
static void
toc_header(struct buf *ob, struct buf *text, int level, void *opaque)
{
- struct xhtml_renderopt *options = opaque;
+ struct html_renderopt *options = opaque;
- if (level > options->toc_data.current_level) {
- if (level > 1)
+ while (level > options->toc_data.current_level) {
+ if (options->toc_data.current_level > 0)
BUFPUTSL(ob, "<li>");
BUFPUTSL(ob, "<ul>\n");
+ options->toc_data.current_level++;
}
-
- if (level < options->toc_data.current_level) {
+
+ while (level < options->toc_data.current_level) {
BUFPUTSL(ob, "</ul>");
if (options->toc_data.current_level > 1)
BUFPUTSL(ob, "</li>\n");
+ options->toc_data.current_level--;
}
- options->toc_data.current_level = level;
-
bufprintf(ob, "<li><a href=\"#toc_%d\">", options->toc_data.header_count++);
if (text)
bufput(ob, text->data, text->size);
@@ -673,7 +534,7 @@ toc_header(struct buf *ob, struct buf *text, int level, void *opaque)
static void
toc_finalize(struct buf *ob, void *opaque)
{
- struct xhtml_renderopt *options = opaque;
+ struct html_renderopt *options = opaque;
while (options->toc_data.current_level > 1) {
BUFPUTSL(ob, "</ul></li>\n");
@@ -685,7 +546,7 @@ toc_finalize(struct buf *ob, void *opaque)
}
void
-ups_toc_renderer(struct mkd_renderer *renderer)
+upshtml_toc_renderer(struct mkd_renderer *renderer)
{
static const struct mkd_renderer toc_render = {
NULL,
@@ -720,17 +581,20 @@ ups_toc_renderer(struct mkd_renderer *renderer)
NULL
};
- struct xhtml_renderopt *options;
- options = calloc(1, sizeof(struct xhtml_renderopt));
- options->flags = XHTML_TOC;
+ struct html_renderopt *options;
+ options = calloc(1, sizeof(struct html_renderopt));
+ options->flags = HTML_TOC;
memcpy(renderer, &toc_render, sizeof(struct mkd_renderer));
renderer->opaque = options;
}
void
-ups_xhtml_renderer(struct mkd_renderer *renderer, unsigned int render_flags)
+upshtml_renderer(struct mkd_renderer *renderer, unsigned int render_flags)
{
+ static const char *xhtml_close = "/>\n";
+ static const char *html_close = ">\n";
+
static const struct mkd_renderer renderer_default = {
rndr_blockcode,
rndr_blockquote,
@@ -764,30 +628,31 @@ ups_xhtml_renderer(struct mkd_renderer *renderer, unsigned int render_flags)
NULL
};
- struct xhtml_renderopt *options;
- options = calloc(1, sizeof(struct xhtml_renderopt));
+ struct html_renderopt *options;
+ options = calloc(1, sizeof(struct html_renderopt));
options->flags = render_flags;
+ options->close_tag = (render_flags & HTML_USE_XHTML) ? xhtml_close : html_close;
memcpy(renderer, &renderer_default, sizeof(struct mkd_renderer));
renderer->opaque = options;
- if (render_flags & XHTML_SKIP_IMAGES)
+ if (render_flags & HTML_SKIP_IMAGES)
renderer->image = NULL;
- if (render_flags & XHTML_SKIP_LINKS) {
+ if (render_flags & HTML_SKIP_LINKS) {
renderer->link = NULL;
renderer->autolink = NULL;
}
- if (render_flags & XHTML_SMARTYPANTS)
- renderer->normal_text = rndr_smartypants;
+ if (render_flags & HTML_SKIP_HTML)
+ renderer->blockhtml = NULL;
- if (render_flags & XHTML_GITHUB_BLOCKCODE)
+ if (render_flags & HTML_GITHUB_BLOCKCODE)
renderer->blockcode = rndr_blockcode_github;
}
void
-ups_free_renderer(struct mkd_renderer *renderer)
+upshtml_free_renderer(struct mkd_renderer *renderer)
{
free(renderer->opaque);
}
View
35 src/xhtml.h → src/html.h
@@ -14,30 +14,35 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#ifndef UPSKIRT_XHTML_H
-#define UPSKIRT_XHTML_H
+#ifndef UPSKIRT_HTML_H
+#define UPSKIRT_HTML_H
+
+#include "markdown.h"
typedef enum {
- XHTML_SKIP_HTML = (1 << 0),
- XHTML_SKIP_STYLE = (1 << 1),
- XHTML_SKIP_IMAGES = (1 << 2),
- XHTML_SKIP_LINKS = (1 << 3),
- XHTML_SMARTYPANTS = (1 << 4),
- XHTML_EXPAND_TABS = (1 << 5),
- XHTML_SAFELINK = (1 << 7),
- XHTML_TOC = (1 << 8),
- XHTML_HARD_WRAP = (1 << 9),
- XHTML_GITHUB_BLOCKCODE = (1 << 10),
+ HTML_SKIP_HTML = (1 << 0),
+ HTML_SKIP_STYLE = (1 << 1),
+ HTML_SKIP_IMAGES = (1 << 2),
+ HTML_SKIP_LINKS = (1 << 3),
+ HTML_EXPAND_TABS = (1 << 5),
+ HTML_SAFELINK = (1 << 7),
+ HTML_TOC = (1 << 8),
+ HTML_HARD_WRAP = (1 << 9),
+ HTML_GITHUB_BLOCKCODE = (1 << 10),
+ HTML_USE_XHTML = (1 << 11),
} render_mode;
extern void
-ups_xhtml_renderer(struct mkd_renderer *renderer, unsigned int render_flags);
+upshtml_renderer(struct mkd_renderer *renderer, unsigned int render_flags);
+
+extern void
+upshtml_toc_renderer(struct mkd_renderer *renderer);
extern void
-ups_toc_renderer(struct mkd_renderer *renderer);
+upshtml_free_renderer(struct mkd_renderer *renderer);
extern void
-ups_free_renderer(struct mkd_renderer *renderer);
+upshtml_smartypants(struct buf *ob, struct buf *text);
#endif
View
262 src/markdown.c
@@ -22,7 +22,7 @@
#include <assert.h>
#include <string.h>
-#include <strings.h> /* for strncasecmp */
+//#include <strings.h> /* for strncasecmp */
#include <ctype.h>
#include <stdio.h>
@@ -56,7 +56,9 @@ static size_t char_codespan(struct buf *ob, struct render *rndr, char *data, siz
static size_t char_escape(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t size);
static size_t char_entity(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t size);
static size_t char_langle_tag(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t size);
-static size_t char_autolink(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t size);
+static size_t char_autolink_url(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t size);
+static size_t char_autolink_email(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t size);
+static size_t char_autolink_www(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t size);
static size_t char_link(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t size);
enum markdown_char_t {
@@ -68,7 +70,9 @@ enum markdown_char_t {
MD_CHAR_LANGLE,
MD_CHAR_ESCAPE,
MD_CHAR_ENTITITY,
- MD_CHAR_AUTOLINK,
+ MD_CHAR_AUTOLINK_URL,
+ MD_CHAR_AUTOLINK_EMAIL,
+ MD_CHAR_AUTOLINK_WWW
};
static char_trigger markdown_char_ptrs[] = {
@@ -80,7 +84,9 @@ static char_trigger markdown_char_ptrs[] = {
&char_langle_tag,
&char_escape,
&char_entity,
- &char_autolink,
+ &char_autolink_url,
+ &char_autolink_email,
+ &char_autolink_www,
};
/* render • structure containing one particular render */
@@ -224,7 +230,7 @@ cmp_html_tag(const void *a, const void *b)
{
const struct html_tag *hta = a;
const struct html_tag *htb = b;
- if (hta->size != htb->size) return (int)((ssize_t)hta->size - (ssize_t)htb->size);
+ if (hta->size != htb->size) return (int)(hta->size - htb->size);
return strncasecmp(hta->text, htb->text, hta->size);
}
@@ -306,7 +312,7 @@ tag_length(char *data, size_t size, enum mkd_autolink *autolink)
/* scheme test */
*autolink = MKDA_NOT_AUTOLINK;
- /* try to find the beggining of an URI */
+ /* try to find the beginning of an URI */
while (i < size && (isalnum(data[i]) || data[i] == '.' || data[i] == '+' || data[i] == '-'))
i++;
@@ -357,7 +363,7 @@ parse_inline(struct buf *ob, struct render *rndr, char *data, size_t size)
struct buf work = { 0, 0, 0, 0, 0 };
if (rndr->work_bufs[BUFFER_SPAN].size +
- rndr->work_bufs[BUFFER_BLOCK].size > rndr->max_nesting)
+ rndr->work_bufs[BUFFER_BLOCK].size > (int)rndr->max_nesting)
return;
while (i < size) {
@@ -651,9 +657,13 @@ char_codespan(struct buf *ob, struct render *rndr, char *data, size_t offset, si
static size_t
char_escape(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t size)
{
+ static const char *escape_chars = "\\`*_{}[]()#+-.!:|&<>";
struct buf work = { 0, 0, 0, 0, 0 };
if (size > 1) {
+ if (strchr(escape_chars, data[1]) == NULL)
+ return 0;
+
if (rndr->make.normal_text) {
work.data = data + 1;
work.size = 1;
@@ -666,7 +676,7 @@ char_escape(struct buf *ob, struct render *rndr, char *data, size_t offset, size
}
/* char_entity • '&' escaped when it doesn't belong to an entity */
-/* valid entities are assumed to be anything mathing &#?[A-Za-z0-9]+; */
+/* valid entities are assumed to be anything matching &#?[A-Za-z0-9]+; */
static size_t
char_entity(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t size)
{
@@ -721,33 +731,47 @@ char_langle_tag(struct buf *ob, struct render *rndr, char *data, size_t offset,
}
static size_t
-char_autolink(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t size)
+autolink_delim(char *data, size_t link_end, size_t offset, size_t size)
{
- struct buf work = { data, 0, 0, 0, 0 };
- char copen = 0;
- size_t link_end;
+ char cclose, copen = 0;
- if (offset > 0) {
- if (!isspace(data[-1]) && !ispunct(data[-1]))
- return 0;
+ /* See if the link finishes with a punctuation sign that can be skipped. */
+ switch (data[link_end - 1]) {
+ case '?':
+ case '!':
+ case '.':
+ case ',':
+ link_end--;
+ break;
+
+ case ';':
+ {
+ size_t new_end = link_end - 2;
+
+ while (new_end > 0 && isalpha(data[new_end]))
+ new_end--;
+
+ if (new_end < link_end - 2 && data[new_end] == '&')
+ link_end = new_end;
+ else
+ link_end--;
+
+ break;
}
- if (!is_safe_link(data, size))
- return 0;
+ case '>':
+ while (link_end > 0 && data[link_end] != '<')
+ link_end--;
- link_end = 0;
- while (link_end < size && !isspace(data[link_end]))
- link_end++;
+ if (link_end == 0)
+ return 0;
- /* Skip punctuation at the end of the link */
- if ((data[link_end - 1] == '.' ||
- data[link_end - 1] == ',' ||
- data[link_end - 1] == ';') &&
- data[link_end - 2] != '\\')
- link_end--;
+ break;
+ }
- /* See if the link finishes with a punctuation sign that can be closed. */
- switch (data[link_end - 1]) {
+ cclose = data[link_end - 1];
+
+ switch (cclose) {
case '"': copen = '"'; break;
case '\'': copen = '\''; break;
case ')': copen = '('; break;
@@ -756,10 +780,9 @@ char_autolink(struct buf *ob, struct render *rndr, char *data, size_t offset, si
}
if (copen != 0) {
- char *buf_start = data - offset;
- char *buf_end = data + link_end - 2;
-
- size_t open_delim = 1;
+ size_t closing = 0;
+ size_t opening = 0;
+ size_t i = 0;
/* Try to close the final punctuation sign in this same line;
* if we managed to close it outside of the URL, that means that it's
@@ -781,31 +804,163 @@ char_autolink(struct buf *ob, struct render *rndr, char *data, size_t offset, si
* => foo http://www.pokemon.com/Pikachu_(Electric)
*/
- while (buf_end >= buf_start && *buf_end != '\n' && open_delim) {
- if (*buf_end == data[link_end - 1])
- open_delim++;
+ while (i < link_end) {
+ if (data[i] == copen)
+ opening++;
+ else if (data[i] == cclose)
+ closing++;
- if (*buf_end == copen)
- open_delim--;
-
- buf_end--;
+ i++;
}
- if (open_delim == 0)
+ if (closing != opening)
link_end--;
}
+ return link_end;
+}
+
+
+static size_t
+char_autolink_www(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t size)
+{
+ struct buf work = { 0, 0, 0, 0, 0 };
+ size_t link_end;
+ int np = 0;
+
+ if (offset > 0 && !ispunct(data[-1]) && !isspace(data[-1]))
+ return 0;
+
+ if (size < 4 || memcmp(data, "www.", STRLEN("www.")) != 0)
+ return 0;
+
+ link_end = 0;
+ while (link_end < size && !isspace(data[link_end])) {
+ if (data[link_end] == '.')
+ np++;
+
+ link_end++;
+ }
+
+ if (np < 2)
+ return 0;
+
+ link_end = autolink_delim(data, link_end, offset, size);
+
+ if (link_end == 0)
+ return 0;
+
work.size = link_end;
+ work.data = data;
+
+ if (rndr->make.link) {
+ struct buf *u_link = rndr_newbuf(rndr, BUFFER_SPAN);
+ BUFPUTSL(u_link, "http://");
+ unscape_text(u_link, &work);
+
+ rndr->make.link(ob, u_link, NULL, &work, rndr->make.opaque);
+ rndr_popbuf(rndr, BUFFER_SPAN);
+ }
+
+ return link_end;
+}
+
+static size_t
+char_autolink_email(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t size)
+{
+ struct buf work = { 0, 0, 0, 0, 0 };
+ size_t link_end, rewind;
+ int nb = 0, np = 0;
+
+ for (rewind = 0; rewind < offset; ++rewind) {
+ char c = data[-rewind - 1];
+
+ if (isalnum(c))
+ continue;
+
+ if (strchr(".+-_", c) != NULL)
+ continue;
+
+ break;
+ }
+
+ if (rewind == 0)
+ return 0;
+
+ for (link_end = 0; link_end < size; ++link_end) {
+ char c = data[link_end];
+
+ if (isalnum(c))
+ continue;
+
+ if (c == '@')
+ nb++;
+ else if (c == '.' && link_end < size - 1)
+ np++;
+ else if (c != '-' && c != '_')
+ break;
+ }
+
+ if (link_end < 2 || nb != 1 || np == 0)
+ return 0;
+
+ link_end = autolink_delim(data, link_end, offset, size);
+
+ if (link_end == 0)
+ return 0;
+
+ work.size = link_end + rewind;
+ work.data = data - rewind;
if (rndr->make.autolink) {
struct buf *u_link = rndr_newbuf(rndr, BUFFER_SPAN);
unscape_text(u_link, &work);
+ ob->size -= rewind;
+ rndr->make.autolink(ob, u_link, MKDA_EMAIL, rndr->make.opaque);
+ rndr_popbuf(rndr, BUFFER_SPAN);
+ }
+
+ return link_end;
+}
+
+static size_t
+char_autolink_url(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t size)
+{
+ struct buf work = { 0, 0, 0, 0, 0 };
+ size_t link_end, rewind = 0;
+
+ if (size < 4 || data[1] != '/' || data[2] != '/')
+ return 0;
+
+ while (rewind < offset && isalpha(data[-rewind - 1]))
+ rewind++;
+
+ if (!is_safe_link(data - rewind, size + rewind))
+ return 0;
+
+ link_end = 0;
+ while (link_end < size && !isspace(data[link_end]))
+ link_end++;
+
+ link_end = autolink_delim(data, link_end, offset, size);
+
+ if (link_end == 0)
+ return 0;
+
+ work.size = link_end + rewind;
+ work.data = data - rewind;
+
+ if (rndr->make.autolink) {
+ struct buf *u_link = rndr_newbuf(rndr, BUFFER_SPAN);
+ unscape_text(u_link, &work);
+
+ ob->size -= rewind;
rndr->make.autolink(ob, u_link, MKDA_NORMAL, rndr->make.opaque);
rndr_popbuf(rndr, BUFFER_SPAN);
}
- return work.size;
+ return link_end;
}
/* char_link • '[': parsing a link or an image */
@@ -1120,7 +1275,7 @@ is_codefence(char *data, size_t size, struct buf *syntax)
if (i == size || data[i] != '}')
return 0;
- /* strip all whitespace at the beggining and the end
+ /* strip all whitespace at the beginning and the end
* of the {} block */
while (syn > 0 && isspace(syntax->data[0])) {
syntax->data++; syn--;
@@ -1251,7 +1406,7 @@ static void parse_block(struct buf *ob, struct render *rndr,
char *data, size_t size);
-/* parse_blockquote • hanldes parsing of a blockquote fragment */
+/* parse_blockquote • handles parsing of a blockquote fragment */
static size_t
parse_blockquote(struct buf *ob, struct render *rndr, char *data, size_t size)
{
@@ -1296,7 +1451,7 @@ parse_blockquote(struct buf *ob, struct render *rndr, char *data, size_t size)
static size_t
parse_htmlblock(struct buf *ob, struct render *rndr, char *data, size_t size, int do_render);
-/* parse_blockquote • hanldes parsing of a regular paragraph */
+/* parse_blockquote • handles parsing of a regular paragraph */
static size_t
parse_paragraph(struct buf *ob, struct render *rndr, char *data, size_t size)
{
@@ -1376,7 +1531,7 @@ parse_paragraph(struct buf *ob, struct render *rndr, char *data, size_t size)
return end;
}
-/* parse_fencedcode • hanldes parsing of a block-level code fragment */
+/* parse_fencedcode • handles parsing of a block-level code fragment */
static size_t
parse_fencedcode(struct buf *ob, struct render *rndr, char *data, size_t size)
{
@@ -1470,7 +1625,7 @@ parse_listitem(struct buf *ob, struct render *rndr, char *data, size_t size, int
size_t beg = 0, end, pre, sublist = 0, orgpre = 0, i;
int in_empty = 0, has_inside_empty = 0;
- /* keeping book of the first indentation prefix */
+ /* keeping track of the first indentation prefix */
while (orgpre < 3 && orgpre < size && data[orgpre] == ' ')
orgpre++;
@@ -1646,7 +1801,7 @@ htmlblock_end(struct html_tag *tag, struct render *rndr, char *data, size_t size
/* assuming data[0] == '<' && data[1] == '/' already tested */
- /* checking tag is a match */
+ /* checking if tag is a match */
if (tag->size + 3 >= size
|| strncasecmp(data + 2, tag->text, tag->size)
|| data[tag->size + 2] != '>')
@@ -1945,7 +2100,7 @@ parse_block(struct buf *ob, struct render *rndr, char *data, size_t size)
beg = 0;
if (rndr->work_bufs[BUFFER_SPAN].size +
- rndr->work_bufs[BUFFER_BLOCK].size > rndr->max_nesting)
+ rndr->work_bufs[BUFFER_BLOCK].size > (int)rndr->max_nesting)
return;
while (beg < size) {
@@ -2183,14 +2338,9 @@ ups_markdown(struct buf *ob, struct buf *ib, const struct mkd_renderer *rndrer,
rndr.active_char['&'] = MD_CHAR_ENTITITY;
if (extensions & MKDEXT_AUTOLINK) {
- rndr.active_char['h'] = MD_CHAR_AUTOLINK; // http, https
- rndr.active_char['H'] = MD_CHAR_AUTOLINK;
-
- rndr.active_char['f'] = MD_CHAR_AUTOLINK; // ftp
- rndr.active_char['F'] = MD_CHAR_AUTOLINK;
-
- rndr.active_char['m'] = MD_CHAR_AUTOLINK; // mailto
- rndr.active_char['M'] = MD_CHAR_AUTOLINK;
+ rndr.active_char[':'] = MD_CHAR_AUTOLINK_URL;
+ rndr.active_char['@'] = MD_CHAR_AUTOLINK_EMAIL;
+ rndr.active_char['w'] = MD_CHAR_AUTOLINK_WWW;
}
/* Extension data */
View
6 src/markdown.h
@@ -21,10 +21,10 @@
#include "buffer.h"
-#define UPSKIRT_VERSION "1.14.1"
+#define UPSKIRT_VERSION "1.15.2"
#define UPSKIRT_VER_MAJOR 1
-#define UPSKIRT_VER_MINOR 14
-#define UPSKIRT_VER_REVISION 1
+#define UPSKIRT_VER_MINOR 15
+#define UPSKIRT_VER_REVISION 2
/********************
* TYPE DEFINITIONS *
View
BIN  src/markdown.o
Binary file not shown
View
139 src/robotskirt.cc
@@ -1,6 +1,7 @@
#include <v8.h>
#include <node.h>
-#include <string.h>
+#include <node_buffer.h>
+#include <string>
#include <stdlib.h>
#include <unistd.h>
@@ -10,26 +11,40 @@ using namespace v8;
extern "C" {
#include"markdown.h"
- #include"xhtml.h"
+ #include"html.h"
}
-#define READ_UNIT 1024
#define OUTPUT_UNIT 64
+// Credit: @samcday
+// http://sambro.is-super-awesome.com/2011/03/03/creating-a-proper-buffer-in-a-node-c-addon/
+#define MAKE_FAST_BUFFER(NG_SLOW_BUFFER, NG_FAST_BUFFER) \
+ Local<Function> NG_JS_BUFFER = Local<Function>::Cast( \
+ Context::GetCurrent()->Global()->Get( \
+ String::New("Buffer"))); \
+ \
+ Handle<Value> NG_JS_ARGS[3] = { \
+ NG_SLOW_BUFFER->handle_, \
+ Integer::New(Buffer::Length(NG_SLOW_BUFFER)), \
+ Integer::New(0) \
+ }; \
+ \
+ NG_FAST_BUFFER = NG_JS_BUFFER->NewInstance(3, NG_JS_ARGS);
+
static Handle<Value> ToHtmlAsync (const Arguments&);
static int ToHtml (eio_req *);
static int ToHtml_After (eio_req *);
struct request {
Persistent<Function> callback;
- char *in;
- char *out;
- size_t size;
- int in_len;
+ string in;
+ string out;
+ int out_size;
};
static Handle<Value> ToHtmlAsync(const Arguments& args) {
HandleScope scope;
+
const char *usage = "usage: toHtml(markdown_string, callback)";
if (args.Length() != 2) {
return ThrowException(Exception::Error(String::New(usage)));
@@ -37,57 +52,70 @@ static Handle<Value> ToHtmlAsync(const Arguments& args) {
String::Utf8Value in(args[0]);
Local<Function> callback = Local<Function>::Cast(args[1]);
- request *sr = (request *) malloc(sizeof(struct request));
+
+ request *sr = new request;
sr->callback = Persistent<Function>::New(callback);
- sr->in_len = strlen(*in);
- sr->in = (char *) malloc(sr->in_len);
- strncpy(sr->in, *in, sr->in_len);
- sr->out = NULL;
- sr->size = 0;
+ sr->in = *in;
eio_custom(ToHtml, EIO_PRI_DEFAULT, ToHtml_After, sr);
ev_ref(EV_DEFAULT_UC);
- return Undefined();
+
+ return scope.Close( Undefined() );
}
static int ToHtml(eio_req *req) {
- struct request *sr = (struct request *)req->data;
- struct mkd_renderer renderer;
+ request *sr = static_cast<request *>(req->data);
- struct buf input_buf, *output_buf;
+ struct mkd_renderer renderer;
+ struct buf *input_buf, *output_buf;
- memset(&input_buf, 0x0, sizeof(struct buf));
- input_buf.data = sr->in;
- input_buf.size = sr->in_len;
+ // Create input buffer from string
+ input_buf = bufnew(sr->in.size());
+ bufput(input_buf, sr->in.c_str(), sr->in.size());
- output_buf = bufnew(128);
- bufgrow(output_buf, sr->in_len * 1.2f);
+ // Create output buffer and reset size to 0
+ output_buf = bufnew(OUTPUT_UNIT);
+ output_buf->size = 0;
- ups_xhtml_renderer(&renderer, 0);
- ups_markdown(output_buf, &input_buf, &renderer, 0xFF);
- ups_free_renderer(&renderer);
+ // Use new Upskirt HTML to render
+ upshtml_renderer(&renderer, 0);
+ ups_markdown(output_buf, input_buf, &renderer, ~0);
+ upshtml_free_renderer(&renderer);
- //Handle<String> md = String::New(output_buf->data, output_buf->size);
sr->out = output_buf->data;
- sr->size = output_buf->size;
+ sr->out_size = output_buf->size;
+
+ /* cleanup */
+ bufrelease(input_buf);
+ bufrelease(output_buf);
- /* cleanup */
return 0;
}
static int ToHtml_After(eio_req *req) {
HandleScope scope;
+
ev_unref(EV_DEFAULT_UC);
- struct request *sr = (struct request *)req->data;
+ request *sr = static_cast<request *>(req->data);
Local<Value> argv[1];
- argv[0] = String::New(sr->out, sr->size);
+ // Set contents
+ const char* contents = sr->out.c_str();
+
+ // Create and assign fast buffer to arguments array
+ Buffer* buffer = Buffer::New(const_cast<char *>(contents), sr->out_size);
+ Local<Object> fastBuffer;
+ MAKE_FAST_BUFFER(buffer, fastBuffer);
+ argv[0] = fastBuffer;
+
+ // Invoke callback function with html argument
TryCatch try_catch;
sr->callback->Call(Context::GetCurrent()->Global(), 1, argv);
if (try_catch.HasCaught()) {
FatalException(try_catch);
}
+ /* cleanup */
sr->callback.Dispose();
free(sr);
return 0;
@@ -96,36 +124,49 @@ static int ToHtml_After(eio_req *req) {
static Handle<Value> ToHtmlSync(const Arguments &args) {
HandleScope scope;
+ const char *usage = "usage: toHtmlSync(markdown_string)";
if (args.Length() < 1 || !args[0]->IsString()) {
- return ThrowException(Exception::TypeError(String::New("String expected")));
+ return ThrowException(Exception::TypeError(String::New(usage)));
}
- String::Utf8Value in(args[0]);
-
struct mkd_renderer renderer;
- struct buf input_buf, *output_buf;
+ struct buf *input_buf, *output_buf;
- memset(&input_buf, 0x0, sizeof(struct buf));
- input_buf.data = *in;
- input_buf.size = strlen(*in);
+ String::Utf8Value utf8_in(args[0]);
+ string in = *utf8_in;
+ string out;
- output_buf = bufnew(128);
- bufgrow(output_buf, strlen(*in) * 1.2f);
+ // Create input buffer from string
+ input_buf = bufnew(in.size());
+ bufput(input_buf, in.c_str(), in.size());
- ups_xhtml_renderer(&renderer, 0);
- ups_markdown(output_buf, &input_buf, &renderer, 0xFF);
- ups_free_renderer(&renderer);
- Handle<String> md = String::New(output_buf->data, output_buf->size);
+ // Create output buffer and reset size to 0
+ output_buf = bufnew(OUTPUT_UNIT);
+ output_buf->size = 0;
- /* cleanup */
+ // Use new Upskirt HTML to render
+ upshtml_renderer(&renderer, 0);
+ ups_markdown(output_buf, input_buf, &renderer, ~0);
+ upshtml_free_renderer(&renderer);
+
+ out = output_buf->data;
+
+ // Create and assign fast buffer to arguments array
+ int bufferLength = out.size();
+ Buffer* buffer = Buffer::New(const_cast<char *>(out.c_str()), bufferLength);
+ Local<Object> fastBuffer;
+ MAKE_FAST_BUFFER(buffer, fastBuffer);
+
+ /* cleanup */
+ bufrelease(input_buf);
bufrelease(output_buf);
- return scope.Close(md);
+ return scope.Close(fastBuffer);
}
extern "C" void init (Handle<Object> target) {
- HandleScope scope;
+ HandleScope scope;
- target->Set(String::New("version"), String::New("0.2.1"));
- NODE_SET_METHOD(target, "toHtml", ToHtmlAsync);
- NODE_SET_METHOD(target, "toHtmlSync", ToHtmlSync);
+ target->Set(String::New("version"), String::New("0.2.2"));
+ NODE_SET_METHOD(target, "toHtml", ToHtmlAsync);
+ NODE_SET_METHOD(target, "toHtmlSync", ToHtmlSync);
}
View
BIN  src/xhtml.o
Binary file not shown
View
4 wscript
@@ -1,6 +1,6 @@
srcdir = '.'
blddir = 'build'
-VERSION = '0.2.1'
+VERSION = '0.2.2'
def set_options(opt):
opt.tool_options('compiler_cxx')
@@ -17,7 +17,7 @@ def build(bld):
src/markdown.c
src/array.c
src/buffer.c
- src/xhtml.c """
+ src/html.c """
upskirt.includes = "src/"
upskirt.name = "upskirt"
upskirt.target = "upskirt"
Please sign in to comment.
Something went wrong with that request. Please try again.