Monday, March 3, 2014

Syntax Highlighter Generik dengan PHP

PHP

<?php

/**
 * Original => http://phoboslab.org/log/2007/08/generic-syntax-highlighting-with-regular-expressions
 * Usage => `echo SyntaxHighlight::process('source code here');`
 */

class SyntaxHighlight {
    public static function process($s) {
        $s = htmlspecialchars($s);

        // Workaround for escaped backslashes
        $s = str_replace('\\\\','\\\\<e>', $s); 

        $regexp = array(

            // Comments/Strings
            '/(
                \/\*.*?\*\/|
                \/\/.*?\n|
                \#.[^a-fA-F0-9]+?\n|
                \&lt;\!\-\-[\s\S]+\-\-\&gt;|
                (?<!\\\)&quot;.*?(?<!\\\)&quot;|
                (?<!\\\)\'(.*?)(?<!\\\)\'
            )/isex' 
            => 'self::replaceId($tokens,\'$1\')',

            // Punctuations
            '/([\-\!\%\^\*\(\)\+\|\~\=\`\{\}\[\]\:\"\'<>\?\,\.\/]+)/'
            => '<span class="P">$1</span>',

            // Numbers (also look for Hex)
            '/(?<!\w)(
                (0x|\#)[\da-f]+|
                \d+|
                \d+(px|em|cm|mm|rem|s|\%)
            )(?!\w)/ix'
            => '<span class="N">$1</span>',

            // Make the bold assumption that an
            // all uppercase word has a special meaning
            '/(?<!\w|>|\#)(
                [A-Z_0-9]{2,}
            )(?!\w)/x'
            => '<span class="D">$1</span>',

            // Keywords
            '/(?<!\w|\$|\%|\@|>)(
                and|or|xor|for|do|while|foreach|as|return|die|exit|if|then|else|
                elseif|new|delete|try|throw|catch|finally|class|function|string|
                array|object|resource|var|bool|boolean|int|integer|float|double|
                real|string|array|global|const|static|public|private|protected|
                published|extends|switch|true|false|null|void|this|self|struct|
                char|signed|unsigned|short|long
            )(?!\w|=")/ix'
            => '<span class="K">$1</span>',

            // PHP/Perl-Style Vars: $var, %var, @var
            '/(?<!\w)(
                (\$|\%|\@)(\-&gt;|\w)+
            )(?!\w)/ix'
            => '<span class="V">$1</span>'

        );

        $tokens = array(); // This array will be filled from the regexp-callback

        $s = preg_replace(array_keys($regexp), array_values($regexp), $s);

        // Paste the comments and strings back in again
        $s = str_replace(array_keys($tokens), array_values($tokens), $s);

        // Delete the "Escaped Backslash Workaround Token" (TM)
        // and replace tabs with four spaces.
        $s = str_replace(array('<e>', "\t"), array('', '    '), $s);

        return '<pre><code>' . $s . '</code></pre>';
    }

    // Regexp-Callback to replace every comment or string with a uniqid and save
    // the matched text in an array
    // This way, strings and comments will be stripped out and wont be processed
    // by the other expressions searching for keywords etc.
    private static function replaceId(&$a, $match) {
        $id = "##r" . uniqid() . "##";

        // String or Comment?
        if(substr($match, 0, 2) == '//' || substr($match, 0, 2) == '/*' || substr($match, 0, 2) == '##' || substr($match, 0, 7) == '&lt;!--') {
            $a[$id] = '<span class="C">' . $match . '</span>';
        } else {
            $a[$id] = '<span class="S">' . $match . '</span>';
        }
        return $id;
    }
}

?>

CSS

pre {
  display:block;
  background-color:#3F3F3F;
  margin:1em 0;
  padding:1em;
  font:normal normal 13px/1.4 Consolas,"Andale Mono WT","Andale Mono","Lucida Console","Lucida Sans Typewriter","DejaVu Sans Mono","Bitstream Vera Sans Mono","Liberation Mono","Nimbus Mono L",Monaco,"Courier New",Courier,Monospace;
  color:#E3CEAB;
  overflow:auto;
  white-space:pre;
  word-wrap:normal;
}
pre code {
  font:inherit;
  color:inherit;
}
pre span.N {color:#8CD0D3} /* Numbers */
pre span.S {color:#CC9385} /* Strings */
pre span.C {color:#7F9F7F} /* Comments */
pre span.K {color:#DFC47D} /* Keywords */
pre span.V {color:#CEDF99} /* Vars */
pre span.D {color:#FFFFFF} /* Defines */
pre span.P {color:#9F9D65} /* Punctuations */

Lihat Demo

Labels: ,

7 Comments:

At Monday, March 3, 2014 at 6:55:00 PM GMT+7, Blogger fizzi said...

Wah, sekarang updatenya enggak tentang blogcepot. Udah ganti profesi kayaknya nih.

 
At Wednesday, March 5, 2014 at 10:21:00 PM GMT+7, Blogger Beben Koben said...

Ho`oh, skrg mah PHP-an...
Mana link demonya ada bacaan "This Account Has Been Suspended" :D

 
At Thursday, March 6, 2014 at 6:20:00 AM GMT+7, Blogger Taufik Nurrohman said...

Itu bukan Saya mas. Situsnya yang kena suspend. Semuanya! :(

 
At Thursday, March 6, 2014 at 9:43:00 AM GMT+7, Blogger Admin said...

kalau syntax yang dipakai mas taufik ini kan lebih keren :yaya: :-bd

 
At Tuesday, August 26, 2014 at 9:28:00 PM GMT+7, Blogger Nursalim Laimi said...

cara membuat syntax kayak punya blog ini gimana?
mohon tutorialnya!

 
At Wednesday, August 27, 2014 at 8:15:00 AM GMT+7, Blogger Taufik Nurrohman said...

Saya pakai Highlight.js, tapi versi yang lama. Panduan cara pemasangannya ada di halaman ini → How to Use Highlight.js

Di sini tutorialnya tidak ada, mungkin bisa Googling.

 
At Sunday, December 11, 2016 at 6:31:00 AM GMT+7, Blogger Wawan Beneran said...

Mas Taufik, maaf mas, ane naksir ama pengumuman macam ini, tutorialnya ada gak ya mas? terimakasih

[img]https://lh3.googleusercontent.com/-B9Y9fbrxvHI/WEyPlN--X8I/AAAAAAAAAVA/qu6Vf8VH5PgwETNmYPPQ08EQcn7S8Sr8QCL0B/w530-d-h231-p/pengumuman.PNG[/img]

 

Post a Comment

<< Home