glmv-pdf-to-web について
glmv-pdf-to-webは、論文や技術文書のPDFを1ページ構成の学術プロジェクトサイトに変換するスキルです。ページ画像のローカル変換、構成案の作成、図の切り出しを行い、ローカル画像を参照するHTMLを生成します。
主な機能
- 01PDFページを画像に変換
- 02構造化されたサイト構成案の作成
- 03ページ画像から図を切り出し
- 041ページ構成のHTMLサイトを生成
- 05ローカル画像素材の利用
活用シーン
- 01研究論文のプロジェクトページ作成
- 02技術PDFのウェブサイト化
- 03論文の図表や結果のオンライン紹介
- 04ローカルまたはURLのPDFから学術ページを作成
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ zai-org/ glm-skills --skill glmv-pdf-to-webインストール後、Claude Code で/glmv-pdf-to-webを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
.DS_Storescripts/crop.pygenerate_web.pypdf_to_images.py詳細
PDF → 学術プロジェクトウェブサイトのスキル
研究論文または技術文書の PDF を、NeurIPS/CVPR/ICLR の論文公開で使われるような、洗練された 1 ページのプロジェクトウェブサイトに変換します。ページはローカルで DPI 120 にて変換され、構造化された outline.json が保存されます。画像はローカルで切り抜かれ、最終ページは generate_web.py で保存されます。
スクリプトの保存先: {SKILL_DIR}/scripts/
依存関係
Python パッケージ(一度だけインストールします):
pip install pymupdf pillow
システムツール:curl(macOS/Linux にプリインストールされています)。
使用するタイミング
PDF からウェブページやプロジェクトページを作成するようユーザーに依頼された場合に使用します。たとえば、「PDF からプロジェクトページを作って」「論文のウェブサイトを作成して」「この論文の学術ウェブサイトを作って」「论文主页」「做项目主页」「根据pdf做网页」「把论文做成主页」など、中国語または英語で同様の意図を示す依頼が該当します。
出力ディレクトリの規則
すべての出力は {WORKSPACE}/web/<pdf_stem>_<timestamp>/ に保存します。
web/
└── <pdf_stem>_<timestamp>/
├── outline.json ← structured web plan (WebPlan schema)
├── crops/ ← locally-saved cropped images
│ ├── fig_arch_crop.png
│ ├── table_results_crop.png
│ └── ...
└── index.html ← the website
<pdf_stem>= 拡張子を除いた PDF ファイル名<timestamp>=YYYYMMDD_HHMMSS形式- HTML では相対パス
crops/<name>_crop.pngで画像を参照します
入力
$ARGUMENTS は PDF ファイルのパス(ローカル)または HTTP/HTTPS URL です。
- ユーザーが URL を指定した場合:まず curl でダウンロードしてから変換します
- ユーザーが ローカル PDF パス を指定した場合:そのまま変換します
ワークフロー
フェーズ 0 — 出力ディレクトリの作成
import os, datetime
pdf_stem = os.path.splitext(os.path.basename(pdf_path))[0]
timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
out_dir = os.path.join(workspace, "web", f"{pdf_stem}_{timestamp}")
mkdir -p "<out_dir>/crops"
フェーズ 1 — PDF ページを画像に変換(DPI 120)
入力が URL の場合は、最初にダウンロードします。
pdf_stem=$(basename "$ARGUMENTS" .pdf)
curl -L -o "/tmp/${pdf_stem}.pdf" "$ARGUMENTS"
次に変換します(ダウンロードしたパスまたは元のローカルパスのいずれかを渡します)。
python {SKILL_DIR}/scripts/pdf_to_images.py "<pdf_path>" --dpi 120
JSON が標準出力に出力されます。
[{"page": 1, "path": "/abs/path/page_001.png"}, ...]
完全な page → path マップを解析して保存します。
フェーズ 2 — すべてのページを順番に読む
計画を立てる前に、すべてのページ画像を順番に確認します。目的は、文書の内容、図、構成を正確に理解することです。
読みながら、以下を記録します。
- タイトル、著者、所属、掲載先、年
- アブストラクトのテキスト(原文のまま)
- 主な貢献
- 論文/コード/データセットへのリンク(arXiv、GitHub など)
- 図、表、ダイアグラム — 掲載ページとおおよその領域
- ティーザー/ヒーロー画像があれば、その画像
まだセクションを計画しないでください。まず、すべてを読みます。
フェーズ 3 — セクションを計画して outline.json を保存
ウェブサイトのセクションを計画します。学術論文の標準的な構成は以下のとおりです(必要に応じて調整してください)。
section_id | 目的 |
|---|---|
hero | タイトル、著者、掲載先バッジ、リンクボタン |
abstract | アブストラクト全文 |
contributions | 主な貢献を紹介する 3~5 枚のカード |
method | アーキテクチャ図と手法の説明 |
results | 定量的な表と定性的な図 |
conclusion | 簡潔な結論 |
citation | BibTeX ブロック |
画像が必要な各セクションについて、以下を特定します。
- 画像の掲載ページ(フェーズ 1 のローカルページパス)
- ビジュアルに何が示されているか、またそのセクションに適している理由の説明
以下のスキーマを厳密に使用して、<out_dir>/outline.json として保存します。
{
"project_title": "Paper Title",
"lang": "English",
"authors": ["Author One", "Author Two"],
"sections_plan": [
{
"section_index": 1,
"section_id": "hero",
"title": "Hero",
"content": "Title, authors, venue, teaser figure description",
"required_images": [
{
"url": "<local_page_path_from_phase1>",
"visual_description": "Figure 1: teaser showing input-output examples",
"usage_reason": "Hero section visual to immediately show the paper's output"
}
]
}
]
}
フィールドに関する注意:
lang:"Chinese"または"English"— PDF の言語に合わせますrequired_images:セクションに画像が不要な場合は、空の配列[]url:ソースページのローカルファイルパス(フェーズ 1 のpathフィールド)- 切り抜きが必要な画像は、おおよその領域を記録します — 正確な切り抜き範囲はフェーズ 4 で決定します
Write ツールを使って、<out_dir>/outline.json に outline.json を書き込みます。
Phase 4 — 必要な画像の切り抜き(グラウンディング + サブエージェント)
重要:すべての切り抜き処理は、Agent ツールを使って、コンテキストを持たないサブエージェントに必ず委任してください。 このフェーズまでに、コンテキストは非常に長くなっています(ページ画像すべて + 概要)。そのため、視覚的な座標の精度が低下します。対象画像だけを扱う新しいサブエージェントを使うと、座標の精度が大幅に高まります。
重要:すべての画像の切り抜きには、必ず指定の {SKILL_DIR}/scripts/crop.py スクリプトを使用してください。独自の切り抜きコードを書いたり、PIL/Pillow を直接使ったり、ほかの方法を使用したりしないでください。
outline.json を読み込みます。必要な切り抜きをすべて集めてから、元ページごとに 1 つのサブエージェント(ページが異なる場合は切り抜きごとに 1 つ)を起動します。サブエージェントはグラウンディング形式の位置特定を行います。画像を見て対象要素の位置を特定し、0〜999 の正規化座標で正確なバウンディングボックスを出力します。
Agent ツールは次のように使用します。
Agent tool call:
description: "Grounding crop page N"
prompt: |
You are a visual grounding and cropping assistant. Your task is to precisely
locate specified visual elements in a page image and crop them out.
## Grounding method
Use visual grounding to locate each target:
1. Read the source image using the Read tool to view it
2. Identify the target element described below
3. Determine its bounding box as normalized coordinates in the 0–999 range:
- 0 = left/top edge of the image
- 999 = right/bottom edge of the image
- These are thousandths, NOT pixels, NOT percentages (0–100)
- Format: [x1, y1, x2, y2] where (x1,y1) is top-left, (x2,y2) is bottom-right
- Example: [0, 0, 500, 500] = top-left quarter of the image
4. Be precise: tightly bound the target element with a small margin (~10–20 units)
around it. Do NOT crop too wide or too narrow.
## Source image
<page_image_path>
## Crops needed
For each crop below, first do grounding (locate the element), then crop:
1. Name: "<descriptive_name>"
Target: "<visual_description from outline.json>"
Context: "<usage_reason from outline.json>"
## Crop command
After determining the bounding box [X1, Y1, X2, Y2] for each target, run:
```bash
python <SKILL_DIR>/scripts/crop.py \
--path "<page_image_path>" \
--box X1 Y1 X2 Y2 \
--name "<crop_name>" \
--out-dir "<out_dir>/crops"
```
## Verification
After each crop, READ the output image to visually verify the correct region
was captured. If the crop missed the target or is too wide/narrow, adjust the
coordinates and re-run crop.py.
## Output
Report the final results as a list:
- crop_name: <name>, file: <output_filename>, box: [X1, Y1, X2, Y2]
<page_image_path>、<SKILL_DIR>、<out_dir>、切り抜きの詳細を、コンテキスト内の実際の値に置き換えてください。
crop.py スクリプトは JSON を出力します:{"path": "/abs/path/<name>_crop.png"}
すべてのサブエージェントから結果を集め、HTML で参照するためのマッピング section_id → [crop filename, ...] を作成します。
可能であれば、独立したページ用のサブエージェントを並行して起動します。次に進む前に、すべての処理が完了するまで待ちます。
Phase 5 — 切り抜いた画像の寸法を測定する
python3 -c "
from PIL import Image; import os, json
d = '<out_dir>/crops'
sizes = {}
for f in sorted(os.listdir(d)):
if f.endswith('.png'):
w, h = Image.open(os.path.join(d, f)).size
sizes[f] = {'width': w, 'height': h, 'aspect': round(w/h, 2)}
print(json.dumps(sizes, indent=2))
"
| アスペクト比 | レイアウトの推奨 |
|---|---|
| < 0.7(縦長/細長い) | max-width: 400–500px、中央揃え |
| 0.7 – 1.3(ほぼ正方形) | max-width: 600–700px |
| > 1.3(横長) | 全幅、max-width: 100% |
| > 2.0(非常に横長。例:表) | 全幅、横スクロールのフォールバックあり |
Phase 6 — 1 ページの HTML を生成する
ステップ A — HTML を /tmp/website.html に書き込みます
- すべての
<img src="...">で相対パスを使用します:crops/<name>_crop.png - 絶対パスは使用しないでください
ステップ B — 保存します:
python {SKILL_DIR}/scripts/generate_web.py \
--html-file /tmp/website.html \
--title "<paper title>" \
--out-dir "<out_dir>/"
HTML 仕様
単独で完結する 1 つの HTML ファイル(CSS を埋め込み、最小限のバニラ JS のみ)。外部 JS フレームワークは使用しません。Google Fonts CDN は使用できます。
ページレイアウト:
- コンテンツの最大幅:
900px、中央揃え、適度な左右のパディング - セクションへのアンカーリンクとスムーズスクロールを備えた、上部固定ナビゲーション
- 幅 1200px で見栄えよく、幅 768px で読みやすいレイアウト
タイポグラフィ:
- 見出し用と本文用に、Google Fonts を 2 種類使用
- 本文:17〜18px、行の高さ 1.7
- 明確な見出し階層(h1 >> h2 >> h3)
ビジュアルスタイル:
- ユーザーがスタイルを指定している場合は、指定どおりにします
- それ以外の場合は、論文の分野と文調から適切なデザインを推測します(例:CV/ML 論文 → モダンでクリーンな学術風、システム論文 → ダークなテクニカル風、人文学 → 温かみのあるエディトリアルなセリフ体)
- 色とフォントは CSS 変数として定義します。決まった配色やフォントの指定はありません
セクションのガイドライン:
hero:
- 大きなタイトル(2〜3rem)、所属機関の上付き文字を付けた著者一覧、会場バッジのピル
- リンクボタン:
[📄 Paper] [💻 Code] [🗄️ Dataset]— URL がない場合はグレーアウト - 見つかった場合は、その下にティーザー図版
abstract:
- 原文をそのまま掲載し、左側に控えめなアクセントボーダーを付けます
contributions:
- 2〜3 列の CSS グリッドにカードを配置します。各カードに Unicode 記号、見出し、説明を含めます
method:
- 全幅のアーキテクチャ図版(
<figure><img><figcaption>)+ 説明文
results:
- 定量的な表は実際の
<table>として作成し、PDF の実際の数値を使用します。最高値は太字にします - 定性的な図版はグリッドに配置します(画像 2〜4 点、キャプション付き)
conclusion:
- 2〜3 段落
citation:
- PDF のメタデータをもとに再構成した BibTeX を
<pre><code>ブロックで掲載 - バニラ JS の
navigator.clipboardを使った「コピー」ボタン
画像:
- すべての
<img>で相対パスを使用します:crops/<name>_crop.png loading="lazy"と説明的なaltを追加します<figure>で囲み、<figcaption>を付けます
アニメーション(控えめに):
IntersectionObserverと CSS トランジションを使った、スクロール時のフェードイン- ボタン/カードにホバー状態を設定
品質チェックリスト
- 出力ディレクトリ名が
<pdf_stem>_<timestamp>/になっている - 有効な WebPlan スキーマで
outline.jsonが保存されている - すべての切り抜き画像が
crops/に保存されている(ローカルのみ) - すべてのメタデータ(タイトル、著者、掲載先、年)が PDF の内容に基づいている
- 要旨が原文どおりである
- 定量データの表に論文中の実際の数値が記載されている
- すべての切り抜き画像が
crops/<name>_crop.pngで参照されている - BibTeX ブロックが正確で、コピーできる
- ナビゲーションのアンカーから正しいセクションに移動できる
-
generate_web.pyが呼び出され、成功が確認されている
言語
PDF の言語に合わせてください。英語の論文なら英語のウェブサイト、中国語の論文なら中国語にしてください。混在させないでください。