Pdf extract
npx -y skills add jmech-pepa/pepa-claude-toolkit --skill pdf-extractAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Extrakce ručních poznámek, zvýraznění, podtržení a označených obrázků z PDF knih. Detekuje barevné anotace (zelené, žluté, červené, modré, černé) a vytvoří strukturovaný .md soubor s přepisem.
SKILL.md
26.1 KB, as published. Nobody here has run it
PDF Extract – extrakce poznámek z knih v4.1
Kdy použít
- Uživatel chce vytáhnout své ruční poznámky a zvýraznění z PDF knihy
- Trigger fráze: "extrahuj poznámky", "poznámky z PDF", "/pdf-extract", "vytáhni z knihy"
Vstup
- Cesta k PDF souboru (povinné)
- Volitelně: výstupní cesta, konkrétní rozsah stran
Kontext uživatele
- Uživatel anotuje digitálním perem na tabletu
- Typické anotace: čárky u textu, ohraničení pasáží, podtržení, sem tam ruční poznámka
- Tahy jsou vždy nepravidelné (nikdy dokonale rovné) – to je klíčový rozlišovací znak od tištěného obsahu
- Schémata a diagramy v knize mají být zachovány jako obrázky, NE převáděny na text
Dávkový režim (výchozí chování)
KRITICKÉ – MUSÍŠ DODRŽET:
- Výchozí: zpracuj prvních 50 stran, vytvoř výstupní
.mdsoubor a ZASTAV SE - STOP po prvních 50 stranách – vypiš uživateli výsledky a ČEKEJ na jeho odpověď
- Uživatel si výstup zkontroluje a řekne, jestli pokračovat s dalšími stranami
- NEPOKRAČUJ automaticky na strany 51+ bez explicitního pokynu uživatele
- Pokud uživatel explicitně řekne "zpracuj celou knihu" / "všechny strany" / "pokračuj", teprve pak pokračuj s dalšími stranami
- Při pokračování přidávej do existujícího
.mdsouboru, nemazej předchozí výsledky
Architektura – šetření kontextu
KRITICKÉ: Tento skill zpracovává desítky až stovky stran s obrázky. Aby nedocházelo k vyčerpání kontextového okna:
- Fáze 1 (detekce) běží v hlavním kontextu – je levná, výstupem je jen seznam čísel stran
- Fáze 2 (vizuální analýza + extrakce) se deleguje na Agent subagenty s model: "opus" (1M kontext)
- Subagenty zpracovávají dávky stran a vrací pouze strukturovaný markdown text, ne obrázky
- Hlavní kontext pak jen skládá výsledky z subagentů do výstupního souboru
Kategorie stran podle náročnosti zpracování:
- Jednoduché (PDF annotations: highlight, underline, strikeout) → extrahuj přímo z PDF dat, BEZ vizuální kontroly
- Marginální (vektorové kresby POUZE na okrajích stránky, tj. x < 60 nebo x > page_width - 60) → programatická extrakce spárováním souřadnic kreseb s textovými bloky (krok 4A-2), BEZ vizuální kontroly – toto je spolehlivější než vizuální analýza, protože fill-only paths se v PNG renderují jako extrémně tenké/neviditelné čáry
- Složité (vektorové kresby v těle stránky, ink anotace, barevné pixely, ruční text) → vyžadují vizuální kontrolu přes PNG → deleguj na subagenty
Workflow
1. Instalace závislostí (pokud chybí)
Ověř dostupnost a nainstaluj pokud chybí:
pip3 install PyMuPDF Pillow numpy
2. Zjisti metadata knihy
import fitz # PyMuPDF
doc = fitz.open("<cesta_k_pdf>")
title = doc.metadata.get("title", "")
author = doc.metadata.get("author", "")
page_count = len(doc)
- Pokud metadata chybí, odvoď název z názvu souboru
- Informuj uživatele: název, autor, počet stran
3. Detekce anotovaných stran (Fáze 1 – hlavní kontext)
Zpracovávej po dávkách (50–100 stran), aby se šetřila paměť.
3a. Detekce barevných pixelových anotací
Renderuj stránky přes PyMuPDF a hledej barevné pixely:
import numpy as np
from PIL import Image
pix = page.get_pixmap(dpi=100)
img = np.frombuffer(pix.samples, dtype=np.uint8).reshape(pix.h, pix.w, pix.n)
r, g, b = img[:,:,0], img[:,:,1], img[:,:,2]
Detekční pravidla pro jednotlivé barvy:
| Barva | Podmínka | Význam |
|---|---|---|
| Černá | viz krok 3b (vektorová detekce) | Hlavní barva – poznámky, podtržení, zatržení |
| Zelená | (g > 100) & (g > r*1.2) & (g > b*1.2) & ((g-r) > 30) | Zvýraznění, zatržení |
| Žlutá | (r > 150) & (g > 150) & (b < 100) & (r+g > 350) | Highlighter |
| Červená | (r > 150) & (r > g*1.5) & (r > b*1.5) | Důležité, opravy |
| Modrá | (b > 100) & (b > r*1.2) & (b > g*1.2) & ((b-r) > 30) | Poznámky, otázky |
| Oranžová | (r > 180) & (g > 80) & (g < 160) & (b < 80) | Doplňkové zvýraznění |
Práh: > 50 barevných pixelů dané barvy = podezřelá strana
3b. Detekce černých anotací (PRIMÁRNÍ – uživatel píše digitálním perem)
Černé anotace jsou nejčastější typ. Detekce je náročnější, protože tištěný text je také černý.
KLÍČOVÉ ROZLIŠENÍ ruční vs. tištěné: Uživatel píše digitálním perem na tabletu. Jeho tahy jsou vždy nepravidelné – nikdy dokonale rovné čáry, body v nepravidelných rozestupech, mírné odchylky od přímky. Tištěné prvky mají přesnou geometrii – dokonale rovné čáry, přesné úhly, pravidelné rozestupy.
Přístup 1: Vektorové kresby (drawings)
drawings = page.get_drawings()
DŮLEŽITÉ – kontroluj OBOJÍ: color (stroke) i fill (výplň):
Některé PDF ukládají ruční anotace jako filled paths (výplň) místo stroked paths (obrys). Mnoho digitálních per generuje color=None, fill=(0,0,0).
import math
def is_hand_drawn(items):
"""Rozliš ruční tah od tištěného prvku.
Ruční tahy (digitální pero na tabletu):
- Mnoho bodů v krátkém úseku (pero sampluje polohu)
- Body NEJSOU na dokonalé přímce – odchylka od spojnice > 0
- Křivky (bezier curves) = téměř jistě ruční
- Celkový tvar je nepravidelný
Tištěné prvky (layout PDF):
- Málo bodů (typicky 2-4 pro čáry a obdélníky)
- Dokonale rovné čáry (odchylka = 0)
- Pravidelné obdélníky, kruhy
- Přesné horizontální/vertikální zarovnání
"""
has_curves = False
line_segments = []
point_count = 0
for item in items:
op = item[0] # typ operace: "l" (line), "c" (curve), "re" (rect), "qu" (quad)
if op == "c": # bezier křivka = téměř jistě ruční
has_curves = True
point_count += 4
elif op == "l": # úsečka
p1, p2 = item[1], item[2]
dx = abs(p2.x - p1.x)
dy = abs(p2.y - p1.y)
length = math.sqrt(dx*dx + dy*dy)
line_segments.append((p1, p2, length, dx, dy))
point_count += 2
elif op == "re": # obdélník = typicky tištěný layout
point_count += 4
elif op == "qu": # quad = typicky tištěný
point_count += 4
# Bezier křivky = ruční
if has_curves:
return True
# Samé obdélníky/quady bez čar = pravděpodobně layout
if not line_segments and not has_curves:
return False
# Mnoho krátkých úseček za sebou = samplovaný tah pera
if len(line_segments) > 5:
short_segments = sum(1 for _, _, l, _, _ in line_segments if l < 15)
if short_segments > len(line_segments) * 0.5:
return True
# Kontrola nepravidelnosti: pokud úsečky NEJSOU dokonale horizontální/vertikální
irregular_count = 0
for _, _, length, dx, dy in line_segments:
if length < 1:
continue
# Dokonale rovná čára: dx==0 nebo dy==0 (nebo téměř)
angle_from_axis = min(dx, dy) / max(dx, dy) if max(dx, dy) > 0 else 0
if angle_from_axis > 0.02: # > 1° odchylka od osy = nepravidelné
irregular_count += 1
if irregular_count > 0 and irregular_count >= len(line_segments) * 0.3:
return True
return False
for d in drawings:
color = d.get("color", None)
fill = d.get("fill", None)
items = d.get("items", [])
is_black_stroke = (color is not None and len(color) >= 3
and color[0] < 0.2 and color[1] < 0.2 and color[2] < 0.2)
is_black_fill = (fill is not None and len(fill) >= 3
and fill[0] < 0.2 and fill[1] < 0.2 and fill[2] < 0.2)
is_bg_rect = (fill is not None and len(fill) >= 3
and fill[0] > 0.9 and fill[1] > 0.9 and fill[2] > 0.9)
if is_bg_rect:
continue # šedé/bílé pozadí citátů – ignorovat
if (is_black_stroke or is_black_fill) and len(items) > 1:
# KLÍČOVÉ: ověř, že jde o ruční tah, ne tištěný prvek
if is_hand_drawn(items):
annotation_items += len(items)
Filtrování false positives – pravidla:
- VŽDY použij
is_hand_drawn()– nepoužívej jen počet items jako práh - Obdélníky (
re) = téměř vždy layout (rámečky, boxy) → ignorovat, pokud nejsou nepravidelné - Dokonale rovné čáry (horizontální/vertikální, odchylka < 1°) = tištěný prvek → ignorovat
- Bezier křivky = téměř jistě ruční → vždy zahrnout
- Mnoho krátkých úseček v řadě = samplovaný tah digitálního pera → zahrnout
- Nepravidelné úhly (odchylka > 1° od osy) = ruční tah → zahrnout
- Práh pro celou stranu: součet items z potvrzeně ručních kreseb > 5 = anotovaná strana
Přístup 2: Ink anotace (PDF annotation layer)
for annot in page.annots():
if annot.type[0] in [8, 15]: # Ink, Polyline
# Ink anotace = vždy ruční → zahrnout
pass
Dodatečné filtry pro snížení false positives:
- Ignoruj kresby uvnitř tabulek – tabulkové čáry jsou tištěné
- Ignoruj dekorativní prvky u nadpisů/zápatí (opakující se vzor na více stranách)
- Pokud se stejný drawing pattern opakuje na > 30 % stran, je to pravděpodobně layout → vyloučit
- Buď přesný – cíl je zachytit VŠECHNY ruční anotace a ŽÁDNÉ tištěné prvky; při pochybnosti pošli stranu na vizuální kontrolu subagentovi, který rozhodne
3c. Detekce vestavěných PDF anotací
annots = page.annots()
- Zkontroluj vestavěné PDF anotace (highlight, underline, strikeout, text notes, ink)
- Typy:
Highlight,Underline,StrikeOut,Text,FreeText,Ink,Square,Circle - Extrahuj barvu a obsah anotace
3d. Klasifikace pozice kreseb na stránce
Pro každou stranu s detekovanými vektorovými kresbami analyzuj POZICI kreseb:
def classify_drawing_position(drawing, page_width):
"""Určí, zda je kresba na okraji stránky nebo v těle textu."""
items = drawing.get("items", [])
xs, ys = [], []
for item in items:
for pt in item[1:]:
if hasattr(pt, 'x'):
xs.append(pt.x)
ys.append(pt.y)
if not xs:
return None, None, None, None
min_x, max_x = min(xs), max(xs)
min_y, max_y = min(ys), max(ys)
x_span = max_x - min_x
y_span = max_y - min_y
# Svislá čára na okraji = zatržení
if x_span < 30: # úzká kresba = svislá čára
if min_x < 60:
return "left_margin", min_x, min_y, max_y
elif min_x > page_width - 60:
return "right_margin", min_x, min_y, max_y
# Široká kresba na okraji
if max_x < 60:
return "left_margin", min_x, min_y, max_y
if min_x > page_width - 60:
return "right_margin", min_x, min_y, max_y
return "body", min_x, min_y, max_y
Pro každou stranu s potvrzeně ručními kresbami ulož:
- Seznam kreseb s jejich pozicí (left_margin / right_margin / body)
- Souřadnice y-rozsahu každé kresby
- Počet items v kresbě
3e. Kategorizace nalezených stran
Rozděl nalezené strany do tří skupin:
Jednoduché strany (BEZ vizuální kontroly):
- Mají POUZE vestavěné PDF anotace typu
Highlight,Underline,StrikeOut - Text pod anotací lze extrahovat přímo z PDF dat přes
page.get_text() - Zpracuj tyto strany přímo v hlavním kontextu (viz krok 4A-1)
Marginální strany (programatická extrakce, BEZ vizuální kontroly):
- Mají vektorové kresby POUZE na okrajích stránky (left_margin / right_margin)
- Žádné kresby v těle stránky (body)
- Text se extrahuje programaticky spárováním y-souřadnic kreseb s textovými bloky (viz krok 4A-2)
- DŮLEŽITÉ: Toto je spolehlivější než vizuální analýza! Fill-only paths (color=None, fill=(0,0,0)) se v PNG renderují jako extrémně tenké/neviditelné čáry a subagent je nevidí
Složité strany (VYŽADUJÍ vizuální kontrolu):
- Mají vektorové kresby v těle stránky, ink anotace, barevné pixelové anotace, nebo ruční text
- Obsahují ruční poznámky, šipky, symboly, schémata
- Deleguj na subagenty (viz krok 4B)
Vypiš uživateli přehled: kolik stran nalezeno, kolik jednoduchých vs. marginálních vs. složitých.
4A-1. Přímá extrakce jednoduchých stran (hlavní kontext)
Pro strany s POUZE vestavěnými PDF anotacemi (highlight, underline, strikeout):
for annot in page.annots():
annot_type = annot.type[1] # "Highlight", "Underline", etc.
annot_color = annot.colors.get("stroke", None) or annot.colors.get("fill", None)
# Získej text pod anotací
text = page.get_text("text", clip=annot.rect)
- Extrahuj text přímo z PDF – žádné PNG, žádná vizuální analýza
- Zapiš rovnou do výstupního markdown (buffer v paměti)
- Toto je extrémně levné na kontext
4A-2. Programatická extrakce marginálních stran (hlavní kontext)
Pro strany s vektorovými kresbami POUZE na okrajích stránky. Toto je spolehlivější než vizuální analýza pro zatržení/podtržení, protože fill-only paths se v PNG renderují jako neviditelné.
def get_text_in_y_range(page, y_min, y_max, margin=15):
"""Získej textové řádky v daném rozsahu y-souřadnic.
DŮLEŽITÉ: margin=15 (ne 5!) – kresby často začínají/končí
mírně mimo textový blok, větší margin zajistí správné párování.
"""
blocks = page.get_text("dict")["blocks"]
lines = []
for b in blocks:
if "lines" not in b:
continue
for line in b["lines"]:
ly = (line["bbox"][1] + line["bbox"][3]) / 2 # střed řádku
if y_min - margin <= ly <= y_max + margin:
text = " ".join(span["text"] for span in line["spans"])
if text.strip():
lines.append(text.strip())
return "\n".join(lines)
def merge_ranges(ranges, gap=10):
"""Slučuj překrývající se y-rozsahy.
KRITICKÉ: Řaď podle y_min (x[1]), NE podle position stringu (x[0])!
Špatné řazení způsobí nesprávné sloučení nepřekrývajících se rozsahů
a ztrátu anotací.
"""
if not ranges: return []
ranges.sort(key=lambda x: x[1]) # řaď podle y_min, NE podle position!
merged = [list(ranges[0])]
for pos, y_min, y_max in ranges[1:]:
if y_min <= merged[-1][2] + gap:
merged[-1][2] = max(merged[-1][2], y_max)
else:
merged.append([pos, y_min, y_max])
return merged
# Pro každou marginální stranu:
page = doc[page_num - 1]
pw = page.rect.width
# Seskup kresby podle pozice a y-rozsahu
margin_annotations = [] # [(position, y_min, y_max)]
for d in drawings:
# ... filtruj jen potvrzeně ruční černé kresby ...
pos, min_x, min_y, max_y = classify_drawing_position(d, pw)
if pos in ("left_margin", "right_margin") and (max_y - min_y) > 20:
margin_annotations.append((pos, min_y, max_y))
# Slučuj překrývající se rozsahy (POZOR: merge_ranges musí řadit dle y_min!)
merged = merge_ranges(margin_annotations)
# Pak pro každý rozsah:
for pos, y_min, y_max in merged:
text = get_text_in_y_range(page, y_min, y_max)
# Zapiš jako [ZATRŽENO] s poznámkou o pozici (left/right/oboustranné)
Pravidla pro marginální extrakci:
- Kresby s y_span < 20pt ignoruj (příliš malé = pravděpodobně tečky/artefakty)
- Pokud je kresba na OBOU okrajích (left + right) ve stejném y-rozsahu → "Oboustranné zatržení"
- Pokud je kresba pouze na jednom okraji → "[ZATRŽENO]" bez speciální poznámky
- Text extrahuj přes
get_text("dict")pro přesné řádky, NE přesget_text("text", clip=...)– clip je méně přesný - Toto je extrémně levné na kontext a spolehlivější než vizuální analýza pro okrajové anotace
4B. Vizuální analýza složitých stran (delegovaná na subagenty)
KRITICKÉ pro šetření kontextu: Vizuální analýzu NIKDY neděle v hlavním kontextu. Vždy deleguj na Agent subagenty.
4B-1. Příprava PNG souborů
Před spuštěním subagentů exportuj všechny složité strany jako PNG:
pix = page.get_pixmap(dpi=250) # 250 DPI – vyšší rozlišení pro spolehlivou detekci jemných tahů
pix.save(f"temp_pages/page_{page_num:04d}.png")
Také pro každou stranu extrahuj tištěný text a drawing metadata:
text = page.get_text()
with open(f"temp_pages/page_{page_num:04d}.txt", "w") as f:
f.write(text)
# Drawing metadata – pomůže subagentovi vědět KAM se dívat
with open(f"temp_pages/page_{page_num:04d}_hints.txt", "w") as f:
for d in page.get_drawings():
fill = d.get("fill", None)
color = d.get("color", None)
items = d.get("items", [])
is_black = (fill and fill[0] < 0.2) or (color and color[0] < 0.2)
if is_black and len(items) > 3:
pos, min_x, min_y, max_y = classify_drawing_position(d, page.rect.width)
if pos:
f.write(f"Drawing: {len(items)} items, pos={pos}, y=[{min_y:.0f}-{max_y:.0f}]\n")
4B-2. Spuštění subagentů po dávkách
Rozděl složité strany do dávek po max 15 stranách. Pro každou dávku spusť Agent subagenta:
Agent(
model: "opus", # 1M kontext – unese 15 stran s obrázky
description: "PDF extract batch X",
prompt: """
Jsi expert na extrakci ručních poznámek z PDF knih.
Zpracuj tyto strany: [seznam čísel stran]
Cesta k PNG: temp_pages/page_XXXX.png
Cesta k textu: temp_pages/page_XXXX.txt
Pro každou stranu:
1. Přečti soubor _hints.txt – obsahuje pozice detekovaných kreseb (kde hledat anotace)
2. Přečti PNG přes Read tool (vizuální kontrola)
3. Přečti textový soubor pro kontext tištěného textu
4. Identifikuj typy anotací (viz tabulka níže) – ZAMĚŘ SE na pozice z hints souboru
5. Pokud je na stránce označený obrázek/schéma, extrahuj ho
Typy anotací:
| Tag | Popis |
|-----|-------|
| [RUKOU PSÁNO] | Ruční text – poznámky, nadpisy, komentáře |
| [ZATRŽENO] | Svislá čára na okraji u tištěné pasáže |
| [ZVÝRAZNĚNO] | Highlight / rámeček kolem textu |
| [PODTRŽENO] | Čára pod tištěným textem |
| [OBRÁZEK] | Označený/orámovaný obrázek na stránce |
| [SCHÉMA] | Diagram, schéma, graf – VŽDY zachovat jako obrázek, NIKDY nepřevádět na text |
| [ŠIPKA] | Šipka ukazující na konkrétní místo |
| [SYMBOL] | Hvězdička, vykřičník, otazník, check |
| [ZÁLOŽKA] | Označení celé strany |
DŮLEŽITÉ – rozlišení ručních anotací vs. tištěný obsah:
- Uživatel anotuje digitálním perem na tabletu
- Jeho tahy jsou VŽDY nepravidelné (nikdy dokonale rovné)
- Tištěný text a layout prvky (čáry tabulek, rámečky, dekorativní prvky) jsou dokonale geometrické
- NEOZNAČUJ tištěné prvky jako anotace!
- Hledej: čárky u textu, ohraničení pasáží, podtržení, ruční poznámky na okrajích
- Pokud si nejsi jistý, jestli je prvek ruční nebo tištěný → ZAHRŇ ho do výstupu s poznámkou [nejisté]
SCHÉMATA A DIAGRAMY:
- Pokud strana obsahuje schéma/diagram/graf (tištěný i ručně kreslený), VŽDY ho zachovej jako obrázek
- NIKDY nepřeváděj schéma na textový popis
- Extrahuj oblast schématu jako samostatný PNG pomocí PyMuPDF s clip parametrem:
```python
import fitz
doc = fitz.open("<cesta_k_pdf>")
page = doc[page_num - 1]
clip = fitz.Rect(x0, y0, x1, y1) # oblast schématu z hints/vizuální analýzy
pix = page.get_pixmap(dpi=300, clip=clip)
pix.save(f"{nazev_knihy}_images/img_page{page_num}_{N}.png")
```
- Vlož do markdown jako obrázek: ``
VÝSTUP: Vrať POUZE strukturovaný markdown pro každou stranu v tomto formátu:
## Strana XX
### [TYP_ANOTACE] emoji_barvy
> text anotace
---
Pokud text nelze přečíst, napiš [nečitelné].
Nevymýšlej text – pokud ho nevidíš, nevymýšlej.
U zatržených pasáží cituj dostatečně velký blok tištěného textu.
U ručních poznámek přepsat text kurzívou.
Schémata a diagramy VŽDY jako obrázek, NIKDY jako text.
Obrázky ukládej jako: {nazev_knihy}_images/img_page{XX}_{N}.png
"""
)
Paralelizace: Pokud je stran hodně (30+), spusť 2–3 subagenty paralelně (nezávislé dávky).
4B-3. Extrakce označených obrázků v subagentovi
Subagent v rámci své dávky extrahuje označené obrázky:
images = page.get_images(full=True)
for img_info in images:
xref = img_info[0]
base_image = doc.extract_image(xref)
# Ulož obrázek do výstupní složky
- Ulož obrázek jako
img_page{XX}_{N}.pngdo složky{nazev_knihy}_images/ - V markdown odkazuj relativní cestou
4C. Programatická verifikace po subagentovi (hlavní kontext)
KRITICKÉ: Po dokončení subagentů porovnej jejich výsledky s detekčními daty z Fáze 1.
Pro každou stranu, kterou subagent označil jako "false positive" nebo "žádné anotace":
- Zkontroluj, zda Fáze 1 detekovala vektorové kresby s > 10 items na okrajích (left_margin / right_margin)
- Pokud ANO → subagent se mýlil (fill-only paths jsou v PNG neviditelné)
- Použij programatickou extrakci (stejný postup jako 4A-2) k získání zatržených textů
- Doplň tyto strany do výstupu
Důvod: Některé PDF ukládají ruční tahy jako color=None, fill=(0,0,0) (filled paths bez stroke). Při renderování do PNG se tyto kresby zobrazí jako extrémně tenké čáry (sub-pixel), které LLM v obrázku nevidí. Vektorová data z PDF jsou v tomto případě autoritativní.
5. Sestavení výstupního souboru (hlavní kontext)
Po dokončení všech subagentů sestav výstupní soubor z:
- Přímé extrakce jednoduchých stran (krok 4A)
- Markdown výstupů ze subagentů (krok 4B)
5a. Název souboru
- Formát:
Nazev_knihy (Autor).md - Příklad:
Thinking_Fast_and_Slow (Daniel Kahneman).md - Mezery v názvu knihy nahraď podtržítky
- Ulož do stejné složky jako zdrojové PDF
5b. Struktura markdown souboru
# Název knihy
**Autor:** Jméno Autora
**Extrahováno:** YYYY-MM-DD
**Zdroj:** název_souboru.pdf
**Počet anotovaných stran:** XX z YY
---
<!-- Uživatelské poznámky – prostor pro vlastní text nad extrakcí -->
---
## Strana 42
### [ZATRŽENO]
> Tištěný text pasáže, která byla zatržena svislou čárou na okraji.
> Může být víceřádková.
### [RUKOU PSÁNO]
> Přepis ručně psané poznámky kurzívou
### [ZVÝRAZNĚNO] 🟡
> Text, který byl zvýrazněn žlutým highlighterem
### [PODTRŽENO]
> Podtržená věta nebo fráze
### [OBRÁZEK]

> Poznámka k obrázku (pokud existuje)
---
## Strana 57
...
5c. Pravidla zápisu
- Řadit chronologicky podle čísla strany (sluč výsledky z jednoduchých stran a subagentů)
- U barevných anotací přidat emoji indikátor barvy: ⚫ černá, 🟢 zelená, 🟡 žlutá, 🔴 červená, 🔵 modrá, 🟠 oranžová
- Černé anotace (nejčastější) nemusí mít emoji – jsou výchozí; emoji přidávej jen u barevných
- U zatržených/zvýrazněných pasáží citovat relevantní tištěný text v bloku
> - U ručních poznámek přepsat text kurzívou v bloku
> - NEMAZAT existující obsah – pokud soubor již existuje, uživatel může mít vlastní poznámky na začátku
- Pokud soubor existuje, aktualizuj/doplň pouze sekce za oddělovačem
---
6. Úklid
rm -rf temp_pages/
- Smaž dočasný adresář s PNG exporty a textovými soubory
- Ponech složku s extrahovanými obrázky (
{nazev_knihy}_images/)
7. Shrnutí
Vypiš uživateli:
- Cestu k výstupnímu
.mdsouboru - Cestu ke složce s obrázky (pokud existuje)
- Počet zpracovaných stran / nalezených anotací
- Rozložení typů anotací (kolik zatržení, kolik poznámek, atd.)
- Stručný přehled nejčastěji anotovaných témat/kapitol
Pravidla kvality
Vždy:
- Ověř, že PDF existuje a je čitelný
- Zpracovávej po dávkách – nenahrávej celé PDF do paměti najednou
- U ručních poznámek se snaž o co nejpřesnější přepis
- Pokud text nelze přečíst, napiš
[nečitelné] - Zachovej kontext – u zatržených pasáží cituj dostatečně velký blok textu
- Informuj uživatele o průběhu (kolik stran zpracováno)
- Schémata/diagramy vždy zachovej jako obrázek (PNG), nepřeváděj na text
- Buď přesný – zachyť všechny ruční anotace, ale neoznačuj tištěné prvky; při pochybnosti pošli na vizuální kontrolu subagentovi
Nikdy:
- Nevynechávej nalezené anotace
- Nevymýšlej text – pokud ho nevidíš, nevymýšlej
- Nemazej existující obsah v cílovém souboru
- Neignoruj obrázky – pokud jsou označené, extrahuj je
- NIKDY nečti PNG obrázky stran v hlavním kontextu – vždy deleguj na subagenty
- NIKDY neoznačuj tištěné prvky (layout, tabulky, dekorace) jako anotace
- NIKDY nepřeváděj schémata/diagramy na textový popis – vždy jako obrázek
Tipy
- U knih s mnoha anotacemi (100+ stran) může zpracování trvat déle – informuj uživatele
- Některé PDF mají anotace jako vestavěné PDF annotations (ne jen barevné pixely) – kontroluj obojí
- Pokud je kvalita skenování nízká, zvyš DPI na 200 pro lepší detekci v subagentovi
- Pro knihy s převážně žlutým highlighterem uprav práh detekce
- Subagenty s model: "opus" mají 1M kontext – klidně jim dej 15 stran najednou
- Pokud má kniha < 10 složitých stran, stačí jeden subagent; pro 30+ stran spusť 2–3 paralelně