예제 #1
0
        bool ErrorOrReturn(string msgKey, params string[] parameters)
        {
            if (ErrorMode == ErrorMode.ErrorFree)
            {
                return(true);
            }

            throw new BbCodeParsingException(
                      string.IsNullOrEmpty(msgKey)
                    ? string.Empty
                    : MessagesHelper.GetString(msgKey, parameters));
        }
예제 #2
0
        public virtual SequenceNode ParseSyntaxTree(string bbCode)
        {
            if (bbCode == null)
            {
                throw new ArgumentNullException(nameof(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)
                {
                    // there is no possible match at the current position
                    throw new BbCodeParsingException(string.Empty);
                }

                // if the error free mode is enabled force interpretation as text if no other match could be made
                AppendText(bbCode[end].ToString(), stack);

                end++;
            }

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

            // close all tags that are still open and can be closed implicitly
            while (stack.Count > 1)
            {
                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);

                // only the root node may be left
                throw new BbCodeParsingException(string.Empty);
            }

            return(rootNode);
        }
예제 #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] == '\\'))
                            {
                                // the next char was not escapable. write the slash into the output array
                                result2[writePos++] = result[i];
                            }
                            else
                            {
                                // the next char is meant to be escaped so the backslash is skipped
                                lastWasEscapeChar = true;
                            }
                        }
                        else
                        {
                            // the backslash was the last char in the string. just write it into the output array
                            result2[writePos++] = '\\';
                        }
                    }
                    else
                    {
                        result2[writePos++] = result[i];

                        lastWasEscapeChar = false;
                    }
                }

                result = new string(result2, 0, writePos);
            }

            pos = end;

            return(result == string.Empty ? null : result);
        }