[feat:] include Markdown.Avalonia for better rendering
This commit is contained in:
+16
-15
@@ -9,25 +9,26 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Avalonia" Version="11.3.2"/>
|
<PackageReference Include="Avalonia" Version="11.3.2" />
|
||||||
<PackageReference Include="Avalonia.Controls.DataGrid" Version="11.3.2"/>
|
<PackageReference Include="Avalonia.Controls.DataGrid" Version="11.3.2" />
|
||||||
<PackageReference Include="Avalonia.Desktop" Version="11.3.2"/>
|
<PackageReference Include="Avalonia.Desktop" Version="11.3.2" />
|
||||||
<PackageReference Include="Avalonia.Themes.Fluent" Version="11.3.2"/>
|
<PackageReference Include="Avalonia.Themes.Fluent" Version="11.3.2" />
|
||||||
<PackageReference Include="Avalonia.Fonts.Inter" Version="11.3.2"/>
|
<PackageReference Include="Avalonia.Fonts.Inter" Version="11.3.2" />
|
||||||
<!--Condition below is needed to remove Avalonia.Diagnostics package from build output in Release configuration.-->
|
<!--Condition below is needed to remove Avalonia.Diagnostics package from build output in Release configuration.-->
|
||||||
<PackageReference Include="Avalonia.Diagnostics" Version="11.3.2">
|
<PackageReference Include="Avalonia.Diagnostics" Version="11.3.2">
|
||||||
<IncludeAssets Condition="'$(Configuration)' != 'Debug'">None</IncludeAssets>
|
<IncludeAssets Condition="'$(Configuration)' != 'Debug'">None</IncludeAssets>
|
||||||
<PrivateAssets Condition="'$(Configuration)' != 'Debug'">All</PrivateAssets>
|
<PrivateAssets Condition="'$(Configuration)' != 'Debug'">All</PrivateAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="ISO3166" Version="1.0.4"/>
|
<PackageReference Include="ISO3166" Version="1.0.4" />
|
||||||
<PackageReference Include="Lucide.Avalonia" Version="0.1.35"/>
|
<PackageReference Include="Lucide.Avalonia" Version="0.1.35" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.4"/>
|
<PackageReference Include="Markdown.Avalonia" Version="11.0.3" />
|
||||||
<PackageReference Include="PdfSharp" Version="6.1.1"/>
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
|
||||||
|
<PackageReference Include="PdfSharp" Version="6.1.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Markdig" Version="0.30.3"/>
|
<PackageReference Include="Markdig" Version="0.30.3" />
|
||||||
<PackageReference Include="AvaloniaEdit" Version="0.10.12"/>
|
<PackageReference Include="AvaloniaEdit" Version="0.10.12" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -37,15 +38,15 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Remove="assets\icon.ico"/>
|
<None Remove="assets\icon.ico" />
|
||||||
<AvaloniaResource Include="assets\icon.ico">
|
<AvaloniaResource Include="assets\icon.ico">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</AvaloniaResource>
|
</AvaloniaResource>
|
||||||
<None Remove="assets\calc_man.png"/>
|
<None Remove="assets\calc_man.png" />
|
||||||
<AvaloniaResource Include="assets\calc_man.png">
|
<AvaloniaResource Include="assets\calc_man.png">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</AvaloniaResource>
|
</AvaloniaResource>
|
||||||
<None Remove="assets\loading.mp4"/>
|
<None Remove="assets\loading.mp4" />
|
||||||
<AvaloniaResource Include="assets\loading.mp4">
|
<AvaloniaResource Include="assets\loading.mp4">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</AvaloniaResource>
|
</AvaloniaResource>
|
||||||
@@ -56,6 +57,6 @@
|
|||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
|
|
||||||
<Folder Include="assets\fonts\"/>
|
<Folder Include="assets\fonts\" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
+2
-3
@@ -2,6 +2,7 @@
|
|||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:md="https://github.com/whistyun/Markdown.Avalonia"
|
||||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||||
MinWidth="1000" MinHeight="600" IsVisible="False"
|
MinWidth="1000" MinHeight="600" IsVisible="False"
|
||||||
x:Class="Logof_Client.MainWindow" WindowState="Maximized" Icon="assets/icon.ico"
|
x:Class="Logof_Client.MainWindow" WindowState="Maximized" Icon="assets/icon.ico"
|
||||||
@@ -370,9 +371,7 @@
|
|||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
<Border Grid.Row="1" Margin="8" BorderBrush="#DDD" BorderThickness="1" CornerRadius="4">
|
<Border Grid.Row="1" Margin="8" BorderBrush="#DDD" BorderThickness="1" CornerRadius="4">
|
||||||
<ScrollViewer>
|
<md:MarkdownScrollViewer x:Name="MsvWikiView"/>
|
||||||
<StackPanel Name="PreviewPanel" Margin="8" />
|
|
||||||
</ScrollViewer>
|
|
||||||
</Border>
|
</Border>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|||||||
+13
-12
@@ -230,18 +230,19 @@ public partial class MainWindow : Window
|
|||||||
{
|
{
|
||||||
_selectedWikiFilePath = item.Path;
|
_selectedWikiFilePath = item.Path;
|
||||||
var text = await _wikiService.LoadFileContentAsync(item.Path);
|
var text = await _wikiService.LoadFileContentAsync(item.Path);
|
||||||
try
|
MsvWikiView.Markdown = text;
|
||||||
{
|
// try
|
||||||
PreviewPanel.Children.Clear();
|
// {
|
||||||
var rendered = MarkdownRenderer.Render(text ?? string.Empty);
|
// PreviewPanel.Children.Clear();
|
||||||
PreviewPanel.Children.Add(rendered);
|
// var rendered = MarkdownRenderer.Render(text ?? string.Empty);
|
||||||
}
|
// PreviewPanel.Children.Add(rendered);
|
||||||
catch (Exception ex)
|
// }
|
||||||
{
|
// catch (Exception ex)
|
||||||
Logger.Log($"Error while rendering markdown: {ex.Message}", Logger.LogType.Error);
|
// {
|
||||||
PreviewPanel.Children.Clear();
|
// Logger.Log($"Error while rendering markdown: {ex.Message}", Logger.LogType.Error);
|
||||||
PreviewPanel.Children.Add(new TextBlock { Text = text ?? string.Empty });
|
// PreviewPanel.Children.Clear();
|
||||||
}
|
// PreviewPanel.Children.Add(new TextBlock { Text = text ?? string.Empty });
|
||||||
|
// }
|
||||||
|
|
||||||
EditButton.IsEnabled = true;
|
EditButton.IsEnabled = true;
|
||||||
}
|
}
|
||||||
|
|||||||
+126
-126
@@ -11,130 +11,130 @@ namespace Logof_Client.Wiki;
|
|||||||
|
|
||||||
public static class MarkdownRenderer
|
public static class MarkdownRenderer
|
||||||
{
|
{
|
||||||
public static Control Render(string markdown)
|
// public static Control Render(string markdown)
|
||||||
{
|
// {
|
||||||
try
|
// try
|
||||||
{
|
// {
|
||||||
var panel = new StackPanel { Spacing = 6 };
|
// var panel = new StackPanel { Spacing = 6 };
|
||||||
if (string.IsNullOrWhiteSpace(markdown)) return panel;
|
// if (string.IsNullOrWhiteSpace(markdown)) return panel;
|
||||||
|
//
|
||||||
var doc = Markdown.Parse(markdown);
|
// var doc = Markdown.Parse(markdown);
|
||||||
|
//
|
||||||
foreach (var block in doc)
|
// foreach (var block in doc)
|
||||||
{
|
// {
|
||||||
switch (block)
|
// switch (block)
|
||||||
{
|
// {
|
||||||
case HeadingBlock hb:
|
// case HeadingBlock hb:
|
||||||
{
|
// {
|
||||||
var text = GetInlineText(hb.Inline);
|
// var text = GetInlineText(hb.Inline);
|
||||||
var tb = new TextBlock
|
// var tb = new TextBlock
|
||||||
{
|
// {
|
||||||
Text = text,
|
// Text = text,
|
||||||
FontWeight = FontWeight.Bold,
|
// FontWeight = FontWeight.Bold,
|
||||||
Margin = new Avalonia.Thickness(0, hb.Level == 1 ? 6 : 2, 0, 2)
|
// Margin = new Avalonia.Thickness(0, hb.Level == 1 ? 6 : 2, 0, 2)
|
||||||
};
|
// };
|
||||||
tb.FontSize = hb.Level switch { 1 => 22, 2 => 18, 3 => 16, _ => 14 };
|
// tb.FontSize = hb.Level switch { 1 => 22, 2 => 18, 3 => 16, _ => 14 };
|
||||||
panel.Children.Add(tb);
|
// panel.Children.Add(tb);
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
case ParagraphBlock pb:
|
// case ParagraphBlock pb:
|
||||||
{
|
// {
|
||||||
var text = GetInlineText(pb.Inline);
|
// var text = GetInlineText(pb.Inline);
|
||||||
var tb = new TextBlock { Text = text, TextWrapping = Avalonia.Media.TextWrapping.Wrap };
|
// var tb = new TextBlock { Text = text, TextWrapping = Avalonia.Media.TextWrapping.Wrap };
|
||||||
panel.Children.Add(tb);
|
// panel.Children.Add(tb);
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
case FencedCodeBlock cb:
|
// case FencedCodeBlock cb:
|
||||||
{
|
// {
|
||||||
var sb = new StringBuilder();
|
// var sb = new StringBuilder();
|
||||||
foreach (var line in cb.Lines.Lines)
|
// foreach (var line in cb.Lines.Lines)
|
||||||
{
|
// {
|
||||||
sb.Append(line.ToString());
|
// sb.Append(line.ToString());
|
||||||
}
|
// }
|
||||||
var codeBox = new TextBox
|
// var codeBox = new TextBox
|
||||||
{
|
// {
|
||||||
Text = sb.ToString(),
|
// Text = sb.ToString(),
|
||||||
FontFamily = "Consolas, monospace",
|
// FontFamily = "Consolas, monospace",
|
||||||
IsReadOnly = true,
|
// IsReadOnly = true,
|
||||||
AcceptsReturn = true
|
// AcceptsReturn = true
|
||||||
};
|
// };
|
||||||
panel.Children.Add(codeBox);
|
// panel.Children.Add(codeBox);
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
case ListBlock lb:
|
// case ListBlock lb:
|
||||||
{
|
// {
|
||||||
var sp = new StackPanel { Spacing = 2 };
|
// var sp = new StackPanel { Spacing = 2 };
|
||||||
var number = 1;
|
// var number = 1;
|
||||||
foreach (var item in lb)
|
// foreach (var item in lb)
|
||||||
{
|
// {
|
||||||
if (item is ListItemBlock lib)
|
// if (item is ListItemBlock lib)
|
||||||
{
|
// {
|
||||||
var itemText = new StringBuilder();
|
// var itemText = new StringBuilder();
|
||||||
foreach (var sub in lib)
|
// foreach (var sub in lib)
|
||||||
{
|
// {
|
||||||
if (sub is ParagraphBlock pp)
|
// if (sub is ParagraphBlock pp)
|
||||||
itemText.Append(GetInlineText(pp.Inline));
|
// itemText.Append(GetInlineText(pp.Inline));
|
||||||
}
|
// }
|
||||||
var tb = new TextBlock { Text = (lb.IsOrdered ? (number++ + ". ") : "• ") + itemText.ToString() };
|
// var tb = new TextBlock { Text = (lb.IsOrdered ? (number++ + ". ") : "• ") + itemText.ToString() };
|
||||||
sp.Children.Add(tb);
|
// sp.Children.Add(tb);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
panel.Children.Add(sp);
|
// panel.Children.Add(sp);
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
default:
|
// default:
|
||||||
{
|
// {
|
||||||
// fallback: raw text
|
// // fallback: raw text
|
||||||
panel.Children.Add(new TextBlock { Text = block.ToString() });
|
// panel.Children.Add(new TextBlock { Text = block.ToString() });
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
return panel;
|
// return panel;
|
||||||
} catch (Exception ex) { Logger.Log($"Error while : {ex.Message}",Logger.LogType.Error);}
|
// } catch (Exception ex) { Logger.Log($"Error while : {ex.Message}",Logger.LogType.Error);}
|
||||||
|
//
|
||||||
return new Panel();
|
// return new Panel();
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
private static string GetInlineText(ContainerInline? container)
|
// private static string GetInlineText(ContainerInline? container)
|
||||||
{
|
// {
|
||||||
try
|
// try
|
||||||
{
|
// {
|
||||||
if (container == null) return string.Empty;
|
// if (container == null) return string.Empty;
|
||||||
var sb = new StringBuilder();
|
// var sb = new StringBuilder();
|
||||||
foreach (var inline in container)
|
// foreach (var inline in container)
|
||||||
{
|
// {
|
||||||
switch (inline)
|
// switch (inline)
|
||||||
{
|
// {
|
||||||
case LiteralInline li:
|
// case LiteralInline li:
|
||||||
sb.Append(li.Content.ToString());
|
// sb.Append(li.Content.ToString());
|
||||||
break;
|
// break;
|
||||||
case EmphasisInline ei:
|
// case EmphasisInline ei:
|
||||||
sb.Append(GetInlineText(ei));
|
// sb.Append(GetInlineText(ei));
|
||||||
break;
|
// break;
|
||||||
case CodeInline ci:
|
// case CodeInline ci:
|
||||||
sb.Append(ci.Content);
|
// sb.Append(ci.Content);
|
||||||
break;
|
// break;
|
||||||
case LinkInline li:
|
// case LinkInline li:
|
||||||
sb.Append(GetInlineText(li));
|
// sb.Append(GetInlineText(li));
|
||||||
break;
|
// break;
|
||||||
case LineBreakInline:
|
// case LineBreakInline:
|
||||||
sb.Append("\n");
|
// sb.Append("\n");
|
||||||
break;
|
// break;
|
||||||
default:
|
// default:
|
||||||
sb.Append(inline.ToString());
|
// sb.Append(inline.ToString());
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
return sb.ToString();
|
// return sb.ToString();
|
||||||
} catch (Exception ex) { Logger.Log($"Error while : {ex.Message}",Logger.LogType.Error);}
|
// } catch (Exception ex) { Logger.Log($"Error while : {ex.Message}",Logger.LogType.Error);}
|
||||||
|
//
|
||||||
return null;
|
// return null;
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user