#!/usr/bin/env bash # init_paper # ---------- # Scaffold de un paper académico reproducible en papers//. # # Calcula el siguiente número incremental escaneando papers/, crea el # directorio con todas las subcarpetas (experiments data figures reviews out), # copia las plantillas paper.md + preregistration.md rellenando el frontmatter # (title, slug, date de hoy, phase=question, status=draft) y crea references.md. # # NO hace `git init`: el paper arranca en fase interna local (papers/ está # gitignored en el repo padre, solo .gitkeep se versiona). La promoción a # sub-repo Gitea (fase publishable) es un paso posterior MANUAL. # # Compone: next_numbered_dir (helper de numeración del registry) + # slugify_ascii (slug ASCII del registry). # # USO: # ./init_paper.sh [--title "..."] [--domain ] [--tags a,b,c] # # EJEMPLOS: # ./init_paper.sh mi-primer-paper --title "Mi primer paper" # ./init_paper.sh reactive-loop-calls --domain datascience --tags registry,telemetria set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" REGISTRY_ROOT="$(cd "$SCRIPT_DIR/../../.." && pwd)" # Funciones atómicas del registry source "$REGISTRY_ROOT/bash/functions/io/next_numbered_dir.sh" # ── Parsing de argumentos ──────────────────────────────────── SLUG_RAW="" TITLE="" DOMAIN="datascience" TAGS="" while [ $# -gt 0 ]; do case "$1" in --title) TITLE="$2"; shift 2 ;; --domain) DOMAIN="$2"; shift 2 ;; --tags) TAGS="$2"; shift 2 ;; -h|--help) grep "^#" "$0" | sed 's/^# \?//' ; exit 0 ;; -*) echo "Flag desconocido: $1" >&2 ; exit 1 ;; *) if [ -z "$SLUG_RAW" ]; then SLUG_RAW="$1" else echo "ERROR: argumento posicional inesperado: '$1' (solo se admite un )." >&2 exit 1 fi shift ;; esac done if [ -z "$SLUG_RAW" ]; then echo "ERROR: falta el argumento ." >&2 echo "Uso: $0 [--title \"...\"] [--domain ] [--tags a,b,c]" >&2 echo " Ejemplo: $0 mi-primer-paper --title \"Mi primer paper\"" >&2 exit 1 fi # ── Slugificar (reutiliza slugify_ascii del registry; solo stdlib) ── PYBIN="$REGISTRY_ROOT/python/.venv/bin/python3" [ -x "$PYBIN" ] || PYBIN="$(command -v python3 || true)" if [ -z "$PYBIN" ]; then echo "ERROR: no se encontró python3 para slugificar el slug." >&2 exit 1 fi SLUG_CLEAN=$("$PYBIN" -c ' import sys, os sys.path.insert(0, os.path.join(sys.argv[2], "python", "functions")) from core.slugify_ascii import slugify_ascii print(slugify_ascii(sys.argv[1], default="paper")) ' "$SLUG_RAW" "$REGISTRY_ROOT") # ── Resolver número incremental y directorio destino ───────── PAPERS_DIR="$REGISTRY_ROOT/papers" mkdir -p "$PAPERS_DIR" NUM=$(next_numbered_dir "$PAPERS_DIR") SLUG_FULL="${NUM}-${SLUG_CLEAN}" PAPER_DIR="$PAPERS_DIR/$SLUG_FULL" if [ -d "$PAPER_DIR" ]; then echo "ERROR: el directorio del paper ya existe: $PAPER_DIR" >&2 exit 1 fi TODAY=$(date +%Y-%m-%d) [ -n "$TITLE" ] || TITLE="$SLUG_CLEAN" TAGS_YAML="[]" if [ -n "$TAGS" ]; then TAGS_YAML="[$(echo "$TAGS" | sed 's/,/, /g')]" fi echo "" echo "════════════════════════════════════════════════════════════" echo " INIT PAPER: ${SLUG_FULL}" echo " Título: ${TITLE}" echo " Directorio: ${PAPER_DIR}" echo "════════════════════════════════════════════════════════════" echo "" # ── Crear estructura ───────────────────────────────────────── echo "[1/3] Creando estructura..." mkdir -p "$PAPER_DIR"/experiments "$PAPER_DIR"/data "$PAPER_DIR"/figures \ "$PAPER_DIR"/reviews "$PAPER_DIR"/out echo " experiments/ data/ figures/ reviews/ out/" # ── Copiar plantillas + rellenar frontmatter ───────────────── echo "[2/3] Escribiendo paper.md + preregistration.md..." # Escapa caracteres especiales del RHS de sed (delimitador |) sed_escape() { printf '%s' "$1" | sed -e 's/[\\&|]/\\&/g'; } TITLE_ESC="$(sed_escape "$TITLE")" DOMAIN_ESC="$(sed_escape "$DOMAIN")" PAPER_MD="$PAPER_DIR/paper.md" PREREG_MD="$PAPER_DIR/preregistration.md" cp "$REGISTRY_ROOT/docs/templates/paper.md" "$PAPER_MD" cp "$REGISTRY_ROOT/docs/templates/preregistration.md" "$PREREG_MD" sed -i \ -e "s|^title:.*|title: \"${TITLE_ESC}\"|" \ -e "s|^slug:.*|slug: ${SLUG_FULL}|" \ -e "s|^date:.*|date: ${TODAY}|" \ -e "s|^domain:.*|domain: ${DOMAIN_ESC}|" \ -e "s|^tags:.*|tags: ${TAGS_YAML}|" \ "$PAPER_MD" sed -i \ -e "s|^paper_slug:.*|paper_slug: ${SLUG_FULL}|" \ "$PREREG_MD" echo " $PAPER_MD" echo " $PREREG_MD" # ── references.md ──────────────────────────────────────────── echo "[3/3] Escribiendo references.md..." cat > "$PAPER_DIR/references.md" << EOF # References — ${TITLE} EOF echo " $PAPER_DIR/references.md" # ── Resumen ────────────────────────────────────────────────── echo "" echo "════════════════════════════════════════════════════════════" echo " PAPER '${SLUG_FULL}' LISTO (fase: question, status: draft)" echo "════════════════════════════════════════════════════════════" echo "" echo " Pasos siguientes:" echo " 1. Revisión de literatura (skill /deep-research) → Related work." echo " 2. Pre-registro: congela H0/H1 + plan en preregistration.md (preregister_hypothesis)." echo " 3. Experimentos en experiments/ → análisis (grupo eda) → escritura IMRaD en paper.md." echo " 4. render_paper_pdf → out/paper.pdf. Peer review adversarial → reviews/." echo "" echo " papers/ está gitignored: este paper vive local hasta promocionar a publishable." echo ""