Skip to content

Commit 66b3588

Browse files
authored
Enhance OCR training documentation with interactive explainer (#107)
* docs: add interactive OCR training pipeline explainer (closes #105) Add an animated HTML page explaining how OCR annotations are incorporated into training via multi-label Partial FC: - PaddleOCR preprocessing → 100 tags per image (over/downsampling) - 8-label random sampling per iteration - 8 independent ArcFace softmax classifiers in parallel - Interactive unit-circle ArcFace visualization with auto-cycling - KaTeX-rendered formulas - Full CN/EN bilingual toggle - docs/index.html redirects for GitHub Pages deployment * docs: refactor into issue-based hub + add opencode skill - Rename ocr_training_pipeline.html → issue-105.html for consistent naming - Rebuild index.html as a hub/directory page listing issue explainers - Add mobile responsiveness fixes (table overflow, flex stacking, touch targets) - Add .opencode/skills/issue-explainer.md for future issue→page workflow - Both pages support CN/EN toggle with centered gradient pill UI
1 parent d4f3c80 commit 66b3588

3 files changed

Lines changed: 1247 additions & 4 deletions

File tree

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
---
2+
name: issue-explainer
3+
description: >
4+
Create an interactive, mobile-friendly HTML explainer page for a GitHub issue.
5+
Covers the full workflow: read the issue, research the codebase, build an animated
6+
single-file HTML page with CN/EN toggle, KaTeX formulas, and deploy via GitHub Pages.
7+
Trigger: "create explainer for issue #N", "answer issue #N with a page".
8+
---
9+
10+
# Issue Explainer Page — Skill
11+
12+
You are building an interactive HTML explainer page that answers a GitHub issue
13+
for the OneVision-Encoder project. The page will be deployed via GitHub Pages
14+
from the `docs/` directory.
15+
16+
## Workflow
17+
18+
### Phase 1: Understand the Issue
19+
20+
1. Fetch the issue content: `gh issue view <N> --repo EvolvingLMMs-Lab/OneVision-Encoder`
21+
(or webfetch the GitHub URL if no GH_TOKEN).
22+
2. Identify the core question(s) the issue asks.
23+
3. Fire parallel explore agents to find relevant code:
24+
- Training pipeline code (loss functions, data flow)
25+
- Dataset/config code (how data is prepared)
26+
- Shell scripts (hyperparameters, flags)
27+
28+
### Phase 2: Build the Page
29+
30+
Create `docs/issue-<N>.html` as a **single self-contained HTML file** (no build tools).
31+
32+
#### Required Structure
33+
34+
```
35+
docs/
36+
index.html ← Hub page listing all issues (auto-directory)
37+
issue-105.html ← Individual explainer page
38+
issue-<N>.html ← New page you create
39+
```
40+
41+
#### Design System (MUST follow)
42+
43+
- **White background** (`#ffffff`), clean typography
44+
- CSS variables: `--accent-blue: #2563eb`, `--accent-pink: #e11d48`, `--accent-emerald: #059669`, `--accent-indigo: #4f46e5`
45+
- Font stack: `-apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif`
46+
- Mono font: `"SF Mono", "Fira Code", Consolas, monospace`
47+
- Card style: white bg, `1px solid #e2e8f0` border, `border-radius: 10px`, subtle shadow
48+
- Code blocks: dark bg (`#1e293b`), syntax-highlighted with span classes: `.kw` `.cm` `.str` `.num` `.fn`
49+
50+
#### CN/EN Bilingual Toggle (MANDATORY)
51+
52+
- Fixed at **top center** of page, pill-shaped, blue-purple gradient background
53+
- Two buttons: "EN" and "中文", active state = white bg + blue text
54+
- Implementation: wrap translatable text in `<span class="lang-span" data-en="..." data-zh="...">`
55+
- JS function `toggleLanguage()` swaps all `.lang-span` innerHTML based on active lang
56+
- Do NOT translate: code blocks, variable names, technical terms (Partial FC, ArcFace, ViT, etc.)
57+
58+
#### Formulas (use KaTeX)
59+
60+
```html
61+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.11/dist/katex.min.css">
62+
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.11/dist/katex.min.js"></script>
63+
```
64+
- Display formulas: `<div class="katex-formula" id="formula-xxx"></div>` + `katex.render(tex, el, {displayMode: true})`
65+
- Inline formulas: `<span class="katex-inline" data-formula="..."></span>` + loop render
66+
67+
#### Animations & Interactivity
68+
69+
- Use **pure Canvas 2D API** or CSS animations — no external libraries
70+
- Scroll-reveal: `IntersectionObserver` with `.reveal` class
71+
- Support `devicePixelRatio` for retina displays on canvas elements
72+
- Auto-cycling animations with `setInterval`, clickable to pause/select
73+
74+
#### Mobile-First (CRITICAL)
75+
76+
- `<meta name="viewport" content="width=device-width, initial-scale=1.0">`
77+
- All flex layouts: `flex-wrap: wrap`
78+
- Flow diagrams: horizontal on desktop, vertical on mobile (`@media max-width: 640px`)
79+
- Touch-friendly: buttons minimum 44px tap target
80+
- Canvas: `style="max-width: 100%; height: auto;"`
81+
- Font sizes: minimum 14px body text on mobile
82+
- No horizontal scroll — test all elements fit in 375px width
83+
84+
### Phase 3: Update the Hub Page
85+
86+
After creating the explainer page, update `docs/index.html`:
87+
88+
- `index.html` is a directory/hub listing all issue explainer pages
89+
- Each entry shows: issue number, title (question), link to the explainer page
90+
- Mobile-friendly card layout
91+
- Same CN/EN toggle as individual pages
92+
- Same design system (white bg, accent colors)
93+
94+
### Phase 4: Commit
95+
96+
- `git add docs/issue-<N>.html docs/index.html`
97+
- Commit message format: `docs: add interactive explainer for issue #<N>`
98+
- Include `closes #<N>` in the commit body if appropriate
99+
100+
### Phase 5: Provide Issue Reply
101+
102+
Draft a concise reply for the GitHub issue:
103+
- Link to the deployed page
104+
- 3-4 sentence summary of the answer
105+
- Mention the interactive visualizations and CN/EN support
106+
107+
## Hard Rules
108+
109+
- Single self-contained HTML file per issue — NO build tools, NO frameworks
110+
- ALL text must have CN/EN translations via `data-en`/`data-zh`
111+
- NO external JS libraries except KaTeX CDN
112+
- NO `as any`, `@ts-ignore` or type suppressions
113+
- Code references must include actual file paths and line numbers from the codebase
114+
- Every formula must be KaTeX-rendered, not plain HTML entities
115+
- Mobile responsive — test mentally at 375px, 768px, 1024px breakpoints
116+
- File naming: `issue-<N>.html` where N is the GitHub issue number

docs/index.html

Lines changed: 179 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,186 @@
11
<!DOCTYPE html>
2-
<html lang="en">
2+
<html lang="en" data-lang="en">
33
<head>
44
<meta charset="UTF-8">
5-
<meta http-equiv="refresh" content="0; url=ocr_training_pipeline.html">
6-
<title>OneVision-Encoder Docs</title>
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<title>OneVision-Encoder — Issue Explainers</title>
7+
<style>
8+
:root {
9+
--bg: #ffffff;
10+
--bg-alt: #f8fafc;
11+
--text: #1e293b;
12+
--text-muted: #64748b;
13+
--accent-blue: #2563eb;
14+
--accent-indigo: #4f46e5;
15+
--accent-pink: #e11d48;
16+
--border: #e2e8f0;
17+
--font-sans: -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
18+
--font-mono: "SF Mono", "Fira Code", Consolas, monospace;
19+
}
20+
* { box-sizing: border-box; margin: 0; padding: 0; }
21+
body {
22+
background: var(--bg); color: var(--text);
23+
font-family: var(--font-sans); line-height: 1.75; font-size: 16px;
24+
}
25+
.container { max-width: 720px; margin: 0 auto; padding: 3.5rem 1.25rem 4rem; }
26+
27+
/* Language Toggle */
28+
.lang-toggle {
29+
position: fixed; top: 0; left: 50%; transform: translateX(-50%);
30+
z-index: 9999; display: flex;
31+
background: linear-gradient(135deg, #2563eb, #7c3aed);
32+
border-radius: 0 0 16px 16px; padding: 8px 6px;
33+
box-shadow: 0 4px 20px rgba(37, 99, 235, 0.35);
34+
cursor: pointer; gap: 4px;
35+
}
36+
.lang-toggle-btn {
37+
padding: 8px 22px; border-radius: 12px; font-size: 0.95rem;
38+
font-weight: 700; color: rgba(255,255,255,0.6);
39+
transition: all 0.3s ease; user-select: none; letter-spacing: 0.03em;
40+
}
41+
.lang-toggle-btn:hover { color: rgba(255,255,255,0.85); }
42+
.lang-toggle-btn.active {
43+
background: #ffffff; color: #2563eb;
44+
box-shadow: 0 2px 8px rgba(0,0,0,0.15);
45+
}
46+
47+
/* Header */
48+
header { text-align: center; margin-bottom: 2.5rem; }
49+
.logo { font-size: 1.1rem; font-weight: 700; color: var(--accent-indigo); letter-spacing: -0.02em; margin-bottom: 0.5rem; }
50+
h1 { font-size: 2rem; font-weight: 800; color: var(--text); line-height: 1.3; margin-bottom: 0.5rem; }
51+
.subtitle { color: var(--text-muted); font-size: 1rem; }
52+
53+
/* Issue Cards */
54+
.issue-list { display: flex; flex-direction: column; gap: 1rem; }
55+
.issue-card {
56+
display: block; text-decoration: none; color: inherit;
57+
background: var(--bg); border: 1px solid var(--border);
58+
border-radius: 12px; padding: 1.25rem 1.5rem;
59+
transition: all 0.2s ease; position: relative;
60+
}
61+
.issue-card:hover {
62+
border-color: var(--accent-blue);
63+
box-shadow: 0 4px 16px rgba(37, 99, 235, 0.1);
64+
transform: translateY(-2px);
65+
}
66+
.issue-card:active { transform: translateY(0); }
67+
.issue-tag {
68+
display: inline-block; font-size: 0.75rem; font-weight: 700;
69+
font-family: var(--font-mono); padding: 3px 10px;
70+
border-radius: 999px; margin-bottom: 0.5rem;
71+
}
72+
.issue-tag.open { background: #dcfce7; color: #16a34a; }
73+
.issue-tag.closed { background: #f3e8ff; color: #7c3aed; }
74+
.issue-title { font-size: 1.1rem; font-weight: 700; color: var(--text); margin-bottom: 0.35rem; line-height: 1.4; }
75+
.issue-desc { font-size: 0.9rem; color: var(--text-muted); line-height: 1.6; }
76+
.issue-meta {
77+
display: flex; gap: 1rem; flex-wrap: wrap; margin-top: 0.75rem;
78+
font-size: 0.8rem; color: var(--text-muted);
79+
}
80+
.issue-meta span { display: flex; align-items: center; gap: 4px; }
81+
.arrow-icon {
82+
position: absolute; right: 1.25rem; top: 50%; transform: translateY(-50%);
83+
color: var(--border); font-size: 1.2rem; transition: color 0.2s ease;
84+
}
85+
.issue-card:hover .arrow-icon { color: var(--accent-blue); }
86+
87+
/* Footer */
88+
footer {
89+
margin-top: 3rem; padding-top: 1.5rem;
90+
border-top: 1px solid var(--border); text-align: center;
91+
font-size: 0.85rem; color: var(--text-muted);
92+
}
93+
footer a { color: var(--accent-blue); text-decoration: none; }
94+
footer a:hover { text-decoration: underline; }
95+
96+
/* Responsive */
97+
@media (max-width: 640px) {
98+
.container { padding: 3rem 1rem 3rem; }
99+
h1 { font-size: 1.5rem; }
100+
.issue-card { padding: 1rem 1.25rem; }
101+
.issue-title { font-size: 1rem; }
102+
.arrow-icon { display: none; }
103+
.lang-toggle { padding: 6px 4px; }
104+
.lang-toggle-btn { padding: 6px 16px; font-size: 0.85rem; }
105+
}
106+
</style>
7107
</head>
8108
<body>
9-
<p>Redirecting to <a href="ocr_training_pipeline.html">OCR Training Pipeline</a>...</p>
109+
110+
<div class="lang-toggle">
111+
<div class="lang-toggle-btn active" id="btn-en" onclick="setLang('en')">EN</div>
112+
<div class="lang-toggle-btn" id="btn-zh" onclick="setLang('zh')">中文</div>
113+
</div>
114+
115+
<div class="container">
116+
<header>
117+
<div class="logo">OneVision-Encoder</div>
118+
<h1><span class="lang-span" data-en="Issue Explainers" data-zh="Issue 详解">Issue Explainers</span></h1>
119+
<p class="subtitle"><span class="lang-span" data-en="Interactive visual explanations for community questions" data-zh="社区问题的交互式可视化解答">Interactive visual explanations for community questions</span></p>
120+
</header>
121+
122+
<div class="issue-list">
123+
124+
<a class="issue-card" href="issue-105.html">
125+
<div class="issue-tag open">#105</div>
126+
<div class="issue-title">
127+
<span class="lang-span"
128+
data-en="Clarification on how OCR annotations are used during training"
129+
data-zh="OCR 标注在训练中如何使用的说明">Clarification on how OCR annotations are used during training</span>
130+
</div>
131+
<div class="issue-desc">
132+
<span class="lang-span"
133+
data-en="How PaddleOCR tags become multi-label Partial FC training signals — with animated ArcFace visualization, KaTeX formulas, and full pipeline walkthrough."
134+
data-zh="PaddleOCR 标签如何成为多标签 Partial FC 训练信号——包含 ArcFace 动画可视化、KaTeX 公式和完整流程解析。">How PaddleOCR tags become multi-label Partial FC training signals — with animated ArcFace visualization, KaTeX formulas, and full pipeline walkthrough.</span>
135+
</div>
136+
<div class="issue-meta">
137+
<span>👤 JerryPW</span>
138+
<span>📅 2026-04-08</span>
139+
<span><span class="lang-span" data-en="6 sections" data-zh="6 个章节">6 sections</span></span>
140+
<span><span class="lang-span" data-en="Interactive animations" data-zh="交互动画">Interactive animations</span></span>
141+
</div>
142+
<div class="arrow-icon"></div>
143+
</a>
144+
145+
<!-- Add more issue cards here following the same pattern:
146+
<a class="issue-card" href="issue-XXX.html">
147+
<div class="issue-tag open">#XXX</div>
148+
<div class="issue-title">
149+
<span class="lang-span" data-en="..." data-zh="...">...</span>
150+
</div>
151+
<div class="issue-desc">
152+
<span class="lang-span" data-en="..." data-zh="...">...</span>
153+
</div>
154+
<div class="issue-meta">...</div>
155+
<div class="arrow-icon">→</div>
156+
</a>
157+
-->
158+
159+
</div>
160+
161+
<footer>
162+
<span class="lang-span"
163+
data-en="Part of the &lt;a href='https://github.com/EvolvingLMMs-Lab/OneVision-Encoder'&gt;OneVision-Encoder&lt;/a&gt; project. Deployed via GitHub Pages."
164+
data-zh="&lt;a href='https://github.com/EvolvingLMMs-Lab/OneVision-Encoder'&gt;OneVision-Encoder&lt;/a&gt; 项目的一部分。通过 GitHub Pages 部署。">Part of the <a href="https://github.com/EvolvingLMMs-Lab/OneVision-Encoder">OneVision-Encoder</a> project. Deployed via GitHub Pages.</span>
165+
</footer>
166+
</div>
167+
168+
<script>
169+
let currentLang = 'en';
170+
function setLang(lang) {
171+
currentLang = lang;
172+
document.documentElement.setAttribute('data-lang', lang);
173+
document.getElementById('btn-en').classList.toggle('active', lang === 'en');
174+
document.getElementById('btn-zh').classList.toggle('active', lang === 'zh');
175+
document.querySelectorAll('.lang-span').forEach(el => {
176+
const val = el.getAttribute('data-' + lang);
177+
if (val) el.innerHTML = val;
178+
});
179+
document.title = lang === 'en'
180+
? 'OneVision-Encoder — Issue Explainers'
181+
: 'OneVision-Encoder — Issue 详解';
182+
}
183+
</script>
184+
10185
</body>
11186
</html>

0 commit comments

Comments
 (0)