highlight.js
来自「OperaMasks是一种基于J2EE的Web开发技术」· JavaScript 代码 · 共 739 行 · 第 1/2 页
JS
739 行
/// <summary>HTML Syntax highlighting methods in JavaScript.</summary>/// <remarks>Author: Jonathan de Halleux, dehalleux@pelikhan.com, 2003</remarks>/// <summary>Handles exceptions</summary>/// <param name="exception">a catched exception</param>/// <code>/// try/// { /// // returns false if failed/// if (!doSomething())/// throw "Could not do anything";/// }/// catch (exception)/// { /// handleException(exception);/// }/// </code>/// <remarks>Author: Jonathan de Halleux, dehalleux@pelikhan.com, 2003</remarks>function handleException( exception ){ if (typeof(exception) == "string") alert("Error: "+ exception); else if (exception.description == null ) alert("Error: "+ exception.message ); else alert("Error: "+ exception.description );// Response.Write("<b>Error in script: " + exception + "</b></br>");}function createDOMDocument() { var result ; if(document.implementation && document.implementation.createDocument) { var ex;// Attr.prototype.__proto__.__defineGetter__( "nodeTypedValue" , function (){// return this.nodeValue ;// }); XMLDocument.prototype.__proto__.__defineGetter__( "xml" , function (){ try { return new XMLSerializer().serializeToString( this ); } catch (ex){ var d = document.createElement( "div" ); d.appendChild( this .cloneNode( true )); return d.innerHTML; } }); Element.prototype.__proto__.__defineGetter__( "xml" , function (){ try { return new XMLSerializer().serializeToString( this ); } catch (ex){ var d = document.createElement( "div" ); d.appendChild( this .cloneNode( true )); return d.innerHTML; } }); XMLDocument.prototype.__proto__.__defineGetter__( "text" , function (){ return this .firstChild.textContent }); Element.prototype.__proto__.__defineGetter__( "text" , function (){ return this .textContent }); XMLDocument.prototype.selectSingleNode = Element.prototype.selectSingleNode = function (xpath){ var x = this.selectNodes(xpath) if ( ! x || x.length < 1 ) return null ; return x[ 0 ]; } XMLDocument.prototype.selectNodes = Element.prototype.selectNodes = function (xpath){ var xpe = new XPathEvaluator(); var nsResolver = xpe.createNSResolver( this .ownerDocument == null ? this .documentElement : this .ownerDocument.documentElement); var result = xpe.evaluate(xpath, this , nsResolver, 0 , null ); var found = []; var res; while (res = result.iterateNext()) found.push(res); return found; } result = document.implementation.createDocument("", "", null); } else { result = new ActiveXObject("Msxml2.DOMDocument"); } return result ;}/// <summary>Loads an xml file</summary>/// <param name="sFileName">XML file name</param>/// <returns>a DOMDocument object ( i.e. a ActiveXObject("Msxml2.DOMDocument") ) </returns>/// <exception>If file not loaded successfully</exception>/// <remarks>Author: Jonathan de Halleux, dehalleux@pelikhan.com, 2003</remarks>function loadXML( sFileName){ var xmlDoc = createDOMDocument() ; xmlDoc.async = false; try { // try loading xml file, throw exception if failed if (!xmlDoc.load( sFileName )) throw "Could not load xml file " + sFileName; } catch (exception) { xmlDoc=null; handleException(exception); } return xmlDoc;};/// <summary>adds a CDATA child elem</summary>/// <param name="node">node to append child</param>/// <param name="nodeName">new child node name</param>/// <param name="cdata">CDATA value</param>/// <exception>If could not create child node</exception>/// <exception>If could not create CDATA node</exception>/// <remarks>Author: Jonathan de Halleux, dehalleux@pelikhan.com, 2003</remarks>function addChildCDATAElem( node, nodeName, cdata ){ var newNode = node.ownerDocument.createElement( nodeName); if (newNode == null) throw "Could not append node to " + node.nodeName; node.appendChild( newNode ); var newCDATANode = node.ownerDocument.createCDATASection( cdata ); if (newCDATANode == null) throw "Could not append CDATA node to " + newNode.nodeName; newNode.appendChild( newCDATANode );}/// <summary>adds a text child elem</summary>/// <param name="node">node to append child</param>/// <param name="nodeName">new child node name</param>/// <param name="text">text value</param>/// <exception>If could not create child node</exception>/// <remarks>Author: Jonathan de Halleux, dehalleux@pelikhan.com, 2003</remarks>function addChildElem( node, nodeName, text ){ var newNode = node.ownerDocument.createElement( nodeName); if (newNode == null) throw "Could not append node to " + node.nodeName; newNode.text = text; node.appendChild( newNode );}/// <summary>Adds \ to regular expression character</summary>/// <param name="char0">character to transform</param>/// <remarks>Author: Jonathan de Halleux, dehalleux@pelikhan.com, 2003</remarks>function stringToRegExp( char0 ){ var regExp = /(\-|\+|\*|\?|\(|\)|\[|\]|\\|\$|\^|\!)/g; return char0.replace(regExp, "\\$1");}/// <summary>Builds keywords family regular expressions</summary>/// <param name="languageNode"><see also cref="XMLDOMNode"/> language node</para>/// <remarks>This method create regular expression that match a whole keyword family and /// add it as a parameter "regexp" to the keywordlist node.</remarks>/// <remarks>Author: Jonathan de Halleux, dehalleux@pelikhan.com, 2003</remarks>function buildKeywordRegExp( languageNode ){ var keywordListList,keywordListNode; var sRegExp,preNode, postNode; var kwList, kwNode,rootNode; rootNode = languageNode.selectSingleNode("/*"); // iterating keywords keywordListList = rootNode.selectNodes("keywordlists/keywordlist"); keywordListList.reset(); for ( keywordListNode = keywordListList.nextNode(); keywordListNode != null; keywordListNode= keywordListList.nextNode() ) { sRegExp="\\b"; // adding pre... preNode = keywordListNode.attributes.getNamedItem("pre"); if (preNode != null) sRegExp=sRegExp+preNode.nodeTypedValue; sRegExp=sRegExp+"("; // build regular expression... kwList = keywordListNode.selectNodes("kw"); kwList.reset(); // iterate kw elements for (kwNode = kwList.nextNode() ; kwNode != null; kwNode = kwList.nextNode() ) { sRegExp=sRegExp + stringToRegExp( kwNode.nodeTypedValue ) + "|"; } // close string if (sRegExp.length > 1) sRegExp=sRegExp.substring(0,sRegExp.length-1); sRegExp=sRegExp+")"; // adding pre... postNode = keywordListNode.attributes.getNamedItem("post"); if (postNode != null) sRegExp=sRegExp+postNode.nodeTypedValue; sRegExp=sRegExp+"\\b"; // add to keywordListNode keywordListNode.setAttribute( "regexp", sRegExp ); }}/// <summary>Builds regular expression out of contextNode</summary>/// <param name="languageNode"><see also cref="XMLDOMNode"/> language node</para>/// <param name="contextNode"><see also cref="XMLDOMNode"/> context node</para>/// <remarks>This method create regular expression that match all the context rules/// add it as a parameter "regexp" to the context node.</remarks>/// <exception>If keyword family not corresponding to keyword attribute.</exception>/// <exception>Regular expression rule missing regexp argument</exception>/// <remarks>Author: Jonathan de Halleux, dehalleux@pelikhan.com, 2003</remarks>function buildRuleRegExp( languageNode, contextNode ){ var sRegExp, ruleNode, regExpExprNode, rootNode; var keywordListNode, keywordListNameNode, keywordListRegExpNode,xp; rootNode = languageNode.selectSingleNode("/*"); sRegExp="("; var ruleList=contextNode.childNodes; // building regular expression for (ruleNode=ruleList.nextNode(); ruleNode != null; ruleNode=ruleList.nextNode() ) { if (ruleNode.nodeName == "#comment") continue; // apply rule... if (ruleNode.nodeName == "detect2chars") { var char0=ruleNode.attributes.getNamedItem("char").value; var char1=ruleNode.attributes.getNamedItem("char1").value; sRegExp= sRegExp + stringToRegExp( char0 + char1 ) + "|"; } else if (ruleNode.nodeName == "detectchar") { var char0=ruleNode.attributes.getNamedItem("char").value; sRegExp=sRegExp + stringToRegExp( char0 ) + "|"; } else if (ruleNode.nodeName == "linecontinue") { sRegExp=sRegExp + "\n|" } else if (ruleNode.nodeName == "regexp" ) { regExpExprNode = ruleNode.attributes.getNamedItem("expression"); if ( regExpExprNode == null ) throw "Regular expression rule missing expression attribute"; sRegExp=sRegExp + regExpExprNode.nodeTypedValue + "|"; } else if (ruleNode.nodeName == "keyword") { // finding keywordlist keywordListNameNode = ruleNode.attributes.getNamedItem("family"); if (keywordListNameNode == null) throw "Keyword rule missing family"; xp="keywordlists/keywordlist[@id=\"" + keywordListNameNode.nodeTypedValue + "\"]"; keywordListNode = rootNode.selectSingleNode(xp); if (keywordListNode == null) throw "Could not find keywordlist (xp: "+ xp + ")"; keywordListRegExpNode = keywordListNode.attributes.getNamedItem("regexp"); if (keywordListRegExpNode == null) throw "Could not find keywordlist regular expression"; // adding regexp sRegExp=sRegExp+keywordListRegExpNode.nodeTypedValue+"|"; } } if (sRegExp.length > 1) sRegExp=sRegExp.substring(0,sRegExp.length-1)+")"; else sRegExp=""; return sRegExp; };/// <summary>Precompiles regular expressions, search strings and prepares rules attribute</summary>/// <param name="xmlDoc"><seealso DOMDocument/> highlight syntax document</param>/// <param name="languageNode"><see also cref="XMLDOMNode"/> context node</para>/// <exception>If rule id not corresponding to a rule family</exception>/// <remarks>Author: Jonathan de Halleux, dehalleux@pelikhan.com, 2003</remarks>function buildRules( languageNode ){ var contextList, contextNode, sRegExp, rootNode; var rulePropList, rulePropNode, rulePropNodeAttributes, ruleList, ruleNode; rootNode = languageNode.selectSingleNode("/*"); // first building keyword regexp buildKeywordRegExp( languageNode ); contextList = languageNode.selectNodes("contexts/context"); // create regular expressions for context for (contextNode = contextList.nextNode(); contextNode != null; contextNode = contextList.nextNode()) { sRegExp = buildRuleRegExp( languageNode, contextNode ); // add attribute contextNode.setAttribute( "regexp", sRegExp ); }}/// <summary>Prepares syntax xml file</summary>/// <param name="xmlDoc">xml Syntax</param>/// <returns><seealso cref"DOMDocument"> language description </returns>/// <remarks>Author: Jonathan de Halleux, dehalleux@pelikhan.com, 2003</remarks>function loadAndBuildSyntax( xmlDoc ){ var xmlModDoc, languageNode, languageNodeList; var needBuildNode, bNeedBuild; // check if build needed... bNeedBuild = true; needBuildNode = xmlDoc.documentElement.selectSingleNode("/highlight").attributes.getNamedItem("needs-build"); if (needBuildNode == null || needBuildNode.nodeTypedValue=="yes") { // iterate languages and prebuild languageNodeList = xmlDoc.documentElement.selectNodes("/highlight/languages/language"); languageNodeList.reset(); for(languageNode = languageNodeList.nextNode(); languageNode != null; languageNode = languageNodeList.nextNode()) { ///////////////////////////////////////////////////////////////////////// // build regular expressions buildRules( languageNode ); } // updating... xmlDoc.documentElement.selectSingleNode("/highlight").setAttribute("needs-build","no"); } // save file if asked saveBuildNode = xmlDoc.documentElement.selectSingleNode("/highlight").attributes.getNamedItem("save-build"); if (saveBuildNode != null && saveBuildNode.nodeTypedValue == "yes") xmlDoc.save( sXMLSyntax ); // closing file return xmlDoc;}/// <summary>Finds the rule that trigerred the match</summary>/// <param name="languageNode"><see also cref="XMLDOMNode"/> language node</para>/// <param name="contextNode"><see also cref="XMLDOMNode"/> context node</para>/// <param name="sMatch"><see also cref="String/> that matched the context regular expression</param>/// <remarks>If the <seealso RegExp/> finds a rule occurence, this method is used to find which rule has been trigerred.</remarks>/// <exception>Triggers if sMatch does not match any rule of contextNode</exception>/// <remarks>Author: Jonathan de Halleux, dehalleux@pelikhan.com, 2003</remarks>function findRule( languageNode, contextNode, sMatch ){ var regExpNode, regExp, sRegExp, arr, familyNode,xp; var ruleNode, regExpExprNode,rootNode; var ruleList=contextNode.childNodes; rootNode=languageNode.selectSingleNode("/*"); // building regular expression for (var i = 0 ; i<ruleList.length ; i++ ) //for (ruleNode=ruleList.nextNode(); ruleNode != null ; ruleNode = ruleList.nextNode() ) {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?