コード例 #1
0
ファイル: BlockMatcher.cs プロジェクト: DevSw/BtrieveWrapper
 public BlockMatcher(BlockType type)
 {
     this.BlockType = type;
     _regex         = new Regex(
         BlockMatcher.GetPattern(type),
         RegexOptions.Compiled | RegexOptions.Singleline);
 }
コード例 #2
0
ファイル: BlockMatcher.cs プロジェクト: DevSw/BtrieveWrapper
        public static BlockMatch GetMatch(string input)
        {
            if (_regexCollection == null)
            {
                BlockMatcher.Setup();
            }
            BlockMatch result = null;

            foreach (var regex in _regexCollection)
            {
                result = BlockMatcher.GetMatch(result, regex.Match(input));
            }
            return(result);
        }
コード例 #3
0
        public string Parse(string block)
        {
            var    resultBuilder = new StringBuilder();
            var    blockBuilder  = new StringBuilder();
            string forItem       = null;

            System.Collections.IEnumerable forMembers = null;
            var ifParameters = new List <IfParameter>();
            var blockStates  = new Stack <BlockState>();

            for (; ;)
            {
                var match = BlockMatcher.GetMatch(block);

                if (match == null)
                {
                    if (blockStates.Count != 0)
                    {
                        throw new ConstructionException();
                    }
                    resultBuilder.Append(block);
                    return(resultBuilder.ToString().UnescapeTemplate());
                }
                if (blockStates.Count == 0)
                {
                    resultBuilder.Append(block.Substring(0, match.Match.Index));
                }
                else
                {
                    blockBuilder.Append(block.Substring(0, match.Match.Index));
                }
                block = block.Substring(match.Match.Index + match.Match.Length, block.Length - match.Match.Index - match.Match.Length);
                switch (match.Type)
                {
                case BlockType.Tag:
                    if (blockStates.Count == 0)
                    {
                        var member = match.Match.Groups["member"];
                        if (member.Success)
                        {
                            resultBuilder.Append(this.GetMemberValue(member.Value));
                        }
                        else
                        {
                            throw new InvalidOperationException();
                        }
                    }
                    else
                    {
                        blockBuilder.Append(match.Match.Value);
                    }
                    break;

                case BlockType.If:
                    if (blockStates.Count == 0)
                    {
                        ifParameters.Clear();
                        blockBuilder = new StringBuilder();

                        var member    = match.Match.Groups["member"];
                        var value     = match.Match.Groups["value"];
                        var parameter = new IfParameter();
                        parameter.Member = this.GetMemberValue(member.Value);
                        parameter.Value  = value.Success ? value.Value.UnescapeValue() : null;
                        parameter.IsElse = false;
                        ifParameters.Add(parameter);
                    }
                    else
                    {
                        blockBuilder.Append(match.Match.Value);
                    }
                    blockStates.Push(BlockState.If);
                    break;

                case BlockType.ElseIf:
                    if (blockStates.Count == 0 || blockStates.Peek() != BlockState.If)
                    {
                        throw new ConstructionException();
                    }
                    else if (blockStates.Count == 1)
                    {
                        ifParameters.Last().Block = blockBuilder.ToString();
                        blockBuilder = new StringBuilder();

                        var member    = match.Match.Groups["member"];
                        var value     = match.Match.Groups["value"];
                        var parameter = new IfParameter();
                        parameter.Member = this.GetMemberValue(member.Value);
                        parameter.Value  = value.Success ? value.Value.UnescapeValue() : null;
                        parameter.IsElse = false;
                        ifParameters.Add(parameter);
                    }
                    else
                    {
                        blockBuilder.Append(match.Match.Value);
                    }
                    break;

                case BlockType.Else:
                    if (blockStates.Count == 0 || blockStates.Peek() != BlockState.If)
                    {
                        throw new ConstructionException();
                    }
                    else if (blockStates.Count == 1)
                    {
                        ifParameters.Last().Block = blockBuilder.ToString();
                        blockBuilder = new StringBuilder();

                        var parameter = new IfParameter();
                        parameter.Member = null;
                        parameter.Value  = null;
                        parameter.IsElse = true;
                        ifParameters.Add(parameter);
                    }
                    else
                    {
                        blockBuilder.Append(match.Match.Value);
                    }
                    break;

                case BlockType.EndIf:
                    if (blockStates.Count == 0 || blockStates.Peek() != BlockState.If)
                    {
                        throw new ConstructionException();
                    }
                    else if (blockStates.Count == 1)
                    {
                        ifParameters.Last().Block = blockBuilder.ToString();
                        blockBuilder = null;

                        foreach (var ifParameter in ifParameters)
                        {
                            var matched = false;
                            if (ifParameter.IsElse)
                            {
                                matched = true;
                            }
                            else if (ifParameter.Value == null)
                            {
                                if (ifParameter.Member != null &&
                                    !ifParameter.Member.Equals(ifParameter.Member.GetType().GetDefault()))
                                {
                                    matched = true;
                                }
                            }
                            else
                            {
                                if (ifParameter.Member != null &&
                                    ifParameter.Member.ToString() == ifParameter.Value)
                                {
                                    matched = true;
                                }
                            }
                            if (matched)
                            {
                                var parser = new BlockParser(this.Context, this.Name, this._parsers);
                                resultBuilder.Append(parser.Parse(ifParameter.Block));
                                break;
                            }
                        }
                    }
                    else
                    {
                        blockBuilder.Append(match.Match.Value);
                    }
                    blockStates.Pop();
                    break;

                case BlockType.For:
                    if (blockStates.Count == 0)
                    {
                        blockBuilder = new StringBuilder();

                        var item = match.Match.Groups["item"];
                        var list = match.Match.Groups["list"];
                        forItem    = item.Value;
                        forMembers = this.GetMemberValue(list.Value) as System.Collections.IEnumerable;
                    }
                    else
                    {
                        blockBuilder.Append(match.Match.Value);
                    }
                    blockStates.Push(BlockState.For);
                    break;

                case BlockType.EndFor:
                    if (blockStates.Count == 0 || blockStates.Peek() != BlockState.For)
                    {
                        throw new ConstructionException();
                    }
                    else if (blockStates.Count == 1)
                    {
                        if (forMembers != null)
                        {
                            var forBlock = blockBuilder.ToString();
                            var members  = new List <object>();
                            foreach (var forMember in forMembers)
                            {
                                members.Add(forMember);
                            }
                            for (var i = 0; i < members.Count; i++)
                            {
                                var parsers = this._parsers.ToList();
                                parsers.Add(this);
                                var context = new ParserContext(members[i]);
                                context.Dictionary["IsFirst"]  = i == 0;
                                context.Dictionary["IsLast"]   = i == members.Count - 1;
                                context.Dictionary["ForIndex"] = i;
                                context.Dictionary["ForCount"] = members.Count;
                                var parser = new BlockParser(context, forItem, parsers);
                                resultBuilder.Append(parser.Parse(forBlock));
                            }
                        }
                    }
                    else
                    {
                        blockBuilder.Append(match.Match.Value);
                    }
                    blockStates.Pop();
                    break;

                default:
                    throw new NotSupportedException();
                }
            }
        }