diff --git a/.gitignore b/.gitignore index b14bfa6..8a39c84 100644 --- a/.gitignore +++ b/.gitignore @@ -32,6 +32,7 @@ audio_wav/ __pycache__/ *.pyc .venv/ +.venv_pdf/ # Logs *.log diff --git a/CLAUDE.md b/CLAUDE.md index cc5360f..d5f0127 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -34,6 +34,11 @@ python transcribe.py --modules 1 # transcribe module 1 only python summarize.py # print summary prompts to stdout python summarize.py --compile # compile SUPORT_CURS.md from existing summaries +# MD → PDF (from WSL2, uses .venv_pdf) +.venv_pdf/bin/python md_to_pdf.py # all MODUL*_*.md → summaries/pdf/ +.venv_pdf/bin/python md_to_pdf.py --modules 1-3 # specific modules +.venv_pdf/bin/python md_to_pdf.py summaries/X.md # specific file + # Setup components individually python setup_whisper.py whisper # download whisper.cpp binary python setup_whisper.py model # download Whisper model diff --git a/PROCES_SUMARIZARE.md b/PROCES_SUMARIZARE.md new file mode 100644 index 0000000..4d274a0 --- /dev/null +++ b/PROCES_SUMARIZARE.md @@ -0,0 +1,49 @@ +# Proces Sumarizare Module NLP Master + +## Scop +Generare notițe de recapitulare pentru testarea finală, din transcrierile audio ale cursului NLP Master Practitioner. + +## Output — 3 fișiere per modul + +| Fișier | Conținut | Uz | +|--------|----------|----| +| `summaries/MODUL{N}_EXHAUSTIV.md` | Toate conceptele, tehnicile pas-cu-pas, exercițiile cu instrucțiuni, exemple, metafore, citate, referințe bibliografice, mindmap text | Studiu aprofundat | +| `summaries/MODUL{N}_CONCENTRAT.md` | Concepte cheie + tehnici principale + mindmap condensat (fără anecdote/exemple extinse) | Recapitulare rapidă | +| `summaries/MODUL{N}_CHEATSHEET.md` | Ultra-condensat: termeni + definiții scurte + tehnici într-o linie | Revisie înainte de test | + +## Pași + +### 1. Identifică transcrierile +``` +transcripts/Master 25M{N} Z{zi}{parte}.txt +``` +- Ziua 1: Z1A, Z1B, Z1C, Z1D (4 părți) +- Ziua 2: Z2A, Z2B, Z2C (3 părți) +- Numărul de părți poate varia per modul + +### 2. Extragere exhaustivă (per fișier transcript) +Din fiecare transcript se extrag: +1. **Concepte și modele NLP** — cu explicații +2. **Tehnici/instrumente** — pași detaliați dacă sunt descriși +3. **Exerciții** — cu instrucțiuni complete +4. **Exemple și metafore** — cele folosite de trainer +5. **Citate/principii importante** +6. **Referințe** — cărți, autori, resurse externe +7. **Fluxul sesiunii** — structura și ordinea subiectelor + +### 3. Compilare în cele 3 fișiere +- **Limba:** Română +- **Structură:** pe zile și sesiuni (Ziua 1 / Ziua 2) +- Exhaustiv → include tot ce are valoare educațională +- Concentrat → filtrează anecdotele, păstrează esența +- Cheatsheet → format tabel/listă, maxim 1-2 pagini + +### 4. Verificare +- Toate conceptele cheie apar în toate cele 3 nivele +- Tehnicile au pași clari în versiunea exhaustivă +- Cheatsheet-ul e suficient de scurt pentru o trecere rapidă + +## Comandă rapidă (în Claude Code) +``` +Sumarizare modul {N} — procesul din PROCES_SUMARIZARE.md +``` diff --git a/PROMPT_EXPERIENTIAL.md b/PROMPT_EXPERIENTIAL.md new file mode 100644 index 0000000..41a07f1 --- /dev/null +++ b/PROMPT_EXPERIENTIAL.md @@ -0,0 +1,142 @@ +# Prompt Experiențial — Caiet de Facilitator NLP Master + +## Cum se folosește + +3 pași per modul: +1. **Per zi:** Citește transcrierile unei zile și aplică PROMPT_ZI +2. **Merge:** Citește drafturile zilelor + EXHAUSTIV-ul modulului și aplică PROMPT_MERGE +3. **Aplicări:** Din jurnalul final, aplică PROMPT_APLICARI + +--- + +## PROMPT_ZI + +``` +Ești un facilitator NLP cu cunoștințe solide de psihologie, neuroștiință, CNV, coaching, +attachment theory, IFS (Internal Family Systems), și filozofie practică. Ai participat +la acest modul de curs NLP Master Practitioner și scrii un caiet de procesare. + +Limba: română. Ton: direct, dens, fără florituri. + +═══════════════════════════════════════════════════════ +REGULI +═══════════════════════════════════════════════════════ + +1. FĂRĂ VOCE DE POVESTITOR + NU scrie: "Nimeni nu bănuia că...", "Și aici apare ceva...", "Sala a tăcut." + SCRIE direct: ce s-a spus, ce înseamnă, cu ce se corelează. + Caiet de gânditor, nu roman. + +2. ȚESE, NU CATALOGA + Nu secțiuni separate de metafore/exerciții/credințe. Fluxul zilei e structura. + Fiecare element apare în contextul lui, legat de ce vine înainte și după. + +3. CORELAȚII PROPRII — cel mai important + După fiecare concept/exercițiu/moment, ADAUGĂ corelații din: + - Psihologie: Jung (evident), dar și Freud, Winnicott, Bowlby, Erikson + - Attachment theory: cum se leagă de stilurile de atașament + - IFS (Internal Family Systems): părți protectoare, exilați, manageri + - Brené Brown: vulnerabilitate, rușine, curaj + - CNV (Marshall Rosenberg): nevoi universale, strategii vs nevoi + - Neuroștiință: amigdala, cortex prefrontal, polyvagal theory (Stephen Porges) + - Filozofie: stoicism, existențialism, budism (non-atașament, non-dualitate) + - Coaching: modele (GROW, clean language, coaching ontologic) + - Alte modele NLP sau terapeutice relevante + + Nu forța corelațiile. Adaugă-le doar unde sunt genuine și utile. + Formatul: scurt, direct. "Asta e în esență ce Brené Brown numește 'vulnerability + hangover' — momentul de după în care regrezi că te-ai deschis." + +4. ANTI-GENERICISM + NU: "Trainerul a explicat conceptul X" + DA: Cuvintele lui exacte (ușor adaptate), apoi ce înseamnă, apoi cu ce se corelează. + +5. EXERCIȚII COMPLETE + Scriptul facilitatorului rămâne complet — pași, cuvinte, ce observi, debriefing, + ce poate ieși greșit. Exercițiile sunt cel mai practic element, nu le comprima. + +═══════════════════════════════════════════════════════ + +STRUCTURA: + +### Firul zilei +Narativa densă a zilei. Concepte → citate relevante ale trainerului → corelații proprii → +exerciții (cu script complet) → ce deschide fiecare element. Tot într-un fir. + +Stil: paragraf dens care gândește, nu care povestește. Cuvintele trainerului apar ca +citate scurte integrate în text, nu ca blocuri dramatice. + +### Constelația de conexiuni +Legăturile non-evidente. Thread-uri deschise. Corelații cross-disciplinare. + +### Scripturi de exerciții (referință rapidă) +Pașii extrași, formatați pentru uz practic. Duplică intenționat. + +--- +TRANSCRIERILE ZILEI: +[se inserează aici] +``` + +--- + +## PROMPT_MERGE + +``` +Ai drafturile jurnalului de facilitator pentru fiecare zi a modulului {N} ({concept}). +Combină-le într-un jurnal coerent. + +REGULI: +- Păstrează tot conținutul — nu comprima exercițiile sau corelațiile +- Adaugă firul roșu al modulului (arc conceptual, nu rezumat) +- Adaugă constelația modulului (conexiuni tematice cross-zi + cross-modul) +- Verifică cu EXHAUSTIV-ul că nu ratezi concepte +- Ton: direct, dens, fără florituri de povestitor +- Unde găsești corelații noi cross-zi, adaugă-le + +STRUCTURA: + +# MODUL {N} — {CONCEPT} +## Caiet de Facilitator + +### Firul roșu al modulului +[Arc conceptual și emoțional. Direct, 3-5 paragrafe.] + +### Ziua 1: [titlu scurt] +[Conținutul din draft, integral] + +### Ziua 2: [titlu scurt] +[Conținutul din draft, integral] + +### Constelația modulului +[Harta conexiunilor tematice + corelații cross-disciplinare + thread-uri deschise] + +### Scripturi de exerciții (referință rapidă) +[Pași extrași pentru uz practic] + +### Lecturi și resurse +[Cărți/documentare menționate] + +--- +REFERINȚĂ: [EXHAUSTIV-ul modulului] +DRAFTURILE: [drafturile zilelor] +``` + +--- + +## PROMPT_APLICARI + +``` +Din jurnalul modulului {N} ({concept}), generează un ghid de aplicare. + +Fii SPECIFIC — CUM adaptezi, cu ce cuvinte, pentru câți oameni, ce efect urmărești. +Arată CONEXIUNILE — de ce funcționează în acest context, ce nevoie adresează. +Ton: direct, practic, fără florituri. + +# MODUL {N} — {CONCEPT}: Ghid de Aplicare + +## Pentru grup de sprijin NLP +## Pentru cercetași adulți +## Pentru întâlniri CNV +## Pentru self-coaching +## Conexiuni cross-modul +``` diff --git a/TODOS.md b/TODOS.md index 0f78274..9deb803 100644 --- a/TODOS.md +++ b/TODOS.md @@ -1,8 +1,43 @@ # TODOS ## Re-run pipeline for Module 6 -- **What:** Re-run `download.py` when module 6 becomes available on cursuri.aresens.ro/curs/26 -- **Why:** Course has 6 modules total, only 5 are currently available. Pipeline is designed to be re-runnable — manifest.json + resumability means it discovers new modules and skips already-downloaded files. -- **How:** Run `python download.py` → check manifest for new files → run `python transcribe.py` → generate summaries → update SUPORT_CURS.md -- **Depends on:** Course provider publishing module 6 +- **What:** Re-run pipeline when module 6 becomes available on cursuri.aresens.ro/curs/26 +- **Why:** Course has 6 modules total, only 5 are currently available. +- **How:** Din Windows nativ: `run.bat 6` (descarcă + transcrie doar modulul 6, skip-uiește M1-M5 deja complete) +- **Depends on:** Course provider publishing module 6 (~2026-04-08) - **Added:** 2026-03-24 + +## Modulul 6 — Sumarizări standard (EXHAUSTIV/CONCENTRAT/CHEATSHEET) +- **When:** După ce transcrierile M6 sunt gata (~2026-04-08 + timp de transcriere) +- **How:** + 1. `run.bat 6` — descarcă + transcrie modulul 6 (sau `run.bat` fără argumente pentru tot) + 2. Aplică procesul standard de sumarizare (vezi `PROCES_SUMARIZARE.md`): + - Citește toate transcrierile M6 (`transcripts/*M6*.txt`) + - Generează `summaries/MODUL6_EXHAUSTIV.md` (toate conceptele, tehnici pas cu pas, exerciții, exemple, citate) + - Generează `summaries/MODUL6_CONCENTRAT.md` (esența, fără anecdote) + - Generează `summaries/MODUL6_CHEATSHEET.md` (tabel/listă, 1-2 pagini) + 4. `python summarize.py --compile` — recompilează `SUPORT_CURS.md` cu M6 + +## Modulul 6 — Caiet experiențial + aplicări +- **When:** După ce EXHAUSTIV-ul M6 e gata +- **How:** + 1. Identifică tema modulului din transcrieri (probabil integrare finală / examen / încheiere) + 2. Aplică promptul din `PROMPT_EXPERIENTIAL.md`: + - **Pas 1:** Per zi — citește transcrierile fiecărei zile, aplică PROMPT_ZI → drafturi per zi + - **Pas 2:** Merge — citește drafturile + MODUL6_EXHAUSTIV.md, aplică PROMPT_MERGE → `summaries/MODUL6_{CONCEPT}.md` + - **Pas 3:** Aplicări — aplică PROMPT_APLICARI → `summaries/MODUL6_{CONCEPT}_APLICARI.md` + 3. Verifică calitatea: ton direct/dens, corelații cross-disciplinare, exerciții cu script complet, cadrări în aplicări +- **Reminders:** + - Tonul: caiet de gânditor, NU roman. Fără voce de povestitor. + - Corelații proprii din: IFS, CNV, attachment theory, Brené Brown, neuroștiință, filozofie + - Aplicările includ secvențe de cadrare complete (concepte ÎNAINTE, metafore, container siguranță) + +## Modulul 6 — Actualizare fișiere cross-modul +- **When:** După ce caietul experiențial M6 e gata +- **How:** Actualizează cele 5 fișiere cross-modul cu conținutul M6: + 1. `summaries/INDEX_EXERCITII.md` — adaugă exercițiile M6 + 2. `summaries/HARTA_CONEXIUNI.md` — adaugă conexiunile M6 și actualizează mindmap-ul + 3. `summaries/GLOSAR_CREDINTE.md` — adaugă credințele/reframe-urile M6 + 4. `summaries/GHID_FACILITARE.md` — adaugă exercițiile M6 în matricele de selecție + 5. `summaries/METAFORE_POVESTI.md` — adaugă metaforele M6 +- **Also:** Deschide plicul sigilat din M1 (se deschide la finalul masterului) diff --git a/md_to_pdf.py b/md_to_pdf.py new file mode 100644 index 0000000..926572e --- /dev/null +++ b/md_to_pdf.py @@ -0,0 +1,239 @@ +#!/usr/bin/env python3 +"""Convert Markdown summaries to print-friendly PDFs.""" + +import argparse +import glob +import os +import sys + +import markdown2 +from weasyprint import HTML + +SUMMARIES_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), "summaries") +PDF_DIR = os.path.join(SUMMARIES_DIR, "pdf") + +CSS = """ +@page { + size: A4; + margin: 2cm; + @bottom-right { + content: counter(page); + font-size: 9pt; + color: #666; + } +} + +body { + font-family: "Segoe UI", "Noto Sans", "DejaVu Sans", sans-serif; + font-size: 11pt; + line-height: 1.5; + color: #111; +} + +h1 { + font-size: 18pt; + font-weight: bold; + margin-top: 0.5em; + margin-bottom: 0.3em; + border-bottom: 1.5pt solid #333; + padding-bottom: 0.2em; + page-break-before: auto; +} + +h1:first-of-type { + page-break-before: avoid; +} + +h2 { + font-size: 14pt; + font-weight: bold; + margin-top: 1em; + margin-bottom: 0.3em; + color: #222; +} + +h3 { + font-size: 12pt; + font-weight: bold; + margin-top: 0.8em; + margin-bottom: 0.2em; + color: #333; +} + +p { + margin: 0.4em 0; +} + +ul, ol { + margin: 0.3em 0; + padding-left: 1.5em; +} + +li { + margin: 0.15em 0; +} + +strong { + font-weight: bold; +} + +em { + font-style: italic; +} + +hr { + border: none; + border-top: 0.5pt solid #999; + margin: 1em 0; +} + +table { + width: 100%; + border-collapse: collapse; + margin: 0.5em 0; + font-size: 10pt; + page-break-inside: avoid; +} + +th { + background-color: #e8e8e8; + font-weight: bold; + text-align: left; + padding: 5pt 8pt; + border: 0.5pt solid #bbb; +} + +td { + padding: 4pt 8pt; + border: 0.5pt solid #ccc; +} + +tr:nth-child(even) td { + background-color: #f5f5f5; +} + +pre { + background-color: #f5f5f5; + border: 0.5pt solid #ccc; + border-radius: 3pt; + padding: 8pt 10pt; + font-family: "Consolas", "DejaVu Sans Mono", monospace; + font-size: 9pt; + line-height: 1.35; + white-space: pre-wrap; + word-wrap: break-word; + page-break-inside: avoid; +} + +code { + font-family: "Consolas", "DejaVu Sans Mono", monospace; + font-size: 9.5pt; + background-color: #f0f0f0; + padding: 1pt 3pt; + border-radius: 2pt; +} + +pre code { + background: none; + padding: 0; +} + +blockquote { + border-left: 2pt solid #999; + margin: 0.5em 0; + padding: 0.3em 0 0.3em 1em; + color: #333; +} +""" + + +def md_to_pdf(md_path, pdf_path): + """Convert a single Markdown file to PDF.""" + with open(md_path, "r", encoding="utf-8") as f: + md_text = f.read() + + html_body = markdown2.markdown( + md_text, + extras=["tables", "fenced-code-blocks", "header-ids", "break-on-newline"], + ) + + html_doc = f""" + +
+ + + + +{html_body} + +""" + + HTML(string=html_doc).write_pdf(pdf_path) + print(f" {os.path.basename(md_path)} -> {os.path.basename(pdf_path)}") + + +def find_files(modules=None): + """Find MODUL*_*.md files, optionally filtered by module numbers.""" + pattern = os.path.join(SUMMARIES_DIR, "MODUL*_*.md") + files = sorted(glob.glob(pattern)) + + if modules: + filtered = [] + for f in files: + basename = os.path.basename(f) + # Extract module number from MODUL{N}_... + try: + num = int(basename.split("_")[0].replace("MODUL", "")) + if num in modules: + filtered.append(f) + except ValueError: + continue + files = filtered + + return files + + +def parse_modules(spec): + """Parse module spec like '1-3' or '2,4,5' into a set of ints.""" + modules = set() + for part in spec.split(","): + part = part.strip() + if "-" in part: + start, end = part.split("-", 1) + modules.update(range(int(start), int(end) + 1)) + else: + modules.add(int(part)) + return modules + + +def main(): + parser = argparse.ArgumentParser(description="Convert MD summaries to PDF") + parser.add_argument("files", nargs="*", help="Specific MD files to convert") + parser.add_argument( + "--modules", "-m", help="Module filter, e.g. '1-3' or '2,4,5'" + ) + args = parser.parse_args() + + os.makedirs(PDF_DIR, exist_ok=True) + + if args.files: + md_files = [os.path.abspath(f) for f in args.files] + else: + modules = parse_modules(args.modules) if args.modules else None + md_files = find_files(modules) + + if not md_files: + print("No MD files found to convert.") + sys.exit(1) + + print(f"Converting {len(md_files)} file(s) to PDF...") + for md_path in md_files: + basename = os.path.splitext(os.path.basename(md_path))[0] + pdf_path = os.path.join(PDF_DIR, basename + ".pdf") + md_to_pdf(md_path, pdf_path) + + print(f"Done. PDFs saved to {PDF_DIR}") + + +if __name__ == "__main__": + main() diff --git a/requirements.txt b/requirements.txt index f8fbc0e..73bbc3d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,5 @@ requests beautifulsoup4 python-dotenv +markdown2 +weasyprint