Use a two-layer array for active character callbacks
Do not stick 2KB of NULL values inside the `struct render`, use a double lookup to character -> ptr. This makes the struct 8 times smaller.
This commit is contained in:
parent
35a580ffce
commit
9fa8438a41
1 changed files with 50 additions and 18 deletions
|
@ -50,12 +50,44 @@ struct render;
|
|||
typedef size_t
|
||||
(*char_trigger)(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t size);
|
||||
|
||||
static size_t char_emphasis(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t size);
|
||||
static size_t char_linebreak(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t size);
|
||||
static size_t char_codespan(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t size);
|
||||
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_link(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t size);
|
||||
|
||||
enum markdown_char_t {
|
||||
MD_CHAR_NONE = 0,
|
||||
MD_CHAR_EMPHASIS,
|
||||
MD_CHAR_CODESPAN,
|
||||
MD_CHAR_LINEBREAK,
|
||||
MD_CHAR_LINK,
|
||||
MD_CHAR_LANGLE,
|
||||
MD_CHAR_ESCAPE,
|
||||
MD_CHAR_ENTITITY,
|
||||
MD_CHAR_AUTOLINK,
|
||||
};
|
||||
|
||||
static char_trigger markdown_char_ptrs[] = {
|
||||
NULL,
|
||||
&char_emphasis,
|
||||
&char_codespan,
|
||||
&char_linebreak,
|
||||
&char_link,
|
||||
&char_langle_tag,
|
||||
&char_escape,
|
||||
&char_entity,
|
||||
&char_autolink,
|
||||
};
|
||||
|
||||
/* render • structure containing one particular render */
|
||||
struct render {
|
||||
struct mkd_renderer make;
|
||||
struct array refs;
|
||||
char_trigger active_char[256];
|
||||
char active_char[256];
|
||||
struct parray work_bufs[2];
|
||||
unsigned int ext_flags;
|
||||
size_t max_nesting;
|
||||
|
@ -305,7 +337,7 @@ static void
|
|||
parse_inline(struct buf *ob, struct render *rndr, char *data, size_t size)
|
||||
{
|
||||
size_t i = 0, end = 0;
|
||||
char_trigger action = 0;
|
||||
char action = 0;
|
||||
struct buf work = { 0, 0, 0, 0, 0 };
|
||||
|
||||
if (rndr->work_bufs[BUFFER_SPAN].size +
|
||||
|
@ -330,7 +362,7 @@ parse_inline(struct buf *ob, struct render *rndr, char *data, size_t size)
|
|||
i = end;
|
||||
|
||||
/* calling the trigger */
|
||||
end = action(ob, rndr, data + i, i, size - i);
|
||||
end = markdown_char_ptrs[(int)action](ob, rndr, data + i, i, size - i);
|
||||
if (!end) /* no action from the callback */
|
||||
end = i + 1;
|
||||
else {
|
||||
|
@ -2066,34 +2098,34 @@ ups_markdown(struct buf *ob, struct buf *ib, const struct mkd_renderer *rndrer,
|
|||
rndr.active_char[i] = 0;
|
||||
|
||||
if (rndr.make.emphasis || rndr.make.double_emphasis || rndr.make.triple_emphasis) {
|
||||
rndr.active_char['*'] = char_emphasis;
|
||||
rndr.active_char['_'] = char_emphasis;
|
||||
rndr.active_char['*'] = MD_CHAR_EMPHASIS;
|
||||
rndr.active_char['_'] = MD_CHAR_EMPHASIS;
|
||||
if (extensions & MKDEXT_STRIKETHROUGH)
|
||||
rndr.active_char['~'] = char_emphasis;
|
||||
rndr.active_char['~'] = MD_CHAR_EMPHASIS;
|
||||
}
|
||||
|
||||
if (rndr.make.codespan)
|
||||
rndr.active_char['`'] = char_codespan;
|
||||
rndr.active_char['`'] = MD_CHAR_CODESPAN;
|
||||
|
||||
if (rndr.make.linebreak)
|
||||
rndr.active_char['\n'] = char_linebreak;
|
||||
rndr.active_char['\n'] = MD_CHAR_LINEBREAK;
|
||||
|
||||
if (rndr.make.image || rndr.make.link)
|
||||
rndr.active_char['['] = char_link;
|
||||
rndr.active_char['['] = MD_CHAR_LINK;
|
||||
|
||||
rndr.active_char['<'] = char_langle_tag;
|
||||
rndr.active_char['\\'] = char_escape;
|
||||
rndr.active_char['&'] = char_entity;
|
||||
rndr.active_char['<'] = MD_CHAR_LANGLE;
|
||||
rndr.active_char['\\'] = MD_CHAR_ESCAPE;
|
||||
rndr.active_char['&'] = MD_CHAR_ENTITITY;
|
||||
|
||||
if (extensions & MKDEXT_AUTOLINK) {
|
||||
rndr.active_char['h'] = char_autolink; // http, https
|
||||
rndr.active_char['H'] = char_autolink;
|
||||
rndr.active_char['h'] = MD_CHAR_AUTOLINK; // http, https
|
||||
rndr.active_char['H'] = MD_CHAR_AUTOLINK;
|
||||
|
||||
rndr.active_char['f'] = char_autolink; // ftp
|
||||
rndr.active_char['F'] = char_autolink;
|
||||
rndr.active_char['f'] = MD_CHAR_AUTOLINK; // ftp
|
||||
rndr.active_char['F'] = MD_CHAR_AUTOLINK;
|
||||
|
||||
rndr.active_char['m'] = char_autolink; // mailto
|
||||
rndr.active_char['M'] = char_autolink;
|
||||
rndr.active_char['m'] = MD_CHAR_AUTOLINK; // mailto
|
||||
rndr.active_char['M'] = MD_CHAR_AUTOLINK;
|
||||
}
|
||||
|
||||
/* Extension data */
|
||||
|
|
Loading…
Reference in a new issue