highlight.js
来自「OperaMasks是一种基于J2EE的Web开发技术」· JavaScript 代码 · 共 739 行 · 第 1/2 页
JS
739 行
ruleNode = ruleList[i] ; if (ruleNode.nodeName == "#comment") continue; if (ruleNode.nodeName == "detect2chars") { var char0=ruleNode.attributes.getNamedItem("char").value; var char1=ruleNode.attributes.getNamedItem("char1").value; if ( sMatch == char0 + char1) return ruleNode; } else if (ruleNode.nodeName == "detectchar") { var char0=ruleNode.attributes.getNamedItem("char").value; if (char0 == sMatch) return ruleNode; } else if (ruleNode.nodeName == "linecontinue") { if ( "\n" == sMatch) return ruleNode; } else if (ruleNode.nodeName == "regexp") { regExpExprNode=ruleNode.attributes.getNamedItem("expression"); if ( regExpExprNode == null ) throw "Regular expression rule missing expression attribute"; regExp = new RegExp( regExpExprNode.value, "m" ); arr = regExp.exec(sMatch); if ( arr != null ) return ruleNode; } else if (ruleNode.nodeName == "keyword") { familyNode = ruleNode.attributes.getNamedItem("family"); if ( familyNode == null) throw "Could not find family attribute for keyword"; xp="keywordlists/keywordlist[@id=\"" + familyNode.nodeTypedValue + "\"]/@regexp"; regExpNode = rootNode.selectSingleNode( xp ); if ( regExpNode == null) throw "Could not find regular expression for keyword family "+ ruleNode.attributes.getNamedItem("attribute").value + "(xp: "+xp+")"; // estimate regular expression sRegExp="(" + regExpNode.nodeTypedValue + ")"; regExp = new RegExp( sRegExp, "m" ); arr=regExp.exec(sMatch); if ( arr != null ) return ruleNode; } } return null;}/// <summary>Applies the context rules succesively to sString</summary>/// <param name="languageNode"><see also cref="XMLDOMNode"/> language node</para>/// <param name="contextNode"><see also cref="XMLDOMNode"/> context node</para>/// <param name"sString">String to parse and convert</param>/// <param name="parsedCodeNode"><seealso cref="XMLDOMNode">mother node for dumping parsed code</param>/// <remarks>This methods uses the pre-computed regular expressions of context rules, rule matching, etc.../// the result is outputted in the xmlResult document, starting at parsedCodeNode node./// <remarks>Author: Jonathan de Halleux, dehalleux@pelikhan.com, 2003</remarks>function applyRules( languageNode, contextNode, sString, parsedCodeNode){ var regExp, arr,sRegExp; var ruleNode,newNode, newCDATANode; // building regExp sRegExp=contextNode.attributes.getNamedItem("regexp").value; var regExp = new RegExp( sRegExp, "m" ); while (sString.length > 0) { // apply arr = regExp.exec( sString ); if (arr == null) { addChildCDATAElem( parsedCodeNode, contextNode.attributes.getNamedItem("attribute").value, sString ); // finished parsing regExp=null; return null; } else { //alert( contextNode.attributes.getNamedItem("attribute").nodeTypedValue ) ; // adding text addChildCDATAElem(parsedCodeNode, contextNode.attributes.getNamedItem("attribute").value, sString.substring(0, arr.index ) ); // find rule... ruleNode = findRule( languageNode, contextNode, arr[0] ); if (ruleNode == null) throw "Didn't matching rule, regular expression false ? ( context: " + contextNode.attributes.getNamedItem("id").value; // check if rule nees to be added to result... attributeNode=ruleNode.attributes.getNamedItem("attribute"); if (attributeNode != null && attributeNode.value!="hidden" ) { addChildCDATAElem(parsedCodeNode, ruleNode.attributes.getNamedItem("attribute").value , arr[0]); } // update context if necessary if ( contextNode.attributes.getNamedItem("id").value != ruleNode.attributes.getNamedItem("context").value ) { // return new context var xpContext = "contexts/context[@id=\"" + ruleNode.attributes.getNamedItem("context").value + "\"]"; contextNode = languageNode.selectSingleNode( xpContext); if (contextNode == null) throw "Didn't matching context, error in xml specification ?"; // build new regular expression sRegExp=contextNode.attributes.getNamedItem("regexp").value; regExp = new RegExp( sRegExp, "m" ); } sString = sString.substring(arr.index+arr[0].length, sString.length); } } regExp = null;}/// <summary>Create and populate an xml document with the corresponging language</summary>/// <param name="xmlDoc"><seealso DOMDocument/> highlight syntax document</param>/// <param name="sLang">language string description. For C++, use cpp.</param> /// <param name="sRootTag">Root tag (under parsed code) for the generated xml tree.</param> /// <param name="bInBox>true if in box</param>/// <param name="sCode">Code to parse</param>/// <returns><seealso cref="DOMDocument"> document containing parsed node.</returns>/// <remarks>This method builds an XML tree containing context node. Use an xsl file to render it.</remarks>/// <remarks>Author: Jonathan de Halleux, dehalleux@pelikhan.com, 2003</remarks>function buildHighlightTree( xmlDoc, sLang, sRootTag, bInBox, sCode ){ var languageAttribute,languageNode,xp; var resultMainNode; var sHighlightedCode, sDefault; try { ///////////////////////////////////////////////////////////////////////// // getting language xp="/highlight/languages/language[@id=\"" + sLang + "\"]"; languageNode=xmlDoc.documentElement.selectSingleNode( xp ); if (languageNode == null) throw "Could not find " + sLang + "language (xpath: " + xp + ")"; ///////////////////////////////////////////////////////////////////////// // getting context contextsNode=languageNode.selectSingleNode( "contexts" ); if (contextsNode == null) throw "Could not find contexts node for " + sLang + "language"; ///////////////////////////////////////////////////////////////////////// // getting default context //alert( contextsNode.attributes.getNamedItem("default").value ) ; sDefault=contextsNode.attributes.getNamedItem("default").value; xp="context[@id=\"" + sDefault + "\"]"; contextNode=contextsNode.selectSingleNode( xp ); if (contextNode == null) throw "Could not find default context for " + sLang + "language (xpath: " + xp + ")"; // create result xml xmlResult = createDOMDocument() ; /////////////////////////////////////////////////////////////////////////// // creating main node resultMainNode=xmlResult.createElement( "parsedcode" ); if (resultMainNode == null) throw "Could not create main node parsedcode"; xmlResult.appendChild(resultMainNode); /////////////////////////////////////////////////////////////////////////// // adding language attribute resultMainNode.setAttribute("lang", sRootTag ); resultMainNode.setAttribute("in-box", bInBox ); /////////////////////////////////////////////////////////////////////////// // parse and populate xmlResult applyRules( languageNode, contextNode, sCode, resultMainNode); return xmlResult; } catch(exception) { handleException (exception); xmlResult=null; return null; }}/// <summary>Apply syntax matching to sCode with the corresponding language sLang</summay>/// <param name="sLang">language string description. For C++, use cpp.</param> /// <param name="sRootTag">Root tag (under parsed code) for the generated xml tree.</param> /// <param name="sCode">Code to parse</param>/// <returns>the highlighted code.</returns>/// <remarks>Author: Jonathan de Halleux, dehalleux@pelikhan.com, 2003</remarks>function highlightCode( sLang, sRootTag, bInBox, sCode){ var xmlResult, sResult; try { // re-build highlight tree xmlResult = buildHighlightTree( xmlGlobDoc, sLang, sRootTag, bInBox, sCode ); // render xml if(document.implementation && document.implementation.createDocument) { var xslProc = new XSLTProcessor(); xslProc.importStylesheet(xslGlobDoc); sResult=xslProc.transformToFragment(xmlResult, document) ; } else { sResult=xmlResult.transformNode( xslGlobDoc ); } } catch(exception) { handleException (exception); xmlResult=null; return ""; } finally { xmlResult=null; return sResult; } };/// <summary>Find the lang in the tag</summary>/// <param name="sMatch">a string</param>/// <returns>the value of the parameter corresponding to sGlobDefaultLong</returns>function findLang( sMatch ){ var sRegExp, regExp, arr; // build regular expression sRegExp= sGlobLangTag + "\\s*=(\"[a-z]+\"|[a-z]+)"; regExp = new RegExp( sRegExp, "im"); arr = regExp.exec( sMatch ); if (arr==null || arr.length < 2 ) return null; else { if (arr[1].charAt(0)=="\"") return arr[1].substring(1, arr[1].length-1); else return arr[1]; }}/// <summary> Helper function to be used in String::Replace</summary>/// <param name="sMatch">Full match ($0)</param>/// <param name="sValue">text inside tags ($1)</param>function replaceByCode( sMatch, sValue ){ var sLang, sTemplate, xp, languageNode; // get language sLang = findLang( sMatch ); // if no language... do nothing if (sLang == null) return sMatch; // find language in language file if not found return text... xp="/highlight/languages/language[@id=\"" + sLang + "\"]"; languageNode=xmlGlobDoc.documentElement.selectSingleNode( xp ); if (languageNode == null) return sMatch; //highlight code sTemplate = sLang; return highlightCode( sLang, sTemplate, bGlobCodeInBox, sValue);} /// <summary>Processes HTML and highlight code in <pre>...</pre> and in <code>...</code></summary>/// <param name="sValue">HTML code</param>/// <param name="sOT">character opening tag: usually <</param>/// <param name="sTag">tag containing code</param>/// <param name="sCT">character closing tag: usually ></param>/// <param name="bInBox">boolean: true if should be in box, false otherwize</param>/// <returns>HTML with colored code</returns>/// Available languages: C++ -> cpp, JSCript -> jscript, VBScript -> vbscript/// <remarks>Author: Jonathan de Halleux, dehalleux@pelikhan.com, 2003</remarks>function processAndHighlightText( sValue, sOT, sTag, sCT, bInBox ){ var sRegExp, regExp; // <pre lang="cpp">using</pre> // setting global variables sGlobOT = sOT; sGlobCT = sCT; sGlobTag = sTag; bGlobCodeInBox=bInBox; // building regular expression sRegExp = sGlobOT +"\\s*" + sGlobTag +".*?" +sGlobCT +"((.|\\n)*?)" +sGlobOT +"\\s*/\\s*" +sGlobTag +"\\s*" +sGlobCT; regExp=new RegExp(sRegExp, "gim"); // render pre return sValue.replace( regExp, function( $0, $1 ){ return replaceByCode( $0, $1 );} );};//////////////////////////////////////////////////////////////////////////////////////// Initialization/// <summary>Load language files and preprocess them. Loads xsl file.</summary>function initHighlighting(){ var sXMLLang, sXSLFile; // getting xml and xsl file names sXMLLang = "highlight.xml"; sXSLStyle = "highlight.xsl"; // prepare tags sGlobOT = "<"; sGlobCT = ">"; sGlobTag = "pre"; sGlobLangTag = "lang"; sGlobTemplate= "cpp"; bGlobCodeInBox=true; try { // load and preprocess language data xmlGlobDoc = loadAndBuildSyntax( loadXML( sXMLLang ) ); // load xsl.. xslGlobDoc = loadXML( sXSLStyle ); } catch(exception) { handleException (exception); xmlGlobDoc = null; xslGlobDoc return false; } finally { return true; }}// Global variables...var sGlobOT, sGlobTag, sGlobCT, sGlobLangTag, sGlobDefaultLang, bGlobCodeInBox;var xmlGlobDoc, xslGlobDoc;// Initialize and preparse...initHighlighting();
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?