La motivación de la pregunta se describió en la sección a continuación. Hay muchas formas de hacer que el texto esté en cursiva , por lo tanto, tal vez, haya más de un buen " algoritmo de intercambio de cursiva ". El problema revela algunas dificultades adicionales en un código XHTML, y el uso de la <i>
etiqueta, que debe ser equilibrado . Ejemplo:
<!-- original text: -->
<p id="p1"><i>Several more</i> Homo sapiens <i>fossils were discovered</i>.</p>
<!-- same text, swapping italics: -->
<p id="p2">Several more <i>Homo sapiens</i> fossils were discovered.</p>
Entonces, se ve así,
Se descubrieron varios fósiles más del Homo sapiens .
Se descubrieron varios fósiles más del Homo sapiens .
Introducción y discusión de algoritmos
Para la " solución de diseño ", el algoritmo más simple es verificar la font-style
propiedad CSS de todos los bloques de texto e invertirlos con jQuery:
$('#myFragment *').each(function(){
if ($(this).css('font-style')=='italic')
$(this).css('font-style','normal')
else
$(this).css('font-style','italic')
});
Pero este algoritmo no sobrevive a una prueba un poco más compleja,
<p id="p3"><b><i>F</i>RAGMENT <big><i>with italics</i> and </big> withOUT.</b></p>
El segundo algoritmo más simple es para una solución concreta , y se utilizó en la sección "Ejemplos". Tiene dos pasos:
- encierra el fragmento XHTML en cursiva;
- invertir abrir / cerrar etiquetas en cursiva (ej.
</i>
a<i>
).
Es decir, escribiendo con Javascript,
var s = '... a fragment of XHTML content ...';
s = '<i>'+
s.replace(/<(\/?)i>/mg,
function (m,p1){
return p1? '<i>': '</i>';
}
) +
'</i>';
Pero tampoco sobrevive a la segunda prueba, perdiendo el equilibrio de las etiquetas ... El algoritmo "corregido" se ejecuta (!), Pero no es portátil, ni rápido ni elegante. Se muestra aquí , y en la sección de ejemplos a continuación.
¡El punto!
Entonces la pregunta es,
Hay un algoritmo simple, bueno y genérico (utilizable en cualquier navegador y portátil a otros idiomas)? ¿Conoces otro "algoritmo de intercambio de cursiva"?
PD: "genérico" en el sentido de que incluso traduzco tu algoritmo a XSLT. El algoritmo debe producir código XHTML direccionalmente equilibrado (sin una caja negra intermedia como Tidy).
Motivaciones
Necesito portar el "algoritmo de intercambio de cursiva" a editores de texto, analizadores de servidores, etc. En todos los casos puedo "normalizar la entrada" (y salida) mediante XHTML estándar y <i>
etiqueta.
Estoy analizando el texto XHTML de libros en prosa y artículos científicos, exportados desde diferentes orígenes y estilos ... La mayoría de los textos se exportan como "texto normal", pero muchos títulos (por ejemplo, título de artículo, título de capítulo) y, a veces , un capítulo completo o un cuadro de texto completo (por ejemplo, resumen del artículo) están estilizados en cursiva. Todos estos "estilizados con cursiva" deben invertirse. Casos tipicos:
Transforme el original "cursiva de todos los capítulos" en "texto normal de todos los capítulos": vea este caso , donde en un libro de aproximadamente 300 páginas, 8 de los 25 capítulos deben invertirse.
Comillas en cursiva, resúmenes, etc. Vea este ejemplo . Necesita volver a la normalidad, pero sin perder las palabras de énfasis.
La escritura de nombres binomiales de especies , en textos científicos, generalmente está escrita en cursiva (o invertida, en una fuente diferente de la utilizada para "texto normal"). Cientos de títulos en cursiva (de artículos y secciones de artículos) de artículos exportados por XHTML deben invertirse en mi lugar de trabajo. PD: vea el ejemplo del comienzo de la pregunta ("Varios Homo sapiens más ...").
También necesito traducir el algoritmo genérico (¡de su respuesta!) A una biblioteca XSLT , donde no existe una "corrección de equilibrio de etiqueta".
Ejemplos
Implementando en Javascript y PHP un "algoritmo de intercambio de cursiva" no genérico . Una genérica necesita un "algoritmo de intercalación XML" general ... Aquí uso las correcciones del navegador (DOM) y Tidy, como alternativa a la "intercalación".
Javascript
Se ejecuta con entradas complejas (!). Ilustrando, mediante una implementación de jQuery :
var s = $('#sample1').html(); // get original html text fragment
// INVERSION ALGORITHM: add and remove italics.
s = "<i>"+
s.replace(/<(\/?)i>/mg,
function (m,p1){
return p1? '<i>': '</i>';
}
) +
"</i>"; // a not-well-formed-XHTML, but it is ok...
$('#inverted').html(s); // ...the DOM do all rigth!
// minor corrections, for clean empties:
s = $('#inverted').html();
s = s.replace(/<([a-z]+)>(\s*)<\/\1>/mg,'$2'); // clean
s = s.replace(/<([a-z]+)>(\s*)<\/\1>/mg,'$2'); // clean remain
$('#inverted').html(s);
// END ALGORITHM
alert(s);
PHP, con Tidy
Lo mismo de Javascript, "traducido" a PHP: la traducción natural es usar DOMDocument()
class y loadHTML
/ saveXML
methodos, pero lo que tiene el mismo comportamiento que los corresponsales del navegador es la tidy
clase . Muestra los mismos resultados (!)
$sample1='<b><i>O</i>RIGINAL <big><i>with italics</i> and </big> withOUT</b>';
$inverted = '... inverted will be here ...';
echo $sample1;
// Tidy correction
$s = $sample1; // get original html text fragment
// INVERSION ALGORITHM: add and remove italics.
$s = "<i>".
preg_replace_callback('/<(\/?)i>/s', function ($m){
return $m[1]? '<i>': '</i>';}, $s) .
"</i>"; // a not-well-formed-XHTML, but it is ok...
$config = array('show-body-only'=>true,'output-xhtml'=>true);
$tidy = new tidy;
$tidy->parseString($s, $config, 'utf8');
$s = $tidy; // ... because Tidy corrects!
// minor corrections, for clean empties:
$s = preg_replace('/<([a-z]+)>(\s*)<\/\1>/s', '$2', $s); // clean
$s = preg_replace('/<([a-z]+)>(\s*)<\/\1>/s', '$2', $s); // clean remain
// END ALGORITHM
echo "\n\n$s";