/** * Prism: Lightweight, robust, elegant syntax highlighting * MIT license http://www.opensource.org/licenses/mit-license.php/ * @author Lea Verou http://lea.verou.me */ (function(){ // Private helper vars var lang = /\blang(?:uage)?-(?!\*)(\w+)\b/i; var _ = self.Prism = { util: { type: function (o) { return Object.prototype.toString.call(o).match(/\[object (\w+)\]/)[1]; }, // Deep clone a language definition (e.g. to extend it) clone: function (o) { var type = _.util.type(o); switch (type) { case 'Object': var clone = {}; for (var key in o) { if (o.hasOwnProperty(key)) { clone[key] = _.util.clone(o[key]); } } return clone; case 'Array': return o.slice(); } return o; } }, languages: { extend: function (id, redef) { var lang = _.util.clone(_.languages[id]); for (var key in redef) { lang[key] = redef[key]; } return lang; }, // Insert a token before another token in a language literal insertBefore: function (inside, before, insert, root) { root = root || _.languages; var grammar = root[inside]; var ret = {}; for (var token in grammar) { if (grammar.hasOwnProperty(token)) { if (token == before) { for (var newToken in insert) { if (insert.hasOwnProperty(newToken)) { ret[newToken] = insert[newToken]; } } } ret[token] = grammar[token]; } } return root[inside] = ret; }, // Traverse a language definition with Depth First Search DFS: function(o, callback) { for (var i in o) { callback.call(o, i, o[i]); if (_.util.type(o) === 'Object') { _.languages.DFS(o[i], callback); } } } }, highlightAll: function(async, callback) { var elements = document.querySelectorAll('code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code'); for (var i=0, element; element = elements[i++];) { _.highlightElement(element, async === true, callback); } }, highlightElement: function(element, async, callback) { // Find language var language, grammar, parent = element; while (parent && !lang.test(parent.className)) { parent = parent.parentNode; } if (parent) { language = (parent.className.match(lang) || [,''])[1]; grammar = _.languages[language]; } if (!grammar) { return; } // Set language on the element, if not present element.className = element.className.replace(lang, '').replace(/\s+/g, ' ') + ' language-' + language; // Set language on the parent, for styling parent = element.parentNode; if (/pre/i.test(parent.nodeName)) { parent.className = parent.className.replace(lang, '').replace(/\s+/g, ' ') + ' language-' + language; } var code = element.textContent; if(!code) { return; } code = code.replace(/&/g, '&').replace(/ text.length) { // Something went terribly wrong, ABORT, ABORT! break tokenloop; } if (str instanceof Token) { continue; } pattern.lastIndex = 0; var match = pattern.exec(str); if (match) { if(lookbehind) { lookbehindLength = match[1].length; } var from = match.index - 1 + lookbehindLength, match = match[0].slice(lookbehindLength), len = match.length, to = from + len, before = str.slice(0, from + 1), after = str.slice(to + 1); var args = [i, 1]; if (before) { args.push(before); } var wrapped = new Token(token, inside? _.tokenize(match, inside) : match); args.push(wrapped); if (after) { args.push(after); } Array.prototype.splice.apply(strarr, args); } } } return strarr; }, hooks: { all: {}, add: function (name, callback) { var hooks = _.hooks.all; hooks[name] = hooks[name] || []; hooks[name].push(callback); }, run: function (name, env) { var callbacks = _.hooks.all[name]; if (!callbacks || !callbacks.length) { return; } for (var i=0, callback; callback = callbacks[i++];) { callback(env); } } } }; var Token = _.Token = function(type, content) { this.type = type; this.content = content; }; Token.stringify = function(o, language, parent) { if (typeof o == 'string') { return o; } if (Object.prototype.toString.call(o) == '[object Array]') { return o.map(function(element) { return Token.stringify(element, language, o); }).join(''); } var env = { type: o.type, content: Token.stringify(o.content, language, parent), tag: 'span', classes: ['token', o.type], attributes: {}, language: language, parent: parent }; if (env.type == 'comment') { env.attributes['spellcheck'] = 'true'; } _.hooks.run('wrap', env); var attributes = ''; for (var name in env.attributes) { attributes += name + '="' + (env.attributes[name] || '') + '"'; } return '<' + env.tag + ' class="' + env.classes.join(' ') + '" ' + attributes + '>' + env.content + ''; }; if (!self.document) { // In worker self.addEventListener('message', function(evt) { var message = JSON.parse(evt.data), lang = message.language, code = message.code; self.postMessage(JSON.stringify(_.tokenize(code, _.languages[lang]))); self.close(); }, false); return; } // Get current script and highlight var script = document.getElementsByTagName('script'); script = script[script.length - 1]; if (script) { _.filename = script.src; if (document.addEventListener && !script.hasAttribute('data-manual')) { document.addEventListener('DOMContentLoaded', _.highlightAll); } } })();; Prism.languages.markup = { 'comment': /<!--[\w\W]*?-->/g, 'prolog': /<\?.+?\?>/, 'doctype': /<!DOCTYPE.+?>/, 'cdata': /<!\[CDATA\[[\w\W]*?]]>/i, 'tag': { pattern: /<\/?[\w:-]+\s*(?:\s+[\w:-]+(?:=(?:("|')(\\?[\w\W])*?\1|[^\s'">=]+))?\s*)*\/?>/gi, inside: { 'tag': { pattern: /^<\/?[\w:-]+/i, inside: { 'punctuation': /^<\/?/, 'namespace': /^[\w-]+?:/ } }, 'attr-value': { pattern: /=(?:('|")[\w\W]*?(\1)|[^\s>]+)/gi, inside: { 'punctuation': /=|>|"/g } }, 'punctuation': /\/?>/g, 'attr-name': { pattern: /[\w:-]+/g, inside: { 'namespace': /^[\w-]+?:/ } } } }, 'entity': /&#?[\da-z]{1,8};/gi }; // Plugin to make entity title show the real entity, idea by Roman Komarov Prism.hooks.add('wrap', function(env) { if (env.type === 'entity') { env.attributes['title'] = env.content.replace(/&/, '&'); } }); ; Prism.languages.css = { 'comment': /\/\*[\w\W]*?\*\//g, 'atrule': { pattern: /@[\w-]+?.*?(;|(?=\s*{))/gi, inside: { 'punctuation': /[;:]/g } }, 'url': /url\((["']?).*?\1\)/gi, 'selector': /[^\{\}\s][^\{\};]*(?=\s*\{)/g, 'property': /(\b|\B)[\w-]+(?=\s*:)/ig, 'string': /("|')(\\?.)*?\1/g, 'important': /\B!important\b/gi, 'ignore': /&(lt|gt|amp);/gi, 'punctuation': /[\{\};:]/g }; if (Prism.languages.markup) { Prism.languages.insertBefore('markup', 'tag', { 'style': { pattern: /(<|<)style[\w\W]*?(>|>)[\w\W]*?(<|<)\/style(>|>)/ig, inside: { 'tag': { pattern: /(<|<)style[\w\W]*?(>|>)|(<|<)\/style(>|>)/ig, inside: Prism.languages.markup.tag.inside }, rest: Prism.languages.css } } }); }; Prism.languages.css.selector = { pattern: /[^\{\}\s][^\{\}]*(?=\s*\{)/g, inside: { 'pseudo-element': /:(?:after|before|first-letter|first-line|selection)|::[-\w]+/g, 'pseudo-class': /:[-\w]+(?:\(.*\))?/g, 'class': /\.[-:\.\w]+/g, 'id': /#[-:\.\w]+/g } }; Prism.languages.insertBefore('css', 'ignore', { 'hexcode': /#[\da-f]{3,6}/gi, 'entity': /\\[\da-f]{1,8}/gi, 'number': /[\d%\.]+/g, 'function': /(attr|calc|cross-fade|cycle|element|hsla?|image|lang|linear-gradient|matrix3d|matrix|perspective|radial-gradient|repeating-linear-gradient|repeating-radial-gradient|rgba?|rotatex|rotatey|rotatez|rotate3d|rotate|scalex|scaley|scalez|scale3d|scale|skewx|skewy|skew|steps|translatex|translatey|translatez|translate3d|translate|url|var)/ig });; Prism.languages.clike = { 'comment': { pattern: /(^|[^\\])(\/\*[\w\W]*?\*\/|(^|[^:])\/\/.*?(\r?\n|$))/g, lookbehind: true }, 'string': /("|')(\\?.)*?\1/g, 'class-name': { pattern: /((?:(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[a-z0-9_\.\\]+/ig, lookbehind: true, inside: { punctuation: /(\.|\\)/ } }, 'keyword': /\b(if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/g, 'boolean': /\b(true|false)\b/g, 'function': { pattern: /[a-z0-9_]+\(/ig, inside: { punctuation: /\(/ } }, 'number': /\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee]-?\d+)?)\b/g, 'operator': /[-+]{1,2}|!|<=?|>=?|={1,3}|(&){1,2}|\|?\||\?|\*|\/|\~|\^|\%/g, 'ignore': /&(lt|gt|amp);/gi, 'punctuation': /[{}[\];(),.:]/g }; ; Prism.languages.javascript = Prism.languages.extend('clike', { 'keyword': /\b(var|let|if|else|while|do|for|return|in|instanceof|function|get|set|new|with|typeof|try|throw|catch|finally|null|break|continue)\b/g, 'number': /\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee]-?\d+)?|NaN|-?Infinity)\b/g }); Prism.languages.insertBefore('javascript', 'keyword', { 'regex': { pattern: /(^|[^/])\/(?!\/)(\[.+?]|\\.|[^/\r\n])+\/[gim]{0,3}(?=\s*($|[\r\n,.;})]))/g, lookbehind: true } }); if (Prism.languages.markup) { Prism.languages.insertBefore('markup', 'tag', { 'script': { pattern: /(<|<)script[\w\W]*?(>|>)[\w\W]*?(<|<)\/script(>|>)/ig, inside: { 'tag': { pattern: /(<|<)script[\w\W]*?(>|>)|(<|<)\/script(>|>)/ig, inside: Prism.languages.markup.tag.inside }, rest: Prism.languages.javascript } } }); } ; /** * Original by Aaron Harun: http://aahacreative.com/2012/07/31/php-syntax-highlighting-prism/ * Modified by Miles Johnson: http://milesj.me * * Supports the following: * - Extends clike syntax * - Support for PHP 5.3 and 5.4 (namespaces, traits, etc) * - Smarter constant and function matching * * Adds the following new token classes: * constant, delimiter, variable, function, package */ Prism.languages.php = Prism.languages.extend('clike', { 'keyword': /\b(and|or|xor|array|as|break|case|cfunction|class|const|continue|declare|default|die|do|else|elseif|enddeclare|endfor|endforeach|endif|endswitch|endwhile|extends|for|foreach|function|include|include_once|global|if|new|return|static|switch|use|require|require_once|var|while|abstract|interface|public|implements|private|protected|parent|throw|null|echo|print|trait|namespace|final|yield|goto|instanceof|finally|try|catch)\b/ig, 'constant': /\b[A-Z0-9_]{2,}\b/g }); Prism.languages.insertBefore('php', 'keyword', { 'delimiter': /(\?>|<\?php|<\?)/ig, 'variable': /(\$\w+)\b/ig, 'package': { pattern: /(\\|namespace\s+|use\s+)[\w\\]+/g, lookbehind: true, inside: { punctuation: /\\/ } } }); // Must be defined after the function pattern Prism.languages.insertBefore('php', 'operator', { 'property': { pattern: /(->)[\w]+/g, lookbehind: true } }); // Add HTML support of the markup language exists if (Prism.languages.markup) { // Tokenize all inline PHP blocks that are wrapped in // This allows for easy PHP + markup highlighting Prism.hooks.add('before-highlight', function(env) { if (env.language !== 'php') { return; } env.tokenStack = []; env.code = env.code.replace(/(?:<\?php|<\?|<\?php|<\?)[\w\W]*?(?:\?>|\?>)/ig, function(match) { env.tokenStack.push(match); return '{{{PHP' + env.tokenStack.length + '}}}'; }); }); // Re-insert the tokens after highlighting Prism.hooks.add('after-highlight', function(env) { if (env.language !== 'php') { return; } for (var i = 0, t; t = env.tokenStack[i]; i++) { env.highlightedCode = env.highlightedCode.replace('{{{PHP' + (i + 1) + '}}}', Prism.highlight(t, env.grammar, 'php')); } env.element.innerHTML = env.highlightedCode; }); // Wrap tokens in classes that are missing them Prism.hooks.add('wrap', function(env) { if (env.language === 'php' && env.type === 'markup') { env.content = env.content.replace(/(\{\{\{PHP[0-9]+\}\}\})/g, "$1"); } }); // Add the rules before all others Prism.languages.insertBefore('php', 'comment', { 'markup': { pattern: /(<|<)[^?]\/?(.*?)(>|>)/g, inside: Prism.languages.markup }, 'php': /\{\{\{PHP[0-9]+\}\}\}/g }); } ; Prism.languages.insertBefore('php', 'variable', { 'this': /\$this/g, 'global': /\$_?(GLOBALS|SERVER|GET|POST|FILES|REQUEST|SESSION|ENV|COOKIE|HTTP_RAW_POST_DATA|argc|argv|php_errormsg|http_response_header)/g, 'scope': { pattern: /\b[\w\\]+::/g, inside: { keyword: /(static|self|parent)/, punctuation: /(::|\\)/ } } });; Prism.languages.c = Prism.languages.extend('clike', { 'keyword': /\b(asm|typeof|inline|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|int|long|register|return|short|signed|sizeof|static|struct|switch|typedef|union|unsigned|void|volatile|while)\b/g, 'operator': /[-+]{1,2}|!=?|<{1,2}=?|>{1,2}=?|\->|={1,2}|\^|~|%|(&){1,2}|\|?\||\?|\*|\//g }); Prism.languages.insertBefore('c', 'keyword', { //property class reused for macro statements 'property': { pattern:/#[a-zA-Z]+\ .*/g, inside: { property: /<[a-zA-Z.]+>/g } } }); ; Prism.languages.cpp = Prism.languages.extend('c', { 'keyword': /\b(alignas|alignof|asm|auto|bool|break|case|catch|char|char16_t|char32_t|class|compl|const|constexpr|const_cast|continue|decltype|default|delete|delete\[\]|do|double|dynamic_cast|else|enum|explicit|export|extern|float|for|friend|goto|if|inline|int|long|mutable|namespace|new|new\[\]|noexcept|nullptr|operator|private|protected|public|register|reinterpret_cast|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|try|typedef|typeid|typename|union|unsigned|using|virtual|void|volatile|wchar_t|while)\b/g, 'operator': /[-+]{1,2}|!=?|<{1,2}=?|>{1,2}=?|\->|:{1,2}|={1,2}|\^|~|%|(&){1,2}|\|?\||\?|\*|\/|\b(and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/g }); ; Prism.languages.sql= { 'comment': { pattern: /(^|[^\\])(\/\*[\w\W]*?\*\/|((--)|(\/\/)).*?(\r?\n|$))/g, lookbehind: true }, 'string' : /("|')(\\?.)*?\1/g, 'keyword' : /\b(ACTION|ADD|AFTER|ALGORITHM|ALTER|ANALYZE|APPLY|AS|ASC|AUTHORIZATION|BACKUP|BDB|BEGIN|BERKELEYDB|BIGINT|BINARY|BIT|BLOB|BOOL|BOOLEAN|BREAK|BROWSE|BTREE|BULK|BY|CALL|CASCADE|CASCADED|CASE|CHAIN|CHAR VARYING|CHARACTER VARYING|CHECK|CHECKPOINT|CLOSE|CLUSTERED|COALESCE|COLUMN|COLUMNS|COMMENT|COMMIT|COMMITTED|COMPUTE|CONNECT|CONSISTENT|CONSTRAINT|CONTAINS|CONTAINSTABLE|CONTINUE|CONVERT|CREATE|CROSS|CURRENT|CURRENT_DATE|CURRENT_TIME|CURRENT_TIMESTAMP|CURRENT_USER|CURSOR|DATA|DATABASE|DATABASES|DATETIME|DBCC|DEALLOCATE|DEC|DECIMAL|DECLARE|DEFAULT|DEFINER|DELAYED|DELETE|DENY|DESC|DESCRIBE|DETERMINISTIC|DISABLE|DISCARD|DISK|DISTINCT|DISTINCTROW|DISTRIBUTED|DO|DOUBLE|DOUBLE PRECISION|DROP|DUMMY|DUMP|DUMPFILE|DUPLICATE KEY|ELSE|ENABLE|ENCLOSED BY|END|ENGINE|ENUM|ERRLVL|ERRORS|ESCAPE|ESCAPED BY|EXCEPT|EXEC|EXECUTE|EXIT|EXPLAIN|EXTENDED|FETCH|FIELDS|FILE|FILLFACTOR|FIRST|FIXED|FLOAT|FOLLOWING|FOR|FOR EACH ROW|FORCE|FOREIGN|FREETEXT|FREETEXTTABLE|FROM|FULL|FUNCTION|GEOMETRY|GEOMETRYCOLLECTION|GLOBAL|GOTO|GRANT|GROUP|HANDLER|HASH|HAVING|HOLDLOCK|IDENTITY|IDENTITY_INSERT|IDENTITYCOL|IF|IGNORE|IMPORT|INDEX|INFILE|INNER|INNODB|INOUT|INSERT|INT|INTEGER|INTERSECT|INTO|INVOKER|ISOLATION LEVEL|JOIN|KEY|KEYS|KILL|LANGUAGE SQL|LAST|LEFT|LIMIT|LINENO|LINES|LINESTRING|LOAD|LOCAL|LOCK|LONGBLOB|LONGTEXT|MATCH|MATCHED|MEDIUMBLOB|MEDIUMINT|MEDIUMTEXT|MERGE|MIDDLEINT|MODIFIES SQL DATA|MODIFY|MULTILINESTRING|MULTIPOINT|MULTIPOLYGON|NATIONAL|NATIONAL CHAR VARYING|NATIONAL CHARACTER|NATIONAL CHARACTER VARYING|NATIONAL VARCHAR|NATURAL|NCHAR|NCHAR VARCHAR|NEXT|NO|NO SQL|NOCHECK|NOCYCLE|NONCLUSTERED|NULLIF|NUMERIC|OF|OFF|OFFSETS|ON|OPEN|OPENDATASOURCE|OPENQUERY|OPENROWSET|OPTIMIZE|OPTION|OPTIONALLY|ORDER|OUT|OUTER|OUTFILE|OVER|PARTIAL|PARTITION|PERCENT|PIVOT|PLAN|POINT|POLYGON|PRECEDING|PRECISION|PREV|PRIMARY|PRINT|PRIVILEGES|PROC|PROCEDURE|PUBLIC|PURGE|QUICK|RAISERROR|READ|READS SQL DATA|READTEXT|REAL|RECONFIGURE|REFERENCES|RELEASE|RENAME|REPEATABLE|REPLICATION|REQUIRE|RESTORE|RESTRICT|RETURN|RETURNS|REVOKE|RIGHT|ROLLBACK|ROUTINE|ROWCOUNT|ROWGUIDCOL|ROWS?|RTREE|RULE|SAVE|SAVEPOINT|SCHEMA|SELECT|SERIAL|SERIALIZABLE|SESSION|SESSION_USER|SET|SETUSER|SHARE MODE|SHOW|SHUTDOWN|SIMPLE|SMALLINT|SNAPSHOT|SOME|SONAME|START|STARTING BY|STATISTICS|STATUS|STRIPED|SYSTEM_USER|TABLE|TABLES|TABLESPACE|TEMPORARY|TEMPTABLE|TERMINATED BY|TEXT|TEXTSIZE|THEN|TIMESTAMP|TINYBLOB|TINYINT|TINYTEXT|TO|TOP|TRAN|TRANSACTION|TRANSACTIONS|TRIGGER|TRUNCATE|TSEQUAL|TYPE|TYPES|UNBOUNDED|UNCOMMITTED|UNDEFINED|UNION|UNPIVOT|UPDATE|UPDATETEXT|USAGE|USE|USER|USING|VALUE|VALUES|VARBINARY|VARCHAR|VARCHARACTER|VARYING|VIEW|WAITFOR|WARNINGS|WHEN|WHERE|WHILE|WITH|WITH ROLLUP|WITHIN|WORK|WRITE|WRITETEXT)\b/gi, 'boolean' : /\b(TRUE|FALSE|NULL)\b/gi, 'number' : /\b-?(0x)?\d*\.?[\da-f]+\b/g, 'operator' : /\b(ALL|AND|ANY|BETWEEN|EXISTS|IN|LIKE|NOT|OR|IS|UNIQUE|CHARACTER SET|COLLATE|DIV|OFFSET|REGEXP|RLIKE|SOUNDS LIKE|XOR)\b|[-+]{1}|!|=?<|=?>|={1}|(&){1,2}|\|?\||\?|\*|\//gi, 'ignore' : /&(lt|gt|amp);/gi, 'punctuation' : /[;[\]()`,.]/g }; ; (function(){ if(!window.Prism) { return; } function $$(expr, con) { return Array.prototype.slice.call((con || document).querySelectorAll(expr)); } function hasClass(element, className) { className = " " + className + " "; return (" " + element.className + " ").replace(/[\n\t]/g, " ").indexOf(className) > -1 } var CRLF = crlf = /\r?\n|\r/g; function highlightLines(pre, lines, classes) { var ranges = lines.replace(/\s+/g, '').split(','), offset = +pre.getAttribute('data-line-offset') || 0; var lineHeight = parseFloat(getComputedStyle(pre).lineHeight); for (var i=0, range; range = ranges[i++];) { range = range.split('-'); var start = +range[0], end = +range[1] || start; var line = document.createElement('div'); line.textContent = Array(end - start + 2).join(' \r\n'); line.className = (classes || '') + ' line-highlight'; //if the line-numbers plugin is enabled, then there is no reason for this plugin to display the line numbers if(!hasClass(pre, 'line-numbers')) { line.setAttribute('data-start', start); if(end > start) { line.setAttribute('data-end', end); } } line.style.top = (start - offset - 1) * lineHeight + 'px'; //allow this to play nicely with the line-numbers plugin if(hasClass(pre, 'line-numbers')) { //need to attack to pre as when line-numbers is enabled, the code tag is relatively which screws up the positioning pre.appendChild(line); } else { (pre.querySelector('code') || pre).appendChild(line); } } } function applyHash() { var hash = location.hash.slice(1); // Remove pre-existing temporary lines $$('.temporary.line-highlight').forEach(function (line) { line.parentNode.removeChild(line); }); var range = (hash.match(/\.([\d,-]+)$/) || [,''])[1]; if (!range || document.getElementById(hash)) { return; } var id = hash.slice(0, hash.lastIndexOf('.')), pre = document.getElementById(id); if (!pre) { return; } if (!pre.hasAttribute('data-line')) { pre.setAttribute('data-line', ''); } highlightLines(pre, range, 'temporary '); document.querySelector('.temporary.line-highlight').scrollIntoView(); } var fakeTimer = 0; // Hack to limit the number of times applyHash() runs Prism.hooks.add('after-highlight', function(env) { var pre = env.element.parentNode; var lines = pre && pre.getAttribute('data-line'); if (!pre || !lines || !/pre/i.test(pre.nodeName)) { return; } clearTimeout(fakeTimer); $$('.line-highlight', pre).forEach(function (line) { line.parentNode.removeChild(line); }); highlightLines(pre, lines); fakeTimer = setTimeout(applyHash, 1); }); addEventListener('hashchange', applyHash); })(); ; Prism.hooks.add('after-highlight', function (env) { // works only for wrapped inside
 (not inline)
	var pre = env.element.parentNode;
	if (!pre || !/pre/i.test(pre.nodeName) || pre.className.indexOf('line-numbers') === -1) {
		return;
	}

	var linesNum = (1 + env.code.split('\n').length);
	var lineNumbersWrapper;

	lines = new Array(linesNum);
	lines = lines.join('');

	lineNumbersWrapper = document.createElement('span');
	lineNumbersWrapper.className = 'line-numbers-rows';
	lineNumbersWrapper.innerHTML = lines;

	if (pre.hasAttribute('data-start')) {
		pre.style.counterReset = 'linenumber ' + (parseInt(pre.getAttribute('data-start'), 10) - 1);
	}

	env.element.appendChild(lineNumbersWrapper);

});;