Wikipedia:WikiProject User scripts/Scripts/Syntax highlighter

Syntax highlighter

This meta-script highlights anything that looks like css code inside pre tags by giving a class to each bit.

A syntax highlighter is built into the site now, displaying on .js and .css pages. Deprecate this? — Omegatron 01:43, 4 April 2008 (UTC)[reply]

Makes it much easier to read. Use your monobook.css to format your monobook.css.  :-)

It's not perfect, and could be extended to do javascript, too. Please fix it and make it better. (I've done a first example for this. -- Olliminatore)

Sort of by User:Omegatron, but heavily based on Simon Willison's script. Other related projects? [1] dp.SyntaxHighlighter has some regexps for javascript highlighting.

Javascript

Add this to your user javascript.

 
/* Syntax highlighter */

 if(document.title.indexOf(".js") == -1)     //   Ignore pages that end in .js
  addOnloadHook(function () {
  /* CSS syntax highlighting */
     multicommentRE = new RegExp('(/\\*[\\s\\S]*?\\*/)', 'g');
     ruleRE = new RegExp('([^\\{]+)\\{([^\\}]+)\\}', 'g');
     idselectorRE = new RegExp('(#[a-zA-Z0-9\-\_]+)\\b', 'g');
     classselectorRE = new RegExp('(\\.[a-zA-Z0-9\-\_]+)\\b', 'g');
     pairRE = new RegExp('([a-zA-Z-]+):([^;]+);', 'g');
     css = document.getElementsByTagName('pre');
     for (i = 0; i < css.length; i++) {
       c = css[i];
       content = c.innerHTML;
       content=content.replace(multicommentRE, '<span class="comment">$1</span>');
       content = content.replace(ruleRE, function(text, selector, body) {
         selector = selector.replace(idselectorRE, '<span class="idselector">$1</span>');
         selector = selector.replace(classselectorRE, '<span class="classselector">$1</span>');
         body = body.replace(pairRE, '<span class="property">$1</span>:<span class="value">$2</span>;');
         return selector + '{' + body + '}';
       });
       c.innerHTML = content;
     }
  });

For additional JavaScript-Code (with optional gutter for line-numbers):

 else { /* JS syntax highlighting */

//

 /** 
 * Code Syntax Highlighter.
 * Version 1.3.0
 * Copyright (C) 2004 Alex Gorbatchev.
 * http://www.dreamprojections.com/syntaxhighlighter/
 * 
 * This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General 
 * Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) 
 * any later version.
 *
 * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied 
 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 
 * details.
 *
 * You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to 
 * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 
 */

var dp={sh:{Brushes:{},Version:'1.3.0'}};dp.SyntaxHighlighter=dp.sh;dp.sh.Match=function(value,index,css){this.value=value;this.index=index,this.length=value.length,this.css=css};dp.sh.Highlighter=function(){this.addGutter=true,this.collapse=false,this.tabsToSpaces=true};dp.sh.Highlighter.SortCallback=function(m1,m2){if(m1.index<m2.index)return -1;else if(m1.index>m2.index)return 1;else{if(m1.length<m2.length)return -1;else if(m1.length>m2.length)return 1};return 0};dp.sh.Highlighter.prototype.GetMatches=function(regex,css){var index=0;var match=null;while((match=regex.exec(this.code))!=null){this.matches[this.matches.length]=new dp.sh.Match(match[0],match.index,css)}};dp.sh.Highlighter.prototype.AddBit=
function(str,css){
var span=document.createElement('span');
str=str.replace(/&/g,'\&');
str=str.replace(/\&/g,'&');
str=str.replace(/\"/g,'"');
str=str.replace(/ |\t/g,' ').replace(/\n/gm,' <br />');
if(css!=null){var regex=new RegExp('<br />','gi');if(regex.test(str)){var lines=str.split(' <br />');str='';for(var i=0;i<lines.length;i++){span=document.createElement('SPAN');span.className=css;span.innerHTML=lines[i];this.div.appendChild(span);if(i+1<lines.length)this.div.appendChild(document.createElement('BR'))}}else{span.className=css,span.innerHTML=str;this.div.appendChild(span)}}else{span.innerHTML=str;this.div.appendChild(span)}};dp.sh.Highlighter.prototype.IsInside=function(match){if(match==null||match.length==0)return;for(var i=0;i<this.matches.length;i++){var c=this.matches[i];if(c==null)continue;if((match.index>c.index)&&(match.index<=c.index+c.length))return true}return false};dp.sh.Highlighter.prototype.ProcessRegexList=function(){for(var i=0;i<this.regexList.length;i++)this.GetMatches(this.regexList[i].regex,this.regexList[i].css)};dp.sh.Highlighter.prototype.ProcessSmartTabs=function(code){var lines=code.split('\n');var result='';var tabSize=4;var tab='\t';function InsertSpaces(line,pos,count){var left=line.substr(0,pos);var right=line.substr(pos+1,line.length);var spaces='';for(var i=0;i<count;i++)spaces+=' ';return left+spaces+right};function ProcessLine(line,tabSize){if(line.indexOf(tab)==-1)return line;var pos=0;while((pos=line.indexOf(tab))!=-1){var spaces=tabSize-pos % tabSize;line=InsertSpaces(line,pos,spaces)}return line};for(var i=0;i<lines.length;i++)result+=ProcessLine(lines[i],tabSize)+'\n';return result};dp.sh.Highlighter.prototype.SwitchToTable=function(){var html=this.div.innerHTML.replace(/<(br)\/?>/gi,'\n');var lines=html.split('\n');var row=null;var cell=null;var tBody=null;var html='';var pipe=' | ';tBody=document.createElement('TBODY');this.table.appendChild(tBody);if(this.addGutter==true){row=tBody.insertRow(-1);cell=row.insertCell(-1)}for(var i=0,lineIndex=this.firstLine;i<lines.length-1;i++,lineIndex++){row=tBody.insertRow(-1);if(this.addGutter==true){cell=row.insertCell(-1);cell.className='gutter';cell.innerHTML=lineIndex};cell=row.insertCell(-1);cell.className='line'+(i % 2+1);cell.innerHTML=lines[i]};this.div.innerHTML=''};dp.sh.Highlighter.prototype.Highlight=function(code){function Trim(str){return str.replace(/^\s*(.*?)[\s\n]*$/g,'$1')};function Chop(str){return str.replace(/\n*$/,'').replace(/^\n*/,'')};function Unindent(str){var lines=str.split('\n');var indents=new Array();var regex=new RegExp('^\\s*','g');var min=1000;for(var i=0;i<lines.length&&min>0;i++){if(Trim(lines[i]).length==0)continue;var matches=regex.exec(lines[i]);if(matches!=null&&matches.length>0)min=Math.min(matches[0].length,min)};if(min>0)for(var i=0;i<lines.length;i++)lines[i]=lines[i].substr(min);return lines.join('\n')};function Copy(string,pos1,pos2){return string.substr(pos1,pos2-pos1)};var pos=0;this.originalCode=code;this.code=Chop(Unindent(code));this.div=document.createElement('DIV');this.table=document.createElement('TABLE');this.matches=new Array();if(this.CssClass!=null)this.table.className=this.CssClass;if(this.tabsToSpaces==true)this.code=this.ProcessSmartTabs(this.code);this.table.border=0;this.table.cellSpacing=0;this.table.cellPadding=0;this.ProcessRegexList();if(this.matches.length==0){this.AddBit(this.code,null);this.SwitchToTable();return};this.matches=this.matches.sort(dp.sh.Highlighter.SortCallback);for(var i=0;i<this.matches.length;i++)if(this.IsInside(this.matches[i]))this.matches[i]=null;for(var i=0;i<this.matches.length;i++){var match=this.matches[i];if(match==null||match.length==0)continue;this.AddBit(Copy(this.code,pos,match.index),null);this.AddBit(match.value,match.css);pos=match.index+match.length};this.AddBit(this.code.substr(pos),null);this.SwitchToTable()};dp.sh.Highlighter.prototype.GetKeyw=function(str){return '\\b'+str.replace(/ /g,'\\b|\\b')+'\\b'};dp.sh.HighlightAll=function(event,showGutter,firstLine){var elements=document.getElementsByTagName('PRE');var highlighter=null;var registered=new Object();if(elements==null)return;for(var i=0;i<elements.length;i++){var element=elements[i];highlighter=new dp.sh.Brushes['JScript']();highlighter.addGutter=(showGutter==null)?true:showGutter;highlighter.firstLine=(firstLine==null)?0:firstLine;highlighter.Highlight(element['innerHTML']);element.innerHTML="";element.className='dp-highlighter';element.appendChild(highlighter.table)}};

dp.sh.Brushes.JScript = function(){
  var keywords =  'abstract boolean break byte case catch char class const continue debugger ' +
          'default delete do double else enum export extends false final finally float ' +
          'for function goto if implements import in instanceof int interface long native ' +
          'new null package private protected public return short static super switch ' +
          'synchronized this throw throws transient true try typeof var void volatile while with';
  this.regexList = [
  {regex: new RegExp('//.*$', 'gm'),            css: 'comment' },    // one line comments
  {regex: new RegExp('/\\*[\\s\\S]*?\\*/', 'g'),css: 'comment' },    // multiline comments
  {regex: new RegExp('"(?:[^"\n]|[\"])*?".*?','g'),css: 'string' },     // double quoted strings
  {regex: new RegExp("'(?:[^'\n]|[\'])*?'.*?",'g'),css: 'string' },     // single quoted strings
  {regex: new RegExp('^\\s*#.*', 'gm'),         css: 'preprocessor'},// preprocessor tags like #region and #endregion
  {regex: new RegExp(this.GetKeyw(keywords),'gm'),css: 'keyword'}    // keywords
  ];
  this.CssClass = 'dp-c';
}
dp.sh.Brushes.JScript.prototype = new dp.sh.Highlighter();
$(dp.SyntaxHighlighter.HighlightAll);
 //
 }

CSS

Add this to your user CSS to style the different code bits. Adjust to taste.

/*

*/

/* Syntax highlighting style */

pre span.idselector {
    color: red;
}

pre span.classselector {
    color: green;
}

pre span.property {
    color: blue;
}

pre span.value {
    color: orange;
}

pre span.comment {
    font-weight: bold;
    background-color: #eee;
}

pre {
    background: white;
}

/*

*/

Additional for CSS-Code:

/*

*/

/* Extreme Syntax highlighting style */

/* Main style for the table */
.dp-highlighter { width: 100%; overflow: auto; line-height: 100% !important; margin: 18px 0px 18px 0px; padding:3px 0 3px 0;}
.dp-highlighter table {width: 100%; margin: 2px 0px 2px 0px; border-collapse: collapse; border-bottom: 2px solid #eee; background-color: #fff;}
.dp-highlighter td { font-family: Courier New; font-size: 11px;}
/* Gutter with line number */
.dp-highlighter .gutter { padding-right: 5px; padding-left: 10px; width: 5px; background-color: #eee; border-right: 1px solid gray; color: gray; text-align: right; vertical-align: top;}
/* Single line style */
.dp-highlighter .line1, .line2 { padding-left: 10px; border-bottom: 1px solid #F7F7F7; white-space:nowrap;}
.dp-highlighter .line2 { background-color: #F7F7F7;}
/* Language specific styles */
.dp-c .comment { color: green; }
.dp-c .string { color: #69C; }
.dp-c .preprocessor { color: gray; }
.dp-c .keyword { color: blue; }
.dp-c .vars { color: #d00; }

/*

*/

Content Disclaimer

Informasi ini disarikan dari Wikipedia dan disajikan kembali untuk tujuan edukasi. Konten tersedia di bawah lisensi CC BY-SA 3.0. Kami tidak bertanggung jawab atas ketidakakuratan data yang bersumber dari kontribusi publik tersebut.

  1. The information displayed on this website is sourced in part or in whole from Wikipedia and has been adapted for the purpose of restating it. We strive to provide accurate and relevant information, however:
  2. There is no guarantee of absolute accuracy. Wikipedia is an open, collaborative project that can be edited by anyone, so information is subject to change.
  3. It is not intended to constitute professional advice. The content displayed is for informational and educational purposes only. For important decisions (e.g., medical, legal, or financial), please consult a professional.
  4. Content copyright. Wikipedia is licensed under the Creative Commons Attribution-ShareAlike License (CC BY-SA). This means that content may be reused with appropriate attribution and shared under a similar license.
  5. Responsible use. Any risk arising from the use of information from this website is entirely the responsibility of the user.