Skip to content

Repository files navigation

slides-to-pdf

A Ruby CLI that converts Google Slides presentations into A4 PDFs with ruled note lines below each slide — built for printing lecture decks as handouts.

It connects to a running Chrome instance over the Chrome DevTools Protocol, so it captures slides using your own logged-in Google session rather than a headless browser or the Slides export API.

Requirements

  • Ruby + Bundler
  • Google Chrome
  • Node.js (used by the Playwright driver)

Setup

bundle install

Usage

1. Launch Chrome with remote debugging enabled (keep this terminal open):

/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome \
  --remote-debugging-port=9222 \
  --user-data-dir="$HOME/chrome-debug-profile"

2. Add presentations to a queue CSV. Each row needs a pending status and a URL:

status,layout,name,number,url
pending,4,auto,01,https://docs.google.com/presentation/d/YOUR_ID/edit
Column Notes
status Set to pending for new rows. The script updates it to done or error after processing — never overwrite a row yourself.
layout 1 — 1 slide/page, portrait, full width · 2 — 2 slides/page, portrait · 4 — 4 slides/page, landscape
name PDF filename, or auto to derive it from the deck title
number Optional filename prefix, e.g. 0101_Deck_Title.pdf
url Full Google Slides URL (edit or present link both work)

3. Run a batch:

bundle exec ruby capture.rb --batch your_queue.csv --dir ~/Documents/"Your Slides"

The script opens each presentation, advances through every slide, and builds one PDF per deck. Re-running is safe — done and error rows are skipped, so only pending rows are (re-)processed.

Single-URL mode

For one-off captures without a CSV:

bundle exec ruby capture.rb --url "https://docs.google.com/presentation/d/..." --layout 4

Flags

Flag Default Description
--batch FILE CSV queue file (the normal workflow)
--url URL (active tab) Process a single URL without a CSV
--layout N (asks interactively) Slides per page — 1, 2, or 4
--name NAME (slide deck title) Output filename without extension
--dir PATH ~/Documents/Slides Output folder
--delay SECONDS 0.8 Wait after each slide change before screenshotting (increase for slow-loading or image-heavy slides)
--port PORT 9222 Chrome remote debugging port
--skip-last off Drop the final slide of every deck (useful for removing blank/closing slides)

Project structure

File Role
capture.rb Entry point — parses args, connects to Chrome, runs batch or single-URL flow
lib/browser.rb Chrome connection, navigation, slide advancing
lib/screenshot.rb Slide change detection, screenshot capture, stall re-screenshot for animations
lib/pdf_builder.rb PDF layout — 1-up/2-up portrait or 4-up landscape, note lines, page numbers

How it works

  • Connects to Chrome via CDP rather than launching a headless browser, so it reuses your logged-in Google session and renders slides exactly as Google Slides displays them (fonts, embeds, animations included).
  • Advances through slides one at a time, screenshotting each. When advancing produces no URL change (an animation step within a slide), it re-takes the screenshot and overwrites the previous one, so by the time the URL changes the saved image is the slide's fully-built final state.
  • Lays out the screenshots onto A4 pages with a ruled note-taking area beneath each slide, plus light grey page numbers in the bottom-right corner.

Queue CSVs

This repo doesn't include queue CSVs — they hold your own presentation URLs and are gitignored. Create your own alongside capture.rb following the format above, or copy the header row:

status,layout,name,number,url

About

Ruby CLI that turns Google Slides decks into printable A4 handout PDFs with note lines — drives your own logged-in Chrome via the DevTools Protocol.

Topics

Resources

Stars

Watchers

Forks

Contributors

Languages