Skip to content

Commit 1eca5d2

Browse files
Copilotreycn
andauthored
Apply remaining changes
Co-authored-by: reycn <11225092+reycn@users.noreply.github.com>
1 parent 70b3be1 commit 1eca5d2

11 files changed

Lines changed: 229 additions & 0 deletions

File tree

‎.github/workflows/pages.yml‎

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
name: Deploy GitHub Pages
2+
on:
3+
push:
4+
branches: [main]
5+
paths: ['pages/**', '.github/workflows/pages.yml']
6+
workflow_dispatch:
7+
permissions:
8+
contents: read
9+
pages: write
10+
id-token: write
11+
concurrency:
12+
group: pages
13+
cancel-in-progress: true
14+
jobs:
15+
deploy:
16+
runs-on: ubuntu-latest
17+
environment:
18+
name: github-pages
19+
url: ${{ steps.deployment.outputs.page_url }}
20+
steps:
21+
- uses: actions/checkout@v4
22+
- uses: actions/configure-pages@v5
23+
- uses: actions/upload-pages-artifact@v3
24+
with:
25+
path: pages
26+
- id: deployment
27+
uses: actions/deploy-pages@v4

‎.prettierignore‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,4 @@ doc/**/*-baseline.json
1111
doc/**/*-optimized.json
1212
doc/**/*-result.json
1313
doc/**/*-results.json
14+
pages/

‎pages/.nojekyll‎

Whitespace-only changes.

‎pages/assets/demo.gif‎

8.61 MB
Loading

‎pages/assets/icon.png‎

6.83 MB
Loading

‎pages/assets/preview-linux.png‎

166 KB
Loading

‎pages/assets/preview-windows.png‎

1.49 MB
Loading

‎pages/assets/preview.png‎

638 KB
Loading

‎pages/index.html‎

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
5+
<title>PDFMathReader — Read papers in any language</title>
6+
<meta name="description" content="A fluid PDF reader with realtime translation that preserves formulas and layout.">
7+
<link rel="icon" href="assets/icon.png"><link rel="stylesheet" href="style.css">
8+
</head>
9+
<body>
10+
<header><img src="assets/icon.png" alt=""><b>PDFMathReader</b>
11+
<a href="#reader">Reader</a><a href="#translate">Translation</a><a href="#controls">Controls</a><a href="#how">How it works</a><a href="#settings">Settings</a>
12+
<a href="https://github.com/PDFMathTranslate/PDFMathReader">GitHub</a></header>
13+
14+
<section class="hero">
15+
<h1>Read science in any language.<br>Translated as you scroll.</h1>
16+
<p class="sub">A smooth PDF reader with realtime translation that keeps formulas, tables and layout intact. Powered by PDFMathTranslate.</p>
17+
<a class="btn" href="https://github.com/PDFMathTranslate/PDFMathReader/actions/workflows/electron-build.yml">Download</a>
18+
<a class="btn alt" href="https://github.com/PDFMathTranslate/PDFMathReader">View on GitHub</a>
19+
<img class="shot" src="assets/demo.gif" alt="PDFMathReader demo">
20+
</section>
21+
22+
<section id="reader">
23+
<h2>A reader that stays out of your way</h2>
24+
<p class="sub">Try it: switch layouts, zoom and scroll direction. Pages and thumbnails are virtualized, so large documents stay fast.</p>
25+
<div class="reader">
26+
<div class="bar">
27+
<button data-layout="v" class="on">Vertical</button><button data-layout="h">Horizontal</button>
28+
<button id="zo">−</button><span id="zv">100%</span><button id="zi">+</button>
29+
<span class="sp"></span><button id="tr" class="on">Translate</button>
30+
</div>
31+
<div class="pages" id="pages">
32+
<div class="page"><h4>On the Convergence of Stochastic Gradient Descent</h4>
33+
<div class="para" data-t="我们研究了在非凸目标下随机梯度下降的收敛性,并给出了新的收敛率上界。">We study the convergence of stochastic gradient descent under nonconvex objectives and derive a new upper bound on the rate.</div>
34+
<div class="eq">E‖∇f(x<sub>t</sub>)‖² ≤ O(1/√T)</div>
35+
<div class="para" data-t="其中 T 表示迭代次数。公式、符号与排版在翻译后保持不变。">Here T denotes the number of iterations. Formulas, symbols and layout are preserved after translation.</div></div>
36+
<div class="page"><h4>2. Preliminaries</h4>
37+
<div class="para" data-t="设 f 为 L-光滑函数。则对任意 x、y,梯度满足 Lipschitz 条件。">Let f be an L-smooth function. Then for all x, y the gradient satisfies the Lipschitz condition.</div>
38+
<div class="eq">‖∇f(x) − ∇f(y)‖ ≤ L‖x − y‖</div>
39+
<div class="para" data-t="我们假设随机梯度的方差有界。">We assume that the variance of the stochastic gradient is bounded.</div></div>
40+
<div class="page"><h4>3. Main Result</h4>
41+
<div class="para" data-t="定理 1:在上述假设下,步长取 η = 1/√T 时,算法以所述速率收敛。">Theorem 1: Under the assumptions above, with step size η = 1/√T the algorithm converges at the stated rate.</div></div>
42+
</div>
43+
<div class="hint">Zoom with − / +. Click a paragraph to toggle original ↔ translation.</div>
44+
</div>
45+
</section>
46+
47+
<section id="translate">
48+
<h2>Realtime translation, paragraph by paragraph</h2>
49+
<p class="sub">Translation runs for nearby pages while you read — no waiting for the whole document. Click any detected paragraph to flip between original and translation.</p>
50+
<div class="reader"><div class="bar"><b>Live demo</b><span class="sp"></span><select id="lang"><option value="zh">简体中文</option><option value="ja">日本語</option><option value="fr">Français</option></select><button id="run">▶ Translate again</button></div>
51+
<div class="pages" style="height:auto"><div class="page" style="margin:0 auto">
52+
<div class="para" id="demo" data-src="The gradient descent method converges linearly when the objective is strongly convex.">The gradient descent method converges linearly when the objective is strongly convex.</div>
53+
<div class="eq">f(x<sub>k+1</sub>) − f* ≤ (1 − μ/L)(f(x<sub>k</sub>) − f*)</div></div></div></div>
54+
</section>
55+
56+
<section id="controls">
57+
<h2>Just the right controls</h2>
58+
<div class="grid">
59+
<div class="card"><h3>Layouts</h3><p>One, two or four pages; vertical or horizontal scrolling.</p></div>
60+
<div class="card"><h3>Thumbnails &amp; zoom</h3><p>Jump anywhere instantly and fit pages to your screen.</p></div>
61+
<div class="card"><h3>Bilingual toggle</h3><p>Click paragraphs to compare original and translation.</p></div>
62+
<div class="card"><h3>Highlights &amp; comments</h3><p>Record notes directly on the page.</p></div>
63+
<div class="card"><h3>Reading links</h3><p>Bidirectional links between search results and where you read them.</p></div>
64+
<div class="card"><h3>Multiple windows</h3><p>Independent windows restore position and display settings.</p></div>
65+
</div>
66+
<div class="shots"><img src="assets/preview.png" alt="macOS"><img src="assets/preview-windows.png" alt="Windows"><img src="assets/preview-linux.png" alt="Linux"></div>
67+
</section>
68+
69+
<section id="how">
70+
<h2>How it works</h2>
71+
<p class="sub">Rendering, layout analysis and translation run independently, so reading is never blocked.</p>
72+
<div class="flow">
73+
<div class="card"><h3>1. Open</h3><p>PDF is uploaded once to a local backend and referenced by ID.</p></div><div class="ar">→</div>
74+
<div class="card"><h3>2. Render</h3><p>PDF.js draws visible pages only (virtualized).</p></div><div class="ar">→</div>
75+
<div class="card"><h3>3. Layout</h3><p>Paragraphs, formulas and tables are detected on demand.</p></div><div class="ar">→</div>
76+
<div class="card"><h3>4. Translate</h3><p>Nearby pages are translated and cached; stale work is cancelled.</p></div><div class="ar">→</div>
77+
<div class="card"><h3>5. Overlay</h3><p>Translated text is placed back in the original layout.</p></div>
78+
</div>
79+
<div class="grid"><div class="card"><h3>Ultra fast</h3><p>Geometric paragraph grouping with text overlays.</p></div>
80+
<div class="card"><h3>Fast &amp; Precise</h3><p>Math translation kernels installed through <code>uv</code>.</p></div>
81+
<div class="card"><h3>Cached</h3><p>Identical requests reuse saved results across documents and restarts.</p></div></div>
82+
</section>
83+
84+
<section id="settings">
85+
<h2>Settings, simplified</h2>
86+
<p class="sub">Explore a preview of the settings window.</p>
87+
<div class="settings">
88+
<nav><button class="on" data-p="a">Translation</button><button data-p="b">Reading</button><button data-p="c">About</button></nav>
89+
<div>
90+
<div class="pane on" id="a"><div class="row"><div>Kernel<br><span>Ultra fast, Fast or Precise</span></div><select><option>Ultra fast</option><option>Fast</option><option>Precise</option></select></div>
91+
<div class="row"><div>Target language<br><span>Custom language codes supported</span></div><select><option>简体中文</option><option>English</option><option>日本語</option></select></div>
92+
<div class="row"><div>Service<br><span>OpenAI-compatible API</span></div><input type="text" placeholder="API key" disabled></div>
93+
<div class="row"><div>Scope<br><span>Full document or nearby pages</span></div><select><option>Nearby pages</option><option>Full document</option></select></div></div>
94+
<div class="pane" id="b"><div class="row"><div>Default mode<br><span>Open documents in reading mode</span></div><select><option>Reading</option><option>Original</option></select></div>
95+
<div class="row"><div>Page layout<br><span>1, 2 or 4 pages</span></div><select><option>1</option><option>2</option><option>4</option></select></div>
96+
<div class="row"><div>Scroll direction</div><select><option>Vertical</option><option>Horizontal</option></select></div></div>
97+
<div class="pane" id="c"><div class="row"><div>Application<br><span>Version, installed kernels and UV</span></div><span>PDFMathReader</span></div>
98+
<div class="row"><div>Updates<br><span>Latest feature commits</span></div><a href="https://github.com/PDFMathTranslate/PDFMathReader/commits">View</a></div></div>
99+
</div></div>
100+
</section>
101+
102+
<footer>PDFMathReader · <a href="https://github.com/PDFMathTranslate/PDFMathReader/blob/main/LICENSE">License</a> · <a href="https://github.com/PDFMathTranslate/PDFMathTranslate">PDFMathTranslate</a></footer>
103+
<script src="main.js"></script>
104+
</body></html>

‎pages/main.js‎

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
(function () {
2+
var $ = function (s, r) { return (r || document).querySelector(s); };
3+
var all = function (s, r) { return Array.prototype.slice.call((r || document).querySelectorAll(s)); };
4+
var pages = $('#pages');
5+
var zoom = 100;
6+
var translate = true;
7+
8+
all('.para', pages).forEach(function (p) { p.dataset.o = p.textContent; });
9+
function show(p, t) { p.textContent = t ? p.dataset.t : p.dataset.o; p.classList.toggle('t', t); }
10+
function sweep() {
11+
all('.para', pages).forEach(function (p, i) {
12+
if (!translate) return show(p, false);
13+
p.classList.add('loading');
14+
setTimeout(function () { p.classList.remove('loading'); show(p, true); }, 350 + i * 250);
15+
});
16+
}
17+
all('.para', pages).forEach(function (p) {
18+
p.addEventListener('click', function () { show(p, !p.classList.contains('t')); });
19+
});
20+
all('[data-layout]').forEach(function (b) {
21+
b.addEventListener('click', function () {
22+
all('[data-layout]').forEach(function (x) { x.classList.toggle('on', x === b); });
23+
pages.classList.toggle('h', b.dataset.layout === 'h');
24+
});
25+
});
26+
function applyZoom() {
27+
$('#zv').textContent = zoom + '%';
28+
all('.page', pages).forEach(function (p) { p.style.transform = 'scale(' + zoom / 100 + ')'; p.style.marginBottom = (18 + (zoom - 100) * 1.2) + 'px'; });
29+
}
30+
$('#zi').onclick = function () { zoom = Math.min(160, zoom + 10); applyZoom(); };
31+
$('#zo').onclick = function () { zoom = Math.max(60, zoom - 10); applyZoom(); };
32+
$('#tr').onclick = function () { translate = !translate; this.classList.toggle('on', translate); sweep(); };
33+
if ('IntersectionObserver' in window) {
34+
var started = false;
35+
new IntersectionObserver(function (e, o) { if (e[0].isIntersecting && !started) { started = true; sweep(); o.disconnect(); } }, { threshold: 0.3 }).observe(pages);
36+
} else sweep();
37+
38+
var texts = {
39+
zh: '当目标函数强凸时,梯度下降法线性收敛。',
40+
ja: '目的関数が強凸のとき、勾配降下法は線形収束します。',
41+
fr: 'La descente de gradient converge linéairement lorsque l’objectif est fortement convexe.'
42+
};
43+
var demo = $('#demo');
44+
function run() {
45+
demo.classList.remove('t'); demo.textContent = '…'; demo.classList.add('loading');
46+
setTimeout(function () { demo.classList.remove('loading'); demo.textContent = texts[$('#lang').value]; demo.classList.add('t'); }, 700);
47+
}
48+
demo.addEventListener('click', function () {
49+
if (demo.classList.contains('t')) { demo.textContent = demo.dataset.src; demo.classList.remove('t'); } else run();
50+
});
51+
$('#run').onclick = run; $('#lang').onchange = run;
52+
53+
all('.settings nav button').forEach(function (b) {
54+
b.addEventListener('click', function () {
55+
all('.settings nav button').forEach(function (x) { x.classList.toggle('on', x === b); });
56+
all('.pane').forEach(function (p) { p.classList.toggle('on', p.id === b.dataset.p); });
57+
});
58+
});
59+
})();

0 commit comments

Comments
 (0)