ConvertToPDFA convierte un documento ordinario en archivable con una sola llamada: elimina lo que prohíbe la parte elegida, añade lo que exige, declara la parte que reclama el documento y después comprueba el resultado. La reclamación solo se notifica como cumplida cuando la comprobación pasa, y GetPDFAConversionReport detalla qué se ha hecho y qué sigue interponiéndose
Esa última propiedad es la decisión de diseño sobre la que merece la pena detenerse. Un conversor que estampa la reclamación sin comprobarla es peor que no tener conversor alguno, porque un archivo que dice ser archivable y no lo es atraviesa justamente los sistemas que de otro modo lo habrían detectado. El fallo aflora años después, en una auditoría, sobre un documento que nadie puede regenerar
¿Por qué un PDF con buen aspecto no supera una comprobación PDF/A?
La mayoría de las veces porque los dos lugares en los que un PDF dice quién lo escribió no coinciden. Un validador lee tanto el diccionario de información del documento como el paquete XMP y rechaza el archivo cuando difieren —y la mayoría de los archivos que fallan en este punto simplemente nunca llegaron a tener escrita la mitad XMP—
RepairDocumentMetadata los pone de acuerdo y devuelve cuántas entradas ha reparado. Cuando solo una mitad lleva un valor, la otra se rellena a partir de ella, así que no se descarta nada ya registrado. Nadie tiene que decidir qué copia es la autoritativa, porque en la práctica una copia está vacía
Hay una segunda reparación en la misma llamada que atrapa un caso más sutil. Un documento fijado a un modo PDF/A recupera su identificación de normas si se había perdido, lo que ocurre siempre que un llamador suministra un paquete XMP propio. Sin esa identificación un validador lee el archivo como un PDF ordinario e informa de que no se cumple ninguna regla de la parte reclamada —un fallo de aspecto espectacular con una causa minúscula—
var
Lib: TPDFlib;
Repaired: Integer;
begin
Lib := TPDFlib.Create;
try
Lib.LoadFromFile('incoming.pdf', '');
Repaired := Lib.RepairDocumentMetadata;
Log(Format('%d metadata entries brought into agreement', [Repaired]));
Lib.SaveToFile('incoming-fixed.pdf');
finally
Lib.Free;
end;
end;
Elegir la parte antes de convertir
SetPDFAMode y ConvertToPDFA comparten la misma numeración de modos, y tres de los valores son recientes. El modo 9 es PDF/A-4, la parte construida sobre PDF 2.0. El modo 10 es PDF/A-4e, que además permite 3D y multimedia enriquecida, y el modo 11 es PDF/A-4f, que permite un archivo incrustado de cualquier formato
La parte 4 se identifica de forma distinta a las anteriores: por número de parte y por el año de publicación de su parte, sin letra de conformidad para el PDF/A-4 puro y con la letra E o F para las dos extensiones. La comprobación reconoce la parte 4, juzga sus archivos frente a PDF 2.0 en lugar de 1.7, e informa de un archivo de parte 4 que no declara su año de revisión
Cada archivo incrustado en un documento de parte 4 declara cómo se relaciona con el documento, tal como exigen tanto la parte 3 como la 4. Esta es la regla que antes atrapaba los adjuntos ordinarios: la relación se escribía solo para los adjuntos posteriores al primero y nunca para el último, así que un documento con un único adjunto —el caso habitual— no portaba ninguna y fallaba la validación precisamente en ese punto
var
Verdict: Integer;
begin
Lib.LoadFromFile('report.pdf', '');
Verdict := Lib.ConvertToPDFA(9); // 9 = PDF/A-4, 10 = 4e, 11 = 4f
Memo1.Lines.Text := Lib.GetPDFAConversionReport;
if Verdict = 1 then
Lib.SaveToFile('report-pdfa4.pdf')
else
Log('conversion incomplete - see the report for what stands in the way');
end;
Para qué sirve el informe de conversión
Para decidir qué hacer a continuación. Una conversión que tiene éxito no necesita informe; una que no lo tiene es toda la razón de que el informe exista. Algunos obstáculos los puede retirar un conversor y otros no —el cifrado, el contenido prohibido que porta significado, un programa de fuente que simplemente no está en ninguna parte de la máquina—. El informe distingue lo que se ha hecho de lo que queda, lo que convierte «la conversión ha fallado» en una tarea concreta
Trata el veredicto como la puerta de paso en un flujo por lotes. Convierte, lee el veredicto y encamina el archivo: archiva los que pasaron, coloca el resto en cola para una persona con el informe adjunto. Lo que no debes hacer es guardar la salida de una conversión fallida en el archivo porque quede mejor que la entrada —ahora porta una reclamación que la comprobación se negó a confirmar—
Leer la marca que un archivo ya porta
Antes de convertir nada, conviene saber qué dice el documento sobre sí mismo. Una comprobación PDF/A incapaz de leer la marca de normas existente juzga cada archivo contra la parte 1 sea cual sea su declaración, lo que significa que un documento PDF/A-2 o PDF/A-3 perfectamente válido se reporta como carente de marca y con una versión excesiva —justo lo contrario de la verdad—
La marca se lee tanto si el productor la escribió como un elemento XMP como si lo hizo como un atributo. Ambas formas son XMP corriente, y aceptar solo una deja los archivos de otros productores con aspecto de no marcados. Si alguna vez te has preguntado por qué un documento que valida en otras partes falla en tu propio flujo, este es un buen lugar donde mirar primero
Saneamiento antes de archivar, y el fallo que vale la pena conocer
La conversión archivable y el saneamiento suelen ir juntos, porque el contenido que una política de seguridad quiere retirar se solapa ampliamente con el que prohíbe PDF/A. SanitizeDocument elimina JavaScript, y eliminar el último script elimina también el árbol de nombres vacío que este deja atrás —un árbol que de otro modo seguiría diciendo a un lector que el documento portaba scripts—
Esa segunda mitad se aprendió por las malas: un error de uno en la lista de paquetes hacía que el saneamiento informara de que eliminaba scripts mientras no eliminaba ninguno, así que un documento saneado seguía ejecutando sus scripts al abrirse. Es un buen argumento a favor del principio general en el que se apoya todo este artículo —verifica el resultado en lugar de confiar en la operación, tanto en tu propio flujo como en la librería—
Para el trabajo archivable colindante, consulta los recorridos por el preflight PDF/A y PDF/UA, la redacción real y la eliminación de contenido y los esquemas de extensión XMP de PDF/A-3 para Factur-X, que cubre el lado de los metadatos cuando el documento archivado también porta datos estructurados de factura
PDFlibPas es una librería PDF nativa en Pascal para Delphi, C++Builder y Lazarus, así que la conversión, la reparación y la validación ocurren íntegramente dentro de tu propio proceso sin ninguna herramienta externa en la cadena; consulta la página del producto PDFlibPas para las partes PDF/A soportadas y las plataformas