k47.cz    — každý den dokud se vám to nezačne líbit
foto Praha výběr povídky kultura | twitter FB


««« »»»

Typografické udělátko

9. 7. 2009 — k47 (CC by-nc-sa)

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"
 * Karel 'kaja47' Čížek (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!

vstoupit do diskuze    sdílet na facebooku, twitteru, google+

štítky: #programování «« »» #obsah «« »» #dev #projekty #PHP #typografie

příbuzné články:
PHP Objektová obálka pspell 📷
get_calling_class() pro PHP 5.2 📷
Konzolové aplikace: DevTodo 📷
Nette JamendoControl 📷
Nette CachedControl 📷
TwitterControl 📷

píše k47 & hosté, ascii@k47.cz