Пример #1
0
        public virtual SequenceNode ParseSyntaxTree(string bbCode)
        {
            if (bbCode == null)
            {
                throw new ArgumentNullException("bbCode");
            }

            Stack <SyntaxTreeNode> stack = new Stack <SyntaxTreeNode>();
            var rootNode = new SequenceNode();

            stack.Push(rootNode);

            int end = 0;

            while (end < bbCode.Length)
            {
                if (MatchTagEnd(bbCode, ref end, stack))
                {
                    continue;
                }

                if (MatchStartTag(bbCode, ref end, stack))
                {
                    continue;
                }

                if (MatchTextNode(bbCode, ref end, stack))
                {
                    continue;
                }

                if (ErrorMode != ErrorMode.ErrorFree)
                {
                    throw new BBCodeParsingException("");  //there is no possible match at the current position
                }
                AppendText(bbCode[end].ToString(), stack); //if the error free mode is enabled force interpretation as text if no other match could be made
                end++;
            }

            Debug.Assert(end == bbCode.Length); //assert bbCode was matched entirely

            while (stack.Count > 1)             //close all tags that are still open and can be closed implicitly
            {
                var node = (TagNode)stack.Pop();
                if (node.Tag.RequiresClosingTag && ErrorMode == ErrorMode.Strict)
                {
                    throw new BBCodeParsingException(MessagesHelper.GetString("TagNotClosed", node.Tag.Name));
                }
            }

            if (stack.Count != 1)
            {
                Debug.Assert(ErrorMode != ErrorMode.ErrorFree);
                throw new BBCodeParsingException(""); //only the root node may be left
            }

            return(rootNode);
        }
Пример #2
0
 bool ErrorOrReturn(string msgKey, params string[] parameters)
 {
     if (ErrorMode == ErrorMode.ErrorFree)
     {
         return(true);
     }
     else
     {
         throw new BBCodeParsingException(string.IsNullOrEmpty(msgKey) ? "" : MessagesHelper.GetString(msgKey, parameters));
     }
 }
Пример #3
0
        string ParseText(string input, ref int pos)
        {
            int  end            = pos;
            bool escapeFound    = false;
            bool anyEscapeFound = false;

            while (end < input.Length)
            {
                if (input[end] == '[' && !escapeFound)
                {
                    break;
                }
                if (input[end] == ']' && !escapeFound)
                {
                    if (ErrorMode == ErrorMode.Strict)
                    {
                        throw new BBCodeParsingException(MessagesHelper.GetString("NonescapedChar"));
                    }
                }

                if (input[end] == '\\' && !escapeFound)
                {
                    escapeFound    = true;
                    anyEscapeFound = true;
                }
                else if (escapeFound)
                {
                    if (!(input[end] == '[' || input[end] == ']' || input[end] == '\\'))
                    {
                        if (ErrorMode == ErrorMode.Strict)
                        {
                            throw new BBCodeParsingException(MessagesHelper.GetString("EscapeChar"));
                        }
                    }
                    escapeFound = false;
                }

                end++;
            }

            if (escapeFound)
            {
                if (ErrorMode == ErrorMode.Strict)
                {
                    throw new BBCodeParsingException("");
                }
            }

            var result = input.Substring(pos, end - pos);

            if (anyEscapeFound)
            {
                var  result2           = new char[result.Length];
                int  writePos          = 0;
                bool lastWasEscapeChar = false;
                for (int i = 0; i < result.Length; i++)
                {
                    if (!lastWasEscapeChar && result[i] == '\\')
                    {
                        if (i < result.Length - 1)
                        {
                            if (!(result[i + 1] == '[' || result[i + 1] == ']' || result[i + 1] == '\\'))
                            {
                                result2[writePos++] = result[i]; //the next char was not escapable. write the slash into the output array
                            }
                            else
                            {
                                lastWasEscapeChar = true; //the next char is meant to be escaped so the backslash is skipped
                            }
                        }
                        else
                        {
                            result2[writePos++] = '\\'; //the backslash was the last char in the string. just write it into the output array
                        }
                    }
                    else
                    {
                        result2[writePos++] = result[i];
                        lastWasEscapeChar   = false;
                    }
                }
                result = new string(result2, 0, writePos);
            }

            pos = end;
            return(result == "" ? null : result);
        }