"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "htmldoc/mmd.c" between
htmldoc-1.9.11-source.tar.gz and htmldoc-1.9.12-source.tar.gz

About: HTMLDOC converts HTML and Markdown source files into indexed HTML, EPUB, PostScript, or PDF files (but doesn’t support CSS).

mmd.c  (htmldoc-1.9.11-source):mmd.c  (htmldoc-1.9.12-source)
/* /*
* Implementation of miniature markdown library. * Implementation of miniature markdown library.
* *
* https://github.com/michaelrsweet/mmd * https://github.com/michaelrsweet/mmd
* *
* Copyright © 2017-2019 by Michael R Sweet. * Copyright © 2017-2021 by Michael R Sweet.
* *
* Licensed under Apache License v2.0. See the file "LICENSE" for more * Licensed under Apache License v2.0. See the file "LICENSE" for more
* information. * information.
*/ */
/* /*
* Define DEBUG to get debug printf messages to stderr. * Define DEBUG to get debug printf messages to stderr.
*/ */
#define DEBUG 0 #define DEBUG 0
#if DEBUG > 0 #if DEBUG > 0
# define DEBUG_printf(...) fprintf(stderr, __VA_ARGS__) # define DEBUG_printf(...) fprintf(stderr, __VA_ARGS__)
skipping to change at line 66 skipping to change at line 66
* Microsoft renames the POSIX functions to _name, and introduces a broken * Microsoft renames the POSIX functions to _name, and introduces a broken
* compatibility layer using the original names. As a result, random crashes * compatibility layer using the original names. As a result, random crashes
* can occur when, for example, strdup() allocates memory from a different heap * can occur when, for example, strdup() allocates memory from a different heap
* than used by malloc() and free(). * than used by malloc() and free().
* *
* To avoid moronic problems like this, we #define the POSIX function names to * To avoid moronic problems like this, we #define the POSIX function names to
* the corresponding non-standard Microsoft names. * the corresponding non-standard Microsoft names.
*/ */
#ifdef _WIN32 #ifdef _WIN32
# define snprintf _snprintf # define snprintf _snprintf
# define strcasecmp _stricmp # define strcasecmp _stricmp
# define strdup _strdup # define strdup _strdup
#endif /* _WIN32 */ #endif /* _WIN32 */
/* /*
* Structures... * Structures...
*/ */
struct _mmd_s struct _mmd_s
{ {
mmd_type_t type; /* Node type */ mmd_type_t type; /* Node type */
int whitespace; /* Leading whitespace? */ int whitespace; /* Leading whitespace? */
char *text, /* Text */ char *text, /* Text */
*url, /* Reference URL (image/link/etc.) */ *url, /* Reference URL (image/link/etc.) */
*extra; /* Title, language name, etc. */ *extra; /* Title, language name, etc. */
mmd_t *parent, /* Parent node */ mmd_t *parent, /* Parent node */
*first_child, /* First child node */ *first_child, /* First child node */
*last_child, /* Last child node */ *last_child, /* Last child node */
*prev_sibling, /* Previous sibling node */ *prev_sibling, /* Previous sibling node */
*next_sibling; /* Next sibling node */ *next_sibling; /* Next sibling node */
}; };
typedef struct _mmd_filebuf_s /**** Buffered file ****/ typedef struct _mmd_filebuf_s /**** Buffered file ****/
{ {
FILE *fp; /* File pointer */ FILE *fp; /* File pointer */
char buffer[65536], /* Buffer */ char buffer[65536], /* Buffer */
*bufptr, /* Pointer into buffer */ *bufptr, /* Pointer into buffer */
*bufend; /* End of buffer */ *bufend; /* End of buffer */
} _mmd_filebuf_t; } _mmd_filebuf_t;
skipping to change at line 132 skipping to change at line 132
* Local globals... * Local globals...
*/ */
static mmd_option_t mmd_options = MMD_OPTION_ALL; static mmd_option_t mmd_options = MMD_OPTION_ALL;
/* Markdown extensions to support */ /* Markdown extensions to support */
/* /*
* Local functions... * Local functions...
*/ */
static mmd_t *mmd_add(mmd_t *parent, mmd_type_t type, int whitespace, char *t static mmd_t *mmd_add(mmd_t *parent, mmd_type_t type, int whitespace, char *te
ext, char *url); xt, char *url);
static void mmd_free(mmd_t *node); static void mmd_free(mmd_t *node);
static int mmd_has_continuation(const char *line, _mmd_filebuf_t *file, int indent); static int mmd_has_continuation(const char *line, _mmd_filebuf_t *file, int indent);
static size_t mmd_is_chars(const char *lineptr, const char *chars, size_t minch ars); static size_t mmd_is_chars(const char *lineptr, const char *chars, size_t minch ars);
static size_t mmd_is_codefence(char *lineptr, char fence, size_t fencelen, char **language); static size_t mmd_is_codefence(char *lineptr, char fence, size_t fencelen, char **language);
static int mmd_is_table(_mmd_filebuf_t *file, int indent); static int mmd_is_table(_mmd_filebuf_t *file, int indent);
static void mmd_parse_inline(_mmd_doc_t *doc, mmd_t *parent, char *lineptr); static void mmd_parse_inline(_mmd_doc_t *doc, mmd_t *parent, char *lineptr);
static char *mmd_parse_link(_mmd_doc_t *doc, char *lineptr, char **text, cha static char *mmd_parse_link(_mmd_doc_t *doc, char *lineptr, char **text, char
r **url, char **title, char **refname); **url, char **title, char **refname);
static void mmd_read_buffer(_mmd_filebuf_t *file); static void mmd_read_buffer(_mmd_filebuf_t *file);
static char *mmd_read_line(_mmd_filebuf_t *file, char *line, size_t linesize) ; static char *mmd_read_line(_mmd_filebuf_t *file, char *line, size_t linesize) ;
static void mmd_ref_add(_mmd_doc_t *doc, mmd_t *node, const char *name, const char *url, const char *title); static void mmd_ref_add(_mmd_doc_t *doc, mmd_t *node, const char *name, const char *url, const char *title);
static _mmd_ref_t *mmd_ref_find(_mmd_doc_t *doc, const char *name); static _mmd_ref_t *mmd_ref_find(_mmd_doc_t *doc, const char *name);
static void mmd_remove(mmd_t *node); static void mmd_remove(mmd_t *node);
#if DEBUG #if DEBUG
static const char *mmd_type_string(mmd_type_t type); static const char *mmd_type_string(mmd_type_t type);
#endif /* DEBUG */ #endif /* DEBUG */
/* /*
* 'mmdCopyAllText()' - Make a copy of all the text under a given node. * 'mmdCopyAllText()' - Make a copy of all the text under a given node.
* *
* The returned string must be freed using free(). * The returned string must be freed using free().
*/ */
skipping to change at line 180 skipping to change at line 180
if (current->text) if (current->text)
{ {
/* /*
* Append this node's text to the string... * Append this node's text to the string...
*/ */
textlen = strlen(current->text); textlen = strlen(current->text);
if (allsize == 0) if (allsize == 0)
{ {
allsize = textlen + (size_t)current->whitespace + 1; allsize = textlen + (size_t)current->whitespace + 1;
all = malloc(allsize); all = malloc(allsize);
allptr = all; allptr = all;
if (!all) if (!all)
return (NULL); return (NULL);
} }
else else
{ {
allsize += textlen + (size_t)current->whitespace; allsize += textlen + (size_t)current->whitespace;
temp = realloc(all, allsize); temp = realloc(all, allsize);
if (!temp) if (!temp)
{ {
free(all); free(all);
return (NULL); return (NULL);
} }
allptr = temp + (allptr - all); allptr = temp + (allptr - all);
all = temp; all = temp;
} }
if (current->whitespace) if (current->whitespace)
*allptr++ = ' '; *allptr++ = ' ';
memcpy(allptr, current->text, textlen); memcpy(allptr, current->text, textlen);
allptr += textlen; allptr += textlen;
} }
/* /*
* Find the next logical node... * Find the next logical node...
*/ */
if ((next = mmdGetNextSibling(current)) == NULL) if ((next = mmdGetNextSibling(current)) == NULL)
{ {
next = mmdGetParent(current); next = mmdGetParent(current);
while (next && next != node && mmdGetNextSibling(next) == NULL) while (next && next != node && mmdGetNextSibling(next) == NULL)
next = mmdGetParent(next); next = mmdGetParent(next);
if (next != node) if (next != node)
next = mmdGetNextSibling(next); next = mmdGetNextSibling(next);
} }
current = next; current = next;
} }
if (allptr) if (allptr)
*allptr = '\0'; *allptr = '\0';
return (all); return (all);
} }
/* /*
* 'mmdFree()' - Free a markdown tree. * 'mmdFree()' - Free a markdown tree.
*/ */
void void
mmdFree(mmd_t *node) /* I - First node */ mmdFree(mmd_t *node) /* I - First node */
{ {
mmd_t *current, /* Current node */ mmd_t *current, /* Current node */
*next; /* Next node */ *next; /* Next node */
mmd_remove(node); mmd_remove(node);
for (current = node->first_child; current; current = next) for (current = node->first_child; current; current = next)
{ {
/* /*
* Get the next node... * Get the next node...
*/ */
if ((next = current->first_child) != NULL) if ((next = current->first_child) != NULL)
skipping to change at line 268 skipping to change at line 268
continue; continue;
} }
if ((next = current->next_sibling) == NULL) if ((next = current->next_sibling) == NULL)
{ {
/* /*
* Next node is the parent, which we'll free as needed... * Next node is the parent, which we'll free as needed...
*/ */
if ((next = current->parent) == node) if ((next = current->parent) == node)
next = NULL; next = NULL;
} }
/* /*
* Free child... * Free child...
*/ */
mmd_free(current); mmd_free(current);
} }
/* /*
* Then free the memory used by the parent node... * Then free the memory used by the parent node...
*/ */
mmd_free(node); mmd_free(node);
} }
/* /*
* 'mmdGetExtra()' - Get extra text (title, language, etc.) associated with a * 'mmdGetExtra()' - Get extra text (title, language, etc.) associated with a
* node. * node.
*/ */
const char * /* O - Extra text or NULL if none */ const char * /* O - Extra text or NULL if none */
mmdGetExtra(mmd_t *node) /* I - Node */ mmdGetExtra(mmd_t *node) /* I - Node */
{ {
return (node ? node->extra : NULL); return (node ? node->extra : NULL);
} }
/* /*
* 'mmdGetFirstChild()' - Return the first child of a node, if any. * 'mmdGetFirstChild()' - Return the first child of a node, if any.
*/ */
mmd_t * /* O - First child or @code NULL@ if non mmd_t * /* O - First child or @code NULL@
e */ if none */
mmdGetFirstChild(mmd_t *node) /* I - Node */ mmdGetFirstChild(mmd_t *node) /* I - Node */
{ {
return (node ? node->first_child : NULL); return (node ? node->first_child : NULL);
} }
/* /*
* 'mmdGetLastChild()' - Return the last child of a node, if any. * 'mmdGetLastChild()' - Return the last child of a node, if any.
*/ */
mmd_t * /* O - Last child or @code NULL@ if none mmd_t * /* O - Last child or @code NULL@
*/ if none */
mmdGetLastChild(mmd_t *node) /* I - Node */ mmdGetLastChild(mmd_t *node) /* I - Node */
{ {
return (node ? node->last_child : NULL); return (node ? node->last_child : NULL);
} }
/* /*
* 'mmdGetMetadata()' - Return the metadata for the given keyword. * 'mmdGetMetadata()' - Return the metadata for the given keyword.
*/ */
const char * /* O - Value or @code NULL@ if none */ const char * /* O - Value or @code NULL@ if none */
mmdGetMetadata(mmd_t *doc, /* I - Document */ mmdGetMetadata(mmd_t *doc, /* I - Document */
const char *keyword) /* I - Keyword */ const char *keyword) /* I - Keyword */
{ {
mmd_t *metadata, /* Metadata node */ mmd_t *metadata, /* Metadata node */
*current; /* Current node */ *current; /* Current node */
char prefix[256]; /* Prefix string */ char prefix[256]; /* Prefix string */
size_t prefix_len; /* Length of prefix string */ size_t prefix_len; /* Length of prefix string */
const char *value; /* Pointer to value */ const char *value; /* Pointer to value */
if (!doc || (metadata = doc->first_child) == NULL || metadata->type != MMD_TYP E_METADATA) if (!doc || (metadata = doc->first_child) == NULL || metadata->type != MMD_TYP E_METADATA)
return (NULL); return (NULL);
snprintf(prefix, sizeof(prefix), "%s:", keyword); snprintf(prefix, sizeof(prefix), "%s:", keyword);
prefix_len = strlen(prefix); prefix_len = strlen(prefix);
for (current = metadata->first_child; current; current = current->next_sibling ) for (current = metadata->first_child; current; current = current->next_sibling )
{ {
if (strncmp(current->text, prefix, prefix_len)) if (strncmp(current->text, prefix, prefix_len))
skipping to change at line 355 skipping to change at line 355
return (value); return (value);
} }
return (NULL); return (NULL);
} }
/* /*
* 'mmdGetNextSibling()' - Return the next sibling of a node, if any. * 'mmdGetNextSibling()' - Return the next sibling of a node, if any.
*/ */
mmd_t * /* O - Next sibling or @code NULL@ if no mmd_t * /* O - Next sibling or @code NULL
ne */ @ if none */
mmdGetNextSibling(mmd_t *node) /* I - Node */ mmdGetNextSibling(mmd_t *node) /* I - Node */
{ {
return (node ? node->next_sibling : NULL); return (node ? node->next_sibling : NULL);
} }
/* /*
* 'mmdGetOptions()' - Get the enabled markdown processing options/extensions. * 'mmdGetOptions()' - Get the enabled markdown processing options/extensions.
*/ */
mmd_option_t /* O - Enabled options */ mmd_option_t /* O - Enabled options */
mmdGetOptions(void) mmdGetOptions(void)
{ {
return (mmd_options); return (mmd_options);
} }
/* /*
* 'mmdGetParent()' - Return the parent of a node, if any. * 'mmdGetParent()' - Return the parent of a node, if any.
*/ */
mmd_t * /* O - Parent node or @code NULL@ if non mmd_t * /* O - Parent node or @code NULL@
e */ if none */
mmdGetParent(mmd_t *node) /* I - Node */ mmdGetParent(mmd_t *node) /* I - Node */
{ {
return (node ? node->parent : NULL); return (node ? node->parent : NULL);
} }
/* /*
* 'mmdGetPrevSibling()' - Return the previous sibling of a node, if any. * 'mmdGetPrevSibling()' - Return the previous sibling of a node, if any.
*/ */
mmd_t * /* O - Previous sibling or @code NULL@ i mmd_t * /* O - Previous sibling or @code
f none */ NULL@ if none */
mmdGetPrevSibling(mmd_t *node) /* I - Node */ mmdGetPrevSibling(mmd_t *node) /* I - Node */
{ {
return (node ? node->prev_sibling : NULL); return (node ? node->prev_sibling : NULL);
} }
/* /*
* 'mmdGetText()' - Return the text associated with a node, if any. * 'mmdGetText()' - Return the text associated with a node, if any.
*/ */
const char * /* O - Text or @code NULL@ if none */ const char * /* O - Text or @code NULL@ if none */
mmdGetText(mmd_t *node) /* I - Node */ mmdGetText(mmd_t *node) /* I - Node */
{ {
return (node ? node->text : NULL); return (node ? node->text : NULL);
} }
/* /*
* 'mmdGetType()' - Return the type of a node, if any. * 'mmdGetType()' - Return the type of a node, if any.
*/ */
mmd_type_t /* O - Type or @code MMD_TYPE_NONE@ if n mmd_type_t /* O - Type or @code MMD_TYPE_NONE@ if no
one */ ne */
mmdGetType(mmd_t *node) /* I - Node */ mmdGetType(mmd_t *node) /* I - Node */
{ {
return (node ? node->type : MMD_TYPE_NONE); return (node ? node->type : MMD_TYPE_NONE);
} }
/* /*
* 'mmdGetURL()' - Return the URL associated with a node, if any. * 'mmdGetURL()' - Return the URL associated with a node, if any.
*/ */
const char * /* O - URL or @code NULL@ if none */ const char * /* O - URL or @code NULL@ if none */
mmdGetURL(mmd_t *node) /* I - Node */ mmdGetURL(mmd_t *node) /* I - Node */
{ {
return (node ? node->url : NULL); return (node ? node->url : NULL);
} }
/* /*
* 'mmdGetWhitespace()' - Return whether whitespace preceded a node. * 'mmdGetWhitespace()' - Return whether whitespace preceded a node.
*/ */
int /* O - 1 for whitespace, 0 for none */ int /* O - 1 for whitespace, 0 for none */
mmdGetWhitespace(mmd_t *node) /* I - Node */ mmdGetWhitespace(mmd_t *node) /* I - Node */
{ {
return (node ? node->whitespace : 0); return (node ? node->whitespace : 0);
} }
/* /*
* 'mmdIsBlock()' - Return whether the node is a block. * 'mmdIsBlock()' - Return whether the node is a block.
*/ */
int /* O - 1 for block nodes, 0 otherwise */ int /* O - 1 for block nodes, 0 otherwise */
mmdIsBlock(mmd_t *node) /* I - Node */ mmdIsBlock(mmd_t *node) /* I - Node */
{ {
return (node ? node->type < MMD_TYPE_NORMAL_TEXT : 0); return (node ? node->type < MMD_TYPE_NORMAL_TEXT : 0);
} }
/* /*
* 'mmdLoad()' - Load a markdown file into nodes. * 'mmdLoad()' - Load a markdown file into nodes.
*/ */
mmd_t * /* O - First node in markdown */ mmd_t * /* O - First node in markdown */
mmdLoad(const char *filename) /* I - File to load */ mmdLoad(const char *filename) /* I - File to load */
{ {
FILE *fp; /* File */ FILE *fp; /* File */
mmd_t *doc; /* Document */ mmd_t *doc; /* Document */
/* /*
* Open the file and create an empty document... * Open the file and create an empty document...
*/ */
if ((fp = fopen(filename, "r")) == NULL) if ((fp = fopen(filename, "r")) == NULL)
return (NULL); return (NULL);
doc = mmdLoadFile(fp); doc = mmdLoadFile(fp);
fclose(fp); fclose(fp);
return (doc); return (doc);
} }
/* /*
* 'mmdLoadFile()' - Load a markdown file into nodes from a stdio file. * 'mmdLoadFile()' - Load a markdown file into nodes from a stdio file.
*/ */
mmd_t * /* O - First node in markdown */ mmd_t * /* O - First node in markdown */
mmdLoadFile(FILE *fp) /* I - File to load */ mmdLoadFile(FILE *fp) /* I - File to load */
{ {
size_t i; /* Looping var */ size_t i; /* Looping var */
_mmd_doc_t doc; /* Document */ _mmd_doc_t doc; /* Document */
_mmd_ref_t *reference; /* Current reference */ _mmd_ref_t *reference; /* Current reference */
mmd_t *block = NULL; /* Current block */ mmd_t *block = NULL; /* Current block */
mmd_type_t type; /* Type for line */ mmd_type_t type; /* Type for line */
_mmd_filebuf_t file; /* File buffer */ _mmd_filebuf_t file; /* File buffer */
char line[8192], /* Read line */ char line[8192], /* Read line */
*linestart, /* Start of line */ *linestart, /* Start of line */
*lineptr, /* Pointer into line */ *lineptr, /* Pointer into line */
*lineend, /* End of line */ *lineend, /* End of line */
*temp; /* Temporary pointer */ *temp; /* Temporary pointer */
int newindent; /* New indentation */ int newindent; /* New indentation */
int blank_code = 0; /* Saved indented blank code line */ int blank_code = 0; /* Saved indented blank code line */
mmd_type_t columns[256]; /* Alignment of table columns */ mmd_type_t columns[256]; /* Alignment of table columns */
int num_columns = 0, /* Number of columns in table */ int num_columns = 0, /* Number of columns in table */
rows = 0; /* Number of rows in table */ rows = 0; /* Number of rows in table */
_mmd_stack_t stack[32], /* Block stack */ _mmd_stack_t stack[32], /* Block stack */
*stackptr = stack; /* Pointer to top of stack */ *stackptr = stack; /* Pointer to top of stack */
/* /*
* Create an empty document... * Create an empty document...
*/ */
DEBUG_printf("mmdLoadFile: mmd_options=%d%s%s\n", mmd_options, (mmd_options & MMD_OPTION_METADATA) ? " METADATA" : "", (mmd_options & MMD_OPTION_TABLES) ? " T ABLES" : ""); DEBUG_printf("mmdLoadFile: mmd_options=%d%s%s\n", mmd_options, (mmd_options & MMD_OPTION_METADATA) ? " METADATA" : "", (mmd_options & MMD_OPTION_TABLES) ? " T ABLES" : "");
memset(&doc, 0, sizeof(doc)); memset(&doc, 0, sizeof(doc));
doc.root = mmd_add(NULL, MMD_TYPE_DOCUMENT, 0, NULL, NULL); doc.root = mmd_add(NULL, MMD_TYPE_DOCUMENT, 0, NULL, NULL);
if (!doc.root) if (!doc.root)
{
fclose(fp);
return (NULL); return (NULL);
}
/* /*
* Initialize the block stack... * Initialize the block stack...
*/ */
memset(stack, 0, sizeof(stack)); memset(stack, 0, sizeof(stack));
stackptr->parent = doc.root; stackptr->parent = doc.root;
/* /*
* Read lines until end-of-file... * Read lines until end-of-file...
*/ */
memset(&file, 0, sizeof(file)); memset(&file, 0, sizeof(file));
file.fp = fp; file.fp = fp;
while ((lineptr = mmd_read_line(&file, line, sizeof(line))) != NULL) while ((lineptr = mmd_read_line(&file, line, sizeof(line))) != NULL)
{ {
DEBUG_printf("%03d %-12s %s", stackptr->indent, mmd_type_string(stackptr-> parent->type) + 9, lineptr); DEBUG_printf("%03d %-12s %s", stackptr->indent, mmd_type_string(stackptr->p arent->type) + 9, lineptr);
#if DEBUG #if DEBUG
if (stackptr->parent->type == MMD_TYPE_CODE_BLOCK) if (stackptr->parent->type == MMD_TYPE_CODE_BLOCK)
DEBUG2_printf(" blank_code=%d\n", blank_code); DEBUG2_printf(" blank_code=%d\n", blank_code);
#endif /* DEBUG */ #endif /* DEBUG */
linestart = lineptr; linestart = lineptr;
while (isspace(*lineptr & 255)) while (isspace(*lineptr & 255))
lineptr ++; lineptr ++;
DEBUG2_printf(" line indent=%d\n", (int)(lineptr - line)); DEBUG2_printf(" line indent=%d\n", (int)(lineptr - line));
DEBUG2_printf(" stackptr=%d\n", (int)(stackptr - stack)); DEBUG2_printf(" stackptr=%d\n", (int)(stackptr - stack));
if (*lineptr == '>' && (lineptr - linestart) < 4) if (*lineptr == '>' && (lineptr - linestart) < 4)
{ {
/* /*
* Block quote. See if there is an existing blockquote... * Block quote. See if there is an existing blockquote...
*/ */
DEBUG_printf(" BLOCKQUOTE (stackptr=%ld)\n", stackptr - stack); DEBUG_printf(" BLOCKQUOTE (stackptr=%ld)\n", stackptr - stack);
if (stackptr == stack || stack[1].parent->type != MMD_TYPE_BLOCK_QUOTE) if (stackptr == stack || stack[1].parent->type != MMD_TYPE_BLOCK_QUOTE)
{ {
block = NULL; block = NULL;
stackptr = stack + 1; stackptr = stack + 1;
stackptr->parent = mmd_add(doc.root, MMD_TYPE_BLOCK_QUOTE, 0, NULL, NULL stackptr->parent = mmd_add(doc.root, MMD_TYPE_BLOCK_QUOTE, 0, NULL, NULL)
); ;
stackptr->indent = 2; stackptr->indent = 2;
stackptr->fence = '\0'; stackptr->fence = '\0';
} }
/* /*
* Skip whitespace after the ">"... * Skip whitespace after the ">"...
*/ */
lineptr ++; lineptr ++;
if (isspace(*lineptr & 255)) if (isspace(*lineptr & 255))
lineptr ++; lineptr ++;
linestart = lineptr; linestart = lineptr;
while (isspace(*lineptr & 255)) while (isspace(*lineptr & 255))
lineptr ++; lineptr ++;
} }
else if (*lineptr != '>' && stackptr > stack && stack[1].parent->type == MMD _TYPE_BLOCK_QUOTE && (!block || *lineptr == '\n' || mmd_is_chars(lineptr, "- \t" , 3) || mmd_is_chars(lineptr, "_ \t", 3) || mmd_is_chars(lineptr, "* \t", 3))) else if (*lineptr != '>' && stackptr > stack && stack[1].parent->type == MMD _TYPE_BLOCK_QUOTE && (!block || *lineptr == '\n' || mmd_is_chars(lineptr, "- \t" , 3) || mmd_is_chars(lineptr, "_ \t", 3) || mmd_is_chars(lineptr, "* \t", 3)))
{ {
/* /*
* Not a lazy continuation so terminate this block quote... * Not a lazy continuation so terminate this block quote...
skipping to change at line 582 skipping to change at line 579
DEBUG_puts(" Terminating BLOCKQUOTE\n"); DEBUG_puts(" Terminating BLOCKQUOTE\n");
block = NULL; block = NULL;
stackptr = stack; stackptr = stack;
} }
/* /*
* Now handle all other markup not related to block quotes... * Now handle all other markup not related to block quotes...
*/ */
DEBUG2_printf(" stackptr=%d (%s), block=%p (%s)\n", (int)(stackptr - sta DEBUG2_printf(" stackptr=%d (%s), block=%p (%s)\n", (int)(stackptr - stac
ck), mmd_type_string(stackptr->parent->type) + 9, block, block ? mmd_type_string k), mmd_type_string(stackptr->parent->type) + 9, block, block ? mmd_type_string(
(block->type) + 9 : ""); block->type) + 9 : "");
DEBUG2_printf(" strchr(lineptr, '|')=%p, mmd_is_table(&file, stackptr->i DEBUG2_printf(" strchr(lineptr, '|')=%p, mmd_is_table(&file, stackptr->in
ndent)=%d\n", strchr(lineptr, '|'), mmd_is_table(&file, stackptr->indent)); dent)=%d\n", strchr(lineptr, '|'), mmd_is_table(&file, stackptr->indent));
DEBUG2_printf(" linestart=%d, lineptr=%d\n", (int)(linestart - line), (i DEBUG2_printf(" linestart=%d, lineptr=%d\n", (int)(linestart - line), (in
nt)(lineptr - line)); t)(lineptr - line));
DEBUG2_printf(" mmd_is_chars(lineptr, \"-\", 1)=%d\n", (int)mmd_is_chars DEBUG2_printf(" mmd_is_chars(lineptr, \"-\", 1)=%d\n", (int)mmd_is_chars(
(lineptr, "-", 1)); lineptr, "-", 1));
DEBUG2_printf(" mmd_is_chars(lineptr, \"=\", 1)=%d\n", (int)mmd_is_chars DEBUG2_printf(" mmd_is_chars(lineptr, \"=\", 1)=%d\n", (int)mmd_is_chars(
(lineptr, "=", 1)); lineptr, "=", 1));
if ((lineptr - line - stackptr->indent) < 4 && ((stackptr->parent->type != M MD_TYPE_CODE_BLOCK && !stackptr->fence && mmd_is_codefence(lineptr, '\0', 0, NUL L)) || (stackptr->fence && mmd_is_codefence(lineptr, stackptr->fence, stackptr-> fencelen, NULL)))) if ((lineptr - line - stackptr->indent) < 4 && ((stackptr->parent->type != M MD_TYPE_CODE_BLOCK && !stackptr->fence && mmd_is_codefence(lineptr, '\0', 0, NUL L)) || (stackptr->fence && mmd_is_codefence(lineptr, stackptr->fence, stackptr-> fencelen, NULL))))
{ {
/* /*
* Code fence... * Code fence...
*/ */
DEBUG2_printf("stackptr->indent=%d, fence='%c', fencelen=%d\n", stackptr-> indent, stackptr->fence, (int)stackptr->fencelen); DEBUG2_printf("stackptr->indent=%d, fence='%c', fencelen=%d\n", stackptr-> indent, stackptr->fence, (int)stackptr->fencelen);
if (stackptr->parent->type == MMD_TYPE_CODE_BLOCK) if (stackptr->parent->type == MMD_TYPE_CODE_BLOCK)
{ {
DEBUG2_puts("Ending code block...\n"); DEBUG2_puts("Ending code block...\n");
stackptr --; stackptr --;
} }
else if (stackptr < (stack + sizeof(stack) / sizeof(stack[0]) - 1)) else if (stackptr < (stack + sizeof(stack) / sizeof(stack[0]) - 1))
{ {
char *language; /* Language name, if any */ char *language; /* Language name, if any */
DEBUG2_printf("Starting code block with fence '%c'.\n", *lineptr); DEBUG2_printf("Starting code block with fence '%c'.\n", *lineptr);
block = NULL; block = NULL;
stackptr[1].parent = mmd_add(stackptr->parent, MMD_TYPE_CODE_BLOCK, 0, stackptr[1].parent = mmd_add(stackptr->parent, MMD_TYPE_CODE_BLOCK, 0,
NULL, NULL); NULL, NULL);
stackptr[1].indent = lineptr - line; stackptr[1].indent = lineptr - line;
stackptr[1].fence = *lineptr; stackptr[1].fence = *lineptr;
stackptr[1].fencelen = mmd_is_codefence(lineptr, '\0', 0, &language); stackptr[1].fencelen = mmd_is_codefence(lineptr, '\0', 0, &language);
stackptr ++; stackptr ++;
DEBUG2_printf("Code language=\"%s\"\n", language); DEBUG2_printf("Code language=\"%s\"\n", language);
if (language) if (language)
stackptr->parent->extra = strdup(language); stackptr->parent->extra = strdup(language);
blank_code = 0; blank_code = 0;
} }
continue; continue;
} }
else if (stackptr->parent->type == MMD_TYPE_CODE_BLOCK && (lineptr - line) > = stackptr->indent) else if (stackptr->parent->type == MMD_TYPE_CODE_BLOCK && (lineptr - line) > = stackptr->indent)
{ {
if (line[stackptr->indent] == '\n') if (line[stackptr->indent] == '\n')
{ {
blank_code ++; blank_code ++;
} }
else else
{ {
while (blank_code > 0) while (blank_code > 0)
{ {
mmd_add(stackptr->parent, MMD_TYPE_CODE_TEXT, 0, "\n", NULL); mmd_add(stackptr->parent, MMD_TYPE_CODE_TEXT, 0, "\n", NULL);
blank_code --; blank_code --;
} }
mmd_add(stackptr->parent, MMD_TYPE_CODE_TEXT, 0, line + stackptr->indent, NULL); mmd_add(stackptr->parent, MMD_TYPE_CODE_TEXT, 0, line + stackptr->indent, NULL);
} }
continue; continue;
} }
else if (stackptr->parent->type == MMD_TYPE_CODE_BLOCK && stackptr->fence) else if (stackptr->parent->type == MMD_TYPE_CODE_BLOCK && stackptr->fence)
{ {
DEBUG2_printf(" fence='%c'\n", stackptr->fence); DEBUG2_printf(" fence='%c'\n", stackptr->fence);
if (!*lineptr) if (!*lineptr)
{ {
blank_code ++; blank_code ++;
} }
else else
{ {
while (blank_code > 0) while (blank_code > 0)
{ {
mmd_add(stackptr->parent, MMD_TYPE_CODE_TEXT, 0, "\n", NULL); mmd_add(stackptr->parent, MMD_TYPE_CODE_TEXT, 0, "\n", NULL);
blank_code --; blank_code --;
} }
mmd_add(stackptr->parent, MMD_TYPE_CODE_TEXT, 0, lineptr, NULL); mmd_add(stackptr->parent, MMD_TYPE_CODE_TEXT, 0, lineptr, NULL);
skipping to change at line 671 skipping to change at line 668
else if (!strncmp(lineptr, "---", 3) && doc.root->first_child == NULL && (mm d_options & MMD_OPTION_METADATA)) else if (!strncmp(lineptr, "---", 3) && doc.root->first_child == NULL && (mm d_options & MMD_OPTION_METADATA))
{ {
/* /*
* Document metadata... * Document metadata...
*/ */
block = mmd_add(doc.root, MMD_TYPE_METADATA, 0, NULL, NULL); block = mmd_add(doc.root, MMD_TYPE_METADATA, 0, NULL, NULL);
while ((lineptr = mmd_read_line(&file, line, sizeof(line))) != NULL) while ((lineptr = mmd_read_line(&file, line, sizeof(line))) != NULL)
{ {
while (isspace(*lineptr & 255)) while (isspace(*lineptr & 255))
lineptr ++; lineptr ++;
if (!strncmp(lineptr, "---", 3) || !strncmp(lineptr, "...", 3)) if (!strncmp(lineptr, "---", 3) || !strncmp(lineptr, "...", 3))
break; break;
lineend = lineptr + strlen(lineptr) - 1; lineend = lineptr + strlen(lineptr) - 1;
if (lineend > lineptr && *lineend == '\n') if (lineend > lineptr && *lineend == '\n')
*lineend = '\0'; *lineend = '\0';
mmd_add(block, MMD_TYPE_METADATA_TEXT, 0, lineptr, NULL); mmd_add(block, MMD_TYPE_METADATA_TEXT, 0, lineptr, NULL);
} }
continue; continue;
} }
else if (block && block->type == MMD_TYPE_PARAGRAPH && (lineptr - linestart) < 4 && (lineptr - line) >= stackptr->indent && (mmd_is_chars(lineptr, "-", 1) | | mmd_is_chars(lineptr, "=", 1))) else if (block && block->type == MMD_TYPE_PARAGRAPH && (lineptr - linestart) < 4 && (lineptr - line) >= stackptr->indent && (mmd_is_chars(lineptr, "-", 1) | | mmd_is_chars(lineptr, "=", 1)))
{ {
int ch = *lineptr; int ch = *lineptr;
DEBUG_puts(" SETEXT HEADING\n"); DEBUG_puts(" SETEXT HEADING\n");
lineptr += 3; lineptr += 3;
while (*lineptr == ch) while (*lineptr == ch)
lineptr ++; lineptr ++;
while (isspace(*lineptr & 255)) while (isspace(*lineptr & 255))
lineptr ++; lineptr ++;
if (!*lineptr) if (!*lineptr)
{ {
if (ch == '=') if (ch == '=')
block->type = MMD_TYPE_HEADING_1; block->type = MMD_TYPE_HEADING_1;
else else
block->type = MMD_TYPE_HEADING_2; block->type = MMD_TYPE_HEADING_2;
block = NULL; block = NULL;
continue; continue;
} }
type = MMD_TYPE_PARAGRAPH; type = MMD_TYPE_PARAGRAPH;
} }
else if ((lineptr - linestart) < 4 && (mmd_is_chars(lineptr, "- \t", 3) || m md_is_chars(lineptr, "_ \t", 3) || mmd_is_chars(lineptr, "* \t", 3))) else if ((lineptr - linestart) < 4 && (mmd_is_chars(lineptr, "- \t", 3) || m md_is_chars(lineptr, "_ \t", 3) || mmd_is_chars(lineptr, "* \t", 3)))
{ {
DEBUG_puts(" THEMATIC BREAK\n"); DEBUG_puts(" THEMATIC BREAK\n");
if (line[0] == '>') if (line[0] == '>')
stackptr = stack + 1; stackptr = stack + 1;
else else
stackptr = stack; stackptr = stack;
mmd_add(stackptr->parent, MMD_TYPE_THEMATIC_BREAK, 0, NULL, NULL); mmd_add(stackptr->parent, MMD_TYPE_THEMATIC_BREAK, 0, NULL, NULL);
type = MMD_TYPE_PARAGRAPH; type = MMD_TYPE_PARAGRAPH;
block = NULL; block = NULL;
continue; continue;
} }
else if ((*lineptr == '-' || *lineptr == '+' || *lineptr == '*') && (lineptr [1] == '\t' || lineptr[1] == ' ')) else if ((*lineptr == '-' || *lineptr == '+' || *lineptr == '*') && (lineptr [1] == '\t' || lineptr[1] == ' '))
{ {
/* /*
* Bulleted list... * Bulleted list...
*/ */
DEBUG_puts(" UNORDERED LIST\n"); DEBUG_puts(" UNORDERED LIST\n");
lineptr += 2; lineptr += 2;
linestart = lineptr; linestart = lineptr;
newindent = linestart - line; newindent = linestart - line;
while (isspace(*lineptr & 255)) while (isspace(*lineptr & 255))
lineptr ++; lineptr ++;
while (stackptr > stack && stackptr->indent > newindent) while (stackptr > stack && stackptr->indent > newindent)
stackptr --; stackptr --;
if (stackptr->parent->type == MMD_TYPE_LIST_ITEM && stackptr->indent == ne windent) if (stackptr->parent->type == MMD_TYPE_LIST_ITEM && stackptr->indent == ne windent)
stackptr --; stackptr --;
if (stackptr->parent->type == MMD_TYPE_ORDERED_LIST && stackptr->indent == newindent) if (stackptr->parent->type == MMD_TYPE_ORDERED_LIST && stackptr->indent == newindent)
stackptr --; stackptr --;
if (stackptr->parent->type == MMD_TYPE_BLOCK_QUOTE && line[0] != '>') if (stackptr->parent->type == MMD_TYPE_BLOCK_QUOTE && line[0] != '>')
stackptr --; stackptr --;
if (stackptr->parent->type != MMD_TYPE_UNORDERED_LIST && stackptr < (stack + sizeof(stack) / sizeof(stack[0]) - 1)) if (stackptr->parent->type != MMD_TYPE_UNORDERED_LIST && stackptr < (stack + sizeof(stack) / sizeof(stack[0]) - 1))
{ {
stackptr[1].parent = mmd_add(stackptr->parent, MMD_TYPE_UNORDERED_LIST, stackptr[1].parent = mmd_add(stackptr->parent, MMD_TYPE_UNORDERED_LIST, 0
0, NULL, NULL); , NULL, NULL);
stackptr[1].indent = linestart - line; stackptr[1].indent = linestart - line;
stackptr[1].fence = '\0'; stackptr[1].fence = '\0';
stackptr ++; stackptr ++;
} }
if (stackptr < (stack + sizeof(stack) / sizeof(stack[0]) - 1)) if (stackptr < (stack + sizeof(stack) / sizeof(stack[0]) - 1))
{ {
stackptr[1].parent = mmd_add(stackptr->parent, MMD_TYPE_LIST_ITEM, 0, NU stackptr[1].parent = mmd_add(stackptr->parent, MMD_TYPE_LIST_ITEM, 0, NUL
LL, NULL); L, NULL);
stackptr[1].indent = linestart - line; stackptr[1].indent = linestart - line;
stackptr[1].fence = '\0'; stackptr[1].fence = '\0';
stackptr ++; stackptr ++;
} }
type = MMD_TYPE_PARAGRAPH; type = MMD_TYPE_PARAGRAPH;
block = NULL; block = NULL;
if (mmd_is_chars(lineptr, "- \t", 3) || mmd_is_chars(lineptr, "_ \t", 3) | | mmd_is_chars(lineptr, "* \t", 3)) if (mmd_is_chars(lineptr, "- \t", 3) || mmd_is_chars(lineptr, "_ \t", 3) | | mmd_is_chars(lineptr, "* \t", 3))
{ {
mmd_add(stackptr->parent, MMD_TYPE_THEMATIC_BREAK, 0, NULL, NULL); mmd_add(stackptr->parent, MMD_TYPE_THEMATIC_BREAK, 0, NULL, NULL);
continue; continue;
} }
skipping to change at line 787 skipping to change at line 784
{ {
/* /*
* Ordered list? * Ordered list?
*/ */
DEBUG_puts(" ORDERED LIST?\n"); DEBUG_puts(" ORDERED LIST?\n");
temp = lineptr + 1; temp = lineptr + 1;
while (isdigit(*temp & 255)) while (isdigit(*temp & 255))
temp ++; temp ++;
if ((*temp == '.' || *temp == ')') && (temp[1] == '\t' || temp[1] == ' ')) if ((*temp == '.' || *temp == ')') && (temp[1] == '\t' || temp[1] == ' '))
{ {
/* /*
* Yes, ordered list. * Yes, ordered list.
*/ */
lineptr = temp + 2; lineptr = temp + 2;
linestart = lineptr; linestart = lineptr;
newindent = linestart - line; newindent = linestart - line;
while (isspace(*lineptr & 255)) while (isspace(*lineptr & 255))
lineptr ++; lineptr ++;
while (stackptr > stack && stackptr->indent > newindent) while (stackptr > stack && stackptr->indent > newindent)
stackptr --; stackptr --;
if (stackptr->parent->type == MMD_TYPE_LIST_ITEM && stackptr->indent == n ewindent) if (stackptr->parent->type == MMD_TYPE_LIST_ITEM && stackptr->indent == n ewindent)
stackptr --; stackptr --;
if (stackptr->parent->type == MMD_TYPE_UNORDERED_LIST && stackptr->indent == newindent) if (stackptr->parent->type == MMD_TYPE_UNORDERED_LIST && stackptr->indent == newindent)
stackptr --; stackptr --;
if (stackptr->parent->type == MMD_TYPE_BLOCK_QUOTE && line[0] != '>') if (stackptr->parent->type == MMD_TYPE_BLOCK_QUOTE && line[0] != '>')
stackptr --; stackptr --;
if (stackptr->parent->type != MMD_TYPE_ORDERED_LIST && stackptr < (stack + sizeof(stack) / sizeof(stack[0]) - 1)) if (stackptr->parent->type != MMD_TYPE_ORDERED_LIST && stackptr < (stack + sizeof(stack) / sizeof(stack[0]) - 1))
{ {
stackptr[1].parent = mmd_add(stackptr->parent, MMD_TYPE_ORDERED_LIST, 0 , NULL, NULL); stackptr[1].parent = mmd_add(stackptr->parent, MMD_TYPE_ORDERED_LIST, 0 , NULL, NULL);
stackptr[1].indent = linestart - line; stackptr[1].indent = linestart - line;
stackptr[1].fence = '\0'; stackptr[1].fence = '\0';
stackptr ++; stackptr ++;
} }
if (stackptr < (stack + sizeof(stack) / sizeof(stack[0]) - 1)) if (stackptr < (stack + sizeof(stack) / sizeof(stack[0]) - 1))
skipping to change at line 836 skipping to change at line 833
stackptr[1].fence = '\0'; stackptr[1].fence = '\0';
stackptr ++; stackptr ++;
} }
type = MMD_TYPE_PARAGRAPH; type = MMD_TYPE_PARAGRAPH;
block = NULL; block = NULL;
} }
else else
{ {
/* /*
* No, just a regular paragraph... * No, just a regular paragraph...
*/ */
type = block ? block->type : MMD_TYPE_PARAGRAPH; type = block ? block->type : MMD_TYPE_PARAGRAPH;
} }
} }
else if (*lineptr == '#' && (lineptr - linestart) < 4) else if (*lineptr == '#' && (lineptr - linestart) < 4)
{ {
/* /*
* Heading, count the number of '#' for the heading level... * Heading, count the number of '#' for the heading level...
*/ */
DEBUG_puts(" HEADING?\n"); DEBUG_puts(" HEADING?\n");
newindent = lineptr - line; newindent = lineptr - line;
temp = lineptr + 1; temp = lineptr + 1;
while (*temp == '#') while (*temp == '#')
temp ++; temp ++;
if ((temp - lineptr) <= 6 && isspace(*temp & 255)) if ((temp - lineptr) <= 6 && isspace(*temp & 255))
{ {
/* /*
* Heading 1-6... * Heading 1-6...
*/ */
type = MMD_TYPE_HEADING_1 + (temp - lineptr - 1); type = MMD_TYPE_HEADING_1 + (temp - lineptr - 1);
block = NULL; block = NULL;
/* /*
* Skip whitespace after "#"... * Skip whitespace after "#"...
*/ */
lineptr = temp; lineptr = temp;
while (isspace(*lineptr & 255)) while (isspace(*lineptr & 255))
lineptr ++; lineptr ++;
linestart = lineptr; linestart = lineptr;
/* /*
* Strip trailing "#" characters and whitespace... * Strip trailing "#" characters and whitespace...
*/ */
temp = lineptr + strlen(lineptr) - 1; temp = lineptr + strlen(lineptr) - 1;
while (temp > lineptr && isspace(*temp & 255)) while (temp > lineptr && isspace(*temp & 255))
*temp-- = '\0'; *temp-- = '\0';
while (temp > lineptr && *temp == '#') while (temp > lineptr && *temp == '#')
temp --; temp --;
if (isspace(*temp & 255)) if (isspace(*temp & 255))
{ {
while (temp > lineptr && isspace(*temp & 255)) while (temp > lineptr && isspace(*temp & 255))
*temp-- = '\0'; *temp-- = '\0';
} }
else if (temp == lineptr) else if (temp == lineptr)
*temp = '\0'; *temp = '\0';
while (stackptr > stack && stackptr->indent > newindent) while (stackptr > stack && stackptr->indent > newindent)
stackptr --; stackptr --;
block = mmd_add(stackptr->parent, type, 0, NULL, NULL); block = mmd_add(stackptr->parent, type, 0, NULL, NULL);
} }
else else
{ {
/* /*
* More than 6 #'s, just treat as a paragraph... * More than 6 #'s, just treat as a paragraph...
*/ */
type = MMD_TYPE_PARAGRAPH; type = MMD_TYPE_PARAGRAPH;
} }
} }
else if (block && block->type >= MMD_TYPE_HEADING_1 && block->type <= MMD_TY PE_HEADING_6) else if (block && block->type >= MMD_TYPE_HEADING_1 && block->type <= MMD_TY PE_HEADING_6)
{ {
DEBUG_puts(" PARAGRAPH\n"); DEBUG_puts(" PARAGRAPH\n");
type = MMD_TYPE_PARAGRAPH; type = MMD_TYPE_PARAGRAPH;
block = NULL; block = NULL;
} }
else if (!block) else if (!block)
{ {
type = MMD_TYPE_PARAGRAPH; type = MMD_TYPE_PARAGRAPH;
if (lineptr == line && stackptr->parent->type != MMD_TYPE_TABLE) if (lineptr == line && stackptr->parent->type != MMD_TYPE_TABLE)
stackptr = stack; stackptr = stack;
} }
else else
type = block->type; type = block->type;
if (!*lineptr) if (!*lineptr)
{ {
if (stackptr->parent->type == MMD_TYPE_CODE_BLOCK) if (stackptr->parent->type == MMD_TYPE_CODE_BLOCK)
blank_code ++; blank_code ++;
else if (stackptr->parent->type == MMD_TYPE_BLOCK_QUOTE && line[0] != '>') else if (stackptr->parent->type == MMD_TYPE_BLOCK_QUOTE && line[0] != '>')
stackptr --; stackptr --;
block = NULL; block = NULL;
continue; continue;
} }
else if (!strcmp(lineptr, "+")) else if (!strcmp(lineptr, "+"))
{ {
if (block) if (block)
{ {
if (block->type == MMD_TYPE_LIST_ITEM) if (block->type == MMD_TYPE_LIST_ITEM)
block = mmd_add(block, MMD_TYPE_PARAGRAPH, 0, NULL, NULL); block = mmd_add(block, MMD_TYPE_PARAGRAPH, 0, NULL, NULL);
else if (block->parent->type == MMD_TYPE_LIST_ITEM) else if (block->parent->type == MMD_TYPE_LIST_ITEM)
block = mmd_add(block->parent, MMD_TYPE_PARAGRAPH, 0, NULL, NULL); block = mmd_add(block->parent, MMD_TYPE_PARAGRAPH, 0, NULL, NULL);
else else
block = NULL; block = NULL;
} }
continue; continue;
} }
else if ((mmd_options & MMD_OPTION_TABLES) && strchr(lineptr, '|') && (stack ptr->parent->type == MMD_TYPE_TABLE || mmd_is_table(&file, stackptr->indent))) else if ((mmd_options & MMD_OPTION_TABLES) && strchr(lineptr, '|') && (stack ptr->parent->type == MMD_TYPE_TABLE || mmd_is_table(&file, stackptr->indent)))
{ {
/* /*
* Table... * Table...
*/ */
int col; /* Current column */ int col; /* Current column */
char *start, /* Start of column/cell */ char *start, /* Start of column/cell */
*end; /* End of column/cell */ *end; /* End of column/cell */
mmd_t *row = NULL, /* Current row */ mmd_t *row = NULL, /* Current row */
*cell; /* Current cell */ *cell; /* Current cell */
DEBUG2_printf("TABLE stackptr->parent=%p (%d), rows=%d\n", stackptr->paren t, stackptr->parent->type, rows); DEBUG2_printf("TABLE stackptr->parent=%p (%d), rows=%d\n", stackptr->paren t, stackptr->parent->type, rows);
if (stackptr->parent->type != MMD_TYPE_TABLE && stackptr < (stack + sizeof (stack) / sizeof(stack[0]) - 1)) if (stackptr->parent->type != MMD_TYPE_TABLE && stackptr < (stack + sizeof (stack) / sizeof(stack[0]) - 1))
{ {
DEBUG2_printf("ADDING NEW TABLE to %p (%s)\n", stackptr->parent, mmd_typ e_string(stackptr->parent->type)); DEBUG2_printf("ADDING NEW TABLE to %p (%s)\n", stackptr->parent, mmd_type _string(stackptr->parent->type));
stackptr[1].parent = mmd_add(stackptr->parent, MMD_TYPE_TABLE, 0, NULL, stackptr[1].parent = mmd_add(stackptr->parent, MMD_TYPE_TABLE, 0, NULL, N
NULL); ULL);
stackptr[1].indent = stackptr->indent; stackptr[1].indent = stackptr->indent;
stackptr[1].fence = '\0'; stackptr[1].fence = '\0';
stackptr ++; stackptr ++;
block = mmd_add(stackptr->parent, MMD_TYPE_TABLE_HEADER, 0, NULL, NULL); block = mmd_add(stackptr->parent, MMD_TYPE_TABLE_HEADER, 0, NULL, NULL);
for (col = 0; col < (int)(sizeof(columns) / sizeof(columns[0])); col ++) for (col = 0; col < (int)(sizeof(columns) / sizeof(columns[0])); col ++)
columns[col] = MMD_TYPE_TABLE_BODY_CELL_LEFT; columns[col] = MMD_TYPE_TABLE_BODY_CELL_LEFT;
num_columns = 0; num_columns = 0;
rows = -1; rows = -1;
} }
else if (rows > 0) else if (rows > 0)
{ {
if (rows == 1) if (rows == 1)
block = mmd_add(stackptr->parent, MMD_TYPE_TABLE_BODY, 0, NULL, NULL); block = mmd_add(stackptr->parent, MMD_TYPE_TABLE_BODY, 0, NULL, NULL);
} }
else else
block = NULL; block = NULL;
if (block) if (block)
row = mmd_add(block, MMD_TYPE_TABLE_ROW, 0, NULL, NULL); row = mmd_add(block, MMD_TYPE_TABLE_ROW, 0, NULL, NULL);
if (*lineptr == '|') if (*lineptr == '|')
lineptr ++; /* Skip leading pipe */ lineptr ++; /* Skip leading pipe */
if ((end = lineptr + strlen(lineptr) - 1) > lineptr) if ((end = lineptr + strlen(lineptr) - 1) > lineptr)
{ {
while ((*end == '\n' || *end == 'r') && end > lineptr) while ((*end == '\n' || *end == 'r') && end > lineptr)
end --; end --;
if (end > lineptr && *end == '|') if (end > lineptr && *end == '|')
*end = '\0'; /* Truncate trailing pipe */ *end = '\0'; /* Truncate trailing pipe */
} }
for (col = 0; lineptr && *lineptr && col < (int)(sizeof(columns) / sizeof( columns[0])); col ++) for (col = 0; lineptr && *lineptr && col < (int)(sizeof(columns) / sizeof( columns[0])); col ++)
{ {
/* /*
* Get the bounds of the stackptr->parent cell... * Get the bounds of the stackptr->parent cell...
*/ */
start = lineptr; start = lineptr;
if ((lineptr = strchr(lineptr + 1, '|')) != NULL) if ((lineptr = strchr(lineptr + 1, '|')) != NULL)
*lineptr++ = '\0'; *lineptr++ = '\0';
if (block) if (block)
{ {
/* /*
* Add a cell to this row... * Add a cell to this row...
*/ */
if (block->type == MMD_TYPE_TABLE_HEADER) if (block->type == MMD_TYPE_TABLE_HEADER)
cell = mmd_add(row, MMD_TYPE_TABLE_HEADER_CELL, 0, NULL, NULL); cell = mmd_add(row, MMD_TYPE_TABLE_HEADER_CELL, 0, NULL, NULL);
else else
cell = mmd_add(row, columns[col], 0, NULL, NULL); cell = mmd_add(row, columns[col], 0, NULL, NULL);
mmd_parse_inline(&doc, cell, start); mmd_parse_inline(&doc, cell, start);
} }
else else
{ {
/* /*
* Process separator row for alignment... * Process separator row for alignment...
*/ */
while (isspace(*start & 255)) while (isspace(*start & 255))
start ++; start ++;
for (end = start + strlen(start) - 1; end > start && isspace(*end & 25 for (end = start + strlen(start) - 1; end > start && isspace(*end & 255
5); end --); ); end --)
; /* Find the last non-space character */
if (*start == ':' && *end == ':') if (*start == ':' && *end == ':')
columns[col] = MMD_TYPE_TABLE_BODY_CELL_CENTER; columns[col] = MMD_TYPE_TABLE_BODY_CELL_CENTER;
else if (*end == ':') else if (*end == ':')
columns[col] = MMD_TYPE_TABLE_BODY_CELL_RIGHT; columns[col] = MMD_TYPE_TABLE_BODY_CELL_RIGHT;
DEBUG2_printf("COLUMN %d SEPARATOR=\"%s\", TYPE=%d\n", col, start, col DEBUG2_printf("COLUMN %d SEPARATOR=\"%s\", TYPE=%d\n", col, start, colu
umns[col]); mns[col]);
} }
} }
/* /*
* Make sure the table is balanced... * Make sure the table is balanced...
*/ */
if (col > num_columns) if (col > num_columns)
{ {
num_columns = col; num_columns = col;
} }
else if (block && block->type != MMD_TYPE_TABLE_HEADER) else if (block && block->type != MMD_TYPE_TABLE_HEADER)
{ {
while (col < num_columns) while (col < num_columns)
{ {
mmd_add(row, columns[col], 0, NULL, NULL); mmd_add(row, columns[col], 0, NULL, NULL);
col ++; col ++;
} }
} }
rows ++; rows ++;
continue; continue;
} }
else if (stackptr->parent->type == MMD_TYPE_TABLE) else if (stackptr->parent->type == MMD_TYPE_TABLE)
{ {
DEBUG2_puts("END TABLE\n"); DEBUG2_puts("END TABLE\n");
stackptr --; stackptr --;
block = NULL; block = NULL;
} }
if (stackptr->parent->type != MMD_TYPE_CODE_BLOCK && (!block || block->type == MMD_TYPE_CODE_BLOCK) && (lineptr - linestart) >= (stackptr->indent + 4)) if (stackptr->parent->type != MMD_TYPE_CODE_BLOCK && (!block || block->type == MMD_TYPE_CODE_BLOCK) && (lineptr - linestart) >= (stackptr->indent + 4))
{ {
/* /*
* Indented code block. * Indented code block.
*/ */
if (stackptr->parent->type != MMD_TYPE_CODE_BLOCK && stackptr < (stack + s izeof(stack) / sizeof(stack[0]) - 1)) if (stackptr->parent->type != MMD_TYPE_CODE_BLOCK && stackptr < (stack + s izeof(stack) / sizeof(stack[0]) - 1))
{ {
stackptr[1].parent = mmd_add(stackptr->parent, MMD_TYPE_CODE_BLOCK, 0, N stackptr[1].parent = mmd_add(stackptr->parent, MMD_TYPE_CODE_BLOCK, 0, NU
ULL, NULL); LL, NULL);
stackptr[1].indent = stackptr->indent + 4; stackptr[1].indent = stackptr->indent + 4;
stackptr[1].fence = '\0'; stackptr[1].fence = '\0';
stackptr ++; stackptr ++;
blank_code = 0; blank_code = 0;
} }
while (blank_code > 0) while (blank_code > 0)
{ {
mmd_add(stackptr->parent, MMD_TYPE_CODE_TEXT, 0, "\n", NULL); mmd_add(stackptr->parent, MMD_TYPE_CODE_TEXT, 0, "\n", NULL);
blank_code --; blank_code --;
} }
mmd_add(stackptr->parent, MMD_TYPE_CODE_TEXT, 0, line + stackptr->indent, NULL); mmd_add(stackptr->parent, MMD_TYPE_CODE_TEXT, 0, line + stackptr->indent, NULL);
continue; continue;
} }
if (!block || block->type != type) if (!block || block->type != type)
{ {
if (stackptr->parent->type == MMD_TYPE_CODE_BLOCK) if (stackptr->parent->type == MMD_TYPE_CODE_BLOCK)
stackptr --; stackptr --;
block = mmd_add(stackptr->parent, type, 0, NULL, NULL); block = mmd_add(stackptr->parent, type, 0, NULL, NULL);
} }
/* /*
* Read continuation lines before parsing this... * Read continuation lines before parsing this...
*/ */
while (mmd_has_continuation(line, &file, stackptr->indent)) while (mmd_has_continuation(line, &file, stackptr->indent))
{ {
char *ptr = line + strlen(line); char *ptr = line + strlen(line);
if (!mmd_read_line(&file, ptr, sizeof(line) - (size_t)(ptr - line))) if (!mmd_read_line(&file, ptr, sizeof(line) - (size_t)(ptr - line)))
break; break;
else if (line[0] == '>' && *ptr == '>') else if (line[0] == '>' && *ptr == '>')
memmove(ptr, ptr + 1, strlen(ptr)); memmove(ptr, ptr + 1, strlen(ptr));
} }
mmd_parse_inline(&doc, block, lineptr); mmd_parse_inline(&doc, block, lineptr);
if (block->type == MMD_TYPE_PARAGRAPH && !block->first_child) if (block->type == MMD_TYPE_PARAGRAPH && !block->first_child)
{ {
mmd_remove(block); mmd_remove(block);
mmd_free(block); mmd_free(block);
block = NULL; block = NULL;
} }
skipping to change at line 1144 skipping to change at line 1143
if (reference->pending) if (reference->pending)
{ {
char text[8192]; /* Reference text */ char text[8192]; /* Reference text */
size_t j; /* Looping var */ size_t j; /* Looping var */
DEBUG2_printf("Clearing links for '%s'.\n", reference->name); DEBUG2_printf("Clearing links for '%s'.\n", reference->name);
snprintf(text, sizeof(text), "[%s]", reference->name); snprintf(text, sizeof(text), "[%s]", reference->name);
for (j = 0; j < reference->num_pending; j ++) for (j = 0; j < reference->num_pending; j ++)
{ {
free(reference->pending[j]->text); free(reference->pending[j]->text);
reference->pending[j]->text = strdup(text); reference->pending[j]->text = strdup(text);
reference->pending[j]->type = MMD_TYPE_NORMAL_TEXT; reference->pending[j]->type = MMD_TYPE_NORMAL_TEXT;
} }
free(reference->pending); free(reference->pending);
} }
free(reference->name); free(reference->name);
free(reference->url); free(reference->url);
} }
free(doc.references); free(doc.references);
skipping to change at line 1179 skipping to change at line 1178
void void
mmdSetOptions(mmd_option_t options) /* I - Options */ mmdSetOptions(mmd_option_t options) /* I - Options */
{ {
mmd_options = options; mmd_options = options;
} }
/* /*
* 'mmd_add()' - Add a new markdown node. * 'mmd_add()' - Add a new markdown node.
*/ */
static mmd_t * /* O - New node */ static mmd_t * /* O - New node */
mmd_add(mmd_t *parent, /* I - Parent node */ mmd_add(mmd_t *parent, /* I - Parent node */
mmd_type_t type, /* I - Node type */ mmd_type_t type, /* I - Node type */
int whitespace, /* I - 1 if whitespace precedes this nod int whitespace, /* I - 1 if whitespace precedes this node
e */ */
char *text, /* I - Text, if any */ char *text, /* I - Text, if any */
char *url) /* I - URL, if any */ char *url) /* I - URL, if any */
{ {
mmd_t *temp; /* New node */ mmd_t *temp; /* New node */
DEBUG2_printf("Adding %s to %p(%s), whitespace=%d, text=\"%s\", url=\"%s\"\n", mmd_type_string(type), parent, parent ? mmd_type_string(parent->type) : "", whi tespace, text ? text : "(null)", url ? url : "(null)"); DEBUG2_printf("Adding %s to %p(%s), whitespace=%d, text=\"%s\", url=\"%s\"\n", mmd_type_string(type), parent, parent ? mmd_type_string(parent->type) : "", whi tespace, text ? text : "(null)", url ? url : "(null)");
if (!parent && type != MMD_TYPE_DOCUMENT)
return (NULL); /* Only document nodes can be at the root
*/
if ((temp = calloc(1, sizeof(mmd_t))) != NULL) if ((temp = calloc(1, sizeof(mmd_t))) != NULL)
{ {
if (parent) if (parent)
{ {
/* /*
* Add node to the parent... * Add node to the parent...
*/ */
temp->parent = parent; temp->parent = parent;
if (parent->last_child) if (parent->last_child)
{ {
parent->last_child->next_sibling = temp; parent->last_child->next_sibling = temp;
temp->prev_sibling = parent->last_child; temp->prev_sibling = parent->last_child;
parent->last_child = temp; parent->last_child = temp;
} }
else else
{ {
parent->first_child = parent->last_child = temp; parent->first_child = parent->last_child = temp;
} }
} }
/* /*
* Copy the node values... * Copy the node values...
*/ */
temp->type = type; temp->type = type;
temp->whitespace = whitespace; temp->whitespace = whitespace;
if (text) if (text)
temp->text = strdup(text); temp->text = strdup(text);
if (url) if (url)
temp->url = strdup(url); temp->url = strdup(url);
} }
return (temp); return (temp);
} }
/* /*
* 'mmd_free()' - Free memory used by a node. * 'mmd_free()' - Free memory used by a node.
*/ */
static void static void
mmd_free(mmd_t *node) /* I - Node */ mmd_free(mmd_t *node) /* I - Node */
{ {
free(node->text); free(node->text);
free(node->url); free(node->url);
free(node->extra); free(node->extra);
free(node); free(node);
} }
/* /*
* 'mmd_has_continuation()' - Determine whether the next line is a continuation * 'mmd_has_continuation()' - Determine whether the next line is a continuation
* of the current one. * of the current one.
*/ */
static int /* O - 1 if the next line continues, 0 ot herwise */ static int /* O - 1 if the next line continues, 0 ot herwise */
mmd_has_continuation( mmd_has_continuation(
const char *line, /* I - Current line */ const char *line, /* I - Current line */
_mmd_filebuf_t *file, /* I - File buffer */ _mmd_filebuf_t *file, /* I - File buffer */
int indent) /* I - Indentation for current block */ int indent) /* I - Indentation for current bl ock */
{ {
const char *lineptr = line; /* Pointer into current line */ const char *lineptr = line; /* Pointer into current line */
const char *fileptr = file->bufptr;/* Pointer into next line */ const char *fileptr = file->bufptr;/* Pointer into next line */
if (*fileptr == '\n' || *fileptr == '\r') if (*fileptr == '\n' || *fileptr == '\r')
return (0); return (0);
do do
{ {
while (isspace(*lineptr & 255)) while (isspace(*lineptr & 255))
skipping to change at line 1352 skipping to change at line 1354
if (count <= 6) if (count <= 6)
return (0); return (0);
} }
return ((fileptr - file->bufptr) <= indent); return ((fileptr - file->bufptr) <= indent);
} }
/* /*
* 'mmd_is_chars()' - Determine whether a line consists solely of whitespace * 'mmd_is_chars()' - Determine whether a line consists solely of whitespace
* and the specified character. * and the specified character.
*/ */
static size_t /* O - 1 if as specified, 0 otherwise */ static size_t /* O - 1 if as specified, 0 otherwise */
mmd_is_chars(const char *lineptr, /* I - Current line */ mmd_is_chars(const char *lineptr, /* I - Current line */
const char *chars, /* I - Non-space character */ const char *chars, /* I - Non-space character */
size_t minchars) /* I - Minimum number of non-space charac size_t minchars) /* I - Minimum number of non-space charac
ters */ ters */
{ {
size_t found_ch = 0; /* Did we find the specified characters? */ size_t found_ch = 0; /* Did we find the specified characters? */
while (*lineptr == *chars) while (*lineptr == *chars)
{ {
found_ch ++; found_ch ++;
lineptr ++; lineptr ++;
} }
if (minchars > 1) if (minchars > 1)
skipping to change at line 1393 skipping to change at line 1395
return (0); return (0);
else else
return (found_ch); return (found_ch);
} }
/* /*
* 'mmd_is_codefence()' - Determine whether the line contains a code fence. * 'mmd_is_codefence()' - Determine whether the line contains a code fence.
*/ */
static size_t /* O - Length of fence or 0 otherwise */ static size_t /* O - Length of fence or 0 otherwise */
mmd_is_codefence(char *lineptr, /* I - Line */ mmd_is_codefence(char *lineptr, /* I - Line */
char fence, /* I - Current fence character, if any */ char fence, /* I - Current fence character, if any */
size_t fencelen, /* I - Current fence length */ size_t fencelen, /* I - Current fence length */
char **language) /* O - Language name, if any */ char **language) /* O - Language name, if any */
{ {
char match = fence; /* Character to match */ char match = fence; /* Character to match */
size_t len = 0; /* Length of fence chars */ size_t len = 0; /* Length of fence chars */
if (language) if (language)
*language = NULL; *language = NULL;
if (!match) if (!match)
{ {
if (*lineptr == '~' || *lineptr == '`') if (*lineptr == '~' || *lineptr == '`')
skipping to change at line 1436 skipping to change at line 1438
return (0); return (0);
while (isspace(*lineptr & 255)) while (isspace(*lineptr & 255))
lineptr ++; lineptr ++;
if (*lineptr && language) if (*lineptr && language)
{ {
*language = lineptr; *language = lineptr;
while (*lineptr && !isspace(*lineptr & 255)) while (*lineptr && !isspace(*lineptr & 255))
lineptr ++; lineptr ++;
*lineptr = '\0'; *lineptr = '\0';
} }
} }
return (len); return (len);
} }
/* /*
* 'mmd_is_table()' - Look ahead to see if the next line contains a heading * 'mmd_is_table()' - Look ahead to see if the next line contains a heading
* divider for a table. * divider for a table.
*/ */
static int /* O - 1 if this is a table, 0 otherwise */ static int /* O - 1 if this is a table, 0 otherwise */
mmd_is_table(_mmd_filebuf_t *file, /* I - File to read from */ mmd_is_table(_mmd_filebuf_t *file, /* I - File to read from */
int indent) /* I - Indentation of table line */ int indent) /* I - Indentation of table line */
{ {
const char *ptr; /* Pointer into buffer */ const char *ptr; /* Pointer into buffer */
ptr = file->bufptr; ptr = file->bufptr;
while (*ptr) while (*ptr)
{ {
if (!strchr(" \t>", *ptr)) if (!strchr(" \t>", *ptr))
break; break;
ptr ++; ptr ++;
skipping to change at line 1484 skipping to change at line 1486
return (*ptr == '\r' || *ptr == '\n'); return (*ptr == '\r' || *ptr == '\n');
} }
/* /*
* 'mmd_parse_inline()' - Parse inline formatting. * 'mmd_parse_inline()' - Parse inline formatting.
*/ */
static void static void
mmd_parse_inline(_mmd_doc_t *doc, /* I - Document */ mmd_parse_inline(_mmd_doc_t *doc, /* I - Document */
mmd_t *parent, /* I - Parent node */ mmd_t *parent, /* I - Parent node */
char *lineptr) /* I - Pointer into line */ char *lineptr) /* I - Pointer into line */
{ {
mmd_t *node; /* New node */ mmd_t *node; /* New node */
mmd_type_t type; /* Current node type */ mmd_type_t type; /* Current node type */
int whitespace; /* Whitespace precedes? */ int whitespace; /* Whitespace precedes? */
char *text, /* Text fragment in line */ char *text, /* Text fragment in line */
*title, /* Link title */ *title, /* Link title */
*url, /* URL in link */ *url, /* URL in link */
*refname; /* Reference name */ *refname; /* Reference name */
const char *delim = NULL; /* Delimiter */ const char *delim = NULL; /* Delimiter */
size_t delimlen = 0; /* Length of delimiter */ size_t delimlen = 0; /* Length of delimiter */
whitespace = parent->last_child != NULL; whitespace = parent->last_child != NULL;
for (text = NULL, type = MMD_TYPE_NORMAL_TEXT; *lineptr; lineptr ++) for (text = NULL, type = MMD_TYPE_NORMAL_TEXT; *lineptr; lineptr ++)
{ {
DEBUG2_printf("mmd_parse_inline: lineptr=\"%s\", type=%d, text=%p, whitespac e=%d\n", lineptr, type, text, whitespace); DEBUG2_printf("mmd_parse_inline: lineptr=%p(\"%32.32s...\"), type=%d, text=% p, whitespace=%d\n", lineptr, lineptr, type, text, whitespace);
if (isspace(*lineptr & 255) && type != MMD_TYPE_CODE_TEXT) if (isspace(*lineptr & 255) && type != MMD_TYPE_CODE_TEXT)
{ {
if (text) if (text)
{ {
*lineptr = '\0'; *lineptr = '\0';
mmd_add(parent, type, whitespace, text, NULL); mmd_add(parent, type, whitespace, text, NULL);
text = NULL; text = NULL;
whitespace = 0; whitespace = 0;
} }
if (!strncmp(lineptr + 1, " \n", 2) && lineptr[3]) if (!strncmp(lineptr + 1, " \n", 2) && lineptr[3])
{ {
DEBUG2_printf("mmd_parse_inline: Adding hard break to %p(%d)\n", parent, DEBUG2_printf("mmd_parse_inline: Adding hard break to %p(%d)\n", parent,
parent->type); parent->type);
mmd_add(parent, MMD_TYPE_HARD_BREAK, 0, NULL, NULL); mmd_add(parent, MMD_TYPE_HARD_BREAK, 0, NULL, NULL);
lineptr += 2; lineptr += 2;
whitespace = 0; whitespace = 0;
} }
else else
{ {
whitespace = 1; whitespace = 1;
} }
} }
else if (*lineptr == '!' && lineptr[1] == '[' && type != MMD_TYPE_CODE_TEXT) else if (*lineptr == '!' && lineptr[1] == '[' && type != MMD_TYPE_CODE_TEXT)
{ {
/* /*
* Image... * Image...
*/ */
if (text) if (text)
{ {
mmd_add(parent, type, whitespace, text, NULL); mmd_add(parent, type, whitespace, text, NULL);
text = NULL; text = NULL;
whitespace = 0; whitespace = 0;
} }
lineptr = mmd_parse_link(doc, lineptr + 1, &text, &url, NULL, &refname); lineptr = mmd_parse_link(doc, lineptr + 1, &text, &url, NULL, &refname);
if (url || refname) if (url || refname)
{ {
node = mmd_add(parent, MMD_TYPE_IMAGE, whitespace, text, url); node = mmd_add(parent, MMD_TYPE_IMAGE, whitespace, text, url);
if (refname) if (refname)
mmd_ref_add(doc, node, refname, NULL, NULL); mmd_ref_add(doc, node, refname, NULL, NULL);
} }
if (!*lineptr) if (!*lineptr)
return; return;
text = url = NULL; text = url = NULL;
whitespace = 0; whitespace = 0;
lineptr --; lineptr --;
} }
else if (*lineptr == '[' && type != MMD_TYPE_CODE_TEXT) else if (*lineptr == '[' && type != MMD_TYPE_CODE_TEXT)
{ {
/* /*
* Link... * Link...
*/ */
if (text) if (text)
{ {
mmd_add(parent, type, whitespace, text, NULL); *lineptr = '\0';
mmd_add(parent, type, whitespace, text, NULL);
*lineptr = '[';
text = NULL; text = NULL;
whitespace = 0; whitespace = 0;
} }
lineptr = mmd_parse_link(doc, lineptr, &text, &url, &title, &refname); lineptr = mmd_parse_link(doc, lineptr, &text, &url, &title, &refname);
if (text && *text == '`') if (text && *text == '`')
{ {
char *end = text + strlen(text) - 1; char *end = text + strlen(text) - 1;
text ++; text ++;
if (end > text && *end == '`') if (end > text && *end == '`')
*end = '\0'; *end = '\0';
node = mmd_add(parent, MMD_TYPE_CODE_TEXT, whitespace, text, url); node = mmd_add(parent, MMD_TYPE_CODE_TEXT, whitespace, text, url);
} }
else if (text) else if (text)
{ {
node = mmd_add(parent, MMD_TYPE_LINKED_TEXT, whitespace, text, url); node = mmd_add(parent, MMD_TYPE_LINKED_TEXT, whitespace, text, url);
if (title) if (title)
node->extra = strdup(title); node->extra = strdup(title);
} }
else else
node = NULL; node = NULL;
DEBUG2_printf("mmd_parse_inline: text=\"%s\", refname=\"%s\", node=%p\n", text, refname, node); DEBUG2_printf("mmd_parse_inline: text=\"%s\", refname=\"%s\", node=%p\n", text, refname, node);
if (refname && node) if (refname && node)
mmd_ref_add(doc, node, refname, NULL, title); mmd_ref_add(doc, node, refname, NULL, title);
if (!*lineptr) if (!*lineptr)
return; return;
text = url = NULL; text = url = NULL;
whitespace = 0; whitespace = 0;
lineptr --; lineptr --;
} }
else if (*lineptr == '<' && type != MMD_TYPE_CODE_TEXT && strchr(lineptr + 1 , '>')) else if (*lineptr == '<' && type != MMD_TYPE_CODE_TEXT && strchr(lineptr + 1 , '>'))
{ {
/* /*
* Autolink... * Autolink...
*/ */
*lineptr++ = '\0'; *lineptr++ = '\0';
if (text) if (text)
{ {
mmd_add(parent, type, whitespace, text, NULL); mmd_add(parent, type, whitespace, text, NULL);
text = NULL; text = NULL;
whitespace = 0; whitespace = 0;
} }
url = lineptr; url = lineptr;
lineptr = strchr(lineptr, '>'); lineptr = strchr(lineptr, '>');
*lineptr = '\0'; *lineptr = '\0';
mmd_add(parent, MMD_TYPE_LINKED_TEXT, whitespace, url, url); mmd_add(parent, MMD_TYPE_LINKED_TEXT, whitespace, url, url);
text = url = NULL; text = url = NULL;
whitespace = 0; whitespace = 0;
skipping to change at line 1649 skipping to change at line 1653
else if (*lineptr == '*') else if (*lineptr == '*')
delim = "*"; delim = "*";
else else
delim = "_"; delim = "_";
delimlen = strlen(delim); delimlen = strlen(delim);
} }
if (type == MMD_TYPE_NORMAL_TEXT && delim && ((end = strstr(lineptr + deli mlen, delim)) == NULL || end == (lineptr + delimlen) || isspace(end[-1] & 255))) if (type == MMD_TYPE_NORMAL_TEXT && delim && ((end = strstr(lineptr + deli mlen, delim)) == NULL || end == (lineptr + delimlen) || isspace(end[-1] & 255)))
{ {
if (!text) if (!text)
text = lineptr; text = lineptr;
delim = NULL; delim = NULL;
delimlen = 0; delimlen = 0;
continue; continue;
} }
if (text) if (text)
{ {
char save = *lineptr; char save = *lineptr;
*lineptr = '\0'; *lineptr = '\0';
mmd_add(parent, type, whitespace, text, NULL); mmd_add(parent, type, whitespace, text, NULL);
*lineptr = save; *lineptr = save;
text = NULL; text = NULL;
whitespace = 0; whitespace = 0;
} }
if (type == MMD_TYPE_NORMAL_TEXT) if (type == MMD_TYPE_NORMAL_TEXT)
{ {
if (!strncmp(lineptr, delim, delimlen) && !isspace(lineptr[delimlen] & 2 if (!strncmp(lineptr, delim, delimlen) && !isspace(lineptr[delimlen] & 25
55)) 5))
{ {
type = delimlen == 2 ? MMD_TYPE_STRONG_TEXT : MMD_TYPE_EMPHASIZED_TEXT type = delimlen == 2 ? MMD_TYPE_STRONG_TEXT : MMD_TYPE_EMPHASIZED_TEXT;
;
text = lineptr + delimlen; text = lineptr + delimlen;
lineptr += delimlen - 1; lineptr += delimlen - 1;
} }
else else
{ {
text = lineptr; text = lineptr;
} }
} }
else if (!strncmp(lineptr, delim, delimlen)) else if (!strncmp(lineptr, delim, delimlen))
{ {
lineptr += delimlen - 1; lineptr += delimlen - 1;
type = MMD_TYPE_NORMAL_TEXT; type = MMD_TYPE_NORMAL_TEXT;
delim = NULL; delim = NULL;
delimlen = 0; delimlen = 0;
} }
} }
else if (lineptr[0] == '~' && lineptr[1] == '~' && type != MMD_TYPE_CODE_TEX T) else if (lineptr[0] == '~' && lineptr[1] == '~' && type != MMD_TYPE_CODE_TEX T)
{ {
if (text) if (text)
{ {
*lineptr = '\0'; *lineptr = '\0';
mmd_add(parent, type, whitespace, text, NULL); mmd_add(parent, type, whitespace, text, NULL);
*lineptr = '~'; *lineptr = '~';
text = NULL; text = NULL;
whitespace = 0; whitespace = 0;
} }
if (!isspace(lineptr[2] & 255) && type == MMD_TYPE_NORMAL_TEXT) if (!isspace(lineptr[2] & 255) && type == MMD_TYPE_NORMAL_TEXT)
{ {
type = MMD_TYPE_STRUCK_TEXT; type = MMD_TYPE_STRUCK_TEXT;
text = lineptr + 2; text = lineptr + 2;
} }
else else
{ {
lineptr ++; lineptr ++;
type = MMD_TYPE_NORMAL_TEXT; type = MMD_TYPE_NORMAL_TEXT;
} }
} }
else if (*lineptr == '`') else if (*lineptr == '`')
{ {
if (type != MMD_TYPE_NORMAL_TEXT || !delim) if (type != MMD_TYPE_NORMAL_TEXT || !delim)
{ {
if (lineptr[1] == '`') if (lineptr[1] == '`')
{ {
if (lineptr[2] == '`') if (lineptr[2] == '`')
{ {
delim = "```"; delim = "```";
delimlen = 3; delimlen = 3;
} }
else else
{ {
delim = "``"; delim = "``";
delimlen = 2; delimlen = 2;
} }
} }
else else
{ {
delim = "`"; delim = "`";
delimlen = 1; delimlen = 1;
} }
} }
if (type != MMD_TYPE_CODE_TEXT && delim && !strstr(lineptr + delimlen, del im)) if (type != MMD_TYPE_CODE_TEXT && delim && !strstr(lineptr + delimlen, del im))
{ {
if (!text) if (!text)
text = lineptr; text = lineptr;
delim = NULL; delim = NULL;
delimlen = 0; delimlen = 0;
continue; continue;
} }
if (text) if (text)
{ {
DEBUG2_printf("mmd_parse_inline: text=\"%s\"\n", text); DEBUG2_printf("mmd_parse_inline: text=\"%s\"\n", text);
if (!strncmp(lineptr, delim, delimlen)) if (!strncmp(lineptr, delim, delimlen))
{ {
char *textptr = lineptr; char *textptr = lineptr;
while (textptr > text && isspace(textptr[-1] & 255)) while (textptr > text && isspace(textptr[-1] & 255))
textptr --; textptr --;
*textptr = '\0'; *textptr = '\0';
} }
if (type == MMD_TYPE_CODE_TEXT) if (type == MMD_TYPE_CODE_TEXT)
{ {
if (whitespace && !*text) if (whitespace && !*text)
{ {
mmd_add(parent, type, 0, " ", NULL); mmd_add(parent, type, 0, " ", NULL);
whitespace = 0; whitespace = 0;
} }
} }
mmd_add(parent, type, whitespace, text, NULL); mmd_add(parent, type, whitespace, text, NULL);
text = NULL; text = NULL;
whitespace = 0; whitespace = 0;
} }
if (type == MMD_TYPE_CODE_TEXT) if (type == MMD_TYPE_CODE_TEXT)
{ {
DEBUG2_puts("mmd_parse_inline: Reverting to normal text.\n"); DEBUG2_puts("mmd_parse_inline: Reverting to normal text.\n");
type = MMD_TYPE_NORMAL_TEXT; type = MMD_TYPE_NORMAL_TEXT;
lineptr += delimlen - 1; lineptr += delimlen - 1;
delim = NULL; delim = NULL;
delimlen = 0; delimlen = 0;
} }
else else
{ {
type = MMD_TYPE_CODE_TEXT; type = MMD_TYPE_CODE_TEXT;
lineptr += delimlen - 1; lineptr += delimlen - 1;
if (isspace(lineptr[1] & 255))
{
whitespace = 1;
if (isspace(lineptr[1] & 255)) while (isspace(lineptr[1] & 255))
{ lineptr ++;
whitespace = 1; }
while (isspace(lineptr[1] & 255))
lineptr ++;
}
text = lineptr + 1; text = lineptr + 1;
} }
} }
else if (!text) else if (!text)
{ {
if (*lineptr == '\\' && lineptr[1] && lineptr[1] != '\n') if (*lineptr == '\\' && lineptr[1] && lineptr[1] != '\n')
{ {
/* /*
* Escaped character... * Escaped character...
*/ */
lineptr ++; lineptr ++;
} }
text = lineptr; text = lineptr;
} }
else if (*lineptr == '\\' && lineptr[1] && lineptr[1] != '\n') else if (*lineptr == '\\' && lineptr[1] && lineptr[1] != '\n')
{ {
/* /*
* Escaped character... * Escaped character...
*/ */
skipping to change at line 1837 skipping to change at line 1841
if (text) if (text)
mmd_add(parent, type, whitespace, text, NULL); mmd_add(parent, type, whitespace, text, NULL);
} }
/* /*
* 'mmd_parse_link()' - Parse a link. * 'mmd_parse_link()' - Parse a link.
*/ */
static char * /* O - End of link text */ static char * /* O - End of link text */
mmd_parse_link(_mmd_doc_t *doc, /* I - Document */ mmd_parse_link(_mmd_doc_t *doc, /* I - Document */
char *lineptr, /* I - Pointer into line */ char *lineptr, /* I - Pointer into line */
char **text, /* O - Text */ char **text, /* O - Text */
char **url, /* O - URL */ char **url, /* O - URL */
char **title, /* O - Title, if any */ char **title, /* O - Title, if any */
char **refname) /* O - Reference name */ char **refname) /* O - Reference name */
{ {
lineptr ++; /* skip "[" */ lineptr ++; /* skip "[" */
*text = lineptr; *text = lineptr;
*url = NULL; *url = NULL;
*refname = NULL; *refname = NULL;
if (title) if (title)
*title = NULL; *title = NULL;
while (*lineptr && *lineptr != ']') while (*lineptr && *lineptr != ']')
{ {
if (*lineptr == '\"' || *lineptr == '\'') if (*lineptr == '\"' || *lineptr == '\'')
{ {
char quote = *lineptr++; char quote = *lineptr++;
while (*lineptr && *lineptr != quote) while (*lineptr && *lineptr != quote)
lineptr ++; lineptr ++;
if (!*lineptr) if (!*lineptr)
return (lineptr); return (lineptr);
} }
lineptr ++; lineptr ++;
} }
if (!*lineptr) if (!*lineptr)
return (lineptr); return (lineptr);
*lineptr++ = '\0'; *lineptr++ = '\0';
skipping to change at line 1885 skipping to change at line 1889
/* /*
* Get URL... * Get URL...
*/ */
lineptr ++; lineptr ++;
*url = lineptr; *url = lineptr;
while (*lineptr && *lineptr != ')') while (*lineptr && *lineptr != ')')
{ {
if (isspace(*lineptr & 255)) if (isspace(*lineptr & 255))
*lineptr = '\0'; *lineptr = '\0';
else if (*lineptr == '\"' || *lineptr == '\'') else if (*lineptr == '\"' || *lineptr == '\'')
{ {
char quote = *lineptr++; char quote = *lineptr++;
if (title) if (title)
*title = lineptr; *title = lineptr;
while (*lineptr && *lineptr != quote) while (*lineptr && *lineptr != quote)
lineptr ++; lineptr ++;
if (!*lineptr) if (!*lineptr)
return (lineptr); return (lineptr);
else if (title) else if (title)
*lineptr = '\0'; *lineptr = '\0';
} }
lineptr ++; lineptr ++;
} }
*lineptr++ = '\0'; *lineptr++ = '\0';
} }
else if (*lineptr == '[') else if (*lineptr == '[')
{ {
/* /*
* Get reference... * Get reference...
*/ */
lineptr ++; lineptr ++;
*refname = lineptr; *refname = lineptr;
while (*lineptr && *lineptr != ']') while (*lineptr && *lineptr != ']')
{ {
if (isspace(*lineptr & 255)) if (isspace(*lineptr & 255))
*lineptr = '\0'; *lineptr = '\0';
else if (*lineptr == '\\' && lineptr[1]) else if (*lineptr == '\\' && lineptr[1])
{ {
/* /*
* Remove \ * Remove \
*/ */
memmove(lineptr, lineptr + 1, strlen(lineptr)); memmove(lineptr, lineptr + 1, strlen(lineptr));
} }
else if (*lineptr == '\"' || *lineptr == '\'') else if (*lineptr == '\"' || *lineptr == '\'')
{ {
char quote = *lineptr++; char quote = *lineptr++;
if (title) if (title)
*title = lineptr; *title = lineptr;
while (*lineptr && *lineptr != quote) while (*lineptr && *lineptr != quote)
lineptr ++; lineptr ++;
if (!*lineptr) if (!*lineptr)
return (lineptr); return (lineptr);
else else
*lineptr = '\0'; *lineptr = '\0';
} }
lineptr ++; lineptr ++;
} }
*lineptr++ = '\0'; *lineptr++ = '\0';
if (!**refname) if (!**refname)
*refname = *text; *refname = *text;
} }
else if (*lineptr == ':') else if (*lineptr == ':')
skipping to change at line 1970 skipping to change at line 1974
*url = lineptr; *url = lineptr;
while (*lineptr && !isspace(*lineptr & 255)) while (*lineptr && !isspace(*lineptr & 255))
lineptr ++; lineptr ++;
if (*lineptr) if (*lineptr)
{ {
*lineptr++ = '\0'; *lineptr++ = '\0';
while (*lineptr && isspace(*lineptr & 255)) while (*lineptr && isspace(*lineptr & 255))
lineptr ++; lineptr ++;
if (*lineptr == '\"' || *lineptr == '\'') if (*lineptr == '\"' || *lineptr == '\'')
{ {
char quote = *lineptr++; char quote = *lineptr++;
if (title) if (title)
*title = lineptr; *title = lineptr;
while (*lineptr && *lineptr != quote) while (*lineptr && *lineptr != quote)
lineptr ++; lineptr ++;
if (!*lineptr) if (!*lineptr)
return (lineptr); return (lineptr);
else else
*lineptr = '\0'; *lineptr = '\0';
} }
} }
mmd_ref_add(doc, NULL, *text, *url, title ? *title : NULL); mmd_ref_add(doc, NULL, *text, *url, title ? *title : NULL);
*text = NULL; *text = NULL;
*url = NULL; *url = NULL;
if (title) if (title)
*title = NULL; *title = NULL;
skipping to change at line 2049 skipping to change at line 2053
*(file->bufend) = '\0'; *(file->bufend) = '\0';
file->bufptr = file->buffer; file->bufptr = file->buffer;
} }
/* /*
* 'mmd_read_line()' - Read a line from a file in a Markdown-aware way. * 'mmd_read_line()' - Read a line from a file in a Markdown-aware way.
*/ */
static char * /* O - Pointer to line or `NULL` on EOF * / static char * /* O - Pointer to line or `NULL` on EOF * /
mmd_read_line(_mmd_filebuf_t *file, /* I - File buffer */ mmd_read_line(_mmd_filebuf_t *file, /* I - File buffer */
char *line, /* I - Line buffer */ char *line, /* I - Line buffer */
size_t linesize) /* I - Size of line buffer */ size_t linesize) /* I - Size of line buffer */
{ {
int ch, /* Current character */ int ch, /* Current character */
column = 0; /* Current column */ column = 0; /* Current column */
char *lineptr = line, /* Pointer into line */ char *lineptr = line, /* Pointer into line */
*lineend = line + linesize - 1; /* Pointer to end of buffer */ *lineend = line + linesize - 1; /* Pointer to end of buffer */
/* /*
* Fill the buffer as needed... * Fill the buffer as needed...
*/ */
if (!file->bufptr || (file->bufptr >= file->bufend) || !strchr(file->bufptr, ' \n')) if (!file->bufptr || (file->bufptr >= file->bufend) || !strchr(file->bufptr, ' \n'))
mmd_read_buffer(file); mmd_read_buffer(file);
/* /*
* Copy a line out of the file buffer... * Copy a line out of the file buffer...
skipping to change at line 2082 skipping to change at line 2086
if (ch == '\t') if (ch == '\t')
{ {
/* /*
* Expand tabs since nobody uses the same tab width and Markdown says * Expand tabs since nobody uses the same tab width and Markdown says
* 4 columns per tab... * 4 columns per tab...
*/ */
do do
{ {
column ++; column ++;
if (lineptr < lineend) if (lineptr < lineend)
*lineptr++ = ' '; *lineptr++ = ' ';
} }
while (column & 3); while (column & 3);
} }
else if (ch != '\r' && lineptr < lineend) else if (ch != '\r' && lineptr < lineend)
{ {
column ++; column ++;
*lineptr++ = ch; *lineptr++ = ch;
} }
if (ch == '\n') if (ch == '\n')
skipping to change at line 2114 skipping to change at line 2118
return (line); return (line);
} }
/* /*
* 'mmd_ref_add()' - Add or update a reference... * 'mmd_ref_add()' - Add or update a reference...
*/ */
static void static void
mmd_ref_add(_mmd_doc_t *doc, /* I - Document */ mmd_ref_add(_mmd_doc_t *doc, /* I - Document */
mmd_t *node, /* I - Link node, if any */ mmd_t *node, /* I - Link node, if any */
const char *name, /* I - Reference name */ const char *name, /* I - Reference name */
const char *url, /* I - Reference URL */ const char *url, /* I - Reference URL */
const char *title) /* I - Title, if any */ const char *title) /* I - Title, if any */
{ {
size_t i; /* Looping var */ size_t i; /* Looping var */
_mmd_ref_t *ref = mmd_ref_find(doc, name); _mmd_ref_t *ref = mmd_ref_find(doc, name);
/* Reference */ /* Reference */
DEBUG2_printf("mmd_ref_add(doc=%p, node=%p, name=\"%s\", url=\"%s\", title=\"% s\")\n", doc, node, name, url, title); DEBUG2_printf("mmd_ref_add(doc=%p, node=%p, name=\"%s\", url=\"%s\", title=\"% s\")\n", doc, node, name, url, title);
if (ref) if (ref)
{ {
DEBUG2_printf("mmd_ref_add: ref=%p, ref->url=\"%s\"\n", ref, ref->url); DEBUG2_printf("mmd_ref_add: ref=%p, ref->url=\"%s\"\n", ref, ref->url);
if (!ref->url && url) if (!ref->url && url)
{ {
if (node) if (node)
node->url = strdup(url); node->url = strdup(url);
ref->url = strdup(url); ref->url = strdup(url);
if (title) if (title)
{ {
if (node) if (node)
node->extra = strdup(title); node->extra = strdup(title);
ref->title = strdup(title); ref->title = strdup(title);
} }
for (i = 0; i < ref->num_pending; i ++) for (i = 0; i < ref->num_pending; i ++)
{ {
ref->pending[i]->url = strdup(url); ref->pending[i]->url = strdup(url);
if (title) if (title)
ref->pending[i]->extra = strdup(title); ref->pending[i]->extra = strdup(title);
} }
free(ref->pending); free(ref->pending);
ref->num_pending = 0; ref->num_pending = 0;
ref->pending = NULL; ref->pending = NULL;
return; return;
} }
} }
else if ((ref = realloc(doc->references, (doc->num_references + 1) * sizeof(_m md_ref_t))) != NULL) else if ((ref = realloc(doc->references, (doc->num_references + 1) * sizeof(_m md_ref_t))) != NULL)
{ {
doc->references = ref; doc->references = ref;
ref += doc->num_references; ref += doc->num_references;
doc->num_references ++; doc->num_references ++;
ref->name = strdup(name); ref->name = strdup(name);
ref->url = url ? strdup(url) : NULL; ref->url = url ? strdup(url) : NULL;
ref->title = title ? strdup(title) : NULL; ref->title = title ? strdup(title) : NULL;
ref->num_pending = 0; ref->num_pending = 0;
ref->pending = NULL; ref->pending = NULL;
} }
else else
return; return;
if (node) if (node)
{ {
if (ref->url) if (ref->url)
{ {
node->url = strdup(ref->url); node->url = strdup(ref->url);
node->extra = ref->title ? strdup(ref->title) : NULL; node->extra = ref->title ? strdup(ref->title) : NULL;
} }
else if ((ref->pending = realloc(ref->pending, (ref->num_pending + 1) * size of(mmd_t *))) != NULL) else if ((ref->pending = realloc(ref->pending, (ref->num_pending + 1) * size of(mmd_t *))) != NULL)
{ {
ref->pending[ref->num_pending ++] = node; ref->pending[ref->num_pending ++] = node;
} }
} }
} }
/* /*
* 'mmd_ref_find()' - Find a reference... * 'mmd_ref_find()' - Find a reference...
*/ */
static _mmd_ref_t * /* O - Reference or NULL */ static _mmd_ref_t * /* O - Reference or NULL */
mmd_ref_find(_mmd_doc_t *doc, /* I - Document */ mmd_ref_find(_mmd_doc_t *doc, /* I - Document */
const char *name) /* I - Reference name */ const char *name) /* I - Reference name */
{ {
size_t i; /* Looping var */ size_t i; /* Looping var */
for (i = 0; i < doc->num_references; i ++) for (i = 0; i < doc->num_references; i ++)
if (!strcasecmp(name, doc->references[i].name)) if (!strcasecmp(name, doc->references[i].name))
return (doc->references + i); return (doc->references + i);
return (NULL); return (NULL);
} }
/* /*
* 'mmd_remove()' - Remove a node from its parent. * 'mmd_remove()' - Remove a node from its parent.
*/ */
static void static void
mmd_remove(mmd_t *node) /* I - Node */ mmd_remove(mmd_t *node) /* I - Node */
{ {
if (node->parent) if (node && node->parent)
{ {
if (node->prev_sibling) if (node->prev_sibling)
node->prev_sibling->next_sibling = node->next_sibling; node->prev_sibling->next_sibling = node->next_sibling;
else else
node->parent->first_child = node->next_sibling; node->parent->first_child = node->next_sibling;
if (node->next_sibling) if (node->next_sibling)
node->next_sibling->prev_sibling = node->prev_sibling; node->next_sibling->prev_sibling = node->prev_sibling;
else else
node->parent->last_child = node->prev_sibling; node->parent->last_child = node->prev_sibling;
skipping to change at line 2243 skipping to change at line 2247
*/ */
static const char * /* O - String representing the type */ static const char * /* O - String representing the type */
mmd_type_string(mmd_type_t type) /* I - Type value */ mmd_type_string(mmd_type_t type) /* I - Type value */
{ {
static char unknown[64]; /* Unknown type buffer */ static char unknown[64]; /* Unknown type buffer */
switch (type) switch (type)
{ {
case MMD_TYPE_NONE : case MMD_TYPE_NONE :
return ("MMD_TYPE_NONE"); return ("MMD_TYPE_NONE");
case MMD_TYPE_DOCUMENT : case MMD_TYPE_DOCUMENT :
return "MMD_TYPE_DOCUMENT"; return "MMD_TYPE_DOCUMENT";
case MMD_TYPE_METADATA : case MMD_TYPE_METADATA :
return "MMD_TYPE_METADATA"; return "MMD_TYPE_METADATA";
case MMD_TYPE_BLOCK_QUOTE : case MMD_TYPE_BLOCK_QUOTE :
return "MMD_TYPE_BLOCK_QUOTE"; return "MMD_TYPE_BLOCK_QUOTE";
case MMD_TYPE_ORDERED_LIST : case MMD_TYPE_ORDERED_LIST :
return "MMD_TYPE_ORDERED_LIST"; return "MMD_TYPE_ORDERED_LIST";
case MMD_TYPE_UNORDERED_LIST : case MMD_TYPE_UNORDERED_LIST :
return "MMD_TYPE_UNORDERED_LIST"; return "MMD_TYPE_UNORDERED_LIST";
case MMD_TYPE_LIST_ITEM : case MMD_TYPE_LIST_ITEM :
return "MMD_TYPE_LIST_ITEM"; return "MMD_TYPE_LIST_ITEM";
case MMD_TYPE_TABLE : case MMD_TYPE_TABLE :
return "MMD_TYPE_TABLE"; return "MMD_TYPE_TABLE";
case MMD_TYPE_TABLE_HEADER : case MMD_TYPE_TABLE_HEADER :
return "MMD_TYPE_TABLE_HEADER"; return "MMD_TYPE_TABLE_HEADER";
case MMD_TYPE_TABLE_BODY : case MMD_TYPE_TABLE_BODY :
return "MMD_TYPE_TABLE_BODY"; return "MMD_TYPE_TABLE_BODY";
case MMD_TYPE_TABLE_ROW : case MMD_TYPE_TABLE_ROW :
return "MMD_TYPE_TABLE_ROW"; return "MMD_TYPE_TABLE_ROW";
case MMD_TYPE_HEADING_1 : case MMD_TYPE_HEADING_1 :
return "MMD_TYPE_HEADING_1"; return "MMD_TYPE_HEADING_1";
case MMD_TYPE_HEADING_2 : case MMD_TYPE_HEADING_2 :
return "MMD_TYPE_HEADING_2"; return "MMD_TYPE_HEADING_2";
case MMD_TYPE_HEADING_3 : case MMD_TYPE_HEADING_3 :
return "MMD_TYPE_HEADING_3"; return "MMD_TYPE_HEADING_3";
case MMD_TYPE_HEADING_4 : case MMD_TYPE_HEADING_4 :
return "MMD_TYPE_HEADING_4"; return "MMD_TYPE_HEADING_4";
case MMD_TYPE_HEADING_5 : case MMD_TYPE_HEADING_5 :
return "MMD_TYPE_HEADING_5"; return "MMD_TYPE_HEADING_5";
case MMD_TYPE_HEADING_6 : case MMD_TYPE_HEADING_6 :
return "MMD_TYPE_HEADING_6"; return "MMD_TYPE_HEADING_6";
case MMD_TYPE_PARAGRAPH : case MMD_TYPE_PARAGRAPH :
return "MMD_TYPE_PARAGRAPH"; return "MMD_TYPE_PARAGRAPH";
case MMD_TYPE_CODE_BLOCK : case MMD_TYPE_CODE_BLOCK :
return "MMD_TYPE_CODE_BLOCK"; return "MMD_TYPE_CODE_BLOCK";
case MMD_TYPE_THEMATIC_BREAK : case MMD_TYPE_THEMATIC_BREAK :
return "MMD_TYPE_THEMATIC_BREAK"; return "MMD_TYPE_THEMATIC_BREAK";
case MMD_TYPE_TABLE_HEADER_CELL : case MMD_TYPE_TABLE_HEADER_CELL :
return "MMD_TYPE_TABLE_HEADER_CELL"; return "MMD_TYPE_TABLE_HEADER_CELL";
case MMD_TYPE_TABLE_BODY_CELL_LEFT : case MMD_TYPE_TABLE_BODY_CELL_LEFT :
return "MMD_TYPE_TABLE_BODY_CELL_LEFT"; return "MMD_TYPE_TABLE_BODY_CELL_LEFT";
case MMD_TYPE_TABLE_BODY_CELL_CENTER : case MMD_TYPE_TABLE_BODY_CELL_CENTER :
return "MMD_TYPE_TABLE_BODY_CELL_CENTER"; return "MMD_TYPE_TABLE_BODY_CELL_CENTER";
case MMD_TYPE_TABLE_BODY_CELL_RIGHT : case MMD_TYPE_TABLE_BODY_CELL_RIGHT :
return "MMD_TYPE_TABLE_BODY_CELL_RIGHT"; return "MMD_TYPE_TABLE_BODY_CELL_RIGHT";
case MMD_TYPE_NORMAL_TEXT : case MMD_TYPE_NORMAL_TEXT :
return "MMD_TYPE_NORMAL_TEXT"; return "MMD_TYPE_NORMAL_TEXT";
case MMD_TYPE_EMPHASIZED_TEXT : case MMD_TYPE_EMPHASIZED_TEXT :
return "MMD_TYPE_EMPHASIZED_TEXT"; return "MMD_TYPE_EMPHASIZED_TEXT";
case MMD_TYPE_STRONG_TEXT : case MMD_TYPE_STRONG_TEXT :
return "MMD_TYPE_STRONG_TEXT"; return "MMD_TYPE_STRONG_TEXT";
case MMD_TYPE_STRUCK_TEXT : case MMD_TYPE_STRUCK_TEXT :
return "MMD_TYPE_STRUCK_TEXT"; return "MMD_TYPE_STRUCK_TEXT";
case MMD_TYPE_LINKED_TEXT : case MMD_TYPE_LINKED_TEXT :
return "MMD_TYPE_LINKED_TEXT"; return "MMD_TYPE_LINKED_TEXT";
case MMD_TYPE_CODE_TEXT : case MMD_TYPE_CODE_TEXT :
return "MMD_TYPE_CODE_TEXT"; return "MMD_TYPE_CODE_TEXT";
case MMD_TYPE_IMAGE : case MMD_TYPE_IMAGE :
return "MMD_TYPE_IMAGE"; return "MMD_TYPE_IMAGE";
case MMD_TYPE_HARD_BREAK : case MMD_TYPE_HARD_BREAK :
return "MMD_TYPE_HARD_BREAK"; return "MMD_TYPE_HARD_BREAK";
case MMD_TYPE_SOFT_BREAK : case MMD_TYPE_SOFT_BREAK :
return "MMD_TYPE_SOFT_BREAK"; return "MMD_TYPE_SOFT_BREAK";
case MMD_TYPE_METADATA_TEXT : case MMD_TYPE_METADATA_TEXT :
return "MMD_TYPE_METADATA_TEXT"; return "MMD_TYPE_METADATA_TEXT";
default : default :
snprintf(unknown, sizeof(unknown), "?? %d ??", (int)type); snprintf(unknown, sizeof(unknown), "?? %d ??", (int)type);
return (unknown); return (unknown);
} }
} }
#endif /* DEBUG */ #endif /* DEBUG */
 End of changes. 262 change blocks. 
534 lines changed or deleted 538 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)