122 lines
4.1 KiB
C
122 lines
4.1 KiB
C
/*
|
|
Lua bindings for the Discount Markdown library.
|
|
Copyright (c) 2012-2018 Craig Barnes
|
|
Copyright (c) 2025 datenlabor.ru
|
|
|
|
Permission to use, copy, modify, and/or distribute this software for any
|
|
purpose with or without fee is hereby granted, provided that the above
|
|
copyright notice and this permission notice appear in all copies.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
|
SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
|
OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
|
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
*/
|
|
|
|
#include <limits.h>
|
|
#include <stddef.h>
|
|
#include <lua.h>
|
|
#include <lauxlib.h>
|
|
#include <mkdio.h>
|
|
#include "compat.h"
|
|
|
|
static const char *const options[] = {
|
|
"nolinks", "noimages", "nopants", "nohtml", "strict",
|
|
"tagtext", "noext", "cdata", "nosuperscript",
|
|
"notables", "nostrikethrough", "toc", "compat", "autolink",
|
|
"safelink", "noheader", "tabstop", "nodivquote",
|
|
"noalphalist", "extrafootnote", "nostyle",
|
|
"dlextra", "fencedcode", "idanchor",
|
|
"githubtags", "urlencodedanchor", "latex", "html5",
|
|
"normallist", "explicitlist", "dldiscount",
|
|
"altastitle", "extendedattr", NULL
|
|
};
|
|
|
|
static const unsigned int option_codes[] = {
|
|
MKD_NOLINKS, MKD_NOIMAGE, MKD_NOPANTS, MKD_NOHTML, MKD_STRICT,
|
|
MKD_TAGTEXT, MKD_NO_EXT, MKD_CDATA, MKD_NOSUPERSCRIPT,
|
|
MKD_NOTABLES, MKD_NOSTRIKETHROUGH, MKD_TOC, MKD_1_COMPAT, MKD_AUTOLINK,
|
|
MKD_SAFELINK, MKD_NOHEADER, MKD_TABSTOP, MKD_NODIVQUOTE,
|
|
MKD_NOALPHALIST, MKD_EXTRA_FOOTNOTE, MKD_NOSTYLE,
|
|
MKD_DLEXTRA, MKD_FENCEDCODE, MKD_IDANCHOR,
|
|
MKD_GITHUBTAGS, MKD_URLENCODEDANCHOR, MKD_LATEX, MKD_HTML5,
|
|
MKD_NORMAL_LISTITEM, MKD_EXPLICITLIST, MKD_DLDISCOUNT,
|
|
MKD_ALT_AS_TITLE, MKD_EXTENDED_ATTR
|
|
};
|
|
|
|
static void add_field(lua_State *L, const char *k, const char *v) {
|
|
lua_pushstring(L, v);
|
|
lua_setfield(L, -2, k);
|
|
}
|
|
|
|
static void add_lfield(lua_State *L, const char *k, const char *v, size_t n) {
|
|
lua_pushlstring(L, v, n);
|
|
lua_setfield(L, -2, k);
|
|
}
|
|
|
|
static int compile(lua_State *L) {
|
|
MMIOT *doc;
|
|
mkd_flag_t *flags = mkd_flags();
|
|
char *body = NULL, *toc = NULL, *css = NULL;
|
|
int body_size, toc_size, css_size, i, argc;
|
|
|
|
size_t input_size;
|
|
const char *input = luaL_checklstring(L, 1, &input_size);
|
|
luaL_argcheck(L, input_size < INT_MAX, 1, "string too long");
|
|
|
|
for (i = 2, argc = lua_gettop(L); i <= argc; i++) {
|
|
mkd_set_flag_num(flags, option_codes[luaL_checkoption(L, i, NULL, options)]);
|
|
}
|
|
|
|
doc = mkd_string(input, (int) input_size, flags);
|
|
if (unlikely(doc == NULL)) {
|
|
lua_pushnil(L);
|
|
lua_pushstring(L, "mkd_string() returned NULL");
|
|
return 2;
|
|
}
|
|
|
|
if (unlikely(mkd_compile(doc, flags) != 1)) {
|
|
mkd_cleanup(doc);
|
|
lua_pushnil(L);
|
|
lua_pushstring(L, "mkd_compile() failed");
|
|
return 2;
|
|
}
|
|
|
|
body_size = mkd_document(doc, &body);
|
|
if (unlikely(body == NULL || body_size < 0)) {
|
|
mkd_cleanup(doc);
|
|
lua_pushnil(L);
|
|
lua_pushstring(L, "mkd_document() failed");
|
|
return 2;
|
|
}
|
|
|
|
lua_createtable(L, 0, 6);
|
|
add_lfield(L, "body", body, (size_t) body_size);
|
|
add_field(L, "title", mkd_doc_title(doc));
|
|
add_field(L, "author", mkd_doc_author(doc));
|
|
add_field(L, "date", mkd_doc_date(doc));
|
|
|
|
if ((css_size = mkd_css(doc, &css)) > 0 && css) {
|
|
add_lfield(L, "css", css, (size_t) css_size);
|
|
}
|
|
|
|
if ((mkd_flag_isset(flags, MKD_TOC)) && (toc_size = mkd_toc(doc, &toc)) > 0 && toc) {
|
|
add_lfield(L, "index", toc, (size_t) toc_size);
|
|
}
|
|
|
|
mkd_cleanup(doc);
|
|
return 1;
|
|
}
|
|
|
|
EXPORT int luaopen_discount3(lua_State *L) {
|
|
lua_createtable(L, 0, 2);
|
|
lua_pushcfunction(L, compile);
|
|
lua_setfield(L, -2, "compile");
|
|
lua_pushstring(L, markdown_version);
|
|
lua_setfield(L, -2, "_libmarkdown_version");
|
|
return 1;
|
|
}
|