This is demo for new feature of sphinx-revealjs
uv run save-pdf.py URL OUTPUT
This 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 OUTPUT
This 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() |