Claude CodeでPDF/UAのveraPDF違反を直す — Typst・HTML・LaTeXの生成元から
veraPDFのPDF/UA検査で出た失敗ルールを、Claude Codeに渡して生成元のソース側で直す手順です。ルール番号ごとの直し先、検査コマンド、CLAUDE.mdと権限の設定例、機械では判定できない確認点を扱います。
PDF/UA(ユニバーサルアクセス向けのPDF規格)の検査は、veraPDFに任せると失敗したルールが番号つきで返ります。その番号を手がかりに、生成元のTypst・HTML・LaTeXを直すところまでをClaude Codeに回させる手順をまとめます。PDFファイルそのものには手を入れません。直すのは常にソースで、直したら再コンパイルして再検査します。
veraPDFが見るのは構造の有無であって、内容の良し悪しではありません。この線引きを先に押さえておくと、Claude Codeに任せる範囲と人が見る範囲が分かれます。
検査プロファイルは -f ua1 で固定する
veraPDFは、PDF/AとPDF/UAの規則群を「検証プロファイル」として同梱しています。verapdf --list で一覧が出ます。
ua1— PDF/UA-1ua2— PDF/UA-2wt1r— WTPDF 1.0 Reusewt1a— WTPDF 1.0 Accessibility
注意したいのは、-f を省いたときの挙動です。veraPDFはPDFの埋め込みXMPメタデータにある適合宣言を読み、プロファイルを自動で選びます。メタデータが無い、または読めないときの既定はPDF/A-1bです。PDF/UAを名乗っていないPDFにPDF/UAの規則は当たらず、PDF/A-1bとして検査されます。
PDF/UAを確かめたいときは、プロファイルを明示します。
verapdf -f ua1 --format text --maxfailuresdisplayed 5 \
report.pdf 2>verapdf.log各オプションの意味は次のとおりです。
--format text— 既定のXMLではなく、人が読みやすいテキスト形式で出す--maxfailuresdisplayed 5— 同じルールの失敗表示を5件で打ち切る。既定は1ルールあたり100件2>verapdf.log— ログは標準エラーに出るため、レポートに混ざらないよう別ファイルへ逃がす
veraPDFの実行にはJava 8以降が必要です。通過したルールも見たいときは --verbose を足します。なお、既定のXMLレポートは失敗ルールごとに clause・testNumber・description・context を持ちます。context には問題のあるオブジェクトの位置が入るので、Claude Codeに原因箇所を探させるときの手がかりになります。
失敗ルールを「どこで直すか」に振り分ける
PDF/UA-1のルール番号は、veraPDFが公開しているルール一覧(7.1-3 のような形式)に対応しています。生成元で直す観点から、よく当たる番号をまとめます。
| 規則 | 規則の内容 | Typstでの直し先 | HTML→PDF(WeasyPrint)での直し先 |
|---|---|---|---|
| 5-1 | 規則の内容PDF/UA識別のXMPが無い | Typstでの直し先--pdf-standard ua-1 を付ける | HTML→PDF(WeasyPrint)での直し先--pdf-variant pdf/ua-1 を付ける |
| 7.1-9 | 規則の内容dc:title が無い | Typstでの直し先#set document(title: …) | HTML→PDF(WeasyPrint)での直し先<title> を書く |
| 6.2-1、7.1-11 | 規則の内容タグ付きPDFでない、構造ツリーが無い | Typstでの直し先--no-pdf-tags を外す | HTML→PDF(WeasyPrint)での直し先--pdf-tags の有無を見る |
| 7.1-3 | 規則の内容内容がArtifactでもタグ付きでもない | Typstでの直し先装飾だけを pdf.artifact で包む | HTML→PDF(WeasyPrint)での直し先HTML構造を見直す |
| 7.2-34 | 規則の内容ページ内容の自然言語が決まらない | Typstでの直し先文書の先頭で #set text(lang: …) | HTML→PDF(WeasyPrint)での直し先<html lang="…"> を付ける |
| 7.3-1 | 規則の内容Figureに代替記述が無い | Typstでの直し先image と figure に alt: | HTML→PDF(WeasyPrint)での直し先<img> の alt を書く |
| 7.7-1 | 規則の内容数式に代替記述が無い | Typstでの直し先math.equation に alt: | HTML→PDF(WeasyPrint)での直し先MathML等の構造を見直す |
| 7.2-3〜7.2-15、7.5-1 | 規則の内容表の構造が不正、THに Scope が無い | Typstでの直し先grid でなく table と table.header | HTML→PDF(WeasyPrint)での直し先<table>・<th> で書く |
HTML側の右端は、WeasyPrintの説明に合わせた書き方です。同ドキュメントは、PDF/UAを通す条件として「正しいHTML構造を使うこと」を挙げ、<title> と <html> の lang を必須の情報に数えています。HTMLの順序がPDFの内容順序になるとも書かれています。<img> の alt が Figure の代替記述として出るかは、再検査で 7.3-1 が消えるかどうかで確かめるのが確実です。
落とし穴
7.1-3 を黙らせるために本文を Artifact にしない
7.1-3 は「内容はArtifactとして印を付けるか、実体としてタグ付けする」という規則です。本文や図を pdf.artifact で包めば失敗は消えますが、Artifactは支援技術から隠されます。Typstのガイドも、ページ上の要素は読み上げ手段を持つか、Artifactかのどちらかでなければならないと説明しています。Claude Codeに渡す指示には「包んでよいのは装飾だけ」と明記します。
Typstで直す
Typstはタグ付きPDFを既定で出力します。PDF/UA-1に絞る場合は、コンパイル時に標準を指定します。
typst compile --pdf-standard ua-1 report.typ report.pdfua-1 を指定すると、Typstは書き出しの時点で追加の検査を走らせます。たとえば、画像に代替記述が無ければコンパイルエラーになります。数式の alt が無い場合もPDF/UA-1の書き出しは失敗します。veraPDFにかける前に、コンパイラが落とせる違反は落としてくれます。
ソース側の書き方は次のようになります。
#set document(title: [四半期レポート])
#set text(lang: "ja")
#title()
= 売上の推移
#figure(
image("sales.png", alt: "四半期ごとの売上を示す棒グラフ。第3四半期が最大"),
caption: [四半期別の売上],
)
#table(
columns: 2,
table.header[四半期][売上],
[第1四半期], [120],
[第2四半期], [135],
)
#math.equation(
alt: "aの2乗プラスbの2乗はcの2乗に等しい",
$a^2 + b^2 = c^2$,
)ポイントは3つあります。
#set text(lang: …)は文書の先頭、内容より前に置く。指定が無いとTypstは英語として扱う。言語はISO 639のコードで書き、2文字コードがあるならそちらを使う- 文書タイトルは
#set document(title: …)で設定する。見出しをタイトル代わりにせず、title要素を使う - 表は
tableで書き、見出し行はtable.headerで印を付ける。gridは読み上げ上は透明な入れ物で、表データには向かない
読み順にも注意が必要です。Typstはマークアップに書いた順を読み順として扱います。place や move、浮動する図を使うときは、論理的に読まれてほしい位置に呼び出しを書きます。この点はveraPDFが検出しないので、後述の人の確認に回ります。
HTMLからPDFにするとき
HTMLから出す場合は、WeasyPrintのPDF/UAバリアントを使います。
weasyprint --pdf-variant pdf/ua-1 report.html report.pdfHTMLの冒頭は、lang と title を含む形にします。
<!doctype html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>四半期レポート</title>
</head>この経路でのClaude Codeの仕事は、HTMLの構造を意味のあるタグに直すことです。<div> の入れ子で組んだ見出しや表を、<h1>・<table>・<th> に置き換えます。見た目のCSSではなく、タグの種類がPDFの構造を決めるためです。HTMLからPDFへの変換全般は、Markdownからdocx・日本語PDFへ変換する記事にまとめています。
LaTeXで直す
LaTeXのタグ付けは、文書クラスの前に置く \DocumentMetadata で有効にします。LaTeX Tagged PDFプロジェクトの資料によると、このコマンドは pdfstandard・lang・pdfversion といったキーを受け付けます。LaTeXニュースの設定例(pdfstandard = ua-2・tagging = on)に、日本語文書向けの lang = ja を足すと次の形になります。
\DocumentMetadata{
lang = ja,
pdfstandard = ua-2,
tagging = on
}
\documentclass{article}この例はPDF/UA-2を宣言するので、検査も verapdf -f ua2 になります。PDF/UA-2はPDF 2.0を前提とする規格で、PDF/UA-1向けのプロファイルとは規則が異なります。UA-1を宣言するかUA-2を宣言するかで、-f に渡す値を揃えてください。
画像・数式・表のタグ付けは、用意されているパッケージごとに状況が違います。プロジェクトは約1000の貢献パッケージの対応状況を「Tagging Status」のページに公開しているので、使っているパッケージが載っているかを先に見ておくと、Claude Codeが原因を探す範囲を絞れます。日本語組版のエンジンとの組み合わせは、この記事では扱っていません。縦書きなどのLaTeX変換は縦書き日本語PDFの記事を参照してください。
Claude Codeに回させる
直す作業を、ソースの編集・コンパイル・検査の繰り返しとして設計します。
PDF/UAの修正ループ
- 1
コンパイルして検査する
生成コマンドと
verapdf -f ua1を続けて実行し、失敗したルール番号を取り出す。 - 2
番号をソースの修正に対応づける
上の対応表の「直し先」に沿って、Typst・HTML・LaTeXのソースだけを編集する。
- 3
再コンパイルして再検査する
失敗ルールが0件になるか、残りが人の判断を要するものだけになるまで繰り返す。
CLAUDE.mdに書く制約
手順を毎回プロンプトで説明しなくて済むよう、プロジェクトの CLAUDE.md に制約を置きます。
## PDF/UA
- 成果物は `typst compile --pdf-standard ua-1` で出す。PDFは直接編集しない
- 修正は `.typ` ファイルにだけ入れる
- `pdf.artifact` で包んでよいのは装飾だけ。本文・図・表は包まない
- 画像の `alt` は画像を見てから書き、変更した alt を一覧で報告する
- 完了条件は `verapdf -f ua1` の失敗ルールが0件であることCLAUDE.mdは文脈として読まれる指示で、守られることが保証される設定ではありません。「失敗ルールが0件になるまで止めない」という完了条件を確実に効かせたいときは、Stopフックで検査を走らせる方法があります。組み方はTypstのPDFをClaude Codeで組む記事にあり、検査コマンドを typst fonts の確認からveraPDFに差し替えるだけで転用できます。
権限を絞る
編集とコンパイル、検査だけを許可します。.claude/settings.json の例です。
{
"permissions": {
"allow": [
"Edit",
"Bash(typst compile *)",
"Bash(verapdf *)"
]
}
}Bashのルールは、* より前の文字列が一致したコマンドだけを許可します。Bash(verapdf *) は verapdf の呼び出しだけに効き、任意のコマンドを通すことはありません。
検査結果をパイプで渡す
非対話モードの claude -p は標準入力を読めるため、検査の出力をそのまま渡せます。
verapdf -f ua1 --format text --maxfailuresdisplayed 5 \
report.pdf 2>/dev/null \
| claude -p "この PDF/UA 検査結果の失敗ルールを、report.typ を直して解消して。\
修正後に typst compile と verapdf を再実行し、結果を報告して" \
--allowedTools "Read,Edit,Bash(typst compile *),Bash(verapdf *)"標準入力は10MBが上限です。--maxfailuresdisplayed で同じルールの失敗を絞っておけば、レポートが大きくなりすぎるのを避けられます。ほかのCLIの検査結果を渡す同じ型の手順は、lycheeのリンク切れを直す記事にもあります。
veraPDFが合格にしても残る確認
veraPDFの規則は、タグや属性の有無を機械的に判定します。次の点は合格しても保証されません。
- 代替記述の中身 —
7.3-1が問うのは、Figureに代替記述があるかどうかです。「グラフ」の一語でも規則上は存在します。Claude Codeは画像を読んで下書きを作れますが、文脈に合う記述かどうかは人が決めます。Typstのガイドは、画像の内容を電話で友人に伝えるつもりで、周囲の文脈に合わせて短く書くよう勧めています - 読み順 — 構造ツリーの順序が読む順序と合っているかは、規則では判定できません
- 言語の正しさ —
langが宣言されていることは見ますが、宣言と実際の本文言語が一致するかは見ません。Typstのガイドもこの点を自動検査の対象外としています - 色やレイアウトだけで伝えている情報 — 色のコントラストや、色だけで区別する凡例は規則の外です。Typstのドキュメントは、PDF/UA-1の書き出し時にもこの種の点を手動で確かめるべきものとして挙げています
実際に支援技術で読み上げさせる確認も、重要な文書では有効です。LaTeXプロジェクトの資料は、タグ構造を確かめる道具として、veraPDFのオンライン版のほか、PAC(Windows専用)、ngPDF、showtagsを挙げています。なおPACはPDF 1.7とPDF/UA-1までを理解し、PDF 2.0とPDF/UA-2には対応しません。UA-2の文書を作った場合、PACで開けない点は規格の違いによるものです。
つまずきやすい点
- PDF/UA-1とPDF/A-4は同時に指定できない — Typstでは、前者がPDF 1.7以前を、後者がPDF 2.0を要求するためです。PDF/UA-1とPDF/A-2aのような組み合わせは指定できます
- TypstのPDF/UAはUA-1のみ — PDF/UA-2は未対応です。UA-2が必要な場合は、WeasyPrintの
pdf/ua-2やLaTeXのpdfstandardを検討します -fを付け忘れて「合格」に見える — メタデータの無いPDFがPDF/A-1bとして検査され、PDF/UAの違反が出ないことがあります。レポートのprofileNameがPDF/UAになっているかを確かめます- PDFを画像として埋め込んでも構造は残らない — Typstは、PDF画像のタグをコンパイル後の文書に引き継ぎません。元のPDFがアクセシブルでも、埋め込み先では代替記述を付け直します
- 画像化した文字 — 文字を画像にした見出しや図は、テキストとして読み上げられません。ネイティブのテキストで組み直すのが原則です
まとめ
veraPDFのレポートは、失敗ルール番号とソース側の修正点を結ぶ地図として使えます。タイトル・言語・代替記述・表の見出しといった、ソースに書けば直る項目はClaude Codeに任せやすい領域です。pdf.artifact で違反を隠さない、PDFを直接編集しない、の2点を制約に書いておけば、ループは安全に回ります。
残るのは、代替記述の質、読み順、色の使い方といった人の判断です。veraPDFが0件を返した時点を「検査を通った」と読み、「アクセシブルになった」とは読まないことが、この手順の前提になります。
参照した一次ソース
この記事の記述は、次の一次ソースと照合しています。更新時に参照先が変わった場合は一覧も更新します。
- docs.verapdf.org/cli/validation
- github.com/veraPDF/veraPDF-validation-profiles/wiki/PDFUA-Part-1-rules
- typst.app/docs/reference/pdf
- typst.app/docs/guides/accessibility
- doc.courtbouillon.org/weasyprint/stable/common_use_cases.html
- latex3.github.io/tagging-project/documentation
- code.claude.com/docs/en/headless
- code.claude.com/docs/en/permissions