This is demo for new feature of sphinx-revealjs
uv run save-pdf.py URL OUTPUTThis is supporing PEP723 (Inline script metadata). It may work without venv.
This is demo for new feature of sphinx-revealjs
uv run save-pdf.py URL OUTPUTThis is supporing PEP723 (Inline script metadata). It may work without venv.
| #!/usr/bin/env python | |
| # /// script | |
| # dependencies = [ | |
| # "click>=8.1.7", | |
| # "playwright>=1.47.0", | |
| # "pypdf>=5.0.1", | |
| # ] | |
| # /// | |
| import io | |
| import subprocess | |
| from pathlib import Path | |
| import click | |
| from playwright.sync_api import Page, sync_playwright | |
| from pypdf import PdfReader, PdfWriter | |
| def collect_slides(page: Page, url: str) -> list[bytes]: | |
| slides = [] | |
| page.emulate_media(media="screen") | |
| page.goto(url) | |
| # NOTE: Optional - Hide component not need for pdf | |
| page.evaluate("Reveal.configure({progress: false});") | |
| size = page.viewport_size | |
| if size is None: | |
| raise Exception("Viewport is None") | |
| while True: | |
| content = page.pdf( | |
| width=str(size["width"]), | |
| height=str(size["height"]), | |
| print_background=True, | |
| ) | |
| if slides and slides[-1] == content: | |
| break | |
| slides.append(content) | |
| page.evaluate("Reveal.next();") | |
| return slides | |
| @click.command() | |
| @click.argument("url", type=str) | |
| @click.argument("out", type=click.Path(path_type=Path)) | |
| def main(url: str, out: Path): | |
| with sync_playwright() as p: | |
| browser = p.chromium.launch() | |
| page = browser.new_page() | |
| slides = collect_slides(page, url) | |
| browser.close() | |
| writer = PdfWriter() | |
| for slide in slides: | |
| reader = PdfReader(io.BytesIO(slide)) | |
| writer.add_page(reader.pages[0]) | |
| writer.write(out) | |
| writer.close() | |
| if __name__ == "__main__": | |
| subprocess.run("playwright install chromium".split()) | |
| main() |