#!/usr/bin/env python3
"""Genera vedabase_archive.tex (→ PDF con XeLaTeX) desde /tmp/pdfdata/.
Incluye: título de libro, título de capítulo (derivado del ref), traducción (negrita), purport.
EXCLUYE verso/transliteración/devanagari/bengalí/sinónimos.
Formato: 8pt, interlineado 1, márgenes 1.5cm, sin líneas en blanco. DejaVu Serif (IAST)."""
import json, re, glob, os

DATA='/tmp/pdfdata'
TEX='vedabase_archive.tex'
MPL='/System/Library/Fonts/Supplemental'

BOOK_TITLES={
 'bg':'Bhagavad-gītā As It Is','iso':'Śrī Īśopaniṣad','sb':'Śrīmad-Bhāgavatam',
 'cc':'Śrī Caitanya-caritāmṛta','kb':'Kṛṣṇa, the Supreme Personality of Godhead',
 'nod':'The Nectar of Devotion','tlc':'Teachings of Lord Caitanya','noi':'The Nectar of Instruction',
 'ssr':'The Science of Self-Realization','tqk':'Teachings of Queen Kuntī','pop':'The Path of Perfection',
 'rv':'Rāja-Vidyā: The King of Knowledge','pqpa':'Perfect Questions, Perfect Answers',
 'ttp':'Kṛṣṇa Consciousness: The Topmost Yoga System','ekc':'Elevation to Kṛṣṇa Consciousness',
 'ej':'Easy Journey to Other Planets','lob':'Light of the Bhāgavata','owk':'On the Way to Kṛṣṇa',
 'poy':'The Perfection of Yoga','bbd':'Beyond Birth and Death','krp':'Kṛṣṇa, the Reservoir of Pleasure',
 'lcfl':'Life Comes from Life'}
LILA={'adi':'Ādi-līlā','madhya':'Madhya-līlā','antya':'Antya-līlā'}

def esc(s):
    s=s.replace('\\','\x00')
    for a,b in [('{',r'\{'),('}',r'\}'),('$',r'\$'),('&',r'\&'),('#',r'\#'),
                ('_',r'\_'),('%',r'\%'),('~',r'\textasciitilde{}'),('^',r'\textasciicircum{}')]:
        s=s.replace(a,b)
    return s.replace('\x00',r'\textbackslash{}')

def clean(t):
    if not t: return ''
    t=t.replace('**','')
    t=re.sub(r'\*([^*\n]+)\*', r'\1', t)
    t=re.sub(r'^\s*#+\s*', '', t, flags=re.M)
    t=t.replace('((','').replace('))','')
    t=re.sub(r'^\s*>\s*', '', t, flags=re.M)
    t=re.sub(r'[ \t]+',' ', t)
    t=re.sub(r'\n\s*\n+', '\n', t)
    return t.strip()

def paras(t):  # cada bloque (separado por \n) -> párrafo
    return [p.strip() for p in t.split('\n') if p.strip()]

def keep(ref):
    # Excluir lo que NO es de Prabhupāda: SB termina en Canto 10, Cap. 13.
    # Caps. 10.14–10.90 y Cantos 11–12 fueron completados por discípulos.
    p=ref.split('/')
    if p[0]=='sb' and len(p)>=3 and p[1].isdigit() and p[2].isdigit():
        canto,chap=int(p[1]),int(p[2])
        if canto>10 or (canto==10 and chap>=14): return False
    return True

SORTKEY=re.compile(r'0[a-z]?|notes', re.I)

def label_is_sortkey(ref):
    """True si el último segmento del ref es una clave de orden interna, no un
    número de verso: 0, 0a..0d (prefacio/dedicatoria/introducción…) y 'notes'.
    Las numeraciones reales con letra (1b, 2b, 1a-2a) NO entran aquí."""
    return bool(SORTKEY.fullmatch(ref.split('/')[-1]))

def chapter_label(ref):
    p=ref.split('/'); b=p[0]
    if b=='sb' and len(p)>=3 and p[1].isdigit() and p[2].isdigit(): return f"Canto {p[1]}, Chapter {p[2]}"
    if b=='cc' and len(p)>=3 and p[2].isdigit(): return f"{LILA.get(p[1],p[1])}, Chapter {p[2]}"
    if b=='bg' and len(p)>=2 and p[1].isdigit(): return f"Chapter {p[1]}"
    return None

PRE=r'''\documentclass[8pt,twocolumn]{extarticle}
\usepackage{fontspec}
%% Arial, no Times, desde el 22-ago-2026. Lo pidio Bruce y las medidas le dan
%% la razon por un motivo mas fuerte que la comodidad: el limite de Abbe. Un
%% objetivo no resuelve detalle mas fino que lambda/2NA, y un 40x seco —lo que
%% tendra quien encuentre el disco— llega a 0,42 µm. En Times el trazo mas fino
%% de la letra queda en 0,38 µm sobre el metal: 0,90 veces el limite, o sea que
%% NO se resuelve. Los remates y los adelgazamientos se vuelven niebla y una «e»
%% pasa a «c». Con Arial el rasgo mas fino —contando el blanco de dentro de la
%% letra, no solo el trazo— son 0,57 µm, 1,35 veces ese limite.
%%
%% Cuesta un 10 por ciento mas de paginas, porque Arial es mas ancha. No se compensa
%% bajando el cuerpo: eso devolveria el problema. Y no cuesta fidelidad, porque
%% este archivo ya era una recomposicion del texto del repo, no una reduccion
%% fotografica de la pagina impresa.
%%
%% Arial y Helvetica son las UNICAS palo seco del sistema con IAST completo en
%% los cuatro cortes. Tahoma y Microsoft Sans Serif no tienen cursiva, y el
%% texto la usa sin parar para el sanscrito, que es justo donde van los
%% diacriticos. Verdana y Gill Sans se dejan 19 de los 29. La Franklin Gothic
%% que propuso Bruce se deja 27: no tiene ni un glifo en U+1E00-1EFF.
\setmainfont{Arial}[
  Path = %s/ ,
  Extension = .ttf,
  UprightFont = Arial,
  BoldFont = Arial Bold,
  ItalicFont = Arial Italic,
  BoldItalicFont = Arial Bold Italic ]
\usepackage[margin=5mm]{geometry}
\setlength{\columnsep}{1.0em}
\usepackage{microtype}
\usepackage{fancyhdr}
\setlength{\parindent}{1em}
\setlength{\parskip}{0pt}
\linespread{1.0}
\setlength{\emergencystretch}{3em}
\hyphenpenalty=100 \tolerance=2000
\pagestyle{empty}
\newcommand{\booktitle}[1]{\par\vspace{1.0em}{\centering\fontsize{13}{15}\selectfont\bfseries #1\par}\vspace{0.5em}\nopagebreak}
\newcommand{\chap}[1]{\par\vspace{0.4em}{\fontsize{10}{12}\selectfont\bfseries #1\par}\nopagebreak}
\begin{document}
\fontsize{8}{9.2}\selectfont
'''%MPL

def main():
    files=sorted(glob.glob(f'{DATA}/*.json'))
    out=[PRE]; nv=0
    for f in files:
        d=json.load(open(f)); rows=d[0]['results'] if isinstance(d,list) else d['results']
        if not rows: continue
        book=rows[0]['ref'].split('/')[0]
        out.append(f"\\booktitle{{{esc(BOOK_TITLES.get(book,book))}}}\n")
        cur=None
        for r in rows:
            ref=r['ref']
            if not keep(ref): continue
            tr=clean(r.get('translation')); pu=clean(r.get('purport'))
            ch=chapter_label(ref)
            if ch and ch!=cur:
                cur=ch; out.append(f"\\chap{{{esc(ch)}}}\n")
            vn=esc(ref.split('/')[-1])
            if tr:
                # Las claves de orden del material preliminar (0, 0a..0d) y 'notes'
                # no son numeración de verso: en el impreso no llevan rótulo. Sin
                # ellas "0a Foreword" queda simplemente "Foreword".
                if label_is_sortkey(ref):
                    out.append("\\par\\textbf{%s}\n"%esc(tr))
                else:
                    out.append("\\par\\textbf{%s~~%s}\n"%(vn, esc(tr)))
            for p in paras(pu):
                out.append("\\par "+esc(p)+"\n")
            nv+=1
    out.append("\\end{document}\n")
    open(TEX,'w').write(''.join(out))
    print(f"{TEX} escrito: {nv} versos, {os.path.getsize(TEX)//1024//1024} MB")

main()
