pluf2

pluf2 Git Source Tree


Root/src/Pluf/Text/Wiki/InlineParser.php

<?php
/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
# ***** BEGIN LICENSE BLOCK *****
# This file is part of Plume Framework, a simple PHP Application Framework.
# Copyright (C) 2001-2007 Loic d'Anterroches and contributors.
#
# Plume Framework is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
#
# Plume Framework is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
#
# ***** END LICENSE BLOCK ***** */

/*
 * Based on Wiki Renderer copyright (C) 2003-2004 Laurent Jouanneau
 * http://ljouanneau.com/softs/wikirenderer/
 */

/**
 * Moteur permettant de transformer les tags wiki inline 
 * d'une chaine en équivalent HTML
 */
class Pluf_Text_Wiki_InlineParser {

    public $resultline = '';
    public $error = false;
    public $listTag = array();
    public $str = array();
    public $splitPattern = '';
    public $checkWikiWord = false;
    public $checkWikiWordFunction = null;
    public $simpletags = null;
    public $_separator;
    public $escapeHtml = true;
    public $end = 0;

    /**
     * constructeur
     * @param array $inlinetags liste des tags permis
     * @param string caractère séparateur des différents composants 
     *               d'un tag wiki
     */

    function __construct($inlinetags, $simpletags, $separator='|',
                         $checkWikiWord=false, $funcCheckWikiWord=null,
                         $escapeHtml=true)
    {
        foreach ($inlinetags as $name=>$prop){
            $this->listTag[$prop[0]] = new Pluf_Text_Wiki_Tag($name, $prop);

            $this->splitPattern.=preg_replace ( '/([^\w\s\d])/', '\\\\\\1',$prop[0]).')|(';
            if ($prop[1] != $prop[0])
                $this->splitPattern.=preg_replace ( '/([^\w\s\d])/', '\\\\\\1',$prop[1]).')|(';
        }
        foreach ($simpletags as $tag=>$html){
            $this->splitPattern.=preg_replace ( '/([^\w\s\d])/', '\\\\\\1',$tag).')|(';
        }

        $this->simpletags = $simpletags;
        $this->_separator = $separator;
        $this->checkWikiWord = $checkWikiWord;
        $this->checkWikiWordFunction = $funcCheckWikiWord;
        $this->escapeHtml = $escapeHtml;
    }

    /**
     * fonction principale du parser.
     * @param   string   $line avec des eventuels tag wiki
     * @return  string   chaine $line avec les tags wiki transformé en HTML
     */
    function parse($line) {
        $this->error = false;

        $this->str = preg_split('/('.$this->splitPattern.'\\'.$this->_separator.')|(\\\\)/',$line, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
        $this->end = count($this->str);
        if ($this->end > 1) {
            $firsttag = new Pluf_Text_Wiki_Tag('dummie',array('','', null,'Pluf_Text_Wiki_Configuration_builddummie'));
            $pos=-1;
            return $this->_parse($firsttag, $pos);
        }
        else {
            if ($this->escapeHtml) {
                if ($this->checkWikiWord && $this->checkWikiWordFunction !== null)
                    return  $this->_doCheckWikiWord(htmlspecialchars($line));
                else
                    return htmlspecialchars($line);
            }
            else {
                if ($this->checkWikiWord && $this->checkWikiWordFunction !== null)
                    return  $this->_doCheckWikiWord($line);
                else
                    return $line;
            }

        }
    }

    /**
     * coeur du parseur. Appelé récursivement
     */

    function _parse($tag, &$posstart) {

        $checkNextTag = true;
        $checkBeginTag = true;

        // on parcours la chaine,  morceau aprés morceau
        for($i=$posstart+1; $i < $this->end; $i++) {

            $t=&$this->str[$i];
            // a t-on un antislash ?
            if ($t=='\\'){
                if ($checkNextTag){
                    $t=''; // oui -> on l'efface et on ignore le tag (on continue)
                    $checkNextTag = false;
                }
                else {
                    $tag->addContent('\\',false);
                }

                // est-ce un séparateur ?
            }
            elseif ($t == $this->_separator) {
                if ($tag->isDummy() || !$checkNextTag)
                    $tag->addContent($this->_separator,false);
                elseif ($tag->useSeparator()) {
                    $checkBeginTag = false;
                    $tag->addSeparator();
                }
                else {
                    $tag->addContent($this->_separator,false);
                }
                // a-t-on une balise de fin du tag ?
            }
            elseif ($checkNextTag && $tag->getEndTag() == $t && !$tag->isDummy()) {
                $posstart = $i;
                return $tag->getHtmlContent();

                // a-t-on une balise de debut de tag quelconque ?
            }
            elseif ($checkBeginTag && $checkNextTag && isset($this->listTag[$t]) ) {

                $content  =  $this->_parse(clone($this->listTag[$t]),$i); // clone indispensable sinon plantage !!!
                if ($content)
                    $tag->addContent($content,false);
                else {
                    if ($tag->getNumberSeparator() == 0 && $this->checkWikiWord && $this->checkWikiWordFunction !== null) {
                        if ($this->escapeHtml)
                            $tag->addContent($this->_doCheckWikiWord(htmlspecialchars($t)),false);
                        else
                            $tag->addContent($this->_doCheckWikiWord($t),false);
                    }
                    else
                        $tag->addContent($t,$this->escapeHtml);
                }

                // a-t-on un saut de ligne forcé ?
            }
            elseif ($checkNextTag && $checkBeginTag && isset($this->simpletags[$t])) {
                $tag->addContent($this->simpletags[$t],false);
            }
            else {
                if ($tag->getNumberSeparator() == 0 && $this->checkWikiWord && $this->checkWikiWordFunction !== null) {
                    if ($this->escapeHtml)
                        $tag->addContent($this->_doCheckWikiWord(htmlspecialchars($t)),false);
                    else
                        $tag->addContent($this->_doCheckWikiWord($t),false);
                }
                else
                    $tag->addContent($t,$this->escapeHtml);
                $checkNextTag = true;
            }
        }
        if (!$tag->isDummy()) {
            //--- on n'a pas trouvé le tag de fin
            // on met en erreur
            $this->error = true;
            return false;
        }
        else
            return $tag->getHtmlContent();
    }

    function _doCheckWikiWord($string) {
        if (preg_match_all("/(?<=\b)[A-Z][a-z]+[A-Z0-9]\w*/", $string, $matches)){
            $fct = $this->checkWikiWordFunction;
            $match = array_unique($matches[0]); // il faut avoir une liste sans doublon, à cause du str_replace plus loin...
            $string = str_replace($match, $fct($match), $string);
        }
        return $string;
    }

    function getError() {
        return $this->error;
    }

}

Archive Download this file

Branches

Number of commits:
Page rendered in 0.07050s using 11 queries.