MediaWiki:Ext/Highlighting.js

Z Wikibooks, biblioteki wolnych podręczników.

Uwaga: Zmiany po zapisaniu nowych ustawień mogą nie być widoczne. Należy wyczyścić zawartość pamięci podręcznej przeglądarki internetowej.

  • Mozilla, Firefox lub Safari – przytrzymaj wciśnięty Shift i kliknij na Odśwież lub wciśnij Ctrl‐F5 lub Ctrl‐R (Cmd‐Shift‐R na Macintoshu)
  • Konqueror – kliknij przycisk Odśwież lub wciśnij F5
  • Opera – wyczyść pamięć podręczną w menu Narzędzia → Preferencje
  • Internet Explorer – przytrzymaj Ctrl i kliknij na Odśwież lub wciśnij Ctrl‐F5
/*
* author: [[User:Piotr]]
* license: BSD
 
{{Podświetl|js}}
== highlighting ==
<pre>
// */
 
var highlighting = {
    defs: {},
    initialized: false,
    csstable: {"lang-c": "C", "lang-cpp": "C++", "lang-py": "Python", "lang-js": "JavaScript", "lang-pas": "Pascal", "lang-php": "PHP", "lang-vhdl": "VHDL"}
};
 
/*
</pre>
=== main functions ===
<pre>
// */
 
highlighting.init = function()
{
    if ( highlighting.initialized ) return;
 
    highlighting.initialized = true;
 
    var hlElem = document.getElementById("highlighting");
    classAttrName = "class";
    this.defaultClass = hlElem.getAttribute("class");
    if ( !this.defaultClass ) {
        classAttrName = "className";
        this.defaultClass = hlElem.getAttribute("className");
    }
 
    var tts = document.getElementsByTagName("tt");
    for (var i=0; i<tts.length; ++i) {
        highlighting.highlight(tts[i]);
    }
 
    var codes = document.getElementsByTagName("code");
    for (var i=0; i<codes.length; ++i) {
        highlighting.highlight(codes[i]);
    }
 
    this.elements = document.getElementsByTagName("pre");
    this.ctr = 0;
    if ( this.elements.length > 0 ) {
        window.setTimeout("highlighting.highlightNextElement()", 0.25); // we have time ;)
    }
}
 
highlighting.highlightNextElement = function()
{
    this.highlight(this.elements[this.ctr++]);
    if ( this.ctr < this.elements.length ) {
        window.setTimeout("highlighting.highlightNextElement()", 0.25);
    } else {
        delete this.elements;
        delete this.ctr;
    }
}
 
// check lang and colorise node
highlighting.highlight = function(node)
{
    var className = node.getAttribute(classAttrName);
    if ( !className ) className = this.defaultClass;
    var lang = this.csstable[className];
    if ( lang )
        highlighting.highlightNode(lang, node);
}
 
// colorise node
highlighting.highlightNode = function(lang, node)
{
    for (var i=0; i<node.childNodes.length; ++i) {
        var data = node.childNodes[i].data;
        if ( data ) {
            data = data.replace(/ /g, "\240"); // &nbsp;
            this.newLine = "\n";
            if ( data.indexOf("\r") != -1 ) {
                this.newLine = "\r";
                data = data.replace(/\r/g, "\n");
            }
            var span = document.createElement("span");
            this.defs[lang].highlight(data, span);
            node.replaceChild(span, node.childNodes[i]);
        }
    }
}
 
// add nodes
highlighting.addNodes = function(text, s, beg, end, cssclass, node)
{
    var ndata = text.slice(s, beg).replace(/\n/g, this.newLine);
    if ( ndata )
        node.appendChild(document.createTextNode(ndata));
    ndata = text.slice(beg, end).replace(/\n/g, this.newLine);
    if ( ndata ) {
        var span = document.createElement("span");
        span.setAttribute(classAttrName, cssclass);
        span.appendChild(document.createTextNode(ndata));
        node.appendChild(span);
    }
}
 
// default function to highlighting
highlighting.defaultHighlight = function(text, node)
{
    var s = 0;
    var i = 0;
    while ( i < text.length ) {
        var R = null;
        for (var m = 0; R == null && m < this.funcList.length; ++m ) {
            this.tmpFunc = this.funcList[m];     
            R = this.tmpFunc(text, i);
        }
        if ( R != null ) {
            if ( R[1] != null ) {
                highlighting.addNodes(text, s, i, R[0], R[1], node);
                s = i = R[0];
            } else {
                i = R[0];
            }
        } else {
            ++i;
        }
    }
    if ( s != text.length ) {
        highlighting.addNodes(text, s, text.length, text.length, "", node);
    }
}
 
/*
</pre>
 
=== isAlpha, isNum, isSpace ===
<pre>
// */
function isAlpha(c)
{
    return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z');
}
 
function isNum(c)
{
    return '0' <= c && c <= '9'
}
 
function isSpace(c)
{
    return c == ' ' || c == '\n' || c == '\t';
}
 
// -----------------
 
/*
</pre>
=== To parsing ===
<pre>
// */
 
// check comments, return pair [last index, cssclass (or null)]
highlighting.commentCheck = function(text, i) 
{
    for (var j=0; j<this.comment.length; ++j) {
        var str1 = this.comment[j][0];
        var str2 = this.comment[j][1];
        if ( text.substr(i, str1.length) == str1 ) {
            i = text.indexOf(str2, i + str1.length);
            if ( i == -1 ) return [text.length, "highlight-comment"];
            return [i + str2.length, "highlight-comment"];
        }
    }
    return null;
}
 
// check strings
highlighting.stringCheck = function(text, i)
{
    if ( this.string.indexOf(text.charAt(i)) != -1 ) {
        var x = text.charAt(i);
        ++i;
        while ( i < text.length && text.charAt(i) != x ) {
            if ( text.charAt(i) == "\\" ) i++;
            i++;
        }
        return [Math.min(i+1, text.length), "highlight-string"];
    }
    return null;
}
 
// check numbers (float and integer)
highlighting.numberCheck = function(text, i)
{
    if ( isNum(text.charAt(i)) || (i+1 < text.length && text.charAt(i) == '.' && isNum(text.charAt(i+1))) ) {
        var isFloat = (text.charAt(i) == '.');
        ++i;
        while ( i < text.length && (isNum(text.charAt(i)) || isAlpha(text.charAt(i))
                || text.charAt(i) == '_' || text.charAt(i) == '.') )
        {
            if ( text.charAt(i) == '.' ) {
                isFloat = true;
            }
            ++i;
        }
        if ( isFloat ) {
            return [i, "highlight-float"];
        }
        return [i, "highlight-int"];
    }
    return null;
}
 
// check keywords
highlighting.keywordCheck = function(text, i)
{
    var beg = i;
    if ( isAlpha(text.charAt(i)) || text.charAt(i) == '_' ) {
            window
            ++i;
            while ( i < text.length && 
                    (isNum(text.charAt(i)) || isAlpha(text.charAt(i)) || text.charAt(i) == '_') ) {
                ++i;
            }
            var wrd = text.slice(beg, i);
            if ( this.casesensitive == false )
                wrd = wrd.toLowerCase();
 
            if ( this.keywords[wrd] ) {
                return [i, "highlight-keyword"];
            } else {
                return [i, null];
            }
    }
    return null;
}
 
// C/C++ preprocessor
highlighting.cpreprocessorCheck = function(text, i)
{
    if ( text.charAt(i) == '\n' || i == 0 ) {
        if ( i > 0 )
            ++i;
 
        var j = i;
        while ( j < text.length && isSpace(text.charAt(j)) ) ++j;
        if ( text.charAt(j) != '#' && i != j ) {
            return [j, null];
        } else if ( text.charAt(j) != '#' ) {
            return null;
        }
        i = j + 1;
 
        while ( i < text.length && isSpace(text.charAt(i)) ) ++i;
        while ( i < text.length && (isAlpha(text.charAt(i)) || isNum(text.charAt(i))) ) ++i;
        return [i, "highlight-keyword"];
    }
    return null;
}
 
/*
</pre>
=== Definitions ===
==== C/C++ ====
<pre>
// */
highlighting.defs["C++"] = {
    funcList: [highlighting.cpreprocessorCheck, highlighting.commentCheck, highlighting.stringCheck, highlighting.numberCheck, highlighting.keywordCheck],
    casesensitive: true,
    string: "'\"",
    comment: [["//", "\n"], ["/*", "*/"]],
    keywords: {"and": 1, "and_eq": 1, "asm": 1, "auto": 1, "bitand": 1, "bitor": 1, "bool": 1, "break": 1, "case": 1, "catch": 1, "char": 1, "class": 1, "compl": 1, "const": 1, "const_cast": 1, "continue": 1, "default": 1, "delete": 1, "do": 1, "double": 1, "dynamic_cast": 1, "else": 1, "enum": 1, "explicit": 1, "extern": 1, "false": 1, "float": 1, "for": 1, "friend": 1, "goto": 1, "if": 1, "inline": 1, "int": 1, "long": 1, "mutable": 1, "namespace": 1, "new": 1, "not": 1, "not_eq": 1, "operator": 1, "or": 1, "or_eq": 1, "private": 1, "protected": 1, "public": 1, "register": 1, "reinterpret_cast": 1, "return": 1, "short": 1, "signed": 1, "sizeof": 1, "static": 1, "static_cast": 1, "struct": 1, "switch": 1, "template": 1, "this": 1, "throw": 1, "true": 1, "try": 1, "typedef": 1, "typeid": 1, "typename": 1, "union": 1, "unsigned": 1, "using": 1, "virtual": 1, "void": 1, "volatile": 1, "wchar_t": 1, "while": 1, "xor": 1, "xor_eq": 1},
    highlight: highlighting.defaultHighlight
}
 
highlighting.defs["C"] = highlighting.defs["C++"];
 
/*
</pre>
==== Python ====
<pre>
// */
highlighting.defs["Python"] = {
    funcList: [highlighting.commentCheck, highlighting.stringCheck, highlighting.numberCheck, highlighting.keywordCheck],
    casesensitive: true,
    string: "'\"",
    comment: [["#", "\n"]],
    keywords: {"and": 1, "assert": 1, "break": 1, "class": 1, "continue": 1, "def": 1, "del": 1, "elif": 1, "else": 1, "except": 1, "exec": 1, "finally": 1, "for": 1, "from": 1, "global": 1, "if": 1, "import": 1, "in": 1, "is": 1, "lambda": 1,"not": 1, "or": 1, "pass": 1, "print": 1, "raise": 1, "return": 1, "try": 1, "while": 1, "yield": 1},
    highlight: highlighting.defaultHighlight
};
 
/*
</pre>
==== JavaScript ====
<pre>
// */
highlighting.defs["JavaScript"] = {
    funcList: [highlighting.commentCheck, highlighting.stringCheck, highlighting.numberCheck, highlighting.keywordCheck],
    casesensitive: true,
    string: "'\"",
    comment: [["//", "\n"], ["/*", "*/"]],
    keywords: {"abstract":1, "boolean":1, "break":1, "byte":1, "case":1, "catch":1, "char":1, "class":1, "const":1, "continue":1, "debugger":1, "default":1, "delete":1, "do":1, "double":1, "else":1, "enum":1, "export":1, "extends":1, "false":1, "final":1, "finally":1, "float":1, "for":1, "function":1, "goto":1, "if":1, "implements":1, "import":1, "in":1, "instanceof":1, "int":1, "interface":1, "long":1, "native":1, "new":1, "null":1, "package":1, "private":1, "protected":1, "public":1, "return":1, "short":1, "static":1, "super":1, "switch":1, "synchronized":1, "this":1, "throw":1, "throws":1, "transient":1, "true":1, "try":1, "typeof":1, "var":1, "void":1, "volatile":1, "while":1, "with":1},
    highlight: highlighting.defaultHighlight
};
 
/*
</pre>
 
==== Pascal ====
<pre>
// */
highlighting.defs["Pascal"] = {
    funcList: [highlighting.commentCheck, highlighting.stringCheck, highlighting.numberCheck, highlighting.keywordCheck],
    casesensitive: false,
    string: "'\"",
    comment: [["{", "}"]],
    keywords: {"and":1, "begin":1, "case":1, "const":1, "div":1, "do":1, "do":1, "downto":1, "else":1, "end":1, "false":1, "for":1, "function":1, "goto":1, "if":1, "implementation":1, "in":1, "interface":1, "label":1, "maxint":1, "mod":1, "nil":1, "not":1, "of":1, "or":1, "packed":1, "private":1, "procedure":1, "program":1, "public":1, "repeat":1, "then":1, "to":1, "true":1, "type":1, "unit":1, "until":1, "uses":1, "var":1, "while":1, "with":1},
    highlight: highlighting.defaultHighlight
};
 
/*
</pre>
 
==== PHP ====
<pre>
// */
 
highlighting.defs["PHP"] = {
    funcList: [highlighting.commentCheck, highlighting.stringCheck, highlighting.numberCheck, highlighting.keywordCheck],
    casesensitive: true,
    string: "'\"",
    comment: [["//", "\n"], ["#", "\n"], ["/*", "*/"]],
    keywords: {"__CLASS__":1, "__FILE__":1, "__FUNCTION__":1, "__LINE__":1, "__METHOD__":1, "abstract":1, "and":1, "array":1, "as":1, "break":1, "case":1, "catch":1, "cfunction":1, "class":1, "clone":1, "const":1, "continue":1, "declare":1, "default":1, "die":1, "do":1, "echo":1, "else":1, "elseif":1, "empty":1, "enddeclare":1, "endfor":1, "endforeach":1, "endif":1, "endswitch":1, "endwhile":1, "eval":1, "exception":1, "exit":1, "extends":1, "extends":1, "final":1, "for":1, "foreach":1, "function":1, "global":1, "if":1, "implements":1, "include":1, "include_once":1, "interface":1, "isset":1, "list":1, "new":1, "old_function":1, "or":1, "php_user_filter":1, "print":1, "private":1, "protected":1, "public":1, "require":1, "require_once":1, "return":1, "static":1, "switch":1, "this":1, "throw":1, "try":1, "unset":1, "use":1, "var":1, "while":1, "xor":1},
    highlight: highlighting.defaultHighlight
};
 
/*
</pre>
==== VHDL ====
<pre>
*/
 
highlighting.defs["VHDL"] = {
    funcList: [highlighting.commentCheck, highlighting.stringCheck, highlighting.numberCheck, highlighting.keywordCheck],
    casesensitive: true,
    string: "'\"",
    comment: [["--", "\n"]],
    keywords: {"abs,":1, "access,":1, "after,":1, "alias,":1, "all,":1, "and,":1, "architecture,":1, "array,":1, "assert,":1, "attribute,":1, "begin,":1, "block,":1, "body,":1, "buffer,":1, "bus,":1, "case,":1, "component,":1, "configuration,":1, "constant,":1, "disconnect,":1, "downto,":1, "else,":1, "elsif,":1, "end,":1, "entity,":1, "exit,":1, "file,":1, "for,":1, "function,":1, "generate,":1, "generic,":1, "group,":1, "guarded,":1, "if,":1, "impure,":1, "in,":1, "inertial,":1, "inout,":1, "is,":1, "label,":1, "library,":1, "linkage,":1, "literal,":1, "loop,":1, "map,":1, "mod,":1, "nand,":1, "new,":1, "next,":1, "nor,":1, "not,":1, "null,":1, "of,":1, "on,":1, "open,":1, "or,":1, "others,":1, "out,":1, "package,":1, "port,":1, "postponed,":1, "procedure,":1, "process,":1, "pure,":1, "range,":1, "record,":1, "register,":1, "reject,":1, "rem,":1, "report,":1, "return,":1, "rol,":1, "ror,":1, "select,":1, "severity,":1, "shared,":1, "signal,":1, "sla,":1, "sll,":1, "sra,":1, "srl,":1, "subtype,":1, "then,":1, "to,":1, "transport,":1, "type,":1, "unaffected,":1, "units,":1, "until,":1, "use,":1, "variable,":1, "wait,":1, "when,":1, "while,":1, "with,":1, "xnor,":1, "xor":1},
    highlight: highlighting.defaultHighlight
};
 
highlighting.init();
 
/*
</pre>
// */