Die Motivationen der Frage wurden im folgenden Abschnitt dargestellt. Es gibt viele Möglichkeiten, Text kursiv zu machen , daher gibt es möglicherweise mehr als einen guten " Swap- Kursiv-Algorithmus ". Das Problem zeigt einige zusätzliche Schwierigkeiten in einem XHTML-Code und die Verwendung des <i>
Tags, die ausgeglichen werden müssen . Beispiel:
<!-- 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>
Sieht also so aus,
Es wurden mehrere weitere Fossilien des Homo sapiens entdeckt .
Es wurden mehrere weitere Fossilien des Homo sapiens entdeckt.
Algoritms Einführung und Diskussion
Bei " Layout-Lösung " überprüft der einfachste Algorithmus die font-style
CSS-Eigenschaft aller Textblöcke und invertiert sie mit jQuery:
$('#myFragment *').each(function(){
if ($(this).css('font-style')=='italic')
$(this).css('font-style','normal')
else
$(this).css('font-style','italic')
});
Aber dieser Algorithmus überlebt einen etwas komplexeren Test nicht.
<p id="p3"><b><i>F</i>RAGMENT <big><i>with italics</i> and </big> withOUT.</b></p>
Der zweiteinfachste Algorithmus ist für eine konkrete Lösung und wurde im Abschnitt "Beispiele" verwendet. Haben Sie zwei Schritte:
- Schließen Sie das XHTML-Fragment kursiv ein.
- kursive Tags zum Öffnen / Schließen invertieren (z. B.
</i>
bis<i>
).
Das heißt, mit Javascript schreiben,
var s = '... a fragment of XHTML content ...';
s = '<i>'+
s.replace(/<(\/?)i>/mg,
function (m,p1){
return p1? '<i>': '</i>';
}
) +
'</i>';
Aber auch nicht bis zum zweiten Test überleben, Gleichgewicht der Tags verlieren ... Der "korrigierte" Algorithmus läuft (!), Ist aber nicht portabel, weder schnell noch elegant. Dies wird hier und im folgenden Beispielabschnitt demonstriert .
Der Punkt!
Die Frage ist also:
Gibt es einen einfachen, guten und generischen Algorithmus (in jedem Browser verwendbar und in eine andere Sprache portierbar)? Sie kennen einen anderen "Swap-Kursiv-Algorithmus"?
PS: "generisch" in dem Sinne, dass ich Ihren Algorithmus sogar in XSLT übersetze. Der Algorithmus muss direkt ausgeglichenen XHTML-Code erzeugen (ohne eine zwischengeschaltete Blackbox wie Tidy).
Motivationen
Ich muss den "Swap-Kursiv-Algorithmus" auf Texteditoren, Server-Parser usw. portieren. In allen Fällen kann ich die Eingabe (und Ausgabe) durch Standard-XHTML und <i>
-Tag "normalisieren" .
Ich analysiere XHTML-Text von Prosabüchern und wissenschaftlichen Artikeln, die aus verschiedenen Ursprüngen und Stilen exportiert wurden ... Die meisten Texte werden als "normaler Text" exportiert, aber viele Titel (z. B. Artikeltitel, Kapiteltitel) und manchmal , ein vollständiges Kapitel oder ein vollständiges Textfeld (z. B. Artikelzusammenfassung) sind kursiv dargestellt. Alle diese "mit Kursivschrift stilisiert" müssen invertiert werden. Typische Fälle:
Wandeln Sie die ursprüngliche Kursivschrift "Alle Kapitel kursiv" in "Normaltext für alle Kapitel" um: Siehe diesen Fall , in dem in einem Buch mit etwa 300 Seiten 8 der 25 Kapitel invertiert werden müssen.
Kursiv gedruckte Anführungszeichen, Abstracts usw. Siehe dieses Beispiel . Müssen Sie wieder normal arbeiten, aber ohne die Betonungswörter zu verlieren.
Das Schreiben von Binomialnamen von Arten in wissenschaftlichen Texten wird normalerweise kursiv geschrieben (oder invertiert in einer anderen Schriftart als der für "normalen Text" verwendete). Hunderte von kursiven Titeln (von Artikeln und Artikelabschnitten) von XHTML-exportierten Artikeln müssen an meinem Arbeitsplatz invertiert werden. PS: siehe das Beispiel am Anfang der Frage ("Mehrere weitere Homo sapiens ...").
Ich muss auch den generischen Algorithmus (Ihrer Antwort!) In eine XSLT-Bibliothek übersetzen , in der keine "Tag-Balancing-Korrektur" vorhanden ist.
Beispiele
Implementierung eines nicht generischen "Swap Italics-Algorithmus" in Javascript und PHP . Ein generischer benötigt einen allgemeinen "XML-Interleaving-Algorithmus" ... Hier verwende ich Browser- (DOM) und Tidy-Korrekturen als Alternative zum "Interleaving".
Javascript
Es läuft mit komplexen Eingaben (!). Veranschaulichung durch eine jQuery-Implementierung :
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, mit ordentlich
Das gleiche wie bei Javascript, das in PHP "übersetzt" wurde - die natürliche Übersetzung verwendet DOMDocument()
Klassen und loadHTML
/ oder saveXML
Methoden, aber was sich genauso verhält wie die Korrespondenten des Browsers, ist die tidy
Klasse . Zeigt die gleichen Ergebnisse (!)
$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";