Skip to content

Commit b49bc6d

Browse files
committed
Tidy up pdf reader and render tab in paperworks
1 parent 16d7728 commit b49bc6d

3 files changed

Lines changed: 49 additions & 8 deletions

File tree

paperworks/lib/pdf_reader.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,16 @@
3535

3636

3737
def _extract_doc_number(text):
38-
"""Find the document number, preferring the 'Document Number:' field."""
38+
"""Find the document number from the 'Document Number:' structured field.
39+
40+
Only the structured header is trusted. Free-text scanning is intentionally
41+
absent: paper titles that mention other paper numbers (e.g. "Coroutine
42+
Executors and P2464R0") would otherwise be misidentified.
43+
"""
3944
m = _DOC_FIELD_RE.search(text)
4045
if m:
4146
return m.group(1).upper()
42-
m = _DOC_NUM_RE.search(text)
43-
if not m:
44-
return None
45-
return (m.group(1) or m.group(2) or m.group(3)).upper()
47+
return None
4648

4749

4850
def _doc_number_from_filename(path):

paperworks/lib/templates/index.html

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,8 @@
131131
.render-card.empty { cursor: pointer; color: var(--text-muted); font-size: 12px; }
132132
.render-card.empty:hover { border-color: var(--blue); background: rgba(88,166,255,0.05); }
133133
.render-card.drop-over { border-color: var(--blue); background: rgba(88,166,255,0.12); }
134-
.render-card.filled { border-style: solid; border-color: var(--border); }
134+
.render-card.filled { border-style: solid; border-color: var(--border); cursor: pointer; }
135+
.render-card.filled:hover { border-color: rgba(88,166,255,0.4); background: rgba(88,166,255,0.04); }
135136
.render-card.filled.rendering { border-color: rgba(88,166,255,0.4); animation: bpulse 1.2s ease-in-out infinite; }
136137
.render-card .card-name { font-family: var(--mono); font-size: 11px; color: var(--text); padding: 0 12px; width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; direction: rtl; text-align: center; }
137138
.render-card .card-x { position: absolute; top: 4px; right: 8px; background: none; border: none; color: var(--text-muted); cursor: pointer; font-size: 14px; padding: 0 3px; line-height: 1; }
@@ -689,11 +690,13 @@ <h2>Activity Log</h2>
689690
card.addEventListener('dragover',e=>{e.preventDefault();card.classList.add('drop-over');});
690691
card.addEventListener('dragleave',()=>card.classList.remove('drop-over'));
691692
card.addEventListener('drop',e=>{e.preventDefault();card.classList.remove('drop-over');handleCardDrop(card,e.dataTransfer.files);});
692-
card.addEventListener('click',()=>{
693+
const emptyClick=()=>{
693694
const inp=document.createElement('input');inp.type='file';inp.multiple=true;inp.accept='.md';
694695
inp.addEventListener('change',()=>{if(inp.files.length)handleCardDrop(card,inp.files);});
695696
inp.click();
696-
});
697+
};
698+
card._emptyClick=emptyClick;
699+
card.addEventListener('click',emptyClick);
697700
grid.appendChild(card);
698701
}
699702
function handleCardDrop(card,fileList){
@@ -712,6 +715,7 @@ <h2>Activity Log</h2>
712715
ensureEmptyCard();
713716
}
714717
function fillCard(card,file,previewTab){
718+
if(card._emptyClick){card.removeEventListener('click',card._emptyClick);card._emptyClick=null;}
715719
card.className='render-card filled';
716720
card.textContent='';
717721
card._file=file;
@@ -734,6 +738,14 @@ <h2>Activity Log</h2>
734738
};
735739
card.appendChild(btn);
736740
card._actionBtn=btn;
741+
card.addEventListener('click',e=>{
742+
if(e.target===x||x.contains(e.target)) return;
743+
if(e.target===btn||btn.contains(e.target)) return;
744+
card._pdfPath=null;
745+
if(btn){btn.textContent='RENDER';btn.className='btn btn-blue';btn.style.cssText='font-size:10px;padding:2px 8px;margin-top:6px';}
746+
if(_previewOn) card._previewTab=window.open('about:blank','_blank');
747+
renderCard(card);
748+
});
737749
renderCard(card);
738750
}
739751
async function renderCard(card){
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
"""Tests for pdf_reader._extract_doc_number."""
2+
import unittest
3+
4+
from lib.pdf_reader import _extract_doc_number
5+
6+
7+
class TestExtractDocNumber(unittest.TestCase):
8+
def test_structured_field_wins(self):
9+
text = "Document Number: P4096R0\nCoroutine Executors and P2464R0"
10+
assert _extract_doc_number(text) == "P4096R0"
11+
12+
def test_title_paper_number_ignored(self):
13+
"""A paper number in the title must not be returned."""
14+
text = "Coroutine Executors and P2464R0\nSome other content"
15+
assert _extract_doc_number(text) is None
16+
17+
def test_no_field_returns_none(self):
18+
text = "Just some text with no document number field."
19+
assert _extract_doc_number(text) is None
20+
21+
def test_case_insensitive_field(self):
22+
text = "document number: d4007r0\nSome title"
23+
assert _extract_doc_number(text) == "D4007R0"
24+
25+
def test_n_paper_structured(self):
26+
text = "Document Number: N4950\nWorking Draft"
27+
assert _extract_doc_number(text) == "N4950"

0 commit comments

Comments
 (0)