mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Conversion EPUB Output: Add an option to output EPUB 3 files.
This commit is contained in:
parent
94058dd07b
commit
10ab8bfa26
@ -117,6 +117,12 @@ class EPUBOutput(OutputFormatPlugin):
|
||||
help=_('Title for any generated in-line table of contents.')
|
||||
),
|
||||
|
||||
OptionRecommendation(name='epub_version', recommended_value='2', choices=('2', '3'),
|
||||
help=_('The version of the EPUB file to generate. EPUB 2 is the'
|
||||
' most widely compatible, only use EPUB 3 if you know you'
|
||||
' actually need it.')
|
||||
),
|
||||
|
||||
])
|
||||
|
||||
recommendations = set([('pretty_print', True, OptionRecommendation.HIGH)])
|
||||
@ -168,6 +174,7 @@ class EPUBOutput(OutputFormatPlugin):
|
||||
seen_names.add(name)
|
||||
|
||||
# }}}
|
||||
|
||||
def convert(self, oeb, output_path, input_plugin, opts, log):
|
||||
self.log, self.opts, self.oeb = log, opts, oeb
|
||||
|
||||
@ -249,6 +256,8 @@ class EPUBOutput(OutputFormatPlugin):
|
||||
opf = [x for x in os.listdir(tdir) if x.endswith('.opf')][0]
|
||||
self.condense_ncx([os.path.join(tdir, x) for x in os.listdir(tdir)
|
||||
if x.endswith('.ncx')][0])
|
||||
if self.opts.epub_version == '3':
|
||||
self.upgrade_to_epub3(tdir, opf)
|
||||
encryption = None
|
||||
if encrypted_fonts:
|
||||
encryption = self.encrypt_fonts(encrypted_fonts, tdir, uuid)
|
||||
@ -274,6 +283,26 @@ class EPUBOutput(OutputFormatPlugin):
|
||||
zf.extractall(path=opts.extract_to)
|
||||
self.log.info('EPUB extracted to', opts.extract_to)
|
||||
|
||||
def upgrade_to_epub3(self, tdir, opf):
|
||||
self.log.info('Upgrading to EPUB 3...')
|
||||
from calibre.ebooks.epub import simple_container_xml
|
||||
try:
|
||||
os.mkdir(os.path.join(tdir, 'META-INF'))
|
||||
except EnvironmentError:
|
||||
pass
|
||||
with open(os.path.join(tdir, 'META-INF', 'container.xml'), 'wb') as f:
|
||||
f.write(simple_container_xml(os.path.basename(opf)).encode('utf-8'))
|
||||
from calibre.ebooks.oeb.polish.container import EpubContainer
|
||||
container = EpubContainer(tdir, self.log)
|
||||
from calibre.ebooks.oeb.polish.upgrade import epub_2_to_3
|
||||
epub_2_to_3(container, self.log.info)
|
||||
container.commit()
|
||||
os.remove(f.name)
|
||||
try:
|
||||
os.rmdir(os.path.join(tdir, 'META-INF'))
|
||||
except EnvironmentError:
|
||||
pass
|
||||
|
||||
def encrypt_fonts(self, uris, tdir, uuid): # {{{
|
||||
from binascii import unhexlify
|
||||
|
||||
@ -324,7 +353,7 @@ class EPUBOutput(OutputFormatPlugin):
|
||||
return ans
|
||||
# }}}
|
||||
|
||||
def condense_ncx(self, ncx_path):
|
||||
def condense_ncx(self, ncx_path): # {{{
|
||||
from lxml import etree
|
||||
if not self.opts.pretty_print:
|
||||
tree = etree.parse(ncx_path)
|
||||
@ -335,6 +364,7 @@ class EPUBOutput(OutputFormatPlugin):
|
||||
tag.tail = tag.tail.strip()
|
||||
compressed = etree.tostring(tree.getroot(), encoding='utf-8')
|
||||
open(ncx_path, 'wb').write(compressed)
|
||||
# }}}
|
||||
|
||||
def workaround_ade_quirks(self): # {{{
|
||||
'''
|
||||
@ -420,8 +450,7 @@ class EPUBOutput(OutputFormatPlugin):
|
||||
if not tag.text:
|
||||
tag.getparent().remove(tag)
|
||||
for tag in XPath('//h:script')(root):
|
||||
if (not tag.text and not tag.get('src', False) and
|
||||
tag.get('type', None) != 'text/x-mathjax-config'):
|
||||
if (not tag.text and not tag.get('src', False) and tag.get('type', None) != 'text/x-mathjax-config'):
|
||||
tag.getparent().remove(tag)
|
||||
for tag in XPath('//h:body/descendant::h:script')(root):
|
||||
tag.getparent().remove(tag)
|
||||
|
@ -17,6 +17,18 @@ def rules(stylesheets):
|
||||
yield r
|
||||
|
||||
|
||||
def simple_container_xml(opf_path, extra_entries=''):
|
||||
return u'''\
|
||||
<?xml version="1.0"?>
|
||||
<container version="1.0" xmlns="urn:oasis:names:tc:opendocument:xmlns:container">
|
||||
<rootfiles>
|
||||
<rootfile full-path="{0}" media-type="application/oebps-package+xml"/>
|
||||
{extra_entries}
|
||||
</rootfiles>
|
||||
</container>
|
||||
'''.format(opf_path, extra_entries=extra_entries)
|
||||
|
||||
|
||||
def initialize_container(path_to_container, opf_name='metadata.opf',
|
||||
extra_entries=[]):
|
||||
'''
|
||||
@ -26,15 +38,7 @@ def initialize_container(path_to_container, opf_name='metadata.opf',
|
||||
for path, mimetype, _ in extra_entries:
|
||||
rootfiles += u'<rootfile full-path="{0}" media-type="{1}"/>'.format(
|
||||
path, mimetype)
|
||||
CONTAINER = u'''\
|
||||
<?xml version="1.0"?>
|
||||
<container version="1.0" xmlns="urn:oasis:names:tc:opendocument:xmlns:container">
|
||||
<rootfiles>
|
||||
<rootfile full-path="{0}" media-type="application/oebps-package+xml"/>
|
||||
{extra_entries}
|
||||
</rootfiles>
|
||||
</container>
|
||||
'''.format(opf_name, extra_entries=rootfiles).encode('utf-8')
|
||||
CONTAINER = simple_container_xml(opf_name, rootfiles).encode('utf-8')
|
||||
zf = ZipFile(path_to_container, 'w')
|
||||
zf.writestr('mimetype', 'application/epub+zip', compression=ZIP_STORED)
|
||||
zf.writestr('META-INF/', '', 0755)
|
||||
@ -42,5 +46,3 @@ def initialize_container(path_to_container, opf_name='metadata.opf',
|
||||
for path, _, data in extra_entries:
|
||||
zf.writestr(path, data)
|
||||
return zf
|
||||
|
||||
|
||||
|
@ -23,9 +23,11 @@ class PluginWidget(Widget, Ui_Form):
|
||||
['dont_split_on_page_breaks', 'flow_size',
|
||||
'no_default_epub_cover', 'no_svg_cover',
|
||||
'epub_inline_toc', 'epub_toc_at_end', 'toc_title',
|
||||
'preserve_cover_aspect_ratio', 'epub_flatten']
|
||||
'preserve_cover_aspect_ratio', 'epub_flatten', 'epub_version']
|
||||
)
|
||||
for i in range(2):
|
||||
self.opt_no_svg_cover.toggle()
|
||||
ev = get_option('epub_version')
|
||||
self.opt_epub_version.addItems(list(ev.option.choices))
|
||||
self.db, self.book_id = db, book_id
|
||||
self.initialize_options(get_option, get_help, db, book_id)
|
||||
|
@ -50,7 +50,7 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<item row="7" column="0">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
@ -118,6 +118,19 @@
|
||||
<item row="4" column="1">
|
||||
<widget class="QLineEdit" name="opt_toc_title"/>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>EP&UB version:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>opt_epub_version</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="QComboBox" name="opt_epub_version"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
|
Loading…
x
Reference in New Issue
Block a user