As motivações das perguntas foram descritas na seção abaixo. Existem várias maneiras de colocar o texto em itálico ; portanto, talvez haja mais de um bom " algoritmo de troca de itálico ". O problema revela algumas dificuldades adicionais em um código XHTML, e o uso da <i>
tag deve ser equilibrado . Exemplo:
<!-- 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>
Então, fica assim,
Vários outros fósseis do Homo sapiens foram descobertos .
Vários outros fósseis do Homo sapiens foram descobertos.
Introdução e discussão de algoritmos
Para " solução de layout ", o algoritmo mais simples é verificar a font-style
propriedade CSS de todos os blocos de texto e invertê-los com jQuery:
$('#myFragment *').each(function(){
if ($(this).css('font-style')=='italic')
$(this).css('font-style','normal')
else
$(this).css('font-style','italic')
});
Mas esse algoritmo não sobrevive a um teste um pouco mais complexo,
<p id="p3"><b><i>F</i>RAGMENT <big><i>with italics</i> and </big> withOUT.</b></p>
O segundo algoritmo mais simples é para uma solução concreta e foi usado na seção "Exemplos". Tenha duas etapas:
- coloque o fragmento XHTML em itálico;
- inverter abrir / fechar tags em itálico (por exemplo,
</i>
para<i>
).
Ou seja, escrevendo com Javascript,
var s = '... a fragment of XHTML content ...';
s = '<i>'+
s.replace(/<(\/?)i>/mg,
function (m,p1){
return p1? '<i>': '</i>';
}
) +
'</i>';
Mas também não sobrevive ao segundo teste, perdendo o equilíbrio de tags ... O algoritmo "corrigido" é executado (!), Mas não é portátil, nem rápido nem elegante. É demonstrado aqui e na seção de exemplo abaixo.
O ponto!
Então a questão é:
existe um algoritmo simples, bom e genérico (utilizável em qualquer navegador e portátil para outros idiomas)? Você conhece outro "algoritmo de troca de itálico"?
PS: "genérico" no sentido em que eu até traduzo seu algoritmo para XSLT. O algoritmo deve produzir código XHTML balanceado diretamente (sem uma caixa preta intermediária como o Tidy).
Motivações
Preciso portar o "algoritmo de troca de itálico" para editores de texto, analisadores de servidor, etc. Em todos os casos, posso "normalizar a entrada" (e a saída) pelo XHTML e <i>
tag padrão .
Estou analisando o texto XHTML de livros de prosa e artigos científicos, exportados de diferentes origens e estilos ... A maioria dos textos é exportada como "texto normal", mas muitos títulos (por exemplo, título do artigo, título do capítulo) e, às vezes , um capítulo completo ou uma caixa de texto completa (por exemplo, resumo do artigo) são estilizados em itálico. Todos estes "estilizados com itálico" devem ser invertidos. Casos típicos:
Transforme o "todos os capítulos em itálico" em "todos os capítulos em texto normal": veja este caso , onde em um livro de aproximadamente 300 páginas, 8 dos 25 capítulos precisam ser invertidos.
Aspas em itálico, resumos, etc. Veja este exemplo . Precisa voltar ao normal, mas sem perder as palavras de ênfase.
Escrever nomes binomiais de espécies , em textos científicos, geralmente é digitado em itálico (ou invertido, em uma fonte diferente daquela usada para o "texto normal"). Centenas de títulos em itálico (de artigos e de seções de artigos) de artigos exportados em XHTML devem ser invertidos no meu local de trabalho. PS: veja o exemplo do início da pergunta ("Vários mais Homo sapiens ...").
Também preciso traduzir o algoritmo genérico (da sua resposta!) Em uma biblioteca XSLT , onde não existe uma "correção de balanceamento de tags".
Exemplos
Implementando em Javascript e PHP um "algoritmo de troca de itálico" não genérico . Um genérico precisa de um "algoritmo de intercalação XML" geral ... Aqui eu uso correções do navegador (DOM) e Tidy, como uma alternativa à "intercalação".
Javascript
É executado com entradas complexas (!). Ilustrando, por uma implementação do 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, com arrumado
O mesmo de Javascript, "traduzido" para PHP - a tradução natural está usando DOMDocument()
classe e loadHTML
/ saveXML
methodos, mas o que tem o mesmo comportamento que os correspondentes do navegador é a tidy
classe . Mostra os mesmos 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";