Le motivazioni delle domande sono state illustrate nella sezione seguente.
Esistono molti modi per rendere il testo in corsivo ,
quindi, forse, ci sono più di un bene
" swap algoritmo in corsivo ".
Il problema rivela alcuni aspetti
difficoltà in un codice XHTML e utilizzo del tag <i>
, che deve essere bilanciato .
Esempio:
<!-- 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>
Quindi, assomiglia a questo,
-
Molti altri Homo sapiens fossili sono stati scoperti .
-
Sono stati scoperti molti altri fossili Homo sapiens .
Introduzione e discussione degli algoritmi
Per " soluzione di layout ", l'algoritmo più semplice controlla la proprietà font-style
CSS di tutti i blocchi di testo,
e invertirli con jQuery:
$('#myFragment *').each(function(){
if ($(this).css('font-style')=='italic')
$(this).css('font-style','normal')
else
$(this).css('font-style','italic')
});
Ma questo algoritmo non sopravvive a un test un po 'più complesso,
<p id="p3"><b><i>F</i>RAGMENT <big><i>with italics</i> and </big> withOUT.</b></p>
Il secondo algoritmo più semplice è per una soluzione concreta ed è stato utilizzato nella sezione "Esempi". Hai due passaggi:
- racchiude il frammento XHTML in corsivo;
- inverti i tag in apertura / chiusura in corsivo (ad esempio
</i>
in<i>
).
Cioè, scrivendo con Javascript,
var s = '... a fragment of XHTML content ...';
s = '<i>'+
s.replace(/<(\/?)i>/mg,
function (m,p1){
return p1? '<i>': '</i>';
}
) +
'</i>';
Ma anche non sopravvivere al secondo test, perdendo l'equilibrio dei tag ... L'algoritmo "corretto" gira (!), Ma non è portatile, né veloce né elegante. È mostrato qui e nella sezione di esempio seguente.
Il punto!
Quindi la domanda è,
ci sono un algoritmo semplice, buono e generico (utilizzabile in qualsiasi browser e portatile in un'altra lingua)? Conosci un altro "algoritmo in corsivo di scambio"?
PS: "generico" nel senso che persino io traduco il tuo algoritmo in XSLT. L'algoritmo deve produrre direttamente codice XHTML bilanciato (senza una blackbox intermedia come Tidy).
Motivazioni
Ho bisogno di portare l'algoritmo "swap italics" in editor di testo, parser server, ecc. In tutti i casi posso "normalizzare l'input" (e l'output) con il tag XHTML standard e <i>
.
Sto analizzando il testo XHTML di libri in prosa e articoli scientifici, esportati da origini e stili diversi ... La maggior parte dei testi viene esportata come "testo normale", ma molti titoli (ad esempio il titolo dell'articolo, il titolo del capitolo), e, a volte, un capitolo completo o una casella di testo completa (ad esempio l'articolo astratto) sono stilizzati con corsivo. Tutti questi "stilizzati con corsivo" devono essere invertiti. Casi tipici:
-
Trasforma l'originale "all chapter italics" in "all chapter normal text": leggi questo caso , dove in un libro di circa 300 pagine, 8 dei 25 capitoli devono essere invertiti.
-
Virgolette, abstract, ecc. in corsivo Vedi questo esempio . Hai bisogno di tornare alla normalità, ma senza perdere le parole di enfasi.
-
Scrivere nomi binomiali delle specie , nei testi scientifici, di solito sono scritti in corsivo (o invertiti, in un carattere diverso da quello utilizzato per "testo normale"). Centinaia di titoli in corsivo (di articoli e di sezioni di articoli) di articoli esportati XHTML devono essere invertiti sul mio posto di lavoro. PS: guarda l'esempio dell'inizio della domanda ("Diversi altri Homo sapiens ...").
Ho anche bisogno di tradurre l'algoritmo generico (della tua risposta!) in una libreria XSLT , dove non esiste "correzione del bilanciamento del tag".
Esempi
Implementazione in Javascript e PHP di un non generico "algoritmo di scambio in corsivo". Un generico ha bisogno di un generale "algoritmo di interleaving XML" ... Qui utilizzo le correzioni del browser (DOM) e di Tidy, in alternativa a "interleaving".
JavaScript
Funziona con input complessi (!). Illustrando, tramite un'implementazione 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*)<\/>/mg,'$2'); // clean
s = s.replace(/<([a-z]+)>(\s*)<\/>/mg,'$2'); // clean remain
$('#inverted').html(s);
// END ALGORITHM
alert(s);
PHP, con Tidy
Lo stesso di Javascript, "tradotto" in PHP - la traduzione naturale utilizza DOMDocument()
class e loadHTML
/ saveXML
methodos, ma ciò che ha lo stesso comportamento dei corrispondenti del browser è il tidy
class . Mostra gli stessi risultati (!)
$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*)<\/>/s', '$2', $s); // clean
$s = preg_replace('/<([a-z]+)>(\s*)<\/>/s', '$2', $s); // clean remain
// END ALGORITHM
echo "\n\n$s";