Uutiset:

Bored?  Looking to kill some time?  Want to chat with other SMF users?  Join us in IRC chat or Discord

Main Menu
Advertisement:

[gelöst] Spellcheck und UTF-8

Aloittaja WintermuteX, huhtikuu 23, 2006, 07:59:08 AP

« edellinen - seuraava »

WintermuteX

Ich habe ein sehr seltsames Problem mit dem Spellchecker seitdem ich den Server auf UTF-8 umgestellt habe. Es läßt sich schwer beschreiben, wirkt aber so als ob sich irgendwas "verzählt" aufgrund der Multibyte Zeichen. Die Auswirkung ist das er Buchstaben der zu ersetzenden Wort übrig läßt. Zu beobachten ist es unter folgendem URL: http://www.gothic-chat-community.net/forum/

Es gibt ein Gäste-Board in dem ihr es testen könnt.

Der Server basiert auf Gentoo, der Apache liefert UTF-8 als defaultcharset, das Template ebenfalls, MySQL hat utf8_unicode_ci als default collation und connection.

Für Ideen wäre ich dankbar.

Was mir aufgefallen ist, aber nichts mit dem Problem zu tun hat, ist das scheinbar kein scharfes S in Subs-Post.php vorgesehen ist:
$alphas = 'šžàáâãäåçèéêëìíîïñòóôõöøùúûüýÿ[:alpha:]\'';

Das mir SMF leider keine Futhark-Runen in die DB schreiben will (sehr wohl aber russischen und griechischen charset) ist weder wichtig noch hier von belang, vielleicht eröffne ich später dazu nochmal einen Thread.

<EDIT> Ich scheine einen Teil der Antwort gefunden zu haben, wenn auch nicht ermutigend:
http://de.wikipedia.org/wiki/PHP#M.C3.A4ngel

Also höchstwahrscheinlich ein PHP<->Unicode Problem, hat jemand einen Workaround?

WintermuteX

#1
Ich habe eine Lösung gefunden ... Es ist aber nur als fast&dirty Hotfix zu sehen, ich hoffe SM bessert da nochmal nach. Generell ist das Thema UTF-8 in vielen Dingen noch nicht vom Tisch (maskierte Sonderzeichen, Javascript und damit der Zwang zu UTF-8 kodierten language Dateien etc.)

in Subs-Post.php:


$alphas = 'šžàáâãäåçèéêëìíîïñòóôõöøùúûüýÿß[:alpha:]\'';


ersetzen durch


$alphas = chr(197).chr(160).chr(197).chr(161).chr(197).chr(189).chr(197).chr(190).chr(195).chr(128).chr(195).chr(129).chr(195).chr(130).chr(195).chr(131).chr(195).chr(132).chr(195).chr(133).chr(195).chr(134).chr(195).chr(135).chr(195).chr(136).chr(195).chr(137).chr(195).chr(138).chr(195).chr(139).chr(195).chr(140).chr(195).chr(141).chr(195).chr(142).chr(195).chr(143).chr(195).chr(144).chr(195).chr(145).chr(195).chr(146).chr(195).chr(147).chr(195).chr(148).chr(195).chr(149).chr(195).chr(150).chr(195).chr(152).chr(195).chr(153).chr(195).chr(154).chr(195).chr(155).chr(195).chr(156).chr(195).chr(157).chr(195).chr(158).chr(195).chr(159).chr(195).chr(160).chr(195).chr(161).chr(195).chr(162).chr(195).chr(163).chr(195).chr(164).chr(195).chr(165).chr(195).chr(166).chr(195).chr(167).chr(195).chr(168).chr(195).chr(169).chr(195).chr(170).chr(195).chr(171).chr(195).chr(172).chr(195).chr(173).chr(195).chr(174).chr(195).chr(175).chr(195).chr(176).chr(195).chr(177).chr(195).chr(178).chr(195).chr(179).chr(195).chr(180).chr(195).chr(181).chr(195).chr(182).chr(195).chr(184).chr(195).chr(185).chr(195).chr(186).chr(195).chr(187).chr(195).chr(188).chr(195).chr(189).chr(195).chr(191).'[:alpha:]\'';


(ACHTUNG! Dieser String enthält nur die deutschen Sonderzeichen, wer die anderen auch will kann sich selber die Arbeit machen und sie anhand der UTF-8 Tabelle nachtragen)
<EDIT: nun enthält er alle Sonderzeichen (und ein paar mehr) des Referenz-Strings>

außerdem müssen in der nachfolgenden Zählschleife einige Stringfunktionen durch die Multibyte Funktionen ersetzt werden (kenntlich am prefix "mb_"):


// This is some sanity checking: they should be chronological.
$last_occurance = 0;

$found_words = false;
$code_block = false;
for ($i = 0, $n = count($alphas[0]); $i < $n; $i++)

// Check if we're inside a code block...
if (preg_match('~\[/?code\]~i', $alphas[0][$i]))
$code_block = !$code_block;

// Code block?  No word?
if (empty($alphas[1][$i]) || $code_block)
{
$last_occurance += mb_strlen($alphas[0][$i]);
continue;
}

$check_word = $alphas[1][$i];
if (mb_substr($check_word, 0, 1) == '\'')
$check_word = mb_substr($check_word, 1);
if (mb_substr($check_word, -1) == '\'')
$check_word = mb_substr($check_word, 0, -1);

// If the word is a known word, or spelled right...
// !!! Add an option for uppercase skipping?
if (in_array(mb_strtolower($check_word), $known_words) || pspell_check($pspell_link, $check_word) || mb_strtoupper($check_word) == $check_word)
{
// Add on this word's length, and continue.
$last_occurance += mb_strlen($alphas[0][$i]);
continue;
}

// Find the word, and move up the "last occurance" to here.
if ($last_occurance <= mb_strlen($mystr))
$last_occurance = mb_strpos($mystr, $alphas[0][$i], $last_occurance + 1);
$found_words = true;

// Add on the javascript for this misspelling.
$context['spell_js'] .= '
new misp("' . $alphas[1][$i] . '", ' . (int) $last_occurance . ', ' . ($last_occurance + mb_strlen($alphas[1][$i]) - 1) . ', [';

// If there are suggestions, add them in...
$suggestions = pspell_suggest($pspell_link, $check_word);
if (!empty($suggestions))
{
for ($j = 0, $k = count($suggestions); $j < $k; $j++)
{
// Add back the quotes...
if (mb_substr($alphas[1][$i], 0, 1) == '\'')
$suggestions[$j] = '\'' . $suggestions[$j];
if (mb_substr($alphas[1][$i], -1) == '\'')
$suggestions[$j] = $suggestions[$j] . '\'';
}

$context['spell_js'] .= '"' . join('", "', $suggestions) . '"';
}

$context['spell_js'] .= ']),';
}

// If words were found, take off the last comma.
if ($found_words)
$context['spell_js'] = mb_substr($context['spell_js'], 0, -1);

$context['spell_js'] .= '
);';

// And instruct the template system to just show the spellcheck sub template.
$context['template_layers'] = array();
$context['sub_template'] = 'spellcheck';
}


<EDIT: Ich hatte ein/zwei mb_ Funktionen übersehen>

WintermuteX

Interessant. Nun hat RC3 angeblich UTF-8 Support, aber ihr dürft raten ... ja ... in der Tat ... Die Rechtschreibprüfung ist wieder/noch Broken.
Mein Workaround funktioniert noch immer, aber ihr müßt "substr,strlen,strpos,strtoupper" von Hand in die Equivalente mit "mb_" Prefix umwandeln, da der Source sich etwas verändert hat.

Gruß an die Devs.

WintermuteX

Hm, wunderprächtig. Nachdem ich nun die interne Umwandlung nach UTF-8 benutzt habe (ENDLICH!) liefert mir das Spellbook selber dummerweise kein UTF-8 an sondern "reguläre" Umlaute nach ISO-8859-1. Damit ist das Spellchecking WIEDER broken. Hat das irgendein Entwickler überhaupt in einer anderen Sprache als Englisch je getestet?

WintermuteX

Korrektur: Mein Fix funktioniert, man sollte nur nicht so ein Esel sein wie ich und nach einem UPGRADE vergessen von "german" auf "german-utf8" zu stellen.

xduugu

IMHO wird Spellcheck eh bald rausgeschmissen. Das ist die unnötigste Funktion, die ich kenne, vor allem da immer mehr Browser ne Rechtschreibprüfung von Haus aus mitbringen.

WintermuteX

Spellcheck ist eine extrem tolle Funktion. Da die Deutschen ihre Sprache nicht beherrschen sogar eine nötige Funktion.

Advertisement: