Source for file typography.php

Documentation is available at typography.php

  1. <?php
  2. /**
  3.  * Typography Helper
  4.  *
  5.  * PHP Version 5.3.1とCakePHP 1.3.11で動作を確認。
  6.  *
  7.  * @author http://purl.org/meta/me/
  8.  * @version Typography Helper 1.0.1 2011-09-17
  9.  * @license Creative Commons License CC BY (http://creativecommons.org/licenses/by/3.0/)
  10.  */
  11.  
  12. App::import('Helper''Text');
  13.  
  14. App::import('Core''String');
  15.  
  16. /**
  17.  * TypographyHelperクラスはタイポグラフィを手助けするヘルパーです。
  18.  *
  19.  * <code>
  20.  * class ExamplesController extends AppController {
  21.  *     var $helpers = array('Typography');
  22.  * }
  23.  * </code>
  24.  */
  25. class TypographyHelper extends TextHelper {
  26.  
  27.     /**
  28.      * List of helpers used by this helper
  29.      *
  30.      * @var array 
  31.      */
  32.     var $helpers = array('Html');
  33.  
  34.     /**
  35.      * 特別な文字の変換リスト
  36.      *
  37.      * @var array 
  38.      * @access public
  39.      */
  40.     var $specialCharacters = array(
  41.         '(c)' => '&#169;',
  42.         '(C)' => '&#169;',
  43.         '(r)' => '&#174;',
  44.         '(R)' => '&#174;',
  45.         '(tm)' => '&#8482;',
  46.         '(TM)' => '&#8482;',
  47.         '(sm)' => '&#8480;',
  48.         '(SM)' => '&#8480;',
  49.         '(p)' => '&#8471;',
  50.         '(P)' => '&#8471;',
  51.         '...' => '&#8230;'
  52.     );
  53.  
  54.     /**
  55.      * 数学に関する記号の変換リスト
  56.      *
  57.      * @var array 
  58.      * @access public
  59.      */
  60.     var $mathCharacters = array(
  61.         '/([0-9.]+) ?x ?([0-9.]+)/' => '$1&#215;$2',
  62.         '/([0-9.]+) ?X ?([0-9.]+)/' => '$1&#215;$2',
  63.         '/([0-9.]+) ?\* ?([0-9.]+)/' => '$1&#215;$2',
  64.         '/([0-9]+)\/([0-9]+)/' => '<sup>$1</sup>&#8260;<sub>$2</sub>',
  65.         '/([0-9.]+)\^([0-9]+)/' => '$1<sup>$2</sup>'
  66.     );
  67.  
  68.     /**
  69.      * Default map of accented and special characters to ASCII characters
  70.      *
  71.      * @var array 
  72.      * @access public
  73.      * @link http://api.cakephp.org/class/inflector
  74.      */
  75.     var $transliteration = array(
  76.         '/ä|æ|ǽ/' => 'ae',
  77.         '/ö|œ/' => 'oe',
  78.         '/ü/' => 'ue',
  79.         '/Ä/' => 'Ae',
  80.         '/Ü/' => 'Ue',
  81.         '/Ö/' => 'Oe',
  82.         '/À|Á|Â|Ã|Ä|Å|Ǻ|Ā|Ă|Ą|Ǎ/' => 'A',
  83.         '/à|á|â|ã|å|ǻ|ā|ă|ą|ǎ|ª/' => 'a',
  84.         '/Ç|Ć|Ĉ|Ċ|Č/' => 'C',
  85.         '/ç|ć|ĉ|ċ|č/' => 'c',
  86.         '/Ð|Ď|Đ/' => 'D',
  87.         '/ð|ď|đ/' => 'd',
  88.         '/È|É|Ê|Ë|Ē|Ĕ|Ė|Ę|Ě/' => 'E',
  89.         '/è|é|ê|ë|ē|ĕ|ė|ę|ě/' => 'e',
  90.         '/Ĝ|Ğ|Ġ|Ģ/' => 'G',
  91.         '/ĝ|ğ|ġ|ģ/' => 'g',
  92.         '/Ĥ|Ħ/' => 'H',
  93.         '/ĥ|ħ/' => 'h',
  94.         '/Ì|Í|Î|Ï|Ĩ|Ī|Ĭ|Ǐ|Į|İ/' => 'I',
  95.         '/ì|í|î|ï|ĩ|ī|ĭ|ǐ|į|ı/' => 'i',
  96.         '/Ĵ/' => 'J',
  97.         '/ĵ/' => 'j',
  98.         '/Ķ/' => 'K',
  99.         '/ķ/' => 'k',
  100.         '/Ĺ|Ļ|Ľ|Ŀ|Ł/' => 'L',
  101.         '/ĺ|ļ|ľ|ŀ|ł/' => 'l',
  102.         '/Ñ|Ń|Ņ|Ň/' => 'N',
  103.         '/ñ|ń|ņ|ň|ʼn/' => 'n',
  104.         '/Ò|Ó|Ô|Õ|Ō|Ŏ|Ǒ|Ő|Ơ|Ø|Ǿ/' => 'O',
  105.         '/ò|ó|ô|õ|ō|ŏ|ǒ|ő|ơ|ø|ǿ|º/' => 'o',
  106.         '/Ŕ|Ŗ|Ř/' => 'R',
  107.         '/ŕ|ŗ|ř/' => 'r',
  108.         '/Ś|Ŝ|Ş|Š/' => 'S',
  109.         '/ś|ŝ|ş|š|ſ/' => 's',
  110.         '/Ţ|Ť|Ŧ/' => 'T',
  111.         '/ţ|ť|ŧ/' => 't',
  112.         '/Ù|Ú|Û|Ũ|Ū|Ŭ|Ů|Ű|Ų|Ư|Ǔ|Ǖ|Ǘ|Ǚ|Ǜ/' => 'U',
  113.         '/ù|ú|û|ũ|ū|ŭ|ů|ű|ų|ư|ǔ|ǖ|ǘ|ǚ|ǜ/' => 'u',
  114.         '/Ý|Ÿ|Ŷ/' => 'Y',
  115.         '/ý|ÿ|ŷ/' => 'y',
  116.         '/Ŵ/' => 'W',
  117.         '/ŵ/' => 'w',
  118.         '/Ź|Ż|Ž/' => 'Z',
  119.         '/ź|ż|ž/' => 'z',
  120.         '/Æ|Ǽ/' => 'AE',
  121.         '/ß/'=> 'ss',
  122.         '/IJ/' => 'IJ',
  123.         '/ij/' => 'ij',
  124.         '/Œ/' => 'OE',
  125.         '/ƒ/' => 'f'
  126.     );
  127.  
  128.     /**
  129.      * 単位に関する記号の変換リスト
  130.      *
  131.      * @var array 
  132.      * @access public
  133.      */
  134.     var $unitCharacters = array(
  135.         '/([0-9.]+) ?°C/' => '$1&#8451;',
  136.         '/([0-9.]+) ?°F/' => '$1&#8457;',
  137.         '/No. ([0-9]+)/' => '&#8470; $1',
  138.         '/([0-9]+) ?(L|l) /' => '$1 &#8467; ',
  139.         '/([0-9]+) ?(µl|µL) /' => '$1 &#13205; ',
  140.         '/([0-9]+) ?(ml|mL|ML) /' => '$1 &#13206; ',
  141.         '/([0-9]+) ?(dl|dL|DL) /' => '$1 &#13207; ',
  142.         '/([0-9]+) ?(kl|kL|KL) /' => '$1 &#13208; ',
  143.     );
  144.  
  145.     /**
  146.      * UUID
  147.      *
  148.      * @var string 
  149.      * @access protected
  150.      */
  151.     var $_uuid = null;
  152.  
  153.     /**
  154.      * Before render callback. beforeRender is called before the view file is rendered.
  155.      *
  156.      * Overridden in subclasses.
  157.      *
  158.      * @return void 
  159.      * @access public
  160.      */
  161.     function beforeRender({
  162.         parent::beforeRender();
  163.  
  164.         $this->_uuid = String::uuid();
  165.     }
  166.  
  167.     /**
  168.      * n回連続したダッシュを長いダッシュに変換します。
  169.      *
  170.      * <code>
  171.      * $typography->horizontal('-------');
  172.      *
  173.      * # 出力すると以下のようになります。
  174.      * # ————
  175.      * </code>
  176.      *
  177.      * @param string $string 処理を行う文字列
  178.      * @param integer $int 何回連続したダッシュを変換するのか
  179.      * @return string n回連続したダッシュが長いダッシュに変換された文字列
  180.      * @access public
  181.      */
  182.     function horizontal($string$int 2{
  183.         return preg_replace_callback(
  184.             '/-{' $int ',}/',
  185.             create_function(
  186.                 '$matches',
  187.                 'return strtr($matches[0], array("--" => "—", "-" => "—"));'
  188.             ),
  189.             $string
  190.         );
  191.     }
  192.  
  193.     /**
  194.      * 数学記号に変換します。
  195.      *
  196.      * <code>
  197.      * $typography->mathCharacters('Multiplication 100x100 Fraction 1/2');
  198.      *
  199.      * # 出力すると以下のようになります。
  200.      * # Multiplication 100&#215;100 Fraction <sup>1</sup>&#8260;<sub>2</sub>
  201.      * </code>
  202.      *
  203.      * @param string $string 処理を行う文字列
  204.      * @return string 数学記号に変換された文字列
  205.      * @access public
  206.      */
  207.     function mathCharacters($string{
  208.         return preg_replace(array_keys($this->mathCharacters)array_values($this->mathCharacters)$string);
  209.     }
  210.  
  211.     /**
  212.      * 基本的にはnl2brと同じ処理をしますが特定の要素内での処理は除くことができます。
  213.      *
  214.      * <code>
  215.      * $typography->nl2brExcept("foo isn't\n bar\n\n<pre>\n pre Element\n</pre>");
  216.      *
  217.      * # 出力すると以下のようになります。
  218.      * # foo isn't<br />
  219.      * #  bar<br />
  220.      * # <br />
  221.      * # <pre>
  222.      * #  pre Element
  223.      * # </pre>
  224.      * </code>
  225.      *
  226.      * @param string $string 入力する文字列
  227.      * @param array $except 処理を除く要素の配列
  228.      * @param boolean $is_xhtml trueの場合はXHTMLに対応した&lt;br /&gt;、falseの場合はHTMLに対応した&lt;br&gt;になります。
  229.      * @return string 改行がbr要素に変換された文字列
  230.      * @access public
  231.      */
  232.     function nl2brExcept($string$except array('pre')$is_xhtml true{
  233.         $newstr $this->__replaceEncode($string$except);
  234.  
  235.         if(version_compare(PHP_VERSION'5.3.0'>= 0{
  236.             $newstr nl2br($newstr$is_xhtml);
  237.         else {
  238.             $newstr nl2br($newstr);
  239.         }
  240.  
  241.         return $this->__replaceDecode($newstr);
  242.     }
  243.  
  244.     /**
  245.      * 改行の前にリターン記号を追加します。
  246.      *
  247.      * <code>
  248.      * $typography->nl2carriageReturn("foo\nbar");
  249.      *
  250.      * # 出力すると以下のようになります。
  251.      * # foo↵
  252.      * # bar
  253.      * </code>
  254.      *
  255.      * @param string $string 処理を行う文字列
  256.      * @param return $return リターン記号
  257.      * @return string 変換された文字列
  258.      * @access public
  259.      */
  260.     function nl2carriageReturn($string$return '↵'{
  261.         return strtr($stringarray("\r\n" => $return "\r\n""\r" => $return "\r""\n" => $return "\n"));
  262.     }
  263.  
  264.     /**
  265.      * URLを正規化します。
  266.      *
  267.      * <code>
  268.      * $typography->normalizeUrl('hxxp URL ttp://example.com/ or hxxp://example.com/example/');
  269.      *
  270.      * # 出力すると以下のようになります。
  271.      * # hxxp URL http://example.com/ or http://example.com/example/
  272.      * </code>
  273.      *
  274.      * @param string $string 処理を行う文字列
  275.      * @return string URLを正規化した文字列
  276.      * @access public
  277.      */
  278.     function normalizeUrl($string{
  279.         $noPchar '[-_.!~*\'()a-zA-Z0-9;\/?:\@&=+\$,%#]+';
  280.         return preg_replace('/(htp|ttp|tp|hxxp|h\+\+p|h\*\*p||ht_tp|htt|_ttp)(s?:\/\/' $noPchar ')/''http$2'$string);
  281.     }
  282.  
  283.     /**
  284.      * URLを正規化してリンクに変換します。
  285.      *
  286.      * <code>
  287.      * $typography->normalizeUrlLink('hxxp URL ttp://example.com/ or hxxp://example.com/example/', array('rel' => 'nofollow'));
  288.      *
  289.      * # 出力すると以下のようになります。
  290.      * # hxxp URL <a href="http://example.com/" rel="nofollow">http://example.com/</a> or <a href="http://example.com/example/" rel="nofollow">http://example.com/example/</a>
  291.      * </code>
  292.      *
  293.      * @param string $string 処理を行う文字列
  294.      * @param array $options Array of HTML options.
  295.      * @return string URLを正規化してリンクに変換された文字列
  296.      * @access public
  297.      */
  298.     function normalizeUrlLink($string$options array()) {
  299.         return $this->autoLink($this->normalizeUrl($string)$options);
  300.     }
  301.  
  302.     /**
  303.      * a要素内のURLを短くします。
  304.      *
  305.      * <code>
  306.      * echo $typography->shortenUrl('The Aristotle <a href="http://ja.wikipedia.org/wiki/%E3%82%A2%E3%83%AA%E3%82%B9%E3%83%88%E3%83%86%E3%83%AC%E3%82%B9">http://ja.wikipedia.org/wiki/%E3%82%A2%E3%83%AA%E3%82%B9%E3%83%88%E3%83%86%E3%83%AC%E3%82%B9</a>', 30, '…');
  307.      *
  308.      * # 出力すると以下のようになります。
  309.      * # The Aristotle <a href="http://ja.wikipedia.org/wiki/%E3%82%A2%E3%83%AA%E3%82%B9%E3%83%88%E3%83%86%E3%83%AC%E3%82%B9">http://ja.wikipedia.org/wiki/%…</a>
  310.      * </code>
  311.      *
  312.      * @param string $string 入力する文字列
  313.      * @param integer $length 何文字まで切り詰めるか
  314.      * @param string $ending 切り詰めた後の文字列
  315.      * @return string a要素内のURLを短くされた文字列
  316.      * @access public
  317.      */
  318.     function shortenUrl($string$length 50$ending null{
  319.         $ending var_export($endingtrue);
  320.  
  321.         return preg_replace_callback(
  322.             '/(<a.*?>)((https?|ftp)(:\/\/[-_.!~*\'()a-zA-Z0-9;\/?:\@&=+\$,%#]+?))<\/a>/',
  323.             create_function(
  324.                 '$matches',
  325.                 'return $matches[1] . substr($matches[2], 0, ' $length ') . ' $ending ' . "</a>";'
  326.             ),
  327.             $string
  328.         );
  329.     }
  330.  
  331.     /**
  332.      * 一部の記述を記号文字へ変換します。
  333.      *
  334.      * <code>
  335.      * $typography->specialCharacters('Copyright (C) 2011 example.com All Rights Reserved.');
  336.      *
  337.      * # 出力すると以下のようになります。
  338.      * # Copyright &#169; 2011 example.com All Rights Reserved.
  339.      * </code>
  340.      *
  341.      * @param string $string 処理を行う文字列
  342.      * @return string 変換された文字列
  343.      * @access public
  344.      */
  345.     function specialCharacters($string{
  346.         return strtr($string$this->specialCharacters);
  347.     }
  348.  
  349.     /**
  350.      * 改行やタブ文字などを消去します。
  351.      *
  352.      * <code>
  353.      * $typography->trim("<p>\r\nWelcome This is my HTML document\r\n</p>");
  354.      *
  355.      * # 出力すると以下のようになります。
  356.      * # <p>Welcome This is my HTML document</p>
  357.      * </code>
  358.      *
  359.      * @param string $string 入力する文字列
  360.      * @return string 改行やタブ文字などを消去された文字列
  361.      * @access public
  362.      */
  363.     function trim($string{
  364.         return str_replace(array("\r""\n""\t""\0""\x0B")''$string);
  365.     }
  366.  
  367.     /**
  368.      * 基本的にはtrimと同じ処理をしますが特定の要素内での処理は除くことができます。
  369.      *
  370.      * <code>
  371.      * $typography->trimExcept("<p>\r\nWelcome This is my HTML document\r\n</p>\r\n<pre>\r\n pre Element\r\n</pre>");
  372.      *
  373.      * # 出力すると以下のようになります。
  374.      * # <p>Welcome This is my HTML document</p><pre>
  375.      * #  pre Element
  376.      * # </pre>
  377.      * </code>
  378.      *
  379.      * @param string $string 入力する文字列
  380.      * @param array $except 処理を除く要素の配列
  381.      * @return string 改行やタブ文字などを消去された文字列
  382.      * @access public
  383.      */
  384.     function trimExcept($string$except array('pre''script')) {
  385.         $newstr $this->__replaceEncode($string$except);
  386.  
  387.         $newstr $this->trim($newstr);
  388.  
  389.         return $this->__replaceDecode($newstr);
  390.     }
  391.  
  392.     /**
  393.      * 2回以上連続するスペースとタブ文字を1つのスペースに変換します。
  394.      *
  395.      * <code>
  396.      * $typography->trimScrapes("Double Scrape  and\tTab");
  397.      *
  398.      * # 出力すると以下のようになります。
  399.      * # Double Scrape and Tab
  400.      * </code>
  401.      *
  402.      * @param string $string 処理を行う文字列
  403.      * @return string 変換された文字列
  404.      * @access public
  405.      */
  406.     function trimScrapes($string{
  407.         return preg_replace(array('/ {2,}/''/\\t{1,}/')' '$string);
  408.     }
  409.  
  410.     /**
  411.      * 文字列を一行にし、2回以上連続するスペースを1つにします。
  412.      *
  413.      * <code>
  414.      * $typography->oneLine("oneLine Test.\r\nDouble Scrape  and\tTab");
  415.      *
  416.      * # 出力すると以下のようになります。
  417.      * # oneLine Test. Double Scrape and Tab
  418.      * </code>
  419.      *
  420.      * @param string $string 処理を行う文字列
  421.      * @return string 一行に変換された文字列
  422.      * @access public
  423.      */
  424.     function oneLine($string{
  425.         $string str_replace(array("\r""\n""\0""\x0B")' '$string);
  426.         return $this->trimScrapes($string);
  427.     }
  428.  
  429.     /**
  430.      * 改行をp要素とbr要素に変換します。
  431.      *
  432.      * 2回以上連続する改行をp要素に変換します。単一の改行はbr要素に変換します。
  433.      *
  434.      * <code>
  435.      * $typography->paragraph("paragraph method Test\r\nbr Elements\r\n\r\np Elements\r\n\r\n\r\nend.");
  436.      *
  437.      * # 出力すると以下のようになります。
  438.      * # <p>paragraph method Test<br />
  439.      * # br Elements</p><p>p Elements</p><p>end.</p>
  440.      * </code>
  441.      *
  442.      * @param string $string 処理を行う文字列
  443.      * @param array $options p要素のオプション
  444.      * @return string 改行がp要素またはbr要素に変換された文字列
  445.      * @access public
  446.      */
  447.     function paragraph($string$options array()) {
  448.         if(isset($options['is_xhtml'])) {
  449.             $is_xhtml $options['is_xhtml'];
  450.  
  451.             unset($options['is_xhtml']);
  452.         else {
  453.             $is_xhtml true;
  454.         }
  455.  
  456.         $string str_replace("\r"''$string);
  457.  
  458.         $array explode("\n\n"$string);
  459.  
  460.         $out '';
  461.         foreach($array as $key => $value{
  462.             if(trim($value)) {
  463.                 $pElement $this->Html->para(nulltrim($value)$options);
  464.  
  465.                 if(version_compare(PHP_VERSION'5.3.0'>= 0{
  466.                     $out .= nl2br($pElement$is_xhtml);
  467.                 else {
  468.                     $out .= nl2br($pElement);
  469.                 }
  470.             }
  471.         }
  472.  
  473.         return $out;
  474.     }
  475.  
  476.     /**
  477.      * タブ文字をスペースに変換します。
  478.      *
  479.      * <code>
  480.      * echo $typography->tabToScrape("tabToScrape\tTest");
  481.      *
  482.      * # 出力すると以下のようになります。
  483.      * # tabToScrape    Test
  484.      * </code>
  485.      *
  486.      * @param string $string 処理を行う文字列
  487.      * @param integer $multiplier タブ文字をスペース何個分に変換するか
  488.      * @return string タブ文字がスペースに変換された文字列
  489.      * @access public
  490.      */
  491.     function tabToScrape($string$multiplier 4{
  492.         return strtr($stringarray("\t" => str_repeat(' '$multiplier)));
  493.     }
  494.  
  495.     /**
  496.      * ASCI文字に変換します。
  497.      *
  498.      * @param string $string 処理を行う文字列
  499.      * @return string ASCI文字に変換された文字列
  500.      * @access public
  501.      */
  502.     function transliteration($string{
  503.         return preg_replace(array_keys($this->transliteration)array_values($this->transliteration)$string);
  504.     }
  505.  
  506.     /**
  507.      * 単位記号に変換します。
  508.      *
  509.      * <code>
  510.      * $typography->unitCharacters('100 L 100 °C 100 °C No. 100');
  511.      *
  512.      * # 出力すると以下のようになります。
  513.      * # 100 &#8467; 100&#8451; 100&#8451; &#8470; 100
  514.      * </code>
  515.      *
  516.      * @param string $string 処理を行う文字列
  517.      * @return string 単位記号に変換された文字列
  518.      * @access public
  519.      */
  520.     function unitCharacters($string{
  521.         return preg_replace(array_keys($this->unitCharacters)array_values($this->unitCharacters)$string);
  522.     }
  523.  
  524.     function __replaceEncode($string$except array()) {
  525.         if(is_string($except)) {
  526.             $except array($except);
  527.         }
  528.  
  529.         $replace '/' implode('|'array_map(
  530.             create_function(
  531.                 '$value',
  532.                 '
  533.                     if(is_array($value) && isset($value["start"]) && isset($value["end"])) {
  534.                         return preg_quote($value["start"], "/") . ".*?" . preg_quote($value["end"], "/");
  535.                     }
  536.                     return "<" . $value . ".*?>.*?<\\/" . $value . ">";
  537.                 '
  538.             ),
  539.             $except
  540.         )) '/s';
  541.  
  542.         return preg_replace_callback($replacecreate_function('$matches''
  543.             return "<" . base64_encode($matches[0]) . "<' $this->_uuid . '>>";
  544.         ')$string);
  545.     }
  546.  
  547.     function __replaceDecode($string{
  548.         return preg_replace_callback('/<([\w+\/=]+?)<' $this->_uuid . '>>/'create_function('$matches''
  549.             return base64_decode($matches[1]);
  550.         ')$string);
  551.     }
  552. }
  553. ?>

Documentation generated on Sat, 17 Sep 2011 04:30:04 +0000 by phpDocumentor 1.4.3