diff --git a/configure.ac b/configure.ac index 2c4b902..03362e3 100644 --- a/configure.ac +++ b/configure.ac @@ -33,7 +33,7 @@ AC_TYPE_UINT8_T # Checks for library functions. AC_FUNC_MALLOC AC_FUNC_REALLOC -AC_CHECK_FUNCS([memset realpath strdup strndup]) +AC_CHECK_FUNCS([memset pledge realpath strdup strndup]) AC_CONFIG_FILES([Makefile data/Makefile diff --git a/data/Makefile.am b/data/Makefile.am index 6c8e803..e3c9689 100644 --- a/data/Makefile.am +++ b/data/Makefile.am @@ -1,2 +1,2 @@ -pkgdata_DATA = *.xsl sermon.dtd -EXTRA_DIST = *.xsl sermon.dtd +pkgdata_DATA = *.xsl ms_odt.odt odt.odt sermon.dtd +EXTRA_DIST = *.xsl ms_odt.odt sermon.dtd diff --git a/data/ms_odt.odt b/data/ms_odt.odt new file mode 100644 index 0000000..76646ff Binary files /dev/null and b/data/ms_odt.odt differ diff --git a/data/odt.odt b/data/odt.odt new file mode 100644 index 0000000..eca53e9 Binary files /dev/null and b/data/odt.odt differ diff --git a/src/Makefile.am b/src/Makefile.am index 159084f..c0c4718 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -7,6 +7,7 @@ AM_YFLAGS = -d --location sermon_SOURCES = citations.c \ format.c \ main.c \ + odt.c \ options.c \ sermon_lexer.l \ sermon_parser.y \ diff --git a/src/main.c b/src/main.c index 7990732..77e3233 100644 --- a/src/main.c +++ b/src/main.c @@ -31,6 +31,9 @@ #include #include #include +#include +#include "meta.h" +#include "odt.h" #include "options.h" #include "sermon.h" #include "xml.h" @@ -39,10 +42,31 @@ extern int yyparse(Sermon *); extern FILE* yyin; +char* +constructMetaXml(const char* sermonTitle, const char* timestamp, + const char* sermonAuthor) { + size_t sz = sizeof(META_XML_TEMPLATE) - 13 + 2 * strlen(sermonTitle) + + 3 * strlen(timestamp) + 2 * strlen(sermonAuthor); + char* result = malloc(sz); + if (!result) { + perror("malloc"); + exit(1); + } + snprintf(result, sz, META_XML_TEMPLATE, sermonTitle, timestamp, + sermonAuthor, timestamp, sermonAuthor, sermonTitle, timestamp); + + return result; +} + int main(int argc, char* argv[]) { Sermon sermon; xmlDocPtr document, transformed; int i = 0, block = 0, normal = 0; +#ifdef HAVE_PLEDGE + if (-1 == pledge("stdio rpath wpath tmppath proc exec", NULL)) { + err(1, "pledge"); + } +#endif /* !def(HAVE_PLEDGE) */ InitOptions(argc, (const char**)argv); InitSermon(&sermon); @@ -53,17 +77,61 @@ int main(int argc, char* argv[]) { } yyparse(&sermon); +#if 0 +#ifdef HAVE_PLEDGE + if (-1 == pledge("stdio", NULL)) { + err(1, "pledge"); + } +#endif /* !def(HAVE_PLEDGE) */ +#endif + document = sermonToXmlDoc(&sermon); - transformed = applyStyleSheet(document, options.styleSheetName); - printXML(transformed); + if (strcmp(options.styleSheetName, "none") != 0) { + transformed = applyStyleSheet(document, options.styleSheetName); + } else { + transformed = document; + } + if (strcmp(options.outputFileName, "-") == 0) { + printXML(transformed); + } else { + if ((strcmp(options.styleSheetName, "odt") == 0) || + (strcmp(options.styleSheetName, "ms_odt") == 0)) { + ODTFileEntry entry[2]; + int sz; + xmlChar* doc; + char templateFileName[FILENAME_MAX]; + char timestamp[20]; + time_t tm; + + /* get timestamp */ + time(&tm); + strftime(timestamp, 20, "%Y-%m-%dT%H:%M:%S", localtime(&tm)); + + xmlDocDumpMemoryEnc(transformed, &doc, &sz, "utf-8"); + entry[0].path = "content.xml"; + entry[0].content = doc; + entry[1].path = "meta.xml"; + entry[1].content = constructMetaXml(sermon.sermonTitle, timestamp, sermon.sermonAuthor ? sermon.sermonAuthor : options.authorName); + snprintf(templateFileName, FILENAME_MAX, "%s.odt", options.styleSheetName); + constructODT(options.outputFileName, OptionsDataFile(templateFileName), 2, entry); + free(doc); + free(entry[1].content); + } else { + xmlSaveFileEnc(options.outputFileName, transformed, "utf-8"); + } + } /* clean up, clean up, everybody, everywhere! */ + VERBOSE_PRINTF("Cleaning up\n"); xmlFreeDoc(document); - xmlFreeDoc(transformed); + if (strcmp(options.styleSheetName, "none") != 0) { + xmlFreeDoc(transformed); + } FreeSermon(&sermon); if (strcmp(options.inputFileName, "-") != 0) { fclose(yyin); } FreeOptions(); + VERBOSE_PRINTF("Cleanup done\n"); } diff --git a/src/meta.h b/src/meta.h new file mode 100644 index 0000000..3e83de6 --- /dev/null +++ b/src/meta.h @@ -0,0 +1,55 @@ +/* + * meta.h + * Copyright © 2016 David A. Baer + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. 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 David A. Baer ''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 David A. Baer 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 _META_H +#define _META_H + +#define META_XML_TEMPLATE \ + "\n" \ + "\n" \ + " \n" \ + " OpenOffice.org/3.1$Unix OpenOffice.org_project/310m19$Build-9420\n" \ + " %s\n" \ + " %s\n" \ + " en-US\n" \ + " 4\n" \ + " PT00H11M59S\n" \ + " %s\n" \ + " %s\n" \ + " %s\n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + "\n" + +#endif /* !def(_META_H) */ diff --git a/src/odt.c b/src/odt.c new file mode 100644 index 0000000..746d8de --- /dev/null +++ b/src/odt.c @@ -0,0 +1,151 @@ +/* + * odt.c + * Copyright © 2016 David A. Baer + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. 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 David A. Baer ''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 David A. Baer 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 +#include +#include +#include +#include "odt.h" +#include "options.h" + +void +saveEntry(const char* rootPath, const ODTFileEntry entry) { + char* fullpath = malloc(FILENAME_MAX); + FILE* ptr; + snprintf(fullpath, FILENAME_MAX, "%s/%s", rootPath, entry.path); + ptr = fopen(fullpath, "w"); + fwrite(entry.content, 1, strlen(entry.content), ptr); + fclose(ptr); + free(fullpath); +} + +static void +extractTemplateDocument(const char* const templateFilename, const char* const tempDir) { + pid_t child_pid; + if ((child_pid = fork()) == 0) { + /* you are the child */ + char* const args[] = { "unzip", "-d", tempDir, templateFilename, NULL }; + freopen("/dev/null", "w", stdout); + execvp("unzip", args); + perror("execvp"); + exit(1); + } else { + /* you are the parent */ + int status; + + waitpid(child_pid, &status, 0); + if (status != 0) { + fprintf(stderr, "unzip exited with status %d.\n", status); + exit(1); + } + } +} + +static void +createOutputDocument(const char* const outputFilename, const char* const tempDir) { + pid_t child_pid; + if ((child_pid = fork()) == 0) { + /* you are the child */ + char outputRealPath[FILENAME_MAX]; + char* const args[] = { "zip", "-r", outputRealPath, ".", NULL }; + realpath(outputFilename, outputRealPath); + chdir(tempDir); + freopen("/dev/null", "w", stdout); + execvp("zip", args); + perror("execvp"); + exit(1); + } else { + /* you are the parent */ + int status; + + waitpid(child_pid, &status, 0); + if (status != 0) { + fprintf(stderr, "zip exited with status %d.\n", status); + exit(1); + } + } +} + +static void +removeDirectory(const char* const tempDir) { + pid_t child_pid; + if ((child_pid = fork()) == 0) { + /* you are the child */ + char* const args[] = { "rm", "-rf", tempDir, NULL }; + freopen("/dev/null", "w", stdout); + execvp("rm", args); + perror("execvp"); + exit(1); + } else { + /* you are the parent */ + int status; + + waitpid(child_pid, &status, 0); + if (status != 0) { + fprintf(stderr, "rm exited with status %d.\n", status); + exit(1); + } + } +} + +int +constructODT(const char* const outputFilename, const char* const templateFilename, + unsigned int numEntries, const ODTFileEntry* entries) { + char tempDir[23]; + int i; + + /* create temporary workspace */ + strlcpy(tempDir, "/tmp/sermon.XXXXXXXXXX", sizeof(tempDir)); + if (mkdtemp(tempDir) == NULL) { + perror("mkdtemp"); + exit(1); + } + VERBOSE_PRINTF("Making temporary directory %s\n", tempDir); + + /* extract template document to workspace */ + VERBOSE_PRINTF("Extracting template %s to temporary directory\n", templateFilename); + extractTemplateDocument(templateFilename, tempDir); + + /* replace/add entries */ + for (i = 0; i < numEntries; i++) { + VERBOSE_PRINTF("Adding %s\n", entries[i].path); + saveEntry(tempDir, entries[i]); + } + + /* create output file */ + VERBOSE_PRINTF("Creating output file %s\n", outputFilename); + createOutputDocument(outputFilename, tempDir); + + /* clean up */ + VERBOSE_PRINTF("Removing %s\n", tempDir); + removeDirectory(tempDir); + + VERBOSE_PRINTF("ODT output successfully created\n"); + return 0; +} diff --git a/src/odt.h b/src/odt.h new file mode 100644 index 0000000..3488121 --- /dev/null +++ b/src/odt.h @@ -0,0 +1,45 @@ +/* + * odt.h + * Copyright © 2016 David A. Baer + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. 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 David A. Baer ''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 David A. Baer 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 _ODT_H +#define _ODT_H 1 + +typedef struct { + char* path; + char* content; +} ODTFileEntry; + +int +constructODT( + const char* const outputFilename, const char* const templateFilename, + unsigned int numEntries, const ODTFileEntry* entries +); + + +#endif /* !def(_ODT_H) */ diff --git a/src/odttemplate.c b/src/odttemplate.c index db0d0c4..595b48f 100644 --- a/src/odttemplate.c +++ b/src/odttemplate.c @@ -35,7 +35,8 @@ int odttemplate(const char* template_fn, const char* output_fn, struct dict* substitutions_dict) { - struct archive* arch_in = archive_read_new(); + struct archive* arch_in = archive_read_new(), + *arch_out = archive_write_new(); struct archive_entry* ent; struct dict_iter* i; char ftype; @@ -43,41 +44,24 @@ int odttemplate(const char* template_fn, const char* output_fn, struct dict* sub if (archive_read_support_format_zip(arch_in) != ARCHIVE_OK) { return ODTTEMPLATE_FATAL; } + if (archive_write_set_format_zip(arch_out) != ARCHIVE_OK) { + return ODTTEMPLATE_FATAL; + } + if (archive_write_zip_set_compression_deflate(arch_out) != ARCHIVE_OK) { + return ODTTEMPLATE_FATAL; + } if (archive_read_open_filename(arch_in, template_fn, ODTTEMPLATE_BLOCK_SIZE) != ARCHIVE_OK) { return ODTTEMPLATE_FATAL; } + if (archive_write_open_filename(arch_out, output_fn) != ARCHIVE_OK) { + return ODTTEMPLATE_FATAL; + } while (archive_read_next_header(arch_in, &ent) != ARCHIVE_EOF) { - switch (archive_entry_filetype(ent)) { - case AE_IFREG: - ftype = 'F'; - break; - case AE_IFLNK: - ftype = 'L'; - break; - case AE_IFSOCK: - ftype = 'S'; - break; - case AE_IFCHR: - ftype = 'C'; - break; - case AE_IFBLK: - ftype = 'B'; - break; - case AE_IFDIR: - ftype = 'D'; - break; - case AE_IFIFO: - ftype = 'P'; - break; - default: - ftype = '?'; + if ((archive_entry_filetype(ent) == AE_IFREG) && + (dict_find(substitutions_dict, archive_entry_pathname(ent), NULL) + == DICT_OK)) { + } else { } - fn = archive_entry_pathname(ent); - printf("%s [%c]", fn, ftype); - if (substitutions_dict && (dict_find(substitutions_dict, fn, NULL) == DICT_OK)) { - printf(" - in dictionary, skip"); - } - printf("\n"); archive_read_data_skip(arch_in); } archive_read_close(arch_in); diff --git a/src/options.c b/src/options.c index 9997529..e578fbb 100644 --- a/src/options.c +++ b/src/options.c @@ -36,7 +36,9 @@ #include "options.h" Options options = { - .progname = NULL, .datadir = DATADIR, .styleSheetName = "html5" + .progname = NULL, .datadir = DATADIR, .styleSheetName = NULL, + .outputFileName = "-", .placeName = "Highlands Presbyterian Church", + .authorName = "David A. Baer", .verbose = 0 }; char* @@ -70,10 +72,14 @@ datadir(const char* progname) { } static void usage(const char* progname) { - fprintf(stderr, "Usage: %s [-h] [-s STYLESHEET] FILE\n" + fprintf(stderr, "Usage: %s [options] FILE\n" "\n" - " -h Display help message\n" - " -s STYLESHEET Apply stylesheet (default \"html5\")\n" + "Options:\n" + " -h|--help Display this help message\n" + " -a|--author AUTHOR Author name\n" + " -o|--output OUTPUT Output file name\n" + " -s|--stylesheet STYLESHEET Apply stylesheet (default \"html5\")\n" + " -v|--verbose Verbose output\n" "\n" " FILE sermon file to scan (\"-\" for stdin)\n", progname); } @@ -83,13 +89,35 @@ void InitOptions(int argc, const char* argv[]) { options.progname = argv[0]; options.datadir = datadir(options.progname); while (++i < argc) { - if (strcmp(argv[i], "-h") == 0) { usage(options.progname); exit(0); } - else if (strcmp(argv[i], "-") == 0) { + if ((strcmp(argv[i], "-h") == 0) || + (strcmp(argv[i], "--help") == 0)) { + usage(options.progname); + exit(0); + } else if (strcmp(argv[i], "-") == 0) { options.inputFileName = argv[i]; - } else if (strcmp(argv[i], "-s") == 0) { + } else if ((strcmp(argv[i], "-s") == 0) || + (strcmp(argv[i], "--stylesheet") == 0)) { options.styleSheetName = argv[++i]; } else if (strncmp(argv[i], "-s", 2) == 0) { options.styleSheetName = argv[i] + 2; + } else if ((strcmp(argv[i], "-o") == 0) || + (strcmp(argv[i], "--output") == 0)) { + options.outputFileName = argv[++i]; + } else if (strncmp(argv[i], "-o", 2) == 0) { + options.outputFileName = argv[i] + 2; + } else if ((strcmp(argv[i], "-a") == 0) || + (strcmp(argv[i], "--author") == 0)) { + options.authorName = argv[++i]; + } else if (strncmp(argv[i], "-a", 2) == 0) { + options.authorName = argv[i] + 2; + } else if ((strcmp(argv[i], "-p") == 0) || + (strcmp(argv[i], "--place") == 0)) { + options.placeName = argv[++i]; + } else if (strncmp(argv[i], "-p", 2) == 0) { + options.placeName = argv[i] + 2; + } else if ((strcmp(argv[i], "-v") == 0) || + (strcmp(argv[i], "--verbose") == 0)) { + options.verbose = 1; } else if (argv[i][0] == '-') { fprintf(stderr, "Unknown option: %s\n", argv[i]); } else { @@ -102,6 +130,23 @@ void InitOptions(int argc, const char* argv[]) { usage(options.progname); exit(1); } + + /* set stylesheet based on output file name */ + if (!options.styleSheetName && options.outputFileName) { + char* outputExten = strrchr(options.outputFileName, '.'); + if (outputExten) { + if (strcasecmp(outputExten, ".odt") == 0) { + options.styleSheetName = "odt"; + } else if (strcasecmp(outputExten, ".html") == 0) { + options.styleSheetName = "html5"; + } + } + } + + /* default stylesheet is html5 */ + if (!options.styleSheetName) { + options.styleSheetName = "html5"; + } } char* diff --git a/src/options.h b/src/options.h index 9a8ee51..e9814ea 100644 --- a/src/options.h +++ b/src/options.h @@ -34,7 +34,11 @@ typedef struct { const char* progname; char* datadir; const char* inputFileName; + const char* outputFileName; const char* styleSheetName; + const char* authorName; + const char* placeName; + int verbose; } Options; extern Options options; @@ -43,4 +47,6 @@ void InitOptions(int argc, const char* argv[]); char* OptionsDataFile(const char* fname); void FreeOptions(); +#define VERBOSE_PRINTF(x...) { if (options.verbose) printf(x); } + #endif /* !def _OPTIONS_H */ diff --git a/src/sermon.h b/src/sermon.h index e33ba4e..a70d400 100644 --- a/src/sermon.h +++ b/src/sermon.h @@ -58,6 +58,7 @@ typedef struct { char* sermonAuthor; char* sermonDate; char* sermonOccasion; + char* sermonPlace; char* sermonText; int numParagraphs; diff --git a/src/sermon_parser.y b/src/sermon_parser.y index 87baed6..bf95352 100644 --- a/src/sermon_parser.y +++ b/src/sermon_parser.y @@ -105,6 +105,7 @@ header: else if (strcmp($2, "text") == 0) { sermon->sermonText = $4; } else if (strcmp($2, "occasion") == 0) { sermon->sermonOccasion = $4; } else if (strcmp($2, "date") == 0) { sermon->sermonDate = $4; } + else if (strcmp($2, "place") == 0) { sermon->sermonPlace = $4; } else { free($4); } free($2); } diff --git a/src/xml.c b/src/xml.c index d93cfb9..e0dcce3 100644 --- a/src/xml.c +++ b/src/xml.c @@ -1,5 +1,6 @@ #include #include +#include "options.h" #include "sermon.h" static xmlNsPtr srmNs = NULL; @@ -18,8 +19,9 @@ xmlNodePtr sermonHeader(xmlNsPtr sermon_ns, const Sermon* srm) { xmlNodePtr header = xmlNewNode(sermon_ns, "header"); appendHeaderNode(sermon_ns, header, "title", srm->sermonTitle); - appendHeaderNode(sermon_ns, header, "author", srm->sermonAuthor); + appendHeaderNode(sermon_ns, header, "author", srm->sermonAuthor ? srm->sermonAuthor : options.authorName); appendHeaderNode(sermon_ns, header, "occasion", srm->sermonOccasion); + appendHeaderNode(sermon_ns, header, "place", srm->sermonPlace ? srm->sermonPlace : options.placeName); appendHeaderNode(sermon_ns, header, "date", srm->sermonDate); appendHeaderNode(sermon_ns, header, "text", srm->sermonText); return header; @@ -166,3 +168,4 @@ printXML(xmlDocPtr document) { xmlOutputBufferPtr output = xmlOutputBufferCreateFd(1, encoding); xmlSaveFileTo(output, document, "utf-8"); } + diff --git a/src/xml.h b/src/xml.h index 6a74710..7cd3588 100644 --- a/src/xml.h +++ b/src/xml.h @@ -1,7 +1,12 @@ #ifndef _XML_H #define _XML_H -xmlDocPtr sermonToXmlDoc(const Sermon*); -void printXML(xmlDocPtr); +#include + +xmlDocPtr +sermonToXmlDoc(const Sermon*); + +void +printXML(xmlDocPtr); #endif /* !def _XML_H */ diff --git a/src/xslt.c b/src/xslt.c index 511ebd8..531e89d 100644 --- a/src/xslt.c +++ b/src/xslt.c @@ -15,7 +15,7 @@ applyStyleSheet(xmlDocPtr document, const char* styleSheetName) { snprintf(t, l, "%s.xsl", styleSheetName); styleSheetFileName = OptionsDataFile(t); free(t); - fprintf(stderr, "Loading stylesheet %s ...\n", styleSheetFileName); + /*fprintf(stderr, "Loading stylesheet %s ...\n", styleSheetFileName);*/ xmlSubstituteEntitiesDefault(1); xmlLoadExtDtdDefaultValue = 1;