# Indent pre-processor directives
--indent-preproc-block
+--indent-preproc-define
--indent-preproc-cond
+# Line endings
+--lineend=linux
+
+# Add brackets to one-liners
+--add-brackets
+
+# Pad with blank lines
+--break-blocks
+
+# Pad around operators
+--pad-oper
+
# Excludes
--exclude="Sources/libMultiMarkdown/scanners.c"
trie * a = malloc(sizeof(trie));
if (a) {
- if (startingSize <= 1)
+ if (startingSize <= 1) {
startingSize = kTrieStartingSize;
+ }
a->node = malloc(sizeof(trie_node) * startingSize);
unsigned short trie_search_match_type(trie * a, const char * query) {
size_t s = trie_search(a, query);
- if (s == -1)
+ if (s == -1) {
return -1;
+ }
return a->node[s].match_type;
}
while ((suffix[0] != '\0') && (n->ac_fail == 0)) {
n->ac_fail = trie_search(a, suffix);
- if (n->ac_fail == -1)
+ if (n->ac_fail == -1) {
n->ac_fail = 0;
+ }
if (n->ac_fail == s) {
// Something went wrong
result = match_new(0, 0, 0);
m = result;
}
+
m = match_add(m, counter - a->node[temp_state].len,
a->node[temp_state].len, a->node[temp_state].match_type);
}
void match_set_describe(match * m, const char * source) {
m = m->next; // Skip header
+
while (m) {
match_describe(m, source);
m = m->next;
match * ac_trie_leftmost_longest_search(trie * a, const char * source, size_t start, size_t len) {
match * result = ac_trie_search(a, source, start, len);
- if (result)
+ if (result) {
match_set_filter_leftmost_longest(result);
+ }
return result;
}
void trie_node_to_graphviz(trie * a, size_t s) {
trie_node * n = &a->node[s];
- if (n->match_type)
+ if (n->match_type) {
fprintf(stderr, "\"%lu\" [shape=doublecircle]\n", s);
+ }
for (int i = 0; i < 256; ++i) {
if (n->child[i]) {
}
}
- if (n->ac_fail)
+ if (n->ac_fail) {
fprintf(stderr, "\"%lu\" -> \"%lu\" [label=\"fail\"]\n", s, n->ac_fail);
+ }
}
void trie_to_graphviz(trie * a) {
fprintf(stderr, "digraph dfa {\n");
+
for (int i = 0; i < a->size; ++i) {
trie_node_to_graphviz(a, i);
}
+
fprintf(stderr, "}\n");
}
case BLOCK_SETEXT_1:
level = 1;
break;
+
case BLOCK_SETEXT_2:
level = 2;
break;
+
default:
level = 1 + current->type - BLOCK_H1;
}
case BLOCK_SETEXT_1:
t_level = 1;
break;
+
case BLOCK_SETEXT_2:
t_level = 2;
break;
+
default:
t_level = 1 + t->type - BLOCK_H1;
}
print_const("\\end{frame}\n\n");
scratch->padded = 2;
break;
+
case 4:
pad(out, 1, scratch);
print_const("}\n\n");
scratch->padded = 1;
stack_push(s, current);
break;
+
case 4:
pad(out, 2, scratch);
print_const("\\mode<article>{");
void mmd_export_token_beamer(DString * out, const char * source, token * t, scratch_pad * scratch) {
- if (t == NULL)
+ if (t == NULL) {
return;
+ }
short temp_short;
char * temp_char = NULL;
case DOC_START_TOKEN:
mmd_export_token_tree_beamer(out, source, t->child, scratch);
break;
+
case BLOCK_CODE_FENCED:
pad(out, 2, scratch);
temp_char = get_fence_language_specifier(t->child->child, source);
+
if (temp_char) {
printf("\\begin{lstlisting}[language=%s]\n", temp_char);
} else {
} else {
print_const("\\end{verbatim}");
}
+
scratch->padded = 0;
break;
+
case BLOCK_CODE_INDENTED:
pad(out, 2, scratch);
print_const("\\begin{verbatim}\n");
print_const("\\end{verbatim}");
scratch->padded = 0;
break;
+
case BLOCK_H1:
case BLOCK_H2:
case BLOCK_H3:
case BLOCK_SETEXT_1:
temp_short = 1;
break;
+
case BLOCK_SETEXT_2:
temp_short = 2;
break;
+
default:
temp_short = t->type - BLOCK_H1 + 1;
}
case 1:
print_const("\\part{");
break;
+
case 2:
print_const("\\section{");
break;
+
case 3:
print_const("\\frametitle{");
break;
+
default:
print_const("\\emph{");
break;
print_const("}");
} else {
temp_token = manual_label_from_header(t, source);
+
if (temp_token) {
temp_char = label_from_token(source, temp_token);
} else {
temp_char = label_from_token(source, t);
}
+
printf("}\n\\label{%s}", temp_char);
- if (temp_char)
+ if (temp_char) {
free(temp_char);
+ }
}
+
scratch->padded = 0;
break;
+
default:
// Default to LaTeX behavior
mmd_export_token_latex(out, source, t, scratch);
// Is character part of Windows line ending ('\r\n')?
int char_is_windows_line_ending(char * c) {
- if (*c == '\n')
+ if (*c == '\n') {
return (*(c - 1) == '\r') ? 1 : 0;
+ }
- if (*c == '\r')
+ if (*c == '\r') {
return (*(c + 1) == '\n') ? 1 : 0;
+ }
return 0;
}
for (char i = 'a'; i <= 'z'; ++i) {
alpha(i);
}
+
for (char i = 'A'; i <= 'Z'; ++i) {
alpha(i);
}
// Extended ASCII
#ifdef USE_EXTENDED_ASCII
+
// Punctuation ranges
for (int i = 132; i < 138; ++i) {
punctuation(i);
case 247:
punctuation(i);
break;
+
case 160:
whitespace(i);
break;
+
case 131:
case 138:
case 140:
case 159:
alpha(i);
break;
+
default:
break;
}
}
+
#endif
if (t->mate) {
d_string_erase(d, t->start, t->len);
}
+
break;
+
case CM_SUB_OPEN:
case CM_ADD_OPEN:
case CM_ADD_CLOSE:
- if (!t->mate)
+ if (!t->mate) {
break;
+ }
+
case CM_SUB_DIV:
case CM_DEL_PAIR:
case CM_COM_PAIR:
// Erase these
d_string_erase(d, t->start, t->len);
break;
+
case CM_SUB_PAIR:
+
// Erase old version and markers
- if (t->child)
+ if (t->child) {
accept_token_tree_sub(d, t->child->mate);
+ }
+
break;
+
case CM_ADD_PAIR:
+
// Check children
- if (t->child)
+ if (t->child) {
accept_token_tree(d, t->child->mate);
+ }
+
break;
}
}
void mmd_critic_markup_accept(DString * d) {
token * t = critic_parse_substring(d->str, 0, d->currentStringLength);
- if (t && t->child)
+ if (t && t->child) {
accept_token_tree(d, t->child->tail);
+ }
token_free(t);
}
if (t->mate) {
d_string_erase(d, t->start, t->len);
}
+
break;
+
case CM_SUB_OPEN:
case CM_DEL_OPEN:
case CM_DEL_CLOSE:
- if (!t->mate)
+ if (!t->mate) {
break;
+ }
+
case CM_SUB_DIV:
case CM_ADD_PAIR:
case CM_COM_PAIR:
// Erase these
d_string_erase(d, t->start, t->len);
break;
+
case CM_SUB_PAIR:
+
// Erase new version and markers
- if (t->child)
+ if (t->child) {
reject_token_tree_sub(d, t->child->mate);
+ }
+
break;
+
case CM_DEL_PAIR:
+
// Check children
- if (t->child)
+ if (t->child) {
reject_token_tree(d, t->child->mate);
+ }
+
break;
}
}
void mmd_critic_markup_reject(DString * d) {
token * t = critic_parse_substring(d->str, 0, d->currentStringLength);
- if (t && t->child)
+ if (t && t->child) {
reject_token_tree(d, t->child->tail);
+ }
token_free(t);
va_copy(ap2, ap);
char tmp[1];
int size = vsnprintf(tmp, 1, fmt, ap2);
- if (size <= 0) return size;
+
+ if (size <= 0) {
+ return size;
+ }
+
va_end(ap2);
size += 1;
*strp = (char*)malloc(size * sizeof(char));
DString* d_string_new(const char * startingString) {
DString* newString = malloc(sizeof(DString));
- if (!newString)
+ if (!newString) {
return NULL;
+ }
- if (startingString == NULL) startingString = "";
+ if (startingString == NULL) {
+ startingString = "";
+ }
size_t startingBufferSize = kStringBufferStartingSize;
size_t startingStringSize = strlen(startingString);
+
while (startingBufferSize < (startingStringSize + 1)) {
startingBufferSize *= kStringBufferGrowthMultiplier;
}
/// Free dynamic string
char* d_string_free(DString * ripString, bool freeCharacterData) {
- if (ripString == NULL)
+ if (ripString == NULL) {
return NULL;
+ }
char* returnedString = ripString->str;
+
if (freeCharacterData) {
if (ripString->str != NULL) {
free(ripString->str);
}
+
returnedString = NULL;
}
/// Ensure that dynamic string has specified capacity
static void ensureStringBufferCanHold(DString * baseString, size_t newStringSize) {
size_t newBufferSizeNeeded = newStringSize + 1;
+
if (newBufferSizeNeeded > baseString->currentStringBufferSize) {
size_t newBufferSize = baseString->currentStringBufferSize;
exit(1);
}
+
baseString->str = temp;
baseString->currentStringBufferSize = newBufferSize;
}
char* formattedString = NULL;
vasprintf(&formattedString, format, args);
+
if (formattedString != NULL) {
d_string_append(baseString, formattedString);
free(formattedString);
}
+
va_end(args);
}
size_t insertedStringLength = strlen(insertedString);
if ((insertedString != NULL) && (insertedStringLength > 0)) {
- if (pos > baseString->currentStringLength)
+ if (pos > baseString->currentStringLength) {
pos = baseString->currentStringLength;
+ }
size_t newStringLength = baseString->currentStringLength + insertedStringLength;
ensureStringBufferCanHold(baseString, newStringLength);
/// Insert single character inside dynamic string
void d_string_insert_c(DString * baseString, size_t pos, char insertedCharacter) {
- if (pos > baseString->currentStringLength)
+ if (pos > baseString->currentStringLength) {
pos = baseString->currentStringLength;
+ }
size_t newSizeNeeded = baseString->currentStringLength + 1;
ensureStringBufferCanHold(baseString, newSizeNeeded);
char* formattedString = NULL;
vasprintf(&formattedString, format, args);
+
if (formattedString != NULL) {
d_string_insert(baseString, pos, formattedString);
free(formattedString);
}
+
va_end(args);
}
/// Erase portion of dynamic string
void d_string_erase(DString * baseString, size_t pos, size_t len) {
- if ((pos > baseString->currentStringLength) || (len <= 0))
+ if ((pos > baseString->currentStringLength) || (len <= 0)) {
return;
+ }
- if ((pos + len) >= baseString->currentStringLength)
+ if ((pos + len) >= baseString->currentStringLength) {
len = -1;
+ }
if (len == -1) {
baseString->currentStringLength = pos;
// Identifier
HASH_FIND_STR(scratch->meta_hash, "uuid", m);
+
if (m) {
print_const("<dc:identifier id=\"pub-id\">urn:uuid:");
mmd_print_string_html(out, m->value, false);
// Title
HASH_FIND_STR(scratch->meta_hash, "title", m);
+
if (m) {
print_const("<dc:title>");
mmd_print_string_html(out, m->value, false);
// Author
HASH_FIND_STR(scratch->meta_hash, "author", m);
+
if (m) {
print_const("<dc:creator>");
mmd_print_string_html(out, m->value, false);
// Language
HASH_FIND_STR(scratch->meta_hash, "language", m);
+
if (m) {
print_const("<dc:language>");
mmd_print_string_html(out, m->value, false);
case LC_ES:
print_const("<dc:language>es</dc:language>\n");
break;
+
case LC_DE:
print_const("<dc:language>de</dc:language>\n");
break;
+
case LC_FR:
print_const("<dc:language>fr</dc:language>\n");
break;
+
case LC_NL:
print_const("<dc:language>nl</dc:language>\n");
break;
+
case LC_SV:
print_const("<dc:language>sv</dc:language>\n");
break;
+
default:
print_const("<dc:language>en</dc:language>\n");
}
// Date
HASH_FIND_STR(scratch->meta_hash, "date", m);
+
if (m) {
print_const("<meta property=\"dcterms:modified\">");
mmd_print_string_html(out, m->value, false);
if (*counter < scratch->header_stack->size - 1) {
next = stack_peek_index(scratch->header_stack, *counter + 1);
next_level = next->type - BLOCK_H1 + 1;
+
if (next_level > entry_level) {
// This entry has children
(*counter)++;
d_string_append(out, "<head>\n<title>");
HASH_FIND_STR(scratch->meta_hash, "title", temp);
+
if (temp) {
mmd_print_string_html(out, temp->value, false);
} else {
print_const("Untitled");
}
+
print_const("</title>\n</head>\n");
print_const("<body>\n<nav epub:type=\"toc\">\n");
static bool add_asset_from_file(mz_zip_archive * pZip, asset * a, const char * destination, const char * directory) {
- if (!directory)
+ if (!directory) {
return false;
+ }
char * path = path_from_dir_base(directory, a->url);
mz_bool status;
struct MemoryStruct * mem = (struct MemoryStruct *)userp;
mem->memory = realloc(mem->memory, mem->size + realsize + 1);
+
if (mem->memory == NULL) {
// Out of memory
fprintf(stderr, "Out of memory\n");
len = strlen(data);
status = mz_zip_writer_add_mem(&zip, "mimetype", data, len, MZ_BEST_COMPRESSION);
free(data);
+
if (!status) {
fprintf(stderr, "Error adding asset to zip.\n");
}
// Create directories
status = mz_zip_writer_add_mem(&zip, "OEBPS/", NULL, 0, MZ_BEST_COMPRESSION);
+
if (!status) {
fprintf(stderr, "Error adding asset to zip.\n");
}
status = mz_zip_writer_add_mem(&zip, "META-INF/", NULL, 0, MZ_BEST_COMPRESSION);
+
if (!status) {
fprintf(stderr, "Error adding asset to zip.\n");
}
len = strlen(data);
status = mz_zip_writer_add_mem(&zip, "META-INF/container.xml", data, len, MZ_BEST_COMPRESSION);
free(data);
+
if (!status) {
fprintf(stderr, "Error adding asset to zip.\n");
}
len = strlen(data);
status = mz_zip_writer_add_mem(&zip, "OEBPS/main.opf", data, len, MZ_BEST_COMPRESSION);
free(data);
+
if (!status) {
fprintf(stderr, "Error adding asset to zip.\n");
}
len = strlen(data);
status = mz_zip_writer_add_mem(&zip, "OEBPS/nav.xhtml", data, len, MZ_BEST_COMPRESSION);
free(data);
+
if (!status) {
fprintf(stderr, "Error adding asset to zip.\n");
}
// Add main document
len = strlen(body);
status = mz_zip_writer_add_mem(&zip, "OEBPS/main.xhtml", body, len, MZ_BEST_COMPRESSION);
+
if (!status) {
fprintf(stderr, "Error adding asset to zip.\n");
}
free(result->str);
status = mz_zip_writer_finalize_heap_archive(&zip, (void **) &(result->str), (size_t *) &(result->currentStringLength));
+
if (!status) {
fprintf(stderr, "Error adding asset to zip.\n");
}
case '"':
print_const(""");
break;
+
case '&':
print_const("&");
break;
+
case '<':
print_const("<");
break;
+
case '>':
print_const(">");
break;
+
case '\t':
print_const("<text:tab/>");
+
default:
print_char(c);
break;
void mmd_print_string_odf(DString * out, const char * str) {
- if (str == NULL)
+ if (str == NULL) {
return;
+ }
while (*str != '\0') {
mmd_print_char_odf(out, *str);
case DASH_N:
print_const("–");
break;
+
case DASH_M:
print_const("—");
break;
+
case ELLIPSIS:
print_const("…");
break;
+
case APOSTROPHE:
print_const("’");
break;
+
case QUOTE_LEFT_SINGLE:
switch (scratch->quotes_lang) {
case SWEDISH:
print( "’");
break;
+
case FRENCH:
print_const("'");
break;
+
case GERMAN:
print_const("‚");
break;
+
case GERMANGUILL:
print_const("›");
break;
+
default:
print_const("‘");
}
+
break;
+
case QUOTE_RIGHT_SINGLE:
switch (scratch->quotes_lang) {
case GERMAN:
print_const("‘");
break;
+
case GERMANGUILL:
print_const("‹");
break;
+
default:
print_const("’");
}
+
break;
+
case QUOTE_LEFT_DOUBLE:
switch (scratch->quotes_lang) {
case DUTCH:
case GERMAN:
print_const("„");
break;
+
case GERMANGUILL:
print_const("»");
break;
+
case FRENCH:
print_const("«");
break;
+
case SWEDISH:
print( "”");
break;
+
default:
print_const("“");
}
+
break;
+
case QUOTE_RIGHT_DOUBLE:
switch (scratch->quotes_lang) {
case GERMAN:
print_const("“");
break;
+
case GERMANGUILL:
print_const("«");
break;
+
case FRENCH:
print_const("»");
break;
+
case SWEDISH:
case DUTCH:
default:
print_const("”");
}
+
break;
}
}
print_const("<text:a xlink:type=\"simple\" xlink:href=\"");
mmd_print_string_odf(out, link->url);
print_const("\"");
- } else
+ } else {
print_const("<a xlink:type=\"simple\" xlink:href=\"\"");
+ }
if (link->title && link->title[0] != '\0') {
print_const(" office:name=\"");
result = my_strdup(original);
- for (i = 0; result[i]; i++)
+ for (i = 0; result[i]; i++) {
result[i] = tolower(result[i]);
+ }
if (strstr(&result[strlen(result)-2],"px")) {
result[strlen(result)-2] = '\0';
printf("svg:width=\"%s\" ", width);
}
- if (height)
+ if (height) {
free(height);
+ }
- if (width)
+ if (width) {
free(width);
+ }
- if (link->url)
+ if (link->url) {
printf(">\n<draw:image xlink:href=\"%s\"", link->url);
+ }
print_const(" xlink:type=\"simple\" xlink:show=\"embed\" xlink:actuate=\"onLoad\" draw:filter-name=\"<All formats>\"/>\n</draw:frame></text:p>");
if (*counter < scratch->header_stack->size - 1) {
next = stack_peek_index(scratch->header_stack, *counter + 1);
next_level = next->type - BLOCK_H1 + 1;
+
if (next_level > entry_level) {
// This entry has children
(*counter)++;
void mmd_export_token_odf(DString * out, const char * source, token * t, scratch_pad * scratch) {
- if (t == NULL)
+ if (t == NULL) {
return;
+ }
short temp_short;
short temp_short2;
case DOC_START_TOKEN:
mmd_export_token_tree_odf(out, source, t->child, scratch);
break;
+
case AMPERSAND:
case AMPERSAND_LONG:
print_const("&");
break;
+
case ANGLE_LEFT:
print_const("<");
break;
+
case ANGLE_RIGHT:
print_const(">");
break;
+
case APOSTROPHE:
if (!(scratch->extensions & EXT_SMART)) {
print_token(t);
} else {
print_localized(APOSTROPHE);
}
+
break;
+
case BACKTICK:
- if (t->mate == NULL)
+ if (t->mate == NULL) {
print_token(t);
- else if (t->mate->type == QUOTE_RIGHT_ALT)
+ } else if (t->mate->type == QUOTE_RIGHT_ALT)
if (!(scratch->extensions & EXT_SMART)) {
print_token(t);
} else {
} else {
print_const("</text:span>");
}
+
break;
+
case BLOCK_BLOCKQUOTE:
pad(out, 2, scratch);
scratch->padded = 2;
scratch->padded = 0;
scratch->odf_para_type = temp_short2;
break;
+
case BLOCK_CODE_FENCED:
pad(out, 2, scratch);
case LINE_FENCE_BACKTICK_5:
temp_token = t->child->tail;
break;
+
default:
temp_token = NULL;
}
+
if (temp_token) {
d_string_append_c_array(out, &source[t->child->next->start], temp_token->start - t->child->next->start);
scratch->padded = 1;
print_const("</text:p>");
scratch->padded = 0;
break;
+
case BLOCK_CODE_INDENTED:
pad(out, 2, scratch);
print_const("<text:p text:style-name=\"Preformatted Text\">");
print_const("</text:p>");
scratch->padded = 0;
break;
+
case BLOCK_DEFINITION:
pad(out, 2, scratch);
temp_short2 = scratch->odf_para_type;
scratch->odf_para_type = BLOCK_DEFINITION;
temp_short = scratch->list_is_tight;
- if (!(t->child->next && (t->child->next->type == BLOCK_EMPTY) && t->child->next->next))
+
+ if (!(t->child->next && (t->child->next->type == BLOCK_EMPTY) && t->child->next->next)) {
scratch->list_is_tight = true;
+ }
if (t->child && t->child->type != BLOCK_PARA) {
print_const("<text:p text:style-name=\"Quotations\">");
} else {
mmd_export_token_tree_odf(out, source, t->child, scratch);
}
+
scratch->padded = 0;
scratch->list_is_tight = temp_short;
scratch->odf_para_type = temp_short2;
break;
+
case BLOCK_DEFLIST:
pad(out, 2, scratch);
scratch->padded = 1;
break;
+
case BLOCK_EMPTY:
break;
+
case BLOCK_H1:
case BLOCK_H2:
case BLOCK_H3:
case BLOCK_SETEXT_1:
case BLOCK_SETEXT_2:
pad(out, 2, scratch);
+
switch (t->type) {
case BLOCK_SETEXT_1:
temp_short = 1;
break;
+
case BLOCK_SETEXT_2:
temp_short = 2;
break;
+
default:
temp_short = t->type - BLOCK_H1 + 1;
}
print_const("</text:h>");
scratch->padded = 0;
break;
+
case BLOCK_HR:
pad(out, 2, scratch);
print_const("<text:p text:style-name=\"Horizontal_20_Line\"/>");
scratch->padded = 0;
break;
+
case BLOCK_HTML:
// Don't print HTML
break;
+
case BLOCK_LIST_BULLETED_LOOSE:
case BLOCK_LIST_BULLETED:
temp_short = scratch->list_is_tight;
+
switch (t->type) {
case BLOCK_LIST_BULLETED_LOOSE:
scratch->list_is_tight = false;
break;
+
case BLOCK_LIST_BULLETED:
scratch->list_is_tight = true;
break;
}
+
pad(out, 2, scratch);
print_const("<text:list text:style-name=\"L1\">");
scratch->padded = 1;
scratch->padded = 0;
scratch->list_is_tight = temp_short;
break;
+
case BLOCK_LIST_ENUMERATED_LOOSE:
case BLOCK_LIST_ENUMERATED:
temp_short = scratch->list_is_tight;
+
switch (t->type) {
case BLOCK_LIST_ENUMERATED_LOOSE:
scratch->list_is_tight = false;
break;
+
case BLOCK_LIST_ENUMERATED:
scratch->list_is_tight = true;
break;
}
+
pad(out, 2, scratch);
print_const("<text:list text:style-name=\"L2\">");
scratch->padded = 1;
scratch->padded = 0;
scratch->list_is_tight = temp_short;
break;
+
case BLOCK_LIST_ITEM:
pad(out, 2, scratch);
print_const("<text:list-item>\n");
print_const("</text:list-item>");
scratch->padded = 0;
break;
+
case BLOCK_LIST_ITEM_TIGHT:
pad(out, 2, scratch);
print_const("<text:list-item>\n");
- if (t->child && t->child->type != BLOCK_PARA)
+ if (t->child && t->child->type != BLOCK_PARA) {
print_const("<text:p text:style-name=\"P1\">\n");
+ }
scratch->padded = 2;
mmd_export_token_tree_odf(out, source, t->child, scratch);
- if (t->child && t->child->type != BLOCK_PARA)
+ if (t->child && t->child->type != BLOCK_PARA) {
print_const("</text:p>");
+ }
print_const("</text:list-item>");
scratch->padded = 0;
break;
+
case BLOCK_META:
break;
+
case BLOCK_PARA:
pad(out, 2, scratch);
print_const("<text:p");
case BLOCK_DEFINITION:
print_const(" text:style-name=\"Quotations\">");
break;
+
case PAIR_BRACKET_ABBREVIATION:
case PAIR_BRACKET_CITATION:
case PAIR_BRACKET_FOOTNOTE:
case PAIR_BRACKET_GLOSSARY:
print_const(" text:style-name=\"Footnote\">");
break;
+
default:
print_const(" text:style-name=\"Standard\">");
break;
print_const("</text:p>");
scratch->padded = 0;
break;
+
case BLOCK_TABLE:
pad(out, 2, scratch);
print_const("<table:table>\n");
// break;
// }
}
+
scratch->padded = 1;
mmd_export_token_tree_odf(out, source, t->child, scratch);
scratch->skip_token = temp_short;
break;
+
case BLOCK_TABLE_HEADER:
pad(out, 2, scratch);
scratch->in_table_header = 1;
scratch->in_table_header = 0;
scratch->padded = 1;
break;
+
case BLOCK_TABLE_SECTION:
pad(out, 2, scratch);
scratch->padded = 2;
mmd_export_token_tree_odf(out, source, t->child, scratch);
scratch->padded = 0;
break;
+
case BLOCK_TOC:
pad(out, 2, scratch);
scratch->padded = 1;
break;
+
case BLOCK_TERM:
pad(out, 2, scratch);
print_const("<text:p><text:span text:style-name=\"MMD-Bold\">");
print_const("</text:span></text:p>\n");
scratch->padded = 2;
break;
+
case BRACE_DOUBLE_LEFT:
print_const("{{");
break;
+
case BRACE_DOUBLE_RIGHT:
print_const("}}");
break;
+
case BRACKET_ABBREVIATION_LEFT:
print_const("[>");
break;
+
case BRACKET_CITATION_LEFT:
print_const("[#");
break;
+
case BRACKET_LEFT:
print_const("[");
break;
+
case BRACKET_RIGHT:
print_const("]");
break;
+
case BRACKET_VARIABLE_LEFT:
print_const("[\%");
break;
+
case COLON:
print_char(':');
break;
+
case CRITIC_ADD_OPEN:
print_const("{++");
break;
+
case CRITIC_ADD_CLOSE:
print_const("++}");
break;
+
case CRITIC_COM_OPEN:
print_const("{>>");
break;
+
case CRITIC_COM_CLOSE:
print_const("<<}");
break;
+
case CRITIC_DEL_OPEN:
print_const("{--");
break;
+
case CRITIC_DEL_CLOSE:
print_const("--}");
break;
+
case CRITIC_HI_OPEN:
print_const("{==");
break;
+
case CRITIC_HI_CLOSE:
print_const("==}");
break;
+
case CRITIC_SUB_OPEN:
print_const("{~~");
break;
+
case CRITIC_SUB_DIV:
print_const("~>");
break;
+
case CRITIC_SUB_CLOSE:
print_const("~~}");
break;
+
case DASH_M:
if (!(scratch->extensions & EXT_SMART)) {
print_token(t);
} else {
print_localized(DASH_M);
}
+
break;
+
case DASH_N:
if (!(scratch->extensions & EXT_SMART)) {
print_token(t);
} else {
print_localized(DASH_N);
}
+
break;
+
case ELLIPSIS:
if (!(scratch->extensions & EXT_SMART)) {
print_token(t);
} else {
print_localized(ELLIPSIS);
}
+
break;
+
case EMPH_START:
print_const("<text:span text:style-name=\"MMD-Italic\">");
break;
+
case EMPH_STOP:
print_const("</text:span>");
break;
+
case EQUAL:
print_char('=');
break;
+
case ESCAPED_CHARACTER:
if (!(scratch->extensions & EXT_COMPATIBILITY) &&
(source[t->start + 1] == ' ')) {
} else {
mmd_print_char_odf(out, source[t->start + 1]);
}
+
break;
+
case HASH1:
case HASH2:
case HASH3:
case HASH6:
print_token(t);
break;
+
case HTML_ENTITY:
print_const("&");
d_string_append_c_array(out, &(source[t->start + 1]), t->len - 1);
break;
+
case HTML_COMMENT_START:
if (!(scratch->extensions & EXT_SMART)) {
print_const("<!--");
print_const("<!");
print_localized(DASH_N);
}
+
break;
+
case HTML_COMMENT_STOP:
if (!(scratch->extensions & EXT_SMART)) {
print_const("-->");
print_localized(DASH_N);
print_const(">");
}
+
break;
+
case INDENT_SPACE:
print_char(' ');
break;
+
case INDENT_TAB:
print_const("<text:tab/>");
break;
+
case LINE_LIST_BULLETED:
case LINE_LIST_ENUMERATED:
mmd_export_token_tree_odf(out, source, t->child, scratch);
break;
+
case LINE_SETEXT_2:
case MANUAL_LABEL:
case MARKER_BLOCKQUOTE:
case MARKER_LIST_BULLET:
case MARKER_LIST_ENUMERATOR:
break;
+
case MATH_BRACKET_OPEN:
if (t->mate) {
print_const("<text:span text:style-name=\"math\">\\[");
- } else
+ } else {
print_const("\\[");
+ }
+
break;
+
case MATH_BRACKET_CLOSE:
if (t->mate) {
print_const("\\]</text:span>");
- } else
+ } else {
print_const("\\]");
+ }
+
break;
+
case MATH_DOLLAR_SINGLE:
if (t->mate) {
(t->start < t->mate->start) ? ( print_const("<text:span text:style-name=\"math\">\\(") ) : ( print_const("\\)</text:span>") );
} else {
print_const("$");
}
+
break;
+
case MATH_DOLLAR_DOUBLE:
if (t->mate) {
(t->start < t->mate->start) ? ( print_const("<text:span text:style-name=\"math\">\\[") ) : ( print_const("\\]</text:span>") );
} else {
print_const("$$");
}
+
break;
+
case MATH_PAREN_OPEN:
if (t->mate) {
print_const("<text:span text:style-name=\"math\">\\(");
- } else
+ } else {
print_const("\\(");
+ }
+
break;
+
case MATH_PAREN_CLOSE:
if (t->mate) {
print_const("\\)</text:span>");
- } else
+ } else {
print_const("\\)");
+ }
+
break;
+
case NON_INDENT_SPACE:
print_char(' ');
break;
+
case PAIR_ANGLE:
temp_char = url_accept(source, t->start + 1, t->len - 2, NULL, true);
free(temp_char);
break;
+
case PAIR_BACKTICK:
+
// Strip leading whitespace
switch (t->child->next->type) {
case TEXT_NL:
case NON_INDENT_SPACE:
t->child->next->type = TEXT_EMPTY;
break;
+
case TEXT_PLAIN:
while (t->child->next->len && char_is_whitespace(source[t->child->next->start])) {
t->child->next->start++;
t->child->next->len--;
}
+
break;
}
case NON_INDENT_SPACE:
t->child->mate->prev->type = TEXT_EMPTY;
break;
+
case TEXT_PLAIN:
while (t->child->mate->prev->len && char_is_whitespace(source[t->child->mate->prev->start + t->child->mate->prev->len - 1])) {
t->child->mate->prev->len--;
}
+
break;
}
+
t->child->type = TEXT_EMPTY;
t->child->mate->type = TEXT_EMPTY;
if (raw_filter_matches(t->next, source, FORMAT_FODT)) {
d_string_append_c_array(out, &(source[t->child->start + t->child->len]), t->child->mate->start - t->child->start - t->child->len);
}
+
// Skip over PAIR_RAW_FILTER
scratch->skip_token = 1;
break;
mmd_export_token_tree_odf_raw(out, source, t->child, scratch);
print_const("</text:span>");
break;
+
case PAIR_BRACE:
case PAIR_BRACES:
mmd_export_token_tree_odf(out, source, t->child, scratch);
break;
+
case PAIR_BRACKET:
if ((scratch->extensions & EXT_NOTES) &&
(t->next && t->next->type == PAIR_BRACKET_CITATION)) {
temp_token = temp_token->next;
}
- if (temp_token && temp_token->type == TEXT_NL)
+ if (temp_token && temp_token->type == TEXT_NL) {
temp_token = temp_token->next;
+ }
- if (temp_token && temp_token->type == TEXT_LINEBREAK)
+ if (temp_token && temp_token->type == TEXT_LINEBREAK) {
temp_token = temp_token->next;
+ }
if (t->prev || temp_token) {
mmd_export_image_odf(out, source, t, temp_link, scratch, false);
// No links exist, so treat as normal
mmd_export_token_tree_odf(out, source, t->child, scratch);
break;
+
case PAIR_BRACKET_CITATION:
parse_citation:
temp_bool = true; // Track whether this is regular vs 'not cited'
// Note-based syntax disabled
mmd_export_token_tree_odf(out, source, t->child, scratch);
}
+
break;
+
case PAIR_BRACKET_FOOTNOTE:
if (scratch->extensions & EXT_NOTES) {
// Note-based syntax enabled
// Note-based syntax disabled
mmd_export_token_tree_odf(out, source, t->child, scratch);
}
+
break;
+
case PAIR_BRACKET_ABBREVIATION:
+
// Which might also be an "auto-tagged" abbreviation
if (scratch->extensions & EXT_NOTES) {
// Note-based syntax enabled
// Note-based syntax disabled
mmd_export_token_tree_odf(out, source, t->child, scratch);
}
+
break;
+
case PAIR_BRACKET_GLOSSARY:
+
// Which might also be an "auto-tagged" glossary
if (scratch->extensions & EXT_NOTES) {
// Note-based syntax enabled
// Note-based syntax disabled
mmd_export_token_tree_odf(out, source, t->child, scratch);
}
+
break;
+
case PAIR_BRACKET_VARIABLE:
temp_char = text_inside_pair(source, t);
temp_char2 = extract_metadata(scratch, temp_char);
- if (temp_char2)
+ if (temp_char2) {
mmd_print_string_odf(out, temp_char2);
- else
+ } else {
mmd_export_token_tree_odf(out, source, t->child, scratch);
+ }
// Don't free temp_char2 (it belongs to meta *)
free(temp_char);
break;
+
case PAIR_CRITIC_ADD:
+
// Ignore if we're rejecting
- if (scratch->extensions & EXT_CRITIC_REJECT)
+ if (scratch->extensions & EXT_CRITIC_REJECT) {
break;
+ }
+
if (scratch->extensions & EXT_CRITIC) {
t->child->type = TEXT_EMPTY;
t->child->mate->type = TEXT_EMPTY;
+
if (scratch->extensions & EXT_CRITIC_ACCEPT) {
mmd_export_token_tree_odf(out, source, t->child, scratch);
} else {
} else {
mmd_export_token_tree_odf(out, source, t->child, scratch);
}
+
break;
+
case PAIR_CRITIC_DEL:
+
// Ignore if we're accepting
- if (scratch->extensions & EXT_CRITIC_ACCEPT)
+ if (scratch->extensions & EXT_CRITIC_ACCEPT) {
break;
+ }
+
if (scratch->extensions & EXT_CRITIC) {
t->child->type = TEXT_EMPTY;
t->child->mate->type = TEXT_EMPTY;
+
if (scratch->extensions & EXT_CRITIC_REJECT) {
mmd_export_token_tree_odf(out, source, t->child, scratch);
} else {
} else {
mmd_export_token_tree_odf(out, source, t->child, scratch);
}
+
break;
+
case PAIR_CRITIC_COM:
+
// Ignore if we're rejecting or accepting
if ((scratch->extensions & EXT_CRITIC_REJECT) ||
- (scratch->extensions & EXT_CRITIC_ACCEPT))
+ (scratch->extensions & EXT_CRITIC_ACCEPT)) {
break;
+ }
+
if (scratch->extensions & EXT_CRITIC) {
t->child->type = TEXT_EMPTY;
t->child->mate->type = TEXT_EMPTY;
} else {
mmd_export_token_tree_odf(out, source, t->child, scratch);
}
+
break;
+
case PAIR_CRITIC_HI:
+
// Ignore if we're rejecting or accepting
if ((scratch->extensions & EXT_CRITIC_REJECT) ||
- (scratch->extensions & EXT_CRITIC_ACCEPT))
+ (scratch->extensions & EXT_CRITIC_ACCEPT)) {
break;
+ }
+
if (scratch->extensions & EXT_CRITIC) {
t->child->type = TEXT_EMPTY;
t->child->mate->type = TEXT_EMPTY;
} else {
mmd_export_token_tree_odf(out, source, t->child, scratch);
}
+
break;
+
case CRITIC_SUB_DIV_A:
print_const("~");
break;
+
case CRITIC_SUB_DIV_B:
print_const(">");
break;
+
case PAIR_CRITIC_SUB_DEL:
if ((scratch->extensions & EXT_CRITIC) &&
(t->next) &&
(t->next->type == PAIR_CRITIC_SUB_ADD)) {
t->child->type = TEXT_EMPTY;
t->child->mate->type = TEXT_EMPTY;
+
if (scratch->extensions & EXT_CRITIC_ACCEPT) {
} else if (scratch->extensions & EXT_CRITIC_REJECT) {
} else {
mmd_export_token_tree_odf(out, source, t->child, scratch);
}
+
break;
+
case PAIR_CRITIC_SUB_ADD:
if ((scratch->extensions & EXT_CRITIC) &&
(t->prev) &&
(t->prev->type == PAIR_CRITIC_SUB_DEL)) {
t->child->type = TEXT_EMPTY;
t->child->mate->type = TEXT_EMPTY;
+
if (scratch->extensions & EXT_CRITIC_REJECT) {
} else if (scratch->extensions & EXT_CRITIC_ACCEPT) {
} else {
mmd_export_token_tree_odf(out, source, t->child, scratch);
}
+
break;
+
case PAIR_HTML_COMMENT:
break;
+
case PAIR_EMPH:
case PAIR_MATH:
case PAIR_PAREN:
case PAIR_UL:
mmd_export_token_tree_odf(out, source, t->child, scratch);
break;
+
case PAREN_LEFT:
print_char('(');
break;
+
case PAREN_RIGHT:
print_char(')');
break;
+
case PIPE:
print_token(t);
break;
+
case PLUS:
print_char('+');
break;
+
case QUOTE_SINGLE:
- if ((t->mate == NULL) || (!(scratch->extensions & EXT_SMART)))
+ if ((t->mate == NULL) || (!(scratch->extensions & EXT_SMART))) {
print_const("'");
- else
+ } else {
(t->start < t->mate->start) ? ( print_localized(QUOTE_LEFT_SINGLE) ) : ( print_localized(QUOTE_RIGHT_SINGLE) );
+ }
+
break;
+
case QUOTE_DOUBLE:
- if ((t->mate == NULL) || (!(scratch->extensions & EXT_SMART)))
+ if ((t->mate == NULL) || (!(scratch->extensions & EXT_SMART))) {
print_const(""");
- else
+ } else {
(t->start < t->mate->start) ? ( print_localized(QUOTE_LEFT_DOUBLE) ) : ( print_localized(QUOTE_RIGHT_DOUBLE) );
+ }
+
break;
+
case QUOTE_RIGHT_ALT:
- if ((t->mate == NULL) || (!(scratch->extensions & EXT_SMART)))
+ if ((t->mate == NULL) || (!(scratch->extensions & EXT_SMART))) {
print_const("''");
- else
+ } else {
print_localized(QUOTE_RIGHT_DOUBLE);
+ }
+
break;
+
case SLASH:
print_char('/');
break;
+
case STAR:
print_char('*');
break;
+
case STRONG_START:
print_const("<text:span text:style-name=\"MMD-Bold\">");
break;
+
case STRONG_STOP:
print_const("</text:span>");
break;
+
case SUBSCRIPT:
if (t->mate) {
(t->start < t->mate->start) ? (print_const("<text:span text:style-name=\"MMD-Subscript\">")) : (print_const("</text:span>"));
} else {
print_const("~");
}
+
break;
+
case SUPERSCRIPT:
if (t->mate) {
(t->start < t->mate->start) ? (print_const("<text:span text:style-name=\"MMD-Superscript\">")) : (print_const("</text:span>"));
} else {
print_const("^");
}
+
break;
+
case TABLE_CELL:
print_const("<table:table-cell");
print_const(">\n<text:p text:style-name=\"Table_20_Heading\"");
} else {
print_const(">\n<text:p");
+
switch (scratch->table_alignment[scratch->table_cell_count]) {
case 'l':
case 'L':
default:
print_const(" text:style-name=\"MMD-Table\"");
break;
+
case 'r':
case 'R':
print_const(" text:style-name=\"MMD-Table-Right\"");
break;
+
case 'c':
case 'C':
print_const(" text:style-name=\"MMD-Table-Center\"");
print_const("</text:p>\n</table:table-cell>\n");
- if (t->next)
+ if (t->next) {
scratch->table_cell_count += t->next->len;
- else
+ } else {
scratch->table_cell_count++;
+ }
break;
+
case TABLE_DIVIDER:
break;
+
case TABLE_ROW:
print_const("<table:table-row>\n");
scratch->table_cell_count = 0;
mmd_export_token_tree_odf(out, source, t->child, scratch);
print_const("</table:table-row>\n");
break;
+
case TEXT_EMPTY:
break;
+
case TEXT_LINEBREAK:
if (t->next) {
print_const("<text:line-break/>\n");
scratch->padded = 0;
}
+
break;
+
case TEXT_NL:
- if (t->next)
+ if (t->next) {
print_char('\n');
+ }
+
break;
+
case RAW_FILTER_LEFT:
case TEXT_BACKSLASH:
case TEXT_BRACE_LEFT:
case UL:
print_token(t);
break;
+
default:
fprintf(stderr, "Unknown token type: %d\n", t->type);
token_describe(t, source);
void mmd_export_token_odf_raw(DString * out, const char * source, token * t, scratch_pad * scratch) {
- if (t == NULL)
+ if (t == NULL) {
return;
+ }
switch (t->type) {
case AMPERSAND:
print_const("&");
break;
+
case AMPERSAND_LONG:
print_const("&amp;");
break;
+
case ANGLE_RIGHT:
print_const(">");
break;
+
case ANGLE_LEFT:
print_const("<");
break;
+
case ESCAPED_CHARACTER:
print_const("\\");
mmd_print_char_odf(out, source[t->start + 1]);
break;
+
case HTML_ENTITY:
print_const("&");
d_string_append_c_array(out, &(source[t->start + 1]), t->len - 1);
break;
+
case INDENT_TAB:
print_const("<text:tab/>");
break;
+
case QUOTE_DOUBLE:
print_const(""");
break;
+
case CODE_FENCE:
- if (t->next)
+ if (t->next) {
t->next->type = TEXT_EMPTY;
+ }
+
case TEXT_EMPTY:
break;
+
case TEXT_NL:
print_const("<text:line-break/>");
break;
+
default:
- if (t->child)
+ if (t->child) {
mmd_export_token_tree_odf_raw(out, source, t->child, scratch);
- else
+ } else {
print_token(t);
+ }
+
break;
}
}
// Iterate over metadata keys
meta * m;
- if (scratch->meta_hash)
+ if (scratch->meta_hash) {
print_const("<office:meta>\n");
+ }
for (m = scratch->meta_hash; m != NULL; m = m->hh.next) {
if (strcmp(m->key, "baseheaderlevel") == 0) {
}
}
- if (scratch->meta_hash)
+ if (scratch->meta_hash) {
print_const("</office:meta>\n");
+ }
print_const("<office:body>\n<office:text>\n");
}
case '"':
print_const(""");
break;
+
case '&':
print_const("&");
break;
+
case '<':
print_const("<");
break;
+
case '>':
print_const(">");
break;
+
default:
if (obfuscate && ((int) c == (((int) c) & 127))) {
- if (ran_num_next() % 2 == 0)
+ if (ran_num_next() % 2 == 0) {
printf("&#%d;", (int) c);
- else
+ } else {
printf("&#x%x;", (unsigned int) c);
+ }
} else {
print_char(c);
}
+
break;
}
}
case DASH_N:
print_const("–");
break;
+
case DASH_M:
print_const("—");
break;
+
case ELLIPSIS:
print_const("…");
break;
+
case APOSTROPHE:
print_const("’");
break;
+
case QUOTE_LEFT_SINGLE:
switch (scratch->quotes_lang) {
case SWEDISH:
print( "’");
break;
+
case FRENCH:
print_const("'");
break;
+
case GERMAN:
print_const("‚");
break;
+
case GERMANGUILL:
print_const("›");
break;
+
default:
print_const("‘");
}
+
break;
+
case QUOTE_RIGHT_SINGLE:
switch (scratch->quotes_lang) {
case GERMAN:
print_const("‘");
break;
+
case GERMANGUILL:
print_const("‹");
break;
+
default:
print_const("’");
}
+
break;
+
case QUOTE_LEFT_DOUBLE:
switch (scratch->quotes_lang) {
case DUTCH:
case GERMAN:
print_const("„");
break;
+
case GERMANGUILL:
print_const("»");
break;
+
case FRENCH:
print_const("«");
break;
+
case SWEDISH:
print( "”");
break;
+
default:
print_const("“");
}
+
break;
+
case QUOTE_RIGHT_DOUBLE:
switch (scratch->quotes_lang) {
case GERMAN:
print_const("“");
break;
+
case GERMANGUILL:
print_const("«");
break;
+
case FRENCH:
print_const("»");
break;
+
case SWEDISH:
case DUTCH:
default:
print_const("”");
}
+
break;
}
}
result = my_strdup(original);
- for (i = 0; result[i]; i++)
+ for (i = 0; result[i]; i++) {
result[i] = tolower(result[i]);
+ }
if (strstr(&result[strlen(result)-2],"px")) {
// Leave 'px' alone
print_const("<a href=\"");
mmd_print_string_html(out, link->url, false);
print_const("\"");
- } else
+ } else {
print_const("<a href=\"\"");
+ }
if (link->title && link->title[0] != '\0') {
print_const(" title=\"");
text->child->next->len++;
}
- if (text && text->child)
+ if (text && text->child) {
mmd_export_token_tree_html(out, source, text->child, scratch);
+ }
print_const("</a>");
}
char * height = NULL;
// Compatibility mode doesn't allow figures
- if (scratch->extensions & EXT_COMPATIBILITY)
+ if (scratch->extensions & EXT_COMPATIBILITY) {
is_figure = false;
+ }
if (is_figure) {
// Remove wrapping <p> markers
} else {
printf("<img src=\"%s\"", link->url);
}
- } else
+ } else {
print_const("<img src=\"\"");
+ }
if (text) {
print_const(" alt=\"");
free(label);
}
- if (link->title && link->title[0] != '\0')
+ if (link->title && link->title[0] != '\0') {
printf(" title=\"%s\"", link->title);
+ }
while (a) {
if (strcmp(a->key, "width") == 0) {
width = strip_dimension_units(a->value);
+
if (strcmp(a->value, width) == 0) {
print_const(" ");
print(a->key);
}
} else if (strcmp(a->key, "height") == 0) {
height = strip_dimension_units(a->value);
+
if (strcmp(a->value, height) == 0) {
print_const(" ");
print(a->key);
if (height || width) {
print_const(" style=\"");
- if (height)
+
+ if (height) {
printf("height:%s;", height);
- if (width)
+ }
+
+ if (width) {
printf("width:%s;", width);
+ }
+
print_const("\"");
}
mmd_export_token_tree_html(out, source, text->child, scratch);
print_const("</figcaption>");
}
+
print_const("\n</figure>");
}
}
if (*counter < scratch->header_stack->size - 1) {
next = stack_peek_index(scratch->header_stack, *counter + 1);
next_level = next->type - BLOCK_H1 + 1;
+
if (next_level > entry_level) {
// This entry has children
(*counter)++;
void mmd_export_token_html(DString * out, const char * source, token * t, scratch_pad * scratch) {
- if (t == NULL)
+ if (t == NULL) {
return;
+ }
short temp_short;
short temp_short2;
case AMPERSAND_LONG:
print_const("&");
break;
+
case ANGLE_LEFT:
print_const("<");
break;
+
case ANGLE_RIGHT:
print_const(">");
break;
+
case APOSTROPHE:
if (!(scratch->extensions & EXT_SMART)) {
print_token(t);
} else {
print_localized(APOSTROPHE);
}
+
break;
+
case BACKTICK:
- if (t->mate == NULL)
+ if (t->mate == NULL) {
print_token(t);
- else if (t->mate->type == QUOTE_RIGHT_ALT)
+ } else if (t->mate->type == QUOTE_RIGHT_ALT)
if (!(scratch->extensions & EXT_SMART)) {
print_token(t);
} else {
} else {
print_const("</code>");
}
+
break;
+
case BLOCK_BLOCKQUOTE:
pad(out, 2, scratch);
print_const("<blockquote>\n");
print_const("</blockquote>");
scratch->padded = 0;
break;
+
case BLOCK_DEFINITION:
pad(out, 2, scratch);
print_const("<dd>");
temp_short = scratch->list_is_tight;
+
if (t->child) {
- if (!(t->child->next && (t->child->next->type == BLOCK_EMPTY) && t->child->next->next))
+ if (!(t->child->next && (t->child->next->type == BLOCK_EMPTY) && t->child->next->next)) {
scratch->list_is_tight = true;
+ }
mmd_export_token_tree_html(out, source, t->child, scratch);
}
scratch->list_is_tight = temp_short;
break;
+
case BLOCK_DEFLIST:
pad(out, 2, scratch);
// Group consecutive definition lists into a single list.
// lemon's LALR(1) parser can't properly handle this (to my understanding).
- if (!(t->prev && (t->prev->type == BLOCK_DEFLIST)))
+ if (!(t->prev && (t->prev->type == BLOCK_DEFLIST))) {
print_const("<dl>\n");
+ }
scratch->padded = 2;
mmd_export_token_tree_html(out, source, t->child, scratch);
pad(out, 1, scratch);
- if (!(t->next && (t->next->type == BLOCK_DEFLIST)))
+ if (!(t->next && (t->next->type == BLOCK_DEFLIST))) {
print_const("</dl>\n");
+ }
scratch->padded = 1;
break;
+
case BLOCK_CODE_FENCED:
pad(out, 2, scratch);
case LINE_FENCE_BACKTICK_5:
temp_token = t->child->tail;
break;
+
default:
temp_token = NULL;
}
+
if (temp_token) {
d_string_append_c_array(out, &source[t->child->next->start], temp_token->start - t->child->next->start);
scratch->padded = 1;
free(temp_char);
break;
}
+
print_const("<pre><code");
printf(" class=\"%s\"", temp_char);
free(temp_char);
print_const("</code></pre>");
scratch->padded = 0;
break;
+
case BLOCK_CODE_INDENTED:
pad(out, 2, scratch);
print_const("<pre><code>");
print_const("</code></pre>");
scratch->padded = 0;
break;
+
case BLOCK_EMPTY:
break;
+
case BLOCK_H1:
case BLOCK_H2:
case BLOCK_H3:
case BLOCK_H6:
pad(out, 2, scratch);
temp_short = t->type - BLOCK_H1 + 1;
+
if (scratch->extensions & EXT_NO_LABELS) {
printf("<h%1d>", temp_short + scratch->base_header_level - 1);
} else {
printf("<h%1d id=\"%s\">", temp_short + scratch->base_header_level - 1, temp_char);
free(temp_char);
}
+
mmd_export_token_tree_html(out, source, t->child, scratch);
printf("</h%1d>", temp_short + scratch->base_header_level - 1);
scratch->padded = 0;
break;
+
case BLOCK_HR:
pad(out, 2, scratch);
print_const("<hr />");
scratch->padded = 0;
break;
+
case BLOCK_HTML:
pad(out, 2, scratch);
print_token_raw(out, source, t);
scratch->padded = 1;
break;
+
case BLOCK_LIST_BULLETED_LOOSE:
case BLOCK_LIST_BULLETED:
temp_short = scratch->list_is_tight;
+
switch (t->type) {
case BLOCK_LIST_BULLETED_LOOSE:
scratch->list_is_tight = false;
break;
+
case BLOCK_LIST_BULLETED:
scratch->list_is_tight = true;
break;
}
+
pad(out, 2, scratch);
print_const("<ul>");
scratch->padded = 0;
scratch->padded = 0;
scratch->list_is_tight = temp_short;
break;
+
case BLOCK_LIST_ENUMERATED_LOOSE:
case BLOCK_LIST_ENUMERATED:
temp_short = scratch->list_is_tight;
+
switch (t->type) {
case BLOCK_LIST_ENUMERATED_LOOSE:
scratch->list_is_tight = false;
break;
+
case BLOCK_LIST_ENUMERATED:
scratch->list_is_tight = true;
break;
}
+
pad(out, 2, scratch);
print_const("<ol>");
scratch->padded = 0;
scratch->padded = 0;
scratch->list_is_tight = temp_short;
break;
+
case BLOCK_LIST_ITEM:
pad(out, 1, scratch);
print_const("<li>");
print_const("</li>");
scratch->padded = 0;
break;
+
case BLOCK_LIST_ITEM_TIGHT:
pad(out, 1, scratch);
print_const("<li>");
- if (!scratch->list_is_tight)
+ if (!scratch->list_is_tight) {
print_const("<p>");
+ }
scratch->padded = 2;
mmd_export_token_tree_html(out, source, t->child, scratch);
if (scratch->close_para) {
- if (!scratch->list_is_tight)
+ if (!scratch->list_is_tight) {
print_const("</p>");
+ }
} else {
scratch->close_para = true;
}
print_const("</li>");
scratch->padded = 0;
break;
+
case BLOCK_META:
break;
+
case BLOCK_PARA:
case BLOCK_DEF_CITATION:
case BLOCK_DEF_FOOTNOTE:
case BLOCK_DEF_GLOSSARY:
pad(out, 2, scratch);
- if (!scratch->list_is_tight)
+ if (!scratch->list_is_tight) {
print_const("<p>");
+ }
mmd_export_token_tree_html(out, source, t->child, scratch);
if (scratch->footnote_para_counter == 0) {
temp_short = scratch->footnote_being_printed;
+
if (scratch->extensions & EXT_RANDOM_FOOT) {
srand(scratch->random_seed_base + temp_short);
temp_short = rand() % 32000 + 1;
}
+
printf(" <a href=\"#fnref:%d\" title=\"%s\" class=\"reversefootnote\"> ↩</a>", temp_short, LC("return to body"));
}
}
}
if (scratch->close_para) {
- if (!scratch->list_is_tight)
+ if (!scratch->list_is_tight) {
print_const("</p>");
+ }
} else {
scratch->close_para = true;
}
+
scratch->padded = 0;
break;
+
case BLOCK_SETEXT_1:
pad(out, 2, scratch);
temp_short = 1;
+
if (scratch->extensions & EXT_NO_LABELS) {
printf("<h%1d>", temp_short + scratch->base_header_level - 1);
} else {
temp_token = manual_label_from_header(t, source);
+
if (temp_token) {
temp_char = label_from_token(source, temp_token);
} else {
temp_char = label_from_token(source, t);
}
+
printf("<h%1d id=\"%s\">", temp_short + scratch->base_header_level - 1, temp_char);
free(temp_char);
}
+
mmd_export_token_tree_html(out, source, t->child, scratch);
printf("</h%1d>", temp_short + scratch->base_header_level - 1);
scratch->padded = 0;
break;
+
case BLOCK_SETEXT_2:
pad(out, 2, scratch);
temp_short = 2;
+
if (scratch->extensions & EXT_NO_LABELS) {
printf("<h%1d>", temp_short + scratch->base_header_level - 1);
} else {
temp_token = manual_label_from_header(t, source);
+
if (temp_token) {
temp_char = label_from_token(source, temp_token);
} else {
temp_char = label_from_token(source, t);
}
+
printf("<h%1d id=\"%s\">", temp_short + scratch->base_header_level - 1, temp_char);
free(temp_char);
}
+
mmd_export_token_tree_html(out, source, t->child, scratch);
printf("</h%1d>", temp_short + scratch->base_header_level - 1);
scratch->padded = 0;
break;
+
case BLOCK_TABLE:
pad(out, 2, scratch);
print_const("<table>\n");
read_table_column_alignments(source, t, scratch);
print_const("<colgroup>\n");
+
for (int i = 0; i < scratch->table_column_count; ++i) {
switch (scratch->table_alignment[i]) {
case 'l':
print_const("<col style=\"text-align:left;\"/>\n");
break;
+
case 'N':
case 'L':
print_const("<col style=\"text-align:left;\" class=\"extended\"/>\n");
break;
+
case 'r':
print_const("<col style=\"text-align:right;\"/>\n");
break;
+
case 'R':
print_const("<col style=\"text-align:right;\" class=\"extended\"/>\n");
break;
+
case 'c':
print_const("<col style=\"text-align:center;\"/>\n");
break;
+
case 'C':
print_const("<col style=\"text-align:center;\" class=\"extended\"/>\n");
break;
+
default:
print_const("<col />\n");
break;
}
}
+
print_const("</colgroup>\n");
scratch->padded = 1;
scratch->skip_token = temp_short;
break;
+
case BLOCK_TABLE_HEADER:
pad(out, 2, scratch);
print_const("<thead>\n");
print_const("</thead>\n");
scratch->padded = 1;
break;
+
case BLOCK_TABLE_SECTION:
pad(out, 2, scratch);
print_const("<tbody>\n");
print_const("</tbody>");
scratch->padded = 0;
break;
+
case BLOCK_TERM:
pad(out, 2, scratch);
print_const("<dt>");
print_const("</dt>\n");
scratch->padded = 2;
break;
+
case BLOCK_TOC:
+
// EPUB uses a separate TOC
- if (scratch->output_format == FORMAT_EPUB)
+ if (scratch->output_format == FORMAT_EPUB) {
break;
+ }
pad(out, 2, scratch);
print_const("<div class=\"TOC\">\n");
print_const("</div>");
scratch->padded = 0;
break;
+
case BRACE_DOUBLE_LEFT:
print_const("{{");
break;
+
case BRACE_DOUBLE_RIGHT:
print_const("}}");
break;
+
case BRACKET_LEFT:
print_const("[");
break;
+
case BRACKET_ABBREVIATION_LEFT:
print_const("[>");
break;
+
case BRACKET_CITATION_LEFT:
print_const("[#");
break;
+
case BRACKET_FOOTNOTE_LEFT:
print_const("[^");
break;
+
case BRACKET_GLOSSARY_LEFT:
print_const("[?");
break;
+
case BRACKET_IMAGE_LEFT:
print_const("![");
break;
+
case BRACKET_VARIABLE_LEFT:
print_const("[\%");
break;
+
case BRACKET_RIGHT:
print_const("]");
break;
+
case COLON:
print_const(":");
break;
+
case CRITIC_ADD_OPEN:
print_const("{++");
break;
+
case CRITIC_ADD_CLOSE:
print_const("++}");
break;
+
case CRITIC_COM_OPEN:
print_const("{>>");
break;
+
case CRITIC_COM_CLOSE:
print_const("<<}");
break;
+
case CRITIC_DEL_OPEN:
print_const("{--");
break;
+
case CRITIC_DEL_CLOSE:
print_const("--}");
break;
+
case CRITIC_HI_OPEN:
print_const("{==");
break;
+
case CRITIC_HI_CLOSE:
print_const("==}");
break;
+
case CRITIC_SUB_OPEN:
print_const("{~~");
break;
+
case CRITIC_SUB_DIV:
print_const("~>");
break;
+
case CRITIC_SUB_CLOSE:
print_const("~~}");
break;
+
case DASH_M:
if (!(scratch->extensions & EXT_SMART)) {
print_token(t);
} else {
print_localized(DASH_M);
}
+
break;
+
case DASH_N:
if (!(scratch->extensions & EXT_SMART)) {
print_token(t);
} else {
print_localized(DASH_N);
}
+
break;
+
case DOC_START_TOKEN:
mmd_export_token_tree_html(out, source, t->child, scratch);
break;
+
case ELLIPSIS:
if (!(scratch->extensions & EXT_SMART)) {
print_token(t);
} else {
print_localized(ELLIPSIS);
}
+
break;
+
case EMPH_START:
print_const("<em>");
break;
+
case EMPH_STOP:
print_const("</em>");
break;
+
case EQUAL:
print_const("=");
break;
+
case ESCAPED_CHARACTER:
if (!(scratch->extensions & EXT_COMPATIBILITY) &&
(source[t->start + 1] == ' ')) {
} else {
mmd_print_char_html(out, source[t->start + 1], false);
}
+
break;
+
case HASH1:
case HASH2:
case HASH3:
case HASH6:
print_token(t);
break;
+
case HTML_ENTITY:
print_token(t);
break;
+
case HTML_COMMENT_START:
if (!(scratch->extensions & EXT_SMART)) {
print_const("<!--");
print_const("<!");
print_localized(DASH_N);
}
+
break;
+
case HTML_COMMENT_STOP:
if (!(scratch->extensions & EXT_SMART)) {
print_const("-->");
print_localized(DASH_N);
print_const(">");
}
+
break;
+
case INDENT_SPACE:
print_char(' ');
break;
+
case INDENT_TAB:
print_char('\t');
break;
+
case LINE_LIST_BULLETED:
case LINE_LIST_ENUMERATED:
mmd_export_token_tree_html(out, source, t->child, scratch);
break;
+
case LINE_SETEXT_2:
case MARKER_BLOCKQUOTE:
case MARKER_H1:
case MARKER_H5:
case MARKER_H6:
break;
+
case MARKER_LIST_BULLET:
case MARKER_LIST_ENUMERATOR:
break;
+
case MATH_BRACKET_OPEN:
if (t->mate) {
print_const("<span class=\"math\">\\[");
- } else
+ } else {
print_const("\\[");
+ }
+
break;
+
case MATH_BRACKET_CLOSE:
if (t->mate) {
print_const("\\]</span>");
- } else
+ } else {
print_const("\\]");
+ }
+
break;
+
case MATH_DOLLAR_SINGLE:
if (t->mate) {
(t->start < t->mate->start) ? ( print_const("<span class=\"math\">\\(") ) : ( print_const("\\)</span>") );
} else {
print_const("$");
}
+
break;
+
case MATH_DOLLAR_DOUBLE:
if (t->mate) {
(t->start < t->mate->start) ? ( print_const("<span class=\"math\">\\[") ) : ( print_const("\\]</span>") );
} else {
print_const("$$");
}
+
break;
+
case MATH_PAREN_OPEN:
if (t->mate) {
print_const("<span class=\"math\">\\(");
- } else
+ } else {
print_const("\\(");
+ }
+
break;
+
case MATH_PAREN_CLOSE:
if (t->mate) {
print_const("\\)</span>");
- } else
+ } else {
print_const("\\)");
+ }
+
break;
+
case NON_INDENT_SPACE:
print_char(' ');
break;
+
case PAIR_BACKTICK:
+
// Strip leading whitespace
switch (t->child->next->type) {
case TEXT_NL:
case NON_INDENT_SPACE:
t->child->next->type = TEXT_EMPTY;
break;
+
case TEXT_PLAIN:
while (t->child->next->len && char_is_whitespace(source[t->child->next->start])) {
t->child->next->start++;
t->child->next->len--;
}
+
break;
}
case NON_INDENT_SPACE:
t->child->mate->prev->type = TEXT_EMPTY;
break;
+
case TEXT_PLAIN:
while (t->child->mate->prev->len && char_is_whitespace(source[t->child->mate->prev->start + t->child->mate->prev->len - 1])) {
t->child->mate->prev->len--;
}
+
break;
}
+
t->child->type = TEXT_EMPTY;
t->child->mate->type = TEXT_EMPTY;
if (raw_filter_matches(t->next, source, FORMAT_HTML)) {
d_string_append_c_array(out, &(source[t->child->start + t->child->len]), t->child->mate->start - t->child->start - t->child->len);
}
+
// Skip over PAIR_RAW_FILTER
scratch->skip_token = 1;
break;
mmd_export_token_tree_html_raw(out, source, t->child, scratch);
print_const("</code>");
break;
+
case PAIR_ANGLE:
temp_char = url_accept(source, t->start + 1, t->len - 2, NULL, true);
free(temp_char);
break;
+
case PAIR_BRACE:
case PAIR_BRACES:
case PAIR_RAW_FILTER:
mmd_export_token_tree_html(out, source, t->child, scratch);
break;
+
case PAIR_BRACKET:
if ((scratch->extensions & EXT_NOTES) &&
(t->next && t->next->type == PAIR_BRACKET_CITATION)) {
temp_token = temp_token->next;
}
- if (temp_token && temp_token->type == TEXT_NL)
+ if (temp_token && temp_token->type == TEXT_NL) {
temp_token = temp_token->next;
+ }
- if (temp_token && temp_token->type == TEXT_LINEBREAK)
+ if (temp_token && temp_token->type == TEXT_LINEBREAK) {
temp_token = temp_token->next;
+ }
if (t->prev || temp_token) {
mmd_export_image_html(out, source, t, temp_link, scratch, false);
// No links exist, so treat as normal
mmd_export_token_tree_html(out, source, t->child, scratch);
break;
+
case PAIR_BRACKET_ABBREVIATION:
+
// Which might also be an "auto-tagged" abbreviation
if (scratch->extensions & EXT_NOTES) {
// Note-based syntax enabled
print_const("<abbr title=\"");
mmd_print_string_html(out, temp_note->clean_text, false);
print_const("\">");
- if (t->child)
+
+ if (t->child) {
mmd_export_token_tree_html(out, source, t->child, scratch);
- else
+ } else {
print_token(t);
+ }
+
print_const("</abbr>");
} else {
// This is the first time this note was used
print_const(" (<abbr title=\"");
mmd_print_string_html(out, temp_note->clean_text, false);
print_const("\">");
- if (t->child)
+
+ if (t->child) {
mmd_export_token_tree_html(out, source, t->child, scratch);
- else
+ } else {
print_token(t);
+ }
+
print_const("</abbr>)");
}
} else {
// Note-based syntax disabled
mmd_export_token_tree_html(out, source, t->child, scratch);
}
+
break;
+
case PAIR_BRACKET_CITATION:
parse_citation:
temp_bool = true; // Track whether this is regular vs 'not cited'
// Note-based syntax disabled
mmd_export_token_tree_html(out, source, t->child, scratch);
}
+
break;
case PAIR_BRACKET_FOOTNOTE:
// Note-based syntax disabled
mmd_export_token_tree_html(out, source, t->child, scratch);
}
+
break;
+
case PAIR_BRACKET_GLOSSARY:
+
// Which might also be an "auto-tagged" glossary
if (scratch->extensions & EXT_NOTES) {
// Note-based syntax enabled
// This instance is not properly formed
print_const("[?");
- if (t->child)
+ if (t->child) {
mmd_export_token_tree_html(out, source, t->child->next, scratch);
- else
+ } else {
print_token(t);
+ }
print_const("]");
break;
// Note-based syntax disabled
mmd_export_token_tree_html(out, source, t->child, scratch);
}
+
break;
+
case PAIR_BRACKET_VARIABLE:
temp_char = text_inside_pair(source, t);
temp_char2 = extract_metadata(scratch, temp_char);
- if (temp_char2)
+ if (temp_char2) {
mmd_print_string_html(out, temp_char2, false);
- else
+ } else {
mmd_export_token_tree_html(out, source, t->child, scratch);
+ }
// Don't free temp_char2 (it belongs to meta *)
free(temp_char);
break;
+
case PAIR_CRITIC_ADD:
+
// Ignore if we're rejecting
- if (scratch->extensions & EXT_CRITIC_REJECT)
+ if (scratch->extensions & EXT_CRITIC_REJECT) {
break;
+ }
+
if (scratch->extensions & EXT_CRITIC) {
t->child->type = TEXT_EMPTY;
t->child->mate->type = TEXT_EMPTY;
+
if (scratch->extensions & EXT_CRITIC_ACCEPT) {
mmd_export_token_tree_html(out, source, t->child, scratch);
} else {
} else {
mmd_export_token_tree_html(out, source, t->child, scratch);
}
+
break;
+
case PAIR_CRITIC_DEL:
+
// Ignore if we're accepting
- if (scratch->extensions & EXT_CRITIC_ACCEPT)
+ if (scratch->extensions & EXT_CRITIC_ACCEPT) {
break;
+ }
+
if (scratch->extensions & EXT_CRITIC) {
t->child->type = TEXT_EMPTY;
t->child->mate->type = TEXT_EMPTY;
+
if (scratch->extensions & EXT_CRITIC_REJECT) {
mmd_export_token_tree_html(out, source, t->child, scratch);
} else {
} else {
mmd_export_token_tree_html(out, source, t->child, scratch);
}
+
break;
+
case PAIR_CRITIC_COM:
+
// Ignore if we're rejecting or accepting
if ((scratch->extensions & EXT_CRITIC_REJECT) ||
- (scratch->extensions & EXT_CRITIC_ACCEPT))
+ (scratch->extensions & EXT_CRITIC_ACCEPT)) {
break;
+ }
+
if (scratch->extensions & EXT_CRITIC) {
t->child->type = TEXT_EMPTY;
t->child->mate->type = TEXT_EMPTY;
} else {
mmd_export_token_tree_html(out, source, t->child, scratch);
}
+
break;
+
case PAIR_CRITIC_HI:
+
// Ignore if we're rejecting or accepting
if ((scratch->extensions & EXT_CRITIC_REJECT) ||
- (scratch->extensions & EXT_CRITIC_ACCEPT))
+ (scratch->extensions & EXT_CRITIC_ACCEPT)) {
break;
+ }
+
if (scratch->extensions & EXT_CRITIC) {
t->child->type = TEXT_EMPTY;
t->child->mate->type = TEXT_EMPTY;
} else {
mmd_export_token_tree_html(out, source, t->child, scratch);
}
+
break;
+
case CRITIC_SUB_DIV_A:
print_const("~");
break;
+
case CRITIC_SUB_DIV_B:
print_const(">");
break;
+
case PAIR_CRITIC_SUB_DEL:
if ((scratch->extensions & EXT_CRITIC) &&
(t->next) &&
(t->next->type == PAIR_CRITIC_SUB_ADD)) {
t->child->type = TEXT_EMPTY;
t->child->mate->type = TEXT_EMPTY;
+
if (scratch->extensions & EXT_CRITIC_ACCEPT) {
} else if (scratch->extensions & EXT_CRITIC_REJECT) {
} else {
mmd_export_token_tree_html(out, source, t->child, scratch);
}
+
break;
+
case PAIR_CRITIC_SUB_ADD:
if ((scratch->extensions & EXT_CRITIC) &&
(t->prev) &&
(t->prev->type == PAIR_CRITIC_SUB_DEL)) {
t->child->type = TEXT_EMPTY;
t->child->mate->type = TEXT_EMPTY;
+
if (scratch->extensions & EXT_CRITIC_REJECT) {
} else if (scratch->extensions & EXT_CRITIC_ACCEPT) {
} else {
mmd_export_token_tree_html(out, source, t->child, scratch);
}
+
break;
+
case PAIR_HTML_COMMENT:
print_token(t);
break;
+
case PAIR_MATH:
print_const("<span class=\"math\">");
mmd_export_token_tree_html_raw(out, source, t->child, scratch);
print_const("</span>");
break;
+
case PAIR_EMPH:
case PAIR_PAREN:
case PAIR_QUOTE_DOUBLE:
case PAIR_UL:
mmd_export_token_tree_html(out, source, t->child, scratch);
break;
+
case PAREN_LEFT:
print_char('(');
break;
+
case PAREN_RIGHT:
print_char(')');
break;
+
case PIPE:
print_token(t);
break;
+
case PLUS:
print_token(t);
break;
+
case QUOTE_SINGLE:
- if ((t->mate == NULL) || (!(scratch->extensions & EXT_SMART)))
+ if ((t->mate == NULL) || (!(scratch->extensions & EXT_SMART))) {
print_const("'");
- else
+ } else {
(t->start < t->mate->start) ? ( print_localized(QUOTE_LEFT_SINGLE) ) : ( print_localized(QUOTE_RIGHT_SINGLE) );
+ }
+
break;
+
case QUOTE_DOUBLE:
- if ((t->mate == NULL) || (!(scratch->extensions & EXT_SMART)))
+ if ((t->mate == NULL) || (!(scratch->extensions & EXT_SMART))) {
print_const(""");
- else
+ } else {
(t->start < t->mate->start) ? ( print_localized(QUOTE_LEFT_DOUBLE) ) : ( print_localized(QUOTE_RIGHT_DOUBLE) );
+ }
+
break;
+
case QUOTE_RIGHT_ALT:
- if ((t->mate == NULL) || (!(scratch->extensions & EXT_SMART)))
+ if ((t->mate == NULL) || (!(scratch->extensions & EXT_SMART))) {
print_const("''");
- else
+ } else {
print_localized(QUOTE_RIGHT_DOUBLE);
+ }
+
break;
+
case SLASH:
case STAR:
print_token(t);
break;
+
case STRONG_START:
print_const("<strong>");
break;
+
case STRONG_STOP:
print_const("</strong>");
break;
+
case SUBSCRIPT:
if (t->mate) {
(t->start < t->mate->start) ? (print_const("<sub>")) : (print_const("</sub>"));
} else {
print_const("~");
}
+
break;
+
case SUPERSCRIPT:
if (t->mate) {
(t->start < t->mate->start) ? (print_const("<sup>")) : (print_const("</sup>"));
} else {
print_const("^");
}
+
break;
+
case TABLE_CELL:
if (scratch->in_table_header) {
print_const("\t<th");
} else {
print_const("\t<td");
}
+
switch (scratch->table_alignment[scratch->table_cell_count]) {
case 'l':
case 'L':
print_const(" style=\"text-align:left;\"");
break;
+
case 'r':
case 'R':
print_const(" style=\"text-align:right;\"");
break;
+
case 'c':
case 'C':
print_const(" style=\"text-align:center;\"");
break;
}
+
if (t->next && t->next->type == TABLE_DIVIDER) {
if (t->next->len > 1) {
printf(" colspan=\"%d\"", t->next->len);
}
}
+
print_const(">");
mmd_export_token_tree_html(out, source, t->child, scratch);
+
if (scratch->in_table_header) {
print_const("</th>\n");
} else {
print_const("</td>\n");
}
- if (t->next)
+
+ if (t->next) {
scratch->table_cell_count += t->next->len;
- else
+ } else {
scratch->table_cell_count++;
+ }
break;
+
case TABLE_DIVIDER:
break;
+
case TABLE_ROW:
print_const("<tr>\n");
scratch->table_cell_count = 0;
mmd_export_token_tree_html(out, source, t->child, scratch);
print_const("</tr>\n");
break;
+
case TEXT_LINEBREAK:
if (t->next) {
print_const("<br />\n");
scratch->padded = 1;
}
+
break;
+
case CODE_FENCE:
case TEXT_EMPTY:
case MANUAL_LABEL:
break;
+
case TEXT_NL:
- if (t->next)
+ if (t->next) {
print_char('\n');
+ }
+
break;
+
case RAW_FILTER_LEFT:
case TEXT_BACKSLASH:
case TEXT_BRACE_LEFT:
case TOC:
print_token(t);
break;
+
case UL:
print_token(t);
break;
+
default:
fprintf(stderr, "Unknown token type: %d (%lu:%lu)\n", t->type, t->start, t->len);
token_describe(t, source);
void mmd_export_token_html_raw(DString * out, const char * source, token * t, scratch_pad * scratch) {
- if (t == NULL)
+ if (t == NULL) {
return;
+ }
switch (t->type) {
case BACKTICK:
print_token(t);
break;
+
case AMPERSAND:
print_const("&");
break;
+
case AMPERSAND_LONG:
print_const("&amp;");
break;
+
case ANGLE_RIGHT:
print_const(">");
break;
+
case ANGLE_LEFT:
print_const("<");
break;
+
case ESCAPED_CHARACTER:
print_const("\\");
mmd_print_char_html(out, source[t->start + 1], false);
break;
+
case HTML_ENTITY:
print_const("&");
d_string_append_c_array(out, &(source[t->start + 1]), t->len - 1);
break;
+
case MATH_BRACKET_OPEN:
print_const("\\[");
break;
+
case MATH_BRACKET_CLOSE:
print_const("\\]");
break;
+
case MATH_DOLLAR_SINGLE:
if (t->mate) {
(t->start < t->mate->start) ? ( print_const("\\(") ) : ( print_const("\\)") );
} else {
print_const("$");
}
+
break;
+
case MATH_DOLLAR_DOUBLE:
if (t->mate) {
(t->start < t->mate->start) ? ( print_const("\\[") ) : ( print_const("\\]") );
} else {
print_const("$$");
}
+
break;
+
case MATH_PAREN_OPEN:
print_const("\\(");
break;
+
case MATH_PAREN_CLOSE:
print_const("\\)");
break;
+
case QUOTE_DOUBLE:
print_const(""");
break;
+
case CODE_FENCE:
- if (t->next)
+ if (t->next) {
t->next->type = TEXT_EMPTY;
+ }
+
case TEXT_EMPTY:
break;
+
default:
- if (t->child)
+ if (t->child) {
mmd_export_token_tree_html_raw(out, source, t->child, scratch);
- else
+ } else {
print_token(t);
+ }
+
break;
}
}
print_const("<!DOCTYPE html>\n<html xmlns=\"http://www.w3.org/1999/xhtml\"");
HASH_FIND_STR(scratch->meta_hash, "language", m);
+
if (m) {
printf(" lang=\"%s\"", m->value);
} else {
case LC_ES:
print_const(" lang=\"es\"");
break;
+
case LC_DE:
print_const(" lang=\"de\"");
break;
+
case LC_FR:
print_const(" lang=\"fr\"");
break;
+
case LC_NL:
print_const(" lang=\"nl\"");
break;
+
case LC_SV:
print_const(" lang=\"sv\"");
break;
+
default:
print_const(" lang=\"en\"");
}
}
+
print_const(">\n<head>\n\t<meta charset=\"utf-8\"/>\n");
// Iterate over metadata keys
} else if (strcmp(m->key, "bibtex") == 0) {
} else if (strcmp(m->key, "css") == 0) {
print_const("\t<link type=\"text/css\" rel=\"stylesheet\" href=\"");
+
if (scratch->store_assets) {
store_asset(scratch, m->value);
asset * a = extract_asset(scratch, m->value);
} else {
mmd_print_string_html(out, m->value, false);
}
+
print_const("\"/>\n");
} else if (strcmp(m->key, "htmlfooter") == 0) {
} else if (strcmp(m->key, "htmlheader") == 0) {
// We need to know which block is the last one in the footnote
while(content) {
- if (content->type == BLOCK_PARA)
+ if (content->type == BLOCK_PARA) {
scratch->footnote_para_counter++;
+ }
content = content->next;
}
// We need to know which block is the last one in the footnote
while(content) {
- if (content->type == BLOCK_PARA)
+ if (content->type == BLOCK_PARA) {
scratch->footnote_para_counter++;
+ }
content = content->next;
}
// We need to know which block is the last one in the footnote
while(content) {
- if (content->type == BLOCK_PARA)
+ if (content->type == BLOCK_PARA) {
scratch->footnote_para_counter++;
+ }
content = content->next;
}
case '\\':
print_const("\\textbackslash{}");
break;
+
case '~':
print_const("\\ensuremath{\\sim}");
break;
+
case '/':
print_const("\\slash ");
break;
+
case '^':
print_const("\\^{}");
break;
+
case '<':
case '>':
print_char('$');
print_char(c);
print_char('$');
break;
+
case '|':
print_const("\\textbar{}");
break;
+
case '#':
case '{':
case '}':
case '&':
case '_':
print_char('\\');
+
default:
print_char(c);
break;
void mmd_print_string_latex(DString * out, const char * str) {
- if (str == NULL)
+ if (str == NULL) {
return;
+ }
while (*str != '\0') {
mmd_print_char_latex(out, *str);
case DASH_N:
print_const("--");
break;
+
case DASH_M:
print_const("---");
break;
+
case ELLIPSIS:
print_const("{\\ldots}");
break;
+
case APOSTROPHE:
print_const("'");
break;
+
case QUOTE_LEFT_SINGLE:
switch (scratch->quotes_lang) {
case SWEDISH:
print_const("'");
break;
+
case FRENCH:
print_const("'");
break;
+
case GERMAN:
print_const("‚");
break;
+
case GERMANGUILL:
print_const("›");
break;
+
default:
print_const("`");
}
+
break;
+
case QUOTE_RIGHT_SINGLE:
switch (scratch->quotes_lang) {
case GERMAN:
print_const("`");
break;
+
case GERMANGUILL:
print_const("‹");
break;
+
default:
print_const("'");
}
+
break;
+
case QUOTE_LEFT_DOUBLE:
switch (scratch->quotes_lang) {
case DUTCH:
case GERMAN:
print_const("„");
break;
+
case GERMANGUILL:
print_const("»");
break;
+
case FRENCH:
print_const("«");
break;
+
case SWEDISH:
print_const("''");
break;
+
default:
print_const("``");
}
+
break;
+
case QUOTE_RIGHT_DOUBLE:
switch (scratch->quotes_lang) {
case GERMAN:
print_const("``");
break;
+
case GERMANGUILL:
print_const("«");
break;
+
case FRENCH:
print_const("»");
break;
+
case SWEDISH:
case DUTCH:
default:
print_const("''");
}
+
break;
}
}
} else {
printf("\\autoref{%s}", &(link->url)[1]);
}
+
return;
} else {
printf("\\href{%s}", link->url);
}
- } else
+ } else {
print_const("\\href{}");
+ }
print_const("{");
result = my_strdup(original);
- for (i = 0; result[i]; i++)
+ for (i = 0; result[i]; i++) {
result[i] = tolower(result[i]);
+ }
if (strstr(&result[strlen(result)-2],"px")) {
result[strlen(result)-2] = '\0';
float temp_float;
// Compatibility mode doesn't allow figures
- if (scratch->extensions & EXT_COMPATIBILITY)
+ if (scratch->extensions & EXT_COMPATIBILITY) {
is_figure = false;
+ }
if (is_figure) {
print_const("\\begin{figure}[htbp]\n\\centering\n");
print_const("keepaspectratio,width=\\textwidth,height=0.75\\textheight");
}
- if (link->url)
+ if (link->url) {
printf("]{%s}", link->url);
- else
+ } else {
print_const("]{}");
+ }
if (is_figure) {
print_const("\n");
+
if (text) {
print_const("\\caption{");
mmd_export_token_tree_latex(out, source, text->child, scratch);
print_const("}\n");
}
+
if (link->label) {
// \todo: Need to decide on approach to id's
char * label = label_from_token(source, link->label);
if (*counter < scratch->header_stack->size - 1) {
next = stack_peek_index(scratch->header_stack, *counter + 1);
next_level = next->type - BLOCK_H1 + 1;
+
if (next_level > entry_level) {
// This entry has children
(*counter)++;
void mmd_export_token_latex(DString * out, const char * source, token * t, scratch_pad * scratch) {
- if (t == NULL)
+ if (t == NULL) {
return;
+ }
short temp_short;
short temp_short2;
case AMPERSAND_LONG:
print_const("\\&");
break;
+
case ANGLE_LEFT:
print_const("<");
break;
+
case ANGLE_RIGHT:
print_const(">");
break;
+
case APOSTROPHE:
if (!(scratch->extensions & EXT_SMART)) {
print_token(t);
} else {
print_localized(APOSTROPHE);
}
+
break;
+
case BACKTICK:
print_token(t);
break;
+
case BLOCK_BLOCKQUOTE:
pad(out, 2, scratch);
print_const("\\begin{quote}\n");
print_const("\\end{quote}");
scratch->padded = 0;
break;
+
case BLOCK_CODE_FENCED:
pad(out, 2, scratch);
case LINE_FENCE_BACKTICK_5:
temp_token = t->child->tail;
break;
+
default:
temp_token = NULL;
}
+
if (temp_token) {
d_string_append_c_array(out, &source[t->child->next->start], temp_token->start - t->child->next->start);
scratch->padded = 1;
free(temp_char);
break;
}
+
printf("\\begin{lstlisting}[language=%s]\n", temp_char);
} else {
print_const("\\begin{verbatim}\n");
} else {
print_const("\\end{verbatim}");
}
+
scratch->padded = 0;
break;
+
case BLOCK_CODE_INDENTED:
pad(out, 2, scratch);
print_const("\\begin{verbatim}\n");
print_const("\\end{verbatim}");
scratch->padded = 0;
break;
+
case BLOCK_DEFINITION:
pad(out, 2, scratch);
temp_short = scratch->list_is_tight;
- if (!(t->child->next && (t->child->next->type == BLOCK_EMPTY) && t->child->next->next))
+
+ if (!(t->child->next && (t->child->next->type == BLOCK_EMPTY) && t->child->next->next)) {
scratch->list_is_tight = true;
+ }
mmd_export_token_tree_latex(out, source, t->child, scratch);
scratch->padded = 0;
scratch->list_is_tight = temp_short;
break;
+
case BLOCK_DEFLIST:
pad(out, 2, scratch);
// Group consecutive definition lists into a single list.
// lemon's LALR(1) parser can't properly handle this (to my understanding).
- if (!(t->prev && (t->prev->type == BLOCK_DEFLIST)))
+ if (!(t->prev && (t->prev->type == BLOCK_DEFLIST))) {
print_const("\\begin{description}\n");
+ }
scratch->padded = 2;
mmd_export_token_tree_latex(out, source, t->child, scratch);
pad(out, 1, scratch);
- if (!(t->next && (t->next->type == BLOCK_DEFLIST)))
+ if (!(t->next && (t->next->type == BLOCK_DEFLIST))) {
print_const("\\end{description}\n");
+ }
scratch->padded = 1;
break;
+
case BLOCK_EMPTY:
break;
+
case BLOCK_H1:
case BLOCK_H2:
case BLOCK_H3:
case BLOCK_SETEXT_1:
case BLOCK_SETEXT_2:
pad(out, 2, scratch);
+
switch (t->type) {
case BLOCK_SETEXT_1:
temp_short = 1;
break;
+
case BLOCK_SETEXT_2:
temp_short = 2;
break;
+
default:
temp_short = t->type - BLOCK_H1 + 1;
}
case 1:
print_const("\\part{");
break;
+
case 2:
print_const("\\chapter{");
break;
+
case 3:
print_const("\\section{");
break;
+
case 4:
print_const("\\subsection{");
break;
+
case 5:
print_const("\\subsubsection{");
break;
+
case 6:
print_const("\\paragraph{");
break;
+
case 7:
print_const("\\subparagraph{");
break;
print_const("}");
} else {
temp_token = manual_label_from_header(t, source);
+
if (temp_token) {
temp_char = label_from_token(source, temp_token);
} else {
temp_char = label_from_token(source, t);
}
+
printf("}\n\\label{%s}", temp_char);
free(temp_char);
}
+
scratch->padded = 0;
break;
+
case BLOCK_HR:
pad(out, 2, scratch);
print_const("\\begin{center}\\rule{3in}{0.4pt}\\end{center}");
scratch->padded = 0;
break;
+
case BLOCK_HTML:
// Don't print HTML
break;
+
case BLOCK_LIST_BULLETED_LOOSE:
case BLOCK_LIST_BULLETED:
temp_short = scratch->list_is_tight;
+
switch (t->type) {
case BLOCK_LIST_BULLETED_LOOSE:
scratch->list_is_tight = false;
break;
+
case BLOCK_LIST_BULLETED:
scratch->list_is_tight = true;
break;
}
+
pad(out, 2, scratch);
print_const("\\begin{itemize}");
scratch->padded = 1;
scratch->padded = 0;
scratch->list_is_tight = temp_short;
break;
+
case BLOCK_LIST_ENUMERATED_LOOSE:
case BLOCK_LIST_ENUMERATED:
temp_short = scratch->list_is_tight;
+
switch (t->type) {
case BLOCK_LIST_ENUMERATED_LOOSE:
scratch->list_is_tight = false;
break;
+
case BLOCK_LIST_ENUMERATED:
scratch->list_is_tight = true;
break;
}
+
pad(out, 2, scratch);
print_const("\\begin{enumerate}");
scratch->padded = 1;
scratch->padded = 0;
scratch->list_is_tight = temp_short;
break;
+
case BLOCK_LIST_ITEM:
pad(out, 2, scratch);
print_const("\\item{} ");
mmd_export_token_tree_latex(out, source, t->child, scratch);
scratch->padded = 0;
break;
+
case BLOCK_LIST_ITEM_TIGHT:
pad(out, 2, scratch);
print_const("\\item{} ");
mmd_export_token_tree_latex(out, source, t->child, scratch);
scratch->padded = 0;
break;
+
case BLOCK_META:
break;
+
case BLOCK_PARA:
pad(out, 2, scratch);
mmd_export_token_tree_latex(out, source, t->child, scratch);
scratch->padded = 0;
break;
+
case BLOCK_TABLE:
pad(out, 2, scratch);
scratch->skip_token = temp_short;
scratch->padded = 0;
break;
+
case BLOCK_TABLE_HEADER:
pad(out, 2, scratch);
case 'C':
print_char(scratch->table_alignment[i]);
break;
+
case 'N':
print_char('L');
break;
+
default:
print_char('l');
break;
scratch->padded = 1;
break;
+
case BLOCK_TABLE_SECTION:
pad(out, 2, scratch);
scratch->padded = 2;
print_const("\\bottomrule");
scratch->padded = 0;
break;
+
case BLOCK_TERM:
pad(out, 2, scratch);
print_const("\\item[");
print_const("]");
scratch->padded = 0;
break;
+
case BLOCK_TOC:
pad(out, 2, scratch);
print_const("\\tableofcontents");
scratch->padded = 0;
break;
+
case BRACE_DOUBLE_LEFT:
print_const("\\{\\{");
break;
+
case BRACE_DOUBLE_RIGHT:
print_const("\\}\\}");
break;
+
case BRACKET_LEFT:
print_const("[");
break;
+
case BRACKET_ABBREVIATION_LEFT:
print_const("[>");
break;
+
case BRACKET_CITATION_LEFT:
print_const("[#");
break;
+
case BRACKET_FOOTNOTE_LEFT:
print_const("[^");
break;
+
case BRACKET_GLOSSARY_LEFT:
print_const("[?");
break;
+
case BRACKET_IMAGE_LEFT:
print_const("![");
break;
+
case BRACKET_VARIABLE_LEFT:
print_const("[\%");
break;
+
case BRACKET_RIGHT:
print_const("]");
break;
+
case CODE_FENCE:
break;
+
case COLON:
print_const(":");
break;
+
case CRITIC_ADD_OPEN:
print_const("\\{++");
break;
+
case CRITIC_ADD_CLOSE:
print_const("++\\}");
break;
+
case CRITIC_COM_OPEN:
print_const("\\{>>");
break;
+
case CRITIC_COM_CLOSE:
print_const("<<\\}");
break;
+
case CRITIC_DEL_OPEN:
print_const("\\{--");
break;
+
case CRITIC_DEL_CLOSE:
print_const("--\\}");
break;
+
case CRITIC_HI_OPEN:
print_const("\\{==");
break;
+
case CRITIC_HI_CLOSE:
print_const("==\\}");
break;
+
case CRITIC_SUB_OPEN:
print_const("\\{~~");
break;
+
case CRITIC_SUB_DIV:
print_const("~>");
break;
+
case CRITIC_SUB_CLOSE:
print_const("~~\\}");
break;
+
case DASH_M:
if (!(scratch->extensions & EXT_SMART)) {
print_token(t);
} else {
print_localized(DASH_M);
}
+
break;
+
case DASH_N:
if (!(scratch->extensions & EXT_SMART)) {
print_token(t);
} else {
print_localized(DASH_N);
}
+
break;
+
case DOC_START_TOKEN:
mmd_export_token_tree_latex(out, source, t->child, scratch);
break;
+
case ELLIPSIS:
if (!(scratch->extensions & EXT_SMART)) {
print_token(t);
} else {
print_localized(ELLIPSIS);
}
+
break;
+
case EMPH_START:
print_const("\\emph{");
break;
+
case EMPH_STOP:
print_const("}");
break;
+
case EQUAL:
print_const("=");
break;
+
case ESCAPED_CHARACTER:
if (!(scratch->extensions & EXT_COMPATIBILITY) &&
(source[t->start + 1] == ' ')) {
} else {
mmd_print_char_latex(out, source[t->start + 1]);
}
+
break;
+
case HASH1:
case HASH2:
case HASH3:
mmd_print_char_latex(out, source[t->start + i]);
}
}
+
break;
+
case HTML_ENTITY:
if (source[t->start + 1] == '#') {
print_const("\\&\\#");
print_const("\\");
print_token(t);
}
+
break;
+
case HTML_COMMENT_START:
if (!(scratch->extensions & EXT_SMART)) {
print_const("<!--");
print_const("<!");
print_localized(DASH_N);
}
+
break;
+
case HTML_COMMENT_STOP:
if (!(scratch->extensions & EXT_SMART)) {
print_const("-->");
print_localized(DASH_N);
print_const(">");
}
+
break;
+
case INDENT_SPACE:
print_char(' ');
break;
+
case INDENT_TAB:
print_char('\t');
break;
+
case LINE_LIST_BULLETED:
case LINE_LIST_ENUMERATED:
mmd_export_token_tree_latex(out, source, t->child, scratch);
break;
+
case LINE_SETEXT_2:
case MANUAL_LABEL:
case MARKER_BLOCKQUOTE:
case MARKER_LIST_BULLET:
case MARKER_LIST_ENUMERATOR:
break;
+
case MATH_BRACKET_OPEN:
print_const("\\[");
break;
+
case MATH_BRACKET_CLOSE:
print_const("\\]");
break;
+
case MATH_DOLLAR_SINGLE:
- if (t->mate)
+ if (t->mate) {
print_const("$");
- else
+ } else {
print_const("\\$");
+ }
+
break;
+
case MATH_DOLLAR_DOUBLE:
- if (t->mate)
+ if (t->mate) {
print_const("$$");
- else
+ } else {
print_const("\\$\\$");
+ }
+
break;
+
case MATH_PAREN_OPEN:
print_const("\\(");
break;
+
case MATH_PAREN_CLOSE:
print_const("\\)");
break;
+
case NON_INDENT_SPACE:
print_char(' ');
break;
+
case PAIR_ANGLE:
temp_char = url_accept(source, t->start + 1, t->len - 2, NULL, true);
free(temp_char);
break;
+
case PAIR_BACKTICK:
+
// Strip leading whitespace
switch (t->child->next->type) {
case TEXT_NL:
case NON_INDENT_SPACE:
t->child->next->type = TEXT_EMPTY;
break;
+
case TEXT_PLAIN:
while (t->child->next->len && char_is_whitespace(source[t->child->next->start])) {
t->child->next->start++;
t->child->next->len--;
}
+
break;
}
case NON_INDENT_SPACE:
t->child->mate->prev->type = TEXT_EMPTY;
break;
+
case TEXT_PLAIN:
while (t->child->mate->prev->len && char_is_whitespace(source[t->child->mate->prev->start + t->child->mate->prev->len - 1])) {
t->child->mate->prev->len--;
}
+
break;
}
+
t->child->type = TEXT_EMPTY;
t->child->mate->type = TEXT_EMPTY;
if (raw_filter_matches(t->next, source, FORMAT_LATEX)) {
d_string_append_c_array(out, &(source[t->child->start + t->child->len]), t->child->mate->start - t->child->start - t->child->len);
}
+
// Skip over PAIR_RAW_FILTER
scratch->skip_token = 1;
break;
mmd_export_token_tree_latex_tt(out, source, t->child, scratch);
print_const("}");
break;
+
case PAIR_BRACE:
case PAIR_BRACES:
mmd_export_token_tree_latex(out, source, t->child, scratch);
break;
+
case PAIR_BRACKET:
if ((scratch->extensions & EXT_NOTES) &&
(t->next && t->next->type == PAIR_BRACKET_CITATION)) {
temp_token = temp_token->next;
}
- if (temp_token && temp_token->type == TEXT_NL)
+ if (temp_token && temp_token->type == TEXT_NL) {
temp_token = temp_token->next;
+ }
- if (temp_token && temp_token->type == TEXT_LINEBREAK)
+ if (temp_token && temp_token->type == TEXT_LINEBREAK) {
temp_token = temp_token->next;
+ }
if (t->prev || temp_token) {
mmd_export_image_latex(out, source, t, temp_link, scratch, false);
// No links exist, so treat as normal
mmd_export_token_tree_latex(out, source, t->child, scratch);
break;
+
case PAIR_BRACKET_ABBREVIATION:
+
// Which might also be an "auto-tagged" abbreviation
if (scratch->extensions & EXT_NOTES) {
// Note-based syntax enabled
// Note-based syntax disabled
mmd_export_token_tree_latex(out, source, t->child, scratch);
}
+
break;
+
case PAIR_BRACKET_CITATION:
parse_citation:
temp_bool = true; // Track whether this is regular vs 'not cited'
// Are we citep vs citet?
temp_char2 = clean_inside_pair(source, t, false);
+
if (temp_char2[strlen(temp_char2) - 1] == ';') {
temp_bool = true; // citet
temp_char2[strlen(temp_char2) - 1] = '\0';
// Are there two arguments in the locator?
// e.g. `[foo\]\[bar]`
temp_char3 = strstr(temp_char, "\\]\\[");
+
if (temp_char3) {
// Convert `\]\[` to `][`
temp_char[temp_char3 - temp_char] = ']';
// Note-based syntax disabled
mmd_export_token_tree_latex(out, source, t->child, scratch);
}
+
break;
+
case PAIR_BRACKET_FOOTNOTE:
if (scratch->extensions & EXT_NOTES) {
// Note-based syntax enabled
// Note-based syntax disabled
mmd_export_token_tree_latex(out, source, t->child, scratch);
}
+
break;
+
case PAIR_BRACKET_GLOSSARY:
+
// Which might also be an "auto-tagged" glossary
if (scratch->extensions & EXT_NOTES) {
// Note-based syntax enabled
// This instance is not properly formed
print_const("[?");
- if (t->child)
+ if (t->child) {
mmd_export_token_tree_latex(out, source, t->child->next, scratch);
- else
+ } else {
print_token(t);
+ }
print_const("]");
break;
// Note-based syntax disabled
mmd_export_token_tree_latex(out, source, t->child, scratch);
}
+
break;
+
case PAIR_BRACKET_VARIABLE:
temp_char = text_inside_pair(source, t);
temp_char2 = extract_metadata(scratch, temp_char);
- if (temp_char2)
+ if (temp_char2) {
mmd_print_string_latex(out, temp_char2);
- else
+ } else {
mmd_export_token_tree_latex(out, source, t->child, scratch);
+ }
// Don't free temp_char2 (it belongs to meta *)
free(temp_char);
break;
+
case PAIR_CRITIC_ADD:
+
// Ignore if we're rejecting
- if (scratch->extensions & EXT_CRITIC_REJECT)
+ if (scratch->extensions & EXT_CRITIC_REJECT) {
break;
+ }
+
if (scratch->extensions & EXT_CRITIC) {
t->child->type = TEXT_EMPTY;
t->child->mate->type = TEXT_EMPTY;
+
if (scratch->extensions & EXT_CRITIC_ACCEPT) {
mmd_export_token_tree_latex(out, source, t->child, scratch);
} else {
} else {
mmd_export_token_tree_latex(out, source, t->child, scratch);
}
+
break;
+
case PAIR_CRITIC_DEL:
+
// Ignore if we're accepting
- if (scratch->extensions & EXT_CRITIC_ACCEPT)
+ if (scratch->extensions & EXT_CRITIC_ACCEPT) {
break;
+ }
+
if (scratch->extensions & EXT_CRITIC) {
t->child->type = TEXT_EMPTY;
t->child->mate->type = TEXT_EMPTY;
+
if (scratch->extensions & EXT_CRITIC_REJECT) {
mmd_export_token_tree_latex(out, source, t->child, scratch);
} else {
} else {
mmd_export_token_tree_latex(out, source, t->child, scratch);
}
+
break;
+
case PAIR_CRITIC_COM:
+
// Ignore if we're rejecting or accepting
if ((scratch->extensions & EXT_CRITIC_REJECT) ||
- (scratch->extensions & EXT_CRITIC_ACCEPT))
+ (scratch->extensions & EXT_CRITIC_ACCEPT)) {
break;
+ }
+
if (scratch->extensions & EXT_CRITIC) {
t->child->type = TEXT_EMPTY;
t->child->mate->type = TEXT_EMPTY;
} else {
mmd_export_token_tree_latex(out, source, t->child, scratch);
}
+
break;
+
case PAIR_CRITIC_HI:
+
// Ignore if we're rejecting or accepting
if ((scratch->extensions & EXT_CRITIC_REJECT) ||
- (scratch->extensions & EXT_CRITIC_ACCEPT))
+ (scratch->extensions & EXT_CRITIC_ACCEPT)) {
break;
+ }
+
if (scratch->extensions & EXT_CRITIC) {
t->child->type = TEXT_EMPTY;
t->child->mate->type = TEXT_EMPTY;
} else {
mmd_export_token_tree_latex(out, source, t->child, scratch);
}
+
break;
+
case CRITIC_SUB_DIV_A:
print_const("~");
break;
+
case CRITIC_SUB_DIV_B:
print_const(">");
break;
+
case PAIR_CRITIC_SUB_DEL:
if ((scratch->extensions & EXT_CRITIC) &&
(t->next) &&
(t->next->type == PAIR_CRITIC_SUB_ADD)) {
t->child->type = TEXT_EMPTY;
t->child->mate->type = TEXT_EMPTY;
+
if (scratch->extensions & EXT_CRITIC_ACCEPT) {
} else if (scratch->extensions & EXT_CRITIC_REJECT) {
} else {
mmd_export_token_tree_latex(out, source, t->child, scratch);
}
+
break;
+
case PAIR_CRITIC_SUB_ADD:
if ((scratch->extensions & EXT_CRITIC) &&
(t->prev) &&
(t->prev->type == PAIR_CRITIC_SUB_DEL)) {
t->child->type = TEXT_EMPTY;
t->child->mate->type = TEXT_EMPTY;
+
if (scratch->extensions & EXT_CRITIC_REJECT) {
} else if (scratch->extensions & EXT_CRITIC_ACCEPT) {
} else {
mmd_export_token_tree_latex(out, source, t->child, scratch);
}
+
break;
+
case PAIR_HTML_COMMENT:
break;
+
case PAIR_MATH:
- if (strncmp(&source[t->child->start + t->child->len], "\\begin", 6) != 0)
+ if (strncmp(&source[t->child->start + t->child->len], "\\begin", 6) != 0) {
mmd_export_token_latex(out, source, t->child, scratch);
+ }
// Math is raw LaTeX -- use string itself rather than interior tokens
d_string_append_c_array(out, &(source[t->child->start + t->child->len]), t->child->mate->start - t->child->start - t->child->len);
- if (strncmp(&source[t->child->start + t->child->len], "\\begin", 6) != 0)
+ if (strncmp(&source[t->child->start + t->child->len], "\\begin", 6) != 0) {
mmd_export_token_latex(out, source, t->child->mate, scratch);
+ }
+
break;
+
case PAIR_EMPH:
case PAIR_PAREN:
case PAIR_QUOTE_DOUBLE:
case PAIR_UL:
mmd_export_token_tree_latex(out, source, t->child, scratch);
break;
+
case PAREN_LEFT:
print_const("(");
break;
+
case PAREN_RIGHT:
print_const(")");
break;
+
case PIPE:
for (int i = 0; i < t->len; ++i) {
print_const("\\textbar{}");
}
+
break;
+
case PLUS:
print_token(t);
break;
+
case QUOTE_SINGLE:
- if ((t->mate == NULL) || (!(scratch->extensions & EXT_SMART)))
+ if ((t->mate == NULL) || (!(scratch->extensions & EXT_SMART))) {
print_const("'");
- else
+ } else {
(t->start < t->mate->start) ? ( print_localized(QUOTE_LEFT_SINGLE) ) : ( print_localized(QUOTE_RIGHT_SINGLE) );
+ }
+
break;
+
case QUOTE_DOUBLE:
- if ((t->mate == NULL) || (!(scratch->extensions & EXT_SMART)))
+ if ((t->mate == NULL) || (!(scratch->extensions & EXT_SMART))) {
print_const("''");
- else
+ } else {
(t->start < t->mate->start) ? ( print_localized(QUOTE_LEFT_DOUBLE) ) : ( print_localized(QUOTE_RIGHT_DOUBLE) );
+ }
+
break;
+
case QUOTE_RIGHT_ALT:
- if ((t->mate == NULL) || (!(scratch->extensions & EXT_SMART)))
+ if ((t->mate == NULL) || (!(scratch->extensions & EXT_SMART))) {
print_const("''");
- else
+ } else {
print_localized(QUOTE_RIGHT_DOUBLE);
+ }
+
break;
+
case SLASH:
print_const("\\slash ");
break;
+
case STAR:
print_token(t);
break;
+
case STRONG_START:
print_const("\\textbf{");
break;
+
case STRONG_STOP:
print_const("}");
break;
+
case SUBSCRIPT:
if (t->mate) {
(t->start < t->mate->start) ? (print_const("\\textsubscript{")) : (print_const("}"));
} else {
print_const("\\ensuremath{\\sim}");
}
+
break;
+
case SUPERSCRIPT:
if (t->mate) {
(t->start < t->mate->start) ? (print_const("\\textsuperscript{")) : (print_const("}"));
} else {
print_const("\\^{}");
}
+
break;
+
case TABLE_CELL:
if (t->next && t->next->type == TABLE_DIVIDER) {
if (t->next->len > 1) {
printf("\\multicolumn{%lu}{",t->next->len);
+
switch (scratch->table_alignment[scratch->table_cell_count]) {
case 'l':
case 'L':
print_const("l}{");
break;
+
case 'r':
case 'R':
print_const("r}{");
break;
+
default:
print_const("c}{");
break;
mmd_export_token_tree_latex(out, source, t->child, scratch);
if (t->next && t->next->type == TABLE_DIVIDER) {
- if (t->next->len > 1)
+ if (t->next->len > 1) {
print_const("}");
+ }
}
if (t->next && t->next->type == TABLE_DIVIDER) {
print_const("&");
scratch->table_cell_count += t->next->len;
}
- } else
+ } else {
scratch->table_cell_count++;
+ }
break;
+
case TABLE_DIVIDER:
break;
+
case TABLE_ROW:
scratch->table_cell_count = 0;
mmd_export_token_tree_latex(out, source, t->child, scratch);
print_const("\\\\\n");
break;
+
case TEXT_BACKSLASH:
print_const("\\textbackslash{}");
break;
+
case TEXT_EMPTY:
break;
+
case TEXT_HASH:
print_const("\\#");
break;
+
case TEXT_LINEBREAK:
if (t->next) {
print_const("\\\\\n");
scratch->padded = 1;
}
+
break;
+
case TEXT_NL:
- if (t->next)
+ if (t->next) {
print_char('\n');
+ }
+
break;
+
case TEXT_PERCENT:
print_const("\\%");
break;
+
case TEXT_BRACE_LEFT:
case TEXT_BRACE_RIGHT:
print_const("\\");
+
case RAW_FILTER_LEFT:
case TEXT_NUMBER_POSS_LIST:
case TEXT_PERIOD:
case TEXT_PLAIN:
print_token(t);
break;
+
case TOC:
print_const("\\{\\{TOC\\}\\}");
break;
+
case UL:
print_const("\\_");
break;
+
default:
fprintf(stderr, "Unknown token type: %d\n", t->type);
token_describe(t, source);
void mmd_export_token_latex_raw(DString * out, const char * source, token * t, scratch_pad * scratch) {
- if (t == NULL)
+ if (t == NULL) {
return;
+ }
switch (t->type) {
case ESCAPED_CHARACTER:
print_char(source[t->start + 1]);
// mmd_print_char_latex(out, source[t->start + 1]);
break;
+
case HTML_ENTITY:
print_token(t);
break;
+
case CODE_FENCE:
- if (t->next)
+ if (t->next) {
t->next->type = TEXT_EMPTY;
+ }
+
case TEXT_EMPTY:
break;
+
default:
- if (t->child)
+ if (t->child) {
mmd_export_token_tree_latex_raw(out, source, t->child, scratch);
- else
+ } else {
print_token(t);
+ }
+
break;
}
}
void mmd_export_token_latex_tt(DString * out, const char * source, token * t, scratch_pad * scratch) {
- if (t == NULL)
+ if (t == NULL) {
return;
+ }
switch (t->type) {
case AMPERSAND:
case AMPERSAND_LONG:
print_const("\\&");
break;
+
case ANGLE_LEFT:
print_const("<");
break;
+
case ANGLE_RIGHT:
print_const(">");
break;
+
case CRITIC_ADD_OPEN:
print_const("\\{++");
break;
+
case CRITIC_ADD_CLOSE:
print_const("++\\}");
break;
+
case CRITIC_COM_OPEN:
print_const("\\{>>");
break;
+
case CRITIC_COM_CLOSE:
print_const("<<\\}");
break;
+
case CRITIC_DEL_OPEN:
print_const("\\{--");
break;
+
case CRITIC_DEL_CLOSE:
print_const("--\\}");
break;
+
case CRITIC_HI_OPEN:
print_const("\\{==");
break;
+
case CRITIC_HI_CLOSE:
print_const("==\\}");
break;
+
case CRITIC_SUB_OPEN:
print_const("\\{~~");
break;
+
case CRITIC_SUB_DIV:
print_const("~>");
break;
+
case CRITIC_SUB_CLOSE:
print_const("~~\\}");
break;
+
case DASH_N:
if (t->len == 1) {
print_const("-");
} else {
print_const("-{}-");
}
+
break;
+
case DASH_M:
print_const("-{}-{}-");
break;
+
case EMPH_START:
case EMPH_STOP:
if (source[t->start] == '_') {
} else {
print_const("*");
}
+
break;
+
case ESCAPED_CHARACTER:
print_const("\\textbackslash{}");
mmd_print_char_latex(out, source[t->start + 1]);
break;
+
case HTML_ENTITY:
if (source[t->start + 1] == '#') {
print_const("\\&\\#");
print_const("\\");
print_token(t);
}
+
break;
+
case CODE_FENCE:
- if (t->next)
+ if (t->next) {
t->next->type = TEXT_EMPTY;
+ }
+
case TEXT_EMPTY:
break;
+
case SLASH:
print_const("\\slash ");
break;
+
case TEXT_BACKSLASH:
print_const("\\textbackslash{}");
break;
+
case BRACE_DOUBLE_LEFT:
print_const("\\{\\{");
break;
+
case BRACE_DOUBLE_RIGHT:
print_const("\\}\\}");
break;
+
case TEXT_BRACE_LEFT:
print_const("\\{");
break;
+
case TEXT_BRACE_RIGHT:
print_const("\\}");
break;
+
case TOC:
print_const("\\{\\{TOC\\}\\}");
break;
+
case UL:
print_const("\\_");
break;
+
default:
- if (t->child)
+ if (t->child) {
mmd_export_token_tree_latex_tt(out, source, t->child, scratch);
- else
+ } else {
print_token(t);
+ }
+
break;
}
}
mmd_export_token_tree_latex(out, source, f->note->content, scratch);
print_const("}\n\n");
}
+
last_key = f->note->clean_text;
}
meta * m;
m = extract_meta_from_stack(scratch, "latexleader");
+
if (m) {
printf("\\input{%s}\n", m->value);
} else {
mmd_define_glossaries_latex(out, source, scratch);
m = extract_meta_from_stack(scratch, "latexbegin");
+
if (m) {
printf("\\input{%s}\n", m->value);
} else {
void mmd_export_token_memoir(DString * out, const char * source, token * t, scratch_pad * scratch) {
- if (t == NULL)
+ if (t == NULL) {
return;
+ }
char * temp_char = NULL;
case DOC_START_TOKEN:
mmd_export_token_tree_memoir(out, source, t->child, scratch);
break;
+
case BLOCK_CODE_FENCED:
pad(out, 2, scratch);
temp_char = get_fence_language_specifier(t->child->child, source);
+
if (temp_char) {
printf("\\begin{adjustwidth}{2.5em}{2.5em}\n\\begin{lstlisting}[language=%s]\n", temp_char);
} else {
} else {
print_const("\\end{verbatim}\n\\end{adjustwidth}");
}
+
scratch->padded = 0;
break;
+
case BLOCK_CODE_INDENTED:
pad(out, 2, scratch);
print_const("\\begin{adjustwidth}{2.5em}{2.5em}\\begin{verbatim}\n");
print_const("\\end{verbatim}\n\\end{adjustwidth}");
scratch->padded = 0;
break;
+
default:
// Default to LaTeX behavior
mmd_export_token_latex(out, source, t, scratch);
/// Set language and smart quotes language
void mmd_engine_set_language(mmd_engine * e, short language) {
- if (!e)
+ if (!e) {
return;
+ }
e->language = language;
case LC_DE:
e->quotes_lang = GERMAN;
break;
+
case LC_EN:
e->quotes_lang = ENGLISH;
break;
+
case LC_ES:
e->quotes_lang = ENGLISH;
break;
+
case LC_FR:
e->quotes_lang = FRENCH;
break;
+
case LC_NL:
e->quotes_lang = DUTCH;
break;
+
case LC_SV:
e->quotes_lang = SWEDISH;
break;
+
default:
e->quotes_lang = ENGLISH;
}
/// Free an existing MMD Engine
void mmd_engine_free(mmd_engine * e, bool freeDString) {
- if (e == NULL)
+ if (e == NULL) {
return;
+ }
mmd_engine_reset(e);
- if (freeDString)
+ if (freeDString) {
d_string_free(e->dstr, true);
+ }
token_pair_engine_free(e->pairings1);
token_pair_engine_free(e->pairings2);
case INDENT_SPACE:
t = t->next;
break;
+
case TEXT_LINEBREAK:
case TEXT_NL:
return true;
+
default:
return false;
}
/// Determine what sort of line this is
void mmd_assign_line_type(mmd_engine * e, token * line) {
- if (!line)
+ if (!line) {
return;
+ }
if (!line->child) {
line->type = LINE_EMPTY;
if (line->child->type == NON_INDENT_SPACE) {
token_remove_first_child(line);
} else if (line->child->type == TEXT_PLAIN && line->child->len == 1) {
- if (source[line->child->start] == ' ')
+ if (source[line->child->start] == ' ') {
token_remove_first_child(line);
+ }
}
if (line->child == NULL) {
if (line_is_empty(line->child)) {
line->type = LINE_EMPTY;
e->allow_meta = false;
- } else
+ } else {
line->type = LINE_INDENTED_TAB;
+ }
+
break;
+
case INDENT_SPACE:
if (line_is_empty(line->child)) {
line->type = LINE_EMPTY;
e->allow_meta = false;
- } else
+ } else {
line->type = LINE_INDENTED_SPACE;
+ }
+
break;
+
case ANGLE_LEFT:
- if (scan_html_block(&source[line->start]))
+ if (scan_html_block(&source[line->start])) {
line->type = LINE_HTML;
- else
+ } else {
line->type = LINE_PLAIN;
+ }
+
break;
+
case ANGLE_RIGHT:
line->type = LINE_BLOCKQUOTE;
line->child->type = MARKER_BLOCKQUOTE;
break;
+
case BACKTICK:
if (e->extensions & EXT_COMPATIBILITY) {
line->type = LINE_PLAIN;
break;
}
+
scan_len = scan_fence_end(&source[line->child->start]);
+
if (scan_len) {
switch (line->child->len) {
case 3:
line->type = LINE_FENCE_BACKTICK_3;
break;
+
case 4:
line->type = LINE_FENCE_BACKTICK_4;
break;
+
default:
line->type = LINE_FENCE_BACKTICK_5;
break;
}
+
break;
} else {
scan_len = scan_fence_start(&source[line->child->start]);
+
if (scan_len) {
switch (line->child->len) {
case 3:
line->type = LINE_FENCE_BACKTICK_START_3;
break;
+
case 4:
line->type = LINE_FENCE_BACKTICK_START_4;
break;
+
default:
line->type = LINE_FENCE_BACKTICK_START_5;
break;
}
+
break;
}
}
+
line->type = LINE_PLAIN;
break;
+
case COLON:
line->type = LINE_PLAIN;
+
if (e->extensions & EXT_COMPATIBILITY) {
break;
}
+
if (scan_definition(&source[line->child->start])) {
line->type = LINE_DEFINITION;
}
+
break;
+
case HASH1:
case HASH2:
case HASH3:
} else {
line->type = LINE_PLAIN;
}
+
break;
+
case HTML_COMMENT_START:
- if (!line->child->next || !line->child->next->next)
+ if (!line->child->next || !line->child->next->next) {
line->type = LINE_START_COMMENT;
- else
+ } else {
line->type = LINE_PLAIN;
+ }
+
break;
+
case HTML_COMMENT_STOP:
- if (!line->child->next || !line->child->next->next)
+ if (!line->child->next || !line->child->next->next) {
line->type = LINE_STOP_COMMENT;
- else
+ } else {
line->type = LINE_PLAIN;
+ }
+
break;
+
case TEXT_NUMBER_POSS_LIST:
switch(source[line->child->next->start]) {
case ' ':
switch (line->child->next->type) {
case TEXT_PLAIN:
+
// Strip whitespace between bullet and text
while (char_is_whitespace(source[line->child->next->start])) {
line->child->next->start++;
line->child->next->len--;
}
+
break;
+
case INDENT_SPACE:
case INDENT_TAB:
case NON_INDENT_SPACE:
t = line->child;
+
while(t->next && ((t->next->type == INDENT_SPACE) ||
(t->next->type == INDENT_TAB) ||
(t->next->type == NON_INDENT_SPACE))) {
tokens_prune(t->next, t->next);
}
+
break;
}
+
break;
+
default:
line->type = LINE_PLAIN;
line->child->type = TEXT_PLAIN;
break;
}
+
break;
+
case EQUAL:
+
// Could this be a setext heading marker?
if (scan_setext(&source[line->child->start])) {
line->type = LINE_SETEXT_1;
} else {
line->type = LINE_PLAIN;
}
+
break;
+
case DASH_N:
case DASH_M:
if (scan_setext(&source[line->child->start])) {
line->type = LINE_SETEXT_2;
break;
}
+
case STAR:
case UL:
// Could this be a horizontal rule?
t = line->child->next;
temp_short = line->child->len;
+
while (t) {
switch (t->type) {
case DASH_N:
case DASH_M:
if (t->type == line->child->type) {
t = t->next;
- if (t)
+
+ if (t) {
temp_short += t->len;
+ }
} else {
temp_short = 0;
t = NULL;
}
+
break;
+
case STAR:
case UL:
if (t->type == line->child->type) {
temp_short = 0;
t = NULL;
}
+
break;
+
case NON_INDENT_SPACE:
case INDENT_TAB:
case INDENT_SPACE:
t = t->next;
break;
+
case TEXT_PLAIN:
if ((t->len == 1) && (source[t->start] == ' ')) {
t = t->next;
break;
}
+
temp_short = 0;
t = NULL;
break;
+
case TEXT_NL:
case TEXT_LINEBREAK:
t = NULL;
break;
+
default:
temp_short = 0;
t = NULL;
break;
}
}
+
if (temp_short > 2) {
// This is a horizontal rule, not a list item
line->type = LINE_HR;
break;
}
+
if (line->child->type == UL) {
// Revert to plain for this type
line->type = LINE_PLAIN;
break;
}
+
// If longer than 1 character, then it can't be a list marker, so it's a
// plain line
if (line->child->len > 1) {
line->type = LINE_PLAIN;
break;
}
+
case PLUS:
if (!line->child->next) {
// TODO: Should this be an empty list item instead??
switch (line->child->next->type) {
case TEXT_PLAIN:
+
// Strip whitespace between bullet and text
while (char_is_whitespace(source[line->child->next->start])) {
line->child->next->start++;
line->child->next->len--;
}
+
break;
+
case INDENT_SPACE:
case INDENT_TAB:
case NON_INDENT_SPACE:
t = line->child;
+
while(t->next && ((t->next->type == INDENT_SPACE) ||
(t->next->type == INDENT_TAB) ||
(t->next->type == NON_INDENT_SPACE))) {
tokens_prune(t->next, t->next);
}
+
break;
}
+
break;
+
default:
line->type = LINE_PLAIN;
break;
}
}
+
break;
+
case TEXT_LINEBREAK:
case TEXT_NL:
e->allow_meta = false;
line->type = LINE_EMPTY;
break;
+
case TOC:
line->type = (e->extensions & EXT_COMPATIBILITY) ? LINE_PLAIN : LINE_TOC;
break;
+
case BRACKET_LEFT:
if (e->extensions & EXT_COMPATIBILITY) {
scan_len = scan_ref_link_no_attributes(&source[line->start]);
scan_len = scan_ref_link(&source[line->start]);
line->type = (scan_len) ? LINE_DEF_LINK : LINE_PLAIN;
}
+
break;
+
case BRACKET_ABBREVIATION_LEFT:
if (e->extensions & EXT_NOTES) {
scan_len = scan_ref_abbreviation(&source[line->start]);
scan_len = scan_ref_link_no_attributes(&source[line->start]);
line->type = (scan_len) ? LINE_DEF_LINK : LINE_PLAIN;
}
+
break;
+
case BRACKET_CITATION_LEFT:
if (e->extensions & EXT_NOTES) {
scan_len = scan_ref_citation(&source[line->start]);
scan_len = scan_ref_link_no_attributes(&source[line->start]);
line->type = (scan_len) ? LINE_DEF_LINK : LINE_PLAIN;
}
+
break;
+
case BRACKET_FOOTNOTE_LEFT:
if (e->extensions & EXT_NOTES) {
scan_len = scan_ref_foot(&source[line->start]);
scan_len = scan_ref_link_no_attributes(&source[line->start]);
line->type = (scan_len) ? LINE_DEF_LINK : LINE_PLAIN;
}
+
break;
+
case BRACKET_GLOSSARY_LEFT:
if (e->extensions & EXT_NOTES) {
scan_len = scan_ref_glossary(&source[line->start]);
scan_len = scan_ref_link_no_attributes(&source[line->start]);
line->type = (scan_len) ? LINE_DEF_LINK : LINE_PLAIN;
}
+
break;
+
case PIPE:
+
// If PIPE is first, save checking later and assign LINE_TABLE now
if (!(e->extensions & EXT_COMPATIBILITY)) {
scan_len = scan_table_separator(&source[line->start]);
break;
}
+
case TEXT_PLAIN:
if (e->allow_meta && !(e->extensions & EXT_COMPATIBILITY)) {
scan_len = scan_url(&source[line->start]);
+
if (scan_len == 0) {
scan_len = scan_meta_line(&source[line->start]);
line->type = (scan_len) ? LINE_META : LINE_PLAIN;
break;
}
}
+
default:
line->type = LINE_PLAIN;
break;
/// Strip leading indenting space from line (if present)
void deindent_line(token * line) {
- if (!line || !line->child)
+ if (!line || !line->child) {
return;
+ }
token * t;
t = line->child;
line->child = t->next;
t->next = NULL;
+
if (line->child) {
line->child->prev = NULL;
line->child->tail = t->tail;
}
+
token_free(t);
break;
}
/// Strip leading indenting space from block
/// (for recursively parsing nested lists)
void deindent_block(mmd_engine * e, token * block) {
- if (!block || !block->child)
+ if (!block || !block->child) {
return;
+ }
token * t = block->child;
/// Strip leading blockquote marker from line
void strip_quote_markers_from_line(token * line, const char * source) {
- if (!line || !line->child)
+ if (!line || !line->child) {
return;
+ }
token * t;
t = line->child;
line->child = t->next;
t->next = NULL;
+
if (line->child) {
line->child->prev = NULL;
line->child->tail = t->tail;
}
+
token_free(t);
break;
}
if (t->len == 0) {
line->child = t->next;
t->next = NULL;
+
if (line->child) {
line->child->prev = NULL;
line->child->tail = t->tail;
/// Strip leading blockquote markers and non-indent space
/// (for recursively parsing blockquotes)
void strip_quote_markers_from_block(mmd_engine * e, token * block) {
- if (!block || !block->child)
+ if (!block || !block->child) {
return;
+ }
token * t = block->child;
token_append_child(root, line);
break;
+
case TEXT_LINEBREAK:
case TEXT_NL:
// We hit the end of a line
}
if (stop_on_empty_line) {
- if (line->type == LINE_EMPTY)
+ if (line->type == LINE_EMPTY) {
return root;
+ }
}
+
line = token_new(0,s.cur - e->dstr->str,0);
break;
+
default:
t = token_new(type, (size_t)(s.start - e->dstr->str), (size_t)(s.cur - s.start));
token_append_child(line, t);
/// Parse token tree
void mmd_parse_token_chain(mmd_engine * e, token * chain) {
- if (e->recurse_depth == kMaxParseRecursiveDepth)
+ if (e->recurse_depth == kMaxParseRecursiveDepth) {
return;
+ }
e->recurse_depth++;
walker->next = NULL;
walker->tail = walker;
- if (remainder)
+ if (remainder) {
remainder->prev = NULL;
+ }
#ifndef NDEBUG
fprintf(stderr, "\nNew line\n");
/// Match token pairs inside block
void mmd_pair_tokens_in_block(token * block, token_pair_engine * e, stack * s) {
- if (block == NULL || e == NULL)
+ if (block == NULL || e == NULL) {
return;
+ }
switch (block->type) {
case BLOCK_BLOCKQUOTE:
case BLOCK_TERM:
token_pairs_match_pairs_inside_token(block, e, s, 0);
break;
+
case DOC_START_TOKEN:
case BLOCK_LIST_BULLETED:
case BLOCK_LIST_BULLETED_LOOSE:
case BLOCK_LIST_ENUMERATED_LOOSE:
mmd_pair_tokens_in_chain(block->child, e, s);
break;
+
case BLOCK_LIST_ITEM:
case BLOCK_LIST_ITEM_TIGHT:
token_pairs_match_pairs_inside_token(block, e, s, 0);
mmd_pair_tokens_in_chain(block->child, e, s);
break;
+
case LINE_TABLE:
case BLOCK_TABLE:
// TODO: Need to parse into cells first
token_pairs_match_pairs_inside_token(block, e, s, 0);
mmd_pair_tokens_in_chain(block->child, e, s);
break;
+
case BLOCK_EMPTY:
case BLOCK_CODE_INDENTED:
case BLOCK_CODE_FENCED:
/// with figuring out which type of asterisk we have. Default behavior is that open and close
/// are enabled, so we just have to figure out when to turn it off.
void mmd_assign_ambidextrous_tokens_in_block(mmd_engine * e, token * block, size_t start_offset) {
- if (block == NULL || block->child == NULL)
+ if (block == NULL || block->child == NULL) {
return;
+ }
size_t offset; // Temp variable for use below
size_t lead_count, lag_count, pre_count, post_count;
while (t != NULL) {
switch (t->type) {
case BLOCK_META:
+
// Do we treat this like metadata?
if (!(e->extensions & EXT_COMPATIBILITY) &&
- !(e->extensions & EXT_NO_METADATA))
+ !(e->extensions & EXT_NO_METADATA)) {
break;
+ }
+
// This is not metadata
t->type = BLOCK_PARA;
+
case DOC_START_TOKEN:
case BLOCK_BLOCKQUOTE:
case BLOCK_DEF_ABBREVIATION:
// Assign child tokens of blocks
mmd_assign_ambidextrous_tokens_in_block(e, t, start_offset);
break;
+
case CRITIC_SUB_DIV:
// Divide this into two tokens
t->child = token_new(CRITIC_SUB_DIV_B, t->start + 1, 1);
t->len = 1;
t->type = CRITIC_SUB_DIV_A;
break;
+
case STAR:
// Look left and skip over neighboring '*' characters
offset = t->start;
// Look right and skip over neighboring '*' characters
offset = t->start + 1;
- while ((str[offset] == '*') || (str[offset] == '_'))
+ while ((str[offset] == '*') || (str[offset] == '_')) {
offset++;
+ }
// We can only open if there is something to right besides whitespace/punctuation
if (char_is_whitespace_or_line_ending(str[offset])) {
}
}
}
+
break;
+
case UL:
// Look left and skip over neighboring '_' characters
offset = t->start;
// Look right and skip over neighboring '_' characters
offset = t->start + 1;
- while ((str[offset] == '*') || (str[offset] == '_'))
+ while ((str[offset] == '*') || (str[offset] == '_')) {
offset++;
+ }
if (char_is_whitespace_or_line_ending(str[offset])) {
// Whitespace to right, so can't open
}
break;
+
case BACKTICK:
// Backticks are used for code spans, but also for ``foo'' double quote syntax.
// We care only about the quote syntax.
// TODO: This does potentially prevent ``foo `` from closing due to space before closer?
// Bug or feature??
- if (t->len != 2)
+ if (t->len != 2) {
break;
+ }
if ((offset == 0) || (str[offset] != '`' && char_is_whitespace_or_line_ending_or_punctuation(str[offset - 1]))) {
// Whitespace or punctuation to left, so can't close
t->can_close = 0;
}
+
break;
+
case QUOTE_SINGLE:
// Some of these are actually APOSTROPHE's and should not be paired
offset = t->start;
}
}
}
+
case QUOTE_DOUBLE:
offset = t->start;
}
break;
+
case DASH_N:
- if (!(e->extensions & EXT_SMART))
+ if (!(e->extensions & EXT_SMART)) {
break;
+ }
+
// We want `1-2` to trigger a DASH_N, but regular hyphen otherwise (`a-b`)
// This doesn't apply to `--` or `---`
offset = t->start;
+
if (t->len == 1) {
// Check whether we have '1-2'
if ((offset == 0) || (!char_is_digit(str[offset - 1])) ||
t->type = TEXT_PLAIN;
}
}
+
break;
+
case MATH_DOLLAR_SINGLE:
case MATH_DOLLAR_DOUBLE:
- if (e->extensions & EXT_COMPATIBILITY)
+ if (e->extensions & EXT_COMPATIBILITY) {
break;
+ }
offset = t->start;
// No whitespace or punctuation to right, can't close
t->can_close = 0;
}
+
break;
+
case SUPERSCRIPT:
case SUBSCRIPT:
if (e->extensions & EXT_COMPATIBILITY) {
// Are we a standalone, e.g x^2
if (!t->can_close && !t->can_open) {
offset = t->start + t->len;
- while (!char_is_whitespace_or_line_ending_or_punctuation(str[offset]))
+
+ while (!char_is_whitespace_or_line_ending_or_punctuation(str[offset])) {
offset++;
+ }
t->len = offset-t->start;
t->can_close = 0;
case STAR:
case UL:
closer = t->mate;
+
if (t->next &&
(t->next->mate == closer->prev) &&
(t->type == t->next->type) &&
closer->type = EMPH_STOP;
token_prune_graft(t, closer, PAIR_EMPH);
}
+
break;
default:
case PAIR_BACKTICK:
case PAIR_MATH:
break;
+
default:
pair_emphasis_tokens(t->child);
break;
// Insert marker back in place
marker->next = block->child->child;
- if (block->child->child)
+
+ if (block->child->child) {
block->child->child->prev = marker;
+ }
+
block->child->child = marker;
}
token * walker = list->child;
- if (walker == NULL)
+ if (walker == NULL) {
return;
+ }
while (walker->next != NULL) {
if (walker->type == BLOCK_LIST_ITEM) {
case BLOCK_LIST_BULLETED:
list->type = BLOCK_LIST_BULLETED_LOOSE;
break;
+
case BLOCK_LIST_ENUMERATED:
list->type = BLOCK_LIST_ENUMERATED_LOOSE;
break;
void is_para_html(mmd_engine * e, token * block) {
if ((block == NULL) ||
(block->child == NULL) ||
- (block->child->type != LINE_PLAIN))
+ (block->child->type != LINE_PLAIN)) {
return;
+ }
+
token * t = block->child->child;
if (t->type == ANGLE_LEFT || t->type == HTML_COMMENT_START) {
meta_set_value(m, d->str);
d_string_erase(d, 0, -1);
}
+
len = scan_meta_key(&source[l->start]);
m = meta_new(source, l->start, len);
start = l->start + len + 1;
d_string_append_c_array(d, &source[start], len);
stack_push(e->metadata_stack, m);
break;
+
case LINE_INDENTED_TAB:
case LINE_INDENTED_SPACE:
while (l->len && char_is_whitespace(source[l->start])) {
l->start++;
l->len--;
}
+
case LINE_PLAIN:
plain:
d_string_append_c(d, '\n');
d_string_append_c_array(d, &source[l->start], l->len);
break;
+
case LINE_SETEXT_2:
case LINE_YAML:
break;
+
case LINE_TABLE:
if (scan_meta_line(&source[l->start])) {
goto meta;
} else {
goto plain;
}
+
default:
fprintf(stderr, "ERROR!\n");
token_describe(l, NULL);
case LINE_EMPTY:
walker->type = TEXT_EMPTY;
break;
+
case LINE_PLAIN:
walker->type = BLOCK_TERM;
+
case BLOCK_TERM:
break;
+
case BLOCK_DEFINITION:
strip_line_tokens_from_block(e, walker);
break;
}
+
walker = walker->next;
}
}
case BLOCK_TABLE_SECTION:
strip_line_tokens_from_block(e, walker);
break;
+
case BLOCK_TABLE_HEADER:
strip_line_tokens_from_block(e, walker);
break;
+
case LINE_EMPTY:
walker->type = TEXT_EMPTY;
break;
last = NULL;
walker->type = TABLE_DIVIDER;
break;
+
case TEXT_NL:
case TEXT_LINEBREAK:
break;
+
default:
- if (!first)
+ if (!first) {
first = walker;
+ }
+
last = walker;
}
void strip_line_tokens_from_block(mmd_engine * e, token * block) {
- if ((block == NULL) || (block->child == NULL))
+ if ((block == NULL) || (block->child == NULL)) {
return;
+ }
#ifndef NDEBUG
fprintf(stderr, "Strip line tokens from %d (%lu:%lu) (child %d)\n", block->type, block->start, block->len, block->child->type);
case BLOCK_META:
// Handle metadata differently
return strip_line_tokens_from_metadata(e, block);
+
case BLOCK_CODE_INDENTED:
+
// Strip trailing empty lines from indented code blocks
- while (l->tail->type == LINE_EMPTY)
+ while (l->tail->type == LINE_EMPTY) {
token_remove_last_child(block);
+ }
+
break;
+
case BLOCK_DEFLIST:
// Handle definition lists
return strip_line_tokens_from_deflist(e, block);
+
case BLOCK_TABLE:
// Handle tables
return strip_line_tokens_from_table(e, block);
l = temp;
break;
}
+
case LINE_DEFINITION:
if (block->type == BLOCK_DEFINITION) {
// Remove leading colon
token_remove_first_child(l);
}
+
case LINE_ATX_1:
case LINE_ATX_2:
case LINE_ATX_3:
case LINE_START_COMMENT:
case LINE_STOP_COMMENT:
handle_line:
+
// Remove leading non-indent space from line
- if (l->child && l->child->type == NON_INDENT_SPACE)
+ if (l->child && l->child->type == NON_INDENT_SPACE) {
token_remove_first_child(l);
+ }
case LINE_INDENTED_TAB:
case LINE_INDENTED_SPACE:
+
// Strip leading indent (Only the first one)
- if (l->child && ((l->child->type == INDENT_SPACE) || (l->child->type == INDENT_TAB)))
+ if (l->child && ((l->child->type == INDENT_SPACE) || (l->child->type == INDENT_TAB))) {
token_remove_first_child(l);
+ }
// If we're not a code block, strip additional indents
if ((block->type != BLOCK_CODE_INDENTED) &&
(block->type != BLOCK_CODE_FENCED)) {
- while (l->child && ((l->child->type == INDENT_SPACE) || (l->child->type == INDENT_TAB)))
+ while (l->child && ((l->child->type == INDENT_SPACE) || (l->child->type == INDENT_TAB))) {
token_remove_first_child(l);
+ }
}
+
// Add contents of line to parent block
token_append_child(block, l->child);
l->child = NULL;
// Need to remember first line we strip
- if (children == NULL)
+ if (children == NULL) {
children = l;
+ }
// Advance to next line
l = l->next;
break;
+
case BLOCK_DEFINITION:
// Sometimes these get created unintentionally inside other blocks
// Process inside it, then treat it like a line to be stripped
temp = token_new(COLON, l->child->start - 1, 1);
token_append_child(block, temp);
}
+
token_append_child(block, l->child);
l->child = NULL;
- if (children == NULL)
+
+ if (children == NULL) {
children = l;
+ }
+
l = l->next;
break;
+
case LINE_TABLE_SEPARATOR:
case LINE_TABLE:
if (block->type == BLOCK_TABLE_HEADER) {
} else {
goto handle_line;
}
+
default:
// token_describe(block, e->dstr->str);
// fprintf(stderr, "Unspecified line type %d inside block type %d\n", l->type, block->type);
/// Does the text have metadata?
bool mmd_engine_has_metadata(mmd_engine * e, size_t * end) {
bool result = false;
- if (!e)
+
+ if (!e) {
return false;
+ }
if (!(scan_meta_line(&e->dstr->str[0]))) {
// First line is not metadata, so can't have metadata
}
// Free existing parse tree
- if (e->root)
+ if (e->root) {
token_tree_free(e->root);
+ }
// Tokenize the string (up until first empty line)
token * doc = mmd_tokenize_string(e, 0, e->dstr->currentStringLength, true);
if (doc->child && doc->child->type == BLOCK_META) {
result = true;
- if (end)
+ if (end) {
*end = doc->child->len;
+ }
}
token_tree_free(doc);
char * mmd_engine_metadata_keys(mmd_engine * e) {
if (e->metadata_stack->size == 0) {
// Ensure we have checked for metadata
- if (!mmd_engine_has_metadata(e, NULL))
+ if (!mmd_engine_has_metadata(e, NULL)) {
return NULL;
+ }
}
char * result = NULL;
mmd_engine * e = mmd_engine_create_with_dstring(source, 0);
result = mmd_engine_metavalue_for_key(e, key);
+
if (result) {
result = my_strdup(result);
}
char * mmd_engine_metavalue_for_key(mmd_engine * e, const char * key) {
if (e->metadata_stack->size == 0) {
// Ensure we have checked for metadata
- if (!mmd_engine_has_metadata(e, NULL))
+ if (!mmd_engine_has_metadata(e, NULL)) {
return NULL;
+ }
}
char * result = NULL;
size_t meta_end = 0;
// Check for metadata and character
- if (!mmd_engine_has_metadata(e, &meta_end))
+ if (!mmd_engine_has_metadata(e, &meta_end)) {
has_meta = false;
+ }
// Get clean metadata key for match
char * clean = label_from_string(key);
// Figure out where to start
char * begin = &(e->dstr->str[start]);
- while (*begin != ':')
+ while (*begin != ':') {
begin++;
+ }
begin++;
- while (char_is_whitespace(*begin))
+ while (char_is_whitespace(*begin)) {
begin++;
+ }
start = begin - e->dstr->str;
case FORMAT_EPUB:
epub_write_wrapper(filepath, output->str, e, directory);
break;
+
case FORMAT_TEXTBUNDLE:
// TODO: Need to implement this
break;
+
case FORMAT_TEXTBUNDLE_COMPRESSED:
textbundle_write_wrapper(filepath, output->str, e, directory);
break;
+
default:
+
// Basic formats just write to file
if (!(output_stream = fopen(filepath, "w"))) {
// Failed to open file
fputc('\n', output_stream);
fclose(output_stream);
}
+
break;
}
d_string_free(output, true);
break;
+
case FORMAT_TEXTBUNDLE:
case FORMAT_TEXTBUNDLE_COMPRESSED:
result = textbundle_create(output->str, e, directory);
d_string_free(output, true);
break;
+
case FORMAT_ODT:
result = opendocument_text_create(output->str, e, directory);
d_string_free(output, true);
break;
+
case FORMAT_FODT:
result = opendocument_flat_text_create(output->str, e, directory);
d_string_free(output, true);
break;
+
default:
result = output;
// Add newline to result
/// Drain pool -- free slabs previously allocated
void pool_drain(pool * p) {
- if (p == NULL)
+ if (p == NULL) {
return;
+ }
void * slab;
case '"':
print_const(""");
break;
+
case '&':
print_const("&");
break;
+
case '<':
print_const("<");
break;
+
case '>':
print_const(">");
break;
+
case '\t':
print_const("<text:tab/>");
+
default:
print_char(c);
break;
void mmd_print_string_opendocument(DString * out, const char * str) {
- if (str == NULL)
+ if (str == NULL) {
return;
+ }
while (*str != '\0') {
mmd_print_char_opendocument(out, *str);
case DASH_N:
print_const("–");
break;
+
case DASH_M:
print_const("—");
break;
+
case ELLIPSIS:
print_const("…");
break;
+
case APOSTROPHE:
print_const("’");
break;
+
case QUOTE_LEFT_SINGLE:
switch (scratch->quotes_lang) {
case SWEDISH:
print( "’");
break;
+
case FRENCH:
print_const("'");
break;
+
case GERMAN:
print_const("‚");
break;
+
case GERMANGUILL:
print_const("›");
break;
+
default:
print_const("‘");
}
+
break;
+
case QUOTE_RIGHT_SINGLE:
switch (scratch->quotes_lang) {
case GERMAN:
print_const("‘");
break;
+
case GERMANGUILL:
print_const("‹");
break;
+
default:
print_const("’");
}
+
break;
+
case QUOTE_LEFT_DOUBLE:
switch (scratch->quotes_lang) {
case DUTCH:
case GERMAN:
print_const("„");
break;
+
case GERMANGUILL:
print_const("»");
break;
+
case FRENCH:
print_const("«");
break;
+
case SWEDISH:
print( "”");
break;
+
default:
print_const("“");
}
+
break;
+
case QUOTE_RIGHT_DOUBLE:
switch (scratch->quotes_lang) {
case GERMAN:
print_const("“");
break;
+
case GERMANGUILL:
print_const("«");
break;
+
case FRENCH:
print_const("»");
break;
+
case SWEDISH:
case DUTCH:
default:
print_const("”");
}
+
break;
}
}
void mmd_export_token_opendocument_raw(DString * out, const char * source, token * t, scratch_pad * scratch) {
- if (t == NULL)
+ if (t == NULL) {
return;
+ }
switch (t->type) {
case AMPERSAND:
print_const("&");
break;
+
case AMPERSAND_LONG:
print_const("&amp;");
break;
+
case ANGLE_RIGHT:
print_const(">");
break;
+
case ANGLE_LEFT:
print_const("<");
break;
+
case ESCAPED_CHARACTER:
print_const("\\");
mmd_print_char_opendocument(out, source[t->start + 1]);
break;
+
case HTML_ENTITY:
print_const("&");
d_string_append_c_array(out, &(source[t->start + 1]), t->len - 1);
break;
+
case INDENT_TAB:
print_const("<text:tab/>");
break;
+
case QUOTE_DOUBLE:
print_const(""");
break;
+
case CODE_FENCE:
- if (t->next)
+ if (t->next) {
t->next->type = TEXT_EMPTY;
+ }
+
case TEXT_EMPTY:
break;
+
case TEXT_NL:
print_const("<text:line-break/>");
break;
+
default:
- if (t->child)
+ if (t->child) {
mmd_export_token_tree_opendocument_raw(out, source, t->child, scratch);
- else
+ } else {
print_token(t);
+ }
+
break;
}
}
print_const("<text:a xlink:type=\"simple\" xlink:href=\"");
mmd_print_string_opendocument(out, link->url);
print_const("\"");
- } else
+ } else {
print_const("<a xlink:type=\"simple\" xlink:href=\"\"");
+ }
if (link->title && link->title[0] != '\0') {
print_const(" office:name=\"");
text->child->next->len++;
}
- if (text)
+ if (text) {
mmd_export_token_tree_opendocument(out, source, text->child, scratch);
+ }
print_const("</text:a>");
}
result = my_strdup(original);
- for (i = 0; result[i]; i++)
+ for (i = 0; result[i]; i++) {
result[i] = tolower(result[i]);
+ }
if (strstr(&result[strlen(result)-2],"px")) {
result[strlen(result)-2] = '\0';
printf("svg:width=\"%s\" ", width);
}
- if (height)
+ if (height) {
free(height);
+ }
- if (width)
+ if (width) {
free(width);
+ }
if (link->url) {
if (scratch->store_assets) {
if (*counter < scratch->header_stack->size - 1) {
next = stack_peek_index(scratch->header_stack, *counter + 1);
next_level = next->type - BLOCK_H1 + 1;
+
if (next_level > entry_level) {
// This entry has children
(*counter)++;
void mmd_export_token_opendocument(DString * out, const char * source, token * t, scratch_pad * scratch) {
- if (t == NULL)
+ if (t == NULL) {
return;
+ }
short temp_short;
short temp_short2;
case DOC_START_TOKEN:
mmd_export_token_tree_opendocument(out, source, t->child, scratch);
break;
+
case AMPERSAND:
case AMPERSAND_LONG:
print_const("&");
break;
+
case ANGLE_LEFT:
print_const("<");
break;
+
case ANGLE_RIGHT:
print_const(">");
break;
+
case APOSTROPHE:
if (!(scratch->extensions & EXT_SMART)) {
print_token(t);
} else {
print_localized(APOSTROPHE);
}
+
break;
+
case BACKTICK:
- if (t->mate == NULL)
+ if (t->mate == NULL) {
print_token(t);
- else if (t->mate->type == QUOTE_RIGHT_ALT)
+ } else if (t->mate->type == QUOTE_RIGHT_ALT)
if (!(scratch->extensions & EXT_SMART)) {
print_token(t);
} else {
} else {
print_const("</text:span>");
}
+
break;
+
case BLOCK_BLOCKQUOTE:
pad(out, 2, scratch);
scratch->padded = 2;
scratch->padded = 0;
scratch->odf_para_type = temp_short2;
break;
+
case BLOCK_CODE_FENCED:
pad(out, 2, scratch);
case LINE_FENCE_BACKTICK_5:
temp_token = t->child->tail;
break;
+
default:
temp_token = NULL;
}
+
if (temp_token) {
d_string_append_c_array(out, &source[t->child->next->start], temp_token->start - t->child->next->start);
scratch->padded = 1;
print_const("</text:p>");
scratch->padded = 0;
break;
+
case BLOCK_CODE_INDENTED:
pad(out, 2, scratch);
print_const("<text:p text:style-name=\"Preformatted Text\">");
print_const("</text:p>");
scratch->padded = 0;
break;
+
case BLOCK_DEFINITION:
pad(out, 2, scratch);
temp_short2 = scratch->odf_para_type;
scratch->odf_para_type = BLOCK_DEFINITION;
temp_short = scratch->list_is_tight;
- if (!(t->child->next && (t->child->next->type == BLOCK_EMPTY) && t->child->next->next))
+
+ if (!(t->child->next && (t->child->next->type == BLOCK_EMPTY) && t->child->next->next)) {
scratch->list_is_tight = true;
+ }
if (t->child && t->child->type != BLOCK_PARA) {
print_const("<text:p text:style-name=\"Quotations\">");
} else {
mmd_export_token_tree_opendocument(out, source, t->child, scratch);
}
+
scratch->padded = 0;
scratch->list_is_tight = temp_short;
scratch->odf_para_type = temp_short2;
break;
+
case BLOCK_DEFLIST:
pad(out, 2, scratch);
scratch->padded = 1;
break;
+
case BLOCK_EMPTY:
break;
+
case BLOCK_H1:
case BLOCK_H2:
case BLOCK_H3:
case BLOCK_SETEXT_1:
case BLOCK_SETEXT_2:
pad(out, 2, scratch);
+
switch (t->type) {
case BLOCK_SETEXT_1:
temp_short = 1;
break;
+
case BLOCK_SETEXT_2:
temp_short = 2;
break;
+
default:
temp_short = t->type - BLOCK_H1 + 1;
}
print_const("</text:h>");
scratch->padded = 0;
break;
+
case BLOCK_HR:
pad(out, 2, scratch);
print_const("<text:p text:style-name=\"Horizontal_20_Line\"/>");
scratch->padded = 0;
break;
+
case BLOCK_HTML:
// Don't print HTML
break;
+
case BLOCK_LIST_BULLETED_LOOSE:
case BLOCK_LIST_BULLETED:
temp_short = scratch->list_is_tight;
+
switch (t->type) {
case BLOCK_LIST_BULLETED_LOOSE:
scratch->list_is_tight = false;
break;
+
case BLOCK_LIST_BULLETED:
scratch->list_is_tight = true;
break;
}
+
pad(out, 2, scratch);
print_const("<text:list text:style-name=\"L1\">");
scratch->padded = 1;
scratch->padded = 0;
scratch->list_is_tight = temp_short;
break;
+
case BLOCK_LIST_ENUMERATED_LOOSE:
case BLOCK_LIST_ENUMERATED:
temp_short = scratch->list_is_tight;
+
switch (t->type) {
case BLOCK_LIST_ENUMERATED_LOOSE:
scratch->list_is_tight = false;
break;
+
case BLOCK_LIST_ENUMERATED:
scratch->list_is_tight = true;
break;
}
+
pad(out, 2, scratch);
print_const("<text:list text:style-name=\"L2\">");
scratch->padded = 1;
scratch->padded = 0;
scratch->list_is_tight = temp_short;
break;
+
case BLOCK_LIST_ITEM:
pad(out, 2, scratch);
print_const("<text:list-item>\n");
print_const("</text:list-item>");
scratch->padded = 0;
break;
+
case BLOCK_LIST_ITEM_TIGHT:
pad(out, 2, scratch);
print_const("<text:list-item>\n");
- if (t->child && t->child->type != BLOCK_PARA)
+ if (t->child && t->child->type != BLOCK_PARA) {
print_const("<text:p text:style-name=\"P1\">\n");
+ }
scratch->padded = 2;
mmd_export_token_tree_opendocument(out, source, t->child, scratch);
- if (t->child && t->child->type != BLOCK_PARA)
+ if (t->child && t->child->type != BLOCK_PARA) {
print_const("</text:p>");
+ }
print_const("</text:list-item>");
scratch->padded = 0;
break;
+
case BLOCK_META:
break;
+
case BLOCK_PARA:
pad(out, 2, scratch);
print_const("<text:p");
case BLOCK_DEFINITION:
print_const(" text:style-name=\"Quotations\">");
break;
+
case PAIR_BRACKET_ABBREVIATION:
case PAIR_BRACKET_CITATION:
case PAIR_BRACKET_FOOTNOTE:
case PAIR_BRACKET_GLOSSARY:
print_const(" text:style-name=\"Footnote\">");
break;
+
default:
print_const(" text:style-name=\"Standard\">");
break;
print_const("</text:p>");
scratch->padded = 0;
break;
+
case BLOCK_TABLE:
pad(out, 2, scratch);
print_const("<table:table>\n");
// break;
// }
}
+
scratch->padded = 1;
mmd_export_token_tree_opendocument(out, source, t->child, scratch);
scratch->skip_token = temp_short;
break;
+
case BLOCK_TABLE_HEADER:
pad(out, 2, scratch);
scratch->in_table_header = 1;
scratch->in_table_header = 0;
scratch->padded = 1;
break;
+
case BLOCK_TABLE_SECTION:
pad(out, 2, scratch);
scratch->padded = 2;
mmd_export_token_tree_opendocument(out, source, t->child, scratch);
scratch->padded = 0;
break;
+
case BLOCK_TOC:
pad(out, 2, scratch);
scratch->padded = 1;
break;
+
case BLOCK_TERM:
pad(out, 2, scratch);
print_const("<text:p><text:span text:style-name=\"MMD-Bold\">");
print_const("</text:span></text:p>\n");
scratch->padded = 2;
break;
+
case BRACE_DOUBLE_LEFT:
print_const("{{");
break;
+
case BRACE_DOUBLE_RIGHT:
print_const("}}");
break;
+
case BRACKET_ABBREVIATION_LEFT:
print_const("[>");
break;
+
case BRACKET_CITATION_LEFT:
print_const("[#");
break;
+
case BRACKET_LEFT:
print_const("[");
break;
+
case BRACKET_RIGHT:
print_const("]");
break;
+
case BRACKET_VARIABLE_LEFT:
print_const("[\%");
break;
+
case COLON:
print_char(':');
break;
+
case CRITIC_ADD_OPEN:
print_const("{++");
break;
+
case CRITIC_ADD_CLOSE:
print_const("++}");
break;
+
case CRITIC_COM_OPEN:
print_const("{>>");
break;
+
case CRITIC_COM_CLOSE:
print_const("<<}");
break;
+
case CRITIC_DEL_OPEN:
print_const("{--");
break;
+
case CRITIC_DEL_CLOSE:
print_const("--}");
break;
+
case CRITIC_HI_OPEN:
print_const("{==");
break;
+
case CRITIC_HI_CLOSE:
print_const("==}");
break;
+
case CRITIC_SUB_OPEN:
print_const("{~~");
break;
+
case CRITIC_SUB_DIV:
print_const("~>");
break;
+
case CRITIC_SUB_CLOSE:
print_const("~~}");
break;
+
case DASH_M:
if (!(scratch->extensions & EXT_SMART)) {
print_token(t);
} else {
print_localized(DASH_M);
}
+
break;
+
case DASH_N:
if (!(scratch->extensions & EXT_SMART)) {
print_token(t);
} else {
print_localized(DASH_N);
}
+
break;
+
case ELLIPSIS:
if (!(scratch->extensions & EXT_SMART)) {
print_token(t);
} else {
print_localized(ELLIPSIS);
}
+
break;
+
case EMPH_START:
print_const("<text:span text:style-name=\"MMD-Italic\">");
break;
+
case EMPH_STOP:
print_const("</text:span>");
break;
+
case EQUAL:
print_char('=');
break;
+
case ESCAPED_CHARACTER:
if (!(scratch->extensions & EXT_COMPATIBILITY) &&
(source[t->start + 1] == ' ')) {
} else {
mmd_print_char_opendocument(out, source[t->start + 1]);
}
+
break;
+
case HASH1:
case HASH2:
case HASH3:
case HASH6:
print_token(t);
break;
+
case HTML_ENTITY:
print_const("&");
d_string_append_c_array(out, &(source[t->start + 1]), t->len - 1);
break;
+
case HTML_COMMENT_START:
if (!(scratch->extensions & EXT_SMART)) {
print_const("<!--");
print_const("<!");
print_localized(DASH_N);
}
+
break;
+
case HTML_COMMENT_STOP:
if (!(scratch->extensions & EXT_SMART)) {
print_const("-->");
print_localized(DASH_N);
print_const(">");
}
+
break;
+
case INDENT_SPACE:
print_char(' ');
break;
+
case INDENT_TAB:
print_const("<text:tab/>");
break;
+
case LINE_LIST_BULLETED:
case LINE_LIST_ENUMERATED:
mmd_export_token_tree_opendocument(out, source, t->child, scratch);
break;
+
case LINE_SETEXT_2:
case MANUAL_LABEL:
case MARKER_BLOCKQUOTE:
case MARKER_LIST_BULLET:
case MARKER_LIST_ENUMERATOR:
break;
+
case MATH_BRACKET_OPEN:
if (t->mate) {
print_const("<text:span text:style-name=\"math\">\\[");
- } else
+ } else {
print_const("\\[");
+ }
+
break;
+
case MATH_BRACKET_CLOSE:
if (t->mate) {
print_const("\\]</text:span>");
- } else
+ } else {
print_const("\\]");
+ }
+
break;
+
case MATH_DOLLAR_SINGLE:
if (t->mate) {
(t->start < t->mate->start) ? ( print_const("<text:span text:style-name=\"math\">\\(") ) : ( print_const("\\)</text:span>") );
} else {
print_const("$");
}
+
break;
+
case MATH_DOLLAR_DOUBLE:
if (t->mate) {
(t->start < t->mate->start) ? ( print_const("<text:span text:style-name=\"math\">\\[") ) : ( print_const("\\]</text:span>") );
} else {
print_const("$$");
}
+
break;
+
case MATH_PAREN_OPEN:
if (t->mate) {
print_const("<text:span text:style-name=\"math\">\\(");
- } else
+ } else {
print_const("\\(");
+ }
+
break;
+
case MATH_PAREN_CLOSE:
if (t->mate) {
print_const("\\)</text:span>");
- } else
+ } else {
print_const("\\)");
+ }
+
break;
+
case NON_INDENT_SPACE:
print_char(' ');
break;
+
case PAIR_ANGLE:
temp_char = url_accept(source, t->start + 1, t->len - 2, NULL, true);
free(temp_char);
break;
+
case PAIR_BACKTICK:
+
// Strip leading whitespace
switch (t->child->next->type) {
case TEXT_NL:
case NON_INDENT_SPACE:
t->child->next->type = TEXT_EMPTY;
break;
+
case TEXT_PLAIN:
while (t->child->next->len && char_is_whitespace(source[t->child->next->start])) {
t->child->next->start++;
t->child->next->len--;
}
+
break;
}
case NON_INDENT_SPACE:
t->child->mate->prev->type = TEXT_EMPTY;
break;
+
case TEXT_PLAIN:
while (t->child->mate->prev->len && char_is_whitespace(source[t->child->mate->prev->start + t->child->mate->prev->len - 1])) {
t->child->mate->prev->len--;
}
+
break;
}
+
t->child->type = TEXT_EMPTY;
t->child->mate->type = TEXT_EMPTY;
if (raw_filter_matches(t->next, source, FORMAT_FODT)) {
d_string_append_c_array(out, &(source[t->child->start + t->child->len]), t->child->mate->start - t->child->start - t->child->len);
}
+
// Skip over PAIR_RAW_FILTER
scratch->skip_token = 1;
break;
mmd_export_token_tree_opendocument_raw(out, source, t->child, scratch);
print_const("</text:span>");
break;
+
case PAIR_BRACE:
case PAIR_BRACES:
mmd_export_token_tree_opendocument(out, source, t->child, scratch);
break;
+
case PAIR_BRACKET:
if ((scratch->extensions & EXT_NOTES) &&
(t->next && t->next->type == PAIR_BRACKET_CITATION)) {
temp_token = temp_token->next;
}
- if (temp_token && temp_token->type == TEXT_NL)
+ if (temp_token && temp_token->type == TEXT_NL) {
temp_token = temp_token->next;
+ }
- if (temp_token && temp_token->type == TEXT_LINEBREAK)
+ if (temp_token && temp_token->type == TEXT_LINEBREAK) {
temp_token = temp_token->next;
+ }
if (t->prev || temp_token) {
mmd_export_image_opendocument(out, source, t, temp_link, scratch, false);
// No links exist, so treat as normal
mmd_export_token_tree_opendocument(out, source, t->child, scratch);
break;
+
case PAIR_BRACKET_CITATION:
parse_citation:
temp_bool = true; // Track whether this is regular vs 'not cited'
// Note-based syntax disabled
mmd_export_token_tree_opendocument(out, source, t->child, scratch);
}
+
break;
+
case PAIR_BRACKET_FOOTNOTE:
if (scratch->extensions & EXT_NOTES) {
// Note-based syntax enabled
// Note-based syntax disabled
mmd_export_token_tree_opendocument(out, source, t->child, scratch);
}
+
break;
+
case PAIR_BRACKET_ABBREVIATION:
+
// Which might also be an "auto-tagged" abbreviation
if (scratch->extensions & EXT_NOTES) {
// Note-based syntax enabled
// Note-based syntax disabled
mmd_export_token_tree_opendocument(out, source, t->child, scratch);
}
+
break;
+
case PAIR_BRACKET_GLOSSARY:
+
// Which might also be an "auto-tagged" glossary
if (scratch->extensions & EXT_NOTES) {
// Note-based syntax enabled
// Note-based syntax disabled
mmd_export_token_tree_opendocument(out, source, t->child, scratch);
}
+
break;
+
case PAIR_BRACKET_VARIABLE:
temp_char = text_inside_pair(source, t);
temp_char2 = extract_metadata(scratch, temp_char);
- if (temp_char2)
+ if (temp_char2) {
mmd_print_string_opendocument(out, temp_char2);
- else
+ } else {
mmd_export_token_tree_opendocument(out, source, t->child, scratch);
+ }
// Don't free temp_char2 (it belongs to meta *)
free(temp_char);
break;
+
case PAIR_CRITIC_ADD:
+
// Ignore if we're rejecting
- if (scratch->extensions & EXT_CRITIC_REJECT)
+ if (scratch->extensions & EXT_CRITIC_REJECT) {
break;
+ }
+
if (scratch->extensions & EXT_CRITIC) {
t->child->type = TEXT_EMPTY;
t->child->mate->type = TEXT_EMPTY;
+
if (scratch->extensions & EXT_CRITIC_ACCEPT) {
mmd_export_token_tree_opendocument(out, source, t->child, scratch);
} else {
} else {
mmd_export_token_tree_opendocument(out, source, t->child, scratch);
}
+
break;
+
case PAIR_CRITIC_DEL:
+
// Ignore if we're accepting
- if (scratch->extensions & EXT_CRITIC_ACCEPT)
+ if (scratch->extensions & EXT_CRITIC_ACCEPT) {
break;
+ }
+
if (scratch->extensions & EXT_CRITIC) {
t->child->type = TEXT_EMPTY;
t->child->mate->type = TEXT_EMPTY;
+
if (scratch->extensions & EXT_CRITIC_REJECT) {
mmd_export_token_tree_opendocument(out, source, t->child, scratch);
} else {
} else {
mmd_export_token_tree_opendocument(out, source, t->child, scratch);
}
+
break;
+
case PAIR_CRITIC_COM:
+
// Ignore if we're rejecting or accepting
if ((scratch->extensions & EXT_CRITIC_REJECT) ||
- (scratch->extensions & EXT_CRITIC_ACCEPT))
+ (scratch->extensions & EXT_CRITIC_ACCEPT)) {
break;
+ }
+
if (scratch->extensions & EXT_CRITIC) {
t->child->type = TEXT_EMPTY;
t->child->mate->type = TEXT_EMPTY;
} else {
mmd_export_token_tree_opendocument(out, source, t->child, scratch);
}
+
break;
+
case PAIR_CRITIC_HI:
+
// Ignore if we're rejecting or accepting
if ((scratch->extensions & EXT_CRITIC_REJECT) ||
- (scratch->extensions & EXT_CRITIC_ACCEPT))
+ (scratch->extensions & EXT_CRITIC_ACCEPT)) {
break;
+ }
+
if (scratch->extensions & EXT_CRITIC) {
t->child->type = TEXT_EMPTY;
t->child->mate->type = TEXT_EMPTY;
} else {
mmd_export_token_tree_opendocument(out, source, t->child, scratch);
}
+
break;
+
case CRITIC_SUB_DIV_A:
print_const("~");
break;
+
case CRITIC_SUB_DIV_B:
print_const(">");
break;
+
case PAIR_CRITIC_SUB_DEL:
if ((scratch->extensions & EXT_CRITIC) &&
(t->next) &&
(t->next->type == PAIR_CRITIC_SUB_ADD)) {
t->child->type = TEXT_EMPTY;
t->child->mate->type = TEXT_EMPTY;
+
if (scratch->extensions & EXT_CRITIC_ACCEPT) {
} else if (scratch->extensions & EXT_CRITIC_REJECT) {
} else {
mmd_export_token_tree_opendocument(out, source, t->child, scratch);
}
+
break;
+
case PAIR_CRITIC_SUB_ADD:
if ((scratch->extensions & EXT_CRITIC) &&
(t->prev) &&
(t->prev->type == PAIR_CRITIC_SUB_DEL)) {
t->child->type = TEXT_EMPTY;
t->child->mate->type = TEXT_EMPTY;
+
if (scratch->extensions & EXT_CRITIC_REJECT) {
} else if (scratch->extensions & EXT_CRITIC_ACCEPT) {
} else {
mmd_export_token_tree_opendocument(out, source, t->child, scratch);
}
+
break;
+
case PAIR_HTML_COMMENT:
break;
+
case PAIR_EMPH:
case PAIR_MATH:
case PAIR_PAREN:
case PAIR_UL:
mmd_export_token_tree_opendocument(out, source, t->child, scratch);
break;
+
case PAREN_LEFT:
print_char('(');
break;
+
case PAREN_RIGHT:
print_char(')');
break;
+
case PIPE:
print_token(t);
break;
+
case PLUS:
print_char('+');
break;
+
case QUOTE_SINGLE:
- if ((t->mate == NULL) || (!(scratch->extensions & EXT_SMART)))
+ if ((t->mate == NULL) || (!(scratch->extensions & EXT_SMART))) {
print_const("'");
- else
+ } else {
(t->start < t->mate->start) ? ( print_localized(QUOTE_LEFT_SINGLE) ) : ( print_localized(QUOTE_RIGHT_SINGLE) );
+ }
+
break;
+
case QUOTE_DOUBLE:
- if ((t->mate == NULL) || (!(scratch->extensions & EXT_SMART)))
+ if ((t->mate == NULL) || (!(scratch->extensions & EXT_SMART))) {
print_const(""");
- else
+ } else {
(t->start < t->mate->start) ? ( print_localized(QUOTE_LEFT_DOUBLE) ) : ( print_localized(QUOTE_RIGHT_DOUBLE) );
+ }
+
break;
+
case QUOTE_RIGHT_ALT:
- if ((t->mate == NULL) || (!(scratch->extensions & EXT_SMART)))
+ if ((t->mate == NULL) || (!(scratch->extensions & EXT_SMART))) {
print_const("''");
- else
+ } else {
print_localized(QUOTE_RIGHT_DOUBLE);
+ }
+
break;
+
case SLASH:
print_char('/');
break;
+
case STAR:
print_char('*');
break;
+
case STRONG_START:
print_const("<text:span text:style-name=\"MMD-Bold\">");
break;
+
case STRONG_STOP:
print_const("</text:span>");
break;
+
case SUBSCRIPT:
if (t->mate) {
(t->start < t->mate->start) ? (print_const("<text:span text:style-name=\"MMD-Subscript\">")) : (print_const("</text:span>"));
} else {
print_const("~");
}
+
break;
+
case SUPERSCRIPT:
if (t->mate) {
(t->start < t->mate->start) ? (print_const("<text:span text:style-name=\"MMD-Superscript\">")) : (print_const("</text:span>"));
} else {
print_const("^");
}
+
break;
+
case TABLE_CELL:
print_const("<table:table-cell");
print_const(">\n<text:p text:style-name=\"Table_20_Heading\"");
} else {
print_const(">\n<text:p");
+
switch (scratch->table_alignment[scratch->table_cell_count]) {
case 'l':
case 'L':
default:
print_const(" text:style-name=\"MMD-Table\"");
break;
+
case 'r':
case 'R':
print_const(" text:style-name=\"MMD-Table-Right\"");
break;
+
case 'c':
case 'C':
print_const(" text:style-name=\"MMD-Table-Center\"");
print_const("</text:p>\n</table:table-cell>\n");
- if (t->next)
+ if (t->next) {
scratch->table_cell_count += t->next->len;
- else
+ } else {
scratch->table_cell_count++;
+ }
break;
+
case TABLE_DIVIDER:
break;
+
case TABLE_ROW:
print_const("<table:table-row>\n");
scratch->table_cell_count = 0;
mmd_export_token_tree_opendocument(out, source, t->child, scratch);
print_const("</table:table-row>\n");
break;
+
case TEXT_EMPTY:
break;
+
case TEXT_LINEBREAK:
if (t->next) {
print_const("<text:line-break/>\n");
scratch->padded = 0;
}
+
break;
+
case TEXT_NL:
- if (t->next)
+ if (t->next) {
print_char('\n');
+ }
+
break;
+
case RAW_FILTER_LEFT:
case TEXT_BACKSLASH:
case TEXT_BRACE_LEFT:
case UL:
print_token(t);
break;
+
default:
fprintf(stderr, "Unknown token type: %d\n", t->type);
token_describe(t, source);
static bool add_asset_from_file(mz_zip_archive * pZip, asset * a, const char * destination, const char * directory) {
- if (!directory)
+ if (!directory) {
return false;
+ }
char * path = path_from_dir_base(directory, a->url);
mz_bool status;
struct MemoryStruct * mem = (struct MemoryStruct *)userp;
mem->memory = realloc(mem->memory, mem->size + realsize + 1);
+
if (mem->memory == NULL) {
// Out of memory
fprintf(stderr, "Out of memory\n");
len = strlen(mime);
status = mz_zip_writer_add_mem(zip, "mimetype", mime, len, MZ_NO_COMPRESSION);
+
if (!status) {
fprintf(stderr, "Error adding mimetype to zip.\n");
}
len = strlen(data);
status = mz_zip_writer_add_mem(zip, "meta.xml", data, len, MZ_BEST_COMPRESSION);
free(data);
+
if (!status) {
fprintf(stderr, "Error adding metadata to zip.\n");
}
len = strlen(data);
status = mz_zip_writer_add_mem(zip, "styles.xml", data, len, MZ_BEST_COMPRESSION);
free(data);
+
if (!status) {
fprintf(stderr, "Error adding styles to zip.\n");
}
len = strlen(data);
status = mz_zip_writer_add_mem(zip, "settings.xml", data, len, MZ_BEST_COMPRESSION);
free(data);
+
if (!status) {
fprintf(stderr, "Error adding settings to zip.\n");
}
// Create directories
status = mz_zip_writer_add_mem(zip, "META-INF/", NULL, 0, MZ_BEST_COMPRESSION);
+
if (!status) {
fprintf(stderr, "Error adding directory to zip.\n");
}
status = mz_zip_writer_add_mem(zip, "Pictures/", NULL, 0, MZ_BEST_COMPRESSION);
+
if (!status) {
fprintf(stderr, "Error adding directory to zip.\n");
}
len = strlen(data);
status = mz_zip_writer_add_mem(zip, "META-INF/manifest.xml", data, len, MZ_BEST_COMPRESSION);
free(data);
+
if (!status) {
fprintf(stderr, "Error adding manifest to zip.\n");
}
len = strlen(data);
status = mz_zip_writer_add_mem(zip, "content.xml", data, len, MZ_BEST_COMPRESSION);
free(data);
+
if (!status) {
fprintf(stderr, "Error adding content.xml to zip.\n");
}
free(result->str);
status = mz_zip_writer_finalize_heap_archive(zip, (void **) &(result->str), (size_t *) &(result->currentStringLength));
+
if (!status) {
fprintf(stderr, "Error finalizing zip archive.\n");
}
#endif
{
register int i,j;
- for (j=0; j<KK; j++) aa[j]=ran_x[j];
- for (; j<n; j++) aa[j]=mod_diff(aa[j-KK],aa[j-LL]);
- for (i=0; i<LL; i++,j++) ran_x[i]=mod_diff(aa[j-KK],aa[j-LL]);
- for (; i<KK; i++,j++) ran_x[i]=mod_diff(aa[j-KK],ran_x[i-LL]);
+
+ for (j=0; j<KK; j++) {
+ aa[j]=ran_x[j];
+ }
+
+ for (; j<n; j++) {
+ aa[j]=mod_diff(aa[j-KK],aa[j-LL]);
+ }
+
+ for (i=0; i<LL; i++,j++) {
+ ran_x[i]=mod_diff(aa[j-KK],aa[j-LL]);
+ }
+
+ for (; i<KK; i++,j++) {
+ ran_x[i]=mod_diff(aa[j-KK],ran_x[i-LL]);
+ }
}
/* the following routines are from exercise 3.6--15 */
register int t,j;
long x[KK+KK-1]; /* the preparation buffer */
register long ss=(seed+2)&(MM-2);
+
for (j=0; j<KK; j++) {
x[j]=ss; /* bootstrap the buffer */
ss<<=1;
- if (ss>=MM) ss-=MM-2; /* cyclic shift 29 bits */
+
+ if (ss>=MM) {
+ ss-=MM-2; /* cyclic shift 29 bits */
+ }
}
+
x[1]++; /* make x[1] (and only x[1]) odd */
+
for (ss=seed&(MM-1),t=TT-1; t; ) {
- for (j=KK-1; j>0; j--) x[j+j]=x[j], x[j+j-1]=0; /* "square" */
+ for (j=KK-1; j>0; j--) {
+ x[j+j]=x[j], x[j+j-1]=0; /* "square" */
+ }
+
for (j=KK+KK-2; j>=KK; j--)
x[j-(KK-LL)]=mod_diff(x[j-(KK-LL)],x[j]),
x[j-KK]=mod_diff(x[j-KK],x[j]);
+
if (is_odd(ss)) { /* "multiply by z" */
- for (j=KK; j>0; j--) x[j]=x[j-1];
+ for (j=KK; j>0; j--) {
+ x[j]=x[j-1];
+ }
+
x[0]=x[KK]; /* shift the buffer cyclically */
x[LL]=mod_diff(x[LL],x[KK]);
}
- if (ss) ss>>=1;
- else t--;
+
+ if (ss) {
+ ss>>=1;
+ } else {
+ t--;
+ }
+ }
+
+ for (j=0; j<LL; j++) {
+ ran_x[j+KK-LL]=x[j];
}
- for (j=0; j<LL; j++) ran_x[j+KK-LL]=x[j];
- for (; j<KK; j++) ran_x[j-LL]=x[j];
- for (j=0; j<10; j++) ran_array(x,KK+KK-1); /* warm things up */
+
+ for (; j<KK; j++) {
+ ran_x[j-LL]=x[j];
+ }
+
+ for (j=0; j<10; j++) {
+ ran_array(x,KK+KK-1); /* warm things up */
+ }
+
ran_arr_ptr=&ran_arr_started;
}
#define ran_arr_next() (*ran_arr_ptr>=0? *ran_arr_ptr++: ran_arr_cycle())
long ran_arr_cycle() {
- if (ran_arr_ptr==&ran_arr_dummy)
- ran_start(314159L); /* the user forgot to initialize */
+ if (ran_arr_ptr==&ran_arr_dummy) {
+ ran_start(314159L); /* the user forgot to initialize */
+ }
+
ran_array(ran_arr_buf,QUALITY);
ran_arr_buf[KK]=-1;
ran_arr_ptr=ran_arr_buf+1;
stack * s = malloc(sizeof(stack));
if (s) {
- if (startingSize <= 0)
+ if (startingSize <= 0) {
startingSize = kStackStartingSize;
+ }
s->element = malloc(sizeof(void *) * startingSize);
void * stack_pop(stack * s) {
void * last = stack_peek(s);
- if (s->size != 0)
+ if (s->size != 0) {
s->size--;
+ }
return last;
}
/// Peek at the top item on the stack
void * stack_peek(stack * s) {
- if (s->size == 0)
+ if (s->size == 0) {
return NULL;
+ }
return s->element[(s->size) - 1];
}
/// Peek at a specific index in the stack
void * stack_peek_index(stack * s, size_t index) {
- if (index >= s->size)
+ if (index >= s->size) {
return NULL;
+ }
return s->element[index];
}
static bool add_asset_from_file(mz_zip_archive * pZip, asset * a, const char * destination, const char * directory) {
- if (!directory)
+ if (!directory) {
return false;
+ }
char * path = path_from_dir_base(directory, a->url);
mz_bool status;
struct MemoryStruct * mem = (struct MemoryStruct *)userp;
mem->memory = realloc(mem->memory, mem->size + realsize + 1);
+
if (mem->memory == NULL) {
// Out of memory
fprintf(stderr, "Out of memory\n");
free(clean);
}
+
break;
+
case BLOCK_EMPTY:
+
// Is this a link definition?
for (int i = 0; i < e->definition_stack->size; ++i) {
if (t == stack_peek_index(e->definition_stack, i)) {
// Find matching link
for (int j = 0; j < e->link_stack->size; ++j) {
l = stack_peek_index(e->link_stack, j);
+
if (l->label->start == t->child->start) {
// This is a match
HASH_FIND_STR(e->asset_hash, l->url, a);
}
}
}
+
break;
+
default:
if (t->child) {
traverse_for_images(t->child, text, e, offset, destination, url);
}
+
break;
}
for (int i = 0; i < e->metadata_stack->size; ++i) {
m = stack_peek_index(e->metadata_stack, i);
+
if (strcmp("css", m->key) == 0) {
// Get METADATA range
t = e->root->child;
// Substitute inside metadata block
HASH_FIND_STR(e->asset_hash, m->value, a);
+
if (a) {
memcpy(&destination[7], a->asset_path, 36);
offset += d_string_replace_text_in_range(text, t->start, t->len, m->value, destination);
len = strlen(data);
status = mz_zip_writer_add_mem(&zip, "info.json", data, len, MZ_BEST_COMPRESSION);
free(data);
+
if (!status) {
fprintf(stderr, "Error adding JSON info to zip.\n");
}
// Create directories
status = mz_zip_writer_add_mem(&zip, "assets/", NULL, 0, MZ_BEST_COMPRESSION);
+
if (!status) {
fprintf(stderr, "Error adding assets directory to zip.\n");
}
len = temp->currentStringLength;
status = mz_zip_writer_add_mem(&zip, "text.markdown", temp->str, len, MZ_BEST_COMPRESSION);
+
if (!status) {
fprintf(stderr, "Error adding content to zip.\n");
}
// Add html version document
len = strlen(body);
status = mz_zip_writer_add_mem(&zip, "text.html", body, len, MZ_BEST_COMPRESSION);
+
if (!status) {
fprintf(stderr, "Error adding content to zip.\n");
}
free(result->str);
status = mz_zip_writer_finalize_heap_archive(&zip, (void **) &(result->str), (size_t *) &(result->currentStringLength));
+
if (!status) {
fprintf(stderr, "Error finalizing zip.\n");
}
// Decrement counter
token_pool_count--;
- if (token_pool_count == 0)
+ if (token_pool_count == 0) {
pool_drain(token_pool);
+ }
}
} else if (child->next == NULL) {
t->len = child->len;
} else {
- while (child->next != NULL)
+ while (child->next != NULL) {
child = child->next;
+ }
t->len = child->start + child->len - t->start;
}
/// may or may not also be the start of a chain
void token_chain_append(token * chain_start, token * t) {
if ((chain_start == NULL) ||
- (t == NULL))
+ (t == NULL)) {
return;
+ }
// Append t
chain_start->tail->next = t;
/// token chain. The new token may or may not be
/// the start of a chain.
void token_append_child(token * parent, token * t) {
- if ((parent == NULL) || (t == NULL))
+ if ((parent == NULL) || (t == NULL)) {
return;
+ }
if (parent->child == NULL) {
// Parent has no children
/// Remove the first child of a token
void token_remove_first_child(token * parent) {
- if ((parent == NULL) || (parent->child == NULL))
+ if ((parent == NULL) || (parent->child == NULL)) {
return;
+ }
token * t = parent->child;
parent->child = t->next;
/// Remove the last child of a token
void token_remove_last_child(token * parent) {
- if ((parent == NULL) || (parent->child == NULL))
+ if ((parent == NULL) || (parent->child == NULL)) {
return;
+ }
token * t = parent->child->tail;
/// Remove the last token in a chain
void token_remove_tail(token * head) {
- if ((head == NULL) || (head->tail == head))
+ if ((head == NULL) || (head->tail == head)) {
return;
+ }
token * t = head->tail;
/// Token must be freed if it is no longer needed.
/// \todo: If t is the tail token of a chain, the tail is no longer correct on the start of chain.
void token_pop_link_from_chain(token * t) {
- if (t == NULL)
+ if (t == NULL) {
return;
+ }
token * prev = t->prev;
token * next = t->next;
/// Remove one or more tokens from chain
void tokens_prune(token * first, token * last) {
- if (first == NULL || last == NULL)
+ if (first == NULL || last == NULL) {
return;
+ }
token * prev = first->prev;
token * next = last->next;
- if (prev != NULL)
+ if (prev != NULL) {
prev->next = next;
+ }
- if (next != NULL)
+ if (next != NULL) {
next->prev = prev;
+ }
first->prev = NULL;
last->next = NULL;
/// Given a start/stop point in token chain, create a new container token.
/// Return pointer to new container token.
token * token_prune_graft(token * first, token * last, unsigned short container_type) {
- if (first == NULL || last == NULL)
+ if (first == NULL || last == NULL) {
return first;
+ }
token * next = last->next;
token * new_child = token_copy(first);
new_child->prev = NULL;
new_child->tail = last;
+
if (new_child->next) {
new_child->next->prev = new_child;
}
// Swap last (if necessary)
- if (first == last)
+ if (first == last) {
last = new_child;
+ }
// Existing first token will be new container
first->child = new_child;
// Disconnect last token
last->next = NULL;
- if (next)
+ if (next) {
next->prev = first;
+ }
return first;
}
#ifdef kUseObjectPool
return;
#else
- if (t == NULL)
+
+ if (t == NULL) {
return;
+ }
token_tree_free(t->child);
t = n;
}
+
#endif
}
for (int i = 0; i < depth; ++i) {
fprintf(stderr, "\t");
}
+
if (string == NULL) {
fprintf(stderr, "* (%d) %lu:%lu\n", t->type, t->start, t->len);
} else {
fprintf(stderr, "* (%d) %lu:%lu\t'%.*s'\n", t->type, t->start, t->len, (int)t->len, &string[t->start]);
}
- if (t->child != NULL)
+ if (t->child != NULL) {
print_token_tree(t->child, depth + 1, string);
+ }
}
}
/// Print a description of the token tree based on specified string
void token_tree_describe(token * t, const char * string) {
fprintf(stderr, "=====>\n");
+
while (t != NULL) {
print_token(t, 0, string);
t = t->next;
}
+
fprintf(stderr, "<=====\n");
}
token * parent, //!< Pointer to parent token
size_t offset //!< Search position
) {
- if (parent == NULL)
+ if (parent == NULL) {
return NULL;
+ }
if ((parent->start > offset) ||
- (parent->start + parent->len < offset))
+ (parent->start + parent->len < offset)) {
return NULL;
+ }
token * walker = parent->child;
return walker;
}
}
- if (walker->start > offset)
+
+ if (walker->start > offset) {
return NULL;
+ }
walker = walker->next;
}
size_t start, //!< Start search position
size_t len //!< Search length
) {
- if (parent == NULL)
+ if (parent == NULL) {
return NULL;
+ }
if ((parent->start > start + len) ||
- (parent->start + parent->len < start))
+ (parent->start + parent->len < start)) {
return NULL;
+ }
token * walker = parent->child;
while (walker != NULL) {
- if (ranges_intersect(start, len, walker->start, walker->len))
+ if (ranges_intersect(start, len, walker->start, walker->len)) {
return walker;
+ }
- if (walker->start > start)
+ if (walker->start > start) {
return NULL;
+ }
walker = walker->next;
}
size_t start, //!< Start search position
size_t len //!< Search length
) {
- if (parent == NULL)
+ if (parent == NULL) {
return NULL;
+ }
if ((parent->start > start + len) ||
- (parent->start + parent->len < start))
+ (parent->start + parent->len < start)) {
return NULL;
+ }
token * walker = parent->child;
token * last = NULL;
while (walker != NULL) {
- if (ranges_intersect(start, len, walker->start, walker->len))
+ if (ranges_intersect(start, len, walker->start, walker->len)) {
last = walker;
+ }
- if (walker->start > start + len)
+ if (walker->start > start + len) {
return last;
+ }
walker = walker->next;
}
for (int i = 0; i < n; ++i) {
result = token_chain_accept(t, va_arg(valist, int));
- if (result)
+
+ if (result) {
break;
+ }
}
va_end(valist);
void token_skip_until_type(token ** t, short type) {
- while ((*t) && ((*t)->type != type))
+ while ((*t) && ((*t)->type != type)) {
*t = (*t)->next;
+ }
}
//
while (*t) {
for (int i = 0; i < n; ++i) {
- if ((*t)->type == type[i])
+ if ((*t)->type == type[i]) {
return;
+ }
}
*t = (*t)->next;
void token_split_on_char(token * t, const char * source, const char c) {
- if (!t)
+ if (!t) {
return;
+ }
size_t start = t->start;
size_t pos = 0;
// Split a token and create new ones as needed
void token_split(token * t, size_t start, size_t len, unsigned short new_type) {
- if (!t)
+ if (!t) {
return;
+ }
size_t stop = start + len;
- if (start < t->start)
+ if (start < t->start) {
return;
+ }
- if (stop > t->start + t->len)
+ if (stop > t->start + t->len) {
return;
+ }
token * A; // This will be new token
bool inset_start = false;
bool inset_stop = false;
// Will we need a leading token?
- if (start > t->start)
+ if (start > t->start) {
inset_start = true;
+ }
// Will we need a lagging token?
- if (stop < t->start + t->len)
+ if (stop < t->start + t->len) {
inset_stop = true;
+ }
if (inset_start) {
A = token_new(new_type, start, len);
+
if (inset_stop) {
// We will end up with t->A->T2
token * T2 = token_new(t->type, stop, t->start + t->len - stop);
T2->next = t->next;
- if (t->next)
+ if (t->next) {
t->next->prev = T2;
+ }
A->next = T2;
T2->prev = A;
// We will end up with T->A
A->next = t->next;
- if (t->next)
+ if (t->next) {
t->next->prev = A;
+ }
}
t->next = A;
A->next = t->next;
t->next = A;
- if (A->next)
+ if (A->next) {
A->next->prev = A;
+ }
t->len = stop - t->start;
t->type = new_type;
/// Free existing token pair engine
void token_pair_engine_free(token_pair_engine * e) {
- if (e == NULL)
+ if (e == NULL) {
return;
+ }
free(e);
}
e->can_close_pair[close_type] = 1;
(e->pair_type)[open_type][close_type] = pair_type;
- if (options & PAIRING_ALLOW_EMPTY)
+ if (options & PAIRING_ALLOW_EMPTY) {
e->empty_allowed[pair_type] = true;
+ }
- if (options & PAIRING_MATCH_LENGTH)
+ if (options & PAIRING_MATCH_LENGTH) {
e->match_len[pair_type] = true;
+ }
- if (options & PAIRING_PRUNE_MATCH)
+ if (options & PAIRING_PRUNE_MATCH) {
e->should_prune[pair_type] = true;
+ }
}
/// Mate opener and closer together
void token_pair_mate(token * a, token * b) {
- if (a == NULL | b == NULL)
+ if (a == NULL | b == NULL) {
return;
+ }
a->mate = b;
a->unmatched = false;
void token_pairs_match_pairs_inside_token(token * parent, token_pair_engine * e, stack * s, unsigned short depth) {
// Avoid stack overflow in "pathologic" input
- if (depth == kMaxPairRecursiveDepth)
+ if (depth == kMaxPairRecursiveDepth) {
return;
+ }
// Walk the child chain
token * walker = parent->child;
if (i > start_counter + kLargeStackThreshold) {
for (int j = 0; j < kMaxTokenTypes; ++j) {
if (opener_count[j]) {
- if (e->pair_type[j][walker->type])
+ if (e->pair_type[j][walker->type]) {
goto close;
+ }
}
}
}
close:
+
// Find matching opener for this closer
while (i > start_counter) {
peek = stack_peek_index(s, i - 1);
peek = stack_pop(s);
opener_count[peek->type]--;
}
+
#ifndef NDEBUG
fprintf(stderr, "stack now sized %lu\n", s->size);
#endif
break;
}
+
#ifndef NDEBUG
else {
fprintf(stderr, "token type %d failed to match stack element\n", walker->type);
}
+
#endif
i--;
}
}
open:
+
// Is this an opener?
if (walker->can_open && e->can_open_pair[walker->type] && walker->unmatched) {
stack_push(s, walker);
// strlen is too slow if strlen(source) >> n
for (len = 0; len < n; ++len) {
- if (test == '\0')
+ if (test == '\0') {
break;
+ }
test++;
}
/// Combine directory and base filename to create a full path */
char * path_from_dir_base(const char * dir, const char * base) {
- if (!dir && !base)
+ if (!dir && !base) {
return NULL;
+ }
DString * path = NULL;
add_trailing_sep(path);
// Append filename (if present)
- if (base)
+ if (base) {
d_string_append(path, base);
+ }
}
result = path->str;
const char sep[] = "/";
#endif
- while ((next = strpbrk(slash + 1, sep)))
+ while ((next = strpbrk(slash + 1, sep))) {
slash = next;
+ }
- if (path != slash)
+ if (path != slash) {
slash++;
+ }
*dir = my_strndup(path, slash - path);
*file = my_strdup(slash);
if ((file = _wfopen(wstr, L"r")) == NULL) {
#else
+
if ((file = fopen(fname, "r")) == NULL ) {
#endif
size_t last_match;
mmd_engine * e = mmd_engine_create_with_dstring(source, EXT_TRANSCLUDE);
+
if (mmd_engine_has_metadata(e, &offset)) {
temp = mmd_engine_metavalue_for_key(e, "transclude base");
while (start != NULL) {
stop = strstr(start, "}}");
- if (stop == NULL)
+ if (stop == NULL) {
break;
+ }
// Remember insertion point
last_match = start - source->str;
case FORMAT_HTML:
d_string_append(file_path, ".html");
break;
+
case FORMAT_LATEX:
case FORMAT_BEAMER:
case FORMAT_MEMOIR:
d_string_append(file_path, ".tex");
break;
+
case FORMAT_FODT:
d_string_append(file_path, ".fodt");
break;
+
default:
d_string_append(file_path, ".txt");
break;
// Prevent infinite recursive loops
for (int i = 0; i < stack_depth; ++i) {
temp = stack_peek_index(parse_stack, i);
+
if (strcmp(file_path->str, temp) == 0) {
// We have parsed this file already, don't recurse infinitely
last_match += 2;
for (int i = 0; i < manifest->size; ++i) {
temp = stack_peek_index(manifest, i);
+
if (strcmp(file_path->str, temp) == 0) {
// Already on manifest, don't duplicate
add = false;
}
// Add path to manifest
- if (add)
+ if (add) {
stack_push(manifest, my_strdup(file_path->str));
+ }
}
// Read the file
d_string_erase(buffer, 0, offset);
} else {
// Do we need to strip BOM?
- if (strncmp(buffer->str, "\xef\xbb\xbf",3) == 0)
+ if (strncmp(buffer->str, "\xef\xbb\xbf",3) == 0) {
d_string_erase(buffer, 0, 3);
+ }
}
mmd_engine_free(e, false);
// strlen is too slow is strlen(source) >> n
for (len = 0; len < n; ++len) {
- if (test == '\0')
+ if (test == '\0') {
break;
+ }
test++;
}
while (scratch->inline_footnotes_to_free->size) {
footnote_free(stack_pop(scratch->inline_footnotes_to_free));
}
+
stack_free(scratch->inline_footnotes_to_free);
while (scratch->inline_citations_to_free->size) {
footnote_free(stack_pop(scratch->inline_citations_to_free));
}
+
stack_free(scratch->inline_citations_to_free);
free(scratch->bibtex_file);
while (scratch->inline_glossaries_to_free->size) {
footnote_free(stack_pop(scratch->inline_glossaries_to_free));
}
+
stack_free(scratch->inline_glossaries_to_free);
while (scratch->inline_abbreviations_to_free->size) {
footnote_free(stack_pop(scratch->inline_abbreviations_to_free));
}
+
stack_free(scratch->inline_abbreviations_to_free);
case STRONG_STOP:
case TEXT_EMPTY:
break;
+
case PAIR_EMPH:
case PAIR_STRONG:
print_token_tree_raw(out, source, t->child);
break;
+
default:
d_string_append_c_array(out, &source[t->start], t->len);
break;
// [foo], [^foo], [#foo] should give different strings -- use closer len
result = my_strndup(&source[pair->start + pair->child->mate->len], pair->len - (pair->child->mate->len * 2));
} else {
- if (pair->child)
+ if (pair->child) {
result = my_strndup(&source[pair->start + pair->child->len], pair->len - (pair->child->len + 1));
+ }
}
}
char * label_from_header(const char * source, token * t) {
char * result;
token * temp_token = manual_label_from_header(t, source);
+
if (temp_token) {
result = label_from_token(source, temp_token);
} else {
/// Clean up whitespace in string for standardization
char * clean_string(const char * str, bool lowercase) {
- if (str == NULL)
+ if (str == NULL) {
return NULL;
+ }
DString * out = d_string_new("");
char * clean = NULL;
d_string_append_c(out, ' ');
block_whitespace = true;
}
+
break;
+
default:
- if (lowercase)
+ if (lowercase) {
d_string_append_c(out, tolower(*str));
- else
+ } else {
d_string_append_c(out, *str);
+ }
block_whitespace = false;
break;
if (l) {
l->label = label;
+
if (label) {
l->clean_text = clean_inside_pair(source, label, true);
l->label_text = label_from_token(source, label);
l->clean_text = NULL;
l->label_text = NULL;
}
+
l->url = clean_string(url, false);
l->title = (title == NULL) ? NULL : my_strdup(title);
l->attributes = (attributes == NULL) ? NULL : parse_attributes(attributes);
HASH_FIND_STR(scratch->link_hash, key, l);
- if (l)
+ if (l) {
return l;
+ }
char * clean = clean_string(key, true);
free(key);
- if (temp)
+ if (temp) {
return temp;
+ }
key = label_from_string(target);
size_t start;
size_t scan_len;
- if (*remainder == NULL)
+ if (*remainder == NULL) {
return url;
+ }
switch ((*remainder)->type) {
case PAIR_PAREN:
t = token_chain_accept_multiple(remainder, 2, PAIR_ANGLE, PAIR_PAREN);
url = text_inside_pair(source, t);
break;
+
default:
start = (*remainder)->start;
// Skip any whitespace
- while (char_is_whitespace(source[start]))
+ while (char_is_whitespace(source[start])) {
start++;
+ }
scan_len = scan_destination(&source[start]);
scan_len = scan_destination(&source[start]);
if (scan_len) {
- if (scan_len > max_len)
+ if (scan_len > max_len) {
scan_len = max_len;
+ }
- if (end_pos)
+ if (end_pos) {
*end_pos = start + scan_len;
+ }
// Is this <foo>?
if ((source[start] == '<') &&
size_t attr_len;
// Skip whitespace
- while (char_is_whitespace(source[pos]))
+ while (char_is_whitespace(source[pos])) {
pos++;
+ }
// Grab URL
*url = url_accept(source, pos, paren->start + paren->len - 1 - pos, &pos, false);
// Skip whitespace
- while (char_is_whitespace(source[pos]))
+ while (char_is_whitespace(source[pos])) {
pos++;
+ }
// Grab title, if present
scan_len = scan_title(&source[pos]);
}
// Skip whitespace
- while (char_is_whitespace(source[pos]))
+ while (char_is_whitespace(source[pos])) {
pos++;
+ }
// Grab attributes, if present
attr_len = scan_attributes(&source[pos]);
extract_from_paren(paren, source, &url_char, &title_char, &attr_char);
if (attr_char) {
- if (!(scratch->extensions & EXT_COMPATIBILITY))
+ if (!(scratch->extensions & EXT_COMPATIBILITY)) {
l = link_new(source, NULL, url_char, title_char, attr_char);
+ }
} else {
l = link_new(source, NULL, url_char, title_char, attr_char);
}
case BLOCK_PARA:
f->content = content;
break;
+
case TEXT_PLAIN:
token_trim_leading_whitespace(content, source);
+
default:
f->content = token_new_parent(content, BLOCK_PARA);
f->free_para = true;
free(f->content);
#endif
}
+
free(f->clean_text);
free(f->label_text);
void meta_set_value(meta * m, const char * value) {
if (value) {
- if (m->value)
+ if (m->value) {
free(m->value);
+ }
m->value = clean_string(value, false);
}
meta * m = extract_meta_from_stack(scratch, clean);
free(clean);
- if (m)
+
+ if (m) {
return m->value;
+ }
return NULL;
}
case PAIR_BRACKET_FOOTNOTE:
case PAIR_BRACKET_GLOSSARY:
if (e->extensions & EXT_NOTES) {
- if (!token_chain_accept(remainder, COLON))
+ if (!token_chain_accept(remainder, COLON)) {
return false;
+ }
title = *remainder; // Track first token of content in 'title'
f = footnote_new(e->dstr->str, label, title, true);
stack_push(e->citation_stack, f);
break;
+
case PAIR_BRACKET_FOOTNOTE:
f = footnote_new(e->dstr->str, label, title, true);
stack_push(e->footnote_stack, f);
break;
+
case PAIR_BRACKET_GLOSSARY:
f = footnote_new(e->dstr->str, label, title, false);
stack_push(e->glossary_stack, f);
break;
}
+
case PAIR_BRACKET:
+
// Reference Link Definition
- if (!token_chain_accept(remainder, COLON))
+ if (!token_chain_accept(remainder, COLON)) {
return false;
+ }
// Skip space
whitespace_accept(remainder);
title = token_chain_accept_multiple(remainder, 2, PAIR_QUOTE_DOUBLE, PAIR_QUOTE_SINGLE);
- if (!title)
+ if (!title) {
*remainder = temp;
+ }
}
title_char = text_inside_pair(e->dstr->str, title);
// Skip forward
attr_len += (*remainder)->start;
- while ((*remainder) && (*remainder)->start < attr_len)
+ while ((*remainder) && (*remainder)->start < attr_len) {
*remainder = (*remainder)->next;
+ }
}
l = link_new(e->dstr->str, label, url_char, title_char, attr_char);
}
// Store link for later use
- if (l)
+ if (l) {
stack_push(e->link_stack, l);
+ }
break;
+
case PAIR_BRACKET_VARIABLE:
fprintf(stderr, "Process variable:\n");
token_describe(label, e->dstr->str);
break;
+
default:
// Rest of block is not definitions (or has already been processed)
return false;
// Advance to next line
token_skip_until_type_multiple(remainder, 2, TEXT_NL, TEXT_LINEBREAK);
- if (*remainder)
+
+ if (*remainder) {
*remainder = (*remainder)->next;
+ }
// Clean up
free(url_char);
footnote * f;
token * label = block->child;
- if (label->type == BLOCK_PARA)
+
+ if (label->type == BLOCK_PARA) {
label = label->child;
+ }
switch (block->type) {
case BLOCK_DEF_ABBREVIATION:
case BLOCK_DEF_ABBREVIATION:
// Strip leading '>'' from term
f = footnote_new(e->dstr->str, label, block->child, false);
+
if (f && f->clean_text) {
memmove(f->clean_text, &(f->clean_text)[1],strlen(f->clean_text));
+
while (char_is_whitespace((f->clean_text)[0])) {
memmove(f->clean_text, &(f->clean_text)[1],strlen(f->clean_text));
}
// Adjust the properties
free(f->label_text);
f->label_text = f->clean_text;
+
if (f->content->child &&
f->content->child->next &&
f->content->child->next->next) {
} else {
f->clean_text = NULL;
}
+
stack_push(e->abbreviation_stack, f);
break;
+
case BLOCK_DEF_CITATION:
f = footnote_new(e->dstr->str, label, block->child, true);
stack_push(e->citation_stack, f);
break;
+
case BLOCK_DEF_FOOTNOTE:
f = footnote_new(e->dstr->str, label, block->child, true);
stack_push(e->footnote_stack, f);
break;
+
case BLOCK_DEF_GLOSSARY:
// Strip leading '?' from term
f = footnote_new(e->dstr->str, label, block->child, false);
- if (f && f->clean_text)
+
+ if (f && f->clean_text) {
memmove(f->clean_text, &(f->clean_text)[1],strlen(f->clean_text));
+ }
+
//if (f && f->label_text)
// memmove(f->label_text, &(f->label_text)[1],strlen(f->label_text));
stack_push(e->glossary_stack, f);
break;
}
+
label->type = TEXT_EMPTY;
- if (label->next)
+
+ if (label->next) {
label->next->type = TEXT_EMPTY;
+ }
+
strip_leading_whitespace(label, e->dstr->str);
break;
+
case BLOCK_DEF_LINK:
definition_extract(e, &(label));
break;
+
default:
fprintf(stderr, "process %d\n", block->type);
}
}
token * manual_label_from_header(token * h, const char * source) {
- if (!h || !h->child)
+ if (!h || !h->child) {
return NULL;
+ }
token * walker = h->child->tail;
token * label = NULL;
label = walker;
walker = NULL;
break;
+
case INDENT_TAB:
case INDENT_SPACE:
case NON_INDENT_SPACE:
case MARKER_H6:
walker = walker->prev;
break;
+
case TEXT_PLAIN:
if (walker->len == 1) {
if (source[walker->start] == ' ') {
break;
}
}
+
walker = NULL;
break;
+
case PAIR_BRACKET:
label = walker;
+
while(walker && walker->type == PAIR_BRACKET) {
walker = walker->prev;
count++;
}
+
if (count % 2 == 0) {
// Even count
label = NULL;
// Odd count
label->type = MANUAL_LABEL;
}
+
default:
walker = NULL;
}
void process_header_stack(mmd_engine * e) {
// NTD in compatibility mode or if disabled
- if (e->extensions & EXT_NO_LABELS)
+ if (e->extensions & EXT_NO_LABELS) {
return;
+ }
for (int i = 0; i < e->header_stack->size; ++i) {
process_header_to_links(e, stack_peek_index(e->header_stack, i));
/// Parse metadata
void process_metadata_stack(mmd_engine * e, scratch_pad * scratch) {
if ((scratch->extensions & EXT_NO_METADATA) ||
- (scratch->extensions & EXT_COMPATIBILITY))
+ (scratch->extensions & EXT_COMPATIBILITY)) {
return;
+ }
meta * m;
short header_level = -10;
m = stack_peek_index(e->metadata_stack, i);
if (strcmp(m->key, "baseheaderlevel") == 0) {
- if (header_level == -10)
+ if (header_level == -10) {
header_level = atoi(m->value);
+ }
} else if (strcmp(m->key, "epubheaderlevel") == 0) {
- if (scratch->output_format == FORMAT_EPUB)
+ if (scratch->output_format == FORMAT_EPUB) {
header_level = atoi(m->value);
+ }
} else if (strcmp(m->key, "htmlheaderlevel") == 0) {
- if (scratch->output_format == FORMAT_HTML)
+ if (scratch->output_format == FORMAT_HTML) {
header_level = atoi(m->value);
+ }
} else if (strcmp(m->key, "xhtmlheaderlevel") == 0) {
- if (scratch->output_format == FORMAT_HTML)
+ if (scratch->output_format == FORMAT_HTML) {
header_level = atoi(m->value);
+ }
} else if (strcmp(m->key, "latexheaderlevel") == 0) {
if ((scratch->output_format == FORMAT_LATEX) ||
(scratch->output_format == FORMAT_BEAMER) ||
- (scratch->output_format == FORMAT_MEMOIR))
+ (scratch->output_format == FORMAT_MEMOIR)) {
header_level = atoi(m->value);
+ }
} else if (strcmp(m->key, "odfheaderlevel") == 0) {
if ((scratch->output_format == FORMAT_ODT) ||
- (scratch->output_format == FORMAT_FODT))
+ (scratch->output_format == FORMAT_FODT)) {
header_level = atoi(m->value);
+ }
} else if (strcmp(m->key, "language") == 0) {
temp_char = label_from_string(m->value);
free(temp_char);
} else if (strcmp(m->key, "bibtex") == 0) {
scratch->bibtex_file = my_strdup(m->value);
+
// Trigger complete document unless explicitly denied
- if (!(scratch->extensions & EXT_SNIPPET))
+ if (!(scratch->extensions & EXT_SNIPPET)) {
scratch->extensions |= EXT_COMPLETE;
+ }
} else {
// Any other key triggers complete document
- if (!(scratch->extensions & EXT_SNIPPET))
+ if (!(scratch->extensions & EXT_SNIPPET)) {
scratch->extensions |= EXT_COMPLETE;
+ }
}
}
- if (header_level != -10)
+ if (header_level != -10) {
scratch->base_header_level = header_level;
+ }
}
token_split(tok, walker->start, walker->len, walker->match_type);
// Advance token to next token
- while (tok->start < walker->start + walker->len)
+ while (tok->start < walker->start + walker->len) {
tok = tok->next;
+ }
// Advance to next match (if present)
walker = walker->next;
case TEXT_PLAIN:
automatic_search_text(e, t, ac);
break;
+
case DOC_START_TOKEN:
case BLOCK_BLOCKQUOTE:
case BLOCK_DEFINITION:
case TABLE_ROW:
automatic_search(e, t->child, ac);
break;
+
// case PAIR_PAREN:
default:
break;
process_metadata_stack(e, scratch);
// Process abbreviations, glossary, etc.
- if (!(e->extensions & EXT_COMPATIBILITY))
+ if (!(e->extensions & EXT_COMPATIBILITY)) {
identify_global_search_terms(e, scratch);
+ }
switch (scratch->output_format) {
case FORMAT_BEAMER:
- if (scratch->extensions & EXT_COMPLETE)
+ if (scratch->extensions & EXT_COMPLETE) {
mmd_start_complete_latex(out, e->dstr->str, scratch);
+ }
mmd_export_token_tree_beamer(out, e->dstr->str, e->root, scratch);
mmd_export_citation_list_beamer(out, e->dstr->str, scratch);
- if (scratch->extensions & EXT_COMPLETE)
+ if (scratch->extensions & EXT_COMPLETE) {
mmd_end_complete_beamer(out, e->dstr->str, scratch);
+ }
break;
+
case FORMAT_EPUB:
case FORMAT_TEXTBUNDLE:
case FORMAT_TEXTBUNDLE_COMPRESSED:
mmd_end_complete_html(out, e->dstr->str, scratch);
break;
+
case FORMAT_HTML:
- if (scratch->extensions & EXT_COMPLETE)
+ if (scratch->extensions & EXT_COMPLETE) {
mmd_start_complete_html(out, e->dstr->str, scratch);
+ }
mmd_export_token_tree_html(out, e->dstr->str, e->root, scratch);
mmd_export_footnote_list_html(out, e->dstr->str, scratch);
mmd_export_glossary_list_html(out, e->dstr->str, scratch);
mmd_export_citation_list_html(out, e->dstr->str, scratch);
- if (scratch->extensions & EXT_COMPLETE)
+ if (scratch->extensions & EXT_COMPLETE) {
mmd_end_complete_html(out, e->dstr->str, scratch);
+ }
break;
+
case FORMAT_LATEX:
- if (scratch->extensions & EXT_COMPLETE)
+ if (scratch->extensions & EXT_COMPLETE) {
mmd_start_complete_latex(out, e->dstr->str, scratch);
+ }
mmd_export_token_tree_latex(out, e->dstr->str, e->root, scratch);
mmd_export_citation_list_latex(out, e->dstr->str, scratch);
- if (scratch->extensions & EXT_COMPLETE)
+ if (scratch->extensions & EXT_COMPLETE) {
mmd_end_complete_latex(out, e->dstr->str, scratch);
+ }
break;
+
case FORMAT_MEMOIR:
- if (scratch->extensions & EXT_COMPLETE)
+ if (scratch->extensions & EXT_COMPLETE) {
mmd_start_complete_latex(out, e->dstr->str, scratch);
+ }
mmd_export_token_tree_memoir(out, e->dstr->str, e->root, scratch);
mmd_export_citation_list_latex(out, e->dstr->str, scratch);
- if (scratch->extensions & EXT_COMPLETE)
+ if (scratch->extensions & EXT_COMPLETE) {
mmd_end_complete_latex(out, e->dstr->str, scratch);
+ }
break;
+
case FORMAT_ODT:
scratch->store_assets = true;
+
case FORMAT_FODT:
// mmd_start_complete_odf(out, e->dstr->str, scratch);
// What is next?
token * next = bracket->next;
- if (next)
+ if (next) {
temp_short = 1;
+ }
// Do not free this link after using it
*free_link = false;
// But not if it's nested brackets, since it would not
// end up being a valid reference
token * walker = bracket->child;
+
while (walker) {
switch (walker->type) {
case PAIR_BRACKET:
temp_link = extract_link_from_stack(scratch, temp_char);
- if (temp_char)
+ if (temp_char) {
free(temp_char);
+ }
if (temp_link) {
// Don't output brackets
if (bracket->child) {
bracket->child->type = TEXT_EMPTY;
- if (bracket->child->mate)
+ if (bracket->child->mate) {
bracket->child->mate->type = TEXT_EMPTY;
+ }
}
*final_link = temp_link;
// Create glossary
token * label = t->child;
- while (label && label->type != PAIR_PAREN)
+
+ while (label && label->type != PAIR_PAREN) {
label = label->next;
+ }
if (label) {
footnote * temp = footnote_new(source, label, label->next, false);
// Create glossary
token * label = t->child;
- while (label && label->type != PAIR_PAREN)
+
+ while (label && label->type != PAIR_PAREN) {
label = label->next;
+ }
if (label) {
footnote * temp = footnote_new(source, label, label->next, false);
// Adjust the properties
free(temp->label_text);
temp->label_text = temp->clean_text;
- if (temp->content && temp->content->child)
+
+ if (temp->content && temp->content->child) {
temp->clean_text = clean_string_from_range(source, temp->content->child->start, t->start + t->len - t->child->mate->len - temp->content->child->start, false);
+ }
// Store as used
stack_push(scratch->used_abbreviations, temp);
token * walker = table->child->child;
// Find the separator line
- while (walker->next)
+ while (walker->next) {
walker = walker->next;
+ }
walker->type = TEXT_EMPTY;
case ALIGN_LEFT:
scratch->table_alignment[counter] = 'l';
break;
+
case ALIGN_RIGHT:
scratch->table_alignment[counter] = 'r';
break;
+
case ALIGN_CENTER:
scratch->table_alignment[counter] = 'c';
break;
+
case ALIGN_LEFT | ALIGN_WRAP:
scratch->table_alignment[counter] = 'L';
break;
+
case ALIGN_RIGHT | ALIGN_WRAP:
scratch->table_alignment[counter] = 'R';
break;
+
case ALIGN_CENTER | ALIGN_WRAP:
scratch->table_alignment[counter] = 'C';
break;
+
case ALIGN_WRAP:
scratch->table_alignment[counter] = 'N';
break;
+
default:
scratch->table_alignment[counter] = 'n';
}
case INDENT_SPACE:
case NON_INDENT_SPACE:
chain->type = TEXT_EMPTY;
+
case TEXT_EMPTY:
chain = chain->next;
break;
+
case TEXT_PLAIN:
token_trim_leading_whitespace(chain, source);
+
default:
return;
}
- if (chain)
+ if (chain) {
chain = chain->next;
+ }
}
}
t = t->next;
if (t && t->next &&
- t->next->type == PAIR_BRACKET)
+ t->next->type == PAIR_BRACKET) {
t = t->next;
+ }
if (t && t->next &&
((t->next->type == TEXT_NL) ||
- (t->next->type == TEXT_LINEBREAK)))
+ (t->next->type == TEXT_LINEBREAK))) {
t = t->next;
+ }
- if (t && t->next == NULL)
+ if (t && t->next == NULL) {
return true;
+ }
}
}
size_t start = fence->start + fence->len;
size_t len = 0;
- while (char_is_whitespace(source[start]))
+ while (char_is_whitespace(source[start])) {
start++;
+ }
- while (!char_is_whitespace_or_line_ending(source[start + len]))
+ while (!char_is_whitespace_or_line_ending(source[start + len])) {
len++;
+ }
- if (len)
+ if (len) {
result = my_strndup(&source[start], len);
+ }
return result;
}
case BLOCK_H1:
case BLOCK_SETEXT_1:
return 1;
+
case BLOCK_H2:
case BLOCK_SETEXT_2:
return 2;
+
case BLOCK_H3:
return 3;
+
case BLOCK_H4:
return 4;
+
case BLOCK_H5:
return 5;
+
case BLOCK_H6:
return 6;
}
bool raw_filter_text_matches(char * pattern, short format) {
- if (!pattern)
+ if (!pattern) {
return false;
+ }
if (strcmp("*", pattern) == 0) {
return true;
} else {
switch(format) {
case FORMAT_HTML:
- if (strstr(pattern, "html"))
+ if (strstr(pattern, "html")) {
return true;
+ }
+
break;
+
case FORMAT_ODT:
case FORMAT_FODT:
- if (strstr(pattern, "odt"))
+ if (strstr(pattern, "odt")) {
return true;
+ }
+
break;
+
case FORMAT_EPUB:
- if (strstr(pattern, "epub"))
+ if (strstr(pattern, "epub")) {
return true;
+ }
+
break;
+
case FORMAT_MEMOIR:
case FORMAT_BEAMER:
case FORMAT_LATEX:
- if (strstr(pattern, "latex"))
+ if (strstr(pattern, "latex")) {
return true;
+ }
+
break;
}
}
bool raw_filter_matches(token * t, const char * source, short format) {
bool result = false;
- if (t->type != PAIR_RAW_FILTER)
+ if (t->type != PAIR_RAW_FILTER) {
return result;
+ }
char * pattern = my_strndup(&source[t->child->start + 2], t->child->mate->start - t->child->start - 2);
for (int i = 0; i < file_count; ++i) {
mz_zip_reader_file_stat(pZip, i, &pStat);
+
if (pStat.m_is_directory) {
// Create the directory
mkdir(pStat.m_filename, 0755);
} else {
status = mz_zip_reader_extract_to_file(pZip, i, pStat.m_filename, 0);
+
if (!status) {
fprintf(stderr, "Error extracting file from zip archive.\n");
return status;
memset(&pZip, 0, sizeof(mz_zip_archive));
mz_bool status = mz_zip_reader_init_mem(&pZip, data, size, 0);
+
if (!status) {
fprintf(stderr, "mz_zip_reader_init_mem() failed.\n");
return status;
}
if (a_format->count > 0) {
- if (strcmp(a_format->sval[0], "html") == 0)
+ if (strcmp(a_format->sval[0], "html") == 0) {
format = FORMAT_HTML;
- else if (strcmp(a_format->sval[0], "latex") == 0)
+ } else if (strcmp(a_format->sval[0], "latex") == 0) {
format = FORMAT_LATEX;
- else if (strcmp(a_format->sval[0], "beamer") == 0)
+ } else if (strcmp(a_format->sval[0], "beamer") == 0) {
format = FORMAT_BEAMER;
- else if (strcmp(a_format->sval[0], "memoir") == 0)
+ } else if (strcmp(a_format->sval[0], "memoir") == 0) {
format = FORMAT_MEMOIR;
- else if (strcmp(a_format->sval[0], "mmd") == 0)
+ } else if (strcmp(a_format->sval[0], "mmd") == 0) {
format = FORMAT_MMD;
- else if (strcmp(a_format->sval[0], "odt") == 0)
+ } else if (strcmp(a_format->sval[0], "odt") == 0) {
format = FORMAT_ODT;
- else if (strcmp(a_format->sval[0], "fodt") == 0)
+ } else if (strcmp(a_format->sval[0], "fodt") == 0) {
format = FORMAT_FODT;
- else if (strcmp(a_format->sval[0], "epub") == 0)
+ } else if (strcmp(a_format->sval[0], "epub") == 0) {
format = FORMAT_EPUB;
- else if (strcmp(a_format->sval[0], "bundle") == 0)
+ } else if (strcmp(a_format->sval[0], "bundle") == 0) {
format = FORMAT_TEXTBUNDLE;
- else if (strcmp(a_format->sval[0], "bundlezip") == 0)
+ } else if (strcmp(a_format->sval[0], "bundlezip") == 0) {
format = FORMAT_TEXTBUNDLE_COMPRESSED;
- else {
+ } else {
// No valid format found
fprintf(stderr, "%s: Unknown output format '%s'\n", binname, a_format->sval[0]);
exitcode = 1;
case FORMAT_HTML:
output_filename = filename_with_extension(a_file->filename[i], ".html");
break;
+
case FORMAT_LATEX:
case FORMAT_BEAMER:
case FORMAT_MEMOIR:
output_filename = filename_with_extension(a_file->filename[i], ".tex");
break;
+
case FORMAT_FODT:
output_filename = filename_with_extension(a_file->filename[i], ".fodt");
break;
+
case FORMAT_ODT:
output_filename = filename_with_extension(a_file->filename[i], ".odt");
break;
+
case FORMAT_MMD:
output_filename = filename_with_extension(a_file->filename[i], ".mmdtext");
break;
+
case FORMAT_EPUB:
output_filename = filename_with_extension(a_file->filename[i], ".epub");
break;
+
case FORMAT_TEXTBUNDLE:
output_filename = filename_with_extension(a_file->filename[i], ".textbundle");
break;
+
case FORMAT_TEXTBUNDLE_COMPRESSED:
output_filename = filename_with_extension(a_file->filename[i], ".textpack");
break;
#ifdef kUseObjectPool
token_pool_init();
#endif
+
if (a_meta->count > 0) {
// List metadata keys
char_result = mmd_string_metadata_keys(buffer->str);
fwrite(result->str, result->currentStringLength, 1, output_stream);
- if (output_stream != stdout)
+ if (output_stream != stdout) {
fclose(output_stream);
+ }
if (FORMAT_MMD != format) {
d_string_free(result, true);