| 875 |
lars |
1 |
/*!
|
|
|
2 |
* XRegExp 2.0.0 <xregexp.com> MIT License
|
|
|
3 |
*/
|
|
|
4 |
var XRegExp;XRegExp=XRegExp||function(n){"use strict";function v(n,i,r){var u;for(u in t.prototype)t.prototype.hasOwnProperty(u)&&(n[u]=t.prototype[u]);return n.xregexp={captureNames:i,isNative:!!r},n}function g(n){return(n.global?"g":"")+(n.ignoreCase?"i":"")+(n.multiline?"m":"")+(n.extended?"x":"")+(n.sticky?"y":"")}function o(n,r,u){if(!t.isRegExp(n))throw new TypeError("type RegExp expected");var f=i.replace.call(g(n)+(r||""),h,"");return u&&(f=i.replace.call(f,new RegExp("["+u+"]+","g"),"")),n=n.xregexp&&!n.xregexp.isNative?v(t(n.source,f),n.xregexp.captureNames?n.xregexp.captureNames.slice(0):null):v(new RegExp(n.source,f),null,!0)}function a(n,t){var i=n.length;if(Array.prototype.lastIndexOf)return n.lastIndexOf(t);while(i--)if(n[i]===t)return i;return-1}function s(n,t){return Object.prototype.toString.call(n).toLowerCase()==="[object "+t+"]"}function d(n){return n=n||{},n==="all"||n.all?n={natives:!0,extensibility:!0}:s(n,"string")&&(n=t.forEach(n,/[^\s,]+/,function(n){this[n]=!0},{})),n}function ut(n,t,i,u){var o=p.length,s=null,e,f;y=!0;try{while(o--)if(f=p[o],(f.scope==="all"||f.scope===i)&&(!f.trigger||f.trigger.call(u))&&(f.pattern.lastIndex=t,e=r.exec.call(f.pattern,n),e&&e.index===t)){s={output:f.handler.call(u,e,i),match:e};break}}catch(h){throw h;}finally{y=!1}return s}function b(n){t.addToken=c[n?"on":"off"],f.extensibility=n}function tt(n){RegExp.prototype.exec=(n?r:i).exec,RegExp.prototype.test=(n?r:i).test,String.prototype.match=(n?r:i).match,String.prototype.replace=(n?r:i).replace,String.prototype.split=(n?r:i).split,f.natives=n}var t,c,u,f={natives:!1,extensibility:!1},i={exec:RegExp.prototype.exec,test:RegExp.prototype.test,match:String.prototype.match,replace:String.prototype.replace,split:String.prototype.split},r={},k={},p=[],e="default",rt="class",it={"default":/^(?:\\(?:0(?:[0-3][0-7]{0,2}|[4-7][0-7]?)?|[1-9]\d*|x[\dA-Fa-f]{2}|u[\dA-Fa-f]{4}|c[A-Za-z]|[\s\S])|\(\?[:=!]|[?*+]\?|{\d+(?:,\d*)?}\??)/,"class":/^(?:\\(?:[0-3][0-7]{0,2}|[4-7][0-7]?|x[\dA-Fa-f]{2}|u[\dA-Fa-f]{4}|c[A-Za-z]|[\s\S]))/},et=/\$(?:{([\w$]+)}|(\d\d?|[\s\S]))/g,h=/([\s\S])(?=[\s\S]*\1)/g,nt=/^(?:[?*+]|{\d+(?:,\d*)?})\??/,ft=i.exec.call(/()??/,"")[1]===n,l=RegExp.prototype.sticky!==n,y=!1,w="gim"+(l?"y":"");return t=function(r,u){if(t.isRegExp(r)){if(u!==n)throw new TypeError("can't supply flags when constructing one RegExp from another");return o(r)}if(y)throw new Error("can't call the XRegExp constructor within token definition functions");var l=[],a=e,b={hasNamedCapture:!1,captureNames:[],hasFlag:function(n){return u.indexOf(n)>-1}},f=0,c,s,p;if(r=r===n?"":String(r),u=u===n?"":String(u),i.match.call(u,h))throw new SyntaxError("invalid duplicate regular expression flag");for(r=i.replace.call(r,/^\(\?([\w$]+)\)/,function(n,t){if(i.test.call(/[gy]/,t))throw new SyntaxError("can't use flag g or y in mode modifier");return u=i.replace.call(u+t,h,""),""}),t.forEach(u,/[\s\S]/,function(n){if(w.indexOf(n[0])<0)throw new SyntaxError("invalid regular expression flag "+n[0]);});f<r.length;)c=ut(r,f,a,b),c?(l.push(c.output),f+=c.match[0].length||1):(s=i.exec.call(it[a],r.slice(f)),s?(l.push(s[0]),f+=s[0].length):(p=r.charAt(f),p==="["?a=rt:p==="]"&&(a=e),l.push(p),++f));return v(new RegExp(l.join(""),i.replace.call(u,/[^gimy]+/g,"")),b.hasNamedCapture?b.captureNames:null)},c={on:function(n,t,r){r=r||{},n&&p.push({pattern:o(n,"g"+(l?"y":"")),handler:t,scope:r.scope||e,trigger:r.trigger||null}),r.customFlags&&(w=i.replace.call(w+r.customFlags,h,""))},off:function(){throw new Error("extensibility must be installed before using addToken");}},t.addToken=c.off,t.cache=function(n,i){var r=n+"/"+(i||"");return k[r]||(k[r]=t(n,i))},t.escape=function(n){return i.replace.call(n,/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&")},t.exec=function(n,t,i,u){var e=o(t,"g"+(u&&l?"y":""),u===!1?"y":""),f;return e.lastIndex=i=i||0,f=r.exec.call(e,n),u&&f&&f.index!==i&&(f=null),t.global&&(t.lastIndex=f?e.lastIndex:0),f},t.forEach=function(n,i,r,u){for(var e=0,o=-1,f;f=t.exec(n,i,e);)r.call(u,f,++o,n,i),e=f.index+(f[0].length||1);return u},t.globalize=function(n){return o(n,"g")},t.install=function(n){n=d(n),!f.natives&&n.natives&&tt(!0),!f.extensibility&&n.extensibility&&b(!0)},t.isInstalled=function(n){return!!f[n]},t.isRegExp=function(n){return s(n,"regexp")},t.matchChain=function(n,i){return function r(n,u){for(var o=i[u].regex?i[u]:{regex:i[u]},f=[],s=function(n){f.push(o.backref?n[o.backref]||"":n[0])},e=0;e<n.length;++e)t.forEach(n[e],o.regex,s);return u===i.length-1||!f.length?f:r(f,u+1)}([n],0)},t.replace=function(i,u,f,e){var c=t.isRegExp(u),s=u,h;return c?(e===n&&u.global&&(e="all"),s=o(u,e==="all"?"g":"",e==="all"?"":"g")):e==="all"&&(s=new RegExp(t.escape(String(u)),"g")),h=r.replace.call(String(i),s,f),c&&u.global&&(u.lastIndex=0),h},t.split=function(n,t,i){return r.split.call(n,t,i)},t.test=function(n,i,r,u){return!!t.exec(n,i,r,u)},t.uninstall=function(n){n=d(n),f.natives&&n.natives&&tt(!1),f.extensibility&&n.extensibility&&b(!1)},t.union=function(n,i){var l=/(\()(?!\?)|\\([1-9]\d*)|\\[\s\S]|\[(?:[^\\\]]|\\[\s\S])*]/g,o=0,f,h,c=function(n,t,i){var r=h[o-f];if(t){if(++o,r)return"(?<"+r+">"}else if(i)return"\\"+(+i+f);return n},e=[],r,u;if(!(s(n,"array")&&n.length))throw new TypeError("patterns must be a nonempty array");for(u=0;u<n.length;++u)r=n[u],t.isRegExp(r)?(f=o,h=r.xregexp&&r.xregexp.captureNames||[],e.push(t(r.source).source.replace(l,c))):e.push(t.escape(r));return t(e.join("|"),i)},t.version="2.0.0",r.exec=function(t){var r,f,e,o,u;if(this.global||(o=this.lastIndex),r=i.exec.apply(this,arguments),r){if(!ft&&r.length>1&&a(r,"")>-1&&(e=new RegExp(this.source,i.replace.call(g(this),"g","")),i.replace.call(String(t).slice(r.index),e,function(){for(var t=1;t<arguments.length-2;++t)arguments[t]===n&&(r[t]=n)})),this.xregexp&&this.xregexp.captureNames)for(u=1;u<r.length;++u)f=this.xregexp.captureNames[u-1],f&&(r[f]=r[u]);this.global&&!r[0].length&&this.lastIndex>r.index&&(this.lastIndex=r.index)}return this.global||(this.lastIndex=o),r},r.test=function(n){return!!r.exec.call(this,n)},r.match=function(n){if(t.isRegExp(n)){if(n.global){var u=i.match.apply(this,arguments);return n.lastIndex=0,u}}else n=new RegExp(n);return r.exec.call(n,this)},r.replace=function(n,r){var e=t.isRegExp(n),u,f,h,o;return e?(n.xregexp&&(u=n.xregexp.captureNames),n.global||(o=n.lastIndex)):n+="",s(r,"function")?f=i.replace.call(String(this),n,function(){var t=arguments,i;if(u)for(t[0]=new String(t[0]),i=0;i<u.length;++i)u[i]&&(t[0][u[i]]=t[i+1]);return e&&n.global&&(n.lastIndex=t[t.length-2]+t[0].length),r.apply(null,t)}):(h=String(this),f=i.replace.call(h,n,function(){var n=arguments;return i.replace.call(String(r),et,function(t,i,r){var f;if(i){if(f=+i,f<=n.length-3)return n[f]||"";if(f=u?a(u,i):-1,f<0)throw new SyntaxError("backreference to undefined group "+t);return n[f+1]||""}if(r==="$")return"$";if(r==="&"||+r==0)return n[0];if(r==="`")return n[n.length-1].slice(0,n[n.length-2]);if(r==="'")return n[n.length-1].slice(n[n.length-2]+n[0].length);if(r=+r,!isNaN(r)){if(r>n.length-3)throw new SyntaxError("backreference to undefined group "+t);return n[r]||""}throw new SyntaxError("invalid token "+t);})})),e&&(n.lastIndex=n.global?0:o),f},r.split=function(r,u){if(!t.isRegExp(r))return i.split.apply(this,arguments);var e=String(this),h=r.lastIndex,f=[],o=0,s;return u=(u===n?-1:u)>>>0,t.forEach(e,r,function(n){n.index+n[0].length>o&&(f.push(e.slice(o,n.index)),n.length>1&&n.index<e.length&&Array.prototype.push.apply(f,n.slice(1)),s=n[0].length,o=n.index+s)}),o===e.length?(!i.test.call(r,"")||s)&&f.push(""):f.push(e.slice(o)),r.lastIndex=h,f.length>u?f.slice(0,u):f},u=c.on,u(/\\([ABCE-RTUVXYZaeg-mopqyz]|c(?![A-Za-z])|u(?![\dA-Fa-f]{4})|x(?![\dA-Fa-f]{2}))/,function(n,t){if(n[1]==="B"&&t===e)return n[0];throw new SyntaxError("invalid escape "+n[0]);},{scope:"all"}),u(/\[(\^?)]/,function(n){return n[1]?"[\\s\\S]":"\\b\\B"}),u(/(?:\(\?#[^)]*\))+/,function(n){return i.test.call(nt,n.input.slice(n.index+n[0].length))?"":"(?:)"}),u(/\\k<([\w$]+)>/,function(n){var t=isNaN(n[1])?a(this.captureNames,n[1])+1:+n[1],i=n.index+n[0].length;if(!t||t>this.captureNames.length)throw new SyntaxError("backreference to undefined group "+n[0]);return"\\"+t+(i===n.input.length||isNaN(n.input.charAt(i))?"":"(?:)")}),u(/(?:\s+|#.*)+/,function(n){return i.test.call(nt,n.input.slice(n.index+n[0].length))?"":"(?:)"},{trigger:function(){return this.hasFlag("x")},customFlags:"x"}),u(/\./,function(){return"[\\s\\S]"},{trigger:function(){return this.hasFlag("s")},customFlags:"s"}),u(/\(\?P?<([\w$]+)>/,function(n){if(!isNaN(n[1]))throw new SyntaxError("can't use integer as capture name "+n[0]);return this.captureNames.push(n[1]),this.hasNamedCapture=!0,"("}),u(/\\(\d+)/,function(n,t){if(!(t===e&&/^[1-9]/.test(n[1])&&+n[1]<=this.captureNames.length)&&n[1]!=="0")throw new SyntaxError("can't use octal escape or backreference to undefined group "+n[0]);return n[0]},{scope:"all"}),u(/\((?!\?)/,function(){return this.hasFlag("n")?"(?:":(this.captureNames.push(null),"(")},{customFlags:"n"}),typeof exports!="undefined"&&(exports.XRegExp=t),t}()
|
|
|
5 |
|
|
|
6 |
|
|
|
7 |
/*!
|
|
|
8 |
* SyntaxHighlighter by Alex Gorbatchev
|
|
|
9 |
* https://github.com/alexgorbatchev/SyntaxHighlighter - MIT license
|
|
|
10 |
*/
|
|
|
11 |
|
|
|
12 |
//
|
|
|
13 |
// Begin anonymous function. This is used to contain local scope variables without polutting global scope.
|
|
|
14 |
//
|
|
|
15 |
if (typeof(SyntaxHighlighter) == 'undefined') var SyntaxHighlighter = function() {
|
|
|
16 |
|
|
|
17 |
// CommonJS
|
|
|
18 |
if (typeof(require) != 'undefined' && typeof(XRegExp) == 'undefined')
|
|
|
19 |
{
|
|
|
20 |
XRegExp = require('xregexp').XRegExp;
|
|
|
21 |
}
|
|
|
22 |
|
|
|
23 |
// Shortcut object which will be assigned to the SyntaxHighlighter variable.
|
|
|
24 |
// This is a shorthand for local reference in order to avoid long namespace
|
|
|
25 |
// references to SyntaxHighlighter.whatever...
|
|
|
26 |
var sh = {
|
|
|
27 |
defaults : {
|
|
|
28 |
/** Additional CSS class names to be added to highlighter elements. */
|
|
|
29 |
'class-name' : '',
|
|
|
30 |
|
|
|
31 |
/** First line number. */
|
|
|
32 |
'first-line' : 1,
|
|
|
33 |
|
|
|
34 |
/**
|
|
|
35 |
* Pads line numbers. Possible values are:
|
|
|
36 |
*
|
|
|
37 |
* false - don't pad line numbers.
|
|
|
38 |
* true - automaticaly pad numbers with minimum required number of leading zeroes.
|
|
|
39 |
* [int] - length up to which pad line numbers.
|
|
|
40 |
*/
|
|
|
41 |
'pad-line-numbers' : false,
|
|
|
42 |
|
|
|
43 |
/** Lines to highlight. */
|
|
|
44 |
'highlight' : null,
|
|
|
45 |
|
|
|
46 |
/** Title to be displayed above the code block. */
|
|
|
47 |
'title' : null,
|
|
|
48 |
|
|
|
49 |
/** Enables or disables smart tabs. */
|
|
|
50 |
'smart-tabs' : true,
|
|
|
51 |
|
|
|
52 |
/** Gets or sets tab size. */
|
|
|
53 |
'tab-size' : 4,
|
|
|
54 |
|
|
|
55 |
/** Enables or disables gutter. */
|
|
|
56 |
'gutter' : true,
|
|
|
57 |
|
|
|
58 |
/** Enables or disables toolbar. */
|
|
|
59 |
'toolbar' : true,
|
|
|
60 |
|
|
|
61 |
/** Enables quick code copy and paste from double click. */
|
|
|
62 |
'quick-code' : true,
|
|
|
63 |
|
|
|
64 |
/** Forces code view to be collapsed. */
|
|
|
65 |
'collapse' : false,
|
|
|
66 |
|
|
|
67 |
/** Enables or disables automatic links. */
|
|
|
68 |
'auto-links' : true,
|
|
|
69 |
|
|
|
70 |
/** Gets or sets light mode. Equavalent to turning off gutter and toolbar. */
|
|
|
71 |
'light' : false,
|
|
|
72 |
|
|
|
73 |
'unindent' : true,
|
|
|
74 |
|
|
|
75 |
'html-script' : false
|
|
|
76 |
},
|
|
|
77 |
|
|
|
78 |
config : {
|
|
|
79 |
space : ' ',
|
|
|
80 |
|
|
|
81 |
/** Enables use of <SCRIPT type="syntaxhighlighter" /> tags. */
|
|
|
82 |
useScriptTags : true,
|
|
|
83 |
|
|
|
84 |
/** Blogger mode flag. */
|
|
|
85 |
bloggerMode : false,
|
|
|
86 |
|
|
|
87 |
stripBrs : false,
|
|
|
88 |
|
|
|
89 |
/** Name of the tag that SyntaxHighlighter will automatically look for. */
|
|
|
90 |
tagName : 'pre',
|
|
|
91 |
|
|
|
92 |
strings : {
|
|
|
93 |
expandSource : 'expand source',
|
|
|
94 |
help : '?',
|
|
|
95 |
alert: 'SyntaxHighlighter\n\n',
|
|
|
96 |
noBrush : 'Can\'t find brush for: ',
|
|
|
97 |
brushNotHtmlScript : 'Brush wasn\'t configured for html-script option: ',
|
|
|
98 |
|
|
|
99 |
// this is populated by the build script
|
|
|
100 |
aboutDialog : ''
|
|
|
101 |
}
|
|
|
102 |
},
|
|
|
103 |
|
|
|
104 |
/** Internal 'global' variables. */
|
|
|
105 |
vars : {
|
|
|
106 |
discoveredBrushes : null,
|
|
|
107 |
highlighters : {}
|
|
|
108 |
},
|
|
|
109 |
|
|
|
110 |
/** This object is populated by user included external brush files. */
|
|
|
111 |
brushes : {},
|
|
|
112 |
|
|
|
113 |
/** Common regular expressions. */
|
|
|
114 |
regexLib : {
|
|
|
115 |
multiLineCComments : XRegExp('/\\*.*?\\*/', 'gs'),
|
|
|
116 |
singleLineCComments : /\/\/.*$/gm,
|
|
|
117 |
singleLinePerlComments : /#.*$/gm,
|
|
|
118 |
doubleQuotedString : /"([^\\"\n]|\\.)*"/g,
|
|
|
119 |
singleQuotedString : /'([^\\'\n]|\\.)*'/g,
|
|
|
120 |
multiLineDoubleQuotedString : XRegExp('"([^\\\\"]|\\\\.)*"', 'gs'),
|
|
|
121 |
multiLineSingleQuotedString : XRegExp("'([^\\\\']|\\\\.)*'", 'gs'),
|
|
|
122 |
xmlComments : XRegExp('(<|<)!--.*?--(>|>)', 'gs'),
|
|
|
123 |
url : /\w+:\/\/[\w-.\/?%&=:@;#,]*/g,
|
|
|
124 |
phpScriptTags : { left: /(<|<)\?(?:=|php)?/g, right: /\?(>|>)/g, 'eof' : true },
|
|
|
125 |
aspScriptTags : { left: /(<|<)%=?/g, right: /%(>|>)/g },
|
|
|
126 |
scriptScriptTags : { left: /(<|<)\s*script.*?(>|>)/gi, right: /(<|<)\/\s*script\s*(>|>)/gi }
|
|
|
127 |
},
|
|
|
128 |
|
|
|
129 |
toolbar: {
|
|
|
130 |
/**
|
|
|
131 |
* Generates HTML markup for the toolbar.
|
|
|
132 |
* @param {Highlighter} highlighter Highlighter instance.
|
|
|
133 |
* @return {String} Returns HTML markup.
|
|
|
134 |
*/
|
|
|
135 |
getHtml: function(highlighter)
|
|
|
136 |
{
|
|
|
137 |
var html = '<div class="toolbar">',
|
|
|
138 |
items = sh.toolbar.items,
|
|
|
139 |
list = items.list
|
|
|
140 |
;
|
|
|
141 |
|
|
|
142 |
function defaultGetHtml(highlighter, name)
|
|
|
143 |
{
|
|
|
144 |
return sh.toolbar.getButtonHtml(highlighter, name, sh.config.strings[name]);
|
|
|
145 |
}
|
|
|
146 |
|
|
|
147 |
for (var i = 0, l = list.length; i < l; i++)
|
|
|
148 |
{
|
|
|
149 |
html += (items[list[i]].getHtml || defaultGetHtml)(highlighter, list[i]);
|
|
|
150 |
}
|
|
|
151 |
|
|
|
152 |
html += '</div>';
|
|
|
153 |
|
|
|
154 |
return html;
|
|
|
155 |
},
|
|
|
156 |
|
|
|
157 |
/**
|
|
|
158 |
* Generates HTML markup for a regular button in the toolbar.
|
|
|
159 |
* @param {Highlighter} highlighter Highlighter instance.
|
|
|
160 |
* @param {String} commandName Command name that would be executed.
|
|
|
161 |
* @param {String} label Label text to display.
|
|
|
162 |
* @return {String} Returns HTML markup.
|
|
|
163 |
*/
|
|
|
164 |
getButtonHtml: function(highlighter, commandName, label)
|
|
|
165 |
{
|
|
|
166 |
return '<span><a href="#" class="toolbar_item'
|
|
|
167 |
+ ' command_' + commandName
|
|
|
168 |
+ ' ' + commandName
|
|
|
169 |
+ '">' + label + '</a></span>'
|
|
|
170 |
;
|
|
|
171 |
},
|
|
|
172 |
|
|
|
173 |
/**
|
|
|
174 |
* Event handler for a toolbar anchor.
|
|
|
175 |
*/
|
|
|
176 |
handler: function(e)
|
|
|
177 |
{
|
|
|
178 |
var target = e.target,
|
|
|
179 |
className = target.className || ''
|
|
|
180 |
;
|
|
|
181 |
|
|
|
182 |
function getValue(name)
|
|
|
183 |
{
|
|
|
184 |
var r = new RegExp(name + '_(\\w+)'),
|
|
|
185 |
match = r.exec(className)
|
|
|
186 |
;
|
|
|
187 |
|
|
|
188 |
return match ? match[1] : null;
|
|
|
189 |
}
|
|
|
190 |
|
|
|
191 |
var highlighter = getHighlighterById(findParentElement(target, '.syntaxhighlighter').id),
|
|
|
192 |
commandName = getValue('command')
|
|
|
193 |
;
|
|
|
194 |
|
|
|
195 |
// execute the toolbar command
|
|
|
196 |
if (highlighter && commandName && sh.toolbar.items[commandName].execute)
|
|
|
197 |
sh.toolbar.items[commandName].execute(highlighter);
|
|
|
198 |
|
|
|
199 |
// disable default A click behaviour
|
|
|
200 |
e.preventDefault();
|
|
|
201 |
},
|
|
|
202 |
|
|
|
203 |
/** Collection of toolbar items. */
|
|
|
204 |
items : {
|
|
|
205 |
// Ordered lis of items in the toolbar. Can't expect `for (var n in items)` to be consistent.
|
|
|
206 |
list: ['expandSource', 'language'],
|
|
|
207 |
|
|
|
208 |
expandSource: {
|
|
|
209 |
getHtml: function(highlighter)
|
|
|
210 |
{
|
|
|
211 |
if (highlighter.getParam('collapse') != true)
|
|
|
212 |
return '';
|
|
|
213 |
|
|
|
214 |
var title = highlighter.getParam('title');
|
|
|
215 |
return sh.toolbar.getButtonHtml(highlighter, 'expandSource', title ? title : sh.config.strings.expandSource);
|
|
|
216 |
},
|
|
|
217 |
|
|
|
218 |
execute: function(highlighter)
|
|
|
219 |
{
|
|
|
220 |
var div = getHighlighterDivById(highlighter.id);
|
|
|
221 |
removeClass(div, 'collapsed');
|
|
|
222 |
}
|
|
|
223 |
},
|
|
|
224 |
|
|
|
225 |
/** Command to display the about dialog window. */
|
|
|
226 |
help: {
|
|
|
227 |
execute: function(highlighter)
|
|
|
228 |
{
|
|
|
229 |
var wnd = popup('', '_blank', 500, 250, 'scrollbars=0'),
|
|
|
230 |
doc = wnd.document
|
|
|
231 |
;
|
|
|
232 |
|
|
|
233 |
doc.write(sh.config.strings.aboutDialog);
|
|
|
234 |
doc.close();
|
|
|
235 |
wnd.focus();
|
|
|
236 |
}
|
|
|
237 |
},
|
|
|
238 |
|
|
|
239 |
language: {
|
|
|
240 |
getHtml: function (highlighter) {
|
|
|
241 |
return highlighter.langLabel ?
|
|
|
242 |
sh.toolbar.getButtonHtml(highlighter, 'lang', highlighter.langLabel) :
|
|
|
243 |
'';
|
|
|
244 |
}
|
|
|
245 |
}
|
|
|
246 |
}
|
|
|
247 |
},
|
|
|
248 |
|
|
|
249 |
/**
|
|
|
250 |
* Finds all elements on the page which should be processes by SyntaxHighlighter.
|
|
|
251 |
*
|
|
|
252 |
* @param {Object} globalParams Optional parameters which override element's
|
|
|
253 |
* parameters. Only used if element is specified.
|
|
|
254 |
*
|
|
|
255 |
* @param {Object} element Optional element to highlight. If none is
|
|
|
256 |
* provided, all elements in the current document
|
|
|
257 |
* are returned which qualify.
|
|
|
258 |
*
|
|
|
259 |
* @return {Array} Returns list of <code>{ target: DOMElement, params: Object }</code> objects.
|
|
|
260 |
*/
|
|
|
261 |
findElements: function(globalParams, element)
|
|
|
262 |
{
|
|
|
263 |
var elements = element ? [element] : toArray(document.getElementsByTagName(sh.config.tagName)),
|
|
|
264 |
conf = sh.config,
|
|
|
265 |
result = []
|
|
|
266 |
;
|
|
|
267 |
|
|
|
268 |
// support for <SCRIPT TYPE="syntaxhighlighter" /> feature
|
|
|
269 |
if (conf.useScriptTags)
|
|
|
270 |
elements = elements.concat(getSyntaxHighlighterScriptTags());
|
|
|
271 |
|
|
|
272 |
if (elements.length === 0)
|
|
|
273 |
return result;
|
|
|
274 |
|
|
|
275 |
for (var i = 0, l = elements.length; i < l; i++)
|
|
|
276 |
{
|
|
|
277 |
var item = {
|
|
|
278 |
target: elements[i],
|
|
|
279 |
// local params take precedence over globals
|
|
|
280 |
params: merge(globalParams, parseParams(elements[i].className))
|
|
|
281 |
};
|
|
|
282 |
|
|
|
283 |
if (item.params['brush'] == null)
|
|
|
284 |
continue;
|
|
|
285 |
|
|
|
286 |
result.push(item);
|
|
|
287 |
}
|
|
|
288 |
|
|
|
289 |
return result;
|
|
|
290 |
},
|
|
|
291 |
|
|
|
292 |
/**
|
|
|
293 |
* Shorthand to highlight all elements on the page that are marked as
|
|
|
294 |
* SyntaxHighlighter source code.
|
|
|
295 |
*
|
|
|
296 |
* @param {Object} globalParams Optional parameters which override element's
|
|
|
297 |
* parameters. Only used if element is specified.
|
|
|
298 |
*
|
|
|
299 |
* @param {Object} element Optional element to highlight. If none is
|
|
|
300 |
* provided, all elements in the current document
|
|
|
301 |
* are highlighted.
|
|
|
302 |
*/
|
|
|
303 |
highlight: function(globalParams, element)
|
|
|
304 |
{
|
|
|
305 |
// Don't run the syntax highlighter on IE6/7 as it absolutely kills
|
|
|
306 |
// performance
|
|
|
307 |
var userAgent = navigator.appVersion;
|
|
|
308 |
if (userAgent.indexOf("MSIE 7.") !== -1 || userAgent.indexOf("MSIE 6.") !== -1) {
|
|
|
309 |
return;
|
|
|
310 |
}
|
|
|
311 |
|
|
|
312 |
var elements = this.findElements(globalParams, element),
|
|
|
313 |
propertyName = 'innerHTML',
|
|
|
314 |
highlighter = null,
|
|
|
315 |
conf = sh.config
|
|
|
316 |
;
|
|
|
317 |
|
|
|
318 |
if (elements.length === 0)
|
|
|
319 |
return;
|
|
|
320 |
|
|
|
321 |
for (var i = 0, l = elements.length; i < l; i++)
|
|
|
322 |
{
|
|
|
323 |
var element = elements[i],
|
|
|
324 |
target = element.target,
|
|
|
325 |
params = element.params,
|
|
|
326 |
brushName = params.brush,
|
|
|
327 |
code
|
|
|
328 |
;
|
|
|
329 |
|
|
|
330 |
if (brushName == null)
|
|
|
331 |
continue;
|
|
|
332 |
|
|
|
333 |
// Instantiate a brush
|
|
|
334 |
if (params['html-script'] == 'true' || sh.defaults['html-script'] == true)
|
|
|
335 |
{
|
|
|
336 |
highlighter = new sh.HtmlScript(brushName);
|
|
|
337 |
brushName = 'htmlscript';
|
|
|
338 |
}
|
|
|
339 |
else
|
|
|
340 |
{
|
|
|
341 |
var brush = findBrush(brushName);
|
|
|
342 |
|
|
|
343 |
if (brush)
|
|
|
344 |
highlighter = new brush();
|
|
|
345 |
else
|
|
|
346 |
continue;
|
|
|
347 |
}
|
|
|
348 |
|
|
|
349 |
code = target[propertyName];
|
|
|
350 |
|
|
|
351 |
// remove CDATA from <SCRIPT/> tags if it's present
|
|
|
352 |
if (conf.useScriptTags)
|
|
|
353 |
code = stripCData(code);
|
|
|
354 |
|
|
|
355 |
// Inject title if the attribute is present
|
|
|
356 |
if ((target.title || '') != '')
|
|
|
357 |
params.title = target.title;
|
|
|
358 |
|
|
|
359 |
params['brush'] = brushName;
|
|
|
360 |
highlighter.init(params);
|
|
|
361 |
element = highlighter.getDiv(code);
|
|
|
362 |
|
|
|
363 |
// carry over ID
|
|
|
364 |
if ((target.id || '') != '')
|
|
|
365 |
element.id = target.id;
|
|
|
366 |
|
|
|
367 |
target.parentNode.replaceChild(element, target);
|
|
|
368 |
}
|
|
|
369 |
},
|
|
|
370 |
|
|
|
371 |
/**
|
|
|
372 |
* Main entry point for the SyntaxHighlighter.
|
|
|
373 |
* @param {Object} params Optional params to apply to all highlighted elements.
|
|
|
374 |
*/
|
|
|
375 |
all: function(params)
|
|
|
376 |
{
|
|
|
377 |
attachEvent(
|
|
|
378 |
window,
|
|
|
379 |
'load',
|
|
|
380 |
function() { sh.highlight(params); }
|
|
|
381 |
);
|
|
|
382 |
}
|
|
|
383 |
}; // end of sh
|
|
|
384 |
|
|
|
385 |
/**
|
|
|
386 |
* Checks if target DOM elements has specified CSS class.
|
|
|
387 |
* @param {DOMElement} target Target DOM element to check.
|
|
|
388 |
* @param {String} className Name of the CSS class to check for.
|
|
|
389 |
* @return {Boolean} Returns true if class name is present, false otherwise.
|
|
|
390 |
*/
|
|
|
391 |
function hasClass(target, className)
|
|
|
392 |
{
|
|
|
393 |
return target.className.indexOf(className) != -1;
|
|
|
394 |
};
|
|
|
395 |
|
|
|
396 |
/**
|
|
|
397 |
* Adds CSS class name to the target DOM element.
|
|
|
398 |
* @param {DOMElement} target Target DOM element.
|
|
|
399 |
* @param {String} className New CSS class to add.
|
|
|
400 |
*/
|
|
|
401 |
function addClass(target, className)
|
|
|
402 |
{
|
|
|
403 |
if (!hasClass(target, className))
|
|
|
404 |
target.className += ' ' + className;
|
|
|
405 |
};
|
|
|
406 |
|
|
|
407 |
/**
|
|
|
408 |
* Removes CSS class name from the target DOM element.
|
|
|
409 |
* @param {DOMElement} target Target DOM element.
|
|
|
410 |
* @param {String} className CSS class to remove.
|
|
|
411 |
*/
|
|
|
412 |
function removeClass(target, className)
|
|
|
413 |
{
|
|
|
414 |
target.className = target.className.replace(className, '');
|
|
|
415 |
};
|
|
|
416 |
|
|
|
417 |
/**
|
|
|
418 |
* Converts the source to array object. Mostly used for function arguments and
|
|
|
419 |
* lists returned by getElementsByTagName() which aren't Array objects.
|
|
|
420 |
* @param {List} source Source list.
|
|
|
421 |
* @return {Array} Returns array.
|
|
|
422 |
*/
|
|
|
423 |
function toArray(source)
|
|
|
424 |
{
|
|
|
425 |
var result = [];
|
|
|
426 |
|
|
|
427 |
for (var i = 0, l = source.length; i < l; i++)
|
|
|
428 |
result.push(source[i]);
|
|
|
429 |
|
|
|
430 |
return result;
|
|
|
431 |
};
|
|
|
432 |
|
|
|
433 |
/**
|
|
|
434 |
* Splits block of text into lines.
|
|
|
435 |
* @param {String} block Block of text.
|
|
|
436 |
* @return {Array} Returns array of lines.
|
|
|
437 |
*/
|
|
|
438 |
function splitLines(block)
|
|
|
439 |
{
|
|
|
440 |
return block.split(/\r?\n/);
|
|
|
441 |
}
|
|
|
442 |
|
|
|
443 |
/**
|
|
|
444 |
* Generates HTML ID for the highlighter.
|
|
|
445 |
* @param {String} highlighterId Highlighter ID.
|
|
|
446 |
* @return {String} Returns HTML ID.
|
|
|
447 |
*/
|
|
|
448 |
function getHighlighterId(id)
|
|
|
449 |
{
|
|
|
450 |
var prefix = 'highlighter_';
|
|
|
451 |
return id.indexOf(prefix) == 0 ? id : prefix + id;
|
|
|
452 |
};
|
|
|
453 |
|
|
|
454 |
/**
|
|
|
455 |
* Finds Highlighter instance by ID.
|
|
|
456 |
* @param {String} highlighterId Highlighter ID.
|
|
|
457 |
* @return {Highlighter} Returns instance of the highlighter.
|
|
|
458 |
*/
|
|
|
459 |
function getHighlighterById(id)
|
|
|
460 |
{
|
|
|
461 |
return sh.vars.highlighters[getHighlighterId(id)];
|
|
|
462 |
};
|
|
|
463 |
|
|
|
464 |
/**
|
|
|
465 |
* Finds highlighter's DIV container.
|
|
|
466 |
* @param {String} highlighterId Highlighter ID.
|
|
|
467 |
* @return {Element} Returns highlighter's DIV element.
|
|
|
468 |
*/
|
|
|
469 |
function getHighlighterDivById(id)
|
|
|
470 |
{
|
|
|
471 |
return document.getElementById(getHighlighterId(id));
|
|
|
472 |
};
|
|
|
473 |
|
|
|
474 |
/**
|
|
|
475 |
* Stores highlighter so that getHighlighterById() can do its thing. Each
|
|
|
476 |
* highlighter must call this method to preserve itself.
|
|
|
477 |
* @param {Highilghter} highlighter Highlighter instance.
|
|
|
478 |
*/
|
|
|
479 |
function storeHighlighter(highlighter)
|
|
|
480 |
{
|
|
|
481 |
sh.vars.highlighters[getHighlighterId(highlighter.id)] = highlighter;
|
|
|
482 |
};
|
|
|
483 |
|
|
|
484 |
/**
|
|
|
485 |
* Looks for a child or parent node which has specified classname.
|
|
|
486 |
* Equivalent to jQuery's $(container).find(".className")
|
|
|
487 |
* @param {Element} target Target element.
|
|
|
488 |
* @param {String} search Class name or node name to look for.
|
|
|
489 |
* @param {Boolean} reverse If set to true, will go up the node tree instead of down.
|
|
|
490 |
* @return {Element} Returns found child or parent element on null.
|
|
|
491 |
*/
|
|
|
492 |
function findElement(target, search, reverse /* optional */)
|
|
|
493 |
{
|
|
|
494 |
if (target == null)
|
|
|
495 |
return null;
|
|
|
496 |
|
|
|
497 |
var nodes = reverse != true ? target.childNodes : [ target.parentNode ],
|
|
|
498 |
propertyToFind = { '#' : 'id', '.' : 'className' }[search.substr(0, 1)] || 'nodeName',
|
|
|
499 |
expectedValue,
|
|
|
500 |
found
|
|
|
501 |
;
|
|
|
502 |
|
|
|
503 |
expectedValue = propertyToFind != 'nodeName'
|
|
|
504 |
? search.substr(1)
|
|
|
505 |
: search.toUpperCase()
|
|
|
506 |
;
|
|
|
507 |
|
|
|
508 |
// main return of the found node
|
|
|
509 |
if ((target[propertyToFind] || '').indexOf(expectedValue) != -1)
|
|
|
510 |
return target;
|
|
|
511 |
|
|
|
512 |
for (var i = 0, l = nodes.length; nodes && i < l && found == null; i++)
|
|
|
513 |
found = findElement(nodes[i], search, reverse);
|
|
|
514 |
|
|
|
515 |
return found;
|
|
|
516 |
};
|
|
|
517 |
|
|
|
518 |
/**
|
|
|
519 |
* Looks for a parent node which has specified classname.
|
|
|
520 |
* This is an alias to <code>findElement(container, className, true)</code>.
|
|
|
521 |
* @param {Element} target Target element.
|
|
|
522 |
* @param {String} className Class name to look for.
|
|
|
523 |
* @return {Element} Returns found parent element on null.
|
|
|
524 |
*/
|
|
|
525 |
function findParentElement(target, className)
|
|
|
526 |
{
|
|
|
527 |
return findElement(target, className, true);
|
|
|
528 |
};
|
|
|
529 |
|
|
|
530 |
/**
|
|
|
531 |
* Finds an index of element in the array.
|
|
|
532 |
* @ignore
|
|
|
533 |
* @param {Object} searchElement
|
|
|
534 |
* @param {Number} fromIndex
|
|
|
535 |
* @return {Number} Returns index of element if found; -1 otherwise.
|
|
|
536 |
*/
|
|
|
537 |
function indexOf(array, searchElement, fromIndex)
|
|
|
538 |
{
|
|
|
539 |
fromIndex = Math.max(fromIndex || 0, 0);
|
|
|
540 |
|
|
|
541 |
for (var i = fromIndex, l = array.length; i < l; i++)
|
|
|
542 |
if(array[i] == searchElement)
|
|
|
543 |
return i;
|
|
|
544 |
|
|
|
545 |
return -1;
|
|
|
546 |
};
|
|
|
547 |
|
|
|
548 |
/**
|
|
|
549 |
* Generates a unique element ID.
|
|
|
550 |
*/
|
|
|
551 |
function guid(prefix)
|
|
|
552 |
{
|
|
|
553 |
return (prefix || '') + Math.round(Math.random() * 1000000).toString();
|
|
|
554 |
};
|
|
|
555 |
|
|
|
556 |
/**
|
|
|
557 |
* Merges two objects. Values from obj2 override values in obj1.
|
|
|
558 |
* Function is NOT recursive and works only for one dimensional objects.
|
|
|
559 |
* @param {Object} obj1 First object.
|
|
|
560 |
* @param {Object} obj2 Second object.
|
|
|
561 |
* @return {Object} Returns combination of both objects.
|
|
|
562 |
*/
|
|
|
563 |
function merge(obj1, obj2)
|
|
|
564 |
{
|
|
|
565 |
var result = {}, name;
|
|
|
566 |
|
|
|
567 |
for (name in obj1)
|
|
|
568 |
result[name] = obj1[name];
|
|
|
569 |
|
|
|
570 |
for (name in obj2)
|
|
|
571 |
result[name] = obj2[name];
|
|
|
572 |
|
|
|
573 |
return result;
|
|
|
574 |
};
|
|
|
575 |
|
|
|
576 |
/**
|
|
|
577 |
* Attempts to convert string to boolean.
|
|
|
578 |
* @param {String} value Input string.
|
|
|
579 |
* @return {Boolean} Returns true if input was "true", false if input was "false" and value otherwise.
|
|
|
580 |
*/
|
|
|
581 |
function toBoolean(value)
|
|
|
582 |
{
|
|
|
583 |
var result = { "true" : true, "false" : false }[value];
|
|
|
584 |
return result == null ? value : result;
|
|
|
585 |
};
|
|
|
586 |
|
|
|
587 |
/**
|
|
|
588 |
* Opens up a centered popup window.
|
|
|
589 |
* @param {String} url URL to open in the window.
|
|
|
590 |
* @param {String} name Popup name.
|
|
|
591 |
* @param {int} width Popup width.
|
|
|
592 |
* @param {int} height Popup height.
|
|
|
593 |
* @param {String} options window.open() options.
|
|
|
594 |
* @return {Window} Returns window instance.
|
|
|
595 |
*/
|
|
|
596 |
function popup(url, name, width, height, options)
|
|
|
597 |
{
|
|
|
598 |
var x = (screen.width - width) / 2,
|
|
|
599 |
y = (screen.height - height) / 2
|
|
|
600 |
;
|
|
|
601 |
|
|
|
602 |
options += ', left=' + x +
|
|
|
603 |
', top=' + y +
|
|
|
604 |
', width=' + width +
|
|
|
605 |
', height=' + height
|
|
|
606 |
;
|
|
|
607 |
options = options.replace(/^,/, '');
|
|
|
608 |
|
|
|
609 |
var win = window.open(url, name, options);
|
|
|
610 |
win.focus();
|
|
|
611 |
return win;
|
|
|
612 |
};
|
|
|
613 |
|
|
|
614 |
/**
|
|
|
615 |
* Adds event handler to the target object.
|
|
|
616 |
* @param {Object} obj Target object.
|
|
|
617 |
* @param {String} type Name of the event.
|
|
|
618 |
* @param {Function} func Handling function.
|
|
|
619 |
*/
|
|
|
620 |
function attachEvent(obj, type, func, scope)
|
|
|
621 |
{
|
|
|
622 |
function handler(e)
|
|
|
623 |
{
|
|
|
624 |
e = e || window.event;
|
|
|
625 |
|
|
|
626 |
if (!e.target)
|
|
|
627 |
{
|
|
|
628 |
e.target = e.srcElement;
|
|
|
629 |
e.preventDefault = function()
|
|
|
630 |
{
|
|
|
631 |
this.returnValue = false;
|
|
|
632 |
};
|
|
|
633 |
}
|
|
|
634 |
|
|
|
635 |
func.call(scope || window, e);
|
|
|
636 |
};
|
|
|
637 |
|
|
|
638 |
if (obj.attachEvent)
|
|
|
639 |
{
|
|
|
640 |
obj.attachEvent('on' + type, handler);
|
|
|
641 |
}
|
|
|
642 |
else
|
|
|
643 |
{
|
|
|
644 |
obj.addEventListener(type, handler, false);
|
|
|
645 |
}
|
|
|
646 |
};
|
|
|
647 |
|
|
|
648 |
/**
|
|
|
649 |
* Displays an alert.
|
|
|
650 |
* @param {String} str String to display.
|
|
|
651 |
*/
|
|
|
652 |
function alert(str)
|
|
|
653 |
{
|
|
|
654 |
window.alert(sh.config.strings.alert + str);
|
|
|
655 |
};
|
|
|
656 |
|
|
|
657 |
/**
|
|
|
658 |
* Finds a brush by its alias.
|
|
|
659 |
*
|
|
|
660 |
* @param {String} alias Brush alias.
|
|
|
661 |
* @param {Boolean} showAlert Suppresses the alert if false.
|
|
|
662 |
* @return {Brush} Returns bursh constructor if found, null otherwise.
|
|
|
663 |
*/
|
|
|
664 |
function findBrush(alias, showAlert)
|
|
|
665 |
{
|
|
|
666 |
var brushes = sh.vars.discoveredBrushes,
|
|
|
667 |
result = null
|
|
|
668 |
;
|
|
|
669 |
|
|
|
670 |
if (brushes == null)
|
|
|
671 |
{
|
|
|
672 |
brushes = {};
|
|
|
673 |
|
|
|
674 |
// Find all brushes
|
|
|
675 |
for (var brush in sh.brushes)
|
|
|
676 |
{
|
|
|
677 |
var info = sh.brushes[brush],
|
|
|
678 |
aliases = info.aliases
|
|
|
679 |
;
|
|
|
680 |
|
|
|
681 |
if (aliases == null)
|
|
|
682 |
continue;
|
|
|
683 |
|
|
|
684 |
// keep the brush name
|
|
|
685 |
info.brushName = brush.toLowerCase();
|
|
|
686 |
|
|
|
687 |
for (var i = 0, l = aliases.length; i < l; i++)
|
|
|
688 |
brushes[aliases[i]] = brush;
|
|
|
689 |
}
|
|
|
690 |
|
|
|
691 |
sh.vars.discoveredBrushes = brushes;
|
|
|
692 |
}
|
|
|
693 |
|
|
|
694 |
result = sh.brushes[brushes[alias]];
|
|
|
695 |
|
|
|
696 |
if (result == null && showAlert)
|
|
|
697 |
alert(sh.config.strings.noBrush + alias);
|
|
|
698 |
|
|
|
699 |
return result;
|
|
|
700 |
};
|
|
|
701 |
|
|
|
702 |
/**
|
|
|
703 |
* Executes a callback on each line and replaces each line with result from the callback.
|
|
|
704 |
* @param {Object} str Input string.
|
|
|
705 |
* @param {Object} callback Callback function taking one string argument and returning a string.
|
|
|
706 |
*/
|
|
|
707 |
function eachLine(str, callback)
|
|
|
708 |
{
|
|
|
709 |
var lines = splitLines(str);
|
|
|
710 |
|
|
|
711 |
for (var i = 0, l = lines.length; i < l; i++)
|
|
|
712 |
lines[i] = callback(lines[i], i);
|
|
|
713 |
|
|
|
714 |
// include \r to enable copy-paste on windows (ie8) without getting everything on one line
|
|
|
715 |
return lines.join('\r\n');
|
|
|
716 |
};
|
|
|
717 |
|
|
|
718 |
/**
|
|
|
719 |
* This is a special trim which only removes first and last empty lines
|
|
|
720 |
* and doesn't affect valid leading space on the first line.
|
|
|
721 |
*
|
|
|
722 |
* @param {String} str Input string
|
|
|
723 |
* @return {String} Returns string without empty first and last lines.
|
|
|
724 |
*/
|
|
|
725 |
function trimFirstAndLastLines(str)
|
|
|
726 |
{
|
|
|
727 |
return str.replace(/^[ ]*[\n]+|[\n]*[ ]*$/g, '');
|
|
|
728 |
};
|
|
|
729 |
|
|
|
730 |
/**
|
|
|
731 |
* Parses key/value pairs into hash object.
|
|
|
732 |
*
|
|
|
733 |
* Understands the following formats:
|
|
|
734 |
* - name: word;
|
|
|
735 |
* - name: [word, word];
|
|
|
736 |
* - name: "string";
|
|
|
737 |
* - name: 'string';
|
|
|
738 |
*
|
|
|
739 |
* For example:
|
|
|
740 |
* name1: value; name2: [value, value]; name3: 'value'
|
|
|
741 |
*
|
|
|
742 |
* @param {String} str Input string.
|
|
|
743 |
* @return {Object} Returns deserialized object.
|
|
|
744 |
*/
|
|
|
745 |
function parseParams(str)
|
|
|
746 |
{
|
|
|
747 |
var match,
|
|
|
748 |
result = {},
|
|
|
749 |
arrayRegex = XRegExp("^\\[(?<values>(.*?))\\]$"),
|
|
|
750 |
pos = 0,
|
|
|
751 |
regex = XRegExp(
|
|
|
752 |
"(?<name>[\\w-]+)" +
|
|
|
753 |
"\\s*:\\s*" +
|
|
|
754 |
"(?<value>" +
|
|
|
755 |
"[\\w%#-]+|" + // word
|
|
|
756 |
"\\[.*?\\]|" + // [] array
|
|
|
757 |
'".*?"|' + // "" string
|
|
|
758 |
"'.*?'" + // '' string
|
|
|
759 |
")\\s*;?",
|
|
|
760 |
"g"
|
|
|
761 |
)
|
|
|
762 |
;
|
|
|
763 |
|
|
|
764 |
while ((match = XRegExp.exec(str, regex, pos)) != null)
|
|
|
765 |
{
|
|
|
766 |
var value = match.value
|
|
|
767 |
.replace(/^['"]|['"]$/g, '') // strip quotes from end of strings
|
|
|
768 |
;
|
|
|
769 |
|
|
|
770 |
// try to parse array value
|
|
|
771 |
if (value != null && arrayRegex.test(value))
|
|
|
772 |
{
|
|
|
773 |
var m = XRegExp.exec(value, arrayRegex);
|
|
|
774 |
value = m.values.length > 0 ? m.values.split(/\s*,\s*/) : [];
|
|
|
775 |
}
|
|
|
776 |
|
|
|
777 |
result[match.name] = value;
|
|
|
778 |
pos = match.index + match[0].length;
|
|
|
779 |
}
|
|
|
780 |
|
|
|
781 |
// AJJ - markdown style language option
|
|
|
782 |
var a = str.match(/language-(.*)/);
|
|
|
783 |
if ( a ) {
|
|
|
784 |
result['brush'] = a[1];
|
|
|
785 |
}
|
|
|
786 |
else if ( str && str.indexOf('multiline') !== -1 ) {
|
|
|
787 |
// Markdown code block without a language identifier
|
|
|
788 |
result['brush'] = 'text';
|
|
|
789 |
}
|
|
|
790 |
|
|
|
791 |
return result;
|
|
|
792 |
};
|
|
|
793 |
|
|
|
794 |
/**
|
|
|
795 |
* Wraps each line of the string into <code/> tag with given style applied to it.
|
|
|
796 |
*
|
|
|
797 |
* @param {String} str Input string.
|
|
|
798 |
* @param {String} css Style name to apply to the string.
|
|
|
799 |
* @return {String} Returns input string with each line surrounded by <span/> tag.
|
|
|
800 |
*/
|
|
|
801 |
function wrapLinesWithCode(str, css)
|
|
|
802 |
{
|
|
|
803 |
if (str == null || str.length == 0 || str == '\n')
|
|
|
804 |
return str;
|
|
|
805 |
|
|
|
806 |
str = str.replace(/</g, '<');
|
|
|
807 |
|
|
|
808 |
// Replace two or more sequential spaces with leaving last space untouched.
|
|
|
809 |
str = str.replace(/ {2,}/g, function(m)
|
|
|
810 |
{
|
|
|
811 |
var spaces = '';
|
|
|
812 |
|
|
|
813 |
for (var i = 0, l = m.length; i < l - 1; i++)
|
|
|
814 |
spaces += sh.config.space;
|
|
|
815 |
|
|
|
816 |
return spaces + ' ';
|
|
|
817 |
});
|
|
|
818 |
|
|
|
819 |
// Split each line and apply <span class="...">...</span> to them so that
|
|
|
820 |
// leading spaces aren't included.
|
|
|
821 |
if (css != null)
|
|
|
822 |
str = eachLine(str, function(line)
|
|
|
823 |
{
|
|
|
824 |
if (line.length == 0)
|
|
|
825 |
return '';
|
|
|
826 |
|
|
|
827 |
var spaces = '';
|
|
|
828 |
|
|
|
829 |
line = line.replace(/^( | )+/, function(s)
|
|
|
830 |
{
|
|
|
831 |
spaces = s;
|
|
|
832 |
return '';
|
|
|
833 |
});
|
|
|
834 |
|
|
|
835 |
if (line.length == 0)
|
|
|
836 |
return spaces;
|
|
|
837 |
|
|
|
838 |
return spaces + '<code class="' + css + '">' + line + '</code>';
|
|
|
839 |
});
|
|
|
840 |
|
|
|
841 |
return str;
|
|
|
842 |
};
|
|
|
843 |
|
|
|
844 |
/**
|
|
|
845 |
* Pads number with zeros until it's length is the same as given length.
|
|
|
846 |
*
|
|
|
847 |
* @param {Number} number Number to pad.
|
|
|
848 |
* @param {Number} length Max string length with.
|
|
|
849 |
* @return {String} Returns a string padded with proper amount of '0'.
|
|
|
850 |
*/
|
|
|
851 |
function padNumber(number, length)
|
|
|
852 |
{
|
|
|
853 |
var result = number.toString();
|
|
|
854 |
|
|
|
855 |
while (result.length < length)
|
|
|
856 |
result = '0' + result;
|
|
|
857 |
|
|
|
858 |
return result;
|
|
|
859 |
};
|
|
|
860 |
|
|
|
861 |
/**
|
|
|
862 |
* Replaces tabs with spaces.
|
|
|
863 |
*
|
|
|
864 |
* @param {String} code Source code.
|
|
|
865 |
* @param {Number} tabSize Size of the tab.
|
|
|
866 |
* @return {String} Returns code with all tabs replaces by spaces.
|
|
|
867 |
*/
|
|
|
868 |
function processTabs(code, tabSize)
|
|
|
869 |
{
|
|
|
870 |
var tab = '';
|
|
|
871 |
|
|
|
872 |
for (var i = 0; i < tabSize; i++)
|
|
|
873 |
tab += ' ';
|
|
|
874 |
|
|
|
875 |
return code.replace(/\t/g, tab);
|
|
|
876 |
};
|
|
|
877 |
|
|
|
878 |
/**
|
|
|
879 |
* Replaces tabs with smart spaces.
|
|
|
880 |
*
|
|
|
881 |
* @param {String} code Code to fix the tabs in.
|
|
|
882 |
* @param {Number} tabSize Number of spaces in a column.
|
|
|
883 |
* @return {String} Returns code with all tabs replaces with roper amount of spaces.
|
|
|
884 |
*/
|
|
|
885 |
function processSmartTabs(code, tabSize)
|
|
|
886 |
{
|
|
|
887 |
var lines = splitLines(code),
|
|
|
888 |
tab = '\t',
|
|
|
889 |
spaces = ''
|
|
|
890 |
;
|
|
|
891 |
|
|
|
892 |
// Create a string with 1000 spaces to copy spaces from...
|
|
|
893 |
// It's assumed that there would be no indentation longer than that.
|
|
|
894 |
for (var i = 0; i < 50; i++)
|
|
|
895 |
spaces += ' '; // 20 spaces * 50
|
|
|
896 |
|
|
|
897 |
// This function inserts specified amount of spaces in the string
|
|
|
898 |
// where a tab is while removing that given tab.
|
|
|
899 |
function insertSpaces(line, pos, count)
|
|
|
900 |
{
|
|
|
901 |
return line.substr(0, pos)
|
|
|
902 |
+ spaces.substr(0, count)
|
|
|
903 |
+ line.substr(pos + 1, line.length) // pos + 1 will get rid of the tab
|
|
|
904 |
;
|
|
|
905 |
};
|
|
|
906 |
|
|
|
907 |
// Go through all the lines and do the 'smart tabs' magic.
|
|
|
908 |
code = eachLine(code, function(line)
|
|
|
909 |
{
|
|
|
910 |
if (line.indexOf(tab) == -1)
|
|
|
911 |
return line;
|
|
|
912 |
|
|
|
913 |
var pos = 0;
|
|
|
914 |
|
|
|
915 |
while ((pos = line.indexOf(tab)) != -1)
|
|
|
916 |
{
|
|
|
917 |
// This is pretty much all there is to the 'smart tabs' logic.
|
|
|
918 |
// Based on the position within the line and size of a tab,
|
|
|
919 |
// calculate the amount of spaces we need to insert.
|
|
|
920 |
var spaces = tabSize - pos % tabSize;
|
|
|
921 |
line = insertSpaces(line, pos, spaces);
|
|
|
922 |
}
|
|
|
923 |
|
|
|
924 |
return line;
|
|
|
925 |
});
|
|
|
926 |
|
|
|
927 |
return code;
|
|
|
928 |
};
|
|
|
929 |
|
|
|
930 |
/**
|
|
|
931 |
* Performs various string fixes based on configuration.
|
|
|
932 |
*/
|
|
|
933 |
function fixInputString(str)
|
|
|
934 |
{
|
|
|
935 |
var br = /<br\s*\/?>|<br\s*\/?>/gi;
|
|
|
936 |
|
|
|
937 |
if (sh.config.bloggerMode == true)
|
|
|
938 |
str = str.replace(br, '\n');
|
|
|
939 |
|
|
|
940 |
if (sh.config.stripBrs == true)
|
|
|
941 |
str = str.replace(br, '');
|
|
|
942 |
|
|
|
943 |
return str;
|
|
|
944 |
};
|
|
|
945 |
|
|
|
946 |
/**
|
|
|
947 |
* Removes all white space at the begining and end of a string.
|
|
|
948 |
*
|
|
|
949 |
* @param {String} str String to trim.
|
|
|
950 |
* @return {String} Returns string without leading and following white space characters.
|
|
|
951 |
*/
|
|
|
952 |
function trim(str)
|
|
|
953 |
{
|
|
|
954 |
return str.replace(/^\s+|\s+$/g, '');
|
|
|
955 |
};
|
|
|
956 |
|
|
|
957 |
/**
|
|
|
958 |
* Unindents a block of text by the lowest common indent amount.
|
|
|
959 |
* @param {String} str Text to unindent.
|
|
|
960 |
* @return {String} Returns unindented text block.
|
|
|
961 |
*/
|
|
|
962 |
function unindent(str)
|
|
|
963 |
{
|
|
|
964 |
var lines = splitLines(fixInputString(str)),
|
|
|
965 |
indents = new Array(),
|
|
|
966 |
regex = /^\s*/,
|
|
|
967 |
min = 1000
|
|
|
968 |
;
|
|
|
969 |
|
|
|
970 |
// go through every line and check for common number of indents
|
|
|
971 |
for (var i = 0, l = lines.length; i < l && min > 0; i++)
|
|
|
972 |
{
|
|
|
973 |
var line = lines[i];
|
|
|
974 |
|
|
|
975 |
if (trim(line).length == 0)
|
|
|
976 |
continue;
|
|
|
977 |
|
|
|
978 |
var matches = regex.exec(line);
|
|
|
979 |
|
|
|
980 |
// In the event that just one line doesn't have leading white space
|
|
|
981 |
// we can't unindent anything, so bail completely.
|
|
|
982 |
if (matches == null)
|
|
|
983 |
return str;
|
|
|
984 |
|
|
|
985 |
min = Math.min(matches[0].length, min);
|
|
|
986 |
}
|
|
|
987 |
|
|
|
988 |
// trim minimum common number of white space from the begining of every line
|
|
|
989 |
if (min > 0)
|
|
|
990 |
for (var i = 0, l = lines.length; i < l; i++)
|
|
|
991 |
lines[i] = lines[i].substr(min);
|
|
|
992 |
|
|
|
993 |
return lines.join('\n');
|
|
|
994 |
};
|
|
|
995 |
|
|
|
996 |
/**
|
|
|
997 |
* Callback method for Array.sort() which sorts matches by
|
|
|
998 |
* index position and then by length.
|
|
|
999 |
*
|
|
|
1000 |
* @param {Match} m1 Left object.
|
|
|
1001 |
* @param {Match} m2 Right object.
|
|
|
1002 |
* @return {Number} Returns -1, 0 or -1 as a comparison result.
|
|
|
1003 |
*/
|
|
|
1004 |
function matchesSortCallback(m1, m2)
|
|
|
1005 |
{
|
|
|
1006 |
// sort matches by index first
|
|
|
1007 |
if(m1.index < m2.index)
|
|
|
1008 |
return -1;
|
|
|
1009 |
else if(m1.index > m2.index)
|
|
|
1010 |
return 1;
|
|
|
1011 |
else
|
|
|
1012 |
{
|
|
|
1013 |
// if index is the same, sort by length
|
|
|
1014 |
if(m1.length < m2.length)
|
|
|
1015 |
return -1;
|
|
|
1016 |
else if(m1.length > m2.length)
|
|
|
1017 |
return 1;
|
|
|
1018 |
}
|
|
|
1019 |
|
|
|
1020 |
return 0;
|
|
|
1021 |
};
|
|
|
1022 |
|
|
|
1023 |
/**
|
|
|
1024 |
* Executes given regular expression on provided code and returns all
|
|
|
1025 |
* matches that are found.
|
|
|
1026 |
*
|
|
|
1027 |
* @param {String} code Code to execute regular expression on.
|
|
|
1028 |
* @param {Object} regex Regular expression item info from <code>regexList</code> collection.
|
|
|
1029 |
* @return {Array} Returns a list of Match objects.
|
|
|
1030 |
*/
|
|
|
1031 |
function getMatches(code, regexInfo)
|
|
|
1032 |
{
|
|
|
1033 |
function defaultAdd(match, regexInfo)
|
|
|
1034 |
{
|
|
|
1035 |
return match[0];
|
|
|
1036 |
};
|
|
|
1037 |
|
|
|
1038 |
var index = 0,
|
|
|
1039 |
match = null,
|
|
|
1040 |
matches = [],
|
|
|
1041 |
func = regexInfo.func ? regexInfo.func : defaultAdd
|
|
|
1042 |
pos = 0
|
|
|
1043 |
;
|
|
|
1044 |
|
|
|
1045 |
while((match = XRegExp.exec(code, regexInfo.regex, pos)) != null)
|
|
|
1046 |
{
|
|
|
1047 |
var resultMatch = func(match, regexInfo);
|
|
|
1048 |
|
|
|
1049 |
if (typeof(resultMatch) == 'string')
|
|
|
1050 |
resultMatch = [new sh.Match(resultMatch, match.index, regexInfo.css)];
|
|
|
1051 |
|
|
|
1052 |
matches = matches.concat(resultMatch);
|
|
|
1053 |
pos = match.index + match[0].length;
|
|
|
1054 |
}
|
|
|
1055 |
|
|
|
1056 |
return matches;
|
|
|
1057 |
};
|
|
|
1058 |
|
|
|
1059 |
/**
|
|
|
1060 |
* Turns all URLs in the code into <a/> tags.
|
|
|
1061 |
* @param {String} code Input code.
|
|
|
1062 |
* @return {String} Returns code with </a> tags.
|
|
|
1063 |
*/
|
|
|
1064 |
function processUrls(code)
|
|
|
1065 |
{
|
|
|
1066 |
var gt = /(.*)((>|<).*)/;
|
|
|
1067 |
|
|
|
1068 |
return code.replace(sh.regexLib.url, function(m)
|
|
|
1069 |
{
|
|
|
1070 |
var suffix = '',
|
|
|
1071 |
match = null
|
|
|
1072 |
;
|
|
|
1073 |
|
|
|
1074 |
// We include < and > in the URL for the common cases like <http://google.com>
|
|
|
1075 |
// The problem is that they get transformed into <http://google.com>
|
|
|
1076 |
// Where as > easily looks like part of the URL string.
|
|
|
1077 |
|
|
|
1078 |
if (match = gt.exec(m))
|
|
|
1079 |
{
|
|
|
1080 |
m = match[1];
|
|
|
1081 |
suffix = match[2];
|
|
|
1082 |
}
|
|
|
1083 |
|
|
|
1084 |
return '<a href="' + m + '">' + m + '</a>' + suffix;
|
|
|
1085 |
});
|
|
|
1086 |
};
|
|
|
1087 |
|
|
|
1088 |
/**
|
|
|
1089 |
* Finds all <SCRIPT TYPE="syntaxhighlighter" /> elementss.
|
|
|
1090 |
* @return {Array} Returns array of all found SyntaxHighlighter tags.
|
|
|
1091 |
*/
|
|
|
1092 |
function getSyntaxHighlighterScriptTags()
|
|
|
1093 |
{
|
|
|
1094 |
var tags = document.getElementsByTagName('script'),
|
|
|
1095 |
result = []
|
|
|
1096 |
;
|
|
|
1097 |
|
|
|
1098 |
for (var i = 0, l = tags.length; i < l; i++)
|
|
|
1099 |
if (tags[i].type == 'syntaxhighlighter')
|
|
|
1100 |
result.push(tags[i]);
|
|
|
1101 |
|
|
|
1102 |
return result;
|
|
|
1103 |
};
|
|
|
1104 |
|
|
|
1105 |
/**
|
|
|
1106 |
* Strips <![CDATA[]]> from <SCRIPT /> content because it should be used
|
|
|
1107 |
* there in most cases for XHTML compliance.
|
|
|
1108 |
* @param {String} original Input code.
|
|
|
1109 |
* @return {String} Returns code without leading <![CDATA[]]> tags.
|
|
|
1110 |
*/
|
|
|
1111 |
function stripCData(original)
|
|
|
1112 |
{
|
|
|
1113 |
var left = '<![CDATA[',
|
|
|
1114 |
right = ']]>',
|
|
|
1115 |
// for some reason IE inserts some leading blanks here
|
|
|
1116 |
copy = trim(original),
|
|
|
1117 |
changed = false,
|
|
|
1118 |
leftLength = left.length,
|
|
|
1119 |
rightLength = right.length
|
|
|
1120 |
;
|
|
|
1121 |
|
|
|
1122 |
if (copy.indexOf(left) == 0)
|
|
|
1123 |
{
|
|
|
1124 |
copy = copy.substring(leftLength);
|
|
|
1125 |
changed = true;
|
|
|
1126 |
}
|
|
|
1127 |
|
|
|
1128 |
var copyLength = copy.length;
|
|
|
1129 |
|
|
|
1130 |
if (copy.indexOf(right) == copyLength - rightLength)
|
|
|
1131 |
{
|
|
|
1132 |
copy = copy.substring(0, copyLength - rightLength);
|
|
|
1133 |
changed = true;
|
|
|
1134 |
}
|
|
|
1135 |
|
|
|
1136 |
return changed ? copy : original;
|
|
|
1137 |
};
|
|
|
1138 |
|
|
|
1139 |
|
|
|
1140 |
/**
|
|
|
1141 |
* Quick code mouse double click handler.
|
|
|
1142 |
*/
|
|
|
1143 |
function quickCodeHandler(e)
|
|
|
1144 |
{
|
|
|
1145 |
var target = e.target,
|
|
|
1146 |
highlighterDiv = findParentElement(target, '.syntaxhighlighter'),
|
|
|
1147 |
container = findParentElement(target, '.container'),
|
|
|
1148 |
textarea = document.createElement('textarea'),
|
|
|
1149 |
highlighter
|
|
|
1150 |
;
|
|
|
1151 |
|
|
|
1152 |
if (!container || !highlighterDiv || findElement(container, 'textarea'))
|
|
|
1153 |
return;
|
|
|
1154 |
|
|
|
1155 |
highlighter = getHighlighterById(highlighterDiv.id);
|
|
|
1156 |
|
|
|
1157 |
// add source class name
|
|
|
1158 |
addClass(highlighterDiv, 'source');
|
|
|
1159 |
|
|
|
1160 |
// Have to go over each line and grab it's text, can't just do it on the
|
|
|
1161 |
// container because Firefox loses all \n where as Webkit doesn't.
|
|
|
1162 |
var lines = container.childNodes,
|
|
|
1163 |
code = []
|
|
|
1164 |
;
|
|
|
1165 |
|
|
|
1166 |
for (var i = 0, l = lines.length; i < l; i++)
|
|
|
1167 |
code.push(lines[i].innerText || lines[i].textContent);
|
|
|
1168 |
|
|
|
1169 |
// using \r instead of \r or \r\n makes this work equally well on IE, FF and Webkit
|
|
|
1170 |
code = code.join('\r');
|
|
|
1171 |
|
|
|
1172 |
// For Webkit browsers, replace nbsp with a breaking space
|
|
|
1173 |
code = code.replace(/\u00a0/g, " ");
|
|
|
1174 |
|
|
|
1175 |
// inject <textarea/> tag
|
|
|
1176 |
textarea.appendChild(document.createTextNode(code));
|
|
|
1177 |
container.appendChild(textarea);
|
|
|
1178 |
|
|
|
1179 |
// preselect all text
|
|
|
1180 |
textarea.focus();
|
|
|
1181 |
textarea.select();
|
|
|
1182 |
|
|
|
1183 |
// set up handler for lost focus
|
|
|
1184 |
attachEvent(textarea, 'blur', function(e)
|
|
|
1185 |
{
|
|
|
1186 |
textarea.parentNode.removeChild(textarea);
|
|
|
1187 |
removeClass(highlighterDiv, 'source');
|
|
|
1188 |
});
|
|
|
1189 |
};
|
|
|
1190 |
|
|
|
1191 |
/**
|
|
|
1192 |
* Match object.
|
|
|
1193 |
*/
|
|
|
1194 |
sh.Match = function(value, index, css)
|
|
|
1195 |
{
|
|
|
1196 |
this.value = value;
|
|
|
1197 |
this.index = index;
|
|
|
1198 |
this.length = value.length;
|
|
|
1199 |
this.css = css;
|
|
|
1200 |
this.brushName = null;
|
|
|
1201 |
};
|
|
|
1202 |
|
|
|
1203 |
sh.Match.prototype.toString = function()
|
|
|
1204 |
{
|
|
|
1205 |
return this.value;
|
|
|
1206 |
};
|
|
|
1207 |
|
|
|
1208 |
/**
|
|
|
1209 |
* Simulates HTML code with a scripting language embedded.
|
|
|
1210 |
*
|
|
|
1211 |
* @param {String} scriptBrushName Brush name of the scripting language.
|
|
|
1212 |
*/
|
|
|
1213 |
sh.HtmlScript = function(scriptBrushName)
|
|
|
1214 |
{
|
|
|
1215 |
var brushClass = findBrush(scriptBrushName),
|
|
|
1216 |
scriptBrush,
|
|
|
1217 |
xmlBrush = new sh.brushes.Xml(),
|
|
|
1218 |
bracketsRegex = null,
|
|
|
1219 |
ref = this,
|
|
|
1220 |
methodsToExpose = 'getDiv getHtml init'.split(' ')
|
|
|
1221 |
;
|
|
|
1222 |
|
|
|
1223 |
if (brushClass == null)
|
|
|
1224 |
return;
|
|
|
1225 |
|
|
|
1226 |
scriptBrush = new brushClass();
|
|
|
1227 |
|
|
|
1228 |
for(var i = 0, l = methodsToExpose.length; i < l; i++)
|
|
|
1229 |
// make a closure so we don't lose the name after i changes
|
|
|
1230 |
(function() {
|
|
|
1231 |
var name = methodsToExpose[i];
|
|
|
1232 |
|
|
|
1233 |
ref[name] = function()
|
|
|
1234 |
{
|
|
|
1235 |
return xmlBrush[name].apply(xmlBrush, arguments);
|
|
|
1236 |
};
|
|
|
1237 |
})();
|
|
|
1238 |
|
|
|
1239 |
if (scriptBrush.htmlScript == null)
|
|
|
1240 |
{
|
|
|
1241 |
alert(sh.config.strings.brushNotHtmlScript + scriptBrushName);
|
|
|
1242 |
return;
|
|
|
1243 |
}
|
|
|
1244 |
|
|
|
1245 |
xmlBrush.regexList.push(
|
|
|
1246 |
{ regex: scriptBrush.htmlScript.code, func: process }
|
|
|
1247 |
);
|
|
|
1248 |
|
|
|
1249 |
function offsetMatches(matches, offset)
|
|
|
1250 |
{
|
|
|
1251 |
for (var j = 0, l = matches.length; j < l; j++)
|
|
|
1252 |
matches[j].index += offset;
|
|
|
1253 |
}
|
|
|
1254 |
|
|
|
1255 |
function process(match, info)
|
|
|
1256 |
{
|
|
|
1257 |
var code = match.code,
|
|
|
1258 |
matches = [],
|
|
|
1259 |
regexList = scriptBrush.regexList,
|
|
|
1260 |
offset = match.index + match.left.length,
|
|
|
1261 |
htmlScript = scriptBrush.htmlScript,
|
|
|
1262 |
result
|
|
|
1263 |
;
|
|
|
1264 |
|
|
|
1265 |
// add all matches from the code
|
|
|
1266 |
for (var i = 0, l = regexList.length; i < l; i++)
|
|
|
1267 |
{
|
|
|
1268 |
result = getMatches(code, regexList[i]);
|
|
|
1269 |
offsetMatches(result, offset);
|
|
|
1270 |
matches = matches.concat(result);
|
|
|
1271 |
}
|
|
|
1272 |
|
|
|
1273 |
// add left script bracket
|
|
|
1274 |
if (htmlScript.left != null && match.left != null)
|
|
|
1275 |
{
|
|
|
1276 |
result = getMatches(match.left, htmlScript.left);
|
|
|
1277 |
offsetMatches(result, match.index);
|
|
|
1278 |
matches = matches.concat(result);
|
|
|
1279 |
}
|
|
|
1280 |
|
|
|
1281 |
// add right script bracket
|
|
|
1282 |
if (htmlScript.right != null && match.right != null)
|
|
|
1283 |
{
|
|
|
1284 |
result = getMatches(match.right, htmlScript.right);
|
|
|
1285 |
offsetMatches(result, match.index + match[0].lastIndexOf(match.right));
|
|
|
1286 |
matches = matches.concat(result);
|
|
|
1287 |
}
|
|
|
1288 |
|
|
|
1289 |
for (var j = 0, l = matches.length; j < l; j++)
|
|
|
1290 |
matches[j].brushName = brushClass.brushName;
|
|
|
1291 |
|
|
|
1292 |
return matches;
|
|
|
1293 |
}
|
|
|
1294 |
};
|
|
|
1295 |
|
|
|
1296 |
/**
|
|
|
1297 |
* Main Highlither class.
|
|
|
1298 |
* @constructor
|
|
|
1299 |
*/
|
|
|
1300 |
sh.Highlighter = function()
|
|
|
1301 |
{
|
|
|
1302 |
// not putting any code in here because of the prototype inheritance
|
|
|
1303 |
};
|
|
|
1304 |
|
|
|
1305 |
sh.Highlighter.prototype = {
|
|
|
1306 |
/**
|
|
|
1307 |
* Returns value of the parameter passed to the highlighter.
|
|
|
1308 |
* @param {String} name Name of the parameter.
|
|
|
1309 |
* @param {Object} defaultValue Default value.
|
|
|
1310 |
* @return {Object} Returns found value or default value otherwise.
|
|
|
1311 |
*/
|
|
|
1312 |
getParam: function(name, defaultValue)
|
|
|
1313 |
{
|
|
|
1314 |
var result = this.params[name];
|
|
|
1315 |
return toBoolean(result == null ? defaultValue : result);
|
|
|
1316 |
},
|
|
|
1317 |
|
|
|
1318 |
/**
|
|
|
1319 |
* Shortcut to document.createElement().
|
|
|
1320 |
* @param {String} name Name of the element to create (DIV, A, etc).
|
|
|
1321 |
* @return {HTMLElement} Returns new HTML element.
|
|
|
1322 |
*/
|
|
|
1323 |
create: function(name)
|
|
|
1324 |
{
|
|
|
1325 |
return document.createElement(name);
|
|
|
1326 |
},
|
|
|
1327 |
|
|
|
1328 |
/**
|
|
|
1329 |
* Applies all regular expression to the code and stores all found
|
|
|
1330 |
* matches in the `this.matches` array.
|
|
|
1331 |
* @param {Array} regexList List of regular expressions.
|
|
|
1332 |
* @param {String} code Source code.
|
|
|
1333 |
* @return {Array} Returns list of matches.
|
|
|
1334 |
*/
|
|
|
1335 |
findMatches: function(regexList, code)
|
|
|
1336 |
{
|
|
|
1337 |
var result = [];
|
|
|
1338 |
|
|
|
1339 |
if (regexList != null)
|
|
|
1340 |
for (var i = 0, l = regexList.length; i < l; i++)
|
|
|
1341 |
// BUG: length returns len+1 for array if methods added to prototype chain (oising@gmail.com)
|
|
|
1342 |
if (typeof (regexList[i]) == "object")
|
|
|
1343 |
result = result.concat(getMatches(code, regexList[i]));
|
|
|
1344 |
|
|
|
1345 |
// sort and remove nested the matches
|
|
|
1346 |
return this.removeNestedMatches(result.sort(matchesSortCallback));
|
|
|
1347 |
},
|
|
|
1348 |
|
|
|
1349 |
/**
|
|
|
1350 |
* Checks to see if any of the matches are inside of other matches.
|
|
|
1351 |
* This process would get rid of highligted strings inside comments,
|
|
|
1352 |
* keywords inside strings and so on.
|
|
|
1353 |
*/
|
|
|
1354 |
removeNestedMatches: function(matches)
|
|
|
1355 |
{
|
|
|
1356 |
// Optimized by Jose Prado (http://joseprado.com)
|
|
|
1357 |
for (var i = 0, l = matches.length; i < l; i++)
|
|
|
1358 |
{
|
|
|
1359 |
if (matches[i] === null)
|
|
|
1360 |
continue;
|
|
|
1361 |
|
|
|
1362 |
var itemI = matches[i],
|
|
|
1363 |
itemIEndPos = itemI.index + itemI.length
|
|
|
1364 |
;
|
|
|
1365 |
|
|
|
1366 |
for (var j = i + 1, l = matches.length; j < l && matches[i] !== null; j++)
|
|
|
1367 |
{
|
|
|
1368 |
var itemJ = matches[j];
|
|
|
1369 |
|
|
|
1370 |
if (itemJ === null)
|
|
|
1371 |
continue;
|
|
|
1372 |
else if (itemJ.index > itemIEndPos)
|
|
|
1373 |
break;
|
|
|
1374 |
else if (itemJ.index == itemI.index && itemJ.length > itemI.length)
|
|
|
1375 |
matches[i] = null;
|
|
|
1376 |
else if (itemJ.index >= itemI.index && itemJ.index < itemIEndPos)
|
|
|
1377 |
matches[j] = null;
|
|
|
1378 |
}
|
|
|
1379 |
}
|
|
|
1380 |
|
|
|
1381 |
return matches;
|
|
|
1382 |
},
|
|
|
1383 |
|
|
|
1384 |
/**
|
|
|
1385 |
* Creates an array containing integer line numbers starting from the 'first-line' param.
|
|
|
1386 |
* @return {Array} Returns array of integers.
|
|
|
1387 |
*/
|
|
|
1388 |
figureOutLineNumbers: function(code)
|
|
|
1389 |
{
|
|
|
1390 |
var lines = [],
|
|
|
1391 |
firstLine = parseInt(this.getParam('first-line'))
|
|
|
1392 |
;
|
|
|
1393 |
|
|
|
1394 |
eachLine(code, function(line, index)
|
|
|
1395 |
{
|
|
|
1396 |
lines.push(index + firstLine);
|
|
|
1397 |
});
|
|
|
1398 |
|
|
|
1399 |
return lines;
|
|
|
1400 |
},
|
|
|
1401 |
|
|
|
1402 |
/**
|
|
|
1403 |
* Determines if specified line number is in the highlighted list.
|
|
|
1404 |
*/
|
|
|
1405 |
isLineHighlighted: function(lineNumber)
|
|
|
1406 |
{
|
|
|
1407 |
var list = this.getParam('highlight', []);
|
|
|
1408 |
|
|
|
1409 |
if (typeof(list) != 'object' && list.push == null)
|
|
|
1410 |
list = [ list ];
|
|
|
1411 |
|
|
|
1412 |
return indexOf(list, lineNumber.toString()) != -1;
|
|
|
1413 |
},
|
|
|
1414 |
|
|
|
1415 |
/**
|
|
|
1416 |
* Generates HTML markup for a single line of code while determining alternating line style.
|
|
|
1417 |
* @param {Integer} lineNumber Line number.
|
|
|
1418 |
* @param {String} code Line HTML markup.
|
|
|
1419 |
* @return {String} Returns HTML markup.
|
|
|
1420 |
*/
|
|
|
1421 |
getLineHtml: function(lineIndex, lineNumber, code)
|
|
|
1422 |
{
|
|
|
1423 |
var classes = [
|
|
|
1424 |
'line',
|
|
|
1425 |
'number' + lineNumber,
|
|
|
1426 |
'index' + lineIndex,
|
|
|
1427 |
'alt' + (lineNumber % 2 == 0 ? 1 : 2).toString()
|
|
|
1428 |
];
|
|
|
1429 |
|
|
|
1430 |
if (this.isLineHighlighted(lineNumber))
|
|
|
1431 |
classes.push('highlighted');
|
|
|
1432 |
|
|
|
1433 |
if (lineNumber == 0)
|
|
|
1434 |
classes.push('break');
|
|
|
1435 |
|
|
|
1436 |
return '<div class="' + classes.join(' ') + '">' + code + '</div>';
|
|
|
1437 |
},
|
|
|
1438 |
|
|
|
1439 |
/**
|
|
|
1440 |
* Generates HTML markup for line number column.
|
|
|
1441 |
* @param {String} code Complete code HTML markup.
|
|
|
1442 |
* @param {Array} lineNumbers Calculated line numbers.
|
|
|
1443 |
* @return {String} Returns HTML markup.
|
|
|
1444 |
*/
|
|
|
1445 |
getLineNumbersHtml: function(code, lineNumbers)
|
|
|
1446 |
{
|
|
|
1447 |
var html = '',
|
|
|
1448 |
count = splitLines(code).length,
|
|
|
1449 |
firstLine = parseInt(this.getParam('first-line')),
|
|
|
1450 |
pad = this.getParam('pad-line-numbers')
|
|
|
1451 |
;
|
|
|
1452 |
|
|
|
1453 |
if (pad == true)
|
|
|
1454 |
pad = (firstLine + count - 1).toString().length;
|
|
|
1455 |
else if (isNaN(pad) == true)
|
|
|
1456 |
pad = 0;
|
|
|
1457 |
|
|
|
1458 |
for (var i = 0; i < count; i++)
|
|
|
1459 |
{
|
|
|
1460 |
var lineNumber = lineNumbers ? lineNumbers[i] : firstLine + i,
|
|
|
1461 |
code = lineNumber == 0 ? sh.config.space : padNumber(lineNumber, pad)
|
|
|
1462 |
;
|
|
|
1463 |
|
|
|
1464 |
html += this.getLineHtml(i, lineNumber, code);
|
|
|
1465 |
}
|
|
|
1466 |
|
|
|
1467 |
return html;
|
|
|
1468 |
},
|
|
|
1469 |
|
|
|
1470 |
/**
|
|
|
1471 |
* Splits block of text into individual DIV lines.
|
|
|
1472 |
* @param {String} code Code to highlight.
|
|
|
1473 |
* @param {Array} lineNumbers Calculated line numbers.
|
|
|
1474 |
* @return {String} Returns highlighted code in HTML form.
|
|
|
1475 |
*/
|
|
|
1476 |
getCodeLinesHtml: function(html, lineNumbers)
|
|
|
1477 |
{
|
|
|
1478 |
html = trim(html);
|
|
|
1479 |
|
|
|
1480 |
var lines = splitLines(html),
|
|
|
1481 |
padLength = this.getParam('pad-line-numbers'),
|
|
|
1482 |
firstLine = parseInt(this.getParam('first-line')),
|
|
|
1483 |
html = '',
|
|
|
1484 |
brushName = this.getParam('brush')
|
|
|
1485 |
;
|
|
|
1486 |
|
|
|
1487 |
for (var i = 0, l = lines.length; i < l; i++)
|
|
|
1488 |
{
|
|
|
1489 |
var line = lines[i],
|
|
|
1490 |
indent = /^( |\s)+/.exec(line),
|
|
|
1491 |
spaces = null,
|
|
|
1492 |
lineNumber = lineNumbers ? lineNumbers[i] : firstLine + i;
|
|
|
1493 |
;
|
|
|
1494 |
|
|
|
1495 |
if (indent != null)
|
|
|
1496 |
{
|
|
|
1497 |
spaces = indent[0].toString();
|
|
|
1498 |
line = line.substr(spaces.length);
|
|
|
1499 |
spaces = spaces.replace(' ', sh.config.space);
|
|
|
1500 |
}
|
|
|
1501 |
|
|
|
1502 |
line = trim(line);
|
|
|
1503 |
|
|
|
1504 |
if (line.length == 0)
|
|
|
1505 |
line = sh.config.space;
|
|
|
1506 |
|
|
|
1507 |
html += this.getLineHtml(
|
|
|
1508 |
i,
|
|
|
1509 |
lineNumber,
|
|
|
1510 |
(spaces != null ? '<code class="' + brushName + ' spaces">' + spaces + '</code>' : '') + line
|
|
|
1511 |
);
|
|
|
1512 |
}
|
|
|
1513 |
|
|
|
1514 |
return html;
|
|
|
1515 |
},
|
|
|
1516 |
|
|
|
1517 |
/**
|
|
|
1518 |
* Returns HTML for the table title or empty string if title is null.
|
|
|
1519 |
*/
|
|
|
1520 |
getTitleHtml: function(title)
|
|
|
1521 |
{
|
|
|
1522 |
return title ? '<caption>' + title + '</caption>' : '';
|
|
|
1523 |
},
|
|
|
1524 |
|
|
|
1525 |
/**
|
|
|
1526 |
* Finds all matches in the source code.
|
|
|
1527 |
* @param {String} code Source code to process matches in.
|
|
|
1528 |
* @param {Array} matches Discovered regex matches.
|
|
|
1529 |
* @return {String} Returns formatted HTML with processed mathes.
|
|
|
1530 |
*/
|
|
|
1531 |
getMatchesHtml: function(code, matches)
|
|
|
1532 |
{
|
|
|
1533 |
var pos = 0,
|
|
|
1534 |
result = '',
|
|
|
1535 |
brushName = this.getParam('brush', '')
|
|
|
1536 |
;
|
|
|
1537 |
|
|
|
1538 |
function getBrushNameCss(match)
|
|
|
1539 |
{
|
|
|
1540 |
var result = match ? (match.brushName || brushName) : brushName;
|
|
|
1541 |
return result ? result + ' ' : '';
|
|
|
1542 |
};
|
|
|
1543 |
|
|
|
1544 |
// Finally, go through the final list of matches and pull the all
|
|
|
1545 |
// together adding everything in between that isn't a match.
|
|
|
1546 |
for (var i = 0, l = matches.length; i < l; i++)
|
|
|
1547 |
{
|
|
|
1548 |
var match = matches[i],
|
|
|
1549 |
matchBrushName
|
|
|
1550 |
;
|
|
|
1551 |
|
|
|
1552 |
if (match === null || match.length === 0)
|
|
|
1553 |
continue;
|
|
|
1554 |
|
|
|
1555 |
matchBrushName = getBrushNameCss(match);
|
|
|
1556 |
|
|
|
1557 |
result += wrapLinesWithCode(code.substr(pos, match.index - pos), matchBrushName + 'plain')
|
|
|
1558 |
+ wrapLinesWithCode(match.value, matchBrushName + match.css)
|
|
|
1559 |
;
|
|
|
1560 |
|
|
|
1561 |
pos = match.index + match.length + (match.offset || 0);
|
|
|
1562 |
}
|
|
|
1563 |
|
|
|
1564 |
// don't forget to add whatever's remaining in the string
|
|
|
1565 |
result += wrapLinesWithCode(code.substr(pos), getBrushNameCss() + 'plain');
|
|
|
1566 |
|
|
|
1567 |
return result;
|
|
|
1568 |
},
|
|
|
1569 |
|
|
|
1570 |
/**
|
|
|
1571 |
* Generates HTML markup for the whole syntax highlighter.
|
|
|
1572 |
* @param {String} code Source code.
|
|
|
1573 |
* @return {String} Returns HTML markup.
|
|
|
1574 |
*/
|
|
|
1575 |
getHtml: function(code)
|
|
|
1576 |
{
|
|
|
1577 |
var html = '',
|
|
|
1578 |
classes = [ 'syntaxhighlighter' ],
|
|
|
1579 |
tabSize,
|
|
|
1580 |
matches,
|
|
|
1581 |
lineNumbers
|
|
|
1582 |
;
|
|
|
1583 |
|
|
|
1584 |
// process light mode
|
|
|
1585 |
if (this.getParam('light') == true)
|
|
|
1586 |
this.params.toolbar = this.params.gutter = false;
|
|
|
1587 |
|
|
|
1588 |
className = 'syntaxhighlighter';
|
|
|
1589 |
|
|
|
1590 |
if (this.getParam('collapse') == true)
|
|
|
1591 |
classes.push('collapsed');
|
|
|
1592 |
|
|
|
1593 |
if ((gutter = this.getParam('gutter')) == false)
|
|
|
1594 |
classes.push('nogutter');
|
|
|
1595 |
|
|
|
1596 |
// add custom user style name
|
|
|
1597 |
classes.push(this.getParam('class-name'));
|
|
|
1598 |
|
|
|
1599 |
// add brush alias to the class name for custom CSS
|
|
|
1600 |
classes.push(this.getParam('brush'));
|
|
|
1601 |
|
|
|
1602 |
code = trimFirstAndLastLines(code)
|
|
|
1603 |
.replace(/\r/g, ' ') // IE lets these buggers through
|
|
|
1604 |
;
|
|
|
1605 |
|
|
|
1606 |
tabSize = this.getParam('tab-size');
|
|
|
1607 |
|
|
|
1608 |
// replace tabs with spaces
|
|
|
1609 |
code = this.getParam('smart-tabs') == true
|
|
|
1610 |
? processSmartTabs(code, tabSize)
|
|
|
1611 |
: processTabs(code, tabSize)
|
|
|
1612 |
;
|
|
|
1613 |
|
|
|
1614 |
// unindent code by the common indentation
|
|
|
1615 |
if (this.getParam('unindent'))
|
|
|
1616 |
code = unindent(code);
|
|
|
1617 |
|
|
|
1618 |
if (gutter)
|
|
|
1619 |
lineNumbers = this.figureOutLineNumbers(code);
|
|
|
1620 |
|
|
|
1621 |
// find matches in the code using brushes regex list
|
|
|
1622 |
matches = this.findMatches(this.regexList, code);
|
|
|
1623 |
// processes found matches into the html
|
|
|
1624 |
html = this.getMatchesHtml(code, matches);
|
|
|
1625 |
// finally, split all lines so that they wrap well
|
|
|
1626 |
html = this.getCodeLinesHtml(html, lineNumbers);
|
|
|
1627 |
|
|
|
1628 |
// finally, process the links
|
|
|
1629 |
if (this.getParam('auto-links'))
|
|
|
1630 |
html = processUrls(html);
|
|
|
1631 |
|
|
|
1632 |
if (typeof(navigator) != 'undefined' && navigator.userAgent && navigator.userAgent.match(/MSIE/))
|
|
|
1633 |
classes.push('ie');
|
|
|
1634 |
|
|
|
1635 |
html =
|
|
|
1636 |
'<div id="' + getHighlighterId(this.id) + '" class="' + classes.join(' ') + '">'
|
|
|
1637 |
+ (this.getParam('toolbar') ? sh.toolbar.getHtml(this) : '')
|
|
|
1638 |
+ '<table border="0" cellpadding="0" cellspacing="0">'
|
|
|
1639 |
+ this.getTitleHtml(this.getParam('title'))
|
|
|
1640 |
+ '<tbody>'
|
|
|
1641 |
+ '<tr>'
|
|
|
1642 |
+ (gutter ? '<td class="gutter">' + this.getLineNumbersHtml(code) + '</td>' : '')
|
|
|
1643 |
+ '<td class="code">'
|
|
|
1644 |
+ '<div class="container">'
|
|
|
1645 |
+ html
|
|
|
1646 |
+ '</div>'
|
|
|
1647 |
+ '</td>'
|
|
|
1648 |
+ '</tr>'
|
|
|
1649 |
+ '</tbody>'
|
|
|
1650 |
+ '</table>'
|
|
|
1651 |
+ '</div>'
|
|
|
1652 |
;
|
|
|
1653 |
|
|
|
1654 |
return html;
|
|
|
1655 |
},
|
|
|
1656 |
|
|
|
1657 |
/**
|
|
|
1658 |
* Highlights the code and returns complete HTML.
|
|
|
1659 |
* @param {String} code Code to highlight.
|
|
|
1660 |
* @return {Element} Returns container DIV element with all markup.
|
|
|
1661 |
*/
|
|
|
1662 |
getDiv: function(code)
|
|
|
1663 |
{
|
|
|
1664 |
if (code === null)
|
|
|
1665 |
code = '';
|
|
|
1666 |
|
|
|
1667 |
this.code = code;
|
|
|
1668 |
|
|
|
1669 |
var div = this.create('div');
|
|
|
1670 |
|
|
|
1671 |
// create main HTML
|
|
|
1672 |
div.innerHTML = this.getHtml(code);
|
|
|
1673 |
|
|
|
1674 |
// set up click handlers
|
|
|
1675 |
if (this.getParam('toolbar'))
|
|
|
1676 |
attachEvent(findElement(div, '.toolbar'), 'click', sh.toolbar.handler);
|
|
|
1677 |
|
|
|
1678 |
if (this.getParam('quick-code'))
|
|
|
1679 |
attachEvent(findElement(div, '.code'), 'dblclick', quickCodeHandler);
|
|
|
1680 |
|
|
|
1681 |
return div;
|
|
|
1682 |
},
|
|
|
1683 |
|
|
|
1684 |
/**
|
|
|
1685 |
* Initializes the highlighter/brush.
|
|
|
1686 |
*
|
|
|
1687 |
* Constructor isn't used for initialization so that nothing executes during necessary
|
|
|
1688 |
* `new SyntaxHighlighter.Highlighter()` call when setting up brush inheritence.
|
|
|
1689 |
*
|
|
|
1690 |
* @param {Hash} params Highlighter parameters.
|
|
|
1691 |
*/
|
|
|
1692 |
init: function(params)
|
|
|
1693 |
{
|
|
|
1694 |
this.id = guid();
|
|
|
1695 |
|
|
|
1696 |
// register this instance in the highlighters list
|
|
|
1697 |
storeHighlighter(this);
|
|
|
1698 |
|
|
|
1699 |
// local params take precedence over defaults
|
|
|
1700 |
this.params = merge(sh.defaults, params || {})
|
|
|
1701 |
|
|
|
1702 |
// process light mode
|
|
|
1703 |
if (this.getParam('light') == true)
|
|
|
1704 |
this.params.toolbar = this.params.gutter = false;
|
|
|
1705 |
},
|
|
|
1706 |
|
|
|
1707 |
/**
|
|
|
1708 |
* Converts space separated list of keywords into a regular expression string.
|
|
|
1709 |
* @param {String} str Space separated keywords.
|
|
|
1710 |
* @return {String} Returns regular expression string.
|
|
|
1711 |
*/
|
|
|
1712 |
getKeywords: function(str)
|
|
|
1713 |
{
|
|
|
1714 |
str = str
|
|
|
1715 |
.replace(/^\s+|\s+$/g, '')
|
|
|
1716 |
.replace(/\s+/g, '|')
|
|
|
1717 |
;
|
|
|
1718 |
|
|
|
1719 |
return '\\b(?:' + str + ')\\b';
|
|
|
1720 |
},
|
|
|
1721 |
|
|
|
1722 |
/**
|
|
|
1723 |
* Makes a brush compatible with the `html-script` functionality.
|
|
|
1724 |
* @param {Object} regexGroup Object containing `left` and `right` regular expressions.
|
|
|
1725 |
*/
|
|
|
1726 |
forHtmlScript: function(regexGroup)
|
|
|
1727 |
{
|
|
|
1728 |
var regex = { 'end' : regexGroup.right.source };
|
|
|
1729 |
|
|
|
1730 |
if(regexGroup.eof)
|
|
|
1731 |
regex.end = "(?:(?:" + regex.end + ")|$)";
|
|
|
1732 |
|
|
|
1733 |
this.htmlScript = {
|
|
|
1734 |
left : { regex: regexGroup.left, css: 'script' },
|
|
|
1735 |
right : { regex: regexGroup.right, css: 'script' },
|
|
|
1736 |
code : XRegExp(
|
|
|
1737 |
"(?<left>" + regexGroup.left.source + ")" +
|
|
|
1738 |
"(?<code>.*?)" +
|
|
|
1739 |
"(?<right>" + regex.end + ")",
|
|
|
1740 |
"sgi"
|
|
|
1741 |
)
|
|
|
1742 |
};
|
|
|
1743 |
}
|
|
|
1744 |
}; // end of Highlighter
|
|
|
1745 |
|
|
|
1746 |
return sh;
|
|
|
1747 |
}(); // end of anonymous function
|
|
|
1748 |
|
|
|
1749 |
// CommonJS
|
|
|
1750 |
typeof(exports) != 'undefined' ? exports.SyntaxHighlighter = SyntaxHighlighter : null;
|
|
|
1751 |
|
|
|
1752 |
|
|
|
1753 |
|
|
|
1754 |
// JS brush
|
|
|
1755 |
;(function()
|
|
|
1756 |
{
|
|
|
1757 |
// CommonJS
|
|
|
1758 |
SyntaxHighlighter = SyntaxHighlighter || (typeof require !== 'undefined'? require('shCore').SyntaxHighlighter : null);
|
|
|
1759 |
|
|
|
1760 |
function Brush()
|
|
|
1761 |
{
|
|
|
1762 |
var keywords = 'break case catch class continue ' +
|
|
|
1763 |
'default delete do else enum export extends false ' +
|
|
|
1764 |
'for function if implements import in instanceof ' +
|
|
|
1765 |
'interface let new null package private protected ' +
|
|
|
1766 |
'static return super switch ' +
|
|
|
1767 |
'this throw true try typeof var while with yield';
|
|
|
1768 |
|
|
|
1769 |
var r = SyntaxHighlighter.regexLib;
|
|
|
1770 |
|
|
|
1771 |
this.regexList = [
|
|
|
1772 |
{ regex: r.multiLineDoubleQuotedString, css: 'string' }, // double quoted strings
|
|
|
1773 |
{ regex: r.multiLineSingleQuotedString, css: 'string' }, // single quoted strings
|
|
|
1774 |
{ regex: r.singleLineCComments, css: 'comments' }, // one line comments
|
|
|
1775 |
{ regex: r.multiLineCComments, css: 'comments' }, // multiline comments
|
|
|
1776 |
{ regex: /\s*#.*/gm, css: 'preprocessor' }, // preprocessor tags like #region and #endregion
|
|
|
1777 |
{ regex: new RegExp(this.getKeywords(keywords), 'gm'), css: 'keyword' } // keywords
|
|
|
1778 |
];
|
|
|
1779 |
|
|
|
1780 |
this.forHtmlScript(r.scriptScriptTags);
|
|
|
1781 |
this.langLabel = "Javascript";
|
|
|
1782 |
};
|
|
|
1783 |
|
|
|
1784 |
Brush.prototype = new SyntaxHighlighter.Highlighter();
|
|
|
1785 |
Brush.aliases = ['js', 'jscript', 'javascript', 'json'];
|
|
|
1786 |
|
|
|
1787 |
SyntaxHighlighter.brushes.JScript = Brush;
|
|
|
1788 |
|
|
|
1789 |
// CommonJS
|
|
|
1790 |
typeof(exports) != 'undefined' ? exports.Brush = Brush : null;
|
|
|
1791 |
})();
|
|
|
1792 |
|
|
|
1793 |
|
|
|
1794 |
|
|
|
1795 |
// XML / HTML brush
|
|
|
1796 |
;(function()
|
|
|
1797 |
{
|
|
|
1798 |
// CommonJS
|
|
|
1799 |
SyntaxHighlighter = SyntaxHighlighter || (typeof require !== 'undefined'? require('shCore').SyntaxHighlighter : null);
|
|
|
1800 |
|
|
|
1801 |
function Brush()
|
|
|
1802 |
{
|
|
|
1803 |
function process(match, regexInfo)
|
|
|
1804 |
{
|
|
|
1805 |
var constructor = SyntaxHighlighter.Match,
|
|
|
1806 |
code = match[0],
|
|
|
1807 |
tag = XRegExp.exec(code, XRegExp('(<|<)[\\s\\/\\?!]*(?<name>[:\\w-\\.]+)', 'xg')),
|
|
|
1808 |
result = []
|
|
|
1809 |
;
|
|
|
1810 |
|
|
|
1811 |
if (match.attributes != null)
|
|
|
1812 |
{
|
|
|
1813 |
var attributes,
|
|
|
1814 |
pos = 0,
|
|
|
1815 |
regex = XRegExp('(?<name> [\\w:.-]+)' +
|
|
|
1816 |
'\\s*=\\s*' +
|
|
|
1817 |
'(?<value> ".*?"|\'.*?\'|\\w+)',
|
|
|
1818 |
'xg');
|
|
|
1819 |
|
|
|
1820 |
while ((attributes = XRegExp.exec(code, regex, pos)) != null)
|
|
|
1821 |
{
|
|
|
1822 |
result.push(new constructor(attributes.name, match.index + attributes.index, 'color1'));
|
|
|
1823 |
result.push(new constructor(attributes.value, match.index + attributes.index + attributes[0].indexOf(attributes.value), 'string'));
|
|
|
1824 |
pos = attributes.index + attributes[0].length;
|
|
|
1825 |
}
|
|
|
1826 |
}
|
|
|
1827 |
|
|
|
1828 |
if (tag != null)
|
|
|
1829 |
result.push(
|
|
|
1830 |
new constructor(tag.name, match.index + tag[0].indexOf(tag.name), 'keyword')
|
|
|
1831 |
);
|
|
|
1832 |
|
|
|
1833 |
return result;
|
|
|
1834 |
}
|
|
|
1835 |
|
|
|
1836 |
this.regexList = [
|
|
|
1837 |
{ regex: XRegExp('(\\<|<)\\!\\[[\\w\\s]*?\\[(.|\\s)*?\\]\\](\\>|>)', 'gm'), css: 'color2' }, // <![ ... [ ... ]]>
|
|
|
1838 |
{ regex: SyntaxHighlighter.regexLib.xmlComments, css: 'comments' }, // <!-- ... -->
|
|
|
1839 |
{ regex: XRegExp('(<|<)[\\s\\/\\?!]*(\\w+)(?<attributes>.*?)[\\s\\/\\?]*(>|>)', 'sg'), func: process }
|
|
|
1840 |
];
|
|
|
1841 |
this.langLabel = "HTML";
|
|
|
1842 |
};
|
|
|
1843 |
|
|
|
1844 |
Brush.prototype = new SyntaxHighlighter.Highlighter();
|
|
|
1845 |
Brush.aliases = ['xml', 'xhtml', 'xslt', 'html', 'plist'];
|
|
|
1846 |
|
|
|
1847 |
SyntaxHighlighter.brushes.Xml = Brush;
|
|
|
1848 |
|
|
|
1849 |
// CommonJS
|
|
|
1850 |
typeof(exports) != 'undefined' ? exports.Brush = Brush : null;
|
|
|
1851 |
})();
|
|
|
1852 |
|
|
|
1853 |
|
|
|
1854 |
|
|
|
1855 |
// CSS brush
|
|
|
1856 |
;(function()
|
|
|
1857 |
{
|
|
|
1858 |
// CommonJS
|
|
|
1859 |
SyntaxHighlighter = SyntaxHighlighter || (typeof require !== 'undefined'? require('shCore').SyntaxHighlighter : null);
|
|
|
1860 |
|
|
|
1861 |
function Brush()
|
|
|
1862 |
{
|
|
|
1863 |
function getKeywordsCSS(str)
|
|
|
1864 |
{
|
|
|
1865 |
return '\\b([a-z_]|)' + str.replace(/ /g, '(?=:)\\b|\\b([a-z_\\*]|\\*|)') + '(?=:)\\b';
|
|
|
1866 |
};
|
|
|
1867 |
|
|
|
1868 |
function getValuesCSS(str)
|
|
|
1869 |
{
|
|
|
1870 |
return '\\b' + str.replace(/ /g, '(?!-)(?!:)\\b|\\b()') + '\:\\b';
|
|
|
1871 |
};
|
|
|
1872 |
|
|
|
1873 |
var keywords = 'ascent azimuth background-attachment background-color background-image background-position ' +
|
|
|
1874 |
'background-repeat background baseline bbox border-collapse border-color border-spacing border-style border-top ' +
|
|
|
1875 |
'border-right border-bottom border-left border-top-color border-right-color border-bottom-color border-left-color ' +
|
|
|
1876 |
'border-top-style border-right-style border-bottom-style border-left-style border-top-width border-right-width ' +
|
|
|
1877 |
'border-bottom-width border-left-width border-width border bottom cap-height caption-side centerline clear clip color ' +
|
|
|
1878 |
'content counter-increment counter-reset cue-after cue-before cue cursor definition-src descent direction display ' +
|
|
|
1879 |
'elevation empty-cells float font-size-adjust font-family font-size font-stretch font-style font-variant font-weight font ' +
|
|
|
1880 |
'height left letter-spacing line-height list-style-image list-style-position list-style-type list-style margin-top ' +
|
|
|
1881 |
'margin-right margin-bottom margin-left margin marker-offset marks mathline max-height max-width min-height min-width orphans ' +
|
|
|
1882 |
'outline-color outline-style outline-width outline overflow padding-top padding-right padding-bottom padding-left padding page ' +
|
|
|
1883 |
'page-break-after page-break-before page-break-inside pause pause-after pause-before pitch pitch-range play-during position ' +
|
|
|
1884 |
'quotes right richness size slope src speak-header speak-numeral speak-punctuation speak speech-rate stemh stemv stress ' +
|
|
|
1885 |
'table-layout text-align top text-decoration text-indent text-shadow text-transform unicode-bidi unicode-range units-per-em ' +
|
|
|
1886 |
'vertical-align visibility voice-family volume white-space widows width widths word-spacing x-height z-index';
|
|
|
1887 |
|
|
|
1888 |
var values = 'above absolute all always aqua armenian attr aural auto avoid baseline behind below bidi-override black blink block blue bold bolder '+
|
|
|
1889 |
'both bottom braille capitalize caption center center-left center-right circle close-quote code collapse compact condensed '+
|
|
|
1890 |
'continuous counter counters crop cross crosshair cursive dashed decimal decimal-leading-zero default digits disc dotted double '+
|
|
|
1891 |
'embed embossed e-resize expanded extra-condensed extra-expanded fantasy far-left far-right fast faster fixed format fuchsia '+
|
|
|
1892 |
'gray green groove handheld hebrew help hidden hide high higher icon inline-table inline inset inside invert italic '+
|
|
|
1893 |
'justify landscape large larger left-side left leftwards level lighter lime line-through list-item local loud lower-alpha '+
|
|
|
1894 |
'lowercase lower-greek lower-latin lower-roman lower low ltr marker maroon medium message-box middle mix move narrower '+
|
|
|
1895 |
'navy ne-resize no-close-quote none no-open-quote no-repeat normal nowrap n-resize nw-resize oblique olive once open-quote outset '+
|
|
|
1896 |
'outside overline pointer portrait pre print projection purple red relative repeat repeat-x repeat-y rgb ridge right right-side '+
|
|
|
1897 |
'rightwards rtl run-in screen scroll semi-condensed semi-expanded separate se-resize show silent silver slower slow '+
|
|
|
1898 |
'small small-caps small-caption smaller soft solid speech spell-out square s-resize static status-bar sub super sw-resize '+
|
|
|
1899 |
'table-caption table-cell table-column table-column-group table-footer-group table-header-group table-row table-row-group teal '+
|
|
|
1900 |
'text-bottom text-top thick thin top transparent tty tv ultra-condensed ultra-expanded underline upper-alpha uppercase upper-latin '+
|
|
|
1901 |
'upper-roman url visible wait white wider w-resize x-fast x-high x-large x-loud x-low x-slow x-small x-soft xx-large xx-small yellow';
|
|
|
1902 |
|
|
|
1903 |
var fonts = '[mM]onospace [tT]ahoma [vV]erdana [aA]rial [hH]elvetica [sS]ans-serif [sS]erif [cC]ourier mono sans serif';
|
|
|
1904 |
|
|
|
1905 |
this.regexList = [
|
|
|
1906 |
{ regex: SyntaxHighlighter.regexLib.multiLineCComments, css: 'comments' }, // multiline comments
|
|
|
1907 |
{ regex: SyntaxHighlighter.regexLib.doubleQuotedString, css: 'string' }, // double quoted strings
|
|
|
1908 |
{ regex: SyntaxHighlighter.regexLib.singleQuotedString, css: 'string' }, // single quoted strings
|
|
|
1909 |
{ regex: /\#[a-fA-F0-9]{3,6}/g, css: 'value' }, // html colors
|
|
|
1910 |
{ regex: /(-?\d+)(\.\d+)?(px|em|pt|\:|\%|)/g, css: 'value' }, // sizes
|
|
|
1911 |
{ regex: /!important/g, css: 'color3' }, // !important
|
|
|
1912 |
{ regex: new RegExp(getKeywordsCSS(keywords), 'gm'), css: 'keyword' }, // keywords
|
|
|
1913 |
{ regex: new RegExp(getValuesCSS(values), 'g'), css: 'value' }, // values
|
|
|
1914 |
{ regex: new RegExp(this.getKeywords(fonts), 'g'), css: 'color1' } // fonts
|
|
|
1915 |
];
|
|
|
1916 |
|
|
|
1917 |
this.forHtmlScript({
|
|
|
1918 |
left: /(<|<)\s*style.*?(>|>)/gi,
|
|
|
1919 |
right: /(<|<)\/\s*style\s*(>|>)/gi
|
|
|
1920 |
});
|
|
|
1921 |
this.langLabel = "CSS";
|
|
|
1922 |
};
|
|
|
1923 |
|
|
|
1924 |
Brush.prototype = new SyntaxHighlighter.Highlighter();
|
|
|
1925 |
Brush.aliases = ['css'];
|
|
|
1926 |
|
|
|
1927 |
SyntaxHighlighter.brushes.CSS = Brush;
|
|
|
1928 |
|
|
|
1929 |
// CommonJS
|
|
|
1930 |
typeof(exports) != 'undefined' ? exports.Brush = Brush : null;
|
|
|
1931 |
})();
|
|
|
1932 |
|
|
|
1933 |
|
|
|
1934 |
|
|
|
1935 |
// PHP brush
|
|
|
1936 |
;(function()
|
|
|
1937 |
{
|
|
|
1938 |
// CommonJS
|
|
|
1939 |
SyntaxHighlighter = SyntaxHighlighter || (typeof require !== 'undefined'? require('shCore').SyntaxHighlighter : null);
|
|
|
1940 |
|
|
|
1941 |
function Brush()
|
|
|
1942 |
{
|
|
|
1943 |
var funcs = 'abs acos acosh addcslashes addslashes ' +
|
|
|
1944 |
'array_change_key_case array_chunk array_combine array_count_values array_diff '+
|
|
|
1945 |
'array_diff_assoc array_diff_key array_diff_uassoc array_diff_ukey array_fill '+
|
|
|
1946 |
'array_filter array_flip array_intersect array_intersect_assoc array_intersect_key '+
|
|
|
1947 |
'array_intersect_uassoc array_intersect_ukey array_key_exists array_keys array_map '+
|
|
|
1948 |
'array_merge array_merge_recursive array_multisort array_pad array_pop array_product '+
|
|
|
1949 |
'array_push array_rand array_reduce array_reverse array_search array_shift '+
|
|
|
1950 |
'array_slice array_splice array_sum array_udiff array_udiff_assoc '+
|
|
|
1951 |
'array_udiff_uassoc array_uintersect array_uintersect_assoc '+
|
|
|
1952 |
'array_uintersect_uassoc array_unique array_unshift array_values array_walk '+
|
|
|
1953 |
'array_walk_recursive atan atan2 atanh base64_decode base64_encode base_convert '+
|
|
|
1954 |
'basename bcadd bccomp bcdiv bcmod bcmul bindec bindtextdomain bzclose bzcompress '+
|
|
|
1955 |
'bzdecompress bzerrno bzerror bzerrstr bzflush bzopen bzread bzwrite ceil chdir '+
|
|
|
1956 |
'checkdate checkdnsrr chgrp chmod chop chown chr chroot chunk_split class_exists '+
|
|
|
1957 |
'closedir closelog copy cos cosh count count_chars date decbin dechex decoct '+
|
|
|
1958 |
'deg2rad delete ebcdic2ascii echo empty end ereg ereg_replace eregi eregi_replace error_log '+
|
|
|
1959 |
'error_reporting escapeshellarg escapeshellcmd eval exec exit exp explode extension_loaded '+
|
|
|
1960 |
'feof fflush fgetc fgetcsv fgets fgetss file_exists file_get_contents file_put_contents '+
|
|
|
1961 |
'fileatime filectime filegroup fileinode filemtime fileowner fileperms filesize filetype '+
|
|
|
1962 |
'floatval flock floor flush fmod fnmatch fopen fpassthru fprintf fputcsv fputs fread fscanf '+
|
|
|
1963 |
'fseek fsockopen fstat ftell ftok getallheaders getcwd getdate getenv gethostbyaddr gethostbyname '+
|
|
|
1964 |
'gethostbynamel getimagesize getlastmod getmxrr getmygid getmyinode getmypid getmyuid getopt '+
|
|
|
1965 |
'getprotobyname getprotobynumber getrandmax getrusage getservbyname getservbyport gettext '+
|
|
|
1966 |
'gettimeofday gettype glob gmdate gmmktime ini_alter ini_get ini_get_all ini_restore ini_set '+
|
|
|
1967 |
'interface_exists intval ip2long is_a is_array is_bool is_callable is_dir is_double '+
|
|
|
1968 |
'is_executable is_file is_finite is_float is_infinite is_int is_integer is_link is_long '+
|
|
|
1969 |
'is_nan is_null is_numeric is_object is_readable is_real is_resource is_scalar is_soap_fault '+
|
|
|
1970 |
'is_string is_subclass_of is_uploaded_file is_writable is_writeable mkdir mktime nl2br '+
|
|
|
1971 |
'parse_ini_file parse_str parse_url passthru pathinfo print readlink realpath rewind rewinddir rmdir '+
|
|
|
1972 |
'round str_ireplace str_pad str_repeat str_replace str_rot13 str_shuffle str_split '+
|
|
|
1973 |
'str_word_count strcasecmp strchr strcmp strcoll strcspn strftime strip_tags stripcslashes '+
|
|
|
1974 |
'stripos stripslashes stristr strlen strnatcasecmp strnatcmp strncasecmp strncmp strpbrk '+
|
|
|
1975 |
'strpos strptime strrchr strrev strripos strrpos strspn strstr strtok strtolower strtotime '+
|
|
|
1976 |
'strtoupper strtr strval substr substr_compare';
|
|
|
1977 |
|
|
|
1978 |
var keywords = 'abstract and array as break case catch cfunction class clone const continue declare default die do ' +
|
|
|
1979 |
'else elseif enddeclare endfor endforeach endif endswitch endwhile extends final finally for foreach ' +
|
|
|
1980 |
'function global goto if implements include include_once interface instanceof insteadof namespace new ' +
|
|
|
1981 |
'old_function or private protected public return require require_once static switch ' +
|
|
|
1982 |
'trait throw try use var while xor yield ';
|
|
|
1983 |
|
|
|
1984 |
var constants = '__FILE__ __LINE__ __METHOD__ __FUNCTION__ __CLASS__';
|
|
|
1985 |
|
|
|
1986 |
this.regexList = [
|
|
|
1987 |
{ regex: SyntaxHighlighter.regexLib.singleLineCComments, css: 'comments' }, // one line comments
|
|
|
1988 |
{ regex: SyntaxHighlighter.regexLib.multiLineCComments, css: 'comments' }, // multiline comments
|
|
|
1989 |
{ regex: SyntaxHighlighter.regexLib.doubleQuotedString, css: 'string' }, // double quoted strings
|
|
|
1990 |
{ regex: SyntaxHighlighter.regexLib.singleQuotedString, css: 'string' }, // single quoted strings
|
|
|
1991 |
{ regex: /\$\w+/g, css: 'variable' }, // variables
|
|
|
1992 |
{ regex: new RegExp(this.getKeywords(funcs), 'gmi'), css: 'functions' }, // common functions
|
|
|
1993 |
{ regex: new RegExp(this.getKeywords(constants), 'gmi'), css: 'constants' }, // constants
|
|
|
1994 |
{ regex: new RegExp(this.getKeywords(keywords), 'gm'), css: 'keyword' } // keyword
|
|
|
1995 |
];
|
|
|
1996 |
|
|
|
1997 |
this.forHtmlScript(SyntaxHighlighter.regexLib.phpScriptTags);
|
|
|
1998 |
this.langLabel = "PHP";
|
|
|
1999 |
};
|
|
|
2000 |
|
|
|
2001 |
Brush.prototype = new SyntaxHighlighter.Highlighter();
|
|
|
2002 |
Brush.aliases = ['php'];
|
|
|
2003 |
|
|
|
2004 |
SyntaxHighlighter.brushes.Php = Brush;
|
|
|
2005 |
|
|
|
2006 |
// CommonJS
|
|
|
2007 |
typeof(exports) != 'undefined' ? exports.Brush = Brush : null;
|
|
|
2008 |
})();
|
|
|
2009 |
|
|
|
2010 |
|
|
|
2011 |
;(function()
|
|
|
2012 |
{
|
|
|
2013 |
// CommonJS
|
|
|
2014 |
SyntaxHighlighter = SyntaxHighlighter || (typeof require !== 'undefined'? require('shCore').SyntaxHighlighter : null);
|
|
|
2015 |
|
|
|
2016 |
function Brush()
|
|
|
2017 |
{
|
|
|
2018 |
var funcs = 'abs avg case cast coalesce convert count current_timestamp ' +
|
|
|
2019 |
'current_user day isnull left lower month nullif replace right ' +
|
|
|
2020 |
'session_user space substring sum system_user upper user year';
|
|
|
2021 |
|
|
|
2022 |
var keywords = 'absolute action add after alter as asc at authorization begin bigint ' +
|
|
|
2023 |
'binary bit by cascade char character check checkpoint close collate ' +
|
|
|
2024 |
'column commit committed connect connection constraint contains continue ' +
|
|
|
2025 |
'create cube current current_date current_time cursor database date ' +
|
|
|
2026 |
'deallocate dec decimal declare default delete desc distinct double drop ' +
|
|
|
2027 |
'dynamic else end end-exec escape except exec execute false fetch first ' +
|
|
|
2028 |
'float for force foreign forward free from full function global goto grant ' +
|
|
|
2029 |
'group grouping having hour ignore index inner insensitive insert instead ' +
|
|
|
2030 |
'int integer intersect into is isolation key last level load local max min ' +
|
|
|
2031 |
'minute modify move name national nchar next no numeric of off on only ' +
|
|
|
2032 |
'open option order out output partial password precision prepare primary ' +
|
|
|
2033 |
'prior privileges procedure public read real references relative repeatable ' +
|
|
|
2034 |
'restrict return returns revoke rollback rollup rows rule schema scroll ' +
|
|
|
2035 |
'second section select sequence serializable set size smallint static ' +
|
|
|
2036 |
'statistics table temp temporary then time timestamp to top transaction ' +
|
|
|
2037 |
'translation trigger true truncate uncommitted union unique update values ' +
|
|
|
2038 |
'varchar varying view when where with work';
|
|
|
2039 |
|
|
|
2040 |
var operators = 'all and any between cross in join like not null or outer some';
|
|
|
2041 |
|
|
|
2042 |
this.regexList = [
|
|
|
2043 |
{ regex: /--(.*)$/gm, css: 'comments' }, // one line comments
|
|
|
2044 |
{ regex: /\/\*([^\*][\s\S]*?)?\*\//gm, css: 'comments' }, // multi line comments
|
|
|
2045 |
{ regex: SyntaxHighlighter.regexLib.multiLineDoubleQuotedString, css: 'string' }, // double quoted strings
|
|
|
2046 |
{ regex: SyntaxHighlighter.regexLib.multiLineSingleQuotedString, css: 'string' }, // single quoted strings
|
|
|
2047 |
{ regex: new RegExp(this.getKeywords(funcs), 'gmi'), css: 'color2' }, // functions
|
|
|
2048 |
{ regex: new RegExp(this.getKeywords(operators), 'gmi'), css: 'color1' }, // operators and such
|
|
|
2049 |
{ regex: new RegExp(this.getKeywords(keywords), 'gmi'), css: 'keyword' } // keyword
|
|
|
2050 |
];
|
|
|
2051 |
|
|
|
2052 |
this.langLabel = "SQL";
|
|
|
2053 |
};
|
|
|
2054 |
|
|
|
2055 |
Brush.prototype = new SyntaxHighlighter.Highlighter();
|
|
|
2056 |
Brush.aliases = ['sql'];
|
|
|
2057 |
|
|
|
2058 |
SyntaxHighlighter.brushes.Sql = Brush;
|
|
|
2059 |
|
|
|
2060 |
// CommonJS
|
|
|
2061 |
typeof(exports) != 'undefined' ? exports.Brush = Brush : null;
|
|
|
2062 |
})();
|
|
|
2063 |
|
|
|
2064 |
|
|
|
2065 |
|
|
|
2066 |
;(function()
|
|
|
2067 |
{
|
|
|
2068 |
// CommonJS
|
|
|
2069 |
SyntaxHighlighter = SyntaxHighlighter || (typeof require !== 'undefined'? require('shCore').SyntaxHighlighter : null);
|
|
|
2070 |
|
|
|
2071 |
function Brush()
|
|
|
2072 |
{
|
|
|
2073 |
this.langLabel = "Plain text";
|
|
|
2074 |
};
|
|
|
2075 |
|
|
|
2076 |
Brush.prototype = new SyntaxHighlighter.Highlighter();
|
|
|
2077 |
Brush.aliases = ['text', 'plain'];
|
|
|
2078 |
|
|
|
2079 |
SyntaxHighlighter.brushes.Plain = Brush;
|
|
|
2080 |
|
|
|
2081 |
// CommonJS
|
|
|
2082 |
typeof(exports) != 'undefined' ? exports.Brush = Brush : null;
|
|
|
2083 |
})();
|
|
|
2084 |
|
|
|
2085 |
;(function()
|
|
|
2086 |
{
|
|
|
2087 |
// CommonJS
|
|
|
2088 |
SyntaxHighlighter = SyntaxHighlighter || (typeof require !== 'undefined'? require('shCore').SyntaxHighlighter : null);
|
|
|
2089 |
|
|
|
2090 |
function Brush()
|
|
|
2091 |
{
|
|
|
2092 |
var keywords = 'abstract as async await base bool break byte case catch char checked class const ' +
|
|
|
2093 |
'continue decimal default delegate do double else enum event explicit volatile ' +
|
|
|
2094 |
'extern false finally fixed float for foreach get goto if implicit in int ' +
|
|
|
2095 |
'interface internal is lock long namespace new null object operator out ' +
|
|
|
2096 |
'override params private protected public readonly ref return sbyte sealed set ' +
|
|
|
2097 |
'short sizeof stackalloc static string struct switch this throw true try ' +
|
|
|
2098 |
'typeof uint ulong unchecked unsafe ushort using virtual void while var ' +
|
|
|
2099 |
'from group by into select let where orderby join on equals ascending descending';
|
|
|
2100 |
|
|
|
2101 |
function fixComments(match, regexInfo)
|
|
|
2102 |
{
|
|
|
2103 |
var css = (match[0].indexOf("///") == 0)
|
|
|
2104 |
? 'color1'
|
|
|
2105 |
: 'comments'
|
|
|
2106 |
;
|
|
|
2107 |
|
|
|
2108 |
return [new SyntaxHighlighter.Match(match[0], match.index, css)];
|
|
|
2109 |
}
|
|
|
2110 |
|
|
|
2111 |
this.regexList = [
|
|
|
2112 |
{ regex: SyntaxHighlighter.regexLib.singleLineCComments, func : fixComments }, // one line comments
|
|
|
2113 |
{ regex: SyntaxHighlighter.regexLib.multiLineCComments, css: 'comments' }, // multiline comments
|
|
|
2114 |
{ regex: /@"(?:[^"]|"")*"/g, css: 'string' }, // @-quoted strings
|
|
|
2115 |
{ regex: SyntaxHighlighter.regexLib.doubleQuotedString, css: 'string' }, // strings
|
|
|
2116 |
{ regex: SyntaxHighlighter.regexLib.singleQuotedString, css: 'string' }, // strings
|
|
|
2117 |
{ regex: /^\s*#.*/gm, css: 'preprocessor' }, // preprocessor tags like #region and #endregion
|
|
|
2118 |
{ regex: new RegExp(this.getKeywords(keywords), 'gm'), css: 'keyword' }, // c# keyword
|
|
|
2119 |
{ regex: /\bpartial(?=\s+(?:class|interface|struct)\b)/g, css: 'keyword' }, // contextual keyword: 'partial'
|
|
|
2120 |
{ regex: /\byield(?=\s+(?:return|break)\b)/g, css: 'keyword' } // contextual keyword: 'yield'
|
|
|
2121 |
];
|
|
|
2122 |
|
|
|
2123 |
this.forHtmlScript(SyntaxHighlighter.regexLib.aspScriptTags);
|
|
|
2124 |
this.langLabel = "C#";
|
|
|
2125 |
};
|
|
|
2126 |
|
|
|
2127 |
Brush.prototype = new SyntaxHighlighter.Highlighter();
|
|
|
2128 |
Brush.aliases = ['c#', 'cs', 'c-sharp', 'csharp'];
|
|
|
2129 |
|
|
|
2130 |
SyntaxHighlighter.brushes.CSharp = Brush;
|
|
|
2131 |
|
|
|
2132 |
// CommonJS
|
|
|
2133 |
typeof(exports) != 'undefined' ? exports.Brush = Brush : null;
|
|
|
2134 |
})();
|
|
|
2135 |
|
|
|
2136 |
|
|
|
2137 |
SyntaxHighlighter.all();
|