lua-discount-2.1.8/0000755000175000017500000000000012736657651013137 5ustar garesgareslua-discount-2.1.8/css.c0000644000175000017500000000272312734302156014060 0ustar garesgares/* markdown: a C implementation of John Gruber's Markdown markup language. * * Copyright (C) 2009 David L Parsons. * The redistribution terms are provided in the COPYRIGHT file that must * be distributed with this source code. */ #include #include #include #include #include #include #include "config.h" #include "cstring.h" #include "markdown.h" #include "amalloc.h" /* * dump out stylesheet sections. */ static void stylesheets(Paragraph *p, Cstring *f) { Line *q; for (; p; p = p->next) { if (p->typ == STYLE) { for (q = p->text; q; q = q->next) Cswrite(f, T(q->text), S(q->text)); Csputc('\n', f); } if (p->down) stylesheets(p->down, f); } } /* dump any embedded styles to a string */ int mkd_css(Document *d, char **res) { Cstring f; if (res && *res && d && d->compiled) { CREATE(f); RESERVE(f, 100); stylesheets(d->code, &f); /* HACK ALERT! HACK ALERT! HACK ALERT! */ *res = T(f); /* we know that a T(Cstring) is a character pointer */ /* so we can simply pick it up and carry it away, */ return S(f); /* leaving the husk of the Ctring on the stack */ /* END HACK ALERT */ } return EOF; } /* dump any embedded styles to a file */ int mkd_generatecss(Document *d, FILE *f) { char *res; int written = EOF, size = mkd_css(d, &res); if (size > 0) written = fwrite(res, size, 1, f); if (res) free(res); return (written == size) ? size : EOF; } lua-discount-2.1.8/lua-discount-dev-1.rockspec0000644000175000017500000000144612734302156020201 0ustar garesgarespackage="lua-discount" version="dev-1" source = { url = "" } description = { summary = "Binding to a fast C implementation of the Markdown text-to-html markup system", homepage = "http://asbradbury.org/projects/lua-discount/", license = "BSD" } dependencies = { "lua >= 5.1" } build = { type = "builtin", modules = { discount = { "basename.c", "Csio.c", "css.c", "docheader.c", "dumptree.c", "emmatch.c", "generate.c", "markdown.c", "mkdio.c", "resource.c", "toc.c", "xml.c", "ldiscount.c" } }, platforms = { windows = { modules = { discount = { defines = {"WINDOWS"} } } } } } lua-discount-2.1.8/resource.c0000644000175000017500000000472412734302156015122 0ustar garesgares/* markdown: a C implementation of John Gruber's Markdown markup language. * * Copyright (C) 2007 David L Parsons. * The redistribution terms are provided in the COPYRIGHT file that must * be distributed with this source code. */ #include #include #include #include #include #include #include "config.h" #include "cstring.h" #include "markdown.h" #include "amalloc.h" /* free a (single) line */ void ___mkd_freeLine(Line *ptr) { DELETE(ptr->text); free(ptr); } /* free a list of lines */ void ___mkd_freeLines(Line *p) { if (p->next) ___mkd_freeLines(p->next); ___mkd_freeLine(p); } /* bye bye paragraph. */ void ___mkd_freeParagraph(Paragraph *p) { if (p->next) ___mkd_freeParagraph(p->next); if (p->down) ___mkd_freeParagraph(p->down); if (p->text) ___mkd_freeLines(p->text); if (p->ident) free(p->ident); free(p); } /* bye bye footnote. */ void ___mkd_freefootnote(Footnote *f) { DELETE(f->tag); DELETE(f->link); DELETE(f->title); } /* bye bye footnotes. */ void ___mkd_freefootnotes(MMIOT *f) { int i; if (f->footnotes) { for (i = 0; i < S(*f->footnotes); i++) ___mkd_freefootnote(&T(*f->footnotes)[i]); DELETE(*f->footnotes); free(f->footnotes); } } /* initialize a new MMIOT */ void ___mkd_initmmiot(MMIOT *f, void *footnotes) { if (f) { memset(f, 0, sizeof *f); CREATE(f->in); CREATE(f->out); CREATE(f->Q); if (footnotes) f->footnotes = footnotes; else { f->footnotes = malloc(sizeof f->footnotes[0]); CREATE(*f->footnotes); } } } /* free the contents of a MMIOT, but leave the object alone. */ void ___mkd_freemmiot(MMIOT *f, void *footnotes) { if (f) { DELETE(f->in); DELETE(f->out); DELETE(f->Q); if (f->footnotes != footnotes) ___mkd_freefootnotes(f); memset(f, 0, sizeof *f); } } /* free lines up to an barrier. */ void ___mkd_freeLineRange(Line *anchor, Line *stop) { Line *r = anchor->next; if (r != stop) { while (r && (r->next != stop)) r = r->next; if (r) r->next = 0; ___mkd_freeLines(anchor->next); } anchor->next = 0; } /* clean up everything allocated in __mkd_compile() */ void mkd_cleanup(Document *doc) { if (doc) { if (doc->ctx) { ___mkd_freemmiot(doc->ctx, 0); free(doc->ctx); } if (doc->code) ___mkd_freeParagraph(doc->code); if (doc->headers) ___mkd_freeLines(doc->headers); if (T(doc->content)) ___mkd_freeLines(T(doc->content)); memset(doc, 0, sizeof doc[0]); free(doc); } } lua-discount-2.1.8/cstring.h0000644000175000017500000000746512734302156014756 0ustar garesgares/* two template types: STRING(t) which defines a pascal-style string * of element (t) [STRING(char) is the closest to the pascal string], * and ANCHOR(t) which defines a baseplate that a linked list can be * built up from. [The linked list /must/ contain a ->next pointer * for linking the list together with.] */ #ifndef _CSTRING_D #define _CSTRING_D #include #include #include "amalloc.h" /* expandable Pascal-style string. */ #define STRING(type) \ struct { \ type *text; \ int size, alloc; \ } #define CREATE(x) T(x) = (void *)(S(x) = (x).alloc = 0) #define EXPAND(x) \ (S(x)++)[(S(x) < (x).alloc) \ ? (T(x)) \ : (T(x) = T(x) ? realloc(T(x), sizeof T(x)[0] *( \ (x).alloc += 100)) \ : malloc(sizeof T(x)[0] *((x).alloc += \ 100)))] #define DELETE(x) ALLOCATED(x) ? (free(T(x)), S(x) = (x).alloc = 0) : (S(x) = 0) #define CLIP(t, i, sz) \ (((i) >= 0) && ((sz) > 0) && (((i) + (sz)) <= S(t))) \ ? (memmove(&T(t)[i], &T(t)[i + sz], \ (S(t) - (i + sz) + 1) * sizeof(T(t)[0])), \ S(t) -= (sz)) \ : -1 #define RESERVE(x, sz) \ T(x) = ((x).alloc > S(x) + (sz) \ ? T(x) \ : T(x) ? realloc(T(x), sizeof T(x)[0] *( \ (x).alloc = 100 + (sz) + S(x))) \ : malloc(sizeof T(x)[0] *((x).alloc = \ 100 + (sz) + S(x)))) #define SUFFIX(t, p, sz) \ memcpy(((S(t) += (sz)) - (sz)) + \ (T(t) = T(t) ? realloc(T(t), \ sizeof T(t)[0] *((t).alloc += sz)) \ : malloc(sizeof T(t)[0] *((t).alloc += sz))), \ (p), sizeof(T(t)[0]) * (sz)) #define PREFIX(t, p, sz) \ RESERVE((t), (sz)); \ if (S(t)) { \ memmove(T(t) + (sz), T(t), S(t)); \ } \ memcpy(T(t), (p), (sz)); \ S(t) += (sz) /* reference-style links (and images) are stored in an array */ #define T(x) (x).text #define S(x) (x).size #define ALLOCATED(x) (x).alloc /* abstract anchor type that defines a list base * with a function that attaches an element to * the end of the list. * * the list base field is named .text so that the T() * macro will work with it. */ #define ANCHOR(t) \ struct { \ t *text, *end; \ } #define E(t) ((t).end) #define ATTACH(t, p) \ (T(t) ? ((E(t)->next = (p)), (E(t) = (p))) : ((T(t) = E(t) = (p)))) typedef STRING(char) Cstring; extern void Csputc(int, Cstring *); extern int Csprintf(Cstring *, char *, ...); extern int Cswrite(Cstring *, char *, int); extern void Csreparse(Cstring *, char *, int, int); #endif /*_CSTRING_D*/ lua-discount-2.1.8/LICENSE0000644000175000017500000000470212734302156014130 0ustar garesgaresThe core Discount C sources are Copyright (C) 2007 David Loren Parsons. The Discount Lua extension sources are Copyright (C) 2008 A.S. Bradbury. Copyright (C) 2008 Tim Channon. All rights reserved. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicence, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution, and in the same place and form as other copyright, license and disclaimer information. 3. The end-user documentation included with the redistribution, if any, must include the following acknowledgment: This product includes software developed by David Loren Parsons in the same place and form as other third-party acknowledgments. Alternately, this acknowledgment may appear in the software itself, in the same form and location as other such third-party acknowledgments. 4. Except as contained in this notice, the name of David Loren Parsons shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from David Loren Parsons. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DAVID LOREN PARSONS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. lua-discount-2.1.8/test_discount.lua0000644000175000017500000000365312734302156016521 0ustar garesgaresluaunit = require("luaunit") discount = require("discount") function test_basic_conversion() luaunit.assertEquals("

Hello World.

", discount("Hello World.")) end function test_relaxed_emphasis() luaunit.assertEquals("

Hello World!

", discount("_Hello World_!")) luaunit.assertEquals("

under_score this_stuff

", discount("under_score this_stuff")) local input = "_start _ foo_bar bar_baz _ end_ *italic* **bold** _blah_" local expected_out = "

start _ foo_bar bar_baz _ end italic bold blah

" luaunit.assertEquals(expected_out, discount(input)) end function test_nolinks() luaunit.assertEquals("

[example](http://example.com)

", discount("[example](http://example.com)", "nolinks")) luaunit.assertEquals('

<a href=“http://example.com”>example

', discount('example', "nolinks")) end function test_noimages() luaunit.assertEquals("

![example](example.png)

", discount("![example](example.png)", "noimage")) luaunit.assertEquals('

<img src=“example.png”/>

', discount('', "noimage")) end function test_nopants() luaunit.assertEquals('

“quote”

', discount('"quote"')) luaunit.assertEquals('

"quote"

', discount('"quote"', "nopants")) end function test_nohtml() local expected = "

This should <em>not</em> be allowed

" luaunit.assertEquals(expected, discount("This should not be allowed", "nohtml")) end --function test_cdata() -- luaunit.assertEquals("<p>foo</p>", discount("foo", "cdata")) --end function test_toc() local expected_out = '\n

Level 1

\n\n\n

Level 2

' local input = "# Level 1\n\n## Level 2\n\n" luaunit.assertEquals(expected_out, discount(input, "toc")) end os.exit(luaunit.LuaUnit.run()) lua-discount-2.1.8/mkdio.c0000644000175000017500000001350512734302156014373 0ustar garesgares/* * mkdio -- markdown front end input functions * * Copyright (C) 2007 David L Parsons. * The redistribution terms are provided in the COPYRIGHT file that must * be distributed with this source code. */ #include "config.h" #include #include #include #include "cstring.h" #include "markdown.h" #include "amalloc.h" typedef ANCHOR(Line) LineAnchor; /* create a new blank Document */ static Document *new_Document() { Document *ret = calloc(sizeof(Document), 1); if (ret) { if ((ret->ctx = calloc(sizeof(MMIOT), 1))) return ret; free(ret); } return 0; } /* add a line to the markdown input chain */ static void queue(Document *a, Cstring *line) { Line *p = calloc(sizeof *p, 1); unsigned char c; int xp = 0; int size = S(*line); unsigned char *str = (unsigned char *)T(*line); CREATE(p->text); ATTACH(a->content, p); while (size--) { if ((c = *str++) == '\t') { /* expand tabs into ->tabstop spaces. We use ->tabstop * because the ENTIRE FREAKING COMPUTER WORLD uses * editors * that don't do ^T/^D, but instead use tabs for * indentation, * and, of course, set their tabs down to 4 spaces */ do { EXPAND(p->text) = ' '; } while (++xp % a->tabstop); } else if (c >= ' ') { EXPAND(p->text) = c; ++xp; } } EXPAND(p->text) = 0; S(p->text)--; p->dle = mkd_firstnonblank(p); } #ifdef PANDOC_HEADER /* trim leading blanks from a header line */ static void snip(Line *p) { CLIP(p->text, 0, 1); p->dle = mkd_firstnonblank(p); } #endif /* build a Document from any old input. */ typedef int (*getc_func)(void *); Document *populate(getc_func getc, void *ctx, int flags) { Cstring line; Document *a = new_Document(); int c; #ifdef PANDOC_HEADER int pandoc = 0; #endif if (!a) return 0; a->tabstop = (flags & STD_TABSTOP) ? 4 : TABSTOP; CREATE(line); while ((c = (*getc)(ctx)) != EOF) { if (c == '\n') { #ifdef PANDOC_HEADER if (pandoc != EOF && pandoc < 3) { if (S(line) && (T(line)[0] == '%')) pandoc++; else pandoc = EOF; } #endif queue(a, &line); S(line) = 0; } else if (isprint(c) || isspace(c) || (c & 0x80)) EXPAND(line) = c; } if (S(line)) queue(a, &line); DELETE(line); #ifdef PANDOC_HEADER if ((pandoc == 3) && !(flags & NO_HEADER)) { /* the first three lines started with %, so we have a header. * clip the first three lines out of content and hang them * off header. */ a->headers = T(a->content); T(a->content) = a->headers->next->next->next; a->headers->next->next->next = 0; snip(a->headers); snip(a->headers->next); snip(a->headers->next->next); } #endif return a; } /* convert a file into a linked list */ Document *mkd_in(FILE *f, int flags) { return populate((getc_func)fgetc, f, flags & INPUT_MASK); } /* return a single character out of a buffer */ struct string_ctx { char *data; /* the unread data */ int size; /* and how much is there? */ }; static int strget(struct string_ctx *in) { if (!in->size) return EOF; --(in->size); return *(in->data)++; } /* convert a block of text into a linked list */ Document *mkd_string(const char *buf, int len, int flags) { struct string_ctx about; about.data = buf; about.size = len; return populate((getc_func)strget, &about, flags & INPUT_MASK); } /* write the html to a file (xmlified if necessary) */ int mkd_generatehtml(Document *p, FILE *output) { char *doc; int szdoc; if ((szdoc = mkd_document(p, &doc)) != EOF) { if (p->ctx->flags & CDATA_OUTPUT) mkd_generatexml(doc, szdoc, output); else fwrite(doc, szdoc, 1, output); putc('\n', output); return 0; } return -1; } /* convert some markdown text to html */ int markdown(Document *document, FILE *out, int flags) { if (mkd_compile(document, flags)) { mkd_generatehtml(document, out); mkd_cleanup(document); return 0; } return -1; } /* write out a Cstring, mangled into a form suitable for ` 0;) { c = *s++; if (c == ' ' || c == '&' || c == '<' || c == '"') (*outchar)('+', out); else if (isalnum(c) || ispunct(c) || (c & 0x80)) (*outchar)(c, out); else (*outchar)('~', out); } } /* ___mkd_reparse() a line */ static void mkd_parse_line(char *bfr, int size, MMIOT *f, int flags) { ___mkd_initmmiot(f, 0); f->flags = flags & USER_FLAGS; ___mkd_reparse(bfr, size, 0, f); ___mkd_emblock(f); } /* ___mkd_reparse() a line, returning it in malloc()ed memory */ int mkd_line(char *bfr, int size, char **res, int flags) { MMIOT f; int len; mkd_parse_line(bfr, size, &f, flags); if (len = S(f.out)) { /* kludge alert; we know that T(f.out) is malloced memory, * so we can just steal it away. This is awful -- there * should be an opaque method that transparently moves * the pointer out of the embedded Cstring. */ *res = T(f.out); T(f.out) = 0; S(f.out) = 0; } else { *res = 0; len = EOF; } ___mkd_freemmiot(&f, 0); return len; } /* ___mkd_reparse() a line, writing it to a FILE */ int mkd_generateline(char *bfr, int size, FILE *output, int flags) { MMIOT f; mkd_parse_line(bfr, size, &f, flags); if (flags & CDATA_OUTPUT) mkd_generatexml(T(f.out), S(f.out), output); else fwrite(T(f.out), S(f.out), 1, output); ___mkd_freemmiot(&f, 0); return 0; } /* set the url display callback */ void mkd_e_url(Document *f, mkd_callback_t edit) { if (f) f->cb.e_url = edit; } /* set the url options callback */ void mkd_e_flags(Document *f, mkd_callback_t edit) { if (f) f->cb.e_flags = edit; } /* set the url display/options deallocator */ void mkd_e_free(Document *f, mkd_free_t dealloc) { if (f) f->cb.e_free = dealloc; } /* set the url display/options context data field */ void mkd_e_data(Document *f, void *data) { if (f) f->cb.e_data = data; } lua-discount-2.1.8/xml.c0000644000175000017500000000304712734302156014070 0ustar garesgares/* markdown: a C implementation of John Gruber's Markdown markup language. * * Copyright (C) 2007 David L Parsons. * The redistribution terms are provided in the COPYRIGHT file that must * be distributed with this source code. */ #include #include #include #include #include #include #include "config.h" #include "cstring.h" #include "markdown.h" #include "amalloc.h" /* return the xml version of a character */ static char *mkd_xmlchar(unsigned char c) { switch (c) { case '<': return "<"; case '>': return ">"; case '&': return "&"; case '"': return """; case '\'': return "'"; default: if (isascii(c) || (c & 0x80)) return 0; return ""; } } /* write output in XML format */ int mkd_generatexml(char *p, int size, FILE *out) { unsigned char c; char *entity; while (size-- > 0) { c = *p++; if (entity = mkd_xmlchar(c)) fputs(entity, out); else fputc(c, out); } return 0; } /* build a xml'ed version of a string */ int mkd_xml(char *p, int size, char **res) { unsigned char c; char *entity; Cstring f; CREATE(f); RESERVE(f, 100); while (size-- > 0) { c = *p++; if (entity = mkd_xmlchar(c)) Cswrite(&f, entity, strlen(entity)); else Csputc(c, &f); } /* HACK ALERT! HACK ALERT! HACK ALERT! */ *res = T(f); /* we know that a T(Cstring) is a character pointer */ /* so we can simply pick it up and carry it away, */ return S(f); /* leaving the husk of the Ctring on the stack */ /* END HACK ALERT */ } lua-discount-2.1.8/ldiscount.c0000644000175000017500000000434012734302156015271 0ustar garesgares#include #include #include #include #include static const char *const discount_opts[] = { "nolinks", "noimage", "nopants", "nohtml", "strict", "tagtext", "no_ext", "cdata", "nosuperscript", "norelaxed", "notables", "nostrikethrough", "toc", "compat", "autolink", "safelink", "noheader", "tabstop", "nodivquote", "noalphalist", "nodlist", "extra_footnote", "nostyle", "embed", NULL}; static const int discount_opts_codes[] = { MKD_NOLINKS, MKD_NOIMAGE, MKD_NOPANTS, MKD_NOHTML, MKD_STRICT, MKD_TAGTEXT, MKD_NO_EXT, MKD_CDATA, MKD_NOSUPERSCRIPT, MKD_NORELAXED, MKD_NOTABLES, MKD_NOSTRIKETHROUGH, MKD_TOC, MKD_1_COMPAT, MKD_AUTOLINK, MKD_SAFELINK, MKD_NOHEADER, MKD_TABSTOP, MKD_NODIVQUOTE, MKD_NOALPHALIST, MKD_NODLIST, MKD_EXTRA_FOOTNOTE, MKD_NOSTYLE, MKD_EMBED}; static int ldiscount(lua_State *L) { size_t len; const char *str = luaL_checklstring(L, 1, &len); int flags = 0; int num_args = lua_gettop(L); MMIOT *doc; int i; for (i = 2; i <= num_args; i++) { int opt_index = luaL_checkoption(L, i, NULL, discount_opts); flags |= discount_opts_codes[opt_index]; } doc = mkd_string(str, len, MKD_TABSTOP | MKD_NOHEADER); if (mkd_compile(doc, flags)) { char *result; int result_size = mkd_document(doc, &result); lua_pushlstring(L, result, result_size); mkd_cleanup(doc); return 1; } else { mkd_cleanup(doc); return luaL_error(L, "error converting document to markdown"); } } static int ldiscount__call(lua_State *L) { luaL_checktype(L, 1, LUA_TTABLE); lua_remove(L, 1); return ldiscount(L); } static const struct luaL_Reg ldiscount_meta[] = {{"__call", ldiscount__call}, {NULL, NULL}}; static const struct luaL_Reg ldiscount_funcs[] = {{"to_html", ldiscount}, {NULL, NULL}}; LUALIB_API int luaopen_discount(lua_State *L) { // Give the discount table a metatable #if (LUA_VERSION_NUM == 501) luaL_register(L, "discount", ldiscount_funcs); lua_newtable(L); luaL_register(L, NULL, ldiscount_meta); lua_setmetatable(L, -2); #elif(LUA_VERSION_NUM == 502) luaL_newlib(L, ldiscount_funcs); lua_newtable(L); luaL_setfuncs(L, ldiscount_meta, 0); lua_setmetatable(L, -2); #else #error "Unsupported Lua version" #endif return 1; } lua-discount-2.1.8/emmatch.c0000644000175000017500000000776112734302156014715 0ustar garesgares/* markdown: a C implementation of John Gruber's Markdown markup language. * * Copyright (C) 2010 David L Parsons. * The redistribution terms are provided in the COPYRIGHT file that must * be distributed with this source code. */ #include #include #include #include #include #include #include "config.h" #include "cstring.h" #include "markdown.h" #include "amalloc.h" /* emmatch: the emphasis mangler that's run after a block * of html has been generated. * * It should create MarkdownTest_1.0 (and _1.0.3) * compatable emphasis for non-pathological cases * and it should fail in a standards-compliant way * when someone attempts to feed it junk. * * Emmatching is done after the input has been * processed into a STRING (f->Q) of text and * emphasis blocks. After ___mkd_emblock() finishes, * it truncates f->Q and leaves the rendered paragraph * if f->out. */ /* empair() -- find the NEAREST matching emphasis token (or * subtoken of a 3+ long emphasis token. */ static int empair(MMIOT *f, int first, int last, int match) { int i; block *begin, *p; begin = &T(f->Q)[first]; for (i = first + 1; i <= last; i++) { p = &T(f->Q)[i]; if ((p->b_type != bTEXT) && (p->b_count <= 0)) continue; /* break? */ if (p->b_type == begin->b_type) { if (p->b_count == match) /* exact match */ return i; if (p->b_count > 2) /* fuzzy match */ return i; } } return 0; } /* empair */ /* emfill() -- if an emphasis token has leftover stars or underscores, * convert them back into character and append them to b_text. */ static void emfill(block *p) { int j; if (p->b_type == bTEXT) return; for (j = 0; j < p->b_count; j++) EXPAND(p->b_text) = p->b_char; p->b_count = 0; } /* emfill */ static void emclose(MMIOT *f, int first, int last) { int j; for (j = first + 1; j < last - 1; j++) emfill(&T(f->Q)[j]); } static struct emtags { char open[10]; char close[10]; int size; } emtags[] = {{"", "", 5}, {"", "", 9}}; static void emblock(MMIOT *, int, int); /* emmatch() -- match emphasis for a single emphasis token. */ static void emmatch(MMIOT *f, int first, int last) { block *start = &T(f->Q)[first]; int e, e2, match; switch (start->b_count) { case 2: if (e = empair(f, first, last, match = 2)) break; case 1: e = empair(f, first, last, match = 1); break; case 0: return; default: e = empair(f, first, last, 1); e2 = empair(f, first, last, 2); if (e2 >= e) { e = e2; match = 2; } else match = 1; break; } if (e) { /* if we found emphasis to match, match it, recursively call * emblock to match emphasis inside the new html block, add * the emphasis markers for the block, then (tail) recursively * call ourself to match any remaining emphasis on this token. */ block *end = &T(f->Q)[e]; end->b_count -= match; start->b_count -= match; emblock(f, first, e); PREFIX(start->b_text, emtags[match - 1].open, emtags[match - 1].size - 1); SUFFIX(end->b_post, emtags[match - 1].close, emtags[match - 1].size); emmatch(f, first, last); } } /* emmatch */ /* emblock() -- walk a blocklist, attempting to match emphasis */ static void emblock(MMIOT *f, int first, int last) { int i; for (i = first; i <= last; i++) if (T(f->Q)[i].b_type != bTEXT) emmatch(f, i, last); emclose(f, first, last); } /* emblock */ /* ___mkd_emblock() -- emblock a string of blocks, then concatinate the * resulting text onto f->out. */ void ___mkd_emblock(MMIOT *f) { int i; block *p; emblock(f, 0, S(f->Q) - 1); for (i = 0; i < S(f->Q); i++) { p = &T(f->Q)[i]; emfill(p); if (S(p->b_post)) { SUFFIX(f->out, T(p->b_post), S(p->b_post)); DELETE(p->b_post); } if (S(p->b_text)) { SUFFIX(f->out, T(p->b_text), S(p->b_text)); DELETE(p->b_text); } } S(f->Q) = 0; } /* ___mkd_emblock */ lua-discount-2.1.8/bench.lua0000644000175000017500000000110612734302156014700 0ustar garesgaresrequire("Benchmark") require('markdown') discount = require('discount') local function read_file(fn) local file = assert(io.open(fn)) local contents = assert(file:read('*a')) file:close() return contents end local bench = Benchmark:new() local REPS = 100 local input = read_file("syntax.text") print("Benchmarking using http://daringfireball.net/projects/markdown/syntax.text\n") bench:add("lua-discount", function() for i=1, REPS do discount(input) end end) bench:add("markdown.lua", function() for i=1, REPS do markdown(input) end end) bench:run() lua-discount-2.1.8/README.mkd0000644000175000017500000000772412734302156014564 0ustar garesgares# lua-discount A binding to [Discount](http://www.pell.portland.or.us/~orc/Code/discount/), a fast C implementation of the [Markdown](http://daringfireball.net/projects/markdown) text to HTML markup system. Discount passes the Markdown test suite. ## Project links * [Home](http://asbradbury.org/projects/lua-discount/) * [Download](http://luaforge.net/projects/lua-discount/) * [Documentation](http://asbradbury.org/projects/lua-discount/#usage) * [Source](http://github.com/asb/lua-discount/) ## Release history * lua-discount-1.3.1 (unreleased) * update to updstream Discount 1.3.1 * new [language extensions][1]: class blocks, superscripts and alphabetic ordered lists. * support the `"toc"` option for table of contents generation - headers will include an `id` attribute. * support the `"strict"` option, to disable relaxed emphasis and superscripts. * lua-discount-1.2.10.1 (2008-09-22) * Windows is now a supported platform (thanks to contributions from Tim Channon) * lua-discount-1.2.10 (2008-09-03) * update to upstream Discount 1.2.10 * support the `"nohtml"` option, to disable embedded html. * compile to use relaxed emphasis, meaning underscores don't count when they're in the middle of a word. * add some tests * include results of a simple benchmark in the readme * lua-discount-1.2.7 (2008-08-03) * first public release [1]: http://www.pell.portland.or.us/~orc/Code/discount/#Language+extensions ## See also * [Discount](http://www.pell.portland.or.us/~orc/Code/discount/) * [Markdown syntax](http://daringfireball.net/projects/markdown/syntax) * [markdown.lua](http://www.frykholm.se/files/markdown.lua) ## Performance Thanks to the underlying Discount implementation, lua-discount is incredibly fast. Benchmarking markdown.lua 0.32 against lua-discount 1.2.10 by parsing the [Markdown syntax document](http://daringfireball.net/projects/markdown/syntax.text) 100 times gives the following result (all figures are in seconds): user system total real lua-discount 0.170000 0.000000 0.170000 0.177374 markdown.lua 48.530000 0.000000 48.530000 48.524910 ## [Usage](id:usage) Note that `require("discount")` returns a single function, which you are responsible for giving a suitable name. Example: discount = require("discount") local markdown_string = [[ # Demonstration This is a demonstration of lua-discount. Passing the options `"nolinks"` disables links such as [this](http://example.com). ]] local html_string = discount(markdown_string, "nolinks") The `discount` function takes as its first argument the Markdown string to convert, and for its subsequent arguments takes any combination of the following strings as options: =`"nolinks"`= do not allow ``, `

`, etc will include an `id` attribute. =`"embed"`= equivalent to specifying `"nolinks"`, `"noimages"` and `"tagtext"`. ## License and acknowledgements lua-discount is distributed under [a BSD-style license](http://github.com/asb/lua-discount/tree/master/LICENSE). Thanks to Tim Channon for Windows support. This product includes software developed by [David Loren Parsons](http://www.pell.portland.or.us/~orc). ## Contact Author: A.S. Bradbury Email: Homepage: lua-discount-2.1.8/basename.c0000644000175000017500000000155012734302156015040 0ustar garesgares/* * mkdio -- markdown front end input functions * * Copyright (C) 2007 David L Parsons. * The redistribution terms are provided in the COPYRIGHT file that must * be distributed with this source code. */ #include "config.h" #include #include #include #include "mkdio.h" #include "cstring.h" #include "amalloc.h" static char *e_basename(const char *string, const int size, void *context) { char *ret; char *base = (char *)context; if (base && string && (*string == '/') && (ret = malloc(strlen(base) + size + 2))) { strcpy(ret, base); strncat(ret, string, size); return ret; } return 0; } static void e_free(char *string, void *context) { if (string) free(string); } void mkd_basename(MMIOT *document, char *base) { mkd_e_url(document, e_basename); mkd_e_data(document, base); mkd_e_free(document, e_free); } lua-discount-2.1.8/markdown.h0000644000175000017500000001163712734302156015123 0ustar garesgares#ifndef _MARKDOWN_D #define _MARKDOWN_D #include "cstring.h" /* reference-style links (and images) are stored in an array * of footnotes. */ typedef struct footnote { Cstring tag; /* the tag for the reference link */ Cstring link; /* what this footnote points to */ Cstring title; /* what it's called (TITLE= attribute) */ int height, width; /* dimensions (for image link) */ int dealloc; /* deallocation needed? */ } Footnote; /* each input line is read into a Line, which contains the line, * the offset of the first non-space character [this assumes * that all tabs will be expanded to spaces!], and a pointer to * the next line. */ typedef struct line { Cstring text; struct line *next; int dle; } Line; /* a paragraph is a collection of Lines, with links to the next paragraph * and (if it's a QUOTE, UL, or OL) to the reparsed contents of this * paragraph. */ typedef struct paragraph { struct paragraph *next; /* next paragraph */ struct paragraph *down; /* recompiled contents of this paragraph */ struct line *text; /* all the text in this paragraph */ char *ident; /* %id% tag for QUOTE */ enum { WHITESPACE = 0, CODE, QUOTE, MARKUP, HTML, STYLE, DL, UL, OL, AL, LISTITEM, HDR, HR, TABLE, SOURCE } typ; enum { IMPLICIT = 0, PARA, CENTER } align; int hnumber; /* for typ == HDR */ } Paragraph; enum { ETX, SETEXT }; /* header types */ typedef struct block { enum { bTEXT, bSTAR, bUNDER } b_type; int b_count; char b_char; Cstring b_text; Cstring b_post; } block; typedef STRING(block) Qblock; typedef char *(*mkd_callback_t)(const char *, const int, void *); typedef void (*mkd_free_t)(char *, void *); typedef struct callback_data { void *e_data; /* private data for callbacks */ mkd_callback_t e_url; /* url edit callback */ mkd_callback_t e_flags; /* extra href flags callback */ mkd_free_t e_free; /* edit/flags callback memory deallocator */ } Callback_data; /* a magic markdown io thing holds all the data structures needed to * do the backend processing of a markdown document */ typedef struct mmiot { Cstring out; Cstring in; Qblock Q; int isp; STRING(Footnote) * footnotes; int flags; #define DENY_A 0x0001 #define DENY_IMG 0x0002 #define DENY_SMARTY 0x0004 #define DENY_HTML 0x0008 #define STRICT 0x0010 #define INSIDE_TAG 0x0020 #define NO_PSEUDO_PROTO 0x0040 #define CDATA_OUTPUT 0x0080 #define NOTABLES 0x0400 #define TOC 0x1000 #define MKD_1_COMPAT 0x2000 #define AUTOLINK 0x4000 #define SAFELINK 0x8000 #define USER_FLAGS 0xFCFF #define EMBEDDED DENY_A | DENY_IMG | NO_PSEUDO_PROTO | CDATA_OUTPUT Callback_data *cb; } MMIOT; /* * the mkdio text input functions return a document structure, * which contains a header (retrieved from the document if * markdown was configured * with the * --enable-pandoc-header * and the document begins with a pandoc-style header) and the * root of the linked list of Lines. */ typedef struct document { Line *headers; /* title -> author(s) -> date */ ANCHOR(Line) content; /* uncompiled text, not valid after compile() */ Paragraph *code; /* intermediate code generated by compile() */ int compiled; /* set after mkd_compile() */ int html; /* set after (internal) htmlify() */ int tabstop; /* for properly expanding tabs (ick) */ MMIOT *ctx; /* backend buffers, flags, and structures */ Callback_data cb; /* callback functions & private data */ } Document; extern int mkd_firstnonblank(Line *); extern int mkd_compile(Document *, int); extern int mkd_document(Document *, char **); extern int mkd_generatehtml(Document *, FILE *); extern int mkd_css(Document *, char **); extern int mkd_generatecss(Document *, FILE *); #define mkd_style mkd_generatecss extern int mkd_xml(char *, int, char **); extern int mkd_generatexml(char *, int, FILE *); extern void mkd_cleanup(Document *); extern int mkd_line(char *, int, char **, int); extern int mkd_generateline(char *, int, FILE *, int); #define mkd_text mkd_generateline extern void mkd_basename(Document *, char *); extern void mkd_string_to_anchor(char *, int, void (*)(int, void *), void *); extern Document *mkd_in(FILE *, int); extern Document *mkd_string(char *, int, int); #define NO_HEADER 0x0100 #define STD_TABSTOP 0x0200 #define INPUT_MASK (NO_HEADER | STD_TABSTOP) /* internal resource handling functions. */ extern void ___mkd_freeLine(Line *); extern void ___mkd_freeLines(Line *); extern void ___mkd_freeParagraph(Paragraph *); extern void ___mkd_freefootnote(Footnote *); extern void ___mkd_freefootnotes(MMIOT *); extern void ___mkd_initmmiot(MMIOT *, void *); extern void ___mkd_freemmiot(MMIOT *, void *); extern void ___mkd_freeLineRange(Line *, Line *); extern void ___mkd_xml(char *, int, FILE *); extern void ___mkd_reparse(char *, int, int, MMIOT *); extern void ___mkd_emblock(MMIOT *); extern void ___mkd_tidy(Cstring *); #endif /*_MARKDOWN_D*/ lua-discount-2.1.8/mkdio.h0000644000175000017500000000647312734302156014406 0ustar garesgares#ifndef _MKDIO_D #define _MKDIO_D #include typedef void MMIOT; /* line builder for markdown() */ MMIOT *mkd_in(FILE *, int); /* assemble input from a file */ MMIOT *mkd_string(const char *, int, int); /* assemble input from a buffer */ void mkd_basename(MMIOT *, char *); /* compilation, debugging, cleanup */ int mkd_compile(MMIOT *, int); int mkd_cleanup(MMIOT *); /* markup functions */ int mkd_dump(MMIOT *, FILE *, int, char *); int markdown(MMIOT *, FILE *, int); int mkd_line(char *, int, char **, int); void mkd_string_to_anchor(char *, int, int (*)(int, void *), void *); int mkd_xhtmlpage(MMIOT *, int, FILE *); /* header block access */ char *mkd_doc_title(MMIOT *); char *mkd_doc_author(MMIOT *); char *mkd_doc_date(MMIOT *); /* compiled data access */ int mkd_document(MMIOT *, char **); int mkd_toc(MMIOT *, char **); int mkd_css(MMIOT *, char **); int mkd_xml(char *, int, char **); /* write-to-file functions */ int mkd_generatehtml(MMIOT *, FILE *); int mkd_generatetoc(MMIOT *, FILE *); int mkd_generatexml(char *, int, FILE *); int mkd_generatecss(MMIOT *, FILE *); #define mkd_style mkd_generatecss int mkd_generateline(char *, int, FILE *, int); #define mkd_text mkd_generateline /* url generator callbacks */ typedef char *(*mkd_callback_t)(const char *, const int, void *); typedef void (*mkd_free_t)(char *, void *); void mkd_e_url(void *, mkd_callback_t); void mkd_e_flags(void *, mkd_callback_t); void mkd_e_free(void *, mkd_free_t); void mkd_e_data(void *, void *); /* version#. */ extern char markdown_version[]; /* special flags for markdown() and mkd_text() */ #define MKD_NOLINKS 0x00000001 /* don't do link processing, block tags */ #define MKD_NOIMAGE 0x00000002 /* don't do image processing, block */ #define MKD_NOPANTS 0x00000004 /* don't run smartypants() */ #define MKD_NOHTML 0x00000008 /* don't allow raw html through AT ALL */ #define MKD_STRICT 0x00000010 /* disable SUPERSCRIPT, RELAXED_EMPHASIS */ #define MKD_TAGTEXT 0x00000020 /* process text inside an html tag; no * , no , no html or [] expansion */ #define MKD_NO_EXT 0x00000040 /* don't allow pseudo-protocols */ #define MKD_NOEXT MKD_NO_EXT /* ^^^ (aliased for user convenience) */ #define MKD_CDATA 0x00000080 /* generate code for xml ![CDATA[...]] */ #define MKD_NOSUPERSCRIPT 0x00000100 /* no A^B */ #define MKD_NORELAXED 0x00000200 /* emphasis happens /everywhere/ */ #define MKD_NOTABLES 0x00000400 /* disallow tables */ #define MKD_NOSTRIKETHROUGH 0x00000800 /* forbid ~~strikethrough~~ */ #define MKD_TOC 0x00001000 /* do table-of-contents processing */ #define MKD_1_COMPAT 0x00002000 /* compatibility with MarkdownTest_1.0 */ #define MKD_AUTOLINK 0x00004000 /* make http://foo.com link even without <>s */ #define MKD_SAFELINK 0x00008000 /* paranoid check for link protocol */ #define MKD_NOHEADER 0x00010000 /* don't process header blocks */ #define MKD_TABSTOP 0x00020000 /* expand tabs to 4 spaces */ #define MKD_NODIVQUOTE 0x00040000 /* forbid >%class% blocks */ #define MKD_NOALPHALIST 0x00080000 /* forbid alphabetic lists */ #define MKD_NODLIST 0x00100000 /* forbid definition lists */ #define MKD_EXTRA_FOOTNOTE 0x00200000 /* enable markdown extra-style footnotes */ #define MKD_NOSTYLE 0x00400000 /* don't extract