More work on kepubify

This commit is contained in:
Kovid Goyal 2025-02-22 09:38:42 +05:30
parent 7bc4030276
commit a8c9c6095b
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
3 changed files with 66 additions and 17 deletions

View File

@ -315,7 +315,7 @@ def add_dummy_title_page(container: Container, cover_image_name: str) -> None:
__CONTENT__
</div></div></body></html>
'''
titlepage_name = container.add_file(f'{DUMMY_TITLE_PAGE_NAME}.html', modify_name_if_needed=True)
titlepage_name = container.add_file(f'{DUMMY_TITLE_PAGE_NAME}.xhtml', modify_name_if_needed=True, spine_index=0)
if cover_image_name:
cover_href = container.name_to_href(cover_image_name, titlepage_name)
html = html.replace('__CONTENT__', f'<img src="{cover_href}" alt="cover" style="height: 100%" />')
@ -329,10 +329,11 @@ def add_dummy_title_page(container: Container, cover_image_name: str) -> None:
with container.open(titlepage_name, 'w') as f:
f.write(html)
container.apply_unique_properties(titlepage_name, 'calibre:title-page')
return titlepage_name
def remove_dummy_title_page(container: Container) -> None:
for name, is_linear in container.spine_names():
for name, is_linear in container.spine_names:
if is_linear:
if DUMMY_TITLE_PAGE_NAME in name:
container.remove_item(name)
@ -400,7 +401,7 @@ def kepubify_path(path, outpath='', max_workers=0, allow_overwrite=False, opts:
while not allow_overwrite and outpath == path:
c += 1
outpath = f'{base} - {c}.kepub'
container.commit(output=outpath)
container.commit(outpath=outpath)
return outpath

View File

@ -58,12 +58,7 @@ def add_resources(raw, rmap):
return raw
def get_simple_book(fmt='epub'):
cache = get_cache()
ans = os.path.join(cache, 'simple.'+fmt)
src = os.path.join(os.path.dirname(__file__), 'simple.html')
if needs_recompile(ans, src):
with TemporaryDirectory('bpt') as tdir, CurrentDir(tdir):
def setup_simple_book(src):
with open(src, 'rb') as sf:
raw = sf.read().decode('utf-8')
raw = add_resources(raw, {
@ -76,6 +71,16 @@ def get_simple_book(fmt='epub'):
x = 'index.html'
with open(x, 'wb') as f:
f.write(raw.encode('utf-8'))
return x
def get_simple_book(fmt='epub'):
cache = get_cache()
ans = os.path.join(cache, 'simple.'+fmt)
src = os.path.join(os.path.dirname(__file__), 'simple.html')
if needs_recompile(ans, src):
with TemporaryDirectory('bpt') as tdir, CurrentDir(tdir):
x = setup_simple_book(src)
build_book(x, ans, args=[
'--level1-toc=//h:h2', '--language=en', '--authors=Kovid Goyal', '--cover=lt.png'])
return ans
@ -99,6 +104,29 @@ def get_split_book(fmt='epub'):
return ans
def get_book_for_kepubify(has_cover=True, epub_version='3'):
cache = get_cache()
ans = os.path.join(cache, f'kepubify-{has_cover}-{epub_version}.epub')
src = os.path.join(os.path.dirname(__file__), 'simple.html')
if needs_recompile(ans, src):
with TemporaryDirectory('bpt') as tdir, CurrentDir(tdir):
index_html = setup_simple_book(src)
args = ['--level1-toc=//h:h2', '--language=en', '--authors=Kovid Goyal', f'--epub-version={epub_version}']
if has_cover:
args.append('--cover=lt.png')
else:
args.append('--no-default-epub-cover')
build_book(index_html, ans, args=args)
c = pc.get_container(ans)
with c.open('page_styles.css', 'r+') as f:
css = f.read()
css += '\n\ndiv { widows: 13; orphans: 12; color: red; }'
f.seek(0), f.truncate(), f.write(css)
c.commit()
return ans
devnull = DevNull()

View File

@ -2,13 +2,33 @@
# License: GPLv3 Copyright: 2025, Kovid Goyal <kovid at kovidgoyal.net>
from calibre.ebooks.oeb.polish.kepubify import Options, kepubify_html_data, remove_kobo_markup_from_html, serialize_html
from calibre.ebooks.oeb.polish.container import get_container
from calibre.ebooks.oeb.polish.kepubify import DUMMY_TITLE_PAGE_NAME, Options, kepubify_html_data, kepubify_path, remove_kobo_markup_from_html, serialize_html
from calibre.ebooks.oeb.polish.parsing import parse
from calibre.ebooks.oeb.polish.tests.base import BaseTest
from calibre.ebooks.oeb.polish.tests.base import BaseTest, get_book_for_kepubify
class KepubifyTests(BaseTest):
def test_kepubify_container(self):
def b(has_cover=True, epub_version='3'):
path = get_book_for_kepubify(has_cover=has_cover, epub_version=epub_version)
opts = Options()
opts = opts._replace(remove_widows_and_orphans=True)
opts = opts._replace(remove_at_page_rules=True)
outpath = kepubify_path(path, opts=opts, allow_overwrite=True)
c = get_container(outpath, tweak_mode=True)
spine_names = tuple(n for n, is_linear in c.spine_names)
cname = 'titlepage.xhtml' if has_cover else f'{DUMMY_TITLE_PAGE_NAME}.xhtml'
self.assertEqual(spine_names, (cname, 'index_split_000.html', 'index_split_001.html'))
ps = c.open('page_styles.css', 'r').read()
for q in ('@page', 'widows', 'orphans'):
self.assertNotIn(q, ps)
cimage = ('cover.png',) if has_cover else ()
self.assertEqual(cimage, tuple(c.manifest_items_with_property('cover-image')))
b()
b(has_cover=False)
def test_kepubify_html(self):
prefix = '''<?xml version='1.0' encoding='utf-8'?>
<html xmlns="http://www.w3.org/1999/xhtml"><head><style type="text/css" class="kobostylehacks">\