Ejemplo n.º 1
0
        static void FormatInlines(Settings settings, CMInline cmInline, InlineCollection wdInlines)
        {
            for (; cmInline != null; cmInline = cmInline.NextSibling)
            {
                switch (cmInline.Tag)
                {
                case InlineTag.Emphasis:
                    var wdItalic = new Italic();
                    FormatInlines(settings, cmInline.FirstChild, wdItalic.Inlines);
                    wdInlines.Add(wdItalic);
                    break;

                case InlineTag.Strong:
                    var wdBold = new Bold();
                    FormatInlines(settings, cmInline.FirstChild, wdBold.Inlines);
                    wdInlines.Add(wdBold);
                    break;

                case InlineTag.Link:
                    var wdLink = new Hyperlink();
                    var url    = cmInline.TargetUrl;
                    if (settings.UrlResolver != null)
                    {
                        url = settings.UrlResolver(url);
                    }
                    wdLink.NavigateUri = new Uri(url);
                    FormatInlines(settings, cmInline.FirstChild, wdLink.Inlines);
                    wdInlines.Add(wdLink);
                    break;

                case InlineTag.Placeholder:
                    var placeholder = cmInline.TargetUrl;
                    if (settings.PlaceholderResolver != null)
                    {
                        placeholder = settings.PlaceholderResolver(placeholder);
                    }
                    wdInlines.Add(new Run(placeholder));
                    break;

                case InlineTag.SoftBreak:
                    wdInlines.Add(new Run(" "));
                    break;

                case InlineTag.LineBreak:
                    wdInlines.Add(new LineBreak());
                    break;

                case InlineTag.String:
                    wdInlines.Add(new Run(cmInline.LiteralContent));
                    break;

                default:
                    throw new NotImplementedException($"InlineTag.{cmInline.Tag}");
                }
            }
        }
Ejemplo n.º 2
0
 private static void PrintPosition(bool enabled, TextWriter writer, Inline inline)
 {
     if (enabled)
     {
         writer.Write(" [");
         writer.Write(inline.SourcePosition);
         writer.Write('-');
         writer.Write(inline.SourceLastPosition);
         writer.Write(']');
     }
 }
Ejemplo n.º 3
0
 public static IEnumerable<Inline> EnumerateInlines(Inline inline)
 {
     if (inline == null) yield break;
     var stack = new Stack<Inline>();
     stack.Push(inline);
     while (stack.Any())
     {
         var next = stack.Pop();
         yield return next;
         if (next.NextSibling != null) stack.Push(next.NextSibling);
         if (next.FirstChild != null) stack.Push(next.FirstChild);
     }
 }
Ejemplo n.º 4
0
        private void HandleImage(Inline inline, IAddChild parent)
        {
            NoteFile  nf     = CurrentNote.Files.FirstOrDefault(n => n.FileName == inline.TargetUrl);
            Paragraph result = parent as Paragraph;

            if (result == null)
            {
                result = new Paragraph();
                parent.AddChild(result);
            }

            if (nf != null && File.Exists(nf.FullName))
            {
                if (!string.IsNullOrWhiteSpace(inline.LiteralContent))
                {
                    result.ToolTip = inline.LiteralContent;
                }

                var imageUri = new Uri(nf.FullName, UriKind.Absolute);

                var imgTemp = new BitmapImage();
                imgTemp.BeginInit();
                imgTemp.CacheOption   = BitmapCacheOption.OnLoad;
                imgTemp.CreateOptions = BitmapCreateOptions.IgnoreImageCache;
                imgTemp.UriSource     = imageUri;
                imgTemp.EndInit();

                var image = new Image
                {
                    Source           = imgTemp,
                    Stretch          = Stretch.None,
                    StretchDirection = StretchDirection.Both,
                    MaxWidth         = imgTemp.Width,
                    MaxHeight        = imgTemp.Height
                };

                if (ImageStyle != null)
                {
                    image.Style = ImageStyle;
                }


                result.Inlines.Add(image);
            }
            else if (nf != null)
            {
                result.Inlines.Add(new Run("Missing file: " + nf.FullName));
            }
        }
Ejemplo n.º 5
0
        internal override async Task WriteConceptualLinkAsync(Inline inline)
        {
            if (GetSectionState() != SectionState.SeeAlso)
            {
                await base.WriteConceptualLinkAsync(inline);
                return;
            }

            var target = GetConceptualLinkTarget(inline.TargetUrl);
            if (!target.StartsWith("#"))
                return;

            var termId = target.TrimStart('#');
            await WriteStartElementAsync("relatedEntry");
            await WriteAttributeStringAsync("termId", termId);
            await WriteEndElementAsync(); //relatedEntry
        }
Ejemplo n.º 6
0
        private async Task WriteInlineAsync(Inline inline)
        {
            switch (inline.Tag)
            {
                case InlineTag.String:
                    await WriteStringAsync(inline);
                    break;

                case InlineTag.Emphasis:
                    await WriteWeakEmphasisAsync(inline);
                    break;

                case InlineTag.Strong:
                    await WriteStrongEmphasisAsync(inline);
                    break;

                default:
                    throw new InvalidOperationException("Unexpected inline tag: " + inline.Tag);
            }
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Writes the specified inline element to the output stream. Does not write the child nodes, instead
        /// the <paramref name="ignoreChildNodes"/> is used to notify the caller whether it should recurse
        /// into the child nodes.
        /// </summary>
        /// <param name="inline">The inline element to be written to the output stream.</param>
        /// <param name="isOpening">Specifies whether the inline element is being opened (or started).</param>
        /// <param name="isClosing">Specifies whether the inline element is being closed. If the inline does not
        /// have child nodes, then both <paramref name="isClosing"/> and <paramref name="isOpening"/> can be
        /// <see langword="true"/> at the same time.</param>
        /// <param name="ignoreChildNodes">Instructs the caller whether to skip processing of child nodes or not.</param>
        protected virtual void WriteInline(Inline inline, bool isOpening, bool isClosing, out bool ignoreChildNodes)
        {
            if (RenderPlainTextInlines.Peek())
            {
                switch (inline.Tag)
                {
                    case InlineTag.String:
                    case InlineTag.Code:
                    case InlineTag.RawHtml:
                        WriteEncodedHtml(inline.LiteralContentValue);
                        break;

                    case InlineTag.LineBreak:
                    case InlineTag.SoftBreak:
                        WriteLine();
                        break;

                    case InlineTag.Image:
                        if (isOpening)
                            RenderPlainTextInlines.Push(true);

                        if (isClosing)
                        {
                            RenderPlainTextInlines.Pop();

                            if (!RenderPlainTextInlines.Peek())
                                goto useFullRendering;
                        }

                        break;

                    case InlineTag.Link:
                    case InlineTag.Strong:
                    case InlineTag.Emphasis:
                    case InlineTag.Strikethrough:
                    case InlineTag.Placeholder:
                        break;

                    default:
                        throw new CommonMarkException("Inline type " + inline.Tag + " is not supported.", inline);
                }

                ignoreChildNodes = false;
                return;
            }

            useFullRendering:

            switch (inline.Tag)
            {
                case InlineTag.String:
                    ignoreChildNodes = true;
                    if (Settings.TrackSourcePosition)
                    {
                        Write("<span");
                        WritePositionAttribute(inline);
                        Write('>');
                        WriteEncodedHtml(inline.LiteralContentValue);
                        Write("</span>");
                    }
                    else
                    {
                        WriteEncodedHtml(inline.LiteralContentValue);
                    }

                    break;

                case InlineTag.LineBreak:
                    ignoreChildNodes = true;
                    WriteLine("<br />");
                    break;

                case InlineTag.SoftBreak:
                    ignoreChildNodes = true;
                    if (Settings.RenderSoftLineBreaksAsLineBreaks)
                        WriteLine("<br />");
                    else
                        WriteLine();
                    break;

                case InlineTag.Code:
                    ignoreChildNodes = true;
                    Write("<code");
                    if (Settings.TrackSourcePosition) WritePositionAttribute(inline);
                    Write('>');
                    WriteEncodedHtml(inline.LiteralContentValue);
                    Write("</code>");
                    break;

                case InlineTag.RawHtml:
                    ignoreChildNodes = true;
                    // cannot output source position for HTML blocks
                    Write(inline.LiteralContentValue);
                    break;

                case InlineTag.Link:
                    ignoreChildNodes = false;

                    if (isOpening)
                    {
                        Write("<a href=\"");
                        var uriResolver = Settings.UriResolver;
                        if (uriResolver != null)
                            WriteEncodedUrl(uriResolver(inline.TargetUrl));
                        else
                            WriteEncodedUrl(inline.TargetUrl);

                        Write('\"');
                        if (inline.LiteralContentValue.Length > 0)
                        {
                            Write(" title=\"");
                            WriteEncodedHtml(inline.LiteralContentValue);
                            Write('\"');
                        }

                        if (Settings.TrackSourcePosition) WritePositionAttribute(inline);

                        Write('>');
                    }

                    if (isClosing)
                    {
                        Write("</a>");
                    }

                    break;

                case InlineTag.Image:
                    ignoreChildNodes = false;

                    if (isOpening)
                    {
                        Write("<img src=\"");
                        var uriResolver = Settings.UriResolver;
                        if (uriResolver != null)
                            WriteEncodedUrl(uriResolver(inline.TargetUrl));
                        else
                            WriteEncodedUrl(inline.TargetUrl);

                        Write("\" alt=\"");

                        if (!isClosing)
                            RenderPlainTextInlines.Push(true);
                    }

                    if (isClosing)
                    {
                        // this.RenderPlainTextInlines.Pop() is done by the plain text renderer above.

                        Write('\"');
                        if (inline.LiteralContentValue.Length > 0)
                        {
                            Write(" title=\"");
                            WriteEncodedHtml(inline.LiteralContentValue);
                            Write('\"');
                        }

                        if (Settings.TrackSourcePosition) WritePositionAttribute(inline);
                        Write(" />");
                    }

                    break;

                case InlineTag.Strong:
                    ignoreChildNodes = false;

                    if (isOpening)
                    {
                        Write("<strong");
                        if (Settings.TrackSourcePosition) WritePositionAttribute(inline);
                        Write('>');
                    }

                    if (isClosing)
                    {
                        Write("</strong>");
                    }
                    break;

                case InlineTag.Emphasis:
                    ignoreChildNodes = false;

                    if (isOpening)
                    {
                        Write("<em");
                        if (Settings.TrackSourcePosition) WritePositionAttribute(inline);
                        Write('>');
                    }

                    if (isClosing)
                    {
                        Write("</em>");
                    }
                    break;

                case InlineTag.Strikethrough:
                    ignoreChildNodes = false;

                    if (isOpening)
                    {
                        Write("<del");
                        if (Settings.TrackSourcePosition) WritePositionAttribute(inline);
                        Write('>');
                    }

                    if (isClosing)
                    {
                        Write("</del>");
                    }
                    break;

                case InlineTag.Placeholder:
                    ignoreChildNodes = false;

                    if (isOpening)
                    {
                        string placeholderSubstitute = null;

                        try
                        {
                            placeholderSubstitute = (_placeholderResolver != null) ? _placeholderResolver(inline.TargetUrl) : null;
                        }
                        catch (Exception ex)
                        {
                            throw new CommonMarkException("An error occurred while resolving a placeholder.", ex);
                        }

                        if (placeholderSubstitute != null)
                        {
                            ignoreChildNodes = true;

                            if (Settings.TrackSourcePosition) WritePositionAttribute(inline);
                            Write(placeholderSubstitute);
                            _endPlaceholders.Push('\0');
                        }
                        else
                        {
                            ignoreChildNodes = false;
                            Write("[");
                            _endPlaceholders.Push(']');
                        }
                    }
                    if (isClosing)
                    {
                        var closingChar = _endPlaceholders.Pop();

                        if (closingChar != '\0')
                        {
                            Write(closingChar);
                        }
                    }
                    break;

                default:
                    throw new CommonMarkException("Inline type " + inline.Tag + " is not supported.", inline);
            }
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="EnumeratorEntry"/> class.
 /// </summary>
 /// <param name="opening">Specifies if this instance represents the opening of the inline element.</param>
 /// <param name="closing">Specifies if this instance represents the closing of the inline element (returned by the
 /// enumerator after the children have been enumerated). Both <paramref name="closing"/> and <paramref name="opening"/>
 /// can be specified at the same time if there are no children for the <paramref name="inline"/> element.</param>
 /// <param name="inline">The inlien element being returned from the enumerator.</param>
 public EnumeratorEntry(bool opening, bool closing, Inline inline)
 {
     this.IsOpening = opening;
     this.IsClosing = closing;
     this.Inline = inline;
 }
Ejemplo n.º 9
0
 internal static Inline CreateLink(Inline label, string url, string title)
 {
     return new Inline()
     {
         Tag = InlineTag.Link,
         FirstChild = label,
         TargetUrl = url,
         LiteralContent = title
     };
 }
Ejemplo n.º 10
0
        private void BlocksToXamlInner(FlowDocument parent, Block block, CommonMarkSettings settings)
        {
            _checkBoxNumber = 0;
            var  stack          = new Stack <BlockStackEntry>();
            var  inlineStack    = new Stack <InlineStackEntry>();
            bool stackTight     = false;
            bool tight          = false;
            bool trackPositions = settings.TrackSourcePosition;
            int  x;

            IAddChild blockParent = parent;

            while (block != null)
            {
                var       visitChildren = false;
                IAddChild lastParent    = null;

                switch (block.Tag)
                {
                case BlockTag.Document:
                    stackTight    = false;
                    visitChildren = true;
                    lastParent    = parent;
                    break;

                case BlockTag.Paragraph:
                    if (tight)
                    {
                        InlinesToXaml(blockParent, block.InlineContent, settings, inlineStack);
                    }
                    else
                    {
                        Paragraph paragraph = new Paragraph();
                        if (trackPositions)
                        {
                            PrintPosition(paragraph, block);
                        }
                        InlinesToXaml(paragraph, block.InlineContent, settings, inlineStack);
                        blockParent.AddChild(paragraph);
                    }
                    break;

                case BlockTag.BlockQuote:
                    Section blockquoteParagraph = new Section();
                    if (trackPositions)
                    {
                        PrintPosition(blockquoteParagraph, block);
                    }

                    if (QuoteStyle != null)
                    {
                        blockquoteParagraph.Style = QuoteStyle;
                    }

                    blockParent.AddChild(blockquoteParagraph);
                    lastParent  = blockParent;
                    blockParent = blockquoteParagraph;

                    stackTight    = true;
                    visitChildren = true;
                    break;

                case BlockTag.ListItem:

                    stackTight = tight;

                    if (block.ListData != null && block.ListData.ListType == ListType.TaskList)
                    {
                        BlockUIContainer ctnr = (BlockUIContainer)blockParent;
                        StackPanel       sp   = (StackPanel)ctnr.Child;

                        visitChildren = false;
                        TextBlock spcb = new TextBlock();
                        spcb.Style = TodoTextStyle;
                        Inline checkBoxInline = block.FirstChild?.InlineContent;
                        if (checkBoxInline != null)
                        {
                            InlinesToXaml(spcb, checkBoxInline, settings, inlineStack);
                        }

                        CheckBox bt = new CheckBox
                        {
                            IsChecked = block.TaskListItemIsChecked,
                            Content   = spcb,
                            Tag       = _checkBoxNumber
                        };
                        bt.CommandParameter = bt;
                        bt.Command          = CheckBoxCheckedCommand;
                        bt.Style            = TodoCheckBoxStyle;

                        sp.Children.Add(bt);

                        //TODO: Add child stack panel and add block.FirstChild.NextSibling

                        _checkBoxNumber++;
                    }
                    else
                    {
                        ListItem listItem = new ListItem();
                        if (ListItemStyle != null)
                        {
                            listItem.Style = ListItemStyle;
                        }

                        if (trackPositions)
                        {
                            PrintPosition(listItem, block);
                        }

                        blockParent.AddChild(listItem);

                        lastParent    = blockParent;
                        blockParent   = listItem;
                        visitChildren = true;
                    }

                    break;

                case BlockTag.List:
                    var       data = block.ListData;
                    IAddChild list;
                    if (data.ListType == ListType.TaskList)
                    {
                        StackPanel sp = new StackPanel();
                        list = new BlockUIContainer(sp);
                    }
                    else
                    {
                        List theList = new List();
                        list = theList;
                        theList.MarkerStyle = data.ListType == ListType.Bullet ? TextMarkerStyle.Disc : TextMarkerStyle.Decimal;

                        if (ListStyle != null)
                        {
                            theList.Style = ListStyle;
                        }
                    }

                    if (trackPositions)
                    {
                        PrintPosition((FrameworkContentElement)list, block);
                    }

                    // TODO: Check if first child starts with [ ] then it is a todo-list item
                    // TODO: Set list.StartIndex if > 1

                    blockParent.AddChild(list);
                    lastParent  = blockParent;
                    blockParent = list;

                    stackTight    = data.IsTight;
                    visitChildren = true;
                    break;

                case BlockTag.AtxHeading:
                case BlockTag.SetextHeading:
                    Paragraph headerParagraph = new Paragraph();
                    if (trackPositions)
                    {
                        PrintPosition(headerParagraph, block);
                    }

                    InlinesToXaml(headerParagraph, block.InlineContent, settings, inlineStack);

                    x = block.Heading.Level;

                    switch (x)
                    {
                    case 1:
                        headerParagraph.Style = Heading1Style;
                        break;

                    case 2:
                        headerParagraph.Style = Heading2Style;
                        break;

                    case 3:
                        headerParagraph.Style = Heading3Style;
                        break;

                    case 4:
                        headerParagraph.Style = Heading4Style;
                        break;

                    default:
                        headerParagraph.Style = Heading1Style;
                        break;
                    }

                    blockParent.AddChild(headerParagraph);

                    break;

                case BlockTag.IndentedCode:
                case BlockTag.FencedCode:
                    Paragraph codeblockParagraph = new Paragraph();

                    if (trackPositions)
                    {
                        PrintPosition(codeblockParagraph, block);
                    }

                    if (CodeBlockStyle != null)
                    {
                        codeblockParagraph.Style = CodeBlockStyle;
                    }

                    var info = block.FencedCodeData == null ? null : block.FencedCodeData.Info;
                    if (info != null && info.Length > 0)
                    {
                        //x = info.IndexOf(' ');
                        //if (x == -1)
                        //	x = info.Length;

                        //parent.WriteConstant(" class=\"language-");
                        //EscapeHtml(new StringPart(info, 0, x), parent);
                        //parent.Write('\"');
                    }

                    EscapeHtml(block.StringContent, codeblockParagraph);

                    blockParent.AddChild(codeblockParagraph);
                    break;

                case BlockTag.HtmlBlock:
                    // cannot output source position for HTML blocks
                    // block.StringContent.WriteTo(parent);

                    //TODO: Unable to convert html to

                    break;

                case BlockTag.ThematicBreak:
                    var line = new Line()
                    {
                        X2 = 1, StrokeThickness = 1.0
                    };
                    var container = new BlockUIContainer(line);
                    if (trackPositions)
                    {
                        PrintPosition(container, block);
                    }

                    if (LineStyle != null)
                    {
                        line.Style = LineStyle;
                    }

                    blockParent.AddChild(container);
                    break;

                case BlockTag.Table:
                    WriteTable(block, blockParent, settings, inlineStack);
                    break;

                case BlockTag.ReferenceDefinition:
                    break;

                default:
                    throw new CommonMarkException("Block type " + block.Tag + " is not supported.", block);
                }

                if (visitChildren)
                {
                    stack.Push(new BlockStackEntry(lastParent, block.NextSibling, tight));

                    tight = stackTight;
                    block = block.FirstChild;
                }
                else if (block.NextSibling != null)
                {
                    block = block.NextSibling;
                }
                else
                {
                    block = null;
                }

                while (block == null && stack.Count > 0)
                {
                    var entry = stack.Pop();

                    blockParent = entry.Parent;
                    tight       = entry.IsTight;
                    block       = entry.Target;
                }
            }
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Writes the inline list to the given parent as HTML code.
        /// </summary>
        private void InlinesToXaml(IAddChild parent, Inline inline, CommonMarkSettings settings, Stack <InlineStackEntry> stack)
        {
            var  uriResolver     = settings.UriResolver;
            bool withinLink      = false;
            bool stackWithinLink = false;
            bool trackPositions  = settings.TrackSourcePosition;

            IAddChild blockParent = parent;

            if (blockParent is ListItem || blockParent is Section || blockParent is TableCell)
            {
                Paragraph p = new Paragraph();
                blockParent.AddChild(p);
                blockParent = p;
            }

            while (inline != null)
            {
                var       visitChildren = false;
                IAddChild lastParent    = null;

                switch (inline.Tag)
                {
                case InlineTag.String:
                    //if (inline.LiteralContent.StartsWith("[ ]") || inline.LiteralContent.StartsWith("[x]"))
                    //{
                    //	CheckBox bt = new CheckBox
                    //	{
                    //		IsChecked = inline.LiteralContent.Contains("[x]"),
                    //		Content = inline.LiteralContent.Substring(2),
                    //		Tag = _checkBoxNumber
                    //	};
                    //	bt.CommandParameter = bt;
                    //	bt.Command = CheckBoxCheckedCommand;
                    //	bt.Style = TodoCheckBoxStyle;
                    //	blockParent.AddChild(new BlockUIContainer(bt));
                    //	_checkBoxNumber++;
                    //}
                    //else
                    blockParent.AddText(inline.LiteralContent);
                    break;

                case InlineTag.LineBreak:
                    blockParent.AddChild(new LineBreak());
                    break;

                case InlineTag.SoftBreak:
                    if (settings.RenderSoftLineBreaksAsLineBreaks)
                    {
                        blockParent.AddChild(new LineBreak());
                    }
                    break;

                case InlineTag.Code:

                    Span codeSpan = new Span(new Run(inline.LiteralContent));
                    if (InlineCodeStyle != null)
                    {
                        codeSpan.Style = InlineCodeStyle;
                    }

                    blockParent.AddChild(codeSpan);

                    break;

                case InlineTag.RawHtml:
                    // cannot output source position for HTML blocks
                    blockParent.AddText(inline.LiteralContent);
                    break;

                case InlineTag.Link:
                    if (withinLink)
                    {
                        //parent.Write('[');
                        //stackLiteral = "]";
                        stackWithinLink = true;
                        visitChildren   = true;
                    }
                    else
                    {
                        Hyperlink hyperlink = new Hyperlink();

                        if (LinkStyle != null)
                        {
                            hyperlink.Style = LinkStyle;
                        }

                        string url = inline.TargetUrl;
                        if (uriResolver != null)
                        {
                            url = uriResolver(inline.TargetUrl);
                        }

                        hyperlink.CommandParameter = url;
                        if (Uri.IsWellFormedUriString(url, UriKind.Absolute))
                        {
                            hyperlink.NavigateUri      = new Uri(url);
                            hyperlink.RequestNavigate += (sender, e) =>
                            {
                                System.Diagnostics.Process.Start(e.Uri.ToString());
                            };
                        }
                        else
                        {
                            hyperlink.Command = HyperlinkCommand;
                        }

                        if (inline.LiteralContent.Length > 0)
                        {
                            hyperlink.ToolTip = inline.LiteralContent;
                        }

                        if (trackPositions)
                        {
                            PrintPosition(hyperlink, inline);
                        }

                        if (!(blockParent is Hyperlink))
                        {
                            blockParent.AddChild(hyperlink);
                        }

                        lastParent  = blockParent;
                        blockParent = hyperlink;

                        visitChildren   = true;
                        stackWithinLink = true;
                    }
                    break;

                case InlineTag.Image:
                    HandleImage(inline, parent);

                    break;

                case InlineTag.Strong:
                    Bold bold = new Bold();
                    blockParent.AddChild(bold);
                    lastParent  = blockParent;
                    blockParent = bold;

                    if (trackPositions)
                    {
                        PrintPosition(bold, inline);
                    }

                    stackWithinLink = withinLink;
                    visitChildren   = true;
                    break;

                case InlineTag.Emphasis:
                    Italic italic = new Italic();
                    blockParent.AddChild(italic);
                    lastParent  = blockParent;
                    blockParent = italic;

                    if (trackPositions)
                    {
                        PrintPosition(italic, inline);
                    }

                    visitChildren   = true;
                    stackWithinLink = withinLink;
                    break;

                case InlineTag.Strikethrough:
                    Span strikethroughSpan = new Span();
                    strikethroughSpan.TextDecorations = TextDecorations.Strikethrough;

                    blockParent.AddChild(strikethroughSpan);
                    lastParent  = blockParent;
                    blockParent = strikethroughSpan;

                    if (trackPositions)
                    {
                        PrintPosition(strikethroughSpan, inline);
                    }

                    visitChildren   = true;
                    stackWithinLink = withinLink;
                    break;

                case InlineTag.Placeholder:
                    // the slim formatter will treat placeholders like literals, without applying any further processing

                    //if (blockParent is ListItem)
                    //	blockParent.AddChild(new Paragraph(new Run("Placeholder")));
                    //else
                    //	blockParent.AddText("Placeholder");

                    //visitChildren = false;

                    //TODO: Handle todo-list items here
                    break;

                default:
                    throw new CommonMarkException("Inline type " + inline.Tag + " is not supported.", inline);
                }

                if (visitChildren)
                {
                    stack.Push(new InlineStackEntry(lastParent, inline.NextSibling, withinLink));

                    withinLink = stackWithinLink;
                    inline     = inline.FirstChild;
                }
                else if (inline.NextSibling != null)
                {
                    inline = inline.NextSibling;
                }
                else
                {
                    inline = null;
                }

                while (inline == null && stack.Count > 0)
                {
                    var entry = stack.Pop();

                    blockParent = entry.Parent;
                    inline      = entry.Target;
                    withinLink  = entry.IsWithinLink;
                }
            }
        }
Ejemplo n.º 12
0
        // Parse an autolink or HTML tag.
        // Assumes the subject has a '<' character at the current position.
        static Inline handle_pointy_brace(Subject subj)
        {
            int matchlen;
            string contents;

            // advance past first <
            subj.Position++;  

            // first try to match a URL autolink
            matchlen = Scanner.scan_autolink_uri(subj.Buffer, subj.Position, subj.Length);
            if (matchlen > 0)
            {
                contents = subj.Buffer.Substring(subj.Position, matchlen - 1);
                var resultContents = ParseStringEntities(contents);
                var result = Inline.CreateLink(resultContents, contents, string.Empty);

                result.SourcePosition = subj.Position - 1;
                resultContents.SourcePosition = subj.Position;
                subj.Position += matchlen;
                result.SourceLastPosition = subj.Position;
                resultContents.SourceLastPosition = subj.Position - 1;
                
                return result;
            }

            // next try to match an email autolink
            matchlen = Scanner.scan_autolink_email(subj.Buffer, subj.Position, subj.Length);
            if (matchlen > 0)
            {
                contents = subj.Buffer.Substring(subj.Position, matchlen - 1);
                var resultContents = ParseStringEntities(contents);
                var result = Inline.CreateLink(resultContents, "mailto:" + contents, string.Empty);
                
                result.SourcePosition = subj.Position - 1;
                resultContents.SourcePosition = subj.Position;
                subj.Position += matchlen;
                result.SourceLastPosition = subj.Position;
                resultContents.SourceLastPosition = subj.Position - 1;

                return result;
            }

            // finally, try to match an html tag
            matchlen = Scanner.scan_html_tag(subj.Buffer, subj.Position, subj.Length);
            if (matchlen > 0)
            {
                var result = new Inline(InlineTag.RawHtml, subj.Buffer, subj.Position - 1, matchlen + 1);
                result.SourcePosition = subj.Position - 1;
                subj.Position += matchlen;
                result.SourceLastPosition = subj.Position;
                return result;
            }
            else
            {
                // if nothing matches, just return the opening <:
                return new Inline("<", subj.Position - 1, subj.Position);
            }
        }
Ejemplo n.º 13
0
 public InlineStackEntry(IAddChild parent, Inline target, bool isWithinLink)
 {
     Parent       = parent;
     Target       = target;
     IsWithinLink = isWithinLink;
 }
Ejemplo n.º 14
0
        /// <summary>
        /// Writes the inline list to the given writer as HTML code. 
        /// </summary>
        private static void InlinesToHtml(HtmlTextWriter writer, Inline inline, CommonMarkSettings settings, Stack<InlineStackEntry> stack)
        {
            var uriResolver = settings.UriResolver;
            bool withinLink = false;
            bool stackWithinLink = false;
            bool visitChildren;
            bool trackPositions = settings.TrackSourcePosition;
            string stackLiteral = null;

            while (inline != null)
            {
                visitChildren = false;

                switch (inline.Tag)
                {
                    case InlineTag.String:
                        if (trackPositions)
                        {
                            writer.WriteConstant("<span");
                            PrintPosition(writer, inline);
                            writer.Write('>');
                            EscapeHtml(inline.LiteralContentValue, writer);
                            writer.WriteConstant("</span>");
                        }
                        else
                        {
                            EscapeHtml(inline.LiteralContentValue, writer);
                        }

                        break;

                    case InlineTag.LineBreak:
                        writer.WriteLineConstant("<br />");
                        break;

                    case InlineTag.SoftBreak:
                        if (settings.RenderSoftLineBreaksAsLineBreaks)
                            writer.WriteLineConstant("<br />");
                        else
                            writer.WriteLine();
                        break;

                    case InlineTag.Code:
                        writer.WriteConstant("<code");
                        if (trackPositions) PrintPosition(writer, inline);
                        writer.Write('>');
                        EscapeHtml(inline.LiteralContentValue, writer);
                        writer.WriteConstant("</code>");
                        break;

                    case InlineTag.RawHtml:
                        // cannot output source position for HTML blocks
                        writer.Write(inline.LiteralContentValue);
                        break;

                    case InlineTag.Link:
                        if (withinLink)
                        {
                            writer.Write('[');
                            stackLiteral = "]";
                            stackWithinLink = true;
                            visitChildren = true;
                        }
                        else
                        {
                            writer.WriteConstant("<a href=\"");
                            if (uriResolver != null)
                                EscapeUrl(uriResolver(inline.TargetUrl), writer);
                            else
                                EscapeUrl(inline.TargetUrl, writer);

                            writer.Write('\"');
                            if (inline.LiteralContentValue.Length > 0)
                            {
                                writer.WriteConstant(" title=\"");
                                EscapeHtml(inline.LiteralContentValue, writer);
                                writer.Write('\"');
                            }

                            if (trackPositions) PrintPosition(writer, inline);

                            writer.Write('>');

                            visitChildren = true;
                            stackWithinLink = true;
                            stackLiteral = "</a>";
                        }
                        break;

                    case InlineTag.Image:
                        writer.WriteConstant("<img src=\"");
                        if (uriResolver != null)
                            EscapeUrl(uriResolver(inline.TargetUrl), writer);
                        else
                            EscapeUrl(inline.TargetUrl, writer);

                        writer.WriteConstant("\" alt=\"");
                        InlinesToPlainText(writer, inline.FirstChild, stack);
                        writer.Write('\"');
                        if (inline.LiteralContentValue.Length > 0)
                        {
                            writer.WriteConstant(" title=\"");
                            EscapeHtml(inline.LiteralContentValue, writer);
                            writer.Write('\"');
                        }

                        if (trackPositions) PrintPosition(writer, inline);
                        writer.WriteConstant(" />");

                        break;

                    case InlineTag.Strong:
                        writer.WriteConstant("<strong");
                        if (trackPositions) PrintPosition(writer, inline);
                        writer.Write('>');
                        stackLiteral = "</strong>";
                        stackWithinLink = withinLink;
                        visitChildren = true;
                        break;

                    case InlineTag.Emphasis:
                        writer.WriteConstant("<em");
                        if (trackPositions) PrintPosition(writer, inline);
                        writer.Write('>');
                        stackLiteral = "</em>";
                        visitChildren = true;
                        stackWithinLink = withinLink;
                        break;

                    case InlineTag.Strikethrough:
                        writer.WriteConstant("<del");
                        if (trackPositions) PrintPosition(writer, inline);
                        writer.Write('>');
                        stackLiteral = "</del>";
                        visitChildren = true;
                        stackWithinLink = withinLink;
                        break;

                    default:
                        throw new CommonMarkException("Inline type " + inline.Tag + " is not supported.", inline);
                }

                if (visitChildren)
                {
                    stack.Push(new InlineStackEntry(stackLiteral, inline.NextSibling, withinLink));

                    withinLink = stackWithinLink;
                    inline = inline.FirstChild;
                }
                else if (inline.NextSibling != null)
                {
                    inline = inline.NextSibling;
                }
                else
                {
                    inline = null;
                }

                while (inline == null && stack.Count > 0)
                {
                    var entry = stack.Pop();
                    writer.WriteConstant(entry.Literal);
                    inline = entry.Target;
                    withinLink = entry.IsWithinLink;
                }
            }
        }
Ejemplo n.º 15
0
 public InlineStackEntry(string literal, Inline target, bool isWithinLink)
 {
     Literal = literal;
     Target = target;
     IsWithinLink = isWithinLink;
 }
Ejemplo n.º 16
0
 internal static void PrintPosition(HtmlTextWriter writer, Inline inline)
 {
     writer.WriteConstant(" data-sourcepos=\"");
     writer.WriteConstant(inline.SourcePosition.ToString(CultureInfo.InvariantCulture));
     writer.Write('-');
     writer.WriteConstant(inline.SourceLastPosition.ToString(CultureInfo.InvariantCulture));
     writer.WriteConstant("\"");
 }
Ejemplo n.º 17
0
        /// <summary>
        /// Writes the inline list to the given writer as plain text (without any HTML tags).
        /// </summary>
        /// <seealso href="https://github.com/jgm/CommonMark/issues/145"/>
        private static void InlinesToPlainText(HtmlTextWriter writer, Inline inline, Stack<InlineStackEntry> stack)
        {
            bool withinLink = false;
            bool stackWithinLink = false; 
            bool visitChildren;
            string stackLiteral = null;
            var origStackCount = stack.Count;

            while (inline != null)
            {
                visitChildren = false;

                switch (inline.Tag)
                {
                    case InlineTag.String:
                    case InlineTag.Code:
                    case InlineTag.RawHtml:
                        EscapeHtml(inline.LiteralContentValue, writer);
                        break;

                    case InlineTag.LineBreak:
                    case InlineTag.SoftBreak:
                        writer.WriteLine();
                        break;

                    case InlineTag.Link:
                        if (withinLink)
                        {
                            writer.Write('[');
                            stackLiteral = "]";
                            visitChildren = true;
                            stackWithinLink = true;
                        }
                        else
                        {
                            visitChildren = true;
                            stackWithinLink = true;
                            stackLiteral = string.Empty;
                        }
                        break;

                    case InlineTag.Image:
                        visitChildren = true;
                        stackWithinLink = true;
                        stackLiteral = string.Empty;
                        break;

                    case InlineTag.Strong:
                    case InlineTag.Emphasis:
                    case InlineTag.Strikethrough:
                        stackLiteral = string.Empty;
                        stackWithinLink = withinLink;
                        visitChildren = true;
                        break;

                    default:
                        throw new CommonMarkException("Inline type " + inline.Tag + " is not supported.", inline);
                }

                if (visitChildren)
                {
                    stack.Push(new InlineStackEntry(stackLiteral, inline.NextSibling, withinLink));

                    withinLink = stackWithinLink;
                    inline = inline.FirstChild;
                }
                else if (inline.NextSibling != null)
                {
                    inline = inline.NextSibling;
                }
                else
                {
                    inline = null;
                }

                while (inline == null && stack.Count > origStackCount)
                {
                    var entry = stack.Pop();
                    writer.WriteConstant(entry.Literal);
                    inline = entry.Target;
                    withinLink = entry.IsWithinLink;
                }
            }
        }
Ejemplo n.º 18
0
 private async Task WriteBlockImageAsync(Inline inline)
 {
     await WriteStartElementAsync("mediaLink");
     await WriteStartElementAsync("image");
     await WriteLinkTargetAsync(inline.TargetUrl);
     await WriteEndElementAsync(); //image
     if (inline.FirstChild != null)
         await WriteCaptionAsync(inline);
     await WriteEndElementAsync(); //mediaLink
 }
Ejemplo n.º 19
0
 public InlineStackEntry(int indent, Inline target)
 {
     this.Indent = indent;
     this.Target = target;
 }
Ejemplo n.º 20
0
        private static void PrintInlines(TextWriter writer, Inline inline, int indent, Stack<InlineStackEntry> stack, StringBuilder buffer, bool trackPositions)
        {
            while (inline != null)
            {
                writer.Write(new string(' ', indent));

                switch (inline.Tag)
                {
                    case InlineTag.String:
                        writer.Write("str");
                        PrintPosition(trackPositions, writer, inline);
                        writer.Write(' ');
                        writer.Write(format_str(inline.LiteralContent, buffer));
                        break;

                    case InlineTag.LineBreak:
                        writer.Write("linebreak");
                        PrintPosition(trackPositions, writer, inline);
                        break;

                    case InlineTag.SoftBreak:
                        writer.Write("softbreak");
                        PrintPosition(trackPositions, writer, inline);
                        break;

                    case InlineTag.Code:
                        writer.Write("code {0}", format_str(inline.LiteralContent, buffer));
                        PrintPosition(trackPositions, writer, inline);
                        writer.Write(' ');
                        writer.Write(format_str(inline.LiteralContent, buffer));
                        break;

                    case InlineTag.RawHtml:
                        writer.Write("html {0}", format_str(inline.LiteralContent, buffer));
                        writer.Write(' ');
                        writer.Write(format_str(inline.LiteralContent, buffer));
                        break;

                    case InlineTag.Link:
                        writer.Write("link");
                        PrintPosition(trackPositions, writer, inline);
                        writer.Write(" url={0} title={1}",
                               format_str(inline.TargetUrl, buffer),
                               format_str(inline.LiteralContent, buffer));
                        break;

                    case InlineTag.Image:
                        writer.Write("image");
                        PrintPosition(trackPositions, writer, inline);
                        writer.Write(" url={0} title={1}",
                               format_str(inline.TargetUrl, buffer),
                               format_str(inline.LiteralContent, buffer));
                        break;

                    case InlineTag.Strong:
                        writer.Write("strong");
                        PrintPosition(trackPositions, writer, inline);
                        break;

                    case InlineTag.Emphasis:
                        writer.Write("emph");
                        PrintPosition(trackPositions, writer, inline);
                        break;

                    case InlineTag.Strikethrough:
                        writer.Write("del");
                        PrintPosition(trackPositions, writer, inline);
                        break;

                    case InlineTag.Subscript:
                        writer.Write("sub");
                        PrintPosition(trackPositions, writer, inline);
                        break;

                    case InlineTag.Superscript:
                        writer.Write("sup");
                        PrintPosition(trackPositions, writer, inline);
                        break;

                    case InlineTag.Math:
                        writer.Write("math");
                        PrintPosition(trackPositions, writer, inline);
                        break;

                    default:
                        writer.Write("unknown: " + inline.Tag.ToString());
                        PrintPosition(trackPositions, writer, inline);
                        break;
                }

                writer.WriteLine();

                if (inline.FirstChild != null)
                {
                    if (inline.NextSibling != null)
                        stack.Push(new InlineStackEntry(indent, inline.NextSibling));

                    indent += 2;
                    inline = inline.FirstChild;
                }
                else if (inline.NextSibling != null)
                {
                    inline = inline.NextSibling;
                }
                else if (stack.Count > 0)
                {
                    var entry = stack.Pop();
                    indent = entry.Indent;
                    inline = entry.Target;
                }
                else
                {
                    inline = null;
                }
            }
        }
Ejemplo n.º 21
0
 internal static void PrintPosition(HtmlTextWriter writer, Inline inline) {
   writer.WriteConstant(" lmo=\"");
   writer.WriteConstant((inline.SourcePosition).ToString(CultureInfo.InvariantCulture));
   writer.WriteConstant("\" lmc=\"");
   writer.WriteConstant((inline.SourceLastPosition).ToString(CultureInfo.InvariantCulture));
   writer.WriteConstant("\"");
 }
Ejemplo n.º 22
0
        private static Inline HandleTilde(Subject subj)
        {
            bool canOpen, canClose;
            var numdelims = ScanEmphasisDelimeters(subj, '~', out canOpen, out canClose);

            if (numdelims == 1)
                return new Inline("~", subj.Position - 1, subj.Position);

            if (canClose)
            {
                // walk the stack and find a matching opener, if there is one
                var istack = InlineStack.FindMatchingOpener(subj.LastPendingInline, InlineStack.InlineStackPriority.Emphasis, '~', out canClose);
                if (istack != null)
                {
                    MatchInlineStack(istack, subj, numdelims, null, null, InlineTag.Strikethrough);

                    // if the closer was not fully used, move back a char or two and try again.
                    if (numdelims > 2)
                    {
                        subj.Position = subj.Position - numdelims + 2;

                        // use recursion only if it will not be very deep.
                        if (numdelims < 10)
                            return HandleTilde(subj);
                    }

                    return null;
                }
            }

            var inlText = new Inline(subj.Buffer, subj.Position - numdelims, numdelims,
                subj.Position - numdelims, subj.Position);

            if (canOpen || canClose)
            {
                var istack = new InlineStack();
                istack.DelimeterCount = numdelims;
                istack.Delimeter = '~';
                istack.StartingInline = inlText;
                istack.Priority = InlineStack.InlineStackPriority.Emphasis;
                istack.Flags = (canOpen ? InlineStack.InlineStackFlags.Opener : 0)
                             | (canClose ? InlineStack.InlineStackFlags.Closer : 0);

                InlineStack.AppendStackEntry(istack, subj);
            }

            return inlText;
        }
Ejemplo n.º 23
0
        private static Inline HandleRightSquareBracket(Subject subj, CommonMarkSettings settings)
        {
            // move past ']'
            subj.Position++;

            bool canClose;
            var istack = InlineStack.FindMatchingOpener(subj.LastPendingInline, InlineStack.InlineStackPriority.Links, '[', out canClose);

            if (istack != null)
            {
                // if the opener is "inactive" then it means that there was a nested link
                if (istack.DelimeterCount == -1)
                {
                    InlineStack.RemoveStackEntry(istack, subj, istack, settings.InlineParserParameters);
                    return new Inline("]", subj.Position - 1, subj.Position);
                }

                var endpos = subj.Position;

                // try parsing details for '[foo](/url "title")' or '[foo][bar]'
                var details = ParseLinkDetails(subj, settings);

                // try lookup of the brackets themselves
                if (details == null || details == Reference.SelfReference)
                {
                    var startpos = istack.StartPosition;
                    var label = new StringPart(subj.Buffer, startpos, endpos - startpos - 1);

                    details = LookupReference(subj.ReferenceMap, label, settings);
                }

                if (details == Reference.InvalidReference)
                    details = null;

                MatchSquareBracketStack(istack, subj, details, settings.InlineParserParameters);
                return null;
            }

            var inlText = new Inline("]", subj.Position - 1, subj.Position);

            if (canClose)
            {
                // note that the current implementation will not work if there are other inlines with priority
                // higher than Links.
                // to fix this the parsed link details should be added to the closer element in the stack.

                throw new NotSupportedException("It is not supported to have inline stack priority higher than Links.");

                ////istack = new InlineStack();
                ////istack.Delimeter = '[';
                ////istack.StartingInline = inlText;
                ////istack.StartPosition = subj.Position;
                ////istack.Priority = InlineStack.InlineStackPriority.Links;
                ////istack.Flags = InlineStack.InlineStackFlags.Closer;

                ////InlineStack.AppendStackEntry(istack, subj);
            }

            return inlText;
        }
Ejemplo n.º 24
0
        /// <summary>
        /// Writes the specified inline element to the output stream. Does not write the child nodes, instead
        /// the <paramref name="ignoreChildNodes"/> is used to notify the caller whether it should recurse
        /// into the child nodes.
        /// </summary>
        /// <param name="inline">The inline element to be written to the output stream.</param>
        /// <param name="isOpening">Specifies whether the inline element is being opened (or started).</param>
        /// <param name="isClosing">Specifies whether the inline element is being closed. If the inline does not
        /// have child nodes, then both <paramref name="isClosing"/> and <paramref name="isOpening"/> can be
        /// <c>true</c> at the same time.</param>
        /// <param name="ignoreChildNodes">Instructs the caller whether to skip processing of child nodes or not.</param>
        protected virtual void WriteInline(Inline inline, bool isOpening, bool isClosing, out bool ignoreChildNodes)
        {
            if (RenderPlainTextInlines.Peek())
            {
                switch (inline.Tag)
                {
                    case InlineTag.String:
                    case InlineTag.Code:
                    case InlineTag.RawHtml:
                        WriteEncodedHtml(inline.LiteralContentValue);
                        break;

                    case InlineTag.LineBreak:
                    case InlineTag.SoftBreak:
                        WriteLine();
                        break;

                    case InlineTag.Image:
                        if (isOpening)
                            RenderPlainTextInlines.Push(true);

                        if (isClosing)
                        {
                            RenderPlainTextInlines.Pop();

                            if (!RenderPlainTextInlines.Peek())
                                goto useFullRendering;
                        }

                        break;

                    case InlineTag.Link:
                    case InlineTag.Strong:
                    case InlineTag.Emphasis:
                    case InlineTag.Strikethrough:
                    case InlineTag.Math:
                        break;

                    default:
                        throw new CommonMarkException("Inline type " + inline.Tag + " is not supported.", inline);
                }

                ignoreChildNodes = false;
                return;
            }

            useFullRendering:

            switch (inline.Tag)
            {
                case InlineTag.String:
                    ignoreChildNodes = true;
                    if (Settings.TrackSourcePosition)
                    {
                        Write("<span");
                        WritePositionAttribute(inline);
                        Write('>');
                        WriteEncodedHtml(inline.LiteralContentValue);
                        Write("</span>");
                    }
                    else
                    {
                        WriteEncodedHtml(inline.LiteralContentValue);
                    }

                    break;

                case InlineTag.LineBreak:
                    ignoreChildNodes = true;
                    WriteLine("<br />");
                    break;

                case InlineTag.SoftBreak:
                    ignoreChildNodes = true;
                    if (Settings.RenderSoftLineBreaksAsLineBreaks)
                        WriteLine("<br />");
                    else
                        WriteLine();
                    break;

                case InlineTag.Code:
                    ignoreChildNodes = true;
                    Write("<code");
                    if (Settings.TrackSourcePosition) WritePositionAttribute(inline);
                    Write('>');
                    WriteEncodedHtml(inline.LiteralContentValue);
                    Write("</code>");
                    break;

                case InlineTag.RawHtml:
                    ignoreChildNodes = true;
                    // cannot output source position for HTML blocks
                    Write(inline.LiteralContentValue);
                    break;

                case InlineTag.Link:
                    ignoreChildNodes = false;

                    if (isOpening)
                    {
                        Write("<a href=\"");
                        var uriResolver = Settings.UriResolver;
                        if (uriResolver != null)
                            WriteEncodedUrl(uriResolver(inline.TargetUrl));
                        else
                            WriteEncodedUrl(inline.TargetUrl);

                        Write('\"');
                        if (inline.LiteralContentValue.Length > 0)
                        {
                            Write(" title=\"");
                            WriteEncodedHtml(inline.LiteralContentValue);
                            Write('\"');
                        }

                        if (Settings.TrackSourcePosition) WritePositionAttribute(inline);

                        Write('>');
                    }

                    if (isClosing)
                    {
                        Write("</a>");
                    }

                    break;

                case InlineTag.Image:
                    ignoreChildNodes = false;

                    if (isOpening)
                    {
                        Write("<img src=\"");
                        var uriResolver = Settings.UriResolver;
                        if (uriResolver != null)
                            WriteEncodedUrl(uriResolver(inline.TargetUrl));
                        else
                            WriteEncodedUrl(inline.TargetUrl);

                        Write("\" alt=\"");

                        if (!isClosing)
                            RenderPlainTextInlines.Push(true);
                    }

                    if (isClosing)
                    {
                        // this.RenderPlainTextInlines.Pop() is done by the plain text renderer above.

                        Write('\"');
                        if (inline.LiteralContentValue.Length > 0)
                        {
                            Write(" title=\"");
                            WriteEncodedHtml(inline.LiteralContentValue);
                            Write('\"');
                        }

                        if (Settings.TrackSourcePosition) WritePositionAttribute(inline);
                        Write(" />");
                    }

                    break;

                case InlineTag.Strong:
                    ignoreChildNodes = false;

                    if (isOpening)
                    {
                        Write("<strong");
                        if (Settings.TrackSourcePosition) WritePositionAttribute(inline);
                        Write('>');
                    }

                    if (isClosing)
                    {
                        Write("</strong>");
                    }
                    break;

                case InlineTag.Emphasis:
                    ignoreChildNodes = false;

                    if (isOpening)
                    {
                        Write("<em");
                        if (Settings.TrackSourcePosition) WritePositionAttribute(inline);
                        Write('>');
                    }

                    if (isClosing)
                    {
                        Write("</em>");
                    }
                    break;

                case InlineTag.Strikethrough:
                    ignoreChildNodes = false;

                    if (isOpening)
                    {
                        Write("<del");
                        if (Settings.TrackSourcePosition) WritePositionAttribute(inline);
                        Write('>');
                    }

                    if (isClosing)
                    {
                        Write("</del>");
                    }
                    break;

                case InlineTag.Subscript:
                    ignoreChildNodes = false;

                    if (isOpening)
                    {
                        Write("<sub");
                        if (Settings.TrackSourcePosition) WritePositionAttribute(inline);
                        Write('>');
                    }

                    if (isClosing)
                    {
                        Write("</sub>");
                    }
                    break;

                case InlineTag.Superscript:
                    ignoreChildNodes = false;

                    if (isOpening)
                    {
                        Write("<sup");
                        if (Settings.TrackSourcePosition) WritePositionAttribute(inline);
                        Write('>');
                    }

                    if (isClosing)
                    {
                        Write("</sup>");
                    }
                    break;

                case InlineTag.Math:
                    ignoreChildNodes = false;

                    if (isOpening)
                    {
                        Write("<span class=\"math\"");
                        if (Settings.TrackSourcePosition) WritePositionAttribute(inline);
                        Write('>');
                    }

                    if (isClosing)
                    {
                        Write("</span>");
                    }
                    break;

                default:
                    throw new CommonMarkException("Inline type " + inline.Tag + " is not supported.", inline);
            }
        }
Ejemplo n.º 25
0
        private static void AdjustInlineSourcePosition(Inline inline, PositionTracker tracker, ref Stack<Inline> stack)
        {
            if (stack == null)
                stack = new Stack<Inline>();

            while (inline != null)
            {
                inline.SourcePosition = tracker.CalculateInlineOrigin(inline.SourcePosition, true);
                inline.SourceLastPosition = tracker.CalculateInlineOrigin(inline.SourceLastPosition, false);

                if (inline.FirstChild != null)
                {
                    if (inline.NextSibling != null)
                        stack.Push(inline.NextSibling);

                    inline = inline.FirstChild;
                }
                else if (inline.NextSibling != null)
                {
                    inline = inline.NextSibling;
                }
                else if (stack.Count > 0)
                {
                    inline = stack.Pop();
                }
                else
                {
                    inline = null;
                }
            }

        }
Ejemplo n.º 26
0
 public InlineStackEntry(Inline target, Inline needsClose)
 {
     this.Target     = target;
     this.NeedsClose = needsClose;
 }
Ejemplo n.º 27
0
 internal static void PrintPosition(FrameworkContentElement writer, Inline inline)
 {
     writer.Tag = "DataSourcePos:" + inline.SourcePosition.ToString(CultureInfo.InvariantCulture) + " - " + (inline.SourcePosition + inline.SourceLength).ToString(CultureInfo.InvariantCulture);
 }
Ejemplo n.º 28
0
 /// <summary>
 /// Initializes a new instance of the <see cref="Inline"/> class.
 /// </summary>
 /// <param name="tag">The type of inline element. Should be one of the types that contain child elements, for example, <see cref="InlineTag.Emphasis"/>.</param>
 /// <param name="content">The first descendant element of the inline that is being created.</param>
 public Inline(InlineTag tag, Inline content)
 {
     this.Tag        = tag;
     this.FirstChild = content;
 }
Ejemplo n.º 29
0
        /// <summary>
        /// Writes the inline list to the given parent as plain text (without any HTML tags).
        /// </summary>
        /// <seealso href="https://github.com/jgm/CommonMark/issues/145"/>
        private void InlinesToPlainText(IAddChild parent, Inline inline, Stack <InlineStackEntry> stack)
        {
            bool   withinLink      = false;
            bool   stackWithinLink = false;
            string stackLiteral    = null;
            var    origStackCount  = stack.Count;


            while (inline != null)
            {
                var visitChildren = false;

                switch (inline.Tag)
                {
                case InlineTag.String:
                case InlineTag.RawHtml:
                    //EscapeHtml(inline.LiteralContent, parent);
                    break;

                case InlineTag.Code:
                    Span codeSpan = new Span(new Run(inline.LiteralContent));
                    if (InlineCodeStyle != null)
                    {
                        codeSpan.Style = InlineCodeStyle;
                    }

                    parent.AddChild(codeSpan);

                    break;

                case InlineTag.LineBreak:
                case InlineTag.SoftBreak:
                    //parent.WriteLine();
                    break;

                case InlineTag.Link:
                    if (withinLink)
                    {
                        //parent.Write('[');
                        stackLiteral    = "]";
                        visitChildren   = true;
                        stackWithinLink = true;
                    }
                    else
                    {
                        visitChildren   = true;
                        stackWithinLink = true;
                        stackLiteral    = string.Empty;
                    }
                    break;

                case InlineTag.Image:
                    visitChildren   = true;
                    stackWithinLink = true;
                    stackLiteral    = string.Empty;
                    break;

                case InlineTag.Strong:
                case InlineTag.Emphasis:
                case InlineTag.Strikethrough:
                    stackLiteral    = string.Empty;
                    stackWithinLink = withinLink;
                    visitChildren   = true;
                    break;

                case InlineTag.Placeholder:
                    visitChildren = true;
                    break;

                default:
                    throw new CommonMarkException("Inline type " + inline.Tag + " is not supported.", inline);
                }

                if (visitChildren)
                {
                    stack.Push(new InlineStackEntry(parent, inline.NextSibling, withinLink));

                    withinLink = stackWithinLink;
                    inline     = inline.FirstChild;
                }
                else if (inline.NextSibling != null)
                {
                    inline = inline.NextSibling;
                }
                else
                {
                    inline = null;
                }

                while (inline == null && stack.Count > origStackCount)
                {
                    var entry = stack.Pop();

                    inline     = entry.Target;
                    withinLink = entry.IsWithinLink;
                }
            }
        }
Ejemplo n.º 30
0
        internal static int MatchInlineStack(InlineStack opener, Subject subj, int closingDelimeterCount, InlineStack closer, InlineTag singleCharTag, InlineTag doubleCharTag, InlineParserParameters parameters)
        {
            // calculate the actual number of delimeters used from this closer
            int useDelims;
            var openerDelims = opener.DelimeterCount;

            if (closingDelimeterCount < 3 || openerDelims < 3)
            {
                useDelims = closingDelimeterCount <= openerDelims ? closingDelimeterCount : openerDelims;
                if (useDelims == 2 && doubleCharTag == 0)
                    useDelims = 1;
                if (useDelims == 1 && singleCharTag == 0)
                    return 0;
            }
            else if (singleCharTag == 0)
                useDelims = 2;
            else if (doubleCharTag == 0)
                useDelims = 1;
            else
                useDelims = closingDelimeterCount % 2 == 0 ? 2 : 1;

            Inline inl = opener.StartingInline;
            InlineTag tag = useDelims == 1 ? singleCharTag : doubleCharTag;
            if (openerDelims == useDelims)
            {
                // the opener is completely used up - remove the stack entry and reuse the inline element
                inl.Tag = tag;
                inl.LiteralContent = null;
                inl.FirstChild = inl.NextSibling;
                inl.NextSibling = null;

                InlineStack.RemoveStackEntry(opener, subj, closer?.Previous, parameters);
            }
            else
            {
                // the opener will only partially be used - stack entry remains (truncated) and a new inline is added.
                opener.DelimeterCount -= useDelims;
                inl.LiteralContent = inl.LiteralContent.Substring(0, opener.DelimeterCount);
                inl.SourceLastPosition -= useDelims;

                inl.NextSibling = new Inline(tag, inl.NextSibling);
                inl = inl.NextSibling;

                inl.SourcePosition = opener.StartingInline.SourcePosition + opener.DelimeterCount;
            }

            // there are two callers for this method, distinguished by the `closer` argument.
            // if closer == null it means the method is called during the initial subject parsing and the closer
            //   characters are at the current position in the subject. The main benefit is that there is nothing
            //   parsed that is located after the matched inline element.
            // if closer != null it means the method is called when the second pass for previously unmatched
            //   stack elements is done. The drawback is that there can be other elements after the closer.
            if (closer != null)
            {
                var clInl = closer.StartingInline;
                if ((closer.DelimeterCount -= useDelims) > 0)
                {
                    // a new inline element must be created because the old one has to be the one that
                    // finalizes the children of the emphasis
                    var newCloserInline = new Inline(clInl.LiteralContent.Substring(useDelims));
                    newCloserInline.SourcePosition = inl.SourceLastPosition = clInl.SourcePosition + useDelims;
                    newCloserInline.SourceLength = closer.DelimeterCount;
                    newCloserInline.NextSibling = clInl.NextSibling;

                    clInl.LiteralContent = null;
                    clInl.NextSibling = null;
                    inl.NextSibling = closer.StartingInline = newCloserInline;
                }
                else
                {
                    inl.SourceLastPosition = clInl.SourceLastPosition;

                    clInl.LiteralContent = null;
                    inl.NextSibling = clInl.NextSibling;
                    clInl.NextSibling = null;
                }
            }
            else if (subj != null)
            {
                inl.SourceLastPosition = subj.Position - closingDelimeterCount + useDelims;
                subj.LastInline = inl;
            }

            return useDelims;
        }
Ejemplo n.º 31
0
        private static System.Windows.Documents.Inline InlineToDocumentInline(CommonMark.Syntax.Inline inline)
        {
            if (inline == null)
            {
                return(null);
            }

            switch (inline.Tag)
            {
            case InlineTag.String:
                return(new Run(inline.LiteralContent));

            case InlineTag.LineBreak:
                return(new LineBreak());

            case InlineTag.SoftBreak:
                return(new Run(" "));

            case InlineTag.Code:
                return(new Run(inline.LiteralContent)
                {
                    FontFamily = new FontFamily("Courier New")
                });

            case InlineTag.RawHtml:
                break;

            case InlineTag.Link:
                var hyperlink = new Hyperlink();
                if (Uri.IsWellFormedUriString(inline.TargetUrl, UriKind.Absolute))
                {
                    hyperlink.NavigateUri      = new Uri(inline.TargetUrl);
                    hyperlink.RequestNavigate += new RequestNavigateEventHandler(LinkRequestNavigate);
                }

                var childInline = InlineToDocumentInline(inline.FirstChild);
                if (childInline != null)
                {
                    hyperlink.Inlines.Add(childInline);
                }

                return(hyperlink);

            case InlineTag.Image:
                Uri uri = null;
                if (Uri.IsWellFormedUriString(inline.TargetUrl, UriKind.Absolute))
                {
                    uri = new Uri(inline.TargetUrl, UriKind.Absolute);
                }
                else
                {
                    uri = new Uri(inline.TargetUrl, UriKind.Relative);
                }

                var image = new Image();
                image.Source = new BitmapImage(uri);
                var uiContainer = new BlockUIContainer(image);

                return(new Floater(uiContainer));

            case InlineTag.Strong:
                return(new Bold(InlineToDocumentInline(inline.FirstChild)));

            case InlineTag.Emphasis:
                return(new Italic(InlineToDocumentInline(inline.FirstChild)));

            case InlineTag.Strikethrough:
                var span = new Span(InlineToDocumentInline(inline.FirstChild));
                span.TextDecorations.Add(new TextDecoration()
                {
                    Location = TextDecorationLocation.Strikethrough
                });
                return(span);

            default:
                throw new CommonMarkException("Inline type " + inline.Tag + " is not supported.", inline);
            }

            return(null);
        }
Ejemplo n.º 32
0
 internal CommonMarkException(string message, Syntax.Inline inline, Exception inner = null)
     : base(message, inner)
 {
     this.InlineElement = inline;
 }
Ejemplo n.º 33
0
 /// <summary>
 /// Initializes a new instance of the <see cref="Inline"/> class.
 /// </summary>
 /// <param name="tag">The type of inline element. Should be one of the types that contain child elements, for example, <see cref="InlineTag.Emphasis"/>.</param>
 /// <param name="content">The first descendant element of the inline that is being created.</param>
 public Inline(InlineTag tag, Inline content)
 {
     this.Tag = tag;
     this.FirstChild = content;
 }
Ejemplo n.º 34
0
 /// <summary>
 /// Initializes a new instance of the <see cref="EnumeratorEntry"/> class.
 /// </summary>
 /// <param name="opening">Specifies if this instance represents the opening of the inline element.</param>
 /// <param name="closing">Specifies if this instance represents the closing of the inline element (returned by the
 /// enumerator after the children have been enumerated). Both <paramref name="closing"/> and <paramref name="opening"/>
 /// can be specified at the same time if there are no children for the <paramref name="inline"/> element.</param>
 /// <param name="inline">The inlien element being returned from the enumerator.</param>
 public EnumeratorEntry(bool opening, bool closing, Inline inline)
 {
     this.IsOpening = opening;
     this.IsClosing = closing;
     this.Inline    = inline;
 }
Ejemplo n.º 35
0
 internal async Task WriteStringAsync(Inline inline)
 {
     var content = inline.LiteralContent;
     if (string.IsNullOrWhiteSpace(content))
         await WriteRawAsync("&#160;");
     else
         await WriteStringAsync(content);
 }
Ejemplo n.º 36
0
        internal static void MatchSquareBracketStack(InlineStack opener, Subject subj, Reference details, InlineParserParameters parameters)
        {
            if (details != null)
            {
                var inl = opener.StartingInline;
                var isImage = 0 != (opener.Flags & InlineStack.InlineStackFlags.ImageLink);
                inl.Tag = isImage ? InlineTag.Image : InlineTag.Link;
                inl.FirstChild = inl.NextSibling;
                inl.NextSibling = null;
                inl.SourceLastPosition = subj.Position;

                inl.TargetUrl = details.Url;
                inl.LiteralContent = details.Title;

                if (!isImage)
                {
                    // since there cannot be nested links, remove any other link openers before this
                    var temp = opener.Previous;
                    while (temp != null && temp.Priority <= InlineStack.InlineStackPriority.Links)
                    {
                        if (temp.Delimeter == '[' && temp.Flags == opener.Flags)
                        {
                            // mark the previous entries as "inactive"
                            if (temp.DelimeterCount == -1)
                                break;

                            temp.DelimeterCount = -1;
                        }

                        temp = temp.Previous;
                    }
                }

                InlineStack.RemoveStackEntry(opener, subj, null, parameters);

                subj.LastInline = inl;
            }
            else
            {
                // this looked like a link, but was not.
                // remove the opener stack entry but leave the inbetween intact
                InlineStack.RemoveStackEntry(opener, subj, opener, parameters);

                var inl = new Inline("]", subj.Position - 1, subj.Position);
                subj.LastInline.LastSibling.NextSibling = inl;
                subj.LastInline = inl;
            }
        }
Ejemplo n.º 37
0
 /// <summary>
 /// Writes a <c>data-sourcepos="start-end"</c> attribute to the target writer. 
 /// This method should only be called if <see cref="CommonMarkSettings.TrackSourcePosition"/> is set to <see langword="true"/>.
 /// Note that the attribute is preceded (but not succeeded) by a single space.
 /// </summary>
 protected void WritePositionAttribute(Inline inline)
 {
     HtmlFormatterSlim.PrintPosition(_target, inline);
 }
Ejemplo n.º 38
0
        private static void BlockToDocumentBlock(CommonMark.Syntax.Block block, BlockCollection collection)
        {
            if (block == null)
            {
                return;
            }

            switch (block.Tag)
            {
            case BlockTag.Document:
                BlockToDocumentBlock(block.FirstChild, collection);
                break;

            case BlockTag.Paragraph:
                var paragraph = new Paragraph();

                CommonMark.Syntax.Inline current = block.InlineContent;
                while (current != null)
                {
                    var inline = InlineToDocumentInline(current);
                    if (inline != null)
                    {
                        paragraph.Inlines.Add(inline);
                    }

                    current = current.NextSibling;
                }

                collection.Add(paragraph);

                BlockToDocumentBlock(block.NextSibling, collection);
                break;

            case BlockTag.BlockQuote:
                var quoteBlock = new Section()
                {
                    Background = Brushes.LightGray, Margin = new Thickness(10)
                };
                collection.Add(quoteBlock);

                BlockToDocumentBlock(block.FirstChild, quoteBlock.Blocks);
                BlockToDocumentBlock(block.NextSibling, collection);
                break;

            case BlockTag.ListItem:
                throw new InvalidOperationException();

            case BlockTag.List:
                var listBlock = new List();
                collection.Add(listBlock);
                if (block.FirstChild != null)
                {
                    if (block.FirstChild.ListData.ListType == ListType.Ordered)
                    {
                        listBlock.MarkerStyle = TextMarkerStyle.Decimal;
                        listBlock.StartIndex  = block.FirstChild.ListData.Start;
                    }

                    BlockToDocumentBlock(block.FirstChild, listBlock.ListItems);
                }


                BlockToDocumentBlock(block.NextSibling, collection);
                break;

            case BlockTag.AtxHeading:
            case BlockTag.SetextHeading:
                var heading = GetHeadingItem(block.Heading.Level);


                heading.Inlines.Add(InlineToDocumentInline(block.InlineContent));
                collection.Add(heading);

                BlockToDocumentBlock(block.NextSibling, collection);
                break;

            case BlockTag.IndentedCode:
            case BlockTag.FencedCode:
                var codeBlock = new Section()
                {
                    Background = Brushes.LightGray, Margin = new Thickness(2)
                };
                collection.Add(codeBlock);
                var code = block.StringContent.TakeFromStart(block.StringContent.Length - 1);

                codeBlock.Blocks.Add(new Paragraph(new Run(code)
                {
                    FontFamily = new FontFamily("Courier New")
                }));

                BlockToDocumentBlock(block.NextSibling, collection);
                break;

            case BlockTag.HtmlBlock:
                // cannot output source position for HTML blocks
                //block.StringContent.WriteTo(writer);
                break;

            case BlockTag.ThematicBreak:
                var separator = new Rectangle();
                separator.Stroke          = new SolidColorBrush(Colors.LightGray);
                separator.StrokeThickness = 3;
                separator.Height          = 2;
                separator.Width           = double.NaN;

                var lineBlock = new BlockUIContainer(separator);
                collection.Add(lineBlock);

                BlockToDocumentBlock(block.NextSibling, collection);
                break;

            case BlockTag.ReferenceDefinition:

                break;

            default:
                throw new CommonMarkException("Block type " + block.Tag + " is not supported.", block);
            }
        }
Ejemplo n.º 39
0
        private static Inline HandleOpenerCloser(Subject subj, InlineTag singleCharTag, InlineTag doubleCharTag, InlineParserParameters parameters)
        {
            bool canOpen, canClose;
            var c = subj.Buffer[subj.Position];
            var numdelims = ScanEmphasisDelimeters(subj, c, out canOpen, out canClose);

            if (canClose)
            {
                // walk the stack and find a matching opener, if there is one
                var istack = InlineStack.FindMatchingOpener(subj.LastPendingInline, InlineStack.InlineStackPriority.Emphasis, c, out canClose);
                if (istack != null)
                {
                    var useDelims = MatchInlineStack(istack, subj, numdelims, null, singleCharTag, doubleCharTag, parameters);

                    // if the closer was not fully used, move back a char or two and try again.
                    if (useDelims < numdelims)
                    {
                        subj.Position = subj.Position - numdelims + useDelims;

                        // use recursion only if it will not be very deep.
                        if (numdelims < 10)
                            return HandleOpenerCloser(subj, singleCharTag, doubleCharTag, parameters);
                    }

                    return null;
                }
            }

            var inlText = new Inline(subj.Buffer, subj.Position - numdelims, numdelims, subj.Position - numdelims, subj.Position, c);

            if (canOpen || canClose)
            {
                var istack = new InlineStack();
                istack.DelimeterCount = numdelims;
                istack.Delimeter = c;
                istack.StartingInline = inlText;
                istack.Priority = InlineStack.InlineStackPriority.Emphasis;
                istack.Flags = (canOpen ? InlineStack.InlineStackFlags.Opener : 0)
                             | (canClose ? InlineStack.InlineStackFlags.Closer : 0);

                InlineStack.AppendStackEntry(istack, subj);
            }

            return inlText;
        }
Ejemplo n.º 40
0
 private async Task WriteCaptionAsync(Inline inline)
 {
     await WriteStartElementAsync("caption");
     await WriteAttributeStringAsync("placement", "after");
     await WriteChildInlinesAsync(inline);
     await WriteEndElementAsync(); //caption
 }
Ejemplo n.º 41
0
 internal override async Task WriteExternalLinkAsync(Inline inline, string targetUrl)
 {
     if (GetSectionState() != SectionState.SeeAlso)
         await base.WriteExternalLinkAsync(inline, targetUrl);
 }
Ejemplo n.º 42
0
        private static Inline HandleLeftSquareBracket(Subject subj, bool isImage, CommonMarkSettings settings)
        {
            Inline inlText;
            
            if (isImage)
            {
                inlText = new Inline("![", subj.Position - 1, subj.Position + 1);
            }
            else
            {
                inlText = new Inline("[", subj.Position, subj.Position + 1);
            }

            // move past the '['
            subj.Position++;

            var istack = new InlineStack();
            istack.Delimeter = '[';
            istack.StartingInline = inlText;
            istack.StartPosition = subj.Position;
            istack.Priority = InlineStack.InlineStackPriority.Links;
            istack.Flags = InlineStack.InlineStackFlags.Opener | (isImage ? InlineStack.InlineStackFlags.ImageLink : InlineStack.InlineStackFlags.None);

            InlineStack.AppendStackEntry(istack, subj);

            return inlText;
        }