Вход Регистрация
Файл: upload/include/library/phpfox/parse/wiki.class.php
Строк: 426
<?php
/**
 * [PHPFOX_HEADER]
 */

defined('PHPFOX') or exit('NO DICE!');

/**
 * WIKI Parser
 * Clones how a common WIKI works and allows the ability for users
 * to use WIKI code to create pages.
 * 
 * @copyright        [PHPFOX_COPYRIGHT]
 * @author            Raymond Benc
 * @package         Phpfox
 * @version         $Id: wiki.class.php 1668 2010-07-12 08:54:32Z Raymond_Benc $
 */
class Phpfox_Parse_Wiki 
{    
    
/**
     * Common regex for HTML.
     *
     * @var array
     */
    
private $_sLineRegexes = array(
        
'preformat' => '^s(.*?)$',
        
'definitionlist' => '^([;:])s*(.*?)$',
        
'newline' => '^$',
        
'list' => '^([*#]+)(.*?)$',
        
'sections' => '^(={1,6})(.*?)(={1,6})$',
        
'horizontalrule' => '^----$'
    
);
        
    
/**
     * Common character regex.
     *
     * @var array
     */
    
private    $_sCharRegexes = array(
        
'internallink' => '([[(([^]]*?):)?([^]]*?)(|([^]]*?))?]]([a-z]+)?)',
        
'externallink' => '([([^]]*?)(s+[^]]*?)?])',
        
'emphasize' => '('{2,5})',
        '
eliminate' => '(__TOC__|__NOTOC__|__NOEDITSECTION__)',
        '
variable' => '({{([^}]*?)}})'
    );    
        
    /**
     * Reference within links.
     *
     * @var string
     */
    private $_sReferenceWiki;
    
    /**
     * Image URI.
     *
     * @var string
     */
    private $_sImageUri;
    
    /**
     * BOOL to ignore images or not.
     *
     * @var bool
     */
    private $_bIgnoreImages = true;
    
    /**
     * Redirect links.
     *
     * @var bool
     */
    private $_bRedirect = false;
    
    /**
     * Format <pre>.
     *
     * @var bool
     */
    private $_bPreformat = false;
    
    /**
     * ARRAY of emphasis tags.
     *
     * @var array
     */
    private $_aEmphasis = array();
    
    /**
     * ARRAY of support nowiki tags.
     *
     * @var array
     */
    private $_aNoWikis = array();
    
    /**
     * <ul> list level types.
     *
     * @var array
     */
    private $_aListLevelTypes = array();
    
    /**
     * Define how many levels a list has.
     *
     * @var int
     */
    private $_iListLevel = 0;
    
    /**
     * Support for <dl>.
     *
     * @var bool
     */
    private $_bDefList = false;
    
    /**
     * Link number.
     *
     * @var int
     */
    private $_iLinkNumber = 0;
    
    /**
     * Supress link breaks.
     *
     * @var bool
     */
    private $_bSuppressLinebreaks = false;
    
    /**
     * Create a link break.
     *
     * @var bool
     */
    private $_bStop = false;
    
    /**
     * Class constructor.
     *
     */
    public function __construct()
    {
    }
    
    /**
     * Parse string and converts WIKI code into HTML.
     *
     * @param string $sText Text to parse.
     * @param string $sTitle Title of this page.
     * @return string Converted text from WIKI to HTML.
     */
    public function parse($sText, $sTitle = '') 
    {        
        $sText = preg_replace_callback('
/<nowiki>([sS]*)</nowiki>/i', array(&$this, "_handleSaveNoWiki"), $sText);

        $aLines = explode("n", $sText);
        
        if (preg_match('
/^#REDIRECTs+[[(.*?)]]$/', trim($aLines[0]), $aMatches)) 
        
{
            
$this->_bRedirect $aMatches[1];
        }
        
        
$sOutput '';
        foreach (
$aLines as $iKey => $sLine
        {
            
$sOutput .= $this->_parseLine($sLine);
        }

        
$sOutput preg_replace_callback('/<nowiki></nowiki>/i', array(&$this"_handleRestoreNoWiki"), $sOutput);

        return 
$sOutput;
    }    
    
    
/**
     * Parses each line of the string and creates handles.
     *
     * @param string $sLine Line of the string we are parsing.
     * @return string Returns the parsed line.
     */
    
private function _parseLine($sLine
    {                
        
$this->_bStop false;
        
$this->_bStopAll false;

        
$aCalled = array();
        
        
$sLine rtrim($sLine);
        
        foreach (
$this->_sLineRegexes as $sFunction => $sRegex
        {
            if (
preg_match("/$sRegex/i"$sLine$aMatches)) 
            {
                
$aCalled[$sFunction] = true;
                
$sFunction '_handle' $sFunction;
                
$sLine $this->$sFunction($aMatches);
                if (
$this->_bStop || $this->_bStopAll)
                {
                    break;
                }
            }
        }
        
        if (!
$this->_bStopAll
        {
            
$this->_bStop false;
            foreach (
$this->_sCharRegexes as $sFunction => $sRegex
            {
                
$sLine preg_replace_callback("/$sRegex/i", array(&$this"_handle" $sFunction), $sLine);
                if (
$this->_bStop)
                {
                    break;
                }
            }
        }
        
        
$isline = (strlen(trim($sLine)) > 0);
        
        if ((
$this->_iListLevel 0) && (!isset($aCalled['list'])))
        {
            
$sLine $this->_handleList(falsetrue) . $sLine;
        }
        
        if (
$this->_bDefList && (!isset($aCalled['definitionlist'])))
        {
            
$sLine $this->_handleDefinitionList(falsetrue) . $sLine;
        }
        
        if (
$this->_bPreformat && (!isset($aCalled['preformat'])))
        {
            
$sLine $this->_handlePreFormat(falsetrue) . $sLine;
        }
        
        if (
$isline)
        {
            
$this->_bSuppressLinebreaks = ((isset($aCalled['newline']) && $aCalled['newline']) || (isset($aCalled['sections']) && $aCalled['sections']));
        }
        
        return 
$sLine;
    }    
    
    
/**
     * Handles sections (h1, h2, h3 etc...)
     *
     * @param array $aMatches ARRAY matches from regex.
     * @return string Converted HTML line.
     */
    
private function _handleSections($aMatches
    {                
        
$iLevel strlen($aMatches[1]);
        
$sContent $aMatches[2];
        
$sContent trim($sContent);
        
$this->_bStop true;
        
        return 
$this->emphasize_off() . "nn<p><a name="" . $this->_cleanTitle($sContent) . "" id="" . $this->_cleanTitle($sContent) . ""></a></p>n<h{$iLevel}>{$sContent}</h{$iLevel}>nn";
    }
    
    
/**
     * Cleans the title of an item.
     *
     * @param string $sTxt Title of the item.
     * @return string Title all clean.
     */
    
private function _cleanTitle($sTxt)
    {
        
$sTxt preg_replace'/ +/''_',preg_replace('/[^0-9a-zA-Z ]+/'''$sTxt));
        
        return 
$sTxt;
    }
    
    
/**
     * Handler for new lines (<br />).
     *
     * @param array $aMatches ARRAY matches from regex.
     * @return string Converted HTML.
     */
    
private function _handleNewline($aMatches
    {
        if (
$this->_bSuppressLinebreaks)
        {
            return 
$this->emphasize_off();
        }
        
        
$this->_bStop true;

        return 
$this->emphasize_off() . "<br /><br />";
    }
    
    
/**
     * Handles lists (<ul><li>)
     *
     * @param array $aMatches ARRAY matches from regex.
     * @param bool $bClose TRUE to close the <ul>. FALSE to leave it open.
     * @return string Converted HTML.
     */
    
private function _handleList($aMatches$bClose false
    {
        
$aListTypes = array(
            
'*' => 'ul',
            
'#' => 'ol',
        );        
        
        
$iNewLevel = (($bClose) ? strlen($aMatches[1]));
        
        
$sOutput '';
        while (
$this->_iListLevel != $iNewLevel
        {
            
$sListChar substr($aMatches[1], -1);                        
            
            
$sListType = (isset($aListTypes[$sListChar]) ? $aListTypes[$sListChar] : '');
            
            if (
$this->_iListLevel $iNewLevel
            {
                
$sListType '/' array_pop($this->_aListLevelTypes);
                
$this->_iListLevel--;
            } 
            else 
            {
                
$this->_iListLevel++;
                
array_push($this->_aListLevelTypes$sListType);
            }
            
$sOutput .= "n<{$sListType}>n";
        }
        
        if (
$bClose)
        {
            return 
$sOutput;
        }
        
        
$sOutput .= "<li>".$aMatches[2]."</li>n";
        
        return 
$sOutput;
    }
    
    
/**
     * Handle <dl>.
     *
     * @param array $aMatches ARRAY matches from regex.
     * @param bool $bClose TRUE to close the <dl>. FALSE to leave it open.
     * @return string Converted HTML.
     */
    
private function _handleDefinitionList($aMatches$bClose false
    {        
        if (
$bClose
        {
            
$this->_bDefList false;
            return 
"</dl>n";
        }        
        
        
$sOutput "";
        if (!
$this->_bDefList)
        {
            
$sOutput .= "<dl>n";
        }
        
$this->_bDefList true;

        switch(
$aMatches[1]) 
        {
            case 
';':
                
$sTerm $aMatches[2];
                if (
strpos($sTerm' :') !== false
                {
                    list(
$sTerm$definition) = explode(':'$sTerm);
                    
$sOutput .= "<dt>{$sTerm}</dt><dd>{$definition}</dd>";
                } 
                else 
                {
                    
$sOutput .= "<dt>{$sTerm}</dt>";
                }
                break;
            case 
':':
                
$definition $aMatches[2];
                
$sOutput .= "<dd>{$definition}</dd>n";
                break;
        }
        
        return 
$sOutput;
    }
    
    
/**
     * Handle <pre>.
     *
     * @param array $aMatches ARRAY matches from regex.
     * @param bool $bClose TRUE to close the <pre>. FALSE to leave it open.
     * @return string Converted HTML.
     */    
    
private function _handlePreFormat($aMatches$bClose false
    {
        if (
$bClose
        {
            
$this->_bPreformat false;
            return 
"</pre>n";
        }
        
        
$this->_bStopAll true;

        
$sOutput "";
        if (!
$this->_bPreformat)
        {
            
$sOutput .= "<pre>";
        }
        
$this->_bPreformat true;
        
        
$sOutput .= $aMatches[1];
        
        return 
$sOutput."n";
    }
    
    
/**
     * Handle <hr />
     *
     * @param array $aMatches ARRAY matches from regex.
     * @return string Converted HTML.
     */
    
private function _handleHorizontalRule($aMatches
    {
        return 
"<hr />";
    }
    
    
/**
     * Handle images (<img>).
     *
     * @param string $sHref Link
     * @param string $sTitle Title
     * @param array $aOptions Extra options for the link.
     * @return string Converted HTML.
     */
    
private function _handleImage($sHref$sTitle$aOptions
    {
        if (
$this->_bIgnoreImages)
        {
            return 
'';
        }
        
        if (!
$this->_sImageUri)
        {
            return 
$sTitle;
        }
        
        
$sHref $this->_sImageUri $sHref;
        
        
$sImageTag sprintf('<img src="%s" alt="%s" />'$sHref$sTitle);
        foreach (
$aOptions as $iKey => $sOption
        {
            switch(
$sOption
            {
                case 
'frame':
                    
$sImageTag sprintf('<div style="float: right; background-color: #F5F5F5; border: 1px solid #D0D0D0; padding: 2px">%s<div>%s</div></div>'$sImageTag$sTitle);
                    break;
                case 
'right':
                    
$sImageTag sprintf('<div style="float: right">%s</div>'$sImageTag);
                    break;
            }
        }
        
        return 
$sImageTag;
    }
    
    
/**
     * Handles internal links.
     *
     * @param array $aMatches ARRAY matches from regex.
     * @return string Converted HTML.
     */
    
private function _handleInternalLink($aMatches
    {
        
$bNoLink false;    
        
$sHref $aMatches[4];
        
$sTitle = (isset($aMatches[6]) ? $aMatches[6] : $sHref . (isset($aMatches[7]) ? $aMatches[7] : ''));
        
$namespace = (isset($aMatches[3]) ? $aMatches[3] : false);

        if (
$namespace == 'Image'
        {
            
$aOptions explode('|'$sTitle);
            
$sTitle array_pop($aOptions);
            
            return 
$this->_handleImage($sHref$sTitle$aOptions);
        }        
        
        
$sTitle preg_replace('/(.*?)/'''$sTitle);
        
$sTitle preg_replace('/^.*?:/'''$sTitle);
        
        if (
$this->_sReferenceWiki
        {
            
$sHref $this->_sReferenceWiki . ($namespace $namespace ':' '') . ucfirst(str_replace(' ''_'$sHref));
        } 
        else 
        {
            
$bNoLink true;
        }

        if (
$bNoLink)
        {
            return 
$sTitle;
        }
        
        
$bNewWindow true;
        
        return 
sprintf('<a href="%s"%s>%s</a>'$sHref, ($bNewWindow ' target="_blank"' ''), $sTitle);
    }
    
    
/**
     * Handles external links.
     *
     * @param array $aMatches ARRAY matches from regex.
     * @return string Converted HTML.
     */    
    
private function _handleExternalLink($aMatches
    {
        
$sHref $aMatches[2];
        
$sTitle = (isset($aMatches[3]) ? $aMatches[3] : false);
        if (!
$sTitle
        {
            
$this->_iLinkNumber++;
            
$sTitle "[{$this->_iLinkNumber}]";
        }
        
$bNewWindow true;
        
        return 
sprintf('<a href="%s"%s>%s</a>'$sHref, ($bNewWindow ' target="_blank"' ''), $sTitle);        
    }
    
    
/**
     * Handles emphasize blocks (em, strong).
     *
     * @param int Type of HTML.
     * @return string Converted HTML.
     */    
    
private function emphasize($iAmount
    {
        
$aAmounts = array(
            
=> array('<em>','</em>'),
            
=> array('<strong>','</strong>'),
            
=> array('<strong>','</strong>'),
            
=> array('<em><strong>','</strong></em>')
        );
        
        
$sOutput "";
        if ((isset(
$this->_aEmphasis[$iAmount]) && !$this->_aEmphasis[$iAmount]) && (isset($this->_aEmphasis[$iAmount-1]) && $this->_aEmphasis[$iAmount-1])) 
        {
            
$iAmount--;
            
$sOutput "'";
        }

        
$sOutput .= $aAmounts[$iAmount][(int) (isset($this->_aEmphasis[$iAmount]) ? $this->_aEmphasis[$iAmount] : 0)];

        
$this->_aEmphasis[$iAmount] = (isset($this->_aEmphasis[$iAmount]) ? !$this->_aEmphasis[$iAmount] : true);
        
        return 
$sOutput;
    }
    
    
/**
     * Handles emphasize blocks (em, strong).
     *
     * @param array $aMatches ARRAY matches from regex.
     * @return string Converted HTML.
     */        
    
private function _handleEmphasize($aMatches
    {
        return 
$this->emphasize(strlen($aMatches[1]));
    }
    
    
/**
     * Checks emphasize diff.
     *
     * @return string Converted HTML.
     */    
    
private function emphasize_off() 
    {
        
$sOutput "";
        
        if (!
is_array($this->_aEmphasis))
        {
            return 
$sOutput;
        }
        
        foreach (
$this->_aEmphasis as $iAmount => $sState
        {
            if (
$sState)
            {
                
$sOutput .= $this->emphasize($iAmount);
            }
        }
        
        return 
$sOutput;
    }
    
    
/**
     * Adds empty string.
     *
     * @return string Empty string.
     */        
    
private function _handleEliminate($aMatches
    {
        return 
'';
    }
    
    
/**
     * Converts WIKI variables.
     *
     * @param array $aMatches ARRAY matches from regex.
     * @return string Converted HTML.
     */
    
private function _handleVariable($aMatches
    {
        switch(
$aMatches[2]) 
        {
            case 
'CURRENTMONTH': return date('m');
            case 
'CURRENTMONTHNAMEGEN':
            case 
'CURRENTMONTHNAME': return date('F');
            case 
'CURRENTDAY': return date('d');
            case 
'CURRENTDAYNAME': return date('l');
            case 
'CURRENTYEAR': return date('Y');
            case 
'CURRENTTIME': return date('H:i');
            case 
'NUMBEROFARTICLES': return 0;
            case 
'PAGENAME': return '';
            case 
'NAMESPACE': return 'None';
            case 
'SITENAME': return $_SERVER['HTTP_HOST'];
            default: return 
'';    
        }
    }
    
    
/**
     * Handles <nowiki>.
     *
     * @param array $aMatches ARRAY matches from regex.
     * @return string Converted HTML.
     */    
    
private function _handleSaveNoWiki($aMatches
    {
        
array_push($this->_aNoWikis$aMatches[1]);
        
        return 
"<nowiki></nowiki>";
    }
    
    
/**
     * Restores wiki.
     *
     * @param array $aMatches ARRAY matches from regex.
     * @return string Converted HTML.
     */
    
private function _handleRestoreNoWiki($aMatches
    {
        return 
array_pop($this->_aNoWikis);
    }
}

?>
Онлайн: 1
Реклама