Пример #1
0
        public string Process(Table table, string pattern, string code)
        {
            var output = new StringBuilder();

            if (table.NumRows == 0)
                return "";

            if (string.IsNullOrWhiteSpace(pattern))
                pattern = "$EACH\r\n$row\r\n";

            var scanner = new Scanner(pattern);
            var tokens = scanner.GetAllTokens();

            // Add EACH as default section token if 'tokens' does not start with any section token
            if (tokens[0].Category != TokenCategory.Each &&
                tokens[0].Category != TokenCategory.EachPlus &&
                tokens[0].Category != TokenCategory.Once)
            {
                tokens.Insert(0, new Token(TokenCategory.Each));
            }

            var tokenList = new TokenList(tokens);
            do
            {
                int rowNoStart;
                int rowNoSentinel;
                MapSectionTypeToRowNumbers(tokenList, table, out rowNoStart, out rowNoSentinel);

                ProcessSection(table, rowNoStart, rowNoSentinel, tokenList, code, output);
            } while (tokenList.Current.Category != TokenCategory.EndOfInput);

            return output.ToString();
        }
Пример #2
0
        private void ProcessSection(Table table, int rowNoStart, int rowNoSentinel, TokenList tokens, string code, StringBuilder output)
        {
            var tokensSectionStartIndex = tokens.Index;
            for (var rowNo = rowNoStart; rowNo < rowNoSentinel; ++rowNo)
            {
                var endOfSection = false;
                tokens.Index = tokensSectionStartIndex; // reset to 1st token in section 
                while (true)
                {
                    var token = tokens.Values[tokens.Index++];

                    string value;
                    int colIndex;
                    switch (token.Category)
                    {
                        case TokenCategory.Text:
                            output.Append(token.Value);
                            break;

                        case TokenCategory.Dollar:
                            output.Append("$");
                            break;

                        case TokenCategory.HeaderIndex:
                            colIndex = int.Parse(token.Value);
                            CheckColIndex(table, colIndex);
                            value = table.RowFields[0][colIndex];
                            output.Append(value);
                            break;
                        case TokenCategory.InvertedHeaderIndex:
                            colIndex = table.NumFields - 1 - int.Parse(token.Value);
                            CheckColIndex(table, colIndex);
                            value = table.RowFields[0][colIndex];
                            output.Append(value);
                            break;
                        case TokenCategory.FieldIndex:
                            colIndex = int.Parse(token.Value);
                            CheckColIndex(table, colIndex);
                            value = table.RowFields[rowNo][colIndex];
                            output.Append(value);
                            break;
                        case TokenCategory.InvertedFieldIndex:
                            colIndex = table.NumFields - 1 - int.Parse(token.Value);
                            CheckColIndex(table, colIndex);
                            value = table.RowFields[rowNo][colIndex];
                            output.Append(value);
                            break;

                        case TokenCategory.Header:
                            output.Append(table.Header);
                            break;
                        case TokenCategory.Row:
                            output.Append(table.Rows[rowNo]);
                            break;
                        case TokenCategory.RowNum:
                            output.Append(rowNo);
                            break;
                        case TokenCategory.RowNumOne:
                            output.Append(rowNo + 1);
                            break;
                        case TokenCategory.NumFields:
                            output.Append(table.NumFields);
                            break;
                        case TokenCategory.NumRows:
                            output.Append(table.NumRows);
                            break;

                        case TokenCategory.MethodCall:
                            var pos = token.Value.IndexOfAny("([{<".ToCharArray());
                            var methodName = token.Value.Substring(0, pos);
                            var args = token.Value.Substring(pos + 1, token.Value.Length - pos - 2);

                            // process args
                            var argsOutput = new StringBuilder();
                            var argsScanner = new Scanner(args);
                            var argsTokens = new TokenList(argsScanner.GetAllTokens());
                            ProcessSection(table, rowNo, rowNo + 1, argsTokens, "", argsOutput);
                            var encodedArgs = EncodeQuotationMark(argsOutput.ToString());

                            var methodCall = $"{methodName}({encodedArgs})"; // without terminating ";" to signal scripting engine that it should return the value!

                            var result = ScriptCSharpCode(code + methodCall);

                            output.Append(result);
                            break;

                        case TokenCategory.Once:
                        case TokenCategory.Each:
                        case TokenCategory.EachPlus:
                        case TokenCategory.EndOfInput:
                            tokens.Index--;
                            endOfSection = true;
                            break;

                        default:
                            throw new Exception("No code implemented for token.Category=" + token.Category);
                    }

                    if (endOfSection)
                        break;
                }
            }
        }
Пример #3
0
 public void CopyPatternScannerTest()
 {
     var scanner = new Scanner(CopyPattern);
     var tokens = scanner.GetAllTokens();
     Assert.NotNull(tokens);
     Assert.Equal(7, tokens.Count);
     Assert.Equal(TokenCategory.FieldIndex, tokens[0].Category);
     Assert.Equal("0", tokens[0].Value);
     Assert.Equal(TokenCategory.Text, tokens[1].Category);
     Assert.Equal(",", tokens[1].Value);
     Assert.Equal(TokenCategory.FieldIndex, tokens[2].Category);
     Assert.Equal("1", tokens[2].Value);
     Assert.Equal(TokenCategory.Text, tokens[3].Category);
     Assert.Equal(",", tokens[3].Value);
     Assert.Equal(TokenCategory.FieldIndex, tokens[4].Category);
     Assert.Equal("2", tokens[4].Value);
     Assert.Equal(TokenCategory.Text, tokens[5].Category);
     Assert.Equal("\r\n", tokens[5].Value);
     Assert.Equal(TokenCategory.EndOfInput, tokens[tokens.Count - 1].Category);
 }
Пример #4
0
 public void FullPatternScannerTest()
 {
     var scanner = new Scanner(AllTokenPattern);
     var tokens = scanner.GetAllTokens();
     Assert.NotNull(tokens);
     //Assert.Equal(_allTokenReference.Count, tokens.Count);
     for (var i = 0; i < _allTokenReference.Count; ++i)
     {
         var token = tokens[i];
         Assert.Equal(_allTokenReference[i].Category, token.Category);
         Assert.Equal(_allTokenReference[i].Value, token.Value);
         Assert.Equal(_allTokenReference[i].Value, token.Value);
     }
 }
Пример #5
0
 public void EmptyInputScannerTest()
 {
     var scanner = new Scanner("");
     var tokens = scanner.GetAllTokens();
     Assert.NotNull(tokens);
     Assert.Equal(1, tokens.Count);
     Assert.Equal(TokenCategory.EndOfInput, tokens[0].Category);
 }