<?php
/*
==================
Welcome to Prism !
==================
*/

// This page is the only documentation atm.
class foo {
  var $foo;
  var $bar;
  function foo() {
    $this->foo = 'Foo';
    $this->bar = array('Bar1', 'Bar2', 'Bar3');
  }
}

$foo = new foo();
$name = 'MonNom';

echo <<<ABC
Mon nom est "$name". J'affiche des $foo->foo.
Maintenant, j'affiche un {$foo->bar[1]}.
Ceci se traduit par un 'A' majuscule : \x41
ABC;

echo <<<'EOT'
Mom nom est "$name". J'affiche quelques $foo->foo.
Maintenant, j'affiche quelques {$foo->bar[1]}.
Ceci ne devrait pas afficher un 'A': \x41
EOT;
?>

Prism: Generalities

Prism is a general syntax highlighting engine for PHP (v5 and more).
It has as some nice features:

  • an MIT licence;
  • it is very light (about 10 kilo octets without the comments);
  • grammars are very easy to build and extend; sure, you'll have to play with regexps, but if you look at them inside Prism's languages files, you'll find out that they are still understandable in most cases.
    This is because Prism does not use regexps all the time: it is helped by a state-machine. Moreover, Prism does not looses its time highlighting things you don't want like spaces, newlines, etc. It also has a nice little callback system inside grammar rules.
    You can see it working by watching the following PHP samples with HereDoc and NowDoc (choose a theme like Birds Of Paradise to view it best).
  • You can test it online (and report bugs) within the Prism's Pastebin (atm, the pastebin is outdated and uses an older version).

NEWS

  • 02.09.2011: A major new version codename 'Vega':
    • Fixed a bug with very very long lines: PHP doesn't like them, I had to cut them in smallest pieces.
    • Prism uses litteral programming inside its sources. I'm building a new documentation format for PHP (the idea is not new, it's a sort of port of Docco but with a Creole markup instead of Markdown). The result is the following. It's not currently avaible, but should be soon.
    • Prism is now using a cache system for syntax rules so it is a bit faster for large files.
    • The old HL class has been renamed Prism, beware of compatibily issues.
    • Added support for two new languages:
  • 02.05.2011: New version fixing some (not all, I shall investigate wich methods should be public/private) bad PHP 4 practices. Also added an HTML cleaning option (turned to true by default), thanks to Shawncplus.

Download and Test

Sources

Prism's zipped archive is here.

Testing in live

The rather limited Pastebin, as you won't be able to edit back your pastes.

Available languages:

At the moment, there's only a few dozen of languages available (with the name used by Prism inside parenthesis), and I must confess that some of them may lack accuracy (because I just don't use them):

  • AutoHotKey (ahk)
  • CoffeeScript (coffeescript)
  • C++ (cpp)
  • Haskell (haskell)
  • PHP (php)
  • JavaScript (js)
  • XML & HTML (xml)
  • CSS (css)
  • Lua (lua)
  • Python (python)
  • Ruby (ruby)
  • F# (fsharp)
  • SQL (sql)
  • Text only (text)
  • A mix of PHP + HTML + JS

Prism: how to use it ?

Generic usage (given that you have two strings : of for your $language, and a (big) one for your $sourcecode):

include('Prism.php'); // include_once('Prism.php'); depending on your needs

// Prism needs a formatter for HTML output (I hope to 
// build one for OpenOffice docs) so here, we instanciate one:
$formatter = new HtmlFormatter();

// We also need an Highlighter (HL) instance.
// It takes a formatter instance and a language (just a string) as arguments.
$p = new Prism($formatter, $language);

// Now, to process your source code
// and get the output just do the following:

$output = $p->from_string($sourcecode);

Real life example to highlight some PHP code

So, let's suppose we want to highlight the follwing PHP snippet:

class foo {
    var $foo;
    var $bar;
    function foo() {
        $this->foo = 'Foo';
        $this->bar = array('Bar1', 'Bar2', 'Bar3');
    }
}

Then, we can use Prism like this:

include('Prism.php');
$formatter = new HtmlFormatter();
$p = new Prism(formatter, 'php');

$sourcecode = <<<'TEST' // we need to quote ; it's the NewDoc format
class foo {
    var $foo;
    var $bar;
    function foo() {
        $this->foo = 'Foo';
        $this->bar = array('Bar1', 'Bar2', 'Bar3');
    }
}
TEST;

$output = $p->from_string($sourcecode);

The HTML output will be :

<span class="Keywords3">class</span> <span class="className">foo</span> <span class="Pars">{</span>
    <span class="Keywords">var</span> <span class="Tag">$foo</span><span class="Pars">;</span>
    <span class="Keywords">var</span> <span class="Tag">$bar</span><span class="Pars">;</span>

    <span class="Keywords">function</span> foo<span class="Pars">() {</span>
        <span class="Tag">$this</span><span class="Operators">-&gt;</span><span class="funcName">foo</span> <span class="Operators">=</span> <span class="SingleString">'Foo'</span><span class="Pars">;</span>
        <span class="Tag">$this</span><span class="Operators">-&gt;</span><span class="funcName">bar</span> <span class="Operators">=</span> <span class="Keywords2">array</span><span class="Pars">(</span><span class="SingleString">'Bar1'</span><span class="Pars">,</span> <span class="SingleString">'Bar2'</span><span class="Pars">,</span> <span class="SingleString">'Bar3'</span><span class="Pars">);
    }
}</span>

Notice that it is your job to englode the result inside a <pre class="code">...</pre> tag.

and the rendering is like:

class foo {
    var $foo;
    var $bar;
    function foo() {
        $this->foo = 'Foo';
        $this->bar = array('Bar1', 'Bar2', 'Bar3');
    }
}

You'll also find a css folder containin some predefined themes files.

What's left ?

So, here we go:

  • Some grammars are still very basic, ie Lisp, SQL to name a few.
  • As I am the only developper, there is maybe still some bugs inside grammar rules, and I should also say that it is my first PHP project.
  • There's no line numbering at the moment, and I don't know if I want them. But you can get the sources and add them if you really need them.
  • For large files, Prism can be rather slow (a few seconds for highlighting ie JQuery 1.5 sources for example);

Bugs ? Ideas ?

Just drop me a mail at: kibleur dot christophe @ gmail dot com

This doc

Yes, the documentation is rather sparse atm. I've build it with a modified version of Ivan Fomichev's Creole parser using Prism inside it. You have the source within Prism's archive.

I was helped by the beautiful cross-plateform SublimeText editor.