Introducing Sunlight[source]
xml
<glacius:metadata> | |
<title>Introducing Sunlight</title> | |
<description>Introduction post for my client-side syntax highlighting library</description> | |
<category>Legacy blog posts</category> | |
<category>Programming</category> | |
</glacius:metadata> | |
<glacius:macro name="legacy blargh banner"> | |
<properties> | |
<originalUrl>https://tmont.com/blargh/2011/4/introducing-sunlight</originalUrl> | |
<originalDate>2011-04-06T22:02:45.000Z</originalDate> | |
</properties> | |
</glacius:macro> | |
<p> | |
So, I wrote a syntax highlighter. The answer is because it was fun. And also because I was | |
displeased with the inadequacy of other ones, such as | |
<a href="https://github.com/syntaxhighlighter/syntaxhighlighter/">SyntaxHighlighter</a> and | |
<a href="https://github.com/googlearchive/code-prettify">Prettify</a>. | |
</p> | |
<p> | |
Specifically, those highlighters rely on hideously complicated regular expressions, | |
which works in a general kind of case, but most languages are a bit more sophisticated | |
than just having keywords. For example, in C#, there are contextual keywords (like get, | |
set and value) that are keywords only when used in a certain context. Obviously a | |
regular expression isn't going to be able to detect that kind of idiosyncrasy. | |
</p> | |
<p> | |
So what I did is write a syntax highlighting library that could. And I called it | |
<a href="https://sunlightjs.com/">Sunlight</a>. | |
</p> | |
<p>Note how awesome this is:</p> | |
<p class="text-center"> | |
<img glacius:src="sunlight-get-set-value.png" alt="Sunlight syntax highlighting example for C#" /> | |
</p> | |
<p> | |
More complete demo (and for other languages) is <a href="https://sunlightjs.com/demo.html">here</a>. | |
</p> | |
<h3>Technical Details</h3> | |
<p> | |
Sunlight behaves much more like an actual language parser. It actually iterates over each | |
character of the string it's highlighting, invoking rules that convert the text into a | |
stream of tokens. Then it analyzes the tokens, which generally just converts it to HTML. | |
I know that sounds like it's slow, but it's actually a little bit faster than Prettify | |
(in the benchmarks I did, which was just comparing the times it took to highlight the | |
C# demo code; Sunlight's C# language definition is by far the most complicated). | |
</p> | |
<p> | |
Each language is defined by an object that specifies a few things like keywords, | |
operators, scopes (like strings and comments) and so forth. It also gives the option | |
for full customization by defining your own parse rules. The C# language definition | |
does this so that it can, for example, detect contextual keywords like get, set and | |
value and color them appropriately. | |
</p> | |
<p> | |
Sunlight also has a fairly easy way to detect what I called "name idents" (e.g. class | |
names) and color them appropriately. You can also write rules to indicate when an | |
identifier should be "named" (like, say, when it comes after the new keyword). | |
</p> | |
<h3>Usage</h3> | |
<p> | |
Usage is simple, and pretty similar to the other syntax highlighters. Include the | |
javascript file(s), a CSS file for styling, and surround your block of code with an | |
element with a special class name, like so: | |
</p> | |
<glacius:code lang="html"><![CDATA[<pre class="sunlight-highlight-csharp">public class MyClass { | |
private int get; | |
private int set; | |
private int value; | |
public int Property { | |
get { return get; } | |
set { | |
value = set ?? value; | |
return set; | |
} | |
} | |
}</pre>]]></glacius:code> | |
<p>And then call <code>Sunlight.highlightAll();</code> and the rest is magic.</p> | |
<p> | |
Sunlight is capable of many other magical things, which are spelled out in some | |
<a href="https://sunlightjs.com/docs.html">tediously detailed documentation</a>. | |
</p> | |