Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added nolinks flag to skip links during rendering #80

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
125 changes: 1 addition & 124 deletions fuzzing/snudown-validator.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "markdown.h"
#include "html.h"
#include "buffer.h"
#include "../snudown.h"

#include <ctype.h>
#include <errno.h>
Expand All @@ -19,130 +20,6 @@

#define SNUDOWN_VERSION "1.3.2"

enum snudown_renderer_mode {
RENDERER_USERTEXT = 0,
RENDERER_WIKI,
RENDERER_USERTEXT_WITHOUTLINKS,
RENDERER_COUNT
};

struct snudown_renderopt {
struct html_renderopt html;
int nofollow;
const char *target;
};

struct snudown_renderer {
struct sd_markdown* main_renderer;
struct sd_markdown* toc_renderer;
struct module_state* state;
struct module_state* toc_state;
};

struct module_state {
struct sd_callbacks callbacks;
struct snudown_renderopt options;
};

static struct snudown_renderer sundown[RENDERER_COUNT];

static char* html_element_whitelist[] = {"tr", "th", "td", "table", "tbody", "thead", "tfoot", "caption", NULL};
static char* html_attr_whitelist[] = {"colspan", "rowspan", "cellspacing", "cellpadding", "scope", NULL};

static struct module_state usertext_toc_state;
static struct module_state wiki_toc_state;
static struct module_state usertext_state;
static struct module_state wiki_state;

static const unsigned int snudown_default_md_flags =
MKDEXT_NO_INTRA_EMPHASIS |
MKDEXT_SUPERSCRIPT |
MKDEXT_AUTOLINK |
MKDEXT_STRIKETHROUGH |
MKDEXT_TABLES;

static const unsigned int snudown_default_md_flags_without_links =
MKDEXT_NO_INTRA_EMPHASIS |
MKDEXT_SUPERSCRIPT |
MKDEXT_STRIKETHROUGH |
MKDEXT_TABLES;

static const unsigned int snudown_default_render_flags =
HTML_SKIP_HTML |
HTML_SKIP_IMAGES |
HTML_SAFELINK |
HTML_ESCAPE |
HTML_USE_XHTML;

static const unsigned int snudown_wiki_render_flags =
HTML_SKIP_HTML |
HTML_SAFELINK |
HTML_ALLOW_ELEMENT_WHITELIST |
HTML_ESCAPE |
HTML_USE_XHTML;

static void
snudown_link_attr(struct buf *ob, const struct buf *link, void *opaque)
{
struct snudown_renderopt *options = opaque;

if (options->nofollow)
BUFPUTSL(ob, " rel=\"nofollow\"");

if (options->target != NULL) {
BUFPUTSL(ob, " target=\"");
bufputs(ob, options->target);
bufputc(ob, '\"');
}
}

static struct sd_markdown* make_custom_renderer(struct module_state* state,
const unsigned int renderflags,
const unsigned int markdownflags,
int toc_renderer) {
if(toc_renderer) {
sdhtml_toc_renderer(&state->callbacks,
(struct html_renderopt *)&state->options);
} else {
sdhtml_renderer(&state->callbacks,
(struct html_renderopt *)&state->options,
renderflags);
}

state->options.html.link_attributes = &snudown_link_attr;
state->options.html.html_element_whitelist = html_element_whitelist;
state->options.html.html_attr_whitelist = html_attr_whitelist;

return sd_markdown_new(
markdownflags,
16,
64,
&state->callbacks,
&state->options
);
}

void init_default_renderer() {
sundown[RENDERER_USERTEXT].main_renderer = make_custom_renderer(&usertext_state, snudown_default_render_flags, snudown_default_md_flags, 0);
sundown[RENDERER_USERTEXT].toc_renderer = make_custom_renderer(&usertext_toc_state, snudown_default_render_flags, snudown_default_md_flags, 1);
sundown[RENDERER_USERTEXT].state = &usertext_state;
sundown[RENDERER_USERTEXT].toc_state = &usertext_toc_state;
}

void init_wiki_renderer() {
sundown[RENDERER_WIKI].main_renderer = make_custom_renderer(&wiki_state, snudown_wiki_render_flags, snudown_default_md_flags, 0);
sundown[RENDERER_WIKI].toc_renderer = make_custom_renderer(&wiki_toc_state, snudown_wiki_render_flags, snudown_default_md_flags, 1);
sundown[RENDERER_WIKI].state = &wiki_state;
sundown[RENDERER_WIKI].toc_state = &wiki_toc_state;
}

void init_default_renderer_without_links() {
sundown[RENDERER_USERTEXT_WITHOUTLINKS].main_renderer = make_custom_renderer(&usertext_state, snudown_default_render_flags, snudown_default_md_flags_without_links, 0);
sundown[RENDERER_USERTEXT_WITHOUTLINKS].toc_renderer = make_custom_renderer(&usertext_toc_state, snudown_default_render_flags, snudown_default_md_flags_without_links, 1);
sundown[RENDERER_USERTEXT_WITHOUTLINKS].state = &usertext_state;
sundown[RENDERER_USERTEXT_WITHOUTLINKS].toc_state = &usertext_toc_state;
}

void
snudown_md(struct buf *ob, const uint8_t *document, size_t doc_size, int wiki_mode)
{
Expand Down
122 changes: 23 additions & 99 deletions snudown.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,77 +2,15 @@
#include <Python.h>

#include "markdown.h"
#include "html.h"
#include "autolink.h"
#include "snudown.h"

#define SNUDOWN_VERSION "1.4.0"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: we should bump this a minor version too, fancy new features!

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed


enum snudown_renderer_mode {
RENDERER_USERTEXT = 0,
RENDERER_WIKI,
RENDERER_USERTEXT_WITHOUTLINKS,
RENDERER_COUNT
};

struct snudown_renderopt {
struct html_renderopt html;
int nofollow;
const char *target;
};

struct snudown_renderer {
struct sd_markdown* main_renderer;
struct sd_markdown* toc_renderer;
struct module_state* state;
struct module_state* toc_state;
};

struct module_state {
struct sd_callbacks callbacks;
struct snudown_renderopt options;
};

static struct snudown_renderer sundown[RENDERER_COUNT];

static char* html_element_whitelist[] = {"tr", "th", "td", "table", "tbody", "thead", "tfoot", "caption", NULL};
static char* html_attr_whitelist[] = {"colspan", "rowspan", "cellspacing", "cellpadding", "scope", NULL};

static struct module_state usertext_toc_state;
static struct module_state wiki_toc_state;
static struct module_state usertext_state;
static struct module_state wiki_state;

/* The module doc strings */
PyDoc_STRVAR(snudown_module__doc__, "When does the narwhal bacon? At Sundown.");
PyDoc_STRVAR(snudown_md__doc__, "Render a Markdown document");

static const unsigned int snudown_default_md_flags =
MKDEXT_NO_INTRA_EMPHASIS |
MKDEXT_SUPERSCRIPT |
MKDEXT_AUTOLINK |
MKDEXT_STRIKETHROUGH |
MKDEXT_TABLES;

static const unsigned int snudown_default_md_flags_without_links =
MKDEXT_NO_INTRA_EMPHASIS |
MKDEXT_SUPERSCRIPT |
MKDEXT_STRIKETHROUGH |
MKDEXT_TABLES;

static const unsigned int snudown_default_render_flags =
HTML_SKIP_HTML |
HTML_SKIP_IMAGES |
HTML_SAFELINK |
HTML_ESCAPE |
HTML_USE_XHTML;

static const unsigned int snudown_wiki_render_flags =
HTML_SKIP_HTML |
HTML_SAFELINK |
HTML_ALLOW_ELEMENT_WHITELIST |
HTML_ESCAPE |
HTML_USE_XHTML;

static void
snudown_link_attr(struct buf *ob, const struct buf *link, void *opaque)
{
Expand All @@ -88,56 +26,42 @@ snudown_link_attr(struct buf *ob, const struct buf *link, void *opaque)
}
}

static struct sd_markdown* make_custom_renderer(struct module_state* state,
const unsigned int renderflags,
const unsigned int markdownflags,
int toc_renderer) {
if(toc_renderer) {
sdhtml_toc_renderer(&state->callbacks,
(struct html_renderopt *)&state->options);
} else {
sdhtml_renderer(&state->callbacks,
(struct html_renderopt *)&state->options,
renderflags);
}

state->options.html.link_attributes = &snudown_link_attr;
state->options.html.html_element_whitelist = html_element_whitelist;
state->options.html.html_attr_whitelist = html_attr_whitelist;

return sd_markdown_new(
markdownflags,
16,
64,
&state->callbacks,
&state->options
);
}

void init_default_renderer(PyObject *module) {
PyModule_AddIntConstant(module, "RENDERER_USERTEXT", RENDERER_USERTEXT);
void init_default_renderer() {
sundown[RENDERER_USERTEXT].main_renderer = make_custom_renderer(&usertext_state, snudown_default_render_flags, snudown_default_md_flags, 0);
sundown[RENDERER_USERTEXT].toc_renderer = make_custom_renderer(&usertext_toc_state, snudown_default_render_flags, snudown_default_md_flags, 1);
sundown[RENDERER_USERTEXT].state = &usertext_state;
sundown[RENDERER_USERTEXT].toc_state = &usertext_toc_state;
}

void init_wiki_renderer(PyObject *module) {
PyModule_AddIntConstant(module, "RENDERER_WIKI", RENDERER_WIKI);
void init_wiki_renderer() {
sundown[RENDERER_WIKI].main_renderer = make_custom_renderer(&wiki_state, snudown_wiki_render_flags, snudown_default_md_flags, 0);
sundown[RENDERER_WIKI].toc_renderer = make_custom_renderer(&wiki_toc_state, snudown_wiki_render_flags, snudown_default_md_flags, 1);
sundown[RENDERER_WIKI].state = &wiki_state;
sundown[RENDERER_WIKI].toc_state = &wiki_toc_state;
}

void init_default_renderer_without_links(PyObject *module) {
PyModule_AddIntConstant(module, "RENDERER_USERTEXT_WITHOUTLINKS", RENDERER_USERTEXT_WITHOUTLINKS);
void init_default_renderer_without_links() {
sundown[RENDERER_USERTEXT_WITHOUTLINKS].main_renderer = make_custom_renderer(&usertext_state, snudown_default_render_flags, snudown_default_md_flags_without_links, 0);
sundown[RENDERER_USERTEXT_WITHOUTLINKS].toc_renderer = make_custom_renderer(&usertext_toc_state, snudown_default_render_flags, snudown_default_md_flags_without_links, 1);
sundown[RENDERER_USERTEXT_WITHOUTLINKS].state = &usertext_state;
sundown[RENDERER_USERTEXT_WITHOUTLINKS].toc_state = &usertext_toc_state;
}

void register_default_renderer(PyObject *module) {
PyModule_AddIntConstant(module, "RENDERER_USERTEXT", RENDERER_USERTEXT);
init_default_renderer();
}

void register_wiki_renderer(PyObject *module) {
PyModule_AddIntConstant(module, "RENDERER_WIKI", RENDERER_WIKI);
init_wiki_renderer();
}

void register_default_renderer_without_links(PyObject *module) {
PyModule_AddIntConstant(module, "RENDERER_USERTEXT_WITHOUTLINKS", RENDERER_USERTEXT_WITHOUTLINKS);
init_default_renderer_without_links();
}

static PyObject *
snudown_md(PyObject *self, PyObject *args, PyObject *kwargs)
{
Expand Down Expand Up @@ -219,10 +143,10 @@ PyMODINIT_FUNC initsnudown(void)
if (module == NULL)
return;

init_default_renderer(module);
init_wiki_renderer(module);
init_default_renderer_without_links(module);
register_default_renderer(module);
register_wiki_renderer(module);
register_default_renderer_without_links(module);

/* Version */
PyModule_AddStringConstant(module, "__version__", SNUDOWN_VERSION);
}
}
Loading