mirror of
https://github.com/bloxstraplabs/bloxstrap.git
synced 2025-04-21 18:11:27 -07:00
bold, italic, and better marked text support
This commit is contained in:
parent
dd70d729f1
commit
70a39376c8
@ -18,6 +18,8 @@ namespace Bloxstrap.UI.Elements.Controls
|
|||||||
[Localizability(LocalizationCategory.Text)]
|
[Localizability(LocalizationCategory.Text)]
|
||||||
class MarkdownTextBlock : TextBlock
|
class MarkdownTextBlock : TextBlock
|
||||||
{
|
{
|
||||||
|
private static MarkdownPipeline _markdownPipeline;
|
||||||
|
|
||||||
public static readonly DependencyProperty MarkdownTextProperty =
|
public static readonly DependencyProperty MarkdownTextProperty =
|
||||||
DependencyProperty.Register(nameof(MarkdownText), typeof(string), typeof(MarkdownTextBlock),
|
DependencyProperty.Register(nameof(MarkdownText), typeof(string), typeof(MarkdownTextBlock),
|
||||||
new FrameworkPropertyMetadata(string.Empty, FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsRender, OnTextMarkdownChanged));
|
new FrameworkPropertyMetadata(string.Empty, FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsRender, OnTextMarkdownChanged));
|
||||||
@ -29,43 +31,39 @@ namespace Bloxstrap.UI.Elements.Controls
|
|||||||
set => SetValue(MarkdownTextProperty, value);
|
set => SetValue(MarkdownTextProperty, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <returns>Span, skip</returns>
|
private static System.Windows.Documents.Inline? GetWpfInlineFromMarkdownInline(Markdig.Syntax.Inlines.Inline? inline)
|
||||||
private static (Span, int) GetInlineUntilEndTagDetected(Markdig.Syntax.Inlines.Inline? inline, string tagName)
|
|
||||||
{
|
|
||||||
string endTag = $"</{tagName}>"; // TODO: better way of doing this
|
|
||||||
|
|
||||||
var span = new Span();
|
|
||||||
|
|
||||||
int skip = 0;
|
|
||||||
var current = inline;
|
|
||||||
while (current is Markdig.Syntax.Inlines.Inline currentInline)
|
|
||||||
{
|
|
||||||
skip++;
|
|
||||||
|
|
||||||
if (currentInline is HtmlInline html)
|
|
||||||
{
|
|
||||||
if (html.Tag == endTag)
|
|
||||||
return (span, skip);
|
|
||||||
}
|
|
||||||
|
|
||||||
(var childInline, int childSkip) = GetWpfInlineFromMarkdownInline(currentInline);
|
|
||||||
if (childInline != null)
|
|
||||||
span.Inlines.Add(childInline);
|
|
||||||
|
|
||||||
skip += childSkip;
|
|
||||||
|
|
||||||
current = currentInline.NextSibling;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new Exception("End tag not detected");
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <returns>Inline, skip</returns>
|
|
||||||
private static (System.Windows.Documents.Inline?, int) GetWpfInlineFromMarkdownInline(Markdig.Syntax.Inlines.Inline? inline)
|
|
||||||
{
|
{
|
||||||
if (inline is LiteralInline literalInline)
|
if (inline is LiteralInline literalInline)
|
||||||
{
|
{
|
||||||
return (new Run(literalInline.ToString()), 0);
|
return new Run(literalInline.ToString());
|
||||||
|
}
|
||||||
|
else if (inline is EmphasisInline emphasisInline)
|
||||||
|
{
|
||||||
|
switch (emphasisInline.DelimiterChar)
|
||||||
|
{
|
||||||
|
case '*':
|
||||||
|
case '_':
|
||||||
|
{
|
||||||
|
if (emphasisInline.DelimiterCount == 1) // 1 = italic
|
||||||
|
{
|
||||||
|
var childInline = new Italic(GetWpfInlineFromMarkdownInline(emphasisInline.FirstChild));
|
||||||
|
return childInline;
|
||||||
|
}
|
||||||
|
else // 2 = bold
|
||||||
|
{
|
||||||
|
var childInline = new Bold(GetWpfInlineFromMarkdownInline(emphasisInline.FirstChild));
|
||||||
|
return childInline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case '=': // marked
|
||||||
|
{
|
||||||
|
var childInline = new Span(GetWpfInlineFromMarkdownInline(emphasisInline.FirstChild));
|
||||||
|
childInline.Background = new SolidColorBrush(Color.FromArgb(50, 255, 255, 255)); // TODO: better colour?
|
||||||
|
return childInline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (inline is LinkInline linkInline)
|
else if (inline is LinkInline linkInline)
|
||||||
{
|
{
|
||||||
@ -77,38 +75,23 @@ namespace Bloxstrap.UI.Elements.Controls
|
|||||||
return GetWpfInlineFromMarkdownInline(textInline);
|
return GetWpfInlineFromMarkdownInline(textInline);
|
||||||
}
|
}
|
||||||
|
|
||||||
(var childInline, int skip) = GetWpfInlineFromMarkdownInline(textInline);
|
var childInline = GetWpfInlineFromMarkdownInline(textInline);
|
||||||
|
|
||||||
return (new Hyperlink(childInline)
|
return new Hyperlink(childInline)
|
||||||
{
|
{
|
||||||
Command = GlobalViewModel.OpenWebpageCommand,
|
Command = GlobalViewModel.OpenWebpageCommand,
|
||||||
CommandParameter = url
|
CommandParameter = url
|
||||||
}, skip);
|
};
|
||||||
}
|
|
||||||
else if (inline is HtmlInline htmlInline)
|
|
||||||
{
|
|
||||||
string? tag = htmlInline.Tag; // TODO: parse tag
|
|
||||||
var nextInline = htmlInline.NextSibling;
|
|
||||||
|
|
||||||
if (tag == "<highlight>")
|
|
||||||
{
|
|
||||||
(var span, int skip) = GetInlineUntilEndTagDetected(nextInline, "highlight");
|
|
||||||
span.Background = new SolidColorBrush(Color.FromArgb(50,255,255,255));
|
|
||||||
return (span, skip);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (null, 0);
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <returns>Skip</returns>
|
private void AddMarkdownInline(Markdig.Syntax.Inlines.Inline? inline)
|
||||||
private int AddMarkdownInline(Markdig.Syntax.Inlines.Inline? inline)
|
|
||||||
{
|
{
|
||||||
(var wpfInline, int skip) = GetWpfInlineFromMarkdownInline(inline);
|
var wpfInline = GetWpfInlineFromMarkdownInline(inline);
|
||||||
if (wpfInline != null)
|
if (wpfInline != null)
|
||||||
Inlines.Add(wpfInline);
|
Inlines.Add(wpfInline);
|
||||||
|
|
||||||
return skip;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void OnTextMarkdownChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
|
private static void OnTextMarkdownChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
|
||||||
@ -119,7 +102,7 @@ namespace Bloxstrap.UI.Elements.Controls
|
|||||||
if (dependencyPropertyChangedEventArgs.NewValue is not string rawDocument)
|
if (dependencyPropertyChangedEventArgs.NewValue is not string rawDocument)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
MarkdownDocument document = Markdown.Parse(rawDocument);
|
MarkdownDocument document = Markdown.Parse(rawDocument, _markdownPipeline);
|
||||||
|
|
||||||
markdownTextBlock.Inlines.Clear();
|
markdownTextBlock.Inlines.Clear();
|
||||||
|
|
||||||
@ -130,9 +113,15 @@ namespace Bloxstrap.UI.Elements.Controls
|
|||||||
{
|
{
|
||||||
var inline = paragraphBlock.Inline.ElementAt(i);
|
var inline = paragraphBlock.Inline.ElementAt(i);
|
||||||
|
|
||||||
int skip = markdownTextBlock.AddMarkdownInline(inline);
|
markdownTextBlock.AddMarkdownInline(inline);
|
||||||
i += skip;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static MarkdownTextBlock()
|
||||||
|
{
|
||||||
|
_markdownPipeline = new MarkdownPipelineBuilder()
|
||||||
|
.UseEmphasisExtras(Markdig.Extensions.EmphasisExtras.EmphasisExtraOptions.Marked) // enable '==' support
|
||||||
|
.Build();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user