fix epub3 toc.xhtml, epub date format to satisfy spec

This commit is contained in:
Yoshiki Shibukawa 2016-07-21 10:08:06 +09:00
parent 511a0aaef7
commit 59ebeb7f1f
3 changed files with 49 additions and 41 deletions

View File

@ -1388,6 +1388,10 @@ the `Dublin Core metadata <http://dublincore.org/>`_.
a chapter, but can be confusing because it mixes entries of different
depth in one list. The default value is ``True``.
.. note::
``epub3`` builder ignores ``epub_tocdup`` option(always ``False``)
.. confval:: epub_tocscope
This setting control the scope of the epub table of contents. The setting

View File

@ -15,6 +15,7 @@ import re
import codecs
import zipfile
from os import path
from datetime import datetime
try:
from PIL import Image
@ -28,7 +29,6 @@ from docutils import nodes
from sphinx import addnodes
from sphinx.builders.html import StandaloneHTMLBuilder
from sphinx.util.i18n import format_date
from sphinx.util.osutil import ensuredir, copyfile, EEXIST
from sphinx.util.smartypants import sphinx_smarty_pants as ssp
from sphinx.util.console import brown
@ -129,8 +129,7 @@ GUIDE_TEMPLATE = u'''\
TOCTREE_TEMPLATE = u'toctree-l%d'
DOCTYPE = u'''<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
'''
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">'''
LINK_TARGET_TEMPLATE = u' [%(uri)s]'
@ -541,8 +540,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
metadata['copyright'] = self.esc(self.config.epub_copyright)
metadata['scheme'] = self.esc(self.config.epub_scheme)
metadata['id'] = self.esc(self.config.epub_identifier)
metadata['date'] = self.esc(format_date('%Y-%m-%d', language=self.config.language,
warn=self.warn))
metadata['date'] = self.esc(datetime.utcnow().strftime("%Y-%m-%d"))
metadata['files'] = files
metadata['spine'] = spine
metadata['guide'] = guide

View File

@ -12,6 +12,7 @@
import codecs
from os import path
from datetime import datetime
from sphinx.builders.epub import EpubBuilder
@ -41,13 +42,12 @@ NAVIGATION_DOC_TEMPLATE = u'''\
</html>
'''
NAVLIST_TEMPLATE = u'''\
%(indent)s <li>
%(indent)s <a href="%(refuri)s">%(text)s</a>
%(indent)s </li>
'''
NAVLIST_INDENT = ' '
NAVLIST_TEMPLATE = u'''%(indent)s <li><a href="%(refuri)s">%(text)s</a></li>'''
NAVLIST_TEMPLATE_HAS_CHILD = u'''%(indent)s <li><a href="%(refuri)s">%(text)s</a>'''
NAVLIST_TEMPLATE_BEGIN_BLOCK = u'''%(indent)s <ol>'''
NAVLIST_TEMPLATE_END_BLOCK = u'''%(indent)s </ol>
%(indent)s </li>'''
NAVLIST_INDENT = ' '
PACKAGE_DOC_TEMPLATE = u'''\
<?xml version="1.0" encoding="UTF-8"?>
@ -81,8 +81,7 @@ PACKAGE_DOC_TEMPLATE = u'''\
</package>
'''
DOCTYPE = u'''<!DOCTYPE html>
'''
DOCTYPE = u'''<!DOCTYPE html>'''
# The epub3 publisher
@ -99,6 +98,9 @@ class Epub3Builder(EpubBuilder):
navigation_doc_template = NAVIGATION_DOC_TEMPLATE
navlist_template = NAVLIST_TEMPLATE
navlist_template_has_child = NAVLIST_TEMPLATE_HAS_CHILD
navlist_template_begin_block = NAVLIST_TEMPLATE_BEGIN_BLOCK
navlist_template_end_block = NAVLIST_TEMPLATE_END_BLOCK
navlist_indent = NAVLIST_INDENT
content_template = PACKAGE_DOC_TEMPLATE
doctype = DOCTYPE
@ -124,15 +126,26 @@ class Epub3Builder(EpubBuilder):
metadata['contributor'] = self.esc(self.config.epub3_contributor)
metadata['page_progression_direction'] = self.esc(
self.config.epub3_page_progression_direction) or 'default'
metadata['date'] = self.esc(datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%SZ"))
return metadata
def new_navlist(self, node, level):
def new_navlist(self, node, level, has_child):
"""Create a new entry in the toc from the node at given level."""
# XXX Modifies the node
self.tocid += 1
node['indent'] = self.navlist_indent * level
navpoint = self.navlist_template % node
return navpoint
if has_child:
return self.navlist_template_has_child % node
else:
return self.navlist_template % node
def begin_navlist_block(self, level):
return self.navlist_template_begin_block % {
"indent": self.navlist_indent * level
}
def end_navlist_block(self, level):
return self.navlist_template_end_block % {"indent": self.navlist_indent * level}
def build_navlist(self, nodes):
"""Create the toc navigation structure.
@ -144,10 +157,9 @@ class Epub3Builder(EpubBuilder):
The difference from build_navpoints method is templates which are used
when generating navigation documents.
"""
navstack = []
navlist = []
level = 1
lastnode = None
usenodes = []
for node in nodes:
if not node['text']:
continue
@ -156,30 +168,23 @@ class Epub3Builder(EpubBuilder):
continue
if node['level'] > self.config.epub_tocdepth:
continue
if node['level'] == level:
navlist.append(self.new_navlist(node, level))
elif node['level'] == level + 1:
navstack.append(navlist)
navlist = []
level += 1
if lastnode and self.config.epub_tocdup:
navlist.append(self.new_navlist(node, level))
navlist[-1] = '<ol>\n' + navlist[-1]
usenodes.append(node)
for i, node in enumerate(usenodes):
curlevel = node['level']
if curlevel == level + 1:
navlist.append(self.begin_navlist_block(level))
while curlevel < level:
level -= 1
navlist.append(self.end_navlist_block(level))
level = curlevel
if i != len(usenodes) - 1 and usenodes[i + 1]['level'] > level:
has_child = True
else:
while node['level'] < level:
subnav = '\n'.join(navlist)
navlist = navstack.pop()
navlist[-1] = self.insert_subnav(navlist[-1], subnav)
level -= 1
navlist[-1] = navlist[-1] + '</ol>'
navlist.append(self.new_navlist(node, level))
lastnode = node
has_child = False
navlist.append(self.new_navlist(node, level, has_child))
while level != 1:
subnav = '\n'.join(navlist)
navlist = navstack.pop()
navlist[-1] = self.insert_subnav(navlist[-1], subnav)
level -= 1
navlist[-1] = navlist[-1] + '</ol>'
navlist.append(self.end_navlist_block(level))
return '\n'.join(navlist)
def navigation_doc_metadata(self, navlist):
@ -213,4 +218,5 @@ class Epub3Builder(EpubBuilder):
finally:
f.close()
# Add nav.xhtml to epub file
self.files.append(outname)
if outname not in self.files:
self.files.append(outname)