Ejemplo n.º 1
0
            protected override bool ReadContent()
            {
                var blockInfo = new CodeBlockInfo {
                    OuterStart = new TextRange(stream.Position, 0)
                };

                lineStart = stream.Position;

                if (!TryReadSpaces(spaceCount))
                {
                    return(false);
                }

                while (true)
                {
                    var thisLineStart = lineStart;
                    var range         = TryConsumeContentLine();
                    if (range == null)
                    {
                        break;
                    }
                    blockInfo.OuterEnd = new TextRange(range.End, 0);
                    // Get the character count of the indent, which may be different if tabs are involved.
                    var indentSize = range.Start - thisLineStart;
                    range.Expand(-indentSize, 0);
                    ReportArtifact(new CodeLineArtifact(blockInfo, range, indentSize, 0));
                }
                return(true);
            }
Ejemplo n.º 2
0
 static string Caption(CodeBlockInfo block)
 {
     if (string.IsNullOrEmpty(block.Language))
     {
         return("[ Code Block ]");
     }
     return("[ " + block.Language + " Code Block ]");
 }
Ejemplo n.º 3
0
        public IEnumerable <ITagSpan <IOutliningRegionTag> > GetTags(NormalizedSnapshotSpanCollection spans)
        {
            if (!spans.Any())
            {
                yield break;
            }

            var artifacts = artifactsGetter();

            // Start from the first artifact after the start
            // position.  Since code blocks will always have
            // an end-boundary artifact, this will work even
            // if we start in the middle of a code block.
            int i = artifacts.GetFirstItemAfterOrAtPosition(spans[0].Start);

            if (i < 0)
            {
                yield break;
            }

            CodeBlockInfo lastBlock = null;

            for (; i < artifacts.Count; i++)
            {
                var cba = artifacts[i] as ICodeBlockArtifact;

                // Skip artifacts that aren't in code blocks, and
                // those in code blocks we have already returned.
                if (cba == null || cba.BlockInfo == lastBlock)
                {
                    continue;
                }

                lastBlock = cba.BlockInfo;

                // Skip single-line indented code blocks, but not single-line fenced code blocks
                if (lastBlock.CodeLines.Count == 1 && lastBlock.OuterEnd.End == lastBlock.CodeLines[0].End)
                {
                    continue;
                }

                yield return(new TagSpan <IOutliningRegionTag>(
                                 new SnapshotSpan(spans[0].Snapshot, Span.FromBounds(lastBlock.OuterStart.Start, lastBlock.OuterEnd.End)),
                                 tagCreator(
                                     Caption(lastBlock),
                                     lastBlock.CodeLines
                                     .Select(a => a.InnerRange.ToSnapshotSpan(spans[0].Snapshot))
                                     .ToList()  // Force eager evaluation; this query is only enumerated when a tooltip is shown, so we need to grab the snapshot
                                     )
                                 ));

                if (lastBlock.OuterStart.Start > spans.Last().End)
                {
                    break;  // If we have completely passed the requested range, stop.
                }
            }
        }
Ejemplo n.º 4
0
        static string Caption(CodeBlockInfo block)
        {
            if (string.IsNullOrEmpty(block.Language))
            {
                return("[ code block ]");
            }

            return("[ " + block.Language.ToUpperInvariant() + " code block ]");
        }
Ejemplo n.º 5
0
        public CodeLineArtifact(CodeBlockInfo blockInfo, ITextRange range, int leftLength, int rightLength)
            : base(ArtifactTreatAs.Code, range, leftLength, rightLength, MarkdownClassificationTypes.MarkdownCode, true)
        {
            if (blockInfo == null)
            {
                throw new ArgumentNullException("blockInfo");
            }

            BlockInfo = blockInfo;
        }
        public BlockBoundaryArtifact(CodeBlockInfo blockInfo, BoundaryType type)
            : base(ArtifactTreatAs.Code, type == BoundaryType.Start ? blockInfo.OuterStart : blockInfo.OuterEnd, 0, 0, MarkdownClassificationTypes.MarkdownCode, true)
        {
            BlockInfo = blockInfo;
            Boundary = type;

            // Replace the BlockInfo's TextRanges with our created
            // artifacts so that they will be adjusted as the user
            // edits the text. TextRangeCollection shifts existing
            // artifacts as the user types elsewhere.
            if (type == BoundaryType.Start)
                BlockInfo.OuterStart = this;
            else
                BlockInfo.OuterEnd = this;
        }
Ejemplo n.º 7
0
            protected override bool ReadContent()
            {
                SkipSpaces(3);
                var sepStart = stream.Position;

                if (TryConsume("```"))
                {
                    fence = "```";
                }
                else if (TryConsume("~~~"))
                {
                    fence = "~~~";
                }
                else
                {
                    return(false);
                }

                blockInfo = new CodeBlockInfo {
                    OuterStart = TextRange.FromBounds(sepStart, stream.Position)
                };

                var langRange = TryConsumeContentLine();

                if (langRange != null)
                {
                    blockInfo.Language = stream.GetSubstringAt(langRange.Start, langRange.Length);
                }

                while (true)
                {
                    var range = TryConsumeContentLine();
                    if (range == null)
                    {
                        break;
                    }
                    ReportArtifact(new CodeLineArtifact(blockInfo, range, 0, 0));
                }
                // If the stream ended without a closing fence, give an empty end.
                if (blockInfo.OuterEnd == null)
                {
                    blockInfo.OuterEnd = new TextRange(stream.Length, 0);
                }
                return(true);
            }
Ejemplo n.º 8
0
        public BlockBoundaryArtifact(CodeBlockInfo blockInfo, BoundaryType type)
            : base(ArtifactTreatAs.Code, type == BoundaryType.Start ? blockInfo.OuterStart : blockInfo.OuterEnd, 0, 0, MarkdownClassificationTypes.MarkdownCode, true)
        {
            BlockInfo = blockInfo;
            Boundary  = type;

            // Replace the BlockInfo's TextRanges with our created
            // artifacts so that they will be adjusted as the user
            // edits the text. TextRangeCollection shifts existing
            // artifacts as the user types elsewhere.
            if (type == BoundaryType.Start)
            {
                BlockInfo.OuterStart = this;
            }
            else
            {
                BlockInfo.OuterEnd = this;
            }
        }
Ejemplo n.º 9
0
        public void GetArtifacts(ITextProvider text, ArtifactCollection artifactCollection)
        {
            var           parser    = new MarkdownParser(new TabAwareCharacterStream(text));
            CodeBlockInfo lastBlock = null;

            parser.ArtifactFound += (s, e) =>
            {
                var cla = e.Artifact as CodeLineArtifact;
                if (cla != null)
                {
                    if (lastBlock == null || lastBlock != cla.BlockInfo)
                    {
                        if (lastBlock != null)
                        {
                            artifactCollection.Add(new BlockBoundaryArtifact(lastBlock, BoundaryType.End));
                        }

                        lastBlock = cla.BlockInfo;
                        artifactCollection.Add(new BlockBoundaryArtifact(cla.BlockInfo, BoundaryType.Start));
                    }

                    // Don't add artifacts for HTML code lines.
                    //if ((cla.BlockInfo.Language ?? "").StartsWith("htm", StringComparison.OrdinalIgnoreCase))
                    //{
                    //    cla.BlockInfo.IsExtradited = true;
                    //    return;
                    //}
                }
                // If we got a non-block artifact after a block end, add the end marker.
                else if (lastBlock != null && e.Artifact.Start >= lastBlock.OuterEnd.End)
                {
                    artifactCollection.Add(new BlockBoundaryArtifact(lastBlock, BoundaryType.End));
                    lastBlock = null;
                }
                artifactCollection.Add(e.Artifact);
            };
            parser.Parse();
            if (lastBlock != null)
            {
                artifactCollection.Add(new BlockBoundaryArtifact(lastBlock, BoundaryType.End));
            }
        }
Ejemplo n.º 10
0
        public CodeLineArtifact(CodeBlockInfo blockInfo, ITextRange range, int leftLength, int rightLength)
            : base(ArtifactTreatAs.Code, range, leftLength, rightLength, MarkdownClassificationTypes.MarkdownCode, true)
        {
            if (blockInfo == null) throw new ArgumentNullException("blockInfo");

            BlockInfo = blockInfo;
        }
Ejemplo n.º 11
0
            protected override bool ReadContent()
            {
                SkipSpaces(3);
                var sepStart = stream.Position;
                if (TryConsume("```"))
                    fence = "```";
                else if (TryConsume("~~~"))
                    fence = "~~~";
                else
                    return false;

                blockInfo = new CodeBlockInfo { OuterStart = TextRange.FromBounds(sepStart, stream.Position) };

                var langRange = TryConsumeContentLine();
                if (langRange != null)
                    blockInfo.Language = stream.GetSubstringAt(langRange.Start, langRange.Length);

                while (true)
                {
                    var range = TryConsumeContentLine();
                    if (range == null)
                        break;
                    ReportArtifact(new CodeLineArtifact(blockInfo, range, 0, 0));
                }
                // If the stream ended without a closing fence, give an empty end.
                if (blockInfo.OuterEnd == null)
                    blockInfo.OuterEnd = new TextRange(stream.Length, 0);
                return true;
            }
Ejemplo n.º 12
0
 protected override bool ReadContent()
 {
     var blockInfo = new CodeBlockInfo { OuterStart = new TextRange(stream.Position, 0) };
     lineStart = stream.Position;
     if (!TryReadSpaces(spaceCount))
         return false;
     while (true)
     {
         var thisLineStart = lineStart;
         var range = TryConsumeContentLine();
         if (range == null)
             break;
         blockInfo.OuterEnd = new TextRange(range.End, 0);
         // Get the character count of the indent, which may be different if tabs are involved.
         var indentSize = range.Start - thisLineStart;
         range.Expand(-indentSize, 0);
         ReportArtifact(new CodeLineArtifact(blockInfo, range, indentSize, 0));
     }
     return true;
 }