ADA PDF Remediation Prompt for UC Compliance — Free AI + CLT

Python script: ada_tag_pdf.py

Tool overview and workflow

Step 1 instructions

STEP 1 INSTRUCTIONS: 1. Copy the prompt below using the button (or select it manually). 2. Paste it into a new conversation with any AI that supports vision and PDF uploads (including free tiers). 3. Upload your PDF in the same message or immediately after. 4. The AI will return a JSON block. Copy that JSON and save it to a file (e.g., elements.json). 5. Proceed to Step 2: python ada_tag_pdf.py input.pdf elements.json

(updated April 21, 2026)

AI prompt text to copy

You are an ADA/Section 508 accessibility analyst. I am uploading a PDF that needs to be made accessible to comply with WCAG 2.1 Level AA and PDF/UA (ISO 14289) standards for a University of California campus accessibility review. Your task is ANALYSIS ONLY — you do not need to write or run any code. Examine every page of this PDF and identify every visual element that requires alternative text for screen reader accessibility, AND identify the document's heading hierarchy so the downstream pipeline can build a properly nested structure tree. --- ### WHAT TO IDENTIFY Examine each page and find every instance of: - **Headings** — any rendered text that visually functions as a title, section header, or subheading. This includes the document/cover title, per-page slide titles, and subsection headings within a page. Classify each with a heading level (see "HEADING HIERARCHY" below). Campus accessibility checkers (including Panorama) will fail the PDF if headings are missing, unnested, or empty, so treat this category as mandatory — every content page with a visible title needs a heading entry. - **Equations** — inline or display math, formulas, chemical notation, any symbolic expression that is not plain text. This includes LaTeX-rendered equations, equation images from tools like LaTeXiT or MathType, and handwritten formulas. **Classify these as `Formula`, not `Figure`** — the downstream pipeline uses this type to create the correct PDF/UA structure element (`/Formula` vs `/Figure`). - **Figures** — photographs, illustrations, diagrams, flowcharts, circuit diagrams, maps, schematics, or any non-text visual content that conveys information. - **Plots and charts** — line plots, bar charts, scatter plots, histograms, pie charts, box plots, or any data visualization. - **Images** — photographs, logos, icons, clip art, screenshots, or QR codes. - **Tables rendered as images** — tables that are graphical rather than text-based. - **Rendered prose blocks** — paragraphs of body text rendered as graphics (common in Keynote/LaTeXiT decks where every text block is a separate rendered element). Classify as `Paragraph`. Do NOT flag purely decorative backgrounds (e.g., a solid-color slide background) or plain text that is already extractable (non-rendered body text in a Word/LaTeX-native PDF). **IMPORTANT — Slides with mixed equation and prose content:** Presentation tools like Keynote with LaTeXiT render every text block (equations, bullet points, headings, prose paragraphs) as a separate graphical element in the PDF. On a typical lecture slide, you might see 5–8 distinct graphical regions: a heading, two prose paragraphs, and three equations. You must identify **every** visually distinct rendered block, not just the ones that look like traditional "figures." If a slide has a heading rendered as a graphic, a prose paragraph rendered as a graphic, and three equations — that is five elements: one `Heading`, one `Paragraph`, and three `Formula`s. When in doubt about whether something is a separate element, err on the side of splitting rather than combining. The pipeline can merge entries that map to the same structural element, but it cannot split an entry that was incorrectly combined. --- ### HEADING HIERARCHY The downstream pipeline builds a WCAG 2.1-compliant heading tree. Your classification must respect these rules: 1. **Exactly one `level: 1` heading per document.** This is the document title — usually on a dedicated title/cover slide, or the most prominent heading on the first page. If the first content page IS the title page (no separate cover), mark that slide's title as `level: 1` and do NOT also mark it as `level: 2`. 2. **Per-page slide/section titles are `level: 2`** on every page *except* the one page where the `level: 1` heading lives. 3. **Subheadings within a page** (e.g., a smaller bold subtitle under the slide title) are `level: 3`. Deeper nesting (`level: 4`, `level: 5`) is rare in lecture material but is allowed if visually warranted. 4. **No level skips.** Each heading's `level` may be at most one greater than the most recent heading's level in document order. `H1 → H2` is fine; `H1 → H3` is not. If a visual subheading looks like it should be H3 but there is no H2 above it, classify it as H2 instead. 5. **Pages with no visible title** (transition slides, pure-image pages, Q&A slides) get no heading entry. Skipping one page is fine; inventing an empty heading is worse than omitting it. 6. **If the document has no visible title at all** (e.g., a problem set that starts with "Problem 1" with no cover), promote the first rendered heading to `level: 1` and classify the rest as `level: 2`. Do not invent an H1 that isn't in the rendered output. --- ### HOW TO DESCRIBE EACH ELEMENT For each element, provide: 1. **page** — the page number (starting from 1) 2. **index** — a sequential integer starting from 1, incrementing for every element across the entire document 3. **type** — one of: `Heading`, `Paragraph`, `Figure`, `Formula`, `Image`, `Diagram`, `Table` - Use `Heading` for rendered title/header text (document title, slide titles, subsection headings). Always include the `level` field for Heading entries. - Use `Paragraph` for rendered prose/body-text blocks (bullet lists, explanatory paragraphs rendered as graphics). - Use `Formula` for any mathematical expression, equation, or symbolic notation — even short inline ones like "k = ±√(2mE/ℏ²)" - Use `Figure` for non-mathematical visual content (diagrams, photos, plots, charts) - Use `Image` for photographs, QR codes, logos, and screenshots - Use `Diagram` for flowcharts, circuit diagrams, or schematic layouts 4. **level** — integer 1–6, **required when `type` is `Heading`**, omit otherwise. See "HEADING HIERARCHY" above. 5. **alt_text** — a complete, screen-reader-quality description: - For **headings**: transcribe the heading text exactly as rendered, preserving original capitalization and punctuation. No prose description — just the text. The pipeline uses this string to locate the matching MCID in the content stream. - For **paragraphs**: transcribe the text content verbatim. If the block is a bullet list, join bullets with newlines or semicolons in the order they appear. - For **equations/formulas**: write the math in spoken English (e.g., "i h-bar times partial derivative of Psi with respect to t equals H-hat times Psi") AND include a LaTeX representation after the prefix `LaTeX:`. - For **plots/charts**: describe the axes, units, data trend, and key quantitative takeaway. Include specific numbers visible on the chart. - For **figures/diagrams**: describe what is depicted, its spatial layout, any labels, and its purpose in context. - For **photographs**: describe what is shown and why it is relevant. - For **QR codes**: note that it is a QR code and state the URL if visible on the slide. - Alt-text for non-heading, non-paragraph elements should be 1–4 sentences. A screen reader user should fully understand the content without seeing the image. 6. **position** — the approximate vertical position of this element on the page: `"top"`, `"upper"`, `"middle"`, `"lower"`, or `"bottom"`. This helps the downstream pipeline match entries to the PDF's internal content stream order. Use `"top"` for slide titles / page headings. Also provide: 7. **title** — a short document title derived from the PDF content (e.g., course name + lecture topic). Provide this ONCE, before the elements list. This should match (or closely match) the alt_text of the `level: 1` heading entry. --- ### ELEMENT COUNTING GUIDANCE To help the downstream pipeline match your analysis to the PDF's internal structure: - **Count every visually distinct rendered block on each page.** On a typical lecture slide with a heading, two bullet-point blocks, and three equations, you should produce 6 entries for that page — one `Heading`, two `Paragraph`s, three `Formula`s. - **Equations that appear as a single visual group** (e.g., two lines of a derivation with no text between them) should be treated as **one** element. - **Bullet point lists** rendered as a single graphical block are **one** `Paragraph` element, not one per bullet. - A **page-level fallback alt-text** entry (type `Figure`, covering the whole page) is acceptable when the page layout is too complex to reliably decompose into individual elements. Mark it with `"position": "full_page"`. The downstream pipeline will apply this alt-text to all figure elements on that page. A full-page fallback does NOT exempt the page from having a `Heading` entry — always include the page title as a separate `Heading` entry even when you use a full_page fallback for the rest. --- ### RESPONSE FORMAT Respond with ONLY a single JSON code block — no commentary before or after. Use this exact structure: ```json { "title": "Physics 113A — Lecture 14: The Schrödinger Equation", "elements": [ { "page": 1, "index": 1, "type": "Heading", "level": 1, "position": "top", "alt_text": "Physics 113A — Lecture 14: The Schrödinger Equation" }, { "page": 2, "index": 2, "type": "Heading", "level": 2, "position": "top", "alt_text": "Time-Dependent Form" }, { "page": 2, "index": 3, "type": "Formula", "position": "middle", "alt_text": "The Schrödinger equation states that i h-bar times the partial derivative of Psi with respect to t equals H-hat times Psi. LaTeX: i\\hbar\\frac{\\partial\\Psi}{\\partial t} = \\hat{H}\\Psi" }, { "page": 2, "index": 4, "type": "Paragraph", "position": "lower", "alt_text": "Here H-hat is the Hamiltonian operator, which for a single particle in a potential V(x) takes the form of the kinetic energy operator plus V(x)." }, { "page": 3, "index": 5, "type": "Heading", "level": 2, "position": "top", "alt_text": "Infinite Square Well" }, { "page": 3, "index": 6, "type": "Figure", "position": "middle", "alt_text": "A diagram showing a particle in a one-dimensional infinite square well potential. The potential is zero between x=0 and x=L, and infinite outside that region. The first three energy eigenfunctions are drawn as sinusoidal waves inside the well." }, { "page": 3, "index": 7, "type": "Heading", "level": 3, "position": "lower", "alt_text": "Boundary Conditions" }, { "page": 4, "index": 8, "type": "Image", "position": "middle", "alt_text": "QR code linking to https://phet.colorado.edu/en/simulation/quantum-tunneling" } ] } ``` Note in the example above: - Exactly one `level: 1` heading (the document title, on page 1). - Page 2 and page 3 each have a `level: 2` heading at the top. - Page 3 has a `level: 3` subheading ("Boundary Conditions") — allowed because the most recent heading above it was `level: 2`. - Page 4 has no heading entry (image-only page). - No heading skips a level. If a page has NO rendered elements (plain extractable text only), do not include any entries for that page. If the PDF has NO rendered elements at all and no visible headings, respond with: ```json { "title": "Document title", "elements": [] } ``` Remember: respond with JSON only. No introduction, no summary, no markdown outside the code block.