Lo hice y lo entendí

El blog de Vicente Navarro
17 nov

Notas sobre la función wptexturize de WordPress, sobre los navegadores que convierten el código HTML a UTF-8 y sobre Unicode/UTF-8

Si nos fijamos en la cabecera del código XHTML de este blog, veremos que está codificado en UTF-8:

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

Con la vistas puesta en un asunto que tal vez trate en una futura entrada, estaba haciendo unas pruebas de guardar el código desde el navegador a un fichero .html y he descubierto algunas cosas interesantes…

La función wptexturize de WordPress

En primer lugar, que WordPress tiene una función/filtro llamado wptexturize (en wp-includes/formatting.php) que nos arregla el aspecto de algunos signos de puntuación. Por ejemplo, si al editar la entrada escribimos:

"prueba"

la función wptexturize, al crear la página final, lo sustituiría por

&#8220;prueba&#8221;

que es equivalente a

&ldquo;prueba&rdquo;

y que, renderizado por el navegador, queda con fancy quotes (comillas de apertura y cierre diferenciadas):

“prueba”

En What is Texturize? encontramos más ejemplos, y si queremos saber exactamente qué y cómo lo hace, podemos consultar el código de la función. También hay que tener en cuenta que hay fuentes que sacan las fancy quotes exactamente igual que las estándar, así que es posible que según la fuente usada no lo notemos.

Algunos navegadores guardan el código HTML codificado

La segunda cosa que he descubierto es que cuando guardas una página codificada en UTF-8 que tienes abierta en Firefox o en Internet Explorer, los códigos HTML como &ldquo; o &rdquo; (podemos consultar todos los códigos HTML en Character entity references in HTML 4) son sustituidos por sus secuencia de bytes correspondiente para formar el código UTF-8 que corresponde. Konqueror no lo hace así y deja los códigos tal y como van en la página.

Por ejemplo, supongamos que creamos un fichero HTML con el siguiente código:

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Prueba</title>
</head>
<body>
Una palabra &ldquo;entrecomillada&rdquo; como ejemplo.
</body>
</html>

El Iceweasel/Firefox nos lo mostraría así:

Comillas dobles en Iceweasel

Y si ahora vamos a Guardar como…, guardamos el fichero con otro nombre, y lo examinamos con el hexdump:

$ hexdump -C prueba_saveas.html
00000000  3c 68 74 6d 6c 3e 3c 68  65 61 64 3e 0a 0a 3c 6d  |<html><head>..<m|
00000010  65 74 61 20 68 74 74 70  2d 65 71 75 69 76 3d 22  |eta http-equiv="|
00000020  43 6f 6e 74 65 6e 74 2d  54 79 70 65 22 20 63 6f  |Content-Type" co|
00000030  6e 74 65 6e 74 3d 22 74  65 78 74 2f 68 74 6d 6c  |ntent="text/html|
00000040  3b 20 63 68 61 72 73 65  74 3d 55 54 46 2d 38 22  |; charset=UTF-8"|
00000050  3e 3c 74 69 74 6c 65 3e  50 72 75 65 62 61 3c 2f  |><title>Prueba</|
00000060  74 69 74 6c 65 3e 3c 2f  68 65 61 64 3e 3c 62 6f  |title></head><bo|
00000070  64 79 3e 0a 55 6e 61 20  70 61 6c 61 62 72 61 20  |dy>.Una palabra |
00000080  e2 80 9c 65 6e 74 72 65  63 6f 6d 69 6c 6c 61 64  |â..entrecomillad|
00000090  61 e2 80 9d 20 63 6f 6d  6f 20 65 6a 65 6d 70 6c  |aâ.. como ejempl|
000000a0  6f 2e 0a 3c 2f 62 6f 64  79 3e 3c 2f 68 74 6d 6c  |o..</body></html|
000000b0  3e                                                |>|

veremos que en vez del símbolo correspondiente a las comillas dobles de apertura (&ldquo;) tenemos la secuencia de bytes E2 80 9C y en vez del símbolo correspondiente a las comillas dobles de cierre (&rdquo;) tenemos la secuencia de bytes E2 80 9D. Son los caracteres Unicode U+201C (LEFT DOUBLE QUOTATION MARK) y U+201D (RIGHT DOUBLE QUOTATION MARK) codificados en UTF-8.

Notas sobre Unicode y UTF-8

Recordemos que Unicode es un juego de caracteres que tiene capacidad para todos los símbolos de todos los idiomas que se usan en el mundo y que se puede codificar de distintas formas, siendo las más típicas el UTF-8 y el UTF-16.

El UTF-8, por ejemplo, codifica cada carácter en una secuencia de 1 a 4 bytes. Las secuencias de 1 byte sólo pueden codificar los 128 símbolos ASCII, que corresponden a los caracteres Unicode U+0000 a U+007F. Con 2 bytes se codifican las letras latinas con acentos, y algunos alfabetos como el griego, el hebreo, el árabe o el cirílico y corresponden a los caracteres Unicode U+0080 a U+07FF. Con 3 bytes se representa el resto de caracteres (p.e. los chinos y japoneses, que son un montón) y normalmente nunca se usan 4 bytes en la práctica.

En la Wikipedia, Mapping of Unicode characters, podemos ver el mapeado de absolutamente todos los caracteres Unicode, y encontramos los caracteres con los que estamos tratando en la tabla de caracteres de puntuación (rango U+2000–206F).

En UTF-8 encoding table and Unicode characters podemos ver todas las equivalencias entre caracteres Unicode y las secuencias de bytes que los codifican en UTF-8.

Comandos de Linux para convertir entre juegos de caracteres

Y todo esto viene, en realidad, de que yo estaba intentando trabajar con el fichero HTML generado con el Guardar como… y al estar codificado en UTF-8 me estaba dando problemas y si lo intentaba convertir con iconv o con tcs a otros juegos de caracteres, los comandos no conseguían convertir esos caracteres que me añadía la función wptexturize, como podemos ver con el HTML del ejemplo anterior:

$ iconv -f UTF-8 -t iso88591 prueba_saveas.html
<html><head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>Prueba</title></head><body>
Una palabra iconv: illegal input sequence at position 128
$ tcs -f utf -t 8859-1 prueba_saveas.html
tcs: rune 0x201c not in output cs
tcs: rune 0x201d not in output cs
<html><head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>Prueba</title></head><body>
Una palabra ýentrecomilladaý como ejemplo.
</body></html>

Deshabilitar el wptexturize

Para mis pruebas, por tanto, me es imprescindible deshabilitar todo o parte del wptexturize. Para ello, hay plugins realmente sencillos, compuestos por un único fichero con apenas unas cuantas líneas fáciles de entender:

y algún otro mucho más complejo y elaborado, como el Text Control.

Pero en realidad, siguiendo las pistas (What is Texturize?, Please give us the option to turn of smart “quotes”, Plugin API) vemos que podemos anular los efectos de la wptexturize sin instalar ningún plugin, tan sólo añadiendo al fichero functions.php de nuestro tema el siguiente código:

<?php
remove_filter('comment_text', 'wptexturize');
remove_filter('comment_author', 'wptexturize');
remove_filter('category_description', 'wptexturize');
remove_filter('list_cats', 'wptexturize');
remove_filter('single_post_title', 'wptexturize');
remove_filter('the_title', 'wptexturize');
remove_filter('the_content', 'wptexturize');
remove_filter('the_excerpt', 'wptexturize');
remove_filter('bloginfo', 'wptexturize');
?>

:wq

Entradas relacionadas

Tema LHYLE09, creado por Vicente Navarro