From: Fletcher T. Penney Date: Tue, 27 Feb 2018 14:45:22 +0000 (-0500) Subject: STASHED changes X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ab97e7942e0fce31783488eeb113aebffabefa97;p=multimarkdown STASHED changes --- diff --git a/CMakeLists.txt b/CMakeLists.txt index cb77894..d246e27 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -195,6 +195,7 @@ set(src_files Sources/libMultiMarkdown/opendocument-content.c Sources/libMultiMarkdown/parser.c Sources/libMultiMarkdown/rng.c + Sources/libMultiMarkdown/rtf.c Sources/libMultiMarkdown/scanners.c Sources/libMultiMarkdown/stack.c Sources/libMultiMarkdown/textbundle.c @@ -225,6 +226,7 @@ set(header_files Sources/libMultiMarkdown/object_pool.h Sources/libMultiMarkdown/opendocument.h Sources/libMultiMarkdown/opendocument-content.h + Sources/libMultiMarkdown/rtf.h Sources/libMultiMarkdown/scanners.h Sources/libMultiMarkdown/stack.h Sources/libMultiMarkdown/textbundle.c diff --git a/Sources/formats/html.json b/Sources/formats/html.json new file mode 100644 index 0000000..e69de29 diff --git a/Sources/libMultiMarkdown/bytecode.h b/Sources/libMultiMarkdown/bytecode.h new file mode 100644 index 0000000..8edcc88 --- /dev/null +++ b/Sources/libMultiMarkdown/bytecode.h @@ -0,0 +1,12 @@ + +/// 9 bytes should be sufficient to cover all tokens (max is 512) + +enum opcode_flags { + OP_PRINT_SOURCE = 1 << 10, //!< Print the text of the token + OP_PRINT_HEAD = 1 << 11, //!< Print header string before token + OP_PRINT_TAIL = 1 << 12, //!< Print tail string after token + OP_PRINT_LOCALIZED = 1 << 13, //!< Print localized version of token text + OP_PAD_SINGLE = 1 << 14, //!< Pad with leading newline + OP_PAD_DOUBLE = 1 << 15, //!< Pad with 2 leading newlines + OP_SET_PADDING = 1 << 16, //!< Set padding after token +}; diff --git a/Sources/libMultiMarkdown/include/libMultiMarkdown.h b/Sources/libMultiMarkdown/include/libMultiMarkdown.h index 36ef020..4cf44c1 100644 --- a/Sources/libMultiMarkdown/include/libMultiMarkdown.h +++ b/Sources/libMultiMarkdown/include/libMultiMarkdown.h @@ -536,6 +536,7 @@ enum output_format { FORMAT_TEXTBUNDLE, FORMAT_TEXTBUNDLE_COMPRESSED, FORMAT_MMD, + FORMAT_RTF }; diff --git a/Sources/libMultiMarkdown/rtf.c b/Sources/libMultiMarkdown/rtf.c new file mode 100644 index 0000000..85de99f --- /dev/null +++ b/Sources/libMultiMarkdown/rtf.c @@ -0,0 +1,183 @@ + +#include +#include +#include +#include + +#include "char.h" +#include "d_string.h" +#include "html.h" +#include "i18n.h" +#include "libMultiMarkdown.h" +#include "parser.h" +#include "token.h" +#include "scanners.h" +#include "writer.h" + + +#define print(x) d_string_append(out, x) +#define print_const(x) d_string_append_c_array(out, x, sizeof(x) - 1) +#define print_char(x) d_string_append_c(out, x) +#define printf(...) d_string_append_printf(out, __VA_ARGS__) +#define print_token(t) d_string_append_c_array(out, &(source[t->start]), t->len) +#define print_localized(x) mmd_print_localized_char_html(out, x, scratch) + + +/// strdup() not available on all platforms +static char * my_strdup(const char * source) { + if (source == NULL) { + return NULL; + } + + char * result = malloc(strlen(source) + 1); + + if (result) { + strcpy(result, source); + } + + return result; +} + + +static void mmd_export_token_tree(DString * out, const char * source, token * t, scratch_pad * scratch); + + +static void mmd_export_token(DString * out, const char * source, token * t, scratch_pad * scratch) { + switch(t->type) { + case 0: + print_const("{\\rtf1\\ansi\\ansicpg1252\\cocoartf1504\\cocoasubrtf830\n{\\fonttbl\\f0\\fswiss\\fcharset0 Helvetica;}\n{\\colortbl;\\red255\\green255\\blue255;\\red191\\green191\\blue191;}\n{\\*\\expandedcolortbl;;\\csgray\\c79525;}\n{\\*\\listtable{\\list\\listtemplateid1\\listhybrid{\\listlevel\\levelnfc23\\levelnfcn23\\leveljc0\\leveljcn0\\levelfollow0\\levelstartat1\\levelspace360\\levelindent0{\\*\\levelmarker \\{disc\\}}{\\leveltext\\leveltemplateid1\\'01\\uc0\\u8226 ;}{\\levelnumbers;}\\fi-360\\li720\\lin720 }{\\listname ;}\\listid1}}\n{\\*\\listoverridetable{\\listoverride\\listid1\\listoverridecount0\\ls1}}\n\\margl1440\\margr1440\\vieww10800\\viewh8400\\viewkind0\n\\pard\\tx720\\tx1440\\tx2160\\tx2880\\tx3600\\tx4320\\tx5040\\tx5760\\tx6480\\tx7200\\tx7920\\tx8640\\pardirnatural\\partightenfactor0\n\n\\f0\\fs24 \\cf0 "); + if (t->child) { + mmd_export_token_tree(out, source, t->child, scratch); + } + break; + case 60: + print_const("\\\n"); + if (t->child) { + mmd_export_token_tree(out, source, t->child, scratch); + } + break; + case 62: + print_const("\\pard\\tx720\\tx1440\\tx2160\\tx2880\\tx3600\\tx4320\\tx5040\\tx5760\\tx6480\\tx7200\\tx7920\\tx8640\\pardirnatural\\partightenfactor0\n\n\\b\\fs36 \\cf0 "); + if (t->child) { + mmd_export_token_tree(out, source, t->child, scratch); + } + print_const("\n\\b0\\fs24 \\\n"); + break; + case 63: + print_const("\n\\b\\fs32 "); + if (t->child) { + mmd_export_token_tree(out, source, t->child, scratch); + } + print_const("\n\\b0\\fs24 \\\n"); + break; + case 64: + print_const("\n\\b\\fs28 "); + if (t->child) { + mmd_export_token_tree(out, source, t->child, scratch); + } + print_const("\n\\b0\\fs24 \\\n"); + break; + case 65: + print_const("\n\\i\\b\\fs26 "); + if (t->child) { + mmd_export_token_tree(out, source, t->child, scratch); + } + print_const("\n\\i0\\b0\\fs24 \\\n"); + break; + case 66: + print_const("\\pard\\tx720\\tx1440\\tx2160\\tx2880\\tx3600\\tx4320\\tx5040\\tx5760\\tx6480\\tx7200\\tx7920\\tx8640\\pardirnatural\\partightenfactor0\n\n\\b \\cf0 "); + if (t->child) { + mmd_export_token_tree(out, source, t->child, scratch); + } + print_const("\n\\b0 \\\n"); + break; + case 67: + print_const("\\pard\\tx720\\tx1440\\tx2160\\tx2880\\tx3600\\tx4320\\tx5040\\tx5760\\tx6480\\tx7200\\tx7920\\tx8640\\pardirnatural\\partightenfactor0\n\n\\i\\b \\cf0 "); + if (t->child) { + mmd_export_token_tree(out, source, t->child, scratch); + } + print_const("\n\\i0\\b0 \\\n"); + break; + case 71: + print_const("\\pard\\tx220\\tx720\\tx1440\\tx2160\\tx2880\\tx3600\\tx4320\\tx5040\\tx5760\\tx6480\\tx7200\\tx7920\\tx8640\\li720\\fi-720\\pardirnatural\\partightenfactor0\n\\ls1\\ilvl0\\cf0 "); + if (t->child) { + mmd_export_token_tree(out, source, t->child, scratch); + } + print_const("\\pard\\tx720\\tx1440\\tx2160\\tx2880\\tx3600\\tx4320\\tx5040\\tx5760\\tx6480\\tx7200\\tx7920\\tx8640\\pardirnatural\\partightenfactor0\n\\cf0 "); + break; + case 74: + print_const("{\\listtext\t\\'95\t}"); + if (t->child) { + mmd_export_token_tree(out, source, t->child, scratch); + } + break; + case 80: + print_const("\n\\itap1\\trowd \\taflags1 \\trgaph108\\trleft-108 \\trbrdrt\\brdrnil \\trbrdrl\\brdrnil \\trbrdrr\\brdrnil \n\\clvertalc \\clshdrawnil \\clbrdrt\\brdrs\\brdrw20\\brdrcf2 \\clbrdrl\\brdrs\\brdrw20\\brdrcf2 \\clbrdrb\\brdrs\\brdrw20\\brdrcf2 \\clbrdrr\\brdrs\\brdrw20\\brdrcf2 \\clpadl100 \\clpadr100 \\gaph\\cellx4320\n\\clvertalc \\clshdrawnil \\clbrdrt\\brdrs\\brdrw20\\brdrcf2 \\clbrdrl\\brdrs\\brdrw20\\brdrcf2 \\clbrdrb\\brdrs\\brdrw20\\brdrcf2 \\clbrdrr\\brdrs\\brdrw20\\brdrcf2 \\clpadl100 \\clpadr100 \\gaph\\cel"); + if (t->child) { + mmd_export_token_tree(out, source, t->child, scratch); + } + break; + case 82: + print_const("bl\\itap1\\tx720\\tx1440\\tx2160\\tx2880\\tx3600\\tx4320\\tx5040\\tx5760\\tx6480\\tx7200\\tx7920\\tx8640\\pardirnatural\\partightenfactor0\n\\cf0 musical\\cell \n\\pard\\intbl\\itap1\\tx720\\tx1440\\tx2160\\tx2880\\tx3600\\tx4320\\tx5040\\tx5760\\tx6480\\tx7200\\tx7920\\tx8640\\pardirnatural\\partightenfactor0\n\\cf0 suspicion\\cell \\row\n\n\\itap1\\trowd \\taflags1 \\trgaph108\\trleft-108 \\trbrdrl\\brdrnil \\trbrdrt\\brdrnil \\trbrdrr\\brdrnil \n\\clvertalc \\clshdrawnil \\clbrdrt\\brdrs\\brdrw20\\brdrcf2 \\clbrdrl\\brdrs\\brdrw"); + if (t->child) { + mmd_export_token_tree(out, source, t->child, scratch); + } + break; + case 115: + print_const(" \n\\i "); + if (t->child) { + mmd_export_token_tree(out, source, t->child, scratch); + } + print_const("\n\\i0 "); + break; + case 125: + print_const(" \n\\b "); + if (t->child) { + mmd_export_token_tree(out, source, t->child, scratch); + } + print_const("\n\\b0 "); + break; + case 216: + print_token(t); + if (t->child) { + mmd_export_token_tree(out, source, t->child, scratch); + } + break; + default: + if (t->child) { + mmd_export_token_tree(out, source, t->child, scratch); + } else { + // print_token(t); + } + break; + } +} + + + +static void mmd_export_token_tree(DString * out, const char * source, token * t, scratch_pad * scratch) { + + // Prevent stack overflow with "dangerous" input causing extreme recursion + if (scratch->recurse_depth == kMaxExportRecursiveDepth) { + return; + } + + scratch->recurse_depth++; + + while (t != NULL) { + if (scratch->skip_token) { + scratch->skip_token--; + } else { + mmd_export_token(out, source, t, scratch); + } + + t = t->next; + } + + scratch->recurse_depth--; +} + + +void mmd_export_rtf(DString * out, const char * source, token * t, scratch_pad * scratch) { + mmd_export_token_tree(out, source, t, scratch); +} diff --git a/Sources/libMultiMarkdown/rtf.h b/Sources/libMultiMarkdown/rtf.h new file mode 100644 index 0000000..b50ecdc --- /dev/null +++ b/Sources/libMultiMarkdown/rtf.h @@ -0,0 +1 @@ +void mmd_export_rtf(DString * out, const char * source, token * t, scratch_pad * scratch); \ No newline at end of file diff --git a/Sources/libMultiMarkdown/writer.c b/Sources/libMultiMarkdown/writer.c index eb6abe8..fc22d82 100644 --- a/Sources/libMultiMarkdown/writer.c +++ b/Sources/libMultiMarkdown/writer.c @@ -70,6 +70,7 @@ #include "mmd.h" #include "opendocument-content.h" #include "parser.h" +#include "rtf.h" #include "scanners.h" #include "token.h" #include "uuid.h" @@ -1900,6 +1901,11 @@ void mmd_engine_export_token_tree(DString * out, mmd_engine * e, short format) { break; + case FORMAT_RTF: + mmd_export_rtf(out, e->dstr->str, e->root, scratch); + + break; + case FORMAT_ODT: scratch->store_assets = true; diff --git a/Sources/multimarkdown/main.c b/Sources/multimarkdown/main.c index d0578bd..7eea385 100644 --- a/Sources/multimarkdown/main.c +++ b/Sources/multimarkdown/main.c @@ -286,6 +286,8 @@ int main(int argc, char** argv) { format = FORMAT_TEXTBUNDLE; } else if (strcmp(a_format->sval[0], "bundlezip") == 0) { format = FORMAT_TEXTBUNDLE_COMPRESSED; + } else if (strcmp(a_format->sval[0], "rtf") == 0) { + format = FORMAT_RTF; } else { // No valid format found fprintf(stderr, "%s: Unknown output format '%s'\n", binname, a_format->sval[0]);