includes/wikiengine/Parse/Mediawiki/Wikilink.php
changeset 1027 98c052fc3337
parent 1026 f0431eb8161e
child 1028 dde4416dea00
equal deleted inserted replaced
1026:f0431eb8161e 1027:98c052fc3337
     1 <?php
       
     2 // vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4:
       
     3 /**
       
     4  * Mediawiki: Parses for links to (inter)wiki pages or images.
       
     5  *
       
     6  * Text_Wiki rule parser to find links, it groups the 3 rules:
       
     7  * # Wikilink: links to internal Wiki pages
       
     8  * # Interwiki: links to external Wiki pages (sister projects, interlangage)
       
     9  * # Image: Images
       
    10  * as defined by text surrounded by double brackets [[]]
       
    11  * Translated are the link itself, the section (anchor) and alternate text
       
    12  *
       
    13  * PHP versions 4 and 5
       
    14  *
       
    15  * @category   Text
       
    16  * @package    Text_Wiki
       
    17  * @author     Bertrand Gugger <bertrand@toggg.com>
       
    18  * @author     Paul M. Jones <pmjones@php.net>
       
    19  * @copyright  2005 bertrand Gugger
       
    20  * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1
       
    21  * @version    CVS: $Id: Wikilink.php,v 1.7 2006/02/25 13:34:50 toggg Exp $
       
    22  * @link       http://pear.php.net/package/Text_Wiki
       
    23  */
       
    24 
       
    25 /**
       
    26  * Wikilink, Interwiki and Image rules parser class for Mediawiki.
       
    27  * This class implements a Text_Wiki_Parse to find links marked
       
    28  * in source by text surrounded by 2 opening/closing brackets as 
       
    29  * [[Wiki page name#Section|Alternate text]]
       
    30  * On parsing, the link is replaced with a token.
       
    31  *
       
    32  * @category   Text
       
    33  * @package    Text_Wiki
       
    34  * @author     Bertrand Gugger <bertrand@toggg.com>
       
    35  * @copyright  2005 bertrand Gugger
       
    36  * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1
       
    37  * @version    Release: @package_version@
       
    38  * @link       http://pear.php.net/package/Text_Wiki
       
    39  * @see        Text_Wiki_Parse::Text_Wiki_Parse()
       
    40  */
       
    41 class Text_Wiki_Parse_Wikilink extends Text_Wiki_Parse {
       
    42 
       
    43     /**
       
    44      * Configuration for this rule (Wikilink)
       
    45      *
       
    46      * @access public
       
    47      * @var array
       
    48     */
       
    49     var $conf = array(
       
    50         'spaceUnderscore' => true,
       
    51         'project' => array('demo', 'd'),
       
    52         'url' => 'http://example.com/en/page=%s',
       
    53         'langage' => 'en'
       
    54     );
       
    55 
       
    56     /**
       
    57      * Configuration for the Image rule
       
    58      *
       
    59      * @access public
       
    60      * @var array
       
    61     */
       
    62     var $imageConf = array(
       
    63         'prefix' => array('Image', 'image')
       
    64     );
       
    65 
       
    66     /**
       
    67      * Configuration for the Interwiki rule
       
    68      *
       
    69      * @access public
       
    70      * @var array
       
    71     */
       
    72     var $interwikiConf = array(
       
    73         'sites' => array(
       
    74             'manual' => 'http://www.php.net/manual/en/%s',
       
    75             'pear'   => 'http://pear.php.net/package/%s',
       
    76             'bugs'   => 'http://pear.php.net/package/%s/bugs'
       
    77         ),
       
    78         'interlangage' => array('en', 'de', 'fr')
       
    79     );
       
    80 
       
    81     /**
       
    82      * The regular expression used to parse the source text and find
       
    83      * matches conforming to this rule.  Used by the parse() method.
       
    84      *
       
    85      * @access public
       
    86      * @var string
       
    87      * @see Text_Wiki_Parse::parse()
       
    88      */
       
    89     var $regex = '/(?<!\[)\[\[(?!\[)\s*(:?)((?:[^:]+:)+)?([^:]+)(?:#(.*))?\s*(?:\|(((?R))|.*))?]]/msU';
       
    90 
       
    91      /**
       
    92      * Constructor.
       
    93      * We override the constructor to get Image and Interwiki config
       
    94      *
       
    95      * @param object &$obj the base conversion handler
       
    96      * @return The parser object
       
    97      * @access public
       
    98      */
       
    99     function Text_Wiki_Parse_Wikilink(&$obj)
       
   100     {
       
   101         $default = $this->conf;
       
   102         parent::Text_Wiki_Parse($obj);
       
   103         
       
   104         if ( defined('IN_ENANO_INSTALL') )
       
   105         {
       
   106           // This doesn't really matter in the installer
       
   107           $this->imageConf = array(
       
   108             'prefix' => array(':File:')
       
   109             );
       
   110         }
       
   111         else
       
   112         {
       
   113           global $paths;
       
   114           $this->imageConf = array(
       
   115             'prefix' => array(':' . $paths->nslist['File'])
       
   116             );
       
   117         }
       
   118 
       
   119         // override config options for image if specified
       
   120         if (in_array('Image', $this->wiki->disable)) {
       
   121             $this->imageConf['prefix'] = array();
       
   122         } else {
       
   123             if (isset($this->wiki->parseConf['Image']) &&
       
   124                 is_array($this->wiki->parseConf['Image'])) {
       
   125                 $this->imageConf = array_merge(
       
   126                     $this->imageConf,
       
   127                     $this->wiki->parseConf['Image']
       
   128                 );
       
   129             }
       
   130         }
       
   131 
       
   132         // override config options for interwiki if specified
       
   133         if (in_array('Interwiki', $this->wiki->disable)) {
       
   134             $this->interwikiConf['sites'] = array();
       
   135             $this->interwikiConf['interlangage'] = array();
       
   136         } else {
       
   137             if (isset($this->wiki->parseConf['Interwiki']) &&
       
   138                 is_array($this->wiki->parseConf['Interwiki'])) {
       
   139                 $this->interwikiConf = array_merge(
       
   140                     $this->interwikiConf,
       
   141                     $this->wiki->parseConf['Interwiki']
       
   142                 );
       
   143             }
       
   144             if (empty($this->conf['langage'])) {
       
   145                 $this->interwikiConf['interlangage'] = array();
       
   146             }
       
   147         }
       
   148         // convert the list of recognized schemes to a regex OR,
       
   149 /*        $schemes = $this->getConf('schemes', $default['schemes']);
       
   150         $this->url = str_replace( '#delim#', $this->wiki->delim,
       
   151            '#(?:' . (is_array($schemes) ? implode('|', $schemes) : $schemes) . ')://'
       
   152            . $this->getConf('host_regexp', $default['host_regexp'])
       
   153            . $this->getConf('path_regexp', $default['path_regexp']) .'#'); */
       
   154     }
       
   155 
       
   156     /**
       
   157      * Generates a replacement for the matched text.  Token options are:
       
   158      * - 'page' => the name of the target wiki page
       
   159      * -'anchor' => the optional section in it
       
   160      * - 'text' => the optional alternate link text
       
   161      *
       
   162      * @access public
       
   163      * @param array &$matches The array of matches from parse().
       
   164      * @return string token to be used as replacement 
       
   165      */
       
   166     function process(&$matches)
       
   167     {
       
   168         // Starting colon ?
       
   169         $colon = !empty($matches[1]);
       
   170         $auto = $interlang = $interwiki = $image = $site = '';
       
   171         // Prefix ?
       
   172         if (!empty($matches[2])) {
       
   173             $prefix = explode(':', substr($matches[2], 0, -1));
       
   174             $count = count($prefix);
       
   175             $i = -1;
       
   176             // Autolink
       
   177             if (isset($this->conf['project']) &&
       
   178                     in_array(trim($prefix[0]), $this->conf['project'])) {
       
   179                 $auto = trim($prefix[0]);
       
   180                 unset($prefix[0]);
       
   181                 $i = 0;
       
   182             }
       
   183             while (++$i < $count) {
       
   184                 $prefix[$i] = trim($prefix[$i]);
       
   185                 // interlangage
       
   186                 if (!$interlang &&
       
   187                     in_array($prefix[$i], $this->interwikiConf['interlangage'])) {
       
   188                     $interlang = $prefix[$i];
       
   189                     unset($prefix[$i]);
       
   190                     continue;
       
   191                 }
       
   192                 // image
       
   193                 if (!$image && in_array($prefix[$i], $this->imageConf['prefix'])) {
       
   194                     $image = $prefix[$i];
       
   195                     unset($prefix[$i]);
       
   196                     break;
       
   197                 }
       
   198                 // interwiki
       
   199                 if (isset($this->interwikiConf['sites'][$prefix[$i]])) {
       
   200                     $interwiki = $this->interwikiConf['sites'][$prefix[$i]];
       
   201                     $site = $prefix[$i];
       
   202                     unset($prefix[$i]);
       
   203                 }
       
   204                 break;
       
   205             }
       
   206             if ($prefix) {
       
   207                 $matches[3] = implode(':', $prefix) . ':' . $matches[3];
       
   208             }
       
   209         }
       
   210         $text = empty($matches[5]) ? $matches[3] : $matches[5];
       
   211         $matches[3] = trim($matches[3]);
       
   212         $matches[4] = empty($matches[4]) ? '' : trim($matches[4]);
       
   213         if ($this->conf['spaceUnderscore']) {
       
   214             $matches[3] = preg_replace('/\s+/', '_', $matches[3]);
       
   215             $matches[4] = preg_replace('/\s+/', '_', $matches[4]);
       
   216         }
       
   217         if ($image) {
       
   218             return $this->image($matches[3] . (empty($matches[4]) ? '' : '#' . $matches[4]),
       
   219                                 $text, $interlang, $colon);
       
   220         }
       
   221         if (!$interwiki && $interlang && isset($this->conf['url'])) {
       
   222             if ($interlang == $this->conf['langage']) {
       
   223                 $interlang = '';
       
   224             } else {
       
   225                 $interwiki = $this->conf['url'];
       
   226                 $site = isset($this->conf['project']) ? $this->conf['project'][0] : '';
       
   227             }
       
   228         }
       
   229         if ($interwiki) {
       
   230             return $this->interwiki($site, $interwiki,
       
   231                 $matches[3] . (empty($matches[4]) ? '' : '#' . $matches[4]),
       
   232                 $text, $interlang, $colon);
       
   233         }
       
   234         if ($interlang) {
       
   235             $matches[3] = $interlang . ':' . $matches[3];
       
   236             $text = (empty($matches[5]) ? $interlang . ':' : '') . $text;
       
   237         }
       
   238         // set the options
       
   239         $options = array(
       
   240             'page'   => $matches[3],
       
   241             'anchor' => (empty($matches[4]) ? '' : $matches[4]),
       
   242             'text'   => $text
       
   243         );
       
   244 
       
   245         // create and return the replacement token
       
   246         return $this->wiki->addToken($this->rule, $options);
       
   247     }
       
   248 
       
   249     /**
       
   250      * Generates an image token.  Token options are:
       
   251      * - 'src' => the name of the image file
       
   252      * - 'attr' => an array of attributes for the image:
       
   253      * | - 'alt' => the optional alternate image text
       
   254      * | - 'align => 'left', 'center' or 'right'
       
   255      *
       
   256      * @access public
       
   257      * @param array &$matches The array of matches from parse().
       
   258      * @return string token to be used as replacement 
       
   259      */
       
   260     function image($name, $text, $interlang, $colon)
       
   261     {
       
   262         $attr = array('alt' => '');
       
   263         // scan text for supplementary attibutes
       
   264         if (strpos($text, '|') !== false) {
       
   265             $splits = explode('|', $text);
       
   266             $sep = '';
       
   267             foreach ($splits as $split) {
       
   268                 switch (strtolower($split)) {
       
   269                     case 'left': case 'center': case 'right':
       
   270                         $attr['align'] = strtolower($split);
       
   271                         break;
       
   272                     default:
       
   273                         $attr['alt'] .= $sep . $split;
       
   274                         $sep = '|';
       
   275                 }
       
   276             }
       
   277         } else {
       
   278             $attr['alt'] = $text;
       
   279         }
       
   280         $options = array(
       
   281             'src' => ($interlang ? $interlang . ':' : '') . $name,
       
   282             'attr' => $attr);
       
   283 
       
   284         // create and return the replacement token
       
   285         return $this->wiki->addToken('Image', $options);
       
   286     }
       
   287 
       
   288     /**
       
   289      * Generates an interwiki token.  Token options are:
       
   290      * - 'page' => the name of the target wiki page
       
   291      * - 'site' => the key for external site
       
   292      * - 'url'  => the full target url
       
   293      * - 'text' => the optional alternate link text
       
   294      *
       
   295      * @access public
       
   296      * @param array &$matches The array of matches from parse().
       
   297      * @return string token to be used as replacement 
       
   298      */
       
   299     function interwiki($site, $interwiki, $page, $text, $interlang, $colon)
       
   300     {
       
   301         if ($interlang) {
       
   302             $interwiki = preg_replace('/\b' . $this->conf['langage'] . '\b/i',
       
   303                             $interlang, $interwiki);
       
   304         }
       
   305         // set the options
       
   306         $options = array(
       
   307             'page' => $page,
       
   308             'site' => $site,
       
   309             'url'  => sprintf($interwiki, $page),
       
   310             'text' => $text
       
   311         );
       
   312 
       
   313         // create and return the replacement token
       
   314         return $this->wiki->addToken('Interwiki', $options);
       
   315     }
       
   316 }
       
   317 ?>