237 lines
8.9 KiB
HTML
237 lines
8.9 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="en">
|
||
<head>
|
||
|
||
<meta charset="utf-8" />
|
||
<link rel="icon" href="assets/favicon.png" />
|
||
<title>FAQ ▲ Prism</title>
|
||
<link rel="stylesheet" href="assets/style.css" />
|
||
<link rel="stylesheet" href="themes/prism.css" data-noprefix />
|
||
<style>
|
||
#toc {
|
||
display: block;
|
||
position: static;
|
||
max-width: 900px;
|
||
font-size: 100%;
|
||
color: black;
|
||
}
|
||
</style>
|
||
<script src="assets/vendor/prefixfree.min.js"></script>
|
||
|
||
<script>var _gaq = [['_setAccount', 'UA-33746269-1'], ['_trackPageview']];</script>
|
||
<script src="https://www.google-analytics.com/ga.js" async></script>
|
||
</head>
|
||
<body class="language-none">
|
||
|
||
<header>
|
||
<div class="intro" data-src="assets/templates/header-main.html" data-type="text/html"></div>
|
||
|
||
<h2>FAQ</h2>
|
||
<p>Frequently Asked Questions, with a few Questions I want people to Frequently Ask.</p>
|
||
</header>
|
||
|
||
<section>
|
||
<h1>This page doesn’t work in Opera!</h1>
|
||
|
||
<p><strong>Prism works fine in Opera.</strong> However, this page might sometimes appear to not be working in Opera, due to the theme switcher triggering an Opera bug.
|
||
This will be fixed soon.</p>
|
||
</section>
|
||
|
||
<section>
|
||
<h1>Isn’t it bad to do syntax highlighting with regular expressions?</h1>
|
||
|
||
<p>It is true that to correctly handle every possible case of syntax found in the wild, one would need to write a full-blown parser.
|
||
However, in most web applications and websites a small error margin is usually acceptable and a rare highlighting failure is not the end of the world.
|
||
A syntax highlighter based on regular expressions might only be accurate 99% of the time (the actual percentage is just a guess),
|
||
but in exchange for the small error margin, it offers some very important benefits:
|
||
|
||
<ul>
|
||
<li>Smaller filesize. Proper parsers are very big.</li>
|
||
<li>Extensibility. Authors can define new languages simply by knowing how to code regular expressions.
|
||
Writing a correct, unambiguous BNF grammar is a task at least an order of magnitude harder.</li>
|
||
<li>Graceful error recovery. Parsers fail on incorrect syntax, where regular expressions keep matching.</li>
|
||
</ul>
|
||
|
||
<p>For this reason, most syntax highlighters on the web and on desktop, are powered by regular expressions. This includes the internal syntax
|
||
highlighters used by popular native applications like Espresso and Sublime Text, at the time of writing.
|
||
Of course, not every regex-powered syntax highlighter is created equal. The number and type of failures can be vastly different, depending on
|
||
the exact algorithm used. <a href="known-failures.html">Prism’s known failures are documented on this page.</a>.</p>
|
||
</section>
|
||
|
||
<section>
|
||
<h1>Why is asynchronous highlighting disabled by default?</h1>
|
||
|
||
<p>Web Workers are good for preventing syntax highlighting of really large code blocks from blocking the main UI thread.
|
||
In most cases, you will want to highlight reasonably sized chunks of code, and this will not be needed.
|
||
Furthermore, using Web Workers is actually <strong>slower</strong> than synchronously highlighting, due to the overhead of creating and terminating
|
||
the Worker. It just appears faster in these cases because it doesn’t block the main thread.
|
||
In addition, since Web Workers operate on files instead of objects, plugins that hook on core parts of Prism (e.g. modify language definitions)
|
||
will not work unless included in the same file (using the builder in the <a href="download.html">Download</a> page will protect you from this pitfall).
|
||
Lastly, Web Workers cannot interact with the DOM and most other APIs (e.g. the console), so they are notoriously hard to debug.
|
||
</p>
|
||
</section>
|
||
|
||
<section>
|
||
<h1>Why is pre-existing HTML stripped off?</h1>
|
||
|
||
<p>Because it would complicate the code a lot, although it’s not a crucial feature for most people.
|
||
If it’s very important to you, you can use the <a href="plugins/keep-markup/">Keep Markup plugin</a>.</p>
|
||
</section>
|
||
|
||
<section>
|
||
<h1>If pre-existing HTML is stripped off, how can I highlight certain parts of the code?</h1>
|
||
|
||
<p>There is a number of ways around it. You can always break the block of code into multiple parts, and wrap the HTML around it (or just use a <code>.highlight</code> class).
|
||
You can see an example of this in action at the “<a href="index.html#basic-usage">Basic usage</a>” section of the homepage.</p>
|
||
<p>Another way around the limitation is to use the <a href="plugins/line-highlight/">Line Highlght plugin</a>, to highlight and link to specific lines and/or line ranges.
|
||
</section>
|
||
|
||
<section>
|
||
<h1>How do I know which tokens I can style for every language?</h1>
|
||
|
||
<p>Every token that is highlighted gets at least two classes: <code>token</code> and a class with the token type (e.g. <code>comment</code>) plus any number of aliases.
|
||
Aliases can be seen as additional token types and are used to give specialized tokens a more common class for easier styling.
|
||
You can find the different types of tokens either by looking at the keys of the object defining the language or by using the below interface.</p>
|
||
|
||
<p>Language: <select id="language-select"></select></p>
|
||
<pre class="language-none" style="height: 30em"><code id="print-tokens-output"></code></pre>
|
||
|
||
<p>Additionally, you can find a list of standard tokens on <a href="/tokens.html">this page</a>.</p>
|
||
</section>
|
||
|
||
<section>
|
||
<h1>How can I use different highlighting for tokens with the same name in different languages?</h1>
|
||
<p>Just use a descendant selector, that includes the language class. The default <code>prism.css</code> does this, to have different colors for
|
||
JavaScript strings (which are very common) and CSS strings (which are relatively rare). Here’s that code, simplified to illustrate the technique:
|
||
<pre><code class="language-css">.token.string {
|
||
color: #690;
|
||
}
|
||
|
||
.language-css .token.string,
|
||
.style .token.string {
|
||
color: #a67f59;
|
||
}</code></pre>
|
||
|
||
<p>Abbreviated language classes (e.g. <code>lang-css</code>) will be converted to their extended forms, so you don’t need to account for them.</p>
|
||
<p>The same technique can be used to differentiate XML tag namespaces from attribute namespaces:</p>
|
||
<pre><code class="language-css">.tag > .token.namespace {
|
||
color: #b37298;
|
||
}
|
||
.attr-name > .token.namespace {
|
||
color: #ab6;
|
||
}</code></pre>
|
||
</section>
|
||
|
||
<footer data-src="assets/templates/footer.html" data-type="text/html"></footer>
|
||
|
||
<script src="assets/vendor/utopia.js"></script>
|
||
<script src="prism.js"></script>
|
||
<script src="plugins/autoloader/prism-autoloader.min.js"></script>
|
||
<script>
|
||
Prism.plugins.autoloader.languages_path = 'components/';
|
||
</script>
|
||
<script src="components.js"></script>
|
||
<script>
|
||
(function () {
|
||
$$('section > h1').forEach(function (h1) {
|
||
$u.element.create('p', {
|
||
contents: {
|
||
tag: 'a',
|
||
properties: {
|
||
href: '#toc'
|
||
},
|
||
contents: '↑ Back to top'
|
||
},
|
||
inside: h1.parentNode
|
||
});
|
||
});
|
||
|
||
function printTokens(grammar) {
|
||
function toArray(x) {
|
||
return Array.isArray(x) ? x : (x == undefined ? [] : [x]);
|
||
}
|
||
|
||
var lines = [];
|
||
function log(line) {
|
||
if (lines.indexOf(line) === -1) {
|
||
lines.push(line);
|
||
}
|
||
}
|
||
|
||
var languageMap = new Map();
|
||
Object.keys(Prism.languages).filter(function (l) { return l in components.languages; }).forEach(function (l) {
|
||
languageMap.set(Prism.languages[l], 'Prism.languages["' + l + '"]');
|
||
});
|
||
|
||
var stack = new Map();
|
||
|
||
function inner(g, prefix) {
|
||
if (prefix && languageMap.has(g)) {
|
||
log(prefix + ' > ...' + languageMap.get(g));
|
||
return;
|
||
}
|
||
if (stack.has(g)) {
|
||
log(prefix + ' > ...' + stack.get(g));
|
||
return;
|
||
}
|
||
|
||
stack.set(g, '(' + (prefix || ':root:') + ')');
|
||
|
||
for (var name in g) {
|
||
var element = g[name];
|
||
if (name === 'rest') {
|
||
inner(element, (prefix ? prefix + ' > ' : '') + ':rest:');
|
||
} else {
|
||
for (var a = toArray(element), i = 0, token; token = a[i++];) {
|
||
var line = (prefix ? prefix + ' > ' : '') + name + toArray(token.alias).map(function (a) {
|
||
return '.' + a;
|
||
}).join('');
|
||
|
||
log(line);
|
||
|
||
if (token.inside) {
|
||
inner(token.inside, line);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
stack.delete(g);
|
||
}
|
||
inner(grammar, '');
|
||
|
||
return lines.join('\n');
|
||
}
|
||
|
||
var loadedLanguages = {};
|
||
function showTokens() {
|
||
var language = $('#language-select').value;
|
||
if (Prism.languages[language]) {
|
||
$('#print-tokens-output').textContent = printTokens(Prism.languages[language]);
|
||
} else if (language in loadedLanguages) {
|
||
$('#print-tokens-output').textContent = '"' + language + '" doesn\'t have any tokens.';
|
||
} else {
|
||
// load grammar
|
||
Prism.plugins.autoloader.loadLanguages([language], function() {
|
||
loadedLanguages[language] = true;
|
||
showTokens();
|
||
}, function () {
|
||
$('#print-tokens-output').textContent = 'Unable to load "' + language + '"';
|
||
});
|
||
}
|
||
}
|
||
|
||
$('#language-select').onchange = showTokens;
|
||
$('#language-select').innerHTML = Object.keys(components.languages)
|
||
.filter(function (x) { return x !== 'meta'; })
|
||
.map(function (x) {
|
||
return '<option value="' + x + '">' + components.languages[x].title + '</option>';
|
||
}).join('');
|
||
showTokens();
|
||
}());
|
||
</script>
|
||
<script src="assets/code.js"></script>
|
||
|
||
</body>
|
||
</html>
|