/// <summary>
        /// Gets a normalized title derived from the file path.
        /// </summary>
        /// <returns>A normalized title.</returns>
        public string GetTitle()
        {
            // Get the filename, unless an index file, then get containing directory
            ReadOnlyMemory <char> titleMemory = Segments[Segments.Length - 1];

            if (titleMemory.StartsWith(IndexFileName) && Segments.Length > 1)
            {
                titleMemory = Segments[Segments.Length - 2];
            }

            // Strip the extension(s)
            int extensionIndex = titleMemory.Span.IndexOf('.');

            if (extensionIndex > 0)
            {
                titleMemory = titleMemory.Slice(0, extensionIndex);
            }

            // Decode URL escapes
            string title = WebUtility.UrlDecode(titleMemory.ToString());

            // Replace special characters with spaces
            title = title.Replace('-', ' ').Replace('_', ' ');

            // Join adjacent spaces
            while (title.IndexOf("  ", StringComparison.Ordinal) > 0)
            {
                title = title.Replace("  ", " ");
            }

            // Capitalize
            return(CultureInfo.CurrentCulture.TextInfo.ToTitleCase(title));
        }
Example #2
0
        // {{#if ...}}
        //    ^
        public static ReadOnlyMemory <char> ParseTemplateScriptBlock(this ReadOnlyMemory <char> literal, ScriptContext context, out PageBlockFragment blockFragment)
        {
            literal = literal.ParseVarName(out var blockNameSpan);

            PageBlockFragment statement;
            var blockName  = blockNameSpan.ToString();
            var endBlock   = "{{/" + blockName + "}}";
            var endExprPos = literal.IndexOf("}}");

            if (endExprPos == -1)
            {
                throw new SyntaxErrorException($"Unterminated '{blockName}' block expression, near '{literal.DebugLiteral()}'");
            }

            var argument = literal.Slice(0, endExprPos).Trim();

            literal = literal.Advance(endExprPos + 2);

            var language = context.ParseAsLanguage.TryGetValue(blockName, out var lang)
                ? lang
                : ScriptTemplate.Language;

            if (language.Name == ScriptVerbatim.Language.Name)
            {
                var endBlockPos = literal.IndexOf(endBlock);
                if (endBlockPos == -1)
                {
                    throw new SyntaxErrorException($"Unterminated end block '{endBlock}'");
                }

                var body = literal.Slice(0, endBlockPos);
                literal = literal.Advance(endBlockPos + endBlock.Length).TrimFirstNewLine();

                blockFragment = language.ParseVerbatimBlock(blockName, argument, body);
                return(literal);
            }

            literal = literal.ParseTemplateBody(blockNameSpan, out var bodyText);
            var bodyFragments = language.Parse(context, bodyText);

            var elseBlocks = new List <PageElseBlock>();

            while (literal.StartsWith("{{else"))
            {
                literal = literal.ParseTemplateElseBlock(blockName, out var elseArgument, out var elseBody);

                var elseBlock = new PageElseBlock(elseArgument, language.Parse(context, elseBody));
                elseBlocks.Add(elseBlock);
            }

            literal = literal.Advance(2 + 1 + blockName.Length + 2);

            //remove new line after partial block end tag
            literal = literal.TrimFirstNewLine();

            blockFragment = new PageBlockFragment(blockName, argument, bodyFragments, elseBlocks);

            return(literal);
        }
        public Neo.VM.Types.StackItem?Evaluate(ReadOnlyMemory <char> expression)
        {
            bool TryGetKeyHash(out int value)
            {
                if (expression.Length >= 18 &&
                    expression.StartsWith("#storage[") &&
                    expression.Span[17] == ']' &&
                    expression.Span[18] == '.' &&
                    int.TryParse(expression.Slice(9, 8).Span, NumberStyles.HexNumber, null, out value))
                {
                    return(true);
                }

                value = default;
                return(false);
            }

            if (TryGetKeyHash(out var keyHash) &&
                TryFind(keyHash, out var tuple))
            {
                var remain = expression.Slice(19);
                if (remain.Span.SequenceEqual("key"))
                {
                    return(tuple.key);
                }
                else if (remain.Span.SequenceEqual("item"))
                {
                    return(tuple.item.Value);
                }
                else if (remain.Span.SequenceEqual("isConstant"))
                {
                    return(tuple.item.IsConstant);
                }
            }

            return(null);

            bool TryFind(int hashCode, out (ReadOnlyMemory <byte> key, StorageItem item) tuple)
            {
                foreach (var(key, item) in GetStorages())
                {
                    var keyHashCode = key.Span.GetSequenceHashCode();
                    if (hashCode == keyHashCode)
                    {
                        tuple = (key, item);
                        return(true);
                    }
                }

                tuple = default;
                return(false);
            }
        }
            static bool TryGetKeyHash(ReadOnlyMemory <char> expression, out int value)
            {
                if (expression.Length >= 18 &&
                    expression.StartsWith(DebugSession.STORAGE_PREFIX) &&
                    expression.Span[8] == '[' &&
                    expression.Span[17] == ']' &&
                    expression.Span[18] == '.' &&
                    int.TryParse(expression.Slice(9, 8).Span, NumberStyles.HexNumber, null, out value))
                {
                    return(true);
                }

                value = default;
                return(false);
            }
        // #if ...
        //  ^
        public static ReadOnlyMemory <char> ParseCodeScriptBlock(this ReadOnlyMemory <char> literal, ScriptContext context,
                                                                 out PageBlockFragment blockFragment)
        {
            literal = literal.ParseVarName(out var blockNameSpan);
            var endArgumentPos = literal.IndexOf('\n');
            var argument       = literal.Slice(0, endArgumentPos).Trim();

            literal = literal.Slice(endArgumentPos + 1);

            var blockName = blockNameSpan.ToString();

            var language = context.ParseAsLanguage.TryGetValue(blockName, out var lang)
                ? lang
                : ScriptCode.Language;

            if (language.Name == ScriptVerbatim.Language.Name)
            {
                literal = literal.ParseCodeBody(blockNameSpan, out var body);
                body    = body.ChopNewLine();

                blockFragment = language.ParseVerbatimBlock(blockName, argument, body);
                return(literal);
            }

            literal = literal.ParseCodeBody(blockNameSpan, out var bodyText);
            var bodyFragments = language.Parse(context, bodyText);

            var elseBlocks = new List <PageElseBlock>();

            literal = literal.AdvancePastWhitespace();
            while (literal.StartsWith("else"))
            {
                literal = literal.ParseCodeElseBlock(blockNameSpan, out var elseArgument, out var elseBody);

                var elseBlock = new PageElseBlock(elseArgument, language.Parse(context, elseBody));
                elseBlocks.Add(elseBlock);

                literal = literal.AdvancePastWhitespace();
            }

            blockFragment = new PageBlockFragment(blockName, argument, bodyFragments, elseBlocks);

            return(literal);
        }
Example #6
0
 public static bool CodeIsInvalid(IReleaseSpec spec, ReadOnlyMemory <byte> output)
 {
     return(spec.IsEip3541Enabled && output.Length >= 1 && output.StartsWith(InvalidStartingCodeByte));
 }
        // {{#if ...}}
        //    ^
        public static ReadOnlyMemory <char> ParseTemplateScriptBlock(this ReadOnlyMemory <char> literal, ScriptContext context, out PageBlockFragment blockFragment)
        {
            literal = literal.ParseVarName(out var blockNameSpan);

            PageBlockFragment statement;
            var blockName  = blockNameSpan.ToString();
            var endBlock   = "{{/" + blockName + "}}";
            var endExprPos = literal.IndexOf("}}");

            if (endExprPos == -1)
            {
                throw new SyntaxErrorException($"Unterminated '{blockName}' block expression, near '{literal.DebugLiteral()}'");
            }

            var blockExpr = literal.Slice(0, endExprPos).Trim();

            literal = literal.Advance(endExprPos + 2);

            if (context.ParseAsVerbatimBlock.Contains(blockName))
            {
                var endBlockPos = literal.IndexOf(endBlock);
                if (endBlockPos == -1)
                {
                    throw new SyntaxErrorException($"Unterminated end block '{endBlock}'");
                }

                var blockBody = literal.Slice(0, endBlockPos);
                literal = literal.Advance(endBlockPos + endBlock.Length).TrimFirstNewLine();

                var body = new List <PageFragment> {
                    new PageStringFragment(blockBody)
                };
                blockFragment = new PageBlockFragment(blockName, blockExpr, body);

                return(literal);
            }
            else
            {
                var parseAsCode = context.ParseAsCodeBlock.Contains(blockName);

                literal = literal.ParseTemplateBody(blockNameSpan, out var bodyText);
                List <PageFragment> bodyFragments  = null;
                JsBlockStatement    bodyStatements = null;

                if (!parseAsCode)
                {
                    bodyFragments = context.ParseTemplate(bodyText);
                }
                else
                {
                    bodyStatements = context.ParseCode(bodyText);
                }

                var elseBlocks = new List <PageElseBlock>();
                while (literal.StartsWith("{{else"))
                {
                    literal = literal.ParseTemplateElseBlock(blockName, out var elseArgument, out var elseBody);

                    var elseBlock = !parseAsCode
                        ? new PageElseBlock(elseArgument, context.ParseTemplate(elseBody))
                        : new PageElseBlock(elseArgument, context.ParseCode(elseBody));
                    elseBlocks.Add(elseBlock);
                }

                literal = literal.Advance(2 + 1 + blockName.Length + 2);

                //remove new line after partial block end tag
                literal = literal.TrimFirstNewLine();

                blockFragment = !parseAsCode
                    ? new PageBlockFragment(blockName, blockExpr, bodyFragments, elseBlocks)
                    : new PageBlockFragment(blockName, blockExpr, bodyStatements, elseBlocks);

                return(literal);
            }
        }