Make the manual's EPUB from the same JPEG pictures as its PDF
Benchmarks / CPU and I/O (per commit) (push) Successful in 3m35s
Benchmarks / Frame budget (on demand) (push) Skipped
Build and test / Desktop (Linux) (push) Failing after 1h38m56s
Build and test / Layer separation (push) Successful in 27s
🐳 Android image / Build and push (push) Successful in 5s
Build and test / android-image (push) Successful in 5s
🐳 Windows image / Build and push (push) Successful in 2s
Build and test / windows-image (push) Successful in 3s
Manual pages / Publish the manual (push) Successful in 44s
Traceability / Requirement traces (push) Successful in 1m3s
Build and test / Android (aarch64) (push) Successful in 47m30s
Build and test / Windows (x86_64, cross) (push) Successful in 31m26s
Build and test / Publish the release (push) Skipped
Benchmarks / CPU and I/O (per commit) (push) Successful in 3m35s
Benchmarks / Frame budget (on demand) (push) Skipped
Build and test / Desktop (Linux) (push) Failing after 1h38m56s
Build and test / Layer separation (push) Successful in 27s
🐳 Android image / Build and push (push) Successful in 5s
Build and test / android-image (push) Successful in 5s
🐳 Windows image / Build and push (push) Successful in 2s
Build and test / windows-image (push) Successful in 3s
Manual pages / Publish the manual (push) Successful in 44s
Traceability / Requirement traces (push) Successful in 1m3s
Build and test / Android (aarch64) (push) Successful in 47m30s
Build and test / Windows (x86_64, cross) (push) Successful in 31m26s
Build and test / Publish the release (push) Skipped
pandoc embedded every recording whole, so the EPUB came out at 63 MB for readers that mostly show a GIF's first frame anyway. tools/manual/pdf.py now makes both downloads from its JPEG copies of the pictures: 7.5 MB.
This commit is contained in:
@@ -62,7 +62,6 @@ jobs:
|
|||||||
# A4, a cover and a contents page with page numbers, a chapter a page —
|
# A4, a cover and a contents page with page numbers, a chapter a page —
|
||||||
# so it says what the page says; tools/manual/pdf.py says why it goes
|
# so it says what the page says; tools/manual/pdf.py says why it goes
|
||||||
# through JPEG copies of the pictures first.
|
# through JPEG copies of the pictures first.
|
||||||
# The EPUB comes from the Markdown, which pandoc reads better than a page.
|
|
||||||
- name: Make the PDF and the EPUB
|
- name: Make the PDF and the EPUB
|
||||||
run: |
|
run: |
|
||||||
set -e
|
set -e
|
||||||
@@ -73,10 +72,8 @@ jobs:
|
|||||||
python3 -m venv /tmp/wp
|
python3 -m venv /tmp/wp
|
||||||
/tmp/wp/bin/pip install -q weasyprint
|
/tmp/wp/bin/pip install -q weasyprint
|
||||||
mkdir -p site
|
mkdir -p site
|
||||||
/tmp/wp/bin/python tools/manual/pdf.py docs/manual site/darkroom-manual.pdf
|
/tmp/wp/bin/python tools/manual/pdf.py docs/manual \
|
||||||
title=$(sed -n 's/^# //p' docs/manual/README.md | head -1)
|
site/darkroom-manual.pdf site/darkroom-manual.epub
|
||||||
(cd docs/manual && pandoc README.md -o ../../site/darkroom-manual.epub \
|
|
||||||
--metadata title="$title" --toc --toc-depth=2 --epub-chapter-level=2)
|
|
||||||
ls -l site
|
ls -l site
|
||||||
|
|
||||||
# One commit, force-pushed: the branch is a build output, and its history
|
# One commit, force-pushed: the branch is a build output, and its history
|
||||||
|
|||||||
+31
-16
@@ -1,14 +1,17 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
"""The manual as a PDF: docs/manual/index.html through its print stylesheet.
|
"""The manual as a PDF, and as an EPUB: the downloads the page links to.
|
||||||
|
|
||||||
python3 tools/manual/pdf.py docs/manual out.pdf
|
python3 tools/manual/pdf.py docs/manual out.pdf [out.epub]
|
||||||
|
|
||||||
Needs WeasyPrint (and so Pillow): `pip install weasyprint`. The Manual pages
|
The PDF is docs/manual/index.html through its print stylesheet; the EPUB is
|
||||||
workflow runs this and publishes the result beside the page.
|
README.md through pandoc, which reads Markdown better than a page. Needs
|
||||||
|
WeasyPrint (and so Pillow), and pandoc for the EPUB. The Manual pages
|
||||||
|
workflow runs this and publishes both beside the page.
|
||||||
|
|
||||||
The page's pictures are PNG screenshots and GIF recordings, 16 MB and 46 MB
|
The page's pictures are PNG screenshots and GIF recordings, 16 MB and 46 MB
|
||||||
of them, and WeasyPrint embeds a picture as it finds it: losslessly, a GIF
|
of them, and WeasyPrint and pandoc embed a picture as they find it:
|
||||||
whole. So the PDF is made from a copy of the page whose pictures are JPEGs
|
losslessly, a GIF whole (63 MB of EPUB, for e-readers that mostly do not
|
||||||
|
animate). So both are made from copies whose pictures are JPEGs
|
||||||
(a recording's first frame, which is all a page can show) at the size they
|
(a recording's first frame, which is all a page can show) at the size they
|
||||||
were recorded. Full chroma, because a 4:2:0 JPEG smears the coloured noise
|
were recorded. Full chroma, because a 4:2:0 JPEG smears the coloured noise
|
||||||
the AI denoise close-ups exist to show.
|
the AI denoise close-ups exist to show.
|
||||||
@@ -16,6 +19,7 @@ the AI denoise close-ups exist to show.
|
|||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import shutil
|
import shutil
|
||||||
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
|
|
||||||
@@ -31,7 +35,7 @@ def as_jpeg(src, dst):
|
|||||||
im.convert('RGB').save(dst, 'JPEG', quality=QUALITY, subsampling=0, optimize=True)
|
im.convert('RGB').save(dst, 'JPEG', quality=QUALITY, subsampling=0, optimize=True)
|
||||||
|
|
||||||
|
|
||||||
def main(manual_dir, out):
|
def main(manual_dir, pdf, epub=None):
|
||||||
with tempfile.TemporaryDirectory() as tmp:
|
with tempfile.TemporaryDirectory() as tmp:
|
||||||
os.mkdir(os.path.join(tmp, 'media'))
|
os.mkdir(os.path.join(tmp, 'media'))
|
||||||
renamed = {}
|
renamed = {}
|
||||||
@@ -42,16 +46,27 @@ def main(manual_dir, out):
|
|||||||
jpg = f'{stem}.{ext[1:].lower()}.jpg' # two pictures may share a stem
|
jpg = f'{stem}.{ext[1:].lower()}.jpg' # two pictures may share a stem
|
||||||
as_jpeg(os.path.join(manual_dir, 'media', name), os.path.join(tmp, 'media', jpg))
|
as_jpeg(os.path.join(manual_dir, 'media', name), os.path.join(tmp, 'media', jpg))
|
||||||
renamed[name] = jpg
|
renamed[name] = jpg
|
||||||
page = open(os.path.join(manual_dir, 'index.html'), encoding='utf-8').read()
|
|
||||||
page = re.sub(r'src="media/([^"]+)"',
|
def copy(source, pattern, out):
|
||||||
lambda m: f'src="media/{renamed.get(m.group(1), m.group(1))}"', page)
|
text = open(os.path.join(manual_dir, source), encoding='utf-8').read()
|
||||||
with open(os.path.join(tmp, 'index.html'), 'w', encoding='utf-8') as f:
|
text = re.sub(pattern, lambda m: m.group(1) + renamed.get(m.group(2), m.group(2)), text)
|
||||||
f.write(page)
|
with open(os.path.join(tmp, out), 'w', encoding='utf-8') as f:
|
||||||
HTML(os.path.join(tmp, 'index.html')).write_pdf(os.path.join(tmp, 'manual.pdf'))
|
f.write(text)
|
||||||
shutil.move(os.path.join(tmp, 'manual.pdf'), out)
|
return os.path.join(tmp, out)
|
||||||
|
|
||||||
|
page = copy('index.html', r'(src="media/)([^"]+)', 'index.html')
|
||||||
|
HTML(page).write_pdf(os.path.join(tmp, 'manual.pdf'))
|
||||||
|
shutil.move(os.path.join(tmp, 'manual.pdf'), pdf)
|
||||||
|
|
||||||
|
if epub:
|
||||||
|
md = copy('README.md', r'(\]\(media/)([^)\s]+)', 'README.md')
|
||||||
|
title = next(l[2:].strip() for l in open(md, encoding='utf-8') if l.startswith('# '))
|
||||||
|
subprocess.run(['pandoc', 'README.md', '-o', 'manual.epub', '--metadata', f'title={title}',
|
||||||
|
'--toc', '--toc-depth=2', '--epub-chapter-level=2'], cwd=tmp, check=True)
|
||||||
|
shutil.move(os.path.join(tmp, 'manual.epub'), epub)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
if len(sys.argv) != 3:
|
if len(sys.argv) not in (3, 4):
|
||||||
sys.exit(__doc__)
|
sys.exit(__doc__)
|
||||||
main(sys.argv[1], sys.argv[2])
|
main(*sys.argv[1:])
|
||||||
|
|||||||
Reference in New Issue
Block a user