Finalize and document EPUB support (Issue #189)

Update footer for mxml(3) man page.

Update header for mxmldoc.xsd file.
This commit is contained in:
Michael Sweet 2017-04-06 09:15:35 -04:00
parent e6146472e6
commit 8b32ac7556
6 changed files with 197 additions and 148 deletions

View File

@ -5,6 +5,7 @@
- mxmlElementSetAttrf did not work with some versions of Visual Studio
(Issue #184)
- The configure script now properly supports cross-compilation (Issue #188)
- The mxmldoc utility now supports generation of EPUB files.
# Changes in Mini-XML 2.10

View File

@ -1,4 +1,4 @@
.SH SEE ALSO
mxmldoc(1), Mini-XML Programmers Manual, http://www.minixml.org/
mxmldoc(1), Mini-XML Programmers Manual, https://michaelrsweet.github.io/mxml
.SH COPYRIGHT
Copyright 2003-2011 by Michael Sweet.
Copyright \[co] 2003-2017 by Michael R Sweet.

View File

@ -1,4 +1,4 @@
.TH mxml 3 "Mini-XML API" "04/05/17" "Mini-XML API"
.TH mxml 3 "Mini-XML API" "04/06/17" "Mini-XML API"
.SH NAME
mxml \- Mini-XML API
.SH INCLUDE FILE
@ -1285,6 +1285,6 @@ The XML node type.
typedef enum mxml_type_e mxml_type_t;
.fi
.SH SEE ALSO
mxmldoc(1), Mini-XML Programmers Manual, http://www.minixml.org/
mxmldoc(1), Mini-XML Programmers Manual, https://michaelrsweet.github.io/mxml
.SH COPYRIGHT
Copyright 2003-2011 by Michael Sweet.
Copyright \[co] 2003-2017 by Michael R Sweet.

View File

@ -1,21 +1,17 @@
.\"
.\" "$Id$"
.\"
.\" mxmldoc man page for mini-XML, a small XML-like file parsing library.
.\"
.\" Copyright 2003-2009 by Michael Sweet.
.\" Copyright 2003-2017 by Michael R Sweet.
.\"
.\" This program is free software; you can redistribute it and/or
.\" modify it under the terms of the GNU Library General Public
.\" License as published by the Free Software Foundation; either
.\" version 2, or (at your option) any later version.
.\" These coded instructions, statements, and computer programs are the
.\" property of Michael R Sweet and are protected by Federal copyright
.\" law. Distribution and use rights are outlined in the file "COPYING"
.\" which should have been included with this file. If this file is
.\" missing or damaged, see the license at:
.\"
.\" This program is distributed in the hope that it will be useful,
.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
.\" GNU General Public License for more details.
.\" https://michaelrsweet.github.io/mxml
.\"
.TH mxmldoc 1 "Mini-XML" "4 May 2009" "Michael Sweet"
.TH mxmldoc 1 "Mini-XML" "6 April 2017" "Michael Sweet"
.SH NAME
mxmldoc \- mini-xml documentation generator
.SH SYNOPSIS
@ -27,7 +23,11 @@ mxmldoc \- mini-xml documentation generator
]
.br
.B mxmldoc
[ \-\-footer
[ \-\-author
.I author
] [ \-\-copyright
.I copyright
] [ \-\-footer
.I footerfile
] [ \-\-header
.I headerfile
@ -47,7 +47,11 @@ mxmldoc \- mini-xml documentation generator
.B mxmldoc
\-\-docset
.I directory.docset
[ \-\-docversion
[ \-\-author
.I author
] [ \-\-copyright
.I copyright
] [ \-\-docversion
.I version
] [ \-\-feedname
.I name
@ -81,7 +85,11 @@ mxmldoc \- mini-xml documentation generator
.B mxmldoc
\-\-framed
.I basename
[ \-\-footer
[ \-\-author
.I author
] [ \-\-copyright
.I copyright
] [ \-\-footer
.I footerfile
] [ \-\-header
.I headerfile
@ -98,7 +106,11 @@ mxmldoc \- mini-xml documentation generator
]
.br
.B mxmldoc
[ \-\-footer
[ \-\-author
.I author
] [ \-\-copyright
.I copyright
] [ \-\-footer
.I footerfile
] [ \-\-header
.I headerfile
@ -116,6 +128,35 @@ mxmldoc \- mini-xml documentation generator
.I source file(s)
] >
.I filename.man
.br
.B mxmldoc
\-\-epub
.I filename.epub
[ \-\-author
.I author
] [ \-\-copyright
.I copyright
] [ \-\-docversion
.I version
] [ \-\-feedname
.I name
] [ \-\-feedurl
.I url
] [ \-\-footer
.I footerfile
] [ \-\-header
.I headerfile
] [ \-\-intro
.I introfile
] [ \-\-section
.I section
] [ \-\-title
.I title
] [
.I filename.xml
] [
.I source file(s)
]
.SH DESCRIPTION
\fImxmldoc\fR scans the specified C and C++ source files to produce
an XML representation of globally accessible classes, constants,
@ -132,9 +173,17 @@ converted to the standard output.
In general, any C or C++ source code is handled by \fImxmldoc\fR,
however it was specifically written to handle code with
documentation that is formatted according to the CUPS Developer
Guide which is available at "http://www.cups.org/documentation.php".
Guide which is available at "http://www.cups.org/doc/spec-cmp.html".
.SH OPTIONS
.TP 5
\-\-author "author name"
.br
Specifies the name of the documentation author.
.TP 5
\-\-copyright "copyright text"
.br
Specifies the copyright text to use.
.TP 5
\-\-docset directory.docset
.br
Creates an Xcode documentation set in the specified directory.
@ -143,6 +192,10 @@ Creates an Xcode documentation set in the specified directory.
.br
Specifies the version number for the Xcode documentation set.
.TP 5
\-\-epub filename.epub
.br
Creates an EPUB book with the specified filename.
.TP 5
\-\-feedname name
.br
Specifies the Xcode documentation set feed name, typically the project or
@ -190,9 +243,6 @@ Sets the title of the output documentation.
.br
Generates a Tokens.xml file for use with the Xcode documentation tools.
.SH SEE ALSO
mxml(3), Mini-XML Programmers Manual, http://www.minixml.org/
mxml(3), Mini-XML Programmers Manual, https://michaelrsweet.github.io/mxml
.SH COPYRIGHT
Copyright 2003-2009 by Michael Sweet.
.\"
.\" End of "$Id$".
.\"
Copyright \[co] 2003-2017 by Michael R Sweet.

View File

@ -2,18 +2,16 @@
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:annotation>
<xsd:documentation xml:lang="en">
Mini-XML 2.9 documentation schema for mxmldoc output.
Copyright 2003-2014 by Michael Sweet.
Mini-XML 2.x documentation schema for mxmldoc output.
Copyright 2003-2017 by Michael R Sweet.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2, or (at your option) any later version.
These coded instructions, statements, and computer programs are the
property of Michael R Sweet and are protected by Federal copyright
law. Distribution and use rights are outlined in the file "COPYING"
which should have been included with this file. If this file is
missing or damaged, see the license at:
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
https://michaelrsweet.github.io/mxml
</xsd:documentation>
</xsd:annotation>

222
mxmldoc.c
View File

@ -3441,7 +3441,6 @@ write_epub(const char *section, /* I - Section */
*package_opf_string; /* package_opf file as a string */
toc_t *toc; /* Table of contents */
toc_entry_t *tentry; /* Current table of contents */
char toc_xhtmlfile[1024]; /* XHTML file for table-of-contents */
int toc_level; /* Current table-of-contents level */
static const char *mimetype = /* mimetype file as a string */
"application/epub+zip";
@ -3761,7 +3760,71 @@ write_epub(const char *section, /* I - Section */
fclose(fp);
/*
* Now make the package_opf file...
* Make the EPUB archive...
*/
if ((epub = zipcOpen(epubfile, "w")) == NULL)
{
fprintf(stderr, "mxmldoc: Unable to create \"%s\": %s\n", epubfile, strerror(errno));
unlink(xhtmlfile);
return;
}
/*
* Add the mimetype file...
*/
status |= zipcCreateFileWithString(epub, "mimetype", mimetype);
/*
* The META-INF/ directory...
*/
status |= zipcCreateDirectory(epub, "META-INF/");
/*
* The META-INF/container.xml file...
*/
if ((epubf = zipcCreateFile(epub, "META-INF/container.xml", 1)) != NULL)
{
status |= zipcFilePuts(epubf, container_xml);
status |= zipcFileFinish(epubf);
}
else
status = -1;
/*
* The OEBPS/ directory...
*/
status |= zipcCreateDirectory(epub, "OEBPS/");
/*
* Copy the OEBPS/body.xhtml file...
*/
if ((epubf = zipcCreateFile(epub, "OEBPS/body.xhtml", 1)) != NULL)
{
if ((fp = fopen(xhtmlfile, "r")) != NULL)
{
char buffer[65536]; /* Copy buffer */
int length; /* Number of bytes */
while ((length = (int)fread(buffer, 1, sizeof(buffer), fp)) > 0)
zipcFileWrite(epubf, buffer, length);
fclose(fp);
zipcFileFinish(epubf);
}
}
else
status = -1;
unlink(xhtmlfile);
/*
* Now the OEBPS/package.opf file...
*/
if ((epubptr = strrchr(epubfile, '/')) != NULL)
@ -3827,131 +3890,68 @@ write_epub(const char *section, /* I - Section */
package_opf_string = mxmlSaveAllocString(package_opf, epub_ws_cb);
/*
* Make the nav.xhtml file...
*/
toc = build_toc(doc, introfile);
strlcpy(toc_xhtmlfile, epubfile, sizeof(toc_xhtmlfile));
if ((xhtmlptr = strstr(toc_xhtmlfile, ".epub")) != NULL)
strlcpy(xhtmlptr, "-toc.xhtml", sizeof(toc_xhtmlfile) - (size_t)(xhtmlptr - toc_xhtmlfile));
else
strlcat(toc_xhtmlfile, "-toc.xhtml", sizeof(toc_xhtmlfile));
fp = fopen(toc_xhtmlfile, "w");
fputs("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
"<!DOCTYPE html>\n"
"<html xmlns=\"http://www.w3.org/1999/xhtml\" xmlns:epub=\"http://www.idpf.org/2007/ops\">\n"
" <head>\n"
" <title>", fp);
write_string(fp, title, OUTPUT_EPUB);
fputs("</title>\n"
" <style>ol { list-style-type: none; }</style>\n"
" </head>\n"
" <body>\n"
" <nav epub:type=\"toc\">\n"
" <ol>\n", fp);
for (i = 0, tentry = toc->entries, toc_level = 1; i < toc->num_entries; i ++, tentry ++)
if ((epubf = zipcCreateFile(epub, "OEBPS/package.opf", 1)) != NULL)
{
if (tentry->level > toc_level)
{
toc_level = tentry->level;
}
else if (tentry->level < toc_level)
{
fputs(" </ol></li>\n", fp);
toc_level = tentry->level;
}
fprintf(fp, " %s<a href=\"body.xhtml#%s\">", toc_level == 1 ? "<li>" : " <li>", tentry->anchor);
write_string(fp, tentry->title, OUTPUT_EPUB);
if ((i + 1) < toc->num_entries && tentry[1].level > toc_level)
fputs("</a><ol>\n", fp);
else
fputs("</a></li>\n", fp);
}
if (toc_level == 2)
fputs(" </ol></li>\n", fp);
fputs(" </ol>\n"
" </nav>\n"
" </body>\n"
"</html>\n", fp);
fclose(fp);
free_toc(toc);
/*
* Make the EPUB archive...
*/
if ((epub = zipcOpen(epubfile, "w")) == NULL)
{
fprintf(stderr, "mxmldoc: Unable to create \"%s\": %s\n", epubfile, strerror(errno));
unlink(xhtmlfile);
return;
}
/* mimetype file */
status |= zipcCreateFileWithString(epub, "mimetype", mimetype);
/* META-INF/ directory */
status |= zipcCreateDirectory(epub, "META-INF/");
/* META-INF/container.xml file */
status |= zipcCreateFileWithString(epub, "META-INF/container.xml", container_xml);
/* OEBPS/ directory */
status |= zipcCreateDirectory(epub, "OEBPS/");
/* OEBPS/body.xhtml file */
if ((epubf = zipcCreateFile(epub, "OEBPS/body.xhtml", 1)) != NULL)
{
if ((fp = fopen(xhtmlfile, "r")) != NULL)
{
char buffer[65536]; /* Copy buffer */
int length; /* Number of bytes */
while ((length = (int)fread(buffer, 1, sizeof(buffer), fp)) > 0)
zipcFileWrite(epubf, buffer, length);
fclose(fp);
zipcFileFinish(epubf);
}
status |= zipcFilePuts(epubf, package_opf_string);
status |= zipcFileFinish(epubf);
}
else
status = -1;
unlink(xhtmlfile);
free(package_opf_string);
/* OEBPS/package.opf file */
status |= zipcCreateFileWithString(epub, "OEBPS/package.opf", package_opf_string);
/*
* Then the OEBPS/nav.xhtml file...
*/
/* OEBPS/nav.xhtml file */
if ((epubf = zipcCreateFile(epub, "OEBPS/nav.xhtml", 1)) != NULL)
{
if ((fp = fopen(toc_xhtmlfile, "r")) != NULL)
toc = build_toc(doc, introfile);
zipcFilePrintf(epubf, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
"<!DOCTYPE html>\n"
"<html xmlns=\"http://www.w3.org/1999/xhtml\" xmlns:epub=\"http://www.idpf.org/2007/ops\">\n"
" <head>\n"
" <title>%s</title>\n"
" <style>ol { list-style-type: none; }</style>\n"
" </head>\n"
" <body>\n"
" <nav epub:type=\"toc\">\n"
" <ol>\n", title);
for (i = 0, tentry = toc->entries, toc_level = 1; i < toc->num_entries; i ++, tentry ++)
{
char buffer[65536]; /* Copy buffer */
int length; /* Number of bytes */
if (tentry->level > toc_level)
{
toc_level = tentry->level;
}
else if (tentry->level < toc_level)
{
zipcFilePuts(epubf, " </ol></li>\n");
toc_level = tentry->level;
}
while ((length = (int)fread(buffer, 1, sizeof(buffer), fp)) > 0)
zipcFileWrite(epubf, buffer, length);
fclose(fp);
zipcFileFinish(epubf);
zipcFilePrintf(epubf, " %s<li><a href=\"body.xhtml#%s\">%s</a>", toc_level == 1 ? "" : " ", tentry->anchor, tentry->title);
if ((i + 1) < toc->num_entries && tentry[1].level > toc_level)
zipcFilePuts(epubf, "<ol>\n");
else
zipcFilePuts(epubf, "</li>\n");
}
if (toc_level == 2)
zipcFilePuts(epubf, " </ol></li>\n");
zipcFilePuts(epubf, " </ol>\n"
" </nav>\n"
" </body>\n"
"</html>\n");
zipcFileFinish(epubf);
free_toc(toc);
}
else
status = -1;
unlink(toc_xhtmlfile);
if (status)
fprintf(stderr, "mxmldoc: Unable to write \"%s\": %s\n", epubfile, zipcError(epub));
else if (zipcClose(epub))