Sources/libMultiMarkdown/transclude.c
Sources/libMultiMarkdown/uuid.c
Sources/libMultiMarkdown/writer.c
+ Sources/libMultiMarkdown/zip.c
)
# Primary header files, also for doxygen documentation
Sources/libMultiMarkdown/uthash.h
Sources/libMultiMarkdown/uuid.h
Sources/libMultiMarkdown/writer.h
+ Sources/libMultiMarkdown/zip.h
)
set (scripts
#include <curl/curl.h>
#endif
-#include "d_string.h"
#include "epub.h"
#include "html.h"
#include "i18n.h"
#include "miniz.h"
-#include "mmd.h"
#include "transclude.h"
#include "uuid.h"
#include "writer.h"
-
+#include "zip.h"
#define print(x) d_string_append(out, x)
#define print_const(x) d_string_append_c_array(out, x, sizeof(x) - 1)
}
-bool add_asset_from_file(const char * filepath, asset * a, const char * destination, const char * directory) {
+bool add_asset_from_file(mz_zip_archive * pZip, asset * a, const char * destination, const char * directory) {
+ if (!directory)
+ return false;
+
char * path = path_from_dir_base(directory, a->url);
mz_bool status;
bool result = false;
DString * buffer = scan_file(path);
if (buffer && buffer->currentStringLength > 0) {
- status = mz_zip_add_mem_to_archive_file_in_place(filepath, destination, buffer->str, buffer->currentStringLength, NULL, 0, MZ_BEST_COMPRESSION);
+ status = mz_zip_writer_add_mem(pZip, destination, buffer->str, buffer->currentStringLength, MZ_BEST_COMPRESSION);
d_string_free(buffer, true);
result = true;
}
// Add assets to zipfile using libcurl
-void add_assets(const char * filepath, mmd_engine * e, const char * directory) {
+void add_assets(mz_zip_archive * pZip, mmd_engine * e, const char * directory) {
asset * a, * a_tmp;
if (e->asset_hash){
if (res != CURLE_OK) {
// Attempt to add asset from local file
- if (!add_asset_from_file(filepath, a, destination, directory)) {
+ if (!add_asset_from_file(pZip, a, destination, directory)) {
fprintf(stderr, "Unable to store '%s' in EPUB\n", a->url);
}
} else {
// Store downloaded file in zip
- status = mz_zip_add_mem_to_archive_file_in_place(filepath, destination, chunk.memory, chunk.size, NULL, 0, MZ_BEST_COMPRESSION);
+ status = mz_zip_writer_add_mem(pZip, destination, chunk.memory, chunk.size, MZ_BEST_COMPRESSION);
}
}
}
#else
// Add local assets only (libcurl not available)
-void add_assets(const char * filepath, mmd_engine * e, const char * directory) {
+void add_assets(mz_zip_archive * pZip, mmd_engine * e, const char * directory) {
asset * a, * a_tmp;
if (e->asset_hash){
memcpy(&destination[13], a->asset_path, 36);
// Attempt to add asset from local file
- if (!add_asset_from_file(filepath, a, destination, directory)) {
+ if (!add_asset_from_file(pZip, a, destination, directory)) {
fprintf(stderr, "Unable to store '%s' in EPUB\n", a->url);
}
}
// Use the miniz library to create a zip archive for the EPUB document
void epub_write_wrapper(const char * filepath, const char * body, mmd_engine * e, const char * directory) {
+ FILE * output_stream;
+
+ DString * result = epub_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 * epub_create(const char * body, mmd_engine * e, const char * directory) {
+ DString * result = d_string_new("");
scratch_pad * scratch = scratch_pad_new(e, FORMAT_EPUB);
+
mz_bool status;
char * data;
size_t len;
- // Delete existing file, if present
- remove(filepath);
+ mz_zip_archive zip;
+ zip_new_archive(&zip);
// Add mimetype
data = epub_mimetype();
len = strlen(data);
- status = mz_zip_add_mem_to_archive_file_in_place(filepath, "mimetype", data, len, NULL, 0, MZ_BEST_COMPRESSION);
+ status = mz_zip_writer_add_mem(&zip, "mimetype", data, len, MZ_BEST_COMPRESSION);
free(data);
// Create directories
- status = mz_zip_add_mem_to_archive_file_in_place(filepath, "OEBPS/", NULL, 0, NULL, 0, MZ_BEST_COMPRESSION);
- status = mz_zip_add_mem_to_archive_file_in_place(filepath, "META-INF/", NULL, 0, NULL, 0, MZ_BEST_COMPRESSION);
+ status = mz_zip_writer_add_mem(&zip, "OEBPS/", NULL, 0, MZ_BEST_COMPRESSION);
+ status = mz_zip_writer_add_mem(&zip, "META-INF/", NULL, 0, MZ_BEST_COMPRESSION);
// Add container
data = epub_container_xml();
len = strlen(data);
- status = mz_zip_add_mem_to_archive_file_in_place(filepath, "META-INF/container.xml", data, len, NULL, 0, MZ_BEST_COMPRESSION);
+ status = mz_zip_writer_add_mem(&zip, "META-INF/container.xml", data, len, MZ_BEST_COMPRESSION);
free(data);
// Add package
data = epub_package_document(scratch);
len = strlen(data);
- status = mz_zip_add_mem_to_archive_file_in_place(filepath, "OEBPS/main.opf", data, len, NULL, 0, MZ_BEST_COMPRESSION);
+ status = mz_zip_writer_add_mem(&zip, "OEBPS/main.opf", data, len, MZ_BEST_COMPRESSION);
free(data);
// Add nav
data = epub_nav(e, scratch);
len = strlen(data);
- status = mz_zip_add_mem_to_archive_file_in_place(filepath, "OEBPS/nav.xhtml", data, len, NULL, 0, MZ_BEST_COMPRESSION);
+ status = mz_zip_writer_add_mem(&zip, "OEBPS/nav.xhtml", data, len, MZ_BEST_COMPRESSION);
free(data);
// Add main document
len = strlen(body);
- status = mz_zip_add_mem_to_archive_file_in_place(filepath, "OEBPS/main.xhtml", body, len, NULL, 0, MZ_BEST_COMPRESSION);
-
+ status = mz_zip_writer_add_mem(&zip, "OEBPS/main.xhtml", body, len, MZ_BEST_COMPRESSION);
// Add assets
- add_assets(filepath, e, directory);
+ add_assets(&zip, e, directory);
scratch_pad_free(scratch);
-}
+ // Finalize zip archive and extract data
+ free(result->str);
+
+ status = mz_zip_writer_finalize_heap_archive(&zip, (void **) &(result->str), &(result->currentStringLength));
+ return result;
+}
#ifndef EPUB_MULTIMARKDOWN_H
#define EPUB_MULTIMARKDOWN_H
+#include "d_string.h"
#include "mmd.h"
void epub_write_wrapper(const char * root_path, const char * body, mmd_engine * e, const char * directory);
+DString * epub_create(const char * body, mmd_engine * e, const char * directory);
+
#endif
char * mmd_string_convert(const char * source, unsigned long extensions, short format, short language);
+/// Convert MMD text to specified format using DString as a container for block of data
+/// and length of that block. Must be used for "complex" output formats such as EPUB.
+/// Returned DString * must be freed
+DString * mmd_string_convert_to_data(const char * source, unsigned long extensions, short format, short language, const char * directory);
+
+
/// Convert MMD text and write results to specified file -- used for "complex" output formats requiring
/// multiple documents (e.g. EPUB)
void mmd_string_convert_to_file(const char * source, unsigned long extensions, short format, short language, const char * directory, const char * filepath);
char * mmd_d_string_convert(DString * source, unsigned long extensions, short format, short language);
+/// Convert MMD text to specified format using DString as a container for block of data
+/// and length of that block. Must be used for "complex" output formats such as EPUB.
+/// Returned DString * must be freed
+DString * mmd_d_string_convert_to_data(DString * source, unsigned long extensions, short format, short language, const char * directory);
+
+
/// Convert MMD text and write results to specified file -- used for "complex" output formats requiring
/// multiple documents (e.g. EPUB)
void mmd_d_string_convert_to_file(DString * source, unsigned long extensions, short format, short language, const char * directory, const char * filepath);
void mmd_engine_convert_to_file(mmd_engine * e, short format, const char * directory, const char * filepath);
+/// Convert MMD text to specified format using DString as a container for block of data
+/// and length of that block. Must be used for "complex" output formats such as EPUB.
+/// Returned DString * must be freed
+DString * mmd_engine_convert_to_data(mmd_engine * e, short format, const char * directory);
+
+
/// Does the text have metadata?
bool mmd_engine_has_metadata(mmd_engine * e, size_t * end);
}
+DString * mmd_string_convert_to_data(const char * source, unsigned long extensions, short format, short language, const char * directory) {
+ mmd_engine * e = mmd_engine_create_with_string(source, extensions);
+
+ mmd_engine_set_language(e, language);
+
+ DString * result = mmd_engine_convert_to_data(e, format, directory);
+
+ mmd_engine_free(e, true);
+
+ return result;
+}
+
+
+DString * mmd_d_string_convert_to_data(DString * source, unsigned long extensions, short format, short language, const char * directory) {
+ mmd_engine * e = mmd_engine_create_with_dstring(source, extensions);
+
+ mmd_engine_set_language(e, language);
+
+ DString * result = mmd_engine_convert_to_data(e, format, directory);
+
+ mmd_engine_free(e, false); // The engine doesn't own the DString, so don't free it.
+
+ return result;
+}
+
+
+DString * mmd_engine_convert_to_data(mmd_engine * e, short format, const char * directory) {
+ DString * output = d_string_new("");
+ DString * result = NULL;
+
+ mmd_engine_parse_string(e);
+
+ mmd_engine_export_token_tree(output, e, format);
+
+ switch (format) {
+ case FORMAT_EPUB:
+ result = epub_create(output->str, e, directory);
+
+ d_string_free(output, true);
+ break;
+ default:
+ result = output;
+ break;
+ }
+
+ return result;
+}
+
+
/// Return string containing engine version.
char * mmd_version(void) {
char * result;
--- /dev/null
+/**
+
+ MultiMarkdown -- Lightweight markup processor to produce HTML, LaTeX, and more.
+
+ @file zip.c
+
+ @brief Common routines for zip-based file formats
+
+
+ @author Fletcher T. Penney
+ @bug
+
+**/
+
+/*
+
+ Copyright © 2016 - 2017 Fletcher T. Penney.
+
+
+ The `MultiMarkdown 6` project is released under the MIT License..
+
+ GLibFacade.c and GLibFacade.h are from the MultiMarkdown v4 project:
+
+ https://github.com/fletcher/MultiMarkdown-4/
+
+ MMD 4 is released under both the MIT License and GPL.
+
+
+ CuTest is released under the zlib/libpng license. See CuTest.c for the
+ text of the license.
+
+ uthash library:
+ Copyright (c) 2005-2016, Troy D. Hanson
+
+ Licensed under Revised BSD license
+
+ miniz library:
+ Copyright 2013-2014 RAD Game Tools and Valve Software
+ Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC
+
+ Licensed under the MIT license
+
+ argtable3 library:
+ Copyright (C) 1998-2001,2003-2011,2013 Stewart Heitmann
+ <sheitmann@users.sourceforge.net>
+ All rights reserved.
+
+ Licensed under the Revised BSD License
+
+
+ ## The MIT License ##
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+ ## Revised BSD License ##
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+ * Neither the name of the <organization> nor the
+ names of its contributors may be used to endorse or promote
+ products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT
+ HOLDER> BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES LOSS OF USE, DATA, OR
+ PROFITS OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+*/
+
+
+#include "miniz.h"
+#include "zip.h"
+
+
+void zip_new_archive(mz_zip_archive * pZip) {
+ memset(pZip, 0, sizeof(mz_zip_archive));
+
+ mz_bool status;
+
+ status = mz_zip_writer_init_heap(pZip, 0, 0);
+
+ if (!status) {
+ fprintf(stderr, "mz_zip_writer_init_heap() failed.\n");
+ }
+}
+
--- /dev/null
+/**
+
+ MultiMarkdown -- Lightweight markup processor to produce HTML, LaTeX, and more.
+
+ @file zip.h
+
+ @brief
+
+
+ @author Fletcher T. Penney
+ @bug
+
+**/
+
+/*
+
+ Copyright © 2016 - 2017 Fletcher T. Penney.
+
+
+ The `MultiMarkdown 6` project is released under the MIT License..
+
+ GLibFacade.c and GLibFacade.h are from the MultiMarkdown v4 project:
+
+ https://github.com/fletcher/MultiMarkdown-4/
+
+ MMD 4 is released under both the MIT License and GPL.
+
+
+ CuTest is released under the zlib/libpng license. See CuTest.c for the
+ text of the license.
+
+ uthash library:
+ Copyright (c) 2005-2016, Troy D. Hanson
+
+ Licensed under Revised BSD license
+
+ miniz library:
+ Copyright 2013-2014 RAD Game Tools and Valve Software
+ Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC
+
+ Licensed under the MIT license
+
+ argtable3 library:
+ Copyright (C) 1998-2001,2003-2011,2013 Stewart Heitmann
+ <sheitmann@users.sourceforge.net>
+ All rights reserved.
+
+ Licensed under the Revised BSD License
+
+
+ ## The MIT License ##
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+ ## Revised BSD License ##
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+ * Neither the name of the <organization> nor the
+ names of its contributors may be used to endorse or promote
+ products derived from this software without specific prior
+ written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT
+ HOLDER> BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES LOSS OF USE, DATA, OR
+ PROFITS OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+*/
+
+
+#ifndef ZIP_MULTIMARKDOWN_H
+#define ZIP_MULTIMARKDOWN_H
+
+void zip_new_archive(mz_zip_archive * pZip);
+
+
+#endif
}
DString * buffer = NULL;
- char * result = NULL;
+ DString * result = NULL;
+ char * char_result = NULL;
FILE * output_stream;
char * output_filename;
#endif
if (a_meta->count > 0) {
// List metadata keys
- result = mmd_string_metadata_keys(buffer->str);
+ char_result = mmd_string_metadata_keys(buffer->str);
- fputs(result, stdout);
+ fputs(char_result, stdout);
- free(result);
+ free(char_result);
} else if (a_extract->count > 0) {
// Extract metadata key
const char * query = a_extract->sval[0];
- result = mmd_string_metavalue_for_key(buffer->str, query);
+ char_result = mmd_string_metavalue_for_key(buffer->str, query);
- fputs(result, stdout);
+ fputs(char_result, stdout);
fputc('\n', stdout);
- free(result);
+ free(char_result);
} else {
// Regular processing
- if (FORMAT_EPUB == format) {
- mmd_d_string_convert_to_file(buffer, extensions, format, language, folder, output_filename);
- result = NULL;
- } else if (FORMAT_MMD == format) {
- result = buffer->str;
+ if (FORMAT_MMD == format) {
+ result = buffer;
} else {
- result = mmd_d_string_convert(buffer, extensions, format, language);
+ result = mmd_d_string_convert_to_data(buffer, extensions, format, language, folder);
}
- if (result) {
- if (!(output_stream = fopen(output_filename, "w"))) {
- // Failed to open file
- perror(output_filename);
- } else {
- fputs(result, output_stream);
- fputc('\n', 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) {
- free(result);
+ d_string_free(result, true);
}
}
buffer = stdin_buffer();
}
+ char * folder = NULL;
+
+ if (a_file->count == 1) {
+ folder = dirname((char *) a_file->filename[0]);
+ }
+
if ((extensions & EXT_TRANSCLUDE) && (a_file->count == 1)) {
// Perform transclusion(s)
- char * folder = dirname((char *) a_file->filename[0]);
mmd_transclude_source(buffer, folder, "", format, NULL, NULL);
if (a_meta->count > 0) {
// List metadata keys
- result = mmd_string_metadata_keys(buffer->str);
+ char_result = mmd_string_metadata_keys(buffer->str);
- fputs(result, stdout);
+ fputs(char_result, stdout);
- free(result);
+ free(char_result);
} else if (a_extract->count > 0) {
// Extract metadata key
const char * query = a_extract->sval[0];
- result = mmd_string_metavalue_for_key(buffer->str, query);
+ char_result = mmd_string_metavalue_for_key(buffer->str, query);
- fputs(result, stdout);
+ fputs(char_result, stdout);
fputc('\n', stdout);
- free(result);
+ free(char_result);
} else {
// Regular processing
if (FORMAT_MMD == format) {
- result = buffer->str;
+ result = buffer;
} else {
- result = mmd_d_string_convert(buffer, extensions, format, language);
+ result = mmd_d_string_convert_to_data(buffer, extensions, format, language, folder);
}
// Where does output go?
goto exit;
}
- fputs(result, output_stream);
- fputc('\n', output_stream);
-
+ fwrite(result->str, result->currentStringLength, 1, output_stream);
+
if (output_stream != stdout)
fclose(output_stream);
if (FORMAT_MMD != format) {
- free(result);
+ d_string_free(result, true);
}
}