Migrando de XHTML a HTML-5

Herramienta para reemplazar texto

En el tema anterior expuse los que, a mi entender, son cambios necesarios para adaptar a HTML-5 la cabecera de los documentos escritos con sintaxis XHTML. Ya tenía desarrollada una herramienta para reemplazar texto en múltiples documentos que aprovecharé para hacer estos cambios genéricos. En primer lugar creamos una nueva configuración con cualquier nombre:

Configura herramienta

Luego hemos de agregar en el área de texto los datos para los patrones y reemplazos. Recuerde que las líneas que empiezan con "#" son comentarios que no serán tenidos en cuenta. Por ejemplo, el grupo siguiente separado por las líneas con ::-- representa un patrón de búsqueda y la cadena que se usará para reemplazar el texto encontrado:

::--
# Migrar XHTML-HTML5: modificar DOCTYPE
/^\<\!DOCTYPE[ \s]+html[ \s]+[^>]+\>/mi
<!DOCTYPE html>
::--

Se trata de sustituir los DOCTYPE por el nuevo de HTML-5. El patrón se escribe en la primera línea tras el separador de grupos ::--, todo ese patrón en una única línea. El resto hasta el final del separador de grupo, incluyendo varias líneas si fuera necesario, es el texto que se usará para reemplazar.

Expresiones regulares para hacer las modificaciones

En el tema anterior expuse los elementos de cabecera que quiero cambiar en todas las páginas de mi sitio. Estas tenían la siguiente estructura de cabecera con sintaxis XHTML:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="es" xml:lang="es">
<head>
    <title>...</title>
    <meta http-equiv="X-UA-Compatible" content="IE=8"/>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
    <meta http-equiv="Content-Script-Type" content="JavaScript" />
    <meta name="title" content="..." />
    ...

Por lo tanto hemos de hacer lo siguiente:

  • Eliminar la declaración XML <?xml...?>.
  • Modificar el <!DOCTYPE html>.
  • Modificar los atributos del elemento raíz quedando <html lang="es"> quitando otros atributos como el espacio de nombres xmlns.
  • Eliminar <meta http-equiv="Content-Script-Type" content="JavaScript" /> pues en HTML-5 será JavaScript por defecto.
  • Eliminar <meta name="title" content="..." /> pues el elemento <title> hace lo mismo.
  • Reubicar y modificar el <meta http-equiv="content-type" content="text/html; charset=UTF-8" /> para situarlo en primer lugar en el inicio del <head>.
  • A continuación crea y/o modifica el <meta http-equiv="X-UA-Compatible" content="IE=edge; chrome=1" /> después del anterior y antes del <title>. Este elemento hace que el navegador IE use su modo mayor posible y no entre en modos alternativos. Si hay marco Chrome para IE lo usará.

Las búsquedas y reemplazos de la herramienta anterior se realizan por grupos. Es decir, se ejecuta cada grupo de forma secuencial. Por lo tanto hemos de seguir un orden para hacer esto. En la lista a continuación se presenta cada paso, separando el patrón de expresión regular usado y la cadena a reemplazar. El patrón aparecerá aquí en varias líneas para acomodar la lectura, pero en la herramienta hay que ponerlo en una única línea.

  1. Eliminar la declaración XML:
    • Patrón:
      /^[ \s]*\<\?xml[ \s]+version[ \s]*\=[ \s]*["']1.0["'][ \s]+
      encoding[ \s]*\=[ \s]*["']UTF-8["'][ \s]*\?\>[ \s]+/mi
    • Reemplazo: como es una eliminación será una cadena vacía.
  2. Modificar el DOCTYPE
    • Patrón:
      /^\<\!DOCTYPE[ \s]+html[ \s]+[^>]+\>/mi
    • Reemplazo:
      <!DOCTYPE html>
  3. Modificar atributos del elemento raiz <html
    • Patrón:
      /^\<html[^>]*\>/mi
    • Reemplazo:
      <html lang="es">
  4. Eliminar provisionalmente el meta http-equiv="X-UA-Compatible"
    • Patrón:
      /^[ \s]*\<meta[ \s]+http\-equiv[ \s]*\=[ \s]*
      ["']X\-UA\-Compatible["'][^>]+\>[ \s]+/mi
    • Reemplazo: como es una eliminación será una cadena vacía.
  5. Eliminar provisionalmente meta http-equiv="content-type"
    • Patrón:
      /^[ \s]*\<meta[ \s]+http\-equiv[ \s]*\=[ \s]*
      ["']content\-type["'][^>]+\>[ \s]+/mi
    • Reemplazo: como es una eliminación será una cadena vacía.
  6. Eliminar definitivamente meta http-equiv="Content-Script-Type"
    • Patrón:
      /^[ \s]*\<meta[ \s]+http\-equiv[ \s]*\=[ \s]*
      ["']Content\-Script\-Type["'][^>]+\>[ \s]+/mi
    • Reemplazo: como es una eliminación será una cadena vacía, pero para evitar que también elimine la tabulación izquierda de la siguiente línea ponemos la usualmente requerida. En mis páginas uso tabulación de 4 espacios.
  7. Eliminar definitivamente meta name="title"
    • Patrón:
      /^[ \s]*\<meta[ \s]+name[ \s]*\=[ \s]*
      ["']title["'][^>]+\>[ \s]+/mi
    • Reemplazo: como es una eliminación será una cadena vacía, pero para evitar que también elimine la tabulación izquierda de la siguiente línea ponemos la usualmente requerida. En mis páginas uso tabulación de 4 espacios.
  8. Rehacer el inicio del <head> ordenándolo para que aparezca en primer lugar el meta http-equiv="content-type" y luego el http-equiv="X-UA-Compatible". A continuación quedará el elemento del título.
    • Patrón:
      /^[ \s]*\<head\>/mi
    • Reemplazo. Tener en cuenta que los espacios, tabulaciones y saltos serán respetados.
      <head>
          <meta http-equiv="content-type" 
              content="text/html; charset=UTF-8" />
          <meta http-equiv="X-UA-Compatible" 
              content="IE=edge; chrome=1" />

Hay que recordar que se deben escapar los caracteres reservados de las expresiones regulares PHP: . \ + * ? [ ^ ] $ ( ) { } = ! < > | : -. La ejecución de esta herramienta me ha funcionado perfectamente con las páginas de mi sitio. Esto se debe a que todas mantienen la misma estructura, por lo que si esto no fuera así habría que tenerlo en cuenta. De todas formas la herramienta emite un informe final explicando el resultado de cada uno de los patrones y si finalmente el archivo fue modificado. Como esta herramienta no incorpora la posibilidad de copias de seguridad, es mejor hacerlas de todo el sitio antes de afrontar grandes cambios. Además es necesario hacer primero algunas pruebas para ver el comportamiento antes de afrontar cualquier cambio.

Probando las expresiones regulares

Para probar esta herramienta y mostrar el resultado he escrito un documento de prueba llamado prueba-original.html. Está escrito con la sintaxis XHTML y haremos las sustituciones para que finalmente quede como prueba.html con las cabeceras HTML-5. Para eso tenemos el conjunto de patrones y remplazos configurados en el archivo de texto datos-xhtml-html-head.txt, archivo que gestiona la herramienta. Cuando ejecutamos nos actualiza un informe de resultados llamado informe-xhtml-html5-head.txt. Este informe lo reproduzco aquí para comentarlo, aunque he acortado las cadenas de la parte de patrones con puntos suspensivos para mayor comodidad (son las mismas que expliqué más arriba):

INFORME DE EJECUCIÓN REEMPLAZANDO TEXTO 13/11/2011 22:11:04
==============================================================
Cargando patrones y reemplazos...
[1]
/^[ \s]*\<\?xml[ \s]+version[ \s]* ...
[2]
/^\<\!DOCTYPE[ \s]+html[ \s]+[^>]+\>/mi
<!DOCTYPE html>
[3]
/^\<html[^>]*\>/mi
<html lang="es">
[4]
/^[ \s]*\<meta[ \s]+http\-equiv[ \s]* ...
[5]
/^[ \s]*\<meta[ \s]+http\-equiv[ \s]* ...
[6]
/^[ \s]*\<meta[ \s]+http\-equiv[ \s]* ...
    
[7]
/^[ \s]*\<meta[ \s]+name[ \s]* ...
    
[8]
/^[ \s]*\<head\>/mi
<head>
    <meta http-equiv="content-type" ...
    <meta http-equiv="X-UA-Compatible" ...
==============================================================
RESULTADOS
==============================================================
(1) /temas/html5-cabecera/ejemplos/prueba.html
    Patrón [1]; Reemplazado; 
    Patrón [2]; Reemplazado; 
    Patrón [3]; Reemplazado; 
    Patrón [4]; Reemplazado; 
    Patrón [5]; Reemplazado; 
    Patrón [6]; Reemplazado; 
    Patrón [7]; Reemplazado; 
    Patrón [8]; Reemplazado; 
    Cambios guardados.

En primer lugar la herramienta lee el archivo de configuración datos-xhtml-html5-head.txt donde están los patrones y reemplazos. Los relaciona con un número en corchetes para que luego nos sirva de referencia. Luego va tomando las rutas de los documentos y las relaciona en paréntesis. En esta ejecución sólo está ese documento de prueba. Por cada patrón nos dice si lo ha reemplazado o si no lo encuentra o cualquier incidencia. Si hay errores en la aplicación de algún patrón no aplicará ningún cambio al archivo.

De esta forma cuando se aplica la herramienta para modificar un gran número de documentos, podremos al final revisar este informe de resultados (informe-xhtml-html5-head.txt) y ver si hay algunos donde tengamos que actuar a mano para resolver la incidencia.