Beispiel #1
0
    public static Paragraph Parse(string text, Style?style = null)
    {
        if (text is null)
        {
            throw new ArgumentNullException(nameof(text));
        }

        style ??= Style.Plain;

        var result = new Paragraph();

        using var tokenizer = new MarkupTokenizer(text);

        var stack = new Stack <Style>();

        while (tokenizer.MoveNext())
        {
            var token = tokenizer.Current;
            if (token == null)
            {
                break;
            }

            if (token.Kind == MarkupTokenKind.Open)
            {
                var parsedStyle = StyleParser.Parse(token.Value);
                stack.Push(parsedStyle);
            }
            else if (token.Kind == MarkupTokenKind.Close)
            {
                if (stack.Count == 0)
                {
                    throw new InvalidOperationException($"Encountered closing tag when none was expected near position {token.Position}.");
                }

                stack.Pop();
            }
            else if (token.Kind == MarkupTokenKind.Text)
            {
                // Get the effective style.
                var effectiveStyle = style.Combine(stack.Reverse());
                result.Append(Emoji.Replace(token.Value), effectiveStyle);
            }
            else
            {
                throw new InvalidOperationException("Encountered unknown markup token.");
            }
        }

        if (stack.Count > 0)
        {
            throw new InvalidOperationException("Unbalanced markup stack. Did you forget to close a tag?");
        }

        return(result);
    }
    /// <summary>
    /// Removes markup from the specified string.
    /// </summary>
    /// <param name="text">The text to remove markup from.</param>
    /// <returns>A string that does not have any markup.</returns>
    public static string RemoveMarkup(this string?text)
    {
        if (string.IsNullOrWhiteSpace(text))
        {
            return(string.Empty);
        }

        var result = new StringBuilder();

        var tokenizer = new MarkupTokenizer(text);

        while (tokenizer.MoveNext() && tokenizer.Current != null)
        {
            if (tokenizer.Current.Kind == MarkupTokenKind.Text)
            {
                result.Append(tokenizer.Current.Value);
            }
        }

        return(result.ToString());
    }
Beispiel #3
0
    /// <summary>
    /// Parse the markup to RichTextParts and add them to the markuptextcontrol.
    /// </summary>
    /// <param name="markup"></param>
    public void ParseMarkup(string markup)
    {
        MarkupTokenizer tokonizer = new MarkupTokenizer(markup);

        tokonizer.FindTokens();
        MarkupToken[] markuptokens = tokonizer.GetTokens();
        SolidBrush    solidbrushTextcolorDefault = new SolidBrush(Color.Black);
        RichTextPart  richtextpart = null;
        bool          previous_markuptokon_hyperlinktext = false;

        for (int i = 0; i < markuptokens.Length; ++i)
        {
            if (markuptokens[i].IsLine)
            {
                richtextpart = new RichTextPart(Pens.Black);
                this.markuptextcontrol.Append(richtextpart);
            }
            else
            {
                switch (markuptokens[i].CharLeft)
                {
                case '#':
                    // head
                    int headlevel = markuptokens[i].Level;
                    richtextpart = new RichTextPart(markuptokens[i].Text,
                                                    this.fontfamily,
                                                    this.headsfontsizes[headlevel],
                                                    solidbrushTextcolorDefault,
                                                    FontStyle.Bold);
                    richtextpart.AppendNewLine = true;
                    this.markuptextcontrol.Append(richtextpart);
                    previous_markuptokon_hyperlinktext = false;
                    break;

                case '-':
                    // list
                    richtextpart = new RichTextPart(markuptokens[i].Text,
                                                    this.fontfamily,
                                                    this.fontsizedefault,
                                                    solidbrushTextcolorDefault,
                                                    FontStyle.Regular);
                    richtextpart.PrependBullit = true;
                    richtextpart.AppendNewLine = true;
                    this.markuptextcontrol.Append(richtextpart);
                    previous_markuptokon_hyperlinktext = false;
                    break;

                case '*':
                case '_':
                    // emphasis
                    int emphasislevel     = markuptokens[i].Level;
                    int emphasisfontstyle = (int)FontStyle.Italic;
                    if (emphasislevel >= 1)
                    {
                        emphasisfontstyle = (int)FontStyle.Bold;
                    }
                    if (emphasislevel >= 2)
                    {
                        emphasisfontstyle += (int)FontStyle.Italic;
                    }

                    richtextpart = new RichTextPart(markuptokens[i].Text,
                                                    this.fontfamily,
                                                    this.fontsizedefault,
                                                    solidbrushTextcolorDefault,
                                                    (FontStyle)emphasisfontstyle);
                    this.markuptextcontrol.Append(richtextpart);
                    previous_markuptokon_hyperlinktext = false;
                    break;

                case '~':
                    // strikethrough
                    richtextpart = new RichTextPart(markuptokens[i].Text,
                                                    this.fontfamily,
                                                    this.fontsizedefault,
                                                    solidbrushTextcolorDefault,
                                                    FontStyle.Strikeout);
                    this.markuptextcontrol.Append(richtextpart);
                    previous_markuptokon_hyperlinktext = false;
                    break;

                case '[':
                    // hyperlink text
                    previous_markuptokon_hyperlinktext = true;
                    break;

                case '(':
                    // hyperlink url
                    if (previous_markuptokon_hyperlinktext && i > 0)
                    {
                        FontStyle  fontsylehyperlink   = FontStyle.Underline;
                        SolidBrush solidbrushHyperlink = new SolidBrush(Color.Blue);
                        richtextpart = new RichTextPart(markuptokens[i - 1].Text,
                                                        this.fontfamily,
                                                        this.fontsizedefault,
                                                        solidbrushHyperlink,
                                                        fontsylehyperlink);
                        richtextpart.Href = markuptokens[i].Text;
                        this.markuptextcontrol.Append(richtextpart);
                    }

                    previous_markuptokon_hyperlinktext = false;
                    break;

                case '`':
                    // TODO: literally and code highlighting
                    previous_markuptokon_hyperlinktext = false;
                    break;

                default:
                    if (markuptokens[i].Nomarkup)
                    {
                        richtextpart = new RichTextPart(markuptokens[i].Text,
                                                        this.fontfamily,
                                                        this.fontsizedefault,
                                                        solidbrushTextcolorDefault,
                                                        FontStyle.Regular);
                        richtextpart.AppendNewLine = markuptokens[i].TextAppendNewLine;
                        this.markuptextcontrol.Append(richtextpart);
                    }

                    break;
                }
            }
        }

        this.markuptextcontrol.Refresh();
    }