コード例 #1
0
ファイル: CodeColorizer.cs プロジェクト: julianhaslinger/SHFB
        /// <summary>
        /// This is used to apply the context rules successively to the code string that needs colorizing.
        /// </summary>
        /// <param name="languageNode">The language node.</param>
        /// <param name="contextNode">The context node.</param>
        /// <param name="code">The code block to parse and convert.</param>
        /// <param name="parsedCodeNode">Parent node that will contain the parsed code.</param>
        /// <remarks>This method uses the pre-computed regular expressions of the context rules, rule matching,
        /// etc.  The results are added to the XML document in the parsedcodeNode.</remarks>
        /// <exception cref="InvalidOperationException">This is thrown if a rule match cannot be found or if a
        /// matching context node cannot be found.</exception>
        private void ApplyRules(XmlNode languageNode, XmlNode contextNode, string code, XmlNode parsedCodeNode)
        {
            XmlNode attributeNode;
            Regex regExp;
            Match m;

            // Get the regular expression for the default context
            regExp = rxDic.GetKey(languageNode, contextNode);

            while(code.Length > 0)
            {
                // Apply
                m = regExp.Match(code);

                if(!m.Success)
                {
                    parsedCodeNode.XmlAddChildCDATAElem(contextNode.Attributes["attribute"].Value, code);

                    // Finished parsing
                    break;
                }

                // Add the skipped text if not empty
                if(m.Index != 0)
                {
                    attributeNode = contextNode.Attributes["attribute"];

                    if(attributeNode != null && attributeNode.Value != "hidden")
                        parsedCodeNode.XmlAddChildCDATAElem(attributeNode.Value, code.Substring(0, m.Index));
                }

                // Find the rule that caused the match
                XmlNode ruleNode = this.FindRule(languageNode, contextNode, m.Value);

                if(ruleNode == null)
                    throw new InvalidOperationException("Didn't find matching rule, regular expression false? " +
                        "(context: " + contextNode.Attributes["id"].Value + ")");

                // Check to see if the match needs to be added to the result
                attributeNode = ruleNode.Attributes["attribute"];

                if(attributeNode != null && attributeNode.Value != "hidden")
                    parsedCodeNode.XmlAddChildCDATAElem(attributeNode.Value, m.Value);

                // Update the context if necessary
                if(contextNode.Attributes["id"].Value != ruleNode.Attributes["context"].Value)
                {
                    // Get the new context
                    contextNode = languageNode.SelectSingleNode("contexts/context[@id=\"" + ruleNode.Attributes[
                        "context"].Value + "\"]");

                    if(contextNode == null)
                        throw new InvalidOperationException("Didn't find matching context, error in XML " +
                            "specification?");

                    // Get the new regular expression
                    regExp = rxDic.GetKey(languageNode, contextNode);
                }

                // Removed the parsed code and carry on
                code = code.Substring(m.Index + m.Length);
            }
        }