mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-07 10:14:46 -04:00
More work on kepubify
This commit is contained in:
parent
7bc4030276
commit
a8c9c6095b
@ -315,7 +315,7 @@ def add_dummy_title_page(container: Container, cover_image_name: str) -> None:
|
|||||||
__CONTENT__
|
__CONTENT__
|
||||||
</div></div></body></html>
|
</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:
|
if cover_image_name:
|
||||||
cover_href = container.name_to_href(cover_image_name, titlepage_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%" />')
|
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:
|
with container.open(titlepage_name, 'w') as f:
|
||||||
f.write(html)
|
f.write(html)
|
||||||
container.apply_unique_properties(titlepage_name, 'calibre:title-page')
|
container.apply_unique_properties(titlepage_name, 'calibre:title-page')
|
||||||
|
return titlepage_name
|
||||||
|
|
||||||
|
|
||||||
def remove_dummy_title_page(container: Container) -> None:
|
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 is_linear:
|
||||||
if DUMMY_TITLE_PAGE_NAME in name:
|
if DUMMY_TITLE_PAGE_NAME in name:
|
||||||
container.remove_item(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:
|
while not allow_overwrite and outpath == path:
|
||||||
c += 1
|
c += 1
|
||||||
outpath = f'{base} - {c}.kepub'
|
outpath = f'{base} - {c}.kepub'
|
||||||
container.commit(output=outpath)
|
container.commit(outpath=outpath)
|
||||||
return outpath
|
return outpath
|
||||||
|
|
||||||
|
|
||||||
|
@ -58,24 +58,29 @@ def add_resources(raw, rmap):
|
|||||||
return raw
|
return raw
|
||||||
|
|
||||||
|
|
||||||
|
def setup_simple_book(src):
|
||||||
|
with open(src, 'rb') as sf:
|
||||||
|
raw = sf.read().decode('utf-8')
|
||||||
|
raw = add_resources(raw, {
|
||||||
|
'LMONOI': P('fonts/liberation/LiberationMono-Italic.ttf'),
|
||||||
|
'LMONOR': P('fonts/liberation/LiberationMono-Regular.ttf'),
|
||||||
|
'IMAGE1': I('marked.png'),
|
||||||
|
'IMAGE2': I('textures/light_wood.png'),
|
||||||
|
})
|
||||||
|
shutil.copy2(I('lt.png'), '.')
|
||||||
|
x = 'index.html'
|
||||||
|
with open(x, 'wb') as f:
|
||||||
|
f.write(raw.encode('utf-8'))
|
||||||
|
return x
|
||||||
|
|
||||||
|
|
||||||
def get_simple_book(fmt='epub'):
|
def get_simple_book(fmt='epub'):
|
||||||
cache = get_cache()
|
cache = get_cache()
|
||||||
ans = os.path.join(cache, 'simple.'+fmt)
|
ans = os.path.join(cache, 'simple.'+fmt)
|
||||||
src = os.path.join(os.path.dirname(__file__), 'simple.html')
|
src = os.path.join(os.path.dirname(__file__), 'simple.html')
|
||||||
if needs_recompile(ans, src):
|
if needs_recompile(ans, src):
|
||||||
with TemporaryDirectory('bpt') as tdir, CurrentDir(tdir):
|
with TemporaryDirectory('bpt') as tdir, CurrentDir(tdir):
|
||||||
with open(src, 'rb') as sf:
|
x = setup_simple_book(src)
|
||||||
raw = sf.read().decode('utf-8')
|
|
||||||
raw = add_resources(raw, {
|
|
||||||
'LMONOI': P('fonts/liberation/LiberationMono-Italic.ttf'),
|
|
||||||
'LMONOR': P('fonts/liberation/LiberationMono-Regular.ttf'),
|
|
||||||
'IMAGE1': I('marked.png'),
|
|
||||||
'IMAGE2': I('textures/light_wood.png'),
|
|
||||||
})
|
|
||||||
shutil.copy2(I('lt.png'), '.')
|
|
||||||
x = 'index.html'
|
|
||||||
with open(x, 'wb') as f:
|
|
||||||
f.write(raw.encode('utf-8'))
|
|
||||||
build_book(x, ans, args=[
|
build_book(x, ans, args=[
|
||||||
'--level1-toc=//h:h2', '--language=en', '--authors=Kovid Goyal', '--cover=lt.png'])
|
'--level1-toc=//h:h2', '--language=en', '--authors=Kovid Goyal', '--cover=lt.png'])
|
||||||
return ans
|
return ans
|
||||||
@ -99,6 +104,29 @@ def get_split_book(fmt='epub'):
|
|||||||
return ans
|
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()
|
devnull = DevNull()
|
||||||
|
|
||||||
|
|
||||||
|
@ -2,13 +2,33 @@
|
|||||||
# License: GPLv3 Copyright: 2025, Kovid Goyal <kovid at kovidgoyal.net>
|
# 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.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):
|
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):
|
def test_kepubify_html(self):
|
||||||
prefix = '''<?xml version='1.0' encoding='utf-8'?>
|
prefix = '''<?xml version='1.0' encoding='utf-8'?>
|
||||||
<html xmlns="http://www.w3.org/1999/xhtml"><head><style type="text/css" class="kobostylehacks">\
|
<html xmlns="http://www.w3.org/1999/xhtml"><head><style type="text/css" class="kobostylehacks">\
|
||||||
|
Loading…
x
Reference in New Issue
Block a user