9c1b7dd0f3
Subsistema papers/: pieza de entrega + control de calidad. - render_paper_pdf_py_datascience (Python, impure, dominio datascience, grupo `papers`): convierte papers/<slug>/paper.md (frontmatter YAML + cuerpo IMRaD) en papers/<slug>/out/paper.pdf. Reutiliza el motor de paginación de flujo del paquete automatic_eda (matplotlib PdfPages, el mismo PDF móvil A5 de los informes EDA) — no reimplementa paginación ni toca matplotlib, y no añade dependencias. Cada sección IMRaD (# H1) → un Chapter en página nueva; portada desde el frontmatter (title/authors/date europea/abstract); detecta las imágenes Markdown  que el motor no entiende y las parte en bloques Image resueltos contra base_dir y base_dir/figures/. dict-no-throw estricto. 5 tests verdes (golden + edges: sin frontmatter, path inexistente, figura inexistente, ruta directa al .md). - .claude/agents/paper-reviewer: revisor académico adversarial read-only (gate anti paper-mill). Puntúa novedad/rigor/reproducibilidad/validez (0-5), intenta refutar cada claim contra la evidencia citada, detecta HARKing contra el preregistration.md, exige limitaciones declaradas y claims ≤ evidencia, y emite veredicto estructurado JSON (accept|major_revision|reject) con default conservador. Tools: Read, Grep, Glob, Bash (sin Edit/Write: solo juzga). Diseño completo: reports/0001-2026-06-30-papers-system-design.md (agente C). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
5.6 KiB
5.6 KiB
name, kind, lang, domain, version, purity, signature, description, tags, uses_functions, uses_types, returns, returns_optional, error_type, imports, params, output, tested, tests, test_file_path, file_path
| name | kind | lang | domain | version | purity | signature | description | tags | uses_functions | uses_types | returns | returns_optional | error_type | imports | params | output | tested | tests | test_file_path | file_path | ||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| render_paper_pdf | function | py | datascience | 1.0.0 | impure | def render_paper_pdf(paper_dir: str) -> dict | Convierte un paper académico IMRaD escrito en Markdown (papers/<slug>/paper.md, con frontmatter YAML opcional title/authors/date/abstract + cuerpo) en un PDF papers/<slug>/out/paper.pdf. REUTILIZA el paginador de flujo del paquete automatic_eda (el mismo motor del PDF móvil A5 de los informes EDA): no reimplementa paginación ni toca matplotlib. Cada sección IMRaD (encabezado de nivel 1, p.ej. # Introduction, # Methods) se mapea a un Chapter que empieza en página nueva; el motor parsea por sí mismo headings, listas, tablas pipe, párrafos y **negrita** dentro del texto. Como el motor NO entiende la sintaxis de imagen Markdown , esta función detecta esas líneas y las parte en bloques Image separados, resolviendo el src relativo a base_dir y base_dir/figures/. La portada (si hay título) lista autores y fecha (DD/MM/AAAA si parseable) más el abstract. dict-no-throw: nunca lanza, devuelve {status, pdf_path, n_pages, note}. |
|
false | error_go_core |
|
|
dict (nunca lanza): {status: 'ok'|'error', pdf_path: str|None, n_pages: int, note: str}. En éxito status='ok', pdf_path es la ruta del PDF escrito (<base_dir>/out/paper.pdf) y n_pages el total de páginas. En error status='error', pdf_path=None, n_pages=0 y note explica la causa (paper.md no encontrado, fallo del motor, o excepción inesperada). | true |
|
python/functions/datascience/render_paper_pdf_test.py | python/functions/datascience/render_paper_pdf.py |
Ejemplo
from datascience import render_paper_pdf
# Estructura del paper:
# papers/zz-demo/paper.md (frontmatter YAML + cuerpo IMRaD)
# papers/zz-demo/figures/fig1.png (figuras referenciadas con )
#
# paper.md:
# ---
# title: A Minimal IMRaD Paper
# authors: [Ada Lovelace, Alan Turing]
# date: 2026-06-30
# abstract: Demostramos que el motor pagina un paper sin cortar nada.
# ---
# # Introduction
# Texto con **negrita** y una lista:
# - Punto uno.
# 
# # Methods
# | Métrica | Valor |
# | --- | --- |
# | Precisión | 0.91 |
res = render_paper_pdf("papers/zz-demo")
print(res["status"], res["n_pages"], res["pdf_path"])
# -> ok 3 papers/zz-demo/out/paper.pdf
# También acepta la ruta directa al .md:
render_paper_pdf("papers/zz-demo/paper.md")
Cuando usarla
Cuando tengas un paper académico (o cualquier documento IMRaD) escrito en
Markdown y quieras un PDF móvil A5 listo para leer, sin montar LaTeX ni
configurar un pipeline de pandoc. Úsala después de redactar paper.md con su
frontmatter (título, autores, fecha, abstract) y secciones de nivel 1; obtienes
out/paper.pdf con portada, una página nueva por sección IMRaD, tablas que se
parten repitiendo la cabecera y figuras escaladas para caber enteras —
garantía de no-corte heredada del motor automatic_eda. Es la capa de
presentación PDF del grupo papers.
Gotchas
- Impura: escribe
out/paper.pdf(y crea el directorioout/) junto alpaper.md. Necesita matplotlib instalado en el venv (lo usa el motorautomatic_eda.render_pdfcon backend headlessAgg; corre en agentes/CI sin display).pyyamles opcional: si falta, el frontmatter se parsea con un parser line-basedclave: valordegradado. - Reutiliza el motor
automatic_eda.render_pdf: NO reimplementa paginación ni toca matplotlib.render_pdfno tiene ID propio en el registry (es parte del paquete de soporteautomatic_eda), por esouses_functionsqueda vacío; la dependencia real es ese motor del paquete. - Nunca lanza (dict-no-throw):
paper.mdinexistente →{status:"error", pdf_path:None, note:"paper.md no encontrado: ..."}; cualquier excepción inesperada →{status:"error", note:"fallo: ..."}. Frontmatter ausente o incompleto degrada limpio (sin portada, el cuerpo entero se pagina). - Figuras relativas a
figures/: elsrcdese resuelve probando<base_dir>/<src>y<base_dir>/figures/<basename>; usa el primero que exista. Si ninguno existe, el motor degrada dibujando "(imagen no encontrada: ...)" — el PDF se genera igual, no crashea. Las URLshttp(s)se dejan como texto Markdown, no se descargan. - Solo imágenes en línea propia: el motor
_place_markdownNO entiende; esta función solo convierte aImagelas líneas cuyo único contenido es la imagen. Una imagen embebida a mitad de un párrafo se quedaría como texto crudo. - A5 portrait mobile-first: el formato (tamaño de página, tipografía, pie
Capítulo · vX.Y.Z) lo fija el motor EDA y no es configurable desde aquí.