From 25ed5c40c4eae9cbc8083f58eef5e9e0af1e09b1 Mon Sep 17 00:00:00 2001 From: "Fletcher T. Penney" Date: Mon, 3 Jul 2017 06:47:48 -0400 Subject: [PATCH] ADDED: Add regular TextBundle format support --- Sources/libMultiMarkdown/mmd.c | 4 ++ Sources/libMultiMarkdown/textbundle.c | 38 ++++++------- Sources/libMultiMarkdown/textbundle.h | 2 +- Sources/libMultiMarkdown/writer.c | 1 + Sources/libMultiMarkdown/zip.c | 82 ++++++++++++++++++++++++++- Sources/libMultiMarkdown/zip.h | 9 +++ Sources/multimarkdown/main.c | 21 ++++--- 7 files changed, 127 insertions(+), 30 deletions(-) diff --git a/Sources/libMultiMarkdown/mmd.c b/Sources/libMultiMarkdown/mmd.c index 78f743c..a493d8e 100644 --- a/Sources/libMultiMarkdown/mmd.c +++ b/Sources/libMultiMarkdown/mmd.c @@ -2220,6 +2220,9 @@ void mmd_engine_convert_to_file(mmd_engine * e, short format, const char * direc 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; @@ -2280,6 +2283,7 @@ DString * mmd_engine_convert_to_data(mmd_engine * e, short format, const char * d_string_free(output, true); break; + case FORMAT_TEXTBUNDLE: case FORMAT_TEXTBUNDLE_COMPRESSED: result = textbundle_create(output->str, e, directory); diff --git a/Sources/libMultiMarkdown/textbundle.c b/Sources/libMultiMarkdown/textbundle.c index e24640b..9559f58 100644 --- a/Sources/libMultiMarkdown/textbundle.c +++ b/Sources/libMultiMarkdown/textbundle.c @@ -110,7 +110,6 @@ #endif #include "textbundle.h" -#include "html.h" #include "miniz.h" #include "transclude.h" #include "writer.h" @@ -360,24 +359,6 @@ void sub_asset_paths(DString * text, mmd_engine * e) { } -// Use the miniz library to create a zip archive for the TEXTBUNDLE_COMPRESSED document -void textbundle_write_wrapper(const char * filepath, const char * body, mmd_engine * e, const char * directory) { - FILE * output_stream; - - DString * result = textbundle_create(body, e, directory); - - if (!(output_stream = fopen(filepath, "w"))) { - // Failed to open file - perror(filepath); - } else { - fwrite(&(result->str), result->currentStringLength, 1, output_stream); - fclose(output_stream); - } - - d_string_free(result, true); -} - - DString * textbundle_create(const char * body, mmd_engine * e, const char * directory) { DString * result = d_string_new(""); scratch_pad * scratch = scratch_pad_new(e, FORMAT_TEXTBUNDLE_COMPRESSED); @@ -438,3 +419,22 @@ DString * textbundle_create(const char * body, mmd_engine * e, const char * dire return result; } + + + +// Use the miniz library to create a zip archive for the TEXTBUNDLE_COMPRESSED document +void textbundle_write_wrapper(const char * filepath, const char * body, mmd_engine * e, const char * directory) { + FILE * output_stream; + + DString * result = textbundle_create(body, e, directory); + + if (!(output_stream = fopen(filepath, "w"))) { + // Failed to open file + perror(filepath); + } else { + fwrite(&(result->str), result->currentStringLength, 1, output_stream); + fclose(output_stream); + } + + d_string_free(result, true); +} diff --git a/Sources/libMultiMarkdown/textbundle.h b/Sources/libMultiMarkdown/textbundle.h index 7b7aa7e..68d8bfd 100644 --- a/Sources/libMultiMarkdown/textbundle.h +++ b/Sources/libMultiMarkdown/textbundle.h @@ -108,7 +108,7 @@ #include "d_string.h" #include "mmd.h" -void textbundle_write_wrapper(const char * root_path, const char * body, mmd_engine * e, const char * directory); +void textbundle_write_wrapper(const char * filepath, const char * body, mmd_engine * e, const char * directory); DString * textbundle_create(const char * body, mmd_engine * e, const char * directory); diff --git a/Sources/libMultiMarkdown/writer.c b/Sources/libMultiMarkdown/writer.c index db58f6e..95e1f42 100644 --- a/Sources/libMultiMarkdown/writer.c +++ b/Sources/libMultiMarkdown/writer.c @@ -1731,6 +1731,7 @@ void mmd_engine_export_token_tree(DString * out, mmd_engine * e, short format) { break; case FORMAT_EPUB: + case FORMAT_TEXTBUNDLE: case FORMAT_TEXTBUNDLE_COMPRESSED: scratch->store_assets = true; diff --git a/Sources/libMultiMarkdown/zip.c b/Sources/libMultiMarkdown/zip.c index 88cba3e..f5b102a 100644 --- a/Sources/libMultiMarkdown/zip.c +++ b/Sources/libMultiMarkdown/zip.c @@ -101,11 +101,15 @@ */ - -#include "miniz.h" #include "zip.h" +#include +#include +#include +#include + +// Create new zip archive void zip_new_archive(mz_zip_archive * pZip) { memset(pZip, 0, sizeof(mz_zip_archive)); @@ -118,3 +122,77 @@ void zip_new_archive(mz_zip_archive * pZip) { } } + +// Unzip archive to specified file path +mz_bool unzip_archive_to_path(mz_zip_archive * pZip, const char * path) { + // Ensure folder 'path' exists + + DIR * dir = opendir(path); + mz_bool status; + + if (!dir) { + // path is not an existing directory + + if (access(path, F_OK) == 0) { + // path is an existing file + fprintf(stderr, "'%s' is an existing file.\n", path); + return -1; + } else { + // path doesn't exist - create directory + mkdir(path, 0755); + } + } + + dir = opendir(path); + + if (dir) { + // Directory 'path' exists + + // Remember current working directory + char cwd[PATH_MAX + 1]; + getcwd(cwd, sizeof(cwd)); + + // Move into the desired directory + chdir(path); + + int file_count = mz_zip_reader_get_num_files(pZip); + + mz_zip_archive_file_stat pStat; + + 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; + } + } + } + + // Return to prior working directory + chdir(cwd); + } + + + return 0; +} + + +// Unzip archive (as plain binary data) to specified file path +mz_bool unzip_data_to_path(const void * data, size_t size, const char * path) { + mz_zip_archive pZip; + 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; + } + + return unzip_archive_to_path(&pZip, path); +} + diff --git a/Sources/libMultiMarkdown/zip.h b/Sources/libMultiMarkdown/zip.h index 64c3549..4c774e2 100644 --- a/Sources/libMultiMarkdown/zip.h +++ b/Sources/libMultiMarkdown/zip.h @@ -105,7 +105,16 @@ #ifndef ZIP_MULTIMARKDOWN_H #define ZIP_MULTIMARKDOWN_H +#include "miniz.h" + +// Create new zip archive void zip_new_archive(mz_zip_archive * pZip); +// Unzip archive to specified file path +mz_bool unzip_archive_to_path(mz_zip_archive * pZip, const char * path); + +// Unzip archive (as plain binary data) to specified file path +mz_bool unzip_data_to_path(const void * data, size_t len, const char * path); + #endif diff --git a/Sources/multimarkdown/main.c b/Sources/multimarkdown/main.c index 40a76ef..a478900 100644 --- a/Sources/multimarkdown/main.c +++ b/Sources/multimarkdown/main.c @@ -67,6 +67,7 @@ #include "token.h" #include "uuid.h" #include "version.h" +#include "zip.h" #define kBUFFERSIZE 4096 // How many bytes to read at a time @@ -153,7 +154,7 @@ int main(int argc, char** argv) { a_rem2 = arg_rem("", ""), - a_format = arg_str0("t", "to", "FORMAT", "convert to FORMAT, FORMAT = html|latex|beamer|memoir|mmd|odf|epub|bundlezip"), + a_format = arg_str0("t", "to", "FORMAT", "convert to FORMAT, FORMAT = html|latex|beamer|memoir|mmd|odf|epub|bundle|bundlezip"), a_o = arg_file0("o", "output", "FILE", "send output to FILE"), a_rem3 = arg_rem("",""), @@ -280,8 +281,8 @@ int main(int argc, char** argv) { format = FORMAT_ODF; else if (strcmp(a_format->sval[0], "epub") == 0) format = FORMAT_EPUB; -// else if (strcmp(a_format->sval[0], "bundle") == 0) -// format = FORMAT_TEXTBUNDLE; + else if (strcmp(a_format->sval[0], "bundle") == 0) + format = FORMAT_TEXTBUNDLE; else if (strcmp(a_format->sval[0], "bundlezip") == 0) format = FORMAT_TEXTBUNDLE_COMPRESSED; else { @@ -407,12 +408,16 @@ int main(int argc, char** argv) { result = mmd_d_string_convert_to_data(buffer, extensions, format, language, folder); } - if (!(output_stream = fopen(output_filename, "w"))) { - // Failed to open file - perror(output_filename); + if (FORMAT_TEXTBUNDLE == format) { + unzip_data_to_path(result->str, result->currentStringLength, output_filename); } else { - fwrite(result->str, result->currentStringLength, 1, output_stream); - fclose(output_stream); + if (!(output_stream = fopen(output_filename, "w"))) { + // Failed to open file + perror(output_filename); + } else { + fwrite(result->str, result->currentStringLength, 1, output_stream); + fclose(output_stream); + } } if (FORMAT_MMD != format) { -- 2.40.0