Cómo recolectar las palabras en negrita de un PDF

Screenshot-A-Ama-1-10.pdf Ése es el problema: tengo un PDF con un texto. Algunas de las palabras de ese texto están en negrita. Quiero crear un script que recoja todas esas palabras. ¿Cómo lo hago? Supongo que habrá varios métodos, a mí se me ha ocurrido éste:

Abrir el PDF con OpenOffice.org (con el soporte de importar y editar PDF’s activado). Se abrirá en Draw. Incluir la siguiente macro en StarBasic. Ejecutar la macro. El meollo de la cuestión estriba en que dicha macro recorre todos los elementos de texto del fichero recién cargado y cada vez que encuentre un trozo en negrita, es decir se cumple que:

if (oTextPortion.charWeight > 100) then

añadirá ese trozo o palabra a una hoja de cálculo (en Calc). Yo lo he probado con este extracto de fichero PDF (extraído del Orotariko Euskal Hiztegia, porque necesitaba la lista de palabras de ese diccionario…)

a2ps y pdftotext: de ASCII a PS y de PDF a texto

Pequeñas herramientas que me hacen la vida más fácil.

a2psa2ps , una aplicación que permite convertir texto ascii en postscript, con formateado de sintaxis (en blanco y negro y con diferentes tamaños de letra) para multitud de lenguajes de programación. El resultado se puede imprimir directamente por impresora, porque la calidad es muy buena. Además, permite imprimir a 2×2, 2×1, etc., en modo dúplex, en color… Genial.

ScreenshotLa siguiente es pdftotext, otra pequeña gran herramienta que nos permite analizar parsear el contenido de un pdf y convertirlo a texto ascii, manteniendo la estructura (lo más posible y siempre que usemos la opción -layout) del pdf original. Por ejemplo, si pasamos pdftotext al fichero PDF con las primeras entradas del diccionario en Euskera Orotariko Euskal Hiztegia, obtendremos una buena reproducción en ascii, con el contenido intacto y la estructura bastante similar.
vim

Lo dicho, dos herramientas más para la toolbox.

OpenOffice.org ecológico con FSniper

Curioso título para un post, ¿a que sí? A diario tengo que imprimir algunas presentaciones y material didáctico para mis clases y quiero consumir el mínimo papel posible (¿llegará un día en el que los alumnos puedan tener sus netbooks en clase sin que nadie se escandalice?). Lo que suelo hacer es imprimir las presentaciones a 2×2, a doble cara. Es decir, 4 diapositivas por cada cara de la hoja. Parece sencillo, pero en OpenOffice.org Impress eso de imprimir a 2×2 no es sencillo. ¿Cómo? ¿he oído handout?. Efectivamente, la pestaña handout de Impress se supone que permite configurar cómo queremos imprimir las diapositivas. De hecho, en OOo 2.x funcionaba perfectamente siguiendo estos pasos. Pero héte aquí que a alguien se le ocurrió que esa no era una buena forma de funcionar. Por lo que «mejoró» la funcionalidad (Issue 85355: Enhance handout printing in impress) y decidió que lo de modificar el handout a mano era una chapucilla, así que, «dejamos la pestaña de handout accesible pero cuando el usuario le dé a imprimir, pues… no hará caso a lo que diga el handout». Qué majos los developers…

Así que la gente se ha enfadado y ha montado el numerito (el 94055 para ser exactos 😉
Issue 94055: Can no longer print handouts with customized size and arrangement of the preview objects

Vale, después de todo este rollo, «¡una solución quiero!». Enter FSniper. Esta aplicación puede verse como un monitorizador de la actividad en disco (de una o varias carpetas del disco). Cada vez que entre algún fichero de interés en la carpeta que queramos monitorizar, FSniper «saltará». ¿Y qué hará? Lo que le digamos. Por ejemplo: quiero que FSniper monitorice la carpeta /tmp/pdf . Cada vez que guarde un PDF en esa carpeta, quiero que FSniper ejecute el siguiente comando:

$ pdfnup --nup 2x2 --frame true --outfile /tmp/2x2/fichero-2x2.pdf  fichero.pdf

PDFNup es una de esas pequeñas joyas de los sistemas Unix que hacen su trabajo a la perfección: recoge un fichero.pdf y lo convierte en otro a 4 páginas por cara (2×2), enmarcando (frame) cada cuadrante (es sólo un ejemplo… «man» es vuestro amigo)

Así que, repasando, cuando FSniper detecta un nuevo PDF (normal, a 1 página por cada cara) en la carpeta /tmp/pdf queremos que lo pase por el comando pdfnup, lo convierta a 2×2 y lo deje en la carpeta /tmp/2×2 .

Bien, para hacer justamente eso, basta con instalar FSniper:

$ sudo apt-get install fsniper

y configurarlo (editar el fichero ~/.config/fsniper/config )

watch {
	/tmp/pdf {
		*.pdf {
			handler = pdfnup --nup 2x2 --frame true --outfile /tmp/2x2/`basename %%`  %%
		}
	}	
}

Nota 1: basename es necesario para recoger únicamente el nombre del fichero, y no su ruta completa.
Nota 2: no olvidarse de lanzar fsniper:

$ fsniper --daemon

Nota 3: si el directorio /tmp es compartido, igual no te interesa que lo que imprimas se quede ahí…

Ahora viene la magia: desde OpenOffice.org Impress, pulsamos en el botoncito de «Exportar a PDF». Elegimos la carpeta /tmp/pdf y guardamos. Abrimos con nuestro explorador de archivos la carpeta /tmp/2×2 y ahí tendremos a nuestro flamante PDF a 2×2, convertido por arte de magia por FSniper.

Obviamente lo que comento es sólo la punta del iceberg. Las posibilidades son infinitas (¿por qué no compartir la carpeta /tmp/pdf y /tmp/2×2 en la red y ofrecer el servicio para toda la LAN? ¿y un script que lo suba automáticamente a Moodle? y…)

Soporte de anotaciones en Evince

Hace un par de días recibí un email con el ChangeLog de Evince 2.27.1 . Entre esas novedades, una que me ha hecho bajar el código de Poppler, compilarlo, bajar el código de Evince, compilarlo e irme a dormir tranquilo, por fin, tras varios años esperando este momento 🙂

* Preliminary annotations support (#315002, Carlos Garcia Campos, Iñigo Martínez)

¡Soporte de anotaciones en Evince! Por el momento muy rudimentario, sólo permite visualizar las anotaciones de un PDF (ni crearlas ni editarlas), pero algo es algo. ¡Felicidades a Iñigo y a Carlos! Se lo han currado…

Protecciones idiotas

No entiendo la dichosa manía que tienen algunos de usar formularios PDF para hacernos rellenar información vía web y hacer que éstos formularios NO PERMITAN ser guardados CONSERVANDO lo que has tecleado en los campos. Es algo que me saca de mis casillas. Más aún cuando esos formularios provienen de la administración pública (tercera vez que me pasa). Ni qué decir tiene que cuando protegen el PDF para que no pueda ser impreso o ni siquiera para permitir el copy&paste del texto, siendo, repito, un PDF expresamente orientado a que los ciudadanos/usuarios lo rellenen, cumplimenten o copien, es como para desquiciarse. ¿Lo hacen aposta? O lo que es peor, ¿ni siquiera saben lo que están haciendo? ¿Publican ficheros PDF protegidos sin tener ni la más remota idea de qué es eso de «protegidos» o qué botoncito hay que pulsar en su querido Adobe Acrobat/Adobe Live Cycle para hacerlos accesibles?

¿Saben que lo que hacen es una protección que NO SIRVE MÁS QUE PARA MOLESTAR porque puede ser saltada fácilmente?

Hoy me he encontrado en la necesidad de rellenar uno de esos formularios PDF del diablo, protegido para que no se puedan guardar los textos que ya has tecleado en los campos correspondientes (¿he dicho ya que esto es una protección idiota?). La solución parecía trivial: lo cumplimento, lo imprimo a fichero .ps y luego lo convierto a .pdf. Nada más lejos de la realidad:

$ ps2pdf ficherodeldiablo.ps
This PostScript file was created from an encrypted PDF file.
Redistilling encrypted PDF is not permitted.

¿QUÉÉÉÉÉÉÉÉÉ?  ¿Un postscript protegido? ¿Nos hemos vuelto todos locos o qué?

Bien, la segunda idea:  abrimos el .ps con el GIMP, lo guardamos como .ps con otro nombre y volvemos a intentarlo. Nones. El GIMP (2.6) se cuelga con el ficherodeldiablo.ps.

Vale, saquemos las armas gordas:

$ locate gs_pdfwr.ps

/usr/share/ghostscript/8.63/lib/gs_pdfwr.ps

$ sudo vi /usr/share/ghostscript/8.63/lib/gs_pdfwr.ps

Buscamos lo siguiente:

% Patch ‘where’ so that the distiller operators are only visible
% if the pdfwrite device is the current one.
{ currentdevice .devicename dup /pdfwrite eq exch /ps2write eq or{

Donde pone /pdfwrite lo sustituímos por /pdfXYZwrite  (o por cualquier otra cosa). Queda así:

% Patch ‘where’ so that the distiller operators are only visible
% if the pdfwrite device is the current one.
{ currentdevice .devicename dup /pdfXYZwrite eq exch /ps2write eq or{

Grabamos y salimos. Adiós, protecciones idiotas, adiós.

$ ps2pdf ficherodeldiablo.ps

$ evince ficherodeldiablo.pdf

PD: ¿y cómo quito las protecciones anti/impresión y anti copy/paste? Así