El formato RTF (Rich Text Format) nace como un método de codificación de texto con formato e imágenes fácil de transferir entre distintos dispositivos, sistemas y aplicaciones. Con la especificación de este formato se pretende que un documento creado en un sistema determinado pueda consultarse y manipularse en cualquier otro contexto diferente sin las barreras impuestas por otros formatos propietarios.
Esta capacidad surge del hecho de que internamente un documento RTF se almacena como texto plano, en el que se incluye tanto la información del documento en sí como una serie de metadatos que informan del formato del documento y del resto de propiedades adicionales aportadas por RTF.
Un documento RTF se compone de cuatro elementos básicos, como son: texto sin formato, palabras de control, símbolos de control y grupos.
Una palabra de control es un comando RTF que se utilizará para dar información acerca del formato del documento o cualquier otro tipo de información adicional sobre el texto. Las palabras de control tienen la siguiente forma:
\PalabraControl<Delimitador>
donde PalabraControl puede ser cualuier combinación de letras en minúscula y <Delimitador> puede ser uno de los siguientes:
Un símbolo de control se utilizará, entre otras cosas, para representar determinados caracteres especiales y tendrá la siguiente forma:
\Caracter
donde Caracter puede ser cualquier caracter no alfanumérico. Además, es importante remarcar que los símbolos de control no van separados por ningún tipo de delimitador. Un ejemplo de símbolo de control puede ser \~ que representa un espacio indivisible.
Un grupo consiste en un conjunto de texto, palabras y símbolos de control encerrados entre llaves ('{' y '}') de forma que todo el texto del documento contenido en un grupo comparte las mismas propiedades. Además, existen grupos especiales que forman parte de la cabecera de un documento RTF y contienen información sobre las fuentes, colores y estilos, entre otros, contenidos en el documento.
Veamos un ejemplo de documento RTF donde aparecen todos los elementos comentados:
| {\rtf1\ansi\ansicpg1252\deff0\deflang3082 {\fonttbl{\f0\fswiss\fcharset0 Arial;}{\f1\fmodern\fprq1\fcharset0 Courier New;}} {\colortbl ;\red255\green0\blue0;\red0\green0\blue128;} \viewkind4\uc1\pard\b\f0\fs20 NRTFTree v0.1\b0 es una librer\'eda \cf1\b\fs24 escrita en C# \cf0\b0\fs20 para el \cf2\i\fs24 tratamiento estructurado\fs20 \cf0\i0 de \f1\fs40 documentos RTF\f0\fs20 .\par} |
Figura 1 - Ejemplo de documento fuente RTF
El texto RTF mostrado corresponde al texto con formato siguiente:
| NRTFTree v0.1 es una librería escrita en C# para el tratamiento estructurado de documentos RTF. |
Figura 2 - Ejemplo de documento formateado RTF
La estructura general de un documento fuente RTF es la siguiente:
Documento RTF --> '{' <Cabecera> <Contenido del documento> '}'
Por su parte, la cabecera del documento tendrá la siguiente estructura:
<Cabecera> --> \rtf <charset> \deff ? <fonttbl> <filetbl>? <colortbl>? <stylesheet>? <listtables>? <revtbl>?
con los siguientes significados:
<charset> : Tabla de caracteres utilizada en la codificación del documento.
\deff : Fuente por defecto.
<fonttbl> : Tabla de fuentes. Aquí se incluirán todas las fuentes utilizadas en el documento.
<filetbl> : Tabla de ficheros. Utilizada sólo cuando el documento incluye subdocumentos.
<colortbl> : Tabla de colores. Aquí se incluirán todos los colores de fuente utilizados en el documento.
<stylesheet> : Tabla de estilos. Aquí se incluirán los estilos utilizados en el documento.
<listtables> : Tablas de listas. Donde se incluye información sobre las listas, numeradas o no, contenidas en el documento.
<revtbl> : Tabla de revisiones. Que contendrá información sobre las modificaciones realizadas en el documento.
De todos estos elementos, tan sólo el conjunto de caracteres y la tabla de fuentes son obligatorios, y normalmente, tan sólo éstos junto con la tabla de colores serán los que aparezcan en la mayoría de documentos.
En el ejemplo de la figura 1 podemos ver estas dos tablas habituales. Por un lado la tabla de fuentes donde se definen dos fuentes distintas Arial y Courier New:
{\fonttbl{\f0\fswiss\fcharset0 Arial;}{\f1\fmodern\fprq1\fcharset0 Courier New;}}
Y por otro lado tembién tenemos la tabla de colores, donde definimos tres colores, uno predeterminado que depende de la aplicación que trate el documento (indicado por el primer punto y coma) y otros dos definidos por sus valores RGB:
{\colortbl ;\red255\green0\blue0;\red0\green0\blue128;}
Por último, justo a continuación de la cabecera del documento, comienza el contenido del documento en sí, que irá acompañado de las palabras y símbolos de control que den información sobre su formato. Así por ejemplo, el fragmento siguiente:
\b\f0\fs20 NRTFTree v0.1
indica que el texto "NRTFTree v0.1" se escribirá en negrita (\b), con la fuente número 0 de la tabla de fuentes (\f0) y con tamaño de fuente 20 (\fs20).
Para una información más detallada sobre la especificación del formato RTF se puede consultar el documento oficial en el enlace que se indica al final de este artículo.
Librería NRtfTree
La librería de clases NRtfTree proporciona una serie de mecanismos generales para la lectura y manipulación de documentos RTF.
Como se ha podido comprobar en el apartado anterior, la estructura de un documento RTF resulta en principio un tanto encríptica y a priori nada fácil de manipular de forma automática. Aunque en el fondo esto no es así, si que es cierto que el desarrollo de analizadores a medida para este tipo de documentos es una tarea relativamente complicada o al menos laboriosa, y es en este punto donde NRtfTree puede resultar de gran ayuda.
Las estrategias utilizadas por NRtfTree para el análisis estruturado de documentos RTF son las mismas que las utilizadas para otro tipo de documentos y formatos muy extendidos como el XML. En el contexto del formato XML existen dos aproximaciones principales al problema del análisis de su contenido: DOM (Document Object Model) y SAX (Simple API for XML).
El primero de los métodos, DOM, consiste básicamente en la carga de un documento XML completo en una estructura de datos en forma de árbol que podrá manipularse fácilmente mediante una serie de métodos para el recorrido y modificación del árbol.
La segunda de las soluciones, SAX, consiste en la lectura y análisis secuencial del documento XML, durante el cual se van lanzando una serie de eventos tratables por el desarrollador y que se corresponden con la lectura de cada uno de los elementos contenidos en el documento. Así, por ejemplo, cada vez que el analizador lee del documento una etiqueta de apertura de un elemento se lanza un evento que se podrá capturar para realizar la acciones oportunas.
El primero de los métodos es quizá el más flexible de ambos debido a que una vez cargado el documento completo éste puede recorrerse tantas veces como se desee y en el sentido que se necesite. En cambio, con SAX el documento es leido una sóla vez y las acciones realizadas deben ejecutarse a medida que se analiza el documento y sin tener la posibilidad de "volver atrás".
Pues bien, NRtfTree transfiere estas dos mismas soluciones al campo del formato RTF, y de esta forma tendremos dos clases principales:
RtfTree y RtfTreeNode
Como hemos comentado, RtfTree nos va dar la posibilidad de tratar los distintos elementos de un documento RTF como si formaran parte de una estructura en forma de árbol. Esto facilitará en gran medida el análisis y modificación de un documento por parte de nuestras aplicaciones, siempre de forma muy general y sin imponer en ningún momento tratamientos o conversiones específicas del contenido.
Una vez cargado un documento en el árbol, cada nodo de éste representará un elemento del documento, que se diferenciarán por el tipo de nodo. De esta forma existirán 5 tipos de nodo:
| ROOT | Nodo raíz del árbol. |
| KEYWORD | Palabra clave. |
| CONTROL | Símbolo de control. |
| TEXT | Texto del documento. |
| GROUP | Grupo RTF |
Cada nodo del árbol irá acompañado además de su parámetro correspondiente en caso de exisitir, por que quedarán perfectamente separados todos los elementos del documento y además junto a su información asociada.
Como ejemplo, veamos el árbol creado al cargar el documento de la figura 1:
ROOT |
Figura 3 - Árbol generado para el documento RTF de ejemplo.
En la figura anterior se muestra cada elemento del documento RTF con su nivel dentro del árbol, su tipo de nodo, la palabra clave o símbolo de control correspondiente y su parámetro asociado en cao de existir. Una salida similar a la mostrada la genera la aplicación de ejemplo disponible para descargar junto a los fuentes de la ibrería NRTFTree.
Una vez cargado el documento, las clases RtfTree y RtfTreeNode proporcionan una serie de métodos sencillos con los que se puede recorrer el árbol y modificar su contenido añadiendo, modificando o eliminando nodos. Para una información más detallada de los métodos y propiedades disponibles se puede consultar la documentación online de la librería o la proporcionada en formato CHM con los fuentes de la misma.
RtfReader y SARParser
El objetivo de estas dos clases es proporcionar la posibilidad de realizar un tratamiento secuencial del documento RTF a medida que éste se va analizando.
El procedimiento general seguido para la utilización de esta técnica será el siguiente:
1. Implementar una clase derivada de SARParser donde habrá que redefinir, entre otros, los métodos correspondientes a cada uno de los eventos lanzados durante la lectura del documento RTF. Los eventos lanzados serán los siguientes:
2. Crear una instancia de las clases RtfReader y de la clase anterior. El objeto RtfReader se encargará de cargar el documento y comenzar su lectura. En el constructor de éste se pasará como parámetro el objeto derivado de SARParser, de forma que le estamos indicando a RtfReader qué acciones tomar cada vez que se lance un evento determinado.
3. Comenzar la lectura del documento llamando al método Parse() del objeto RtfReader.
Enlaces relacionados
- Especificación formato RTF versión 1.6 [http://latex2rtf.sourceforge.net/rtfspec.html]