Typografické udělátko
Všechny vtipy, které teď na stránkách vtipy.k47.cz vydávám za své jsem ukradl. Pochopitelně. Přece bych sám nedokázal vyprodukovat 26 tisíc vtipů. To není v silách jednotlivce. Krádež byla vcelku rychlou a pohodlnou cestou, jak vybudovat největší databázi vtipů na českých interwebech. Ale má to svou stinnou stránku – kvalitu. Teď nenarážím na to, že některé vtipy jsou špatné nebo bůh ví co (každému se navíc líbí něco jiného, žejo), ale na úroveň textu, gramatiku a zásady typografie. Jelikož byl zdrojem lid – a lid vůbec neumí psát správně česky – pak je jasné, že to místy stojí za hovno.
Lidi z nepochopitelných důvodů rádi píšou bez háčků a bez čárek, někdy si vystačí jenom s velkými písmeny, vyprodukují spoustu chyb v y/i, mě/mně a hlavně ta typografie. Za čárkou, tečkou, vykřičníkem, otazníkem, dvojtečkou a středníkem se píše mezera, nikdy ne před ním. Interpunkční znaménko stačí jedno, nejsou potřeba tři vykřičníky. Ale v případě takové trojtečky, jsou třeba přesně tři tečky ne dvě, ne deset. Panebože, je to tak těžký? Není. Navíc nejde o nějaké vymyšlenosti, protože text, kde se dodržují tyto (a další) pravidla se čte mnohem lépe, než nějaká samo-domo zmršenina.
Navíc vtipy jsou už z podstaty věci vtipné a proto tam není třeba cpát smajlíky. To člověk pochopí, že je to vtip. Boha jeho.
A protože mě tyhle věci štvaly a chtěl jsem trochu pozvednout úroveň vtipů, napsal jsem si malou PHP třídu TypographCorrector, která přesně tyhle věci řeší.
Jednoduše stačí zavolat TypographCorrector::correct('To,co chci zkorektůrovat
? :D olol')
a výsledkem je krásný opravený text. Dokonce se metoda snaží
detekovat případ, kdy je celý text napsaný velkými písmeny. V tom případě text
převede na malé písmo s výjimkami začátků vět (má to nějaké chyby, jako třeba,
že zvětší písmeno i za pořadovým číslem, ale je to pořád lepší než zlo SE
ZAPNUTÝM CAPSLOCKEM).
A teď kód:
<?php /** * Třída, která se snaží napravit aspoň nějaké prohřešky proti typografickým pravidlům. * * Něco málo o typografii: http://www.pixy.cz/pixylophone/2003_02_archiv.html#1046432237 * * ---------------------------------------------------------------------------- * "BEER-WARE LICENSE" * XXXXX 'kaja47' XXXXX (k47.cz) stvořil tento soubor. * Dokud ponecháte tuto hlavičku s licencí beze změna, můžete si s kusem kódu * pod ní dělat, co se vám zlíbí. Když se někdy potkáme a vy si budete myslet, * že za to tahle věc stojí, můžete mi na oplátku koupit pivo. * ---------------------------------------------------------------------------- * */ class TypographCorrector { /** * @param string $text */ public static function correct($text, $removeSmiles = TRUE) { // odstraní opakované vykřičníky nebo otazníky $text = preg_replace('#\!{2,}#', '!', $text); $text = preg_replace('#\?{2,}#', '?', $text); // odstraní smajlíky if ($removeSmiles === TRUE) { $text = preg_replace(array('#\:\)+(?! )#', '#\:D+(?= )#'), '', $text); } // více mezer za sebou zredukuje na jednu $text = preg_replace('# +#', ' ', $text); // více než tři tečky za sebou zredukuje na tři $text = preg_replace('#\.{4,}#', '...', $text); // dvě tečky za sebou zredukuje na jednu (předpokládá, že to neměla být trojtečka) $text = preg_replace('#([^\.])\.\.([^\.])#', '\\1.\\2', $text); // mezera po interpunkčním znaménku // když po ,.;:?! rovnou následuje písmeno, pak za ní udělá mezeru $text = preg_replace('#([,\.;\:\?\!])([a-zA-Záčďéíňóřšťúůýž])#', '\\1 \\2', $text); // odstraní mezery před interpunkčními znaménky $text = preg_replace('# ([,\.;\:\?\!])#', '\\1', $text); if (self::isMostlyUpperCase($text)) { $text = self::guessUpperCaseLetters($text); } return trim($text); } private static function isMostlyUpperCase($text, $limit = 0.45) { $upperCaseLetters = preg_match_all('#[A-ZÁČĎÉÍŇÓŘŠŤÚŮÝŽ]#', $text, $m); $allLetters = mb_strlen($text); return ( $upperCaseLetters / $allLetters ) > $limit; } private static function guessUpperCaseLetters($text) { $text = mb_strtolower($text, 'utf8'); $s = preg_split('#([\.\?\!] )#', $text, -1, PREG_SPLIT_DELIM_CAPTURE); for ($i = 0 ; $i < count($s) ; $i+=2) { $sentences[] = $s[$i] . ( isset($s[$i+1]) ? $s[$i+1] : '' ) ; } foreach ($sentences as $key => $sentence) { $sentences[$key] = ucfirst($sentence); } $text = implode('', $sentences); return $text; } }
Když už se rozhodnete pro dvojtakt copy-paste (což schvaluji a budu moc rád, když to použijete a dosáhnu nirvány, když do komentářů napíšete, že jste to skutečně použili), věnujte pozornost hlavně licenci. Jde o beerware!