DocBook (II): XInclude

8 12 2008

DocBook me está gustando porque simplifica la tarea de la generación y mantenimiento de la documentación. En esta entrada voy a comentar cómo utilizar XInclude para insertar ficheros externos en la documentación, ahorrando la tarea de editarlos, escapar caráctares e insertar. Porque si eso lo vamos a hacer con todos los fragmentos de código, ficheros XML, etc y es programable, pues que lo haga el ordenador.

Concretamente se ilustra el caso con la inserción de un fichero XML, que de otra forma deberíamos editar para escapar los carácteres XML. Con XInclude e indicando text en el atributo parse, tendremos lo mismo pero sin hacer ese trabajo.

Tenemos en un nuestro directorio de trabajo dos ficheros XML: el primero (articulo.xml) es la fuente DocBook, mientras que el segundo (pom.xml) contiene el fichero XML que deseamos insertar en docbook.

<?xml version=”1.0″ encoding=”utf-8″?>
<article xmlns=”http://docbook.org/ns/docbook&#8221;
xmlns:xi=”http://www.w3.org/2001/XInclude&#8221;
xml:lang=”es”>

<section xml:id=”pom”>
<title>Fichero POM</title>

<para>Aquí va el fichero pom.xml</para>

<programlisting><xi:include href=”pom.xml” parse=”text” /></programlisting>
</section>

</article>

Finalmente basta añadir la opción –xinclude en la llamada a xsltproc:

xsltproc --xinclude --o articulo.xhtml /sw/share/xml/xsl/docbook-xsl/xhtml/docbook.xsl articulo.xml

Si lo que se desea es insertar un fragmento de XML se puede realizar con el xinclude, por ejemplo si se quiere añadir el noveno elemento del elemento raíz mostrando un mensaje de error en caso de fallo, de esta forma se procesa el documento.

<programlisting>
<xi:include href=”pom.xml” xpointer=”element(/1/9)”>
<xi:fallback>no cargado pom.xml</xi:fallback>
</xi:include>
</programlisting>

Anuncios




Shell scripting con Ruby

10 11 2008

Aunque para la automatización de tareas se suele recurrir a bash o ksh, en definitiva la shell por defecto, también es fácil encontrarse con scripts realizados en Perl. Pero en el ámbito del software libre han surgido lenguajes modernos que nos pueden resultar atractivos por la funcionalidad que aportan, sencillez o simplemente sana curiosidad.

Dos de los nuevos lenguajes que han ganado popularidad recientemente son Python y Ruby. En este post vamos a comentar cómo realizar un sencillo script que nos simplifique la tarea de generar salidas en HTML, XML o PDF a partir de un XML original en DocBook 5.

Nuestro script, recibirá al menos un parámetro de entrada (“clean” para limpiar el directorio de trabajo) o dos (formato de salida: “html”, “xhtml” o “pdf”, y nombre del fichero sin extensión).

#!/usr/bin/ruby
print "procesador DocBook - JM 2008\n"
XSLEXE = "xsltproc --output "
HTMEXE = ".html --stringparam generate.toc 0 /sw/share/xml/xsl/docbook-xsl/html/docbook.xsl "
PDFEXE = ".fo --stringparam paper.type A4 --stringparam generate.toc 0 /sw/share/xml/xsl/docbook-xsl/fo/docbook.xsl "
XHTEXE = ".xhtml --stringparam generate.toc 0 /sw/share/xml/xsl/docbook-xsl/xhtml/docbook.xsl "
ejecutable = case $*[0]
when "html" : XSLEXE + $*[1] + HTMEXE + $*[1] + ".xml"
when "pdf" : XSLEXE + $*[1] + PDFEXE + $*[1] + ".xml"
when "xhtml" : XSLEXE + $*[1] + XHTEXE + $*[1] + ".xml"
when "clean" : "rm *.fo *.pdf *.html *.xhtml"
else
print "sintaxis: opciones nombre_fichero_sin_extensión\n"
print "opciones: html, pdf y xhtml\n"
exit
end
system(ejecutable)
print "\n"
if $*[0] == "pdf"
ejecutable = "java org.apache.fop.cli.Main -fo " + $*[1] + ".fo -pdf " + $*[1] + ".pdf"
system(ejecutable)
print "\n"
end
print "finalizando procesado\n"

 
Como es habitual en los shell scripts, la primera línea es para invocar al intérprete Ruby.

Se han definido una series de constantes, en mayúsculas, que se usan en la sentencia CASE para componer las diferentes órdenes (mediante concatenación de strings con el operador +).

Y la variable $*, que realmente es un array, almacena los diferentes parámetros recibidos por línea de comandos: $*[0] para la opción y $*[1] para el nombre del fichero.

La invocación de comandos externos se realiza mediante el comando system, mientras que el salto de línea (\n) se incluye para hacer bonita la salida.

Diferentes ejecuciones:
./miscript.rb clean
./miscript.rb xhtml fichero





Subversion y Eclipse en OS X

28 10 2008

Aunque existe documentación suficiente, en inglés, me inspira escribir esta entrada para dejarlo mascadito en castellano, vamos para los vagos como yo.

La instalación de Eclipse en OS X no tiene ningún secreto: se descomprime el fichero descargado en el directorio deseado y ya está. Para poder interactuar con un servidor Subversion se comentará la instalación del plugin Subclipse, se creará un repositorio local y se importará un proyecto desde Eclipse.

En mi caso el servidor Subversion se ejecuta en local, el siguiente enlace ha sido de gran ayuda. Pero resumiendo, tan sólo es necesario habilitar el servidor ssh desde las preferencias del sistema, pues el servidor subversion ya viene instalado con OS X Leopard, y la comunicación con el mismo se realiza mediante ssh.

Los repositorios he decidido alojarlos en /Library/Subversion/Repository, y debo crearlos a mano desde la consola, hecho este paso ya se puede añadir el repositorio a Eclipse y trabajar desde el propio IDE.

svnadmin create /Library/Subversion/Repository/J2EE

En Eclipse para instalar Subclipse basta con añadir la URL http://subclipse.tigris.org/update_1.4.x en Help/Software Updates. Me limité a seleccionar las dependencias obligatorias y pasé de las opcionales.

Tras instalarlo y reiniciar Eclipse como se recomienda, se abre la vista SVN Repository Exploring y se añade el repositorio creado mediante el menú contextual de la ventana SVN Repositories: New/Repository Location. La URL a introducir es svn+ssh://localhost/Library/Subversion/Repository/J2EE y ya está.

A partir de este punto ya se puede trabajar con Subversion desde Eclipse. En un proyecto serio la gestión de versiones de código estaría ya disponible y tras introducir la URL del repositorio correcto se podría realizar los clásicos check out y demás. En mi caso, como está todo mi verde, indico como incorporar un proyecto ya creado en mi workspace. Se trata de una aplicación J2EE sencilla, donde he procedido a limpiar el proyecto para no subir las clases compiladas, tan sólo el código, librerías y ficheros adicionales de configuración.

Click derecho sobre el proyecto para seleccionar Team/Share Project, luego SVN (CVS está disponible) y finalmente el repositorio como ilustra la secuencia de imágenes.





DocBook en OS X Leopard

15 10 2008

Aunque soy un usuario convencido de LaTeX2e, quería probar DocBook por varias razones:

  • Curiosidad técnica
  • XML como mejor formato para gestionar documentos

Como además soy usuario de un MacBook y he encontrado poca información actualizada al respecto me he decidido a añadir una nueva entrada a mi blog.

Primero instalé fink (y su version GUI finkcommander) para realizar la instalación de DocBook mediante este gestor de paquetes. Los paquetes a instalar son:

  • docbook-bundle
  • docbook-xsl

A continuación creo las siguientes variables de entorno (i.e. /etc/profile)


# DocBook
JADE_HOME=/usr/local/openjade-1.3
SGML_SHARE=/sw/share/sgml


# DSSSL stylesheets
# Norman Walsh's Modular DocBook Stylesheets
SGML_CATALOG_FILES=$SGML_SHARE/dsssl/docbook/catalog
# OpenJade stylesheets
SGML_CATALOG_FILES=$SGML_CATALOG_FILES:$JADE_HOME/dsssl/catalog
# sgmltools-lite's stylesheets
SGML_CATALOG_FILES=$SGML_CATALOG_FILES:$SGML_SHARE/stylesheets/sgmltools/sgmltools.cat


# DocBook DTD
# From OASIS-Open.org
SGML_CATALOG_FILES=$SGML_CATALOG_FILES:$SGML_SHARE/docbook/3.1/catalog
SGML_CATALOG_FILES=$SGML_CATALOG_FILES:$SGML_SHARE/docbook/4.1/catalog
# These old ones were installed with doctools-1.2 from XFree86.org
SGML_CATALOG_FILES=$SGML_CATALOG_FILES:$SGML_SHARE/docbook/2.4.1/catalog
SGML_CATALOG_FILES=$SGML_CATALOG_FILES:$SGML_SHARE/docbook/3.0/catalog

# sgmltools-lite catalogs for LinuxDoc
SGML_CATALOG_FILES=$SGML_CATALOG_FILES:$SGML_SHARE/dtd/sgmltools/catalog

# XSL files home directory
XSL=/sw/share/xml/xsl


export JADE_HOME SGML_SHARE SGML_CATALOG_FILES XSL

Realmente creo que las necesarias para DocBook 5 es $XSL, y el resto son para retrocompatibilidad o si se van a procesar ficheros SGML.

También he instalado FOP (para generar salida en pdf), copiando las librerías Java necesarias a /Library/Java/Extensions y estén disponibles para todos los usuarios.

  • avalon-framework-4.2.0.jar
  • batik-all-1.7.jar
  • commons-io-1.3.1.jar
  • commons-logging-1.0.4.jar
  • fop-hyph.jar (no incluida en FOP por asunto de licencias)
  • fop.jar
  • serializer-2.7.0.jar
  • xalan-2.7.0.jar
  • xercesImpl-2.7.1.jar
  • xml-apis-1.3.04.jar
  • xml-apis-ext-1.3.04.jar
  • xmlgraphics-commons-1.3.1.jar

Y para generar un documento en pdf sólo son necesarios dos comandos:
xsltproc --output articulo.fo /sw/share/xml/xsl/docbook-xsl/fo/docbook.xsl articulo.xml
java org.apache.fop.cli.Main -fo articulo.fo -pdf articulo.pdf

Siendo el fichero original articulo.xml:

<xml version="1.0" encoding="utf-8">
<article>
<title>Mi titulo</title>
<section><title>Seccion primera</title>
<para>Parrafada de la primera seccion.
</para>
</section>
</article>

Finalmente recomiendo los siguientes enlaces que han sido de muchísima ayuda:
Working With DocBook XML On Mac OS X
Con respecto a este enlace he realizado una serie de modificaciones: el modo nXML lo instalo para todos los usuarios (/usr/local/share/emac/site-lisp), en el fichero .emacs indico la ruta absoluta a rng-auto.el para que sea cargado.
DocBook XSL: The Complete Guide
DocBook Install mini-HOWTO





Formateando código en LaTeX2e

1 08 2008

Documentando aplicaciones informáticas en un documento LaTeX2e surge la necesidad de formatear adecuadamente el código fuente. Lo habitual es recurrir para este menester al uso del entorno verbatim, pero suele chocar con la buena costumbre de separar contenido de presentación: a veces es necesario reformatearlo a mano.

Con la idea de evitar este problema, descubrí el paquete listing, que genera una presentación correcta liberando al redactor de la incómoda tarea comentada antes.

Para usarlo se debe cargar el paquete listing en el preámbulo del documento, e invocarlo allí donde se quiere formatear código fuente con las opciones adecuadas (lenguaje de programación, auto salto de línea, fuente, etc).

%preámbulo
\usepackage{listings}


\lstset{language=ksh,basicstyle=\ttfamily}
\begin{lstlisting}[frame=none]
cd norf/exper/sh/
pwd
ps -ef
\end{lstlisting}

quedando la salida de esta forma:

código formateado

codigo formateado





Consulta a base de datos con Vim

26 06 2008

Suele ser más habitual usar Vi como editor auxiliar en el cliente en línea de comandos disponible para determinadas bases de datos. A continuación comento el procedimiento para interactuar con una base de datos MySQL desde Vim (clónico muy popular del omnipresente editor).

Se necesita:

Se descomprime dbext.zip en $Vim/vimfiles de forma que los archivos se copien a los directorios doc, autoload y plugin.

A continuación se edita el fichero de configuración de Vim, vimrc, y se insertan las siguientes líneas:

"MySQL
let g:dbext_default_profile_mysql_local = 'type=MYSQL:user=root:passwd=mysql:dbname=mysql:extra=-t'

En este caso existe una base de datos MySQL, y el cliente en línea de comandos se ha añadido a la variable PATH.

Para probar que funciona, se crea un fichero nuevo con extensión sql, y se realiza una consulta (escribiendo la sentencia SQL y ejecutando con SCAPE+\+s+e o desde el menú en la versión gráfica).

vim prueba.sql

select current_time();

Para muestra, un botón 🙂

vim_mysql

P.D.: La \ representa a <Leader> por defecto en Vim.





ANSI Inner join de tres tablas

24 06 2008

Los desarrolladores acostumbrados a trabajar con Oracle como base de datos suelen recurrir a la sintaxis propia para escribir una consulta donde se relacionan tres tablas a través de un identificador:

SELECT COUNT(a.id)
FROM a, b, c
WHERE a.id = b.id
AND a.id = c.id;

pero existe otra sintaxis que empieza a recomendarse, la sintaxis ANSI, que para el caso de la INNER JOIN escrita antes quedaría:

SELECT COUNT(a.id)
FROM a INNER JOIN b
ON a.id = b.id
INNER JOIN c
ON a.id = c.id;

Espero que os sea de utilidad.