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 &lt;</param>/// <param name="sTag">tag containing code</param>/// <param name="sCT">character closing tag: usually &gt;</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 + -
显示快捷键?