183 lines
8.5 KiB
HTML
183 lines
8.5 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="en">
|
||
<head>
|
||
|
||
<meta charset="utf-8" />
|
||
<title>Extending Prism ▲ Prism</title>
|
||
<link rel="stylesheet" href="style.css" />
|
||
<link rel="stylesheet" href="prism.css" data-noprefix />
|
||
<script src="../prefixfree/prefixfree.min.js"></script>
|
||
|
||
</head>
|
||
<body class="language-javascript">
|
||
|
||
<header>
|
||
<div class="intro" data-src="templates/header-main.html" data-type="text/html"></div>
|
||
|
||
<h2>Extending Prism</h2>
|
||
<p>Prism is awesome out of the box, but it’s even awesomer when it’s customized to your own needs. This section will help you write new language definitions, plugins and all-around Prism hacking.</p>
|
||
</header>
|
||
|
||
<section id="language-definitions">
|
||
<h1>Language definitions</h1>
|
||
|
||
<p>Every language is defined as a set of tokens, which are expressed as regular expressions. For example, this is the language definition for CSS:</p>
|
||
<pre data-src="components/prism-css.js"></pre>
|
||
|
||
<p>A regular expression literal is the simplest way to express a token. An alternative way, with more options, is by using an object literal. With that notation, the regular expression describing the token would be the <code>pattern</code> attribute:</p>
|
||
<pre><code class="language-javascript">...
|
||
'tokenname': {
|
||
pattern: /regex/
|
||
}
|
||
...</code></pre>
|
||
<p>So far the functionality is exactly the same between the short and extended notations. However, the extended notation allows for additional options:</p>
|
||
|
||
<dl>
|
||
<dt>inside</dt>
|
||
<dd>This property accepts another object literal, with tokens that are allowed to be nested in this token.
|
||
This makes it easier to define certain languages. However, keep in mind that they’re slower and if coded poorly, can even result in infinite recursion.
|
||
For an example of nested tokens, check out the Markup language definition:
|
||
<pre data-src="components/prism-markup.js"></pre></dd>
|
||
|
||
<dt>lookbehind</dt>
|
||
<dd>This option mitigates JavaScript’s lack of lookbehind. When set to <code>true</code>,
|
||
the first capturing group in the regex <code>pattern</code> is discarded when matching this token, so it effectively behaves
|
||
as if it was lookbehind. For an example of this, check out the JavaScript language definition, in particular the regex and line-comment tokens:
|
||
<pre data-src="components/prism-javascript.js"></pre></dd>
|
||
|
||
<dt>rest</dt>
|
||
<dd>Accepts an object literal with tokens and appends them to the end of the current object literal. Useful for referring to tokens defined elsewhere. For an example where <code>rest</code> is useful, check the Markup definitions above.</dd>
|
||
</dl>
|
||
|
||
<p>Unless explicitly allowed through the <code>inside</code> property, each token cannot contain other tokens, so their order is significant. Although per the ECMAScript specification, objects are not required to have a specific ordering of their properties, in practice they do in every modern browser.</p>
|
||
|
||
<section>
|
||
<h1><code>Prism.languages.insertBefore(inside, before, insert<span class="optional" title="Default value: Prism.languages">, root</span>)</code></h1>
|
||
|
||
<p>This is a helper method to ease modifying existing languages. For example, the CSS language definition not only defines CSS highlighting for CSS documents,
|
||
but also needs to define highlighting for CSS embedded in HTML through <code class="language-markup"><style></code> elements. To do this, it needs to modify
|
||
<code>Prism.languages.markup</code> and add the appropriate tokens. However, <code>Prism.languages.markup</code>
|
||
is a regular JavaScript object literal, so if you do this:</p>
|
||
|
||
<pre><code >Prism.languages.markup.style = {
|
||
/* tokens */
|
||
};</code></pre>
|
||
|
||
<p>then the <code>style</code> token will be added (and processed) at the end. <code>Prism.languages.insertBefore</code> allows you to insert
|
||
tokens <em>before</em> existing tokens. For the CSS example above, you would use it like this:</p>
|
||
|
||
<pre><code>Prism.languages.insertBefore('markup', 'cdata', {
|
||
'style': {
|
||
/* tokens */
|
||
}
|
||
});</code></pre>
|
||
|
||
<h2>Parameters</h2>
|
||
<dl>
|
||
<dt>inside</dt>
|
||
<dd>The property of <code>root</code> that contains the object to be modified.</dd>
|
||
|
||
<dt>before</dt>
|
||
<dd>Key to insert before (String)</dd>
|
||
|
||
<dt>insert</dt>
|
||
<dd>An object containing the key-value pairs to be inserted</dd>
|
||
|
||
<dt>root</dt>
|
||
<dd>The root object, i.e. the object that contains the object that will be modified. Optional, default value is <code>Prism.languages</code>.</dd>
|
||
</dl>
|
||
</section>
|
||
</section>
|
||
|
||
<section id="writing-plugins">
|
||
<h1>Writing plugins</h1>
|
||
|
||
<p>Prism’s plugin architecture is fairly simple. To add a callback, you use <code class="language-javascript">Prism.hooks.add(hookname, callback)</code>.
|
||
<code>hookname</code> is a string with the hook id, that uniquely identifies the hook your code should run at.
|
||
<code>callback</code> is a function that accepts one parameter: an object with various variables that can be modified, since objects in JavaScript are passed by reference.
|
||
For example, here’s a plugin from the Markup language definition that adds a tooltip to entity tokens which shows the actual character encoded:
|
||
<pre><code class="language-javascript">Prism.hooks.add('wrap', function(env) {
|
||
if (env.token === 'entity') {
|
||
env.attributes['title'] = env.content.replace(/&amp;/, '&');
|
||
}
|
||
});</code></pre>
|
||
<p>Of course, to understand which hooks to use you would have to read Prism’s source. Imagine where you would add your code and then find the appropriate hook.
|
||
If there is no hook you can use, you may <a href="">request one to be added</a>, detailing why you need it there.
|
||
</section>
|
||
|
||
<section id="api">
|
||
<h1>API documentation</h1>
|
||
|
||
<section id="highlight-all">
|
||
<h1><code>Prism.highlightAll(async, callback)</code></h1>
|
||
<p>This is the most high-level function in Prism’s API. It fetches all the elements that have a <code>.language-xxxx</code> class
|
||
and then calls <code>Prism.highlightElement()</code> on each one of them.</p>
|
||
|
||
<h2>Parameters</h2>
|
||
<dl>
|
||
<dt>async</dt>
|
||
<dd>Whether to use Web Workers to improve performance and avoid blocking the UI when highlighting very large chunks of code. False by default (<a href="faq.html#why-is-asynchronous-highlighting-disabled-by-default">why?</a>).</dd>
|
||
|
||
<dt>callback</dt>
|
||
<dd>An optional callback to be invoked after the highlighting is done. Mostly useful when <code>async</code> is true, since in that case, the highlighting is done asynchronously.</dd>
|
||
</dl>
|
||
</section>
|
||
|
||
<section id="highlight-element">
|
||
<h1><code>Prism.highlightElement(element, async, callback)</code></h1>
|
||
<p>Highlights the code inside a single element.</p>
|
||
|
||
<h2>Parameters</h2>
|
||
<dl>
|
||
<dt>element</dt>
|
||
<dd>The element containing the code. It must have a class of <code>language-xxxx</code> to be processed, where <code>xxxx</code> is a valid language identifier.</dd>
|
||
|
||
<dt>async</dt>
|
||
<dt>callback</dt>
|
||
<dd>Same as in <a href="#highlight-all"><code>Prism.highlightAll()</code></a></dd>
|
||
</dl>
|
||
</section>
|
||
|
||
<section id="highlight">
|
||
<h1><code>Prism.highlight(text, grammar)</code></h1>
|
||
<p>Low-level function, only use if you know what you’re doing.
|
||
It accepts a string of text as input and the language definitions to use, and returns a string with the HTML produced.</p>
|
||
|
||
<h2>Parameters</h2>
|
||
<dl>
|
||
<dt>text</dt>
|
||
<dd>A string with the code to be highlighted.</dd>
|
||
<dt>grammar</dt>
|
||
<dd>An object containing the tokens to use. Usually a language definition like <code>Prism.languages.html</code></dd>
|
||
</dl>
|
||
|
||
<h2>Returns</h2>
|
||
<p>The highlighted HTML</p>
|
||
</section>
|
||
|
||
<section id="tokenize">
|
||
<h1><code>Prism.tokenize(text, grammar)</code></h1>
|
||
<p>This is the heart of Prism, and the most low-level function you can use. It accepts a string of text as input and the language definitions to use, and returns an array with the tokenized code.
|
||
When the language definition includes nested tokens, the function is called recursively on each of these tokens. This method could be useful in other contexts as well, as a very crude parser.</p>
|
||
|
||
<h2>Parameters</h2>
|
||
<dl>
|
||
<dt>text</dt>
|
||
<dd>A string with the code to be highlighted.</dd>
|
||
<dt>grammar</dt>
|
||
<dd>An object containing the tokens to use. Usually a language definition like <code>Prism.languages.html</code></dd>
|
||
</dl>
|
||
|
||
<h2>Returns</h2>
|
||
<p>An array of strings, tokens (class <code>Prism.Token</code>) and other arrays.</p>
|
||
</section>
|
||
</section>
|
||
|
||
<footer data-src="templates/footer.html" data-type="text/html"></footer>
|
||
|
||
<script src="prism.js"></script>
|
||
<script src="utopia.js"></script>
|
||
<script src="code.js"></script>
|
||
|
||
</body>
|
||
</html> |