Un PDF es un contenedor, no una hoja de papel
Un PDF puede llevar archivos enteros dentro, en un árbol de nombres que la página nunca enseña. Cómo funcionan los adjuntos, por qué existe PDF/A-3 y qué se rompe.
Casi todo el mundo se imagina un PDF como un taco de folios impresos que resulta que vive en un ordenador. Es un modelo mental razonable y falla justo donde importa. Un PDF es un contenedor. Las páginas son una de las cosas que guarda, junto con las fuentes, los perfiles de color, los metadatos, la definición de los formularios, los marcadores y, si quieres, archivos enteros de cualquier tipo.
Eso último es lo menos conocido y lo más aprovechable. Una hoja de cálculo, un documento XML, una carpeta entera de mediciones en bruto: todo eso puede vivir dentro del PDF, viajar con él y volver a salir en cualquier lector. En files.co se hace desde el navegador con adjuntar archivos a un PDF, y merece la pena saber qué le pasa de verdad al archivo cuando lo haces.
Dónde vive un adjunto
Todo PDF tiene un catálogo, el objeto raíz que dice dónde está cada cosa. Colgando de él puede haber un árbol de nombres, y dentro una rama llamada /EmbeddedFiles. Esa rama asocia nombres con especificaciones de archivo, y cada especificación apunta a un stream con los bytes de tu adjunto, comprimidos.
Un árbol de nombres no es una lista plana. La especificación permite que sea un árbol de verdad: un nodo raíz con /Kids apuntando a nodos intermedios, cada uno cubriendo un tramo alfabético de los nombres, para que un lector encuentre una entrada entre miles sin recorrerlas todas. En documentos pequeños suele haber un único nodo con un array /Names plano. En los grandes, o en los que produce un sistema que espera guardar muchos adjuntos, aparece la versión ramificada.
Por eso los adjuntos salen en el panel del clip del lector y no en una página. Se referencian desde la estructura del documento, no desde el contenido de la página. No se dibuja nada, no se descoloca nada y la maquetación queda intacta. Quien no abra ese panel no sabrá nunca que están ahí.
El fallo que se lleva por delante los adjuntos antiguos
Aquí es donde la estructura del árbol deja de ser una curiosidad. Si añades un adjunto a un PDF que ya tenía otros, una librería que se limite a añadir al final puede crear un array /Names justo al lado del /Kids que ya existía. Un nodo con las dos claves es inválido. Cada lector hace lo que le parece con un nodo inválido, y lo habitual es que el panel enseñe solo los adjuntos recién añadidos mientras los anteriores desaparecen de la vista. Los bytes siguen dentro del archivo, pero nadie llega a ellos.
Es un fallo feo porque tiene toda la pinta de haber ido bien. Adjuntaste el archivo, el archivo está, mandaste el documento. Y los tres adjuntos que había metido la persona anterior ya no aparecen en ningún panel que lo abra.
El motor que hay detrás de nuestra herramienta aplana el árbol en un único array /Names ordenado antes de adjuntar, para que las entradas nuevas caigan en el mismo array que las viejas, y lo vuelve a ordenar después, porque la especificación pide las entradas ordenadas por clave y añadir al final no respeta ese orden. Un arreglo poco lucido para un problema que descubrirías meses más tarde.
PDF/A-3 y la factura híbrida
Los adjuntos son además el motivo de que exista un estándar de archivado concreto. Como contamos en PDF/A, explicado, PDF/A-2 apretó el formato hasta dejarlo lo bastante predecible como para archivar durante décadas. PDF/A-3 es casi el mismo estándar con una relajación puesta a propósito: permite incrustar archivos arbitrarios de cualquier tipo junto a las páginas archivadas.
Ese cambio es la base de la factura electrónica híbrida. Una factura Factur-X o ZUGFeRD es un solo archivo que a la vez es una página legible por una persona y un documento XML legible por una máquina, porque el XML viaja dentro del PDF/A-3. Sin parejas de archivos, sin nombres que cuadrar y sin el riesgo de que las dos mitades acaben diciendo cosas distintas después de que alguien toque una.
El estándar tiene además un campo para declarar por qué va adjunto un archivo: si es la fuente de la que salió el documento, datos complementarios, una representación alternativa y demás. Nuestra herramienta lo deja como “sin especificar” por defecto en vez de adivinar, porque afirmar que una hoja de cálculo es la fuente autorizada de un documento sin tener ni idea es peor que reconocer que no lo sabemos. Si necesitas conformidad con un perfil de archivado concreto, convertir a PDF/A es otro paso distinto con sus propias reglas.
Comprimir no es cifrar
El stream incrustado va comprimido con Flate. Eso es una optimización de tamaño y nada más. Un adjunto dentro de un PDF no está cifrado, y cualquiera que tenga el archivo lo saca en un par de clics.
Conviene decirlo en voz alta porque la metáfora del contenedor empuja a pensar lo contrario: lo que está “dentro” de algo parece protegido, y no lo está. Trata un adjunto exactamente igual que el adjunto de un correo, porque en cuanto a quién puede leerlo es justo lo mismo. Si tienes la costumbre de dar un repaso antes de que salga un documento, los adjuntos van en esa lista al lado de los metadatos; el resto lo tienes en qué revisar antes de enviar un PDF.
Qué te llevas exactamente
Antes de modificar nada, la herramienta lista lo que el documento ya lleva, con nombres y tamaños reales, y te deja descargarlo. Los adjuntos existentes se conservan siempre. Un archivo nuevo cuyo nombre choque con uno antiguo se numera en lugar de pisar nada.
El techo práctico son veinte archivos y 50 MB por pasada, menos en iPhone porque el navegador da mucha menos memoria a una pestaña. Cuenta con que el documento engorde más o menos lo que ocupen los adjuntos comprimidos, que en CSV o XML es poquísimo y en un JPEG o un zip es casi el tamaño entero, porque eso ya venía apretado.
Una negativa que conviene conocer: un PDF protegido con contraseña se rechaza en lugar de reescribirse medio a ciegas. Y el soporte varía en el otro extremo. Los lectores de escritorio manejan bien los adjuntos, los de móvil muchas veces ni enseñan el panel, así que si quien lo recibe va con el teléfono, dile qué lleva dentro en vez de dar por hecho que verá el clip.