Luminous PHP Syntax Highlighter

Luminous is a generic syntax highlighter for php aimed towards use in a web environment, where one might wish to display source code in a readable manner. It currently supports about 30 languages and output in HTML and LaTeX.

Luminous 0.5.7 released on 18/01/11

zip (recommended): []
tar.bz2: []
Stable Development info: Code/SVN/Issues etc []
Usage and API: documentation

the haps

Hey guys! Luminous is undergoing an experimental redesign and rewrite RIGHT NOW. If you want to be involved, check out the experimental branch [] on github. See this document [] for a rough overview. If you're just interested in using Luminous, ignore this paragraph and use a stable version (0.5.7 or SVN trunk on Google Code)!



Try out an online demo (html only).
Example LaTeX output: .tex, pdf (made with pdflatex), using the zenophilia highlighting theme.



Download a distribution archive above and extract it to a location inside the document root of your webserver (we'll assume it's to a directory called luminous/). Create a php source file that looks something like the following:

luminous_get_html_head(); //outputs the CSS includes 
echo luminous('cpp', '#include <stdio.h>
int main()
  printf("hello, world");
  return 0;

and you should see syntax highlighted output that looks a lot like this:

#include <stdio.h>
int main()
    printf("Hello world!");
    return 0;

If you have trouble, check to see whether the luminous/example.php file works (note: it doesn't in 0.5.4).

Advanced Usage

Look at the Doxygen documents for full usage and API documentation.


What makes Luminous so great?

Well, the answer to this is correctness and consistency. Some languages have excellent syntax highlighting options available but you may find yourself comparatively dissatisfied with the quality of those available for PHP. Luminous aims to:
  1. Usually get the right answer, i.e. highlight the right symbols and not highlight the wrong ones
  2. Be fast enough to be useful
  3. Highlight many different languages and make it pretty easy for anyone with a familiarity of a language to add acceptable support for it
  4. Provide consistency in colour themes
Obviously, the first three are somewhat at odds with each other: you can write a perfect syntax highlighter for a highly complex language if you don't need it to be fast and you don't care about reusing its logic to highlight other languages. Likewise, it's easy to make something fast if you don't mind that it often makes mistakes. Highlighting many languages is not so hard, but you're constrained to a single generic scanning algorithm which may not be powerful enough for all languages all of the time. So, as with all syntax highlighters, Luminous has to balance these things and aims to deliver what its author considers the most desirable solution. This may or may not intersect with what you consider the most desirable solution. It works very well for languages like C, Java(Script)? C#, Python, PHP, XML, CSS, etc, but, for example, Ruby in particular has some demanding syntax which Luminous (currently) can't handle 100% of the time (but it should be mostly okay).

System requirements

PHP >= 5.2. If you're using an earlier version, you really should upgrade!
Be warned that with full highlighting, highlighted output often reaches around 10x the size of the input. Memory requirements are a little higher still. However, the output is usually gzip-able down to roughly the input's size.


Luminous is licensed under the GPLv3. That basically means you're free to do pretty much what you want with it, but if you redistribute a modified version to other people, you must make your modified source code available to them also.

I used the HTML formatter and the output doesn't stretch vertically

This isn't a bug: the default behaviour is to limit the output to a maximum of height of 500px, you can override this with the $LUMINOUS_MAX_HEIGHT [] global variable.

I made some CSS changes to my page and they have affected Luminous

Yes, unfortunately Luminous's CSS cannot explicitly define unoverridable default rules for everything, so you'll have to either make your CSS selectors more discriminating so as to avoid Luminous, or, possibly easier, you can define .luminous { } blocks in your CSS to re-apply the default stylings to whatever properties you changed.

I think I found a bug...

Please submit it via the issue tracking section of the development site [], if it's not already there. Patches welcome too!

The docs are unclear/incomplete/wrong...

Documentation errors (and yes, lack of clarity or completeness is classed as an error) should be submitted to the issue tracker.

I want to add a theme/language/output-format, how?

See doxygen's language, and theme pages. There's no documentation for creating a new formatter yet, but have a look in src/formatters/ to see how it works; the HTML and LaTeX formatters inherit from an abstract base class, which yours will too.
If you'd like it included in Luminous after you've finished, feel free to post a patch (an SVN/unified diff, or simply your newly created .php/.css file will suffice) to the issue tracker.

It's too slow/it highlights far too much

You can reduce the highlighting level with the $LUMINOUS_HIGHLIGHTING_LEVEL [] variable. It defaults to 4, which is the maximum. Dropping it to 3 will make it leave things like operators alone and will give you a very noticeable performance increase and a less in-your-face output. It will gradually reduce what it highlights down to 0, at which only essentials like comments and strings are highlighted.

Could Luminous be used for things other than highlighting?

Possibly, depending on exactly what you wanted. It wouldn't be realistic to use it to detect errors in source code or act as a full interpreter or compiler (not that anyone should want to build either in PHP), but it is possible to use Luminous to parse and transform some languages, if the transformations are relatively simple.

As of version 0.5.0 Luminous can act like a full state machine with 'rules' (tokens) specfied as regular expressions and state transitions specified in terms of hierarchical rule relations. In 0.5.4 there's a script which parses CSS and loads the properties and values into memory (this is used to make the themes 'portable' away from HTML output). Parsing CSS properly is a non-trivial process as different tokens mean different things depending on exactly where they occur, but Luminous is capable of doing so. The script hooks into the state transitions (and the matched text) with callback functions. So in that sense Luminous is capable of being more than a syntax highlighter, and with enough glue around the callbacks you can probably make it do whatever you want, but highlighting is the focus.


If you want to hack the source code, get the latest SVN version (or the most recent tagged version). The pre-packaged versions do not include a few internal functions in the documentation, but more importantly the trunk/development version includes a large testing suite which is pretty much mandatory if you plan to make any changes. You'll need Python2.x, Bash and php-cli to run the tests (Windows users should investigate Cygwin for Bash, but I would recommend a Ubuntu virtual machine instead). There are a few READMEs in various parts of the tests/ directory. The top level tests/ script called runtests is most general and useful, you should run
$ python runtests --verbose --run-simple --run-regression
after every change you make to get a summary of whether you have obviously broken anything. The tests/regressions/ subdirectory is very useful (and you're essentially working blind without it); if you start triggering regressions it will dump diff files detailing the difference between what Luminous expected to generate and what it now generates (it might be that your regression isn't a regression at all, but a fix to a long standing minor bug, in which case, assuming the difference is entirely desired, the test cases will need updating). Look at tests/regressions/README for more info.

If you fix a bug in a language, you should add a regression test case.

You should also occasionally look at the fuzz tester to ensure you're not introducing any potentially infinite loops (which is deceptively easy to do if you're hacking the parsing algorithm; it's easy to overlook safety checks). The fuzz tester just throws a lot of random data at Luminous and expects it to exit after a while. If it doesn't exit and has to be interrupted, it will warn you. Before using it, run.

$ php fuzz.php --help
Formatter tests don't exist yet but will in future.


Last edited by mark at 23:55:54 14/03/11

Page loaded in 0.085s
2 calls to Luminous, total: 0.0036s, average: 0.0018s