| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245 | <?php/* Copyright (c) * - 2006-2013, Ivan Sagalaev (maniacsoftwaremaniacs.org), highlight.js *              (original author) * - 2013-2015, Geert Bergman (geertscrivo.nl), highlight.php * - 2014,      Daniel Lynge, highlight.php (contributor) * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, *    this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, *    this list of conditions and the following disclaimer in the documentation *    and/or other materials provided with the distribution. * 3. Neither the name of "highlight.js", "highlight.php", nor the names of its *    contributors may be used to endorse or promote products derived from this *    software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */namespace Highlight;class Language{    public $caseInsensitive = false;    public $aliases = null;    public function complete(&$e)    {        if (!isset($e)) {            $e = new \stdClass();        }                $patch = array(            "begin" => true,            "end" => true,            "lexemes" => true,            "illegal" => true,        );        $def = array(            "begin" => "",            "beginRe" => "",            "beginKeywords" => "",            "excludeBegin" => "",            "returnBegin" => "",            "end" => "",            "endRe" => "",            "endsParent" => "",            "endsWithParent" => "",            "excludeEnd" => "",            "returnEnd" => "",            "starts" => "",            "terminators" => "",            "terminatorEnd" => "",            "lexemes" => "",            "lexemesRe" => "",            "illegal" => "",            "illegalRe" => "",            "className" => "",            "contains" => array(),            "keywords" => null,            "subLanguage" => null,            "subLanguageMode" => "",            "compiled" => false,            "relevance" => 1);        foreach ($patch as $k =>  $v) {            if (isset($e->$k)) {                $e->$k = str_replace("\\/", "/", $e->$k);                $e->$k = str_replace("/", "\\/", $e->$k);            }        }        foreach ($def as $k =>  $v) {            if (!isset($e->$k)) {                @$e->$k = $v;            }        }    }    public function __construct($lang)    {        $json = file_get_contents(__DIR__ . DIRECTORY_SEPARATOR . "languages" .            DIRECTORY_SEPARATOR . "{$lang}.json");        $this->mode = json_decode($json);        $this->name = $lang;        $this->aliases =            isset($this->mode->aliases) ? $this->mode->aliases : null;        $this->caseInsensitive = isset($this->mode->case_insensitive) ?            $this->mode->case_insensitive : false;    }    private function langRe($value, $global=false)    {        return "/{$value}/um" . ($this->caseInsensitive ? "i" : "");    }    private function processKeyWords($kw)    {        if (is_string($kw)) {            if ($this->caseInsensitive) {                $kw = mb_strtolower($kw, "UTF-8");            }            $kw = array("keyword" => explode(" ", $kw));        } else {            foreach ($kw as $cls=>$vl) {                if (!is_array($vl)) {                    if ($this->caseInsensitive) {                        $vl = mb_strtolower($vl, "UTF-8");                    }                    $kw->$cls = explode(" ", $vl);                }            }        }        return $kw;    }    private function compileMode($mode, $parent=null)    {        if (isset($mode->compiled)) {            return;        }        $this->complete($mode);        $mode->compiled = true;        $mode->keywords =            $mode->keywords ? $mode->keywords : $mode->beginKeywords;        /* Note: JsonRef method creates different references as those in the         * original source files. Two modes may refer to the same keywors         * set, so only testing if the mode has keywords is not enough: the         * mode's keywords might be compiled already, so it is necessary         * to do an 'is_array' check.         */        if ($mode->keywords && !is_array($mode->keywords)) {            $compiledKeywords = array();            $mode->lexemesRe = $this->langRe($mode->lexemes                    ? $mode->lexemes : "\b\w+\b", true);            foreach ($this->processKeyWords($mode->keywords) as $clsNm => $dat) {                if (!is_array($dat)) {                    $dat = array($dat);                }                foreach ($dat as $kw) {                    $pair = explode("|", $kw);                    $compiledKeywords[$pair[0]] =                        array($clsNm, isset($pair[1]) ? intval($pair[1]) : 1);                }            }            $mode->keywords = $compiledKeywords;        }        if ($parent) {            if ($mode->beginKeywords) {                $mode->begin = "\\b(" .                    implode("|",explode(" ", $mode->beginKeywords)) . ")\\b";            }            if (!$mode->begin) {                $mode->begin = "\B|\b";            }            $mode->beginRe = $this->langRe($mode->begin);            if (!$mode->end && !$mode->endsWithParent) {                $mode->end = "\B|\b";            }            if ($mode->end) {                $mode->endRe = $this->langRe($mode->end);            }            $mode->terminatorEnd = $mode->end;            if ($mode->endsWithParent && $parent->terminatorEnd) {                $mode->terminatorEnd .=                    ($mode->end ? "|" : "") . $parent->terminatorEnd;            }        }        if ($mode->illegal) {            $mode->illegalRe = $this->langRe($mode->illegal);        }        $expanded_contains = array();        for ($i=0; $i<count($mode->contains); $i++) {            if (isset($mode->contains[$i]->variants)) {                foreach ($mode->contains[$i]->variants as $v) {                    $x = (object)((array)$v + (array)$mode->contains[$i]);                    unset($x->variants);                    $expanded_contains[] = $x;                }            } else {                $expanded_contains[] = "self" === $mode->contains[$i] ?                    $mode : $mode->contains[$i];            }        }        $mode->contains = $expanded_contains;        for ($i=0; $i<count($mode->contains); $i++) {            $this->compileMode($mode->contains[$i], $mode);        }        if ($mode->starts) {            $this->compileMode($mode->starts, $parent);        }        $terminators = array();        for ($i=0; $i<count($mode->contains); $i++) {            $terminators[] = $mode->contains[$i]->beginKeywords                ? "\.?(" . $mode->contains[$i]->begin . ")\.?"                : $mode->contains[$i]->begin;        }        if ($mode->terminatorEnd) {            $terminators[] = $mode->terminatorEnd;        }        if ($mode->illegal) {            $terminators[] = $mode->illegal;        }        $mode->terminators = count($terminators)            ? $this->langRe(implode("|", $terminators), true) : null;    }    public function compile()    {        if (!isset($this->mode->compiled)) {            $jr = new JsonRef();            $this->mode = $jr->decode($this->mode);            $this->compileMode($this->mode);        }    }}
 |