Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MarkdownTextBlock MyCodeBlock renders empty RichTextBox as doesn't use StringBuilder for anything #547

Open
2 of 20 tasks
JoeTomkinson opened this issue Jun 2, 2024 · 2 comments · May be fixed by #595
Open
2 of 20 tasks
Assignees
Labels
bug 🐛 Something isn't working

Comments

@JoeTomkinson
Copy link

Describe the bug

The 'MyCodeBlock' in the pre-release of the MarkDownTextBlock doesnt actually use the lines of text for anything resulting in empty code blocks. I've attached the class snippet below so you can see what I mean.

components/MarkdownTextBlock/src/TextElements/MyCodeBlock.cs

// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using Markdig.Syntax;

namespace CommunityToolkit.Labs.WinUI.MarkdownTextBlock.TextElements;

internal class MyCodeBlock : IAddChild
{
    private CodeBlock _codeBlock;
    private Paragraph _paragraph;
    private MarkdownConfig _config;

    public TextElement TextElement
    {
        get => _paragraph;
    }

    public MyCodeBlock(CodeBlock codeBlock, MarkdownConfig config)
    {
        _codeBlock = codeBlock;
        _config = config;
        _paragraph = new Paragraph();
        var container = new InlineUIContainer();
        var border = new Border();
        border.Background = (Brush)Application.Current.Resources["ExpanderHeaderBackground"];
        border.Padding = _config.Themes.Padding;
        border.Margin = _config.Themes.InternalMargin;
        border.CornerRadius = _config.Themes.CornerRadius;
        var richTextBlock = new RichTextBlock();

        if (codeBlock is FencedCodeBlock fencedCodeBlock)
        {
//#if !WINAPPSDK
//            var formatter = new ColorCode.RichTextBlockFormatter(Extensions.GetOneDarkProStyle());
//#else
//            var formatter = new ColorCode.RichTextBlockFormatter(Extensions.GetOneDarkProStyle());
//#endif
            var stringBuilder = new StringBuilder();

            // go through all the lines backwards and only add the lines to a stack if we have encountered the first non-empty line
            var lines = fencedCodeBlock.Lines.Lines;
            var stack = new Stack<string>();
            var encounteredFirstNonEmptyLine = false;
            if (lines != null)
            {
                for (var i = lines.Length - 1; i >= 0; i--)
                {
                    var line = lines[i];
                    if (String.IsNullOrWhiteSpace(line.ToString()) && !encounteredFirstNonEmptyLine)
                    {
                        continue;
                    }

                    encounteredFirstNonEmptyLine = true;
                    stack.Push(line.ToString());
                }

                // append all the lines in the stack to the string builder
                while (stack.Count > 0)
                {
                    stringBuilder.AppendLine(stack.Pop());
                }
            }

            //formatter.FormatRichTextBlock(stringBuilder.ToString(), fencedCodeBlock.ToLanguage(), richTextBlock);
        }
        else
        {
            foreach (var line in codeBlock.Lines.Lines)
            {
                var paragraph = new Paragraph();
                var lineString = line.ToString();
                if (!String.IsNullOrWhiteSpace(lineString))
                {
                    paragraph.Inlines.Add(new Run() { Text = lineString });
                }
                richTextBlock.Blocks.Add(paragraph);
            }
        }
        border.Child = richTextBlock;
        container.Child = border;
        _paragraph.Inlines.Add(container);
    }

    public void AddChild(IAddChild child) {}
}

Steps to reproduce

1) Add in the pre-release version of the MarkdownTextBox from Labs-Windows feed.
2) Add MarkdownTextBox to XAML page.
3) Add in markdown text that contains a code snippet.
4) Code block is rendered and it appears empty with no content.

Expected behavior

Can see the lines of code rendered within the code block.

Screenshots

No response

Code Platform

  • UWP
  • WinAppSDK / WinUI 3
  • Web Assembly (WASM)
  • Android
  • iOS
  • MacOS
  • Linux / GTK

Windows Build Number

  • Windows 10 1809 (Build 17763)
  • Windows 10 1903 (Build 18362)
  • Windows 10 1909 (Build 18363)
  • Windows 10 2004 (Build 19041)
  • Windows 10 20H2 (Build 19042)
  • Windows 10 21H1 (Build 19043)
  • Windows 11 21H2 (Build 22000)
  • Other (specify)

Other Windows Build number

No response

App minimum and target SDK version

  • Windows 10, version 1809 (Build 17763)
  • Windows 10, version 1903 (Build 18362)
  • Windows 10, version 1909 (Build 18363)
  • Windows 10, version 2004 (Build 19041)
  • Other (specify)

Other SDK version

No response

Visual Studio Version

2022

Visual Studio Build Number

No response

Device form factor

Desktop

Additional context

No response

Help us help you

Yes, but only if others can assist.

@JoeTomkinson JoeTomkinson added the bug 🐛 Something isn't working label Jun 2, 2024
@JoeTomkinson
Copy link
Author

There's actually a handful of issues upon looking over it a bit closer, so far I've identified the following:

Newlines are not handled so there's no spacing between paragraphs if there's empty lines in the markdown content.

Bullets are not indented and there's no spacing betwen the bullet and the first word of the run.

Code Block doesn't render the language type and colours as the formatting is commented out, relates directly the the initial problem, easy fix though.

Inadvertant spacing - When pasting in code that then gets rendered to a MarkdownTextblock inside of a chat bubble, it adds a lot of whitespace to the bottom of the code block, not sure why yet still looking into that one.

@beeradmoore
Copy link

beeradmoore commented Sep 8, 2024

I have some examples of the spacing and whatnot.

I am using MarkdownTextBlock in a ContentDialog. The markdown part of this looks like,

var markdownTextBlock = new MarkdownTextBlock()
{
    Text = @"DLSS Swapper should find games from your installed game libraries automatically. If your game is not listed there may be a few settings preventing it. Please check:

- Games list filter is not set to ""Hide non-DLSS games""
- Specific game library is enabled in settings

If you have checked these and your game is still not showing up there may be a bug. We would appreciate it if you could report the issue on our GitHub repository so we can make a fix and have your games better detected in the future.",
    Background = new SolidColorBrush(Microsoft.UI.Colors.Transparent),
};

In the old v7 version it would generate a window that would look like,

markdowntextblock-original

After moving to CommunityToolkit.Labs.WinUI.Controls.MarkdownTextBlock, version 0.1.240906-build.1745 it now looks like,

markdowntextblock-new

Looking at the examples I could see they were also using a MarkdownConfig object. After I created an empty one of those and applied to to the Config property I now get.

markdowntextblock-new-config

As @JoeTomkinson said, newlines and bullet spacing is broken.

Looking at the examples again I can see here is a bunch of &nbsp; symbols. So adding those in I get this code,

var markdownTextBlock = new MarkdownTextBlock()
{
    Text = @"DLSS Swapper should find games from your installed game libraries automatically. If your game is not listed there may be a few settings preventing it. Please check:

&nbsp;

- &nbsp; Games list filter is not set to ""Hide non-DLSS games""
- &nbsp; Specific game library is enabled in settings

&nbsp;

If you have checked these and your game is still not showing up there may be a bug. We would appreciate it if you could report the issue on our GitHub repository so we can make a fix and have your games better detected in the future.",
    Background = new SolidColorBrush(Microsoft.UI.Colors.Transparent),
    Config = new MarkdownConfig(),
};

which produces this output,

markdowntextblock-new-config-nbsp

It's certainly more readable, and for my in app markdown I can modify text or swap to a formatted textblock of some sort. But I also pull in release notes from GitHub which would then need the &nbsp; treatment throughout it which may then display incorrectly for older versions of the app, and then display incorrectly again when MarkdownTextBlock is more mature.

Before this goes live it would also be good to get MarkdownConfig set by default to make the migration process easier.

EDIT: I was curious what changelog looks like,

Old:

markdowntextblock-old-changelog

New:

markdowntextblock-new-changelog

@Arlodotexe Arlodotexe self-assigned this Nov 13, 2024
@Arlodotexe Arlodotexe moved this to 📋 Backlog in Toolkit 8.x Nov 13, 2024
@Arlodotexe Arlodotexe moved this from 📋 Backlog to 🔖 Ready in Toolkit 8.x Nov 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug 🐛 Something isn't working
Projects
Status: 🔖 Ready
Development

Successfully merging a pull request may close this issue.

3 participants