From 9bc508bedc7be7601e7da60873fb354dc60df278 Mon Sep 17 00:00:00 2001 From: Dragomir Cerbero Date: Fri, 24 Nov 2017 17:18:21 +0100 Subject: [PATCH] Initial Commit --- LICENSE | 21 ++++ README.md | 55 ++++++++ lang/abstractLang.php | 43 +++++++ lang/css.php | 283 ++++++++++++++++++++++++++++++++++++++++++ lang/htaccess.php | 161 ++++++++++++++++++++++++ lang/html.php | 173 ++++++++++++++++++++++++++ lang/php.php | 77 ++++++++++++ lang/phpdev.php | 177 ++++++++++++++++++++++++++ synParser.php | 228 ++++++++++++++++++++++++++++++++++ temp.css | 51 ++++++++ 10 files changed, 1269 insertions(+) create mode 100644 LICENSE create mode 100644 README.md create mode 100644 lang/abstractLang.php create mode 100644 lang/css.php create mode 100644 lang/htaccess.php create mode 100644 lang/html.php create mode 100644 lang/php.php create mode 100644 lang/phpdev.php create mode 100644 synParser.php create mode 100644 temp.css diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..5285f42 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2017 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..7441942 --- /dev/null +++ b/README.md @@ -0,0 +1,55 @@ +# SynHigh - Syntax Highlight Module + +Easy to use php syntax highlight module. + +## Supported Languages/Configurations + +* HTML +* CSS +* PHP (with PHP `highlight_string`) +* JS (with PHP `highlight_string`) +* HTACCESS + +## Features + +* Modular +* Expandable + +## Using + +Download the `dist/synhigh.zip`, unzip and put it into to your project directory. Then load the module in your `.php` file with: + +```php +require_once('synParser.php') +``` + +Initialize with: + +```php +new synhigh(string $source, string $language, bool $lineNumbers, int $lineBegin, int $lineEnd); +``` + +* `$source`: string to highlight +* `$language`: language name + * `php`, for PHP or JS + * `html`, for HTML and mixed HTML/PHP + * `css` + * `htaccess` +* `$lineNumbers`: when `true` synhigh will append line numbers [optional] +* `$lineBegin`: line where the source begins [optional] +* `$lineEnd`: line where the source ends [optional] + +Functions: + +* `$myVar->parseCode()`, returns the output as string +* `$myVar->setWithinLine(true)`, formats the output for using within a line +* Setter: + * `$myVar->setSource($source)` string + * `$myVar->setLang($lang)` string + * `$myVar->setLineNumbers($lineNumbers)` boolean + * `$myVar->setLineBegin($lineBegin)` integer + * `$myVar->setLineEnd($lineEnd)` integer + +## License + +Check the LICENSE file. diff --git a/lang/abstractLang.php b/lang/abstractLang.php new file mode 100644 index 0000000..3d7b711 --- /dev/null +++ b/lang/abstractLang.php @@ -0,0 +1,43 @@ +getCode($source); + } +} + +?> diff --git a/lang/css.php b/lang/css.php new file mode 100644 index 0000000..6a7330e --- /dev/null +++ b/lang/css.php @@ -0,0 +1,283 @@ +cssCom = $this->cssComment; + // ID: #id + $this->cssID = $this->cssHighlight; + // Class: .class + $this->cssClass = $this->cssKeyword; + // HTML Tags: hmtl, body, ... + $this->cssTag = $this->cssFont; + // Pseudo Selectors :hover + $this->cssPsd = $this->cssHighlight; + // Attribute Selectors [href="..."] + $this->cssSAttr = $this->cssFont; + // @ Selectors @media (...) + $this->cssSAt = $this->cssBold; + + // Properties: Property: Value; + $this->cssAttr = ''; + // Properties Property + $this->cssAttrI = $this->cssBold; + // Quotes "Value" + $this->cssQuo = $this->cssHighlight; + // HEX Colors: #000000, #000 + $this->cssHC = $this->cssHighlight; + // Functions Etc. name(...) + $this->cssFnc = $this->cssBold; + // Numbers And Units 1px + $this->cssUnts = $this->cssBold; + // !important + $this->cssImp = $this->cssBold; + // @-Rules + $this->cssAt = $this->cssKeyword; + } + + + // RexEx Rules + // Comments: /* */ + protected $regexCom = '/\/\*(?:.|\s)+?\*\//'; + + // Style: Selector { Property [, Selector { Property, [, Property]}]} + protected $regexStyle = '/([^{}\n,]+(?:,[\s]*.+)*)([\s]{)((?:[^{}]|(?R))+?)?(})/'; + // ID: #id + protected $regexID = '/#[\w-]+(?![\w# ]*")/'; + // Class: .class + protected $regexClass = '/\.[\w-]+(?![\w# ]*")/'; + // HTML Tags: html, body, ... + protected $regexTag = '/(?:^[a-z-]+|(?<=[\s,])[a-z-]+)/'; + // Pseudo Selectors :hover + protected $regexPsd = '/[:]+[\w-]+/'; + // Attribute Selectors [href=...] + protected $regexSAttr = '/(\[)(\w+)([~|^$*=]*)("?[\w.-]*"?)(\])/'; + // @ Selectors @media (...) + protected $regexSAt = '/(@[\w-]+\s*)(?:(\()(.+?)(\))|(\w+))?/'; + + // Properties: Property: Value; + protected $regexAttr = '/(?<=[\s;{])([\w-]+)([\s]*:[\s]*)(.+?)(?=;|\^id|\s*})/'; + // Quotes "Value" + protected $regexQuo = '/(["\']).*?(\1)/'; + // HEX Colors: #000000, #000 + protected $regexHC = '/^#[\w]{0,6}/'; + // Functions Etc. name(...) + protected $regexFnc = '/^([\w\-]+)(\(.+?\))/'; + // Numbers and units 1px + protected $regexUnts = '/([\d.]*[\d]+)([a-z%]+)/'; + // !important + protected $regexImp = '/^!important/'; + + // @-Rules @import ... + protected $regexAt = '/(@[\w\-]+)(.+?)(;)/'; + + // Buffer For Comments + protected $comments = array(); + + /** + * Highlighting The String + * + * @param string Source + * @return string Output + */ + protected function getCode($source) + { + // Remove HTML Specialchars + $source = htmlspecialchars($source, ENT_NOQUOTES); + + $regex = array( + // Comments + $this->regexCom => array($this,'comment'), + // Style + $this->regexStyle => array($this,'style'), + // Properties + $this->regexAttr => array($this,'attr'), + // @-Rules + $this->regexAt => array($this,'atrule') + ); + + // RegEX + foreach($regex as $key=>$value) + $source = preg_replace_callback($key, $value, $source); + + // Comments + $source = str_replace(array_keys($this->comments), array_values($this->comments), $source); + + return $source; + } + + /** + * Saves The Comments + * + * @param array RegEx Match + * @return string ID + */ + protected function comment($source) + { + $id = uniqid("^id", true); + $this->comments[$id] = '' . htmlspecialchars($source[0]) . ''; + + return $id; + } + + /** + * Highlights Style: selector { content } + * + * @param array RegEx Match + * @return string Output + */ + protected function style($source) + { + // Selectors + $ident = $source[1]; + + // Lines With @ + if(preg_match("/^@.+/", $ident)) { + preg_match($this->regexSAt, $ident, $matches); + + // @value + $pre = ''.$matches[1].''; + $ident = $pre; + $mid = ''; + if(count($matches) == 5) { + // { Property : Value } + $mid = $matches[2].preg_replace_callback('/([\w-]+)([\s]*:[\s]*)([^;\n]*)/', array($this,'attr'), $matches[3]).$matches[4]; + } + if (count($matches) == 6) { + // [@value] name + $mid = ''.$matches[5].''; + } + + $ident .= $mid; + } + // Split Selectors + else { + $ident = preg_replace_callback('/[\w.#"\'\[\]\-=~|^$*:;()]+/', array($this,'ident'), $ident); + } + + // Nesting: [ Selector { ] Selector { Property : Value ; } [ } ] + $content = preg_replace_callback($this->regexStyle, array($this,'style'), $source[3]); + + return $ident.$source[2].$content.$source[4]; + } + + /** + * Highlights Selectors + * + * @param array RegEx Match + * @return string Output + */ + protected function ident($source) + { + // Check if > + if ($source[0] == 'gt;') + return 'gt;'; + // Check if < + if ($source[0] == 'lt;') + return 'lt;'; + + $regex = array( + // HTML Tags + $this->regexTag => '$0', + // ID + $this->regexID => '$0', + // Class + $this->regexClass => '$0', + // Pseudo Stuff + $this->regexPsd => '$0', + // Attribute + $this->regexSAttr => '$1$2$3$4$5', + ); + + foreach($regex as $key=>$value) + $source[0] = preg_replace($key, $value, $source[0]); + + return $source[0]; + } + + /** + * Highlights Properties + * + * @param array RegEx Match + * @return string Output + */ + protected function attr($source) + { + // Property + $attr = ''.$source[1].''; + + // Split Values + $valuet = preg_replace_callback('/(?:[\w\-]+)?(["\']|\().+?(?:\1|\))|(?:[#\w\-.!]+)/', array($this,'value'), $source[3]); + + // Style + if ($this->cssAttr) + $valuet = ''.$valuet.''; + + return $attr.$source[2].$valuet.$source[4]; + } + + /** + * Highlights Values + * + * @param array RegEx Match + * @return string Output + */ + protected function value($source) + { + $regex = array( + // Quotes + $this->regexQuo => '$0', + // Hex-Color + $this->regexHC => '$0', + // Functions + $this->regexFnc => '$1$2', + // Units + $this->regexUnts => '$1$2', + // !important + $this->regexImp => '$0', + ); + + foreach($regex as $key=>$value) + $source[0] = preg_replace($key, $value, $source[0]); + + return $source[0]; + } + + /** + * @-Rules + * + * @param array RegEx Match + * @return string Output + */ + protected function atrule($source) + { + // Property + $pref = ''.$source[1].''; + + // Split Values + $valuet = preg_replace_callback('/(?:[\w\-]+)?(["\']|\().+?(?:\1|\))|(?:[#\w\-.!]+)/', array($this,'value'), $source[2]); + + return $pref.$valuet.$source[3]; + } +} + +?> diff --git a/lang/htaccess.php b/lang/htaccess.php new file mode 100644 index 0000000..e98b19c --- /dev/null +++ b/lang/htaccess.php @@ -0,0 +1,161 @@ +cssCom = $this->cssComment; + // Opening & Closing + $this->cssOpCl = $this->cssFont; + // Value + $this->cssSec = $this->cssFont; + // Rules & Chains + $this->cssRules = $this->cssBold; + // Quotes + $this->cssQuotes = $this->cssHighlight; + } + + // RexEx Rules + // Comments: #... + protected $regexCom = '/(? + protected $regexSec = '/(<\/?)([\w]+)([^>]*)(>)/'; + // Rules Value + protected $regexRules = '/^([\t ]*)([A-Z]{1}\w+)/m'; + // Quotes "..." '...' + protected $regexQuotes = '/(["\'])(?:(?:.)+?)?(?:\1)/'; + // Chains value value ... + protected $regexChain = '/^([\t ]*)([a-z]{1}[\w ]+)/m'; + + + // Buffer + protected $buffer = array(); + + /** + * Highlighting The String + * + * @param string Source + * @return string Output + */ + protected function getCode($source) + { + $regex = array( + // Comments + $this->regexCom => array($this,'comment'), + // Quotes + $this->regexQuotes => array($this,'quotes'), + // Section + $this->regexSec => array($this,'section'), + // Rules + $this->regexRules => array($this,'rules'), + // Chains + $this->regexChain => array($this,'chain') + ); + + // RegEX + foreach($regex as $key=>$value) + $source = preg_replace_callback($key, $value, $source); + + // Remove HTML Special Chars + $source = htmlspecialchars($source); + + // Load From Buffer + $this->buffer = array_reverse($this->buffer, true); + $source = str_replace(array_keys($this->buffer), array_values($this->buffer), $source); + + return $source; + } + + /** + * Saves The Comments + * + * @param array RegEx Match + * @return string ID + */ + protected function comment($source) + { + $id = uniqid("^idc", true); + $this->buffer[$id] = '' . htmlspecialchars($source[0]) . ''; + + return $id; + } + + /** + * Highlighting Quotes + * + * @param array RegEx Match + * @return string ID + */ + protected function quotes($source) + { + $id = uniqid("^idq", true); + $this->buffer[$id] = '' . htmlspecialchars($source[0]) . ''; + + return $id; + } + + /** + * Highlighting Sections + * + * @param array RegEx Match + * @return string ID + */ + protected function section($source) + { + $opening = '' . htmlspecialchars($source[1]) . ''; + $value = '' . htmlspecialchars($source[2]) . ''; + $closing = '' . htmlspecialchars($source[4]) . ''; + + $id = uniqid("^ids", true); + $this->buffer[$id] = $opening.$value.htmlspecialchars($source[3]).$closing; + + return $id; + } + + /** + * Highlighting Rules + * + * @param array RegEx Match + * @return string ID + */ + protected function rules($source) + { + $id = uniqid("^idr", true); + $this->buffer[$id] = $source[1].'' . htmlspecialchars($source[2]) . ''; + + return $id; + } + + /** + * Highlighting Chains + * + * @param array RegEx Match + * @return string ID + */ + protected function chain($source) + { + $id = uniqid("^idch", true); + $this->buffer[$id] = '' . htmlspecialchars($source[0]) . ''; + + return $id; + } + +} + +?> diff --git a/lang/html.php b/lang/html.php new file mode 100644 index 0000000..bbaf830 --- /dev/null +++ b/lang/html.php @@ -0,0 +1,173 @@ +cssCom = $this->cssComment; + // Opening And Closing Tags + $this->cssTags = $this->cssFont; + // HTML Tag + $this->cssTag = $this->cssFont; + // Attribute + $this->cssAttr = $this->cssKeyword; + // Attribute Value + $this->cssAttrS = $this->cssHighlight; + } + + // RexEx Rules + // PHP + protected $regexPhp = '/<(\?|%)(?:php|\s|=){1}(.|\s)*?(?:(?:\1)>|$)/'; + // Comments And Doctype + protected $regexCom = '/((?:)|(?:))/'; + // Tags + protected $regexTags = '/(<\\/?[^><]+>)/'; + // Tag Parameter + protected $regexTag = '/(<[\\/]?)([\\w]*){1}((?:.|\\s)+?)?([\\/]?>{1})/'; + // All Attributes + protected $regexAttr = '/[\\s\\w-]+(?:(?:=(["\']))(?:(?:.)+?)?(?:\\1))?/'; + //Single Attribute + protected $regexAttrS = '/([\\s\\w-]+[=]?)(["\'](?:(?:.)+)?["\'])?/'; + + // Buffer For Comments + protected $comments = array(); + + /** + * Highlights The String + * + * @param string Source + * @return string Output + */ + protected function getCode($source) + { + $regex = array( + // php + $this->regexPhp => array($this,'phpcode'), + // Comments and Doctype + $this->regexCom => array($this,'comment'), + // Tags + $this->regexTags => array($this,'tag') + ); + + // RegEX + foreach($regex as $key=>$value) + $source = preg_replace_callback($key, $value, $source); + + // Comments + $source = str_replace(array_keys($this->comments), array_values($this->comments), $source); + + return $source; + } + + /** + * Highlights PHP + * + * @param array RegEx Match + * @return string ID + */ + protected function phpcode($source) + { + $id = uniqid("#php", true); + + // Language Name + $fileName = TUCALSYN_LANGDIR . 'php.php'; + + // If Language Not Exists + if (!is_readable($fileName)) { + $this->comments[$id] = '' . htmlspecialchars($source[0]) . ''; + return $id; + } + + // Load Language + require_once($fileName); + + // Init The Class + $classSyn = new phpSyn; + $output = $classSyn->parse($source[0]); + + $this->comments[$id] = $output; + return $id; + } + + /** + * Saves The Comments + * + * @param array RegEx Match + * @return string ID + */ + protected function comment($source) + { + $id = uniqid("#", true); + $this->comments[$id] = '' . htmlspecialchars($source[0]) . ''; + return $id; + } + + /** + * Split And Highlights Tags + * + * @param array RegEx Match + * @return string Output + */ + protected function tag($source) + { + if (preg_match($this->regexTag, $source[0], $matches)) { + if (count($matches) == 5) { + $opening = '' . htmlspecialchars($matches[1]) . ''; + $tag = '' . htmlspecialchars($matches[2]) . ''; + $attr = $this->attributes($matches[3]); + $closing = '' . htmlspecialchars($matches[4]) . ''; + } + return $opening . $tag . $attr . $closing; + } + } + + /** + * Highlight Attributes + * + * @param string RegEx Match + * @return string Output + */ + protected function attributes($source) + { + // Separates Attributes + return preg_replace_callback( + $this->regexAttr, + function ($matches) { + // Highlight Attributes + return preg_replace_callback( + $this->regexAttrS, + function ($value) { + // Attribute Name + $output = '' . htmlspecialchars($value[1]) . ''; + + // Attribute Value + if (count($value) == 3) + $output .= '' . htmlspecialchars($value[2]) . ''; + + return $output; + }, + $matches[0] + ); + }, + $source + ); + } +} + +?> diff --git a/lang/php.php b/lang/php.php new file mode 100644 index 0000000..918ac7c --- /dev/null +++ b/lang/php.php @@ -0,0 +1,77 @@ +cssCom = $this->cssComment; + // Text + $this->cssTxt = $this->cssKeyword; + // Definitions + $this->cssDef = $this->cssFont; + // Strings + $this->cssStr = $this->cssHighlight; + } + + /** + * Highlights The String + * + * @param string Source + * @return string Output + */ + protected function getCode($source) + { + // PHP Syntaxhighlighting + $source = trim($source); + // add and + $source = preg_replace('/^\\/', '', $source, 1); + $source = preg_replace('/\<\/code\>$/', '', $source, 1); + $source = preg_replace('/\<\/span\>$/', '', $source, 1); + $source = trim($source); + // remove )(<\?php )(.*?)(<\/span>)/', '$1$3$4', $source); + $source = str_replace("
", "\n", $source); + + // Convert Colors + $regex = array( + // Comment + '#FF8000' => $this->cssCom, + // Text + '#007700' => $this->cssTxt, + // Definitions + '#0000BB' => $this->cssDef, + // Strings + '#DD0000' => $this->cssStr + ); + + //RegEX + foreach($regex as $key=>$value) + $source = preg_replace('/()/', '$1class="'.$value.'"$3', $source); + + return $source; + } +} + +?> diff --git a/lang/phpdev.php b/lang/phpdev.php new file mode 100644 index 0000000..3627be4 --- /dev/null +++ b/lang/phpdev.php @@ -0,0 +1,177 @@ +cssCom = $this->cssComment; + // namespace, use, class and other keywords + $this->cssNS = $this->cssKeyword; + // (stuff-> || stuff::) and variables + $this->cssRef = $this->cssKeyword; + // Class Names + $this->cssCN = $this->cssFont; + } + + // RexEx Rules + // opening and closing tags + protected $regexTags = '/(<(\\?|%){1}(?:php|=)?)(?:.|\\s)+?((?:\\2)>)|(<(?:\\?|%){1}(?:php|=)?)/'; + // comments + protected $regexCom = '/(?:\\/\\*(?:.|\\s)+?\\*\\/)|(?:\\/\\/(?:.)+)|(?:#(?:.)+)/'; + // namespace + protected $regexNS = '/(namespace|use)([\\s]+[\\w\\\\]+)/i'; + // functions: [stuff::][$]stuff([content]) + protected $regexFunc = '/([\w]+::)?([$\w]+)[\s]*\(((?:[^()]|(?R))*)\)/'; + // class + protected $regexCN = '/(class)([\s]+[\w\\\\]+(?2)?)([\s]+{)/'; + // variables + protected $regexVar = '/((?:[\w]+::)?\$[\w\d]+[\s]*(?:->[\w]*)?)([+-]?=)?/'; + // buffer for comments + protected $comments = array(); + + /** + * Highlights The String + * + * @param string Source + * @return string Output + */ + protected function getCode($source) + { + $source = htmlspecialchars($source); + + $regex = array( + // opening and closing tags + $this->regexTags => array($this,'tag'), + // comments + $this->regexCom => array($this,'comment'), + // namespace + $this->regexNS => array($this,'names'), + // functions + $this->regexFunc => array($this,'func'), + // class + $this->regexCN => array($this,'classmatch'), + // variables + $this->regexVar => array($this,'varmatch') + ); + + // RegEX + foreach($regex as $key=>$value) + $source = preg_replace_callback($key, $value, $source); + + // Comments + $source = str_replace(array_keys($this->comments), array_values($this->comments), $source); + + return $source; + } + + /** + * Saves The Comments + * + * @param array RegEx Match + * @return string ID + */ + protected function comment($source) + { + $id = uniqid("#", true); + $this->comments[$id] = '' . $source[0] . ''; + return $id; + } + + /** + * Highlights namespace & use + * + * @param array RegEx Match + * @return string Output + */ + protected function names($source) + { + return ''.$source[1].''.$source[2]; + } + + /** + * Highlights Functions + * + * @param array RegEx Match + * @return string Output + */ + protected function func($source) + { + //print_r($source); + //echo "

"; + + $ref = ($source[1] !== '') ? ''.$source[1].'' : ''; + $name = ''.$source[2].''; + + $content = ''; + if($source[3] !== '') { + $regex = array( + // functions + $this->regexFunc => array($this,'func') + // TODO: Content + ); + + foreach($regex as $key=>$value) + $content = preg_replace_callback($key, $value, $source[3]); + } + + return $ref.$name.'('.$content.')'; + } + + /** + * Highlights Classes + * + * @param array RegEx Match + * @return string Output + */ + protected function classmatch($source) + { + $init = ''.$source[1].''; + + $mid = $source[2]; + if($source[2] !== '') { + if(preg_match_all('/[\w\\\\]+\b(?cssCN.'">'.$value.'
',$mid); + } + } + if(preg_match_all('/extends|implements/',$mid,$matches)) { + foreach ($matches[0] as $value) { + $mid = str_replace($value,''.$value.'',$mid); + } + } + } + + return $init.$mid.$source[3]; + } + + /** + * Highlights Variables + * + * @param array RegEx Match + * @return string Output + */ + protected function varmatch($source) + { + $var = ''.$source[1].''; + + return $var.$source[2]; + } +} + +?> diff --git a/synParser.php b/synParser.php new file mode 100644 index 0000000..d75fdfe --- /dev/null +++ b/synParser.php @@ -0,0 +1,228 @@ +setSource($source); + $this->setLang($lang); + $this->setLineNumbers($lineNumbers); + $this->setLineBegin($lineBegin); + $this->setLineEnd($lineEnd); + } + + /* + * SETTER + */ + + /** + * Sets The Source + * + * @param string Source + * @return void + */ + public function setSource($source) + { + if (is_string($source) && ($source !== '')) { + $this->source = $this->normalizeNewlines($source); + } + } + + /** + * Sets The Language + * + * @param string Language + */ + public function setLang($lang) + { + if (is_string($lang) && ($lang !== '')) { + // Präpariert den Sprachnamen + $lang = preg_replace('/[^\w\-]/', '', $lang); + $lang = strtolower($lang); + + // Setzt den Sprachnamen + $fileName = $this->langPath . $lang . '.php'; + $lang = ucfirst($lang); + $this->lang = $lang . 'Syn'; + + if (!is_readable($fileName)) { + throw new \Exception('Unable to load the language file!'); + } + + require_once($fileName); + } + } + + /** + * Activates Line Numbers + * + * @param bool + * @return void + */ + public function setLineNumbers($lineNumbers) + { + if (is_bool($lineNumbers)) { + $this->lineNumbers = $lineNumbers; + } + } + + /** + * Set Line Begin + * + * @param integer + * @return void + */ + public function setLineBegin($lineBegin) + { + if (is_int($lineBegin)) { + $this->lineBegin = $lineBegin; + } + } + + /** + * Set End Line + * + * @param integer + * @return void + */ + public function setLineEnd($lineEnd) + { + if (is_int($lineEnd)) { + $this->lineEnd = $lineEnd; + } + } + + /** + * Set Within Line + * + * @param bool + * @return void + */ + public function setWithinLine($withinLine) + { + if (is_bool($withinLine)) { + $this->withinLine = $withinLine; + } + } + + /* + * FUNCTIONS + */ + + /** + * Converts All Line Breaks To UNIX Format + * + * @param string Source + * @return string Source + */ + function normalizeNewlines($source) + { + $source = str_replace("\r\n", "\n", $source); + $source = str_replace("\r", "\n", $source); + + return $source; + } + + /** + * Limits The Source + * + * @param integer Line Where The Source Begins + * @param integer Line Where The Source Ends + * @return void + */ + function limitSource() + { + // Split + $sourcetemp = explode("\n", $this->source); + + if ($this->lineBegin <= 0 || $this->lineBegin > count($sourcetemp)) { + $this->lineBegin = 0; + } else { + $this->lineBegin -= 1; // Arrays starts with 0 + } + + // Limit + if ($this->lineBegin > $this->lineEnd || $this->lineEnd > count($sourcetemp)) { + $sourcetemp = array_slice($sourcetemp, $this->lineBegin); + } else { + $sourcetemp = array_slice($sourcetemp, $this->lineBegin, ($this->lineEnd - 1) - (count($sourcetemp) - 1)); + } + + // Melting + $this->source = implode("\n", $sourcetemp); + } + + /** + * Highlights The Source + * + * @return string + */ + function parseCode() + { + // Limit + if ($this->lineEnd || $this->lineBegin) { + $this->limitSource(); + } + + // Language + $classSyn = new $this->lang(); + + // Create Output + $output = $classSyn->parse($this->source); + + // Within Line + if ($this->withinLine) { + return '' . $output . ''; + } + // Linenumbers + if (!$this->lineNumbers) { + return '
' . $output . '
'; + } else { + $linenb = ''; + for ($i = substr_count($output, "\n") + 1; $i > 0; $i--) { + $linenb .= ""; + } + return '
' . $output . '' . $linenb . '
'; + } + } +} + +?> diff --git a/temp.css b/temp.css new file mode 100644 index 0000000..defb69e --- /dev/null +++ b/temp.css @@ -0,0 +1,51 @@ +code .c { + color:#9e9e9e; +} +code .b { + font-weight:800; +} +code .k { + color:#689f38; +} +code .h { + color:#dd2c00; +} +code .s { + color:#1e88e5; +} +code .u { + text-decoration: underline; +} +/* Inline */ +code.wl { + padding: 1px; + background-color: #F5F5F5; + border: 1px solid #ccc; +} +/* Line Numbers */ +pre.ln { + padding-left: 45px; +} +pre.ln code { + position: relative; + counter-reset: linenb; + word-break: normal !important; + word-wrap: normal !important; + white-space: pre !important; +} +pre.ln code span.ln { + position: absolute; + width: 40px; + top: -2px; + left: -45px; + border-right: 1px solid #999; + pointer-events: none; +} +pre.ln code span.ln span::before { + display: block; + text-align: right; + padding-right: 5px; + counter-increment: linenb; + content: counter(linenb); + color: #888; +}