Skip to content

MarkdownTextBlock: Fix nested styles, sub & super #614

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

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions components/MarkdownTextBlock/src/TextElements/ICascadeChild.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// 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.


namespace CommunityToolkit.Labs.WinUI.MarkdownTextBlock.TextElements;

/// <summary>
/// Interface for elements that inherit properties from their parent.
/// </summary>
public interface ICascadeChild
{
void InheritProperties(IAddChild parent);
}
67 changes: 51 additions & 16 deletions components/MarkdownTextBlock/src/TextElements/MyEmphasisInline.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@

namespace CommunityToolkit.Labs.WinUI.MarkdownTextBlock.TextElements;

internal class MyEmphasisInline : IAddChild
internal class MyEmphasisInline : IAddChild, ICascadeChild
{
private Span _span;
private EmphasisInline _markdownObject;
private TextElement _textElementCur;

private bool _isBold;
private bool _isItalic;
private bool _isStrikeThrough;
private bool _isSuperscript;
private bool _isSubscript;

public TextElement TextElement
{
Expand All @@ -24,23 +24,25 @@ public TextElement TextElement
public MyEmphasisInline(EmphasisInline emphasisInline)
{
_span = new Span();
_textElementCur = _span;
_markdownObject = emphasisInline;
}

public void AddChild(IAddChild child)
{
try
{
if (child is ICascadeChild cascadeChild)
cascadeChild.InheritProperties(this);

var inlines = _textElementCur is Span span ? span.Inlines : ((Paragraph)_textElementCur).Inlines;
if (child is MyInlineText inlineText)
{
_span.Inlines.Add((Run)inlineText.TextElement);
inlines.Add((Run)inlineText.TextElement);
}
else if (child is MyEmphasisInline emphasisInline)
{
if (emphasisInline._isBold) { SetBold(); }
if (emphasisInline._isItalic) { SetItalic(); }
if (emphasisInline._isStrikeThrough) { SetStrikeThrough(); }
_span.Inlines.Add(emphasisInline._span);
inlines.Add(emphasisInline._span);
}
}
catch (Exception ex)
Expand All @@ -56,14 +58,11 @@ public void SetBold()
#elif WINUI2
_span.FontWeight = Windows.UI.Text.FontWeights.Bold;
#endif

_isBold = true;
}

public void SetItalic()
{
_span.FontStyle = FontStyle.Italic;
_isItalic = true;
}

public void SetStrikeThrough()
Expand All @@ -73,17 +72,53 @@ public void SetStrikeThrough()
#elif WINUI2
_span.TextDecorations = Windows.UI.Text.TextDecorations.Strikethrough;
#endif

_isStrikeThrough = true;
}

public void SetSubscript()
{
_span.SetValue(Typography.VariantsProperty, FontVariants.Subscript);
_isSubscript = true;
ConstructSubSuperContainer();
}

public void SetSuperscript()
{
_span.SetValue(Typography.VariantsProperty, FontVariants.Superscript);
_isSuperscript = true;
ConstructSubSuperContainer();
}

public void InheritProperties(IAddChild parent)
{
if (!_isSuperscript && !_isSubscript)
return;

_textElementCur.FontFamily = parent.TextElement.FontFamily;
_textElementCur.FontWeight = parent.TextElement.FontWeight;
_textElementCur.FontStyle = parent.TextElement.FontStyle;
_textElementCur.Foreground = parent.TextElement.Foreground;
}

private void ConstructSubSuperContainer()
{
// usually runs get added directly under _span.Inlines (_span -> Run)
// for sub/superscript, we use a inline container under _span to translate the Y position of the text
// (_span -> InlineUIContainer -> RichTextBlock -> Paragraph -> Run)

var container = new InlineUIContainer();
var richText = new RichTextBlock();
var paragraph = new Paragraph
{
FontSize = _span.FontSize * 0.8,
};
richText.Blocks.Add(paragraph);
container.Child = richText;

double offset = _isSuperscript ? -0.4 : 0.16;
richText.RenderTransform = new TranslateTransform
{
Y = _span.FontSize * offset
};

_span.Inlines.Add(container);
_textElementCur = paragraph;
}
}
2 changes: 2 additions & 0 deletions components/MarkdownTextBlock/src/TextElements/MyHeading.cs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ public void AddChild(IAddChild child)
{
if (child.TextElement is Inline inlineChild)
{
if (child is ICascadeChild cascadeChild)
cascadeChild.InheritProperties(this);
_paragraph.Inlines.Add(inlineChild);
}
}
Expand Down
Loading