mirror of
				https://github.com/Nioux/AideDeJeu.git
				synced 2025-10-31 07:26:09 +00:00 
			
		
		
		
	MardownView déplacé à l'intérieur du projet
This commit is contained in:
		
							parent
							
								
									4649c8f7b7
								
							
						
					
					
						commit
						888bcb110a
					
				
					 11 changed files with 890 additions and 12 deletions
				
			
		|  | @ -58,11 +58,11 @@ | ||||||
|     <Reference Include="System.Xml" /> |     <Reference Include="System.Xml" /> | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
|   <ItemGroup> |   <ItemGroup> | ||||||
|     <PackageReference Include="SkiaSharp.Views.Forms"> |     <PackageReference Include="SkiaSharp.Svg"> | ||||||
|       <Version>1.60.0</Version> |       <Version>1.60.0</Version> | ||||||
|     </PackageReference> |     </PackageReference> | ||||||
|     <PackageReference Include="Xam.Forms.MarkdownView"> |     <PackageReference Include="SkiaSharp.Views.Forms"> | ||||||
|       <Version>0.0.0</Version> |       <Version>1.60.0</Version> | ||||||
|     </PackageReference> |     </PackageReference> | ||||||
|     <PackageReference Include="Xamarin.Forms"> |     <PackageReference Include="Xamarin.Forms"> | ||||||
|       <Version>3.1.0.583944</Version> |       <Version>3.1.0.583944</Version> | ||||||
|  |  | ||||||
|  | @ -175,13 +175,13 @@ | ||||||
|     </Page> |     </Page> | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
|   <ItemGroup> |   <ItemGroup> | ||||||
|  |     <PackageReference Include="SkiaSharp.Svg"> | ||||||
|  |       <Version>1.60.0</Version> | ||||||
|  |     </PackageReference> | ||||||
|     <PackageReference Include="SkiaSharp.Views.Forms"> |     <PackageReference Include="SkiaSharp.Views.Forms"> | ||||||
|       <Version>1.60.0</Version> |       <Version>1.60.0</Version> | ||||||
|     </PackageReference> |     </PackageReference> | ||||||
|     <PackageReference Include="Microsoft.NETCore.UniversalWindowsPlatform" Version="6.1.5" /> |     <PackageReference Include="Microsoft.NETCore.UniversalWindowsPlatform" Version="6.1.5" /> | ||||||
|     <PackageReference Include="Xam.Forms.MarkdownView"> |  | ||||||
|       <Version>0.0.0</Version> |  | ||||||
|     </PackageReference> |  | ||||||
|     <PackageReference Include="Xamarin.Forms"> |     <PackageReference Include="Xamarin.Forms"> | ||||||
|       <Version>3.1.0.583944</Version> |       <Version>3.1.0.583944</Version> | ||||||
|     </PackageReference> |     </PackageReference> | ||||||
|  |  | ||||||
|  | @ -111,11 +111,11 @@ | ||||||
|     <Reference Include="Xamarin.iOS" /> |     <Reference Include="Xamarin.iOS" /> | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
|   <ItemGroup> |   <ItemGroup> | ||||||
|     <PackageReference Include="SkiaSharp.Views.Forms"> |     <PackageReference Include="SkiaSharp.Svg"> | ||||||
|       <Version>1.60.0</Version> |       <Version>1.60.0</Version> | ||||||
|     </PackageReference> |     </PackageReference> | ||||||
|     <PackageReference Include="Xam.Forms.MarkdownView"> |     <PackageReference Include="SkiaSharp.Views.Forms"> | ||||||
|       <Version>0.0.0</Version> |       <Version>1.60.0</Version> | ||||||
|     </PackageReference> |     </PackageReference> | ||||||
|     <PackageReference Include="Xamarin.Forms"> |     <PackageReference Include="Xamarin.Forms"> | ||||||
|       <Version>3.1.0.583944</Version> |       <Version>3.1.0.583944</Version> | ||||||
|  |  | ||||||
|  | @ -27,8 +27,8 @@ | ||||||
| 
 | 
 | ||||||
|   <ItemGroup> |   <ItemGroup> | ||||||
|     <PackageReference Include="Markdig" Version="0.15.0" /> |     <PackageReference Include="Markdig" Version="0.15.0" /> | ||||||
|  |     <PackageReference Include="SkiaSharp.Svg" Version="1.60.0" /> | ||||||
|     <PackageReference Include="SkiaSharp.Views.Forms" Version="1.60.0" /> |     <PackageReference Include="SkiaSharp.Views.Forms" Version="1.60.0" /> | ||||||
|     <PackageReference Include="Xam.Forms.MarkdownView" Version="0.0.0" /> |  | ||||||
|     <PackageReference Include="Xamarin.Forms" Version="3.1.0.583944" /> |     <PackageReference Include="Xamarin.Forms" Version="3.1.0.583944" /> | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
| 
 | 
 | ||||||
|  | @ -49,6 +49,7 @@ | ||||||
| 
 | 
 | ||||||
|   <ItemGroup> |   <ItemGroup> | ||||||
|     <Folder Include="Data\" /> |     <Folder Include="Data\" /> | ||||||
|  |     <Folder Include="MarkdownView\" /> | ||||||
|     <Folder Include="Services\" /> |     <Folder Include="Services\" /> | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -0,0 +1,30 @@ | ||||||
|  | namespace Xam.Forms.Markdown | ||||||
|  | { | ||||||
|  |     using System.Text.RegularExpressions; | ||||||
|  | 
 | ||||||
|  |     /// <summary> | ||||||
|  |     /// A set o helper extensions for parsing Github common urls. | ||||||
|  |     /// </summary> | ||||||
|  |     public static class GithubExtensions | ||||||
|  |     { | ||||||
|  |         private static readonly Regex GithubRepoRegex = new Regex("http(s)?:\\/\\/github.com\\/([a-zA-Z0-9_-]+)\\/([a-zA-Z0-9_-]+)\\/((blob|tree)\\/([a-zA-Z0-9_-]+))?"); | ||||||
|  | 
 | ||||||
|  |         private const string GithubReadmeUrl = "https://raw.githubusercontent.com/{0}/{1}/{2}/README.md"; | ||||||
|  | 
 | ||||||
|  |         public static bool TryExtractGithubRawMarkdownUrl(string url, out string readmeUrl) | ||||||
|  |         { | ||||||
|  |             var match = GithubRepoRegex.Match(url); | ||||||
|  |             if(match.Success) | ||||||
|  |             { | ||||||
|  |                 var user = match.Groups[2].Value; | ||||||
|  |                 var repo = match.Groups[3].Value; | ||||||
|  |                 var branch = match.Groups.Count > 6 ? match.Groups[6].Value : "master"; | ||||||
|  |                 readmeUrl = string.Format(GithubReadmeUrl, user, repo, branch); | ||||||
|  |                 return true; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             readmeUrl = null; | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -0,0 +1,52 @@ | ||||||
|  | namespace Xam.Forms.Markdown.Extensions | ||||||
|  | { | ||||||
|  |     using System; | ||||||
|  |     using System.IO; | ||||||
|  |     using System.Net; | ||||||
|  |     using SkiaSharp; | ||||||
|  |     using Xamarin.Forms; | ||||||
|  |     using System.Diagnostics; | ||||||
|  | 
 | ||||||
|  |     public static class ImageExtensions | ||||||
|  |     { | ||||||
|  |         public static void RenderSvg(this Image view, string uri) | ||||||
|  |         { | ||||||
|  |             try | ||||||
|  |             { | ||||||
|  |                 var req = (HttpWebRequest)WebRequest.Create(uri); | ||||||
|  | 
 | ||||||
|  |                 var svg = new SkiaSharp.Extended.Svg.SKSvg(); | ||||||
|  |                 req.BeginGetResponse((ar) =>  | ||||||
|  |                 { | ||||||
|  |                     var res = (ar.AsyncState as HttpWebRequest).EndGetResponse(ar) as HttpWebResponse; | ||||||
|  |                     using (var stream = res.GetResponseStream()) | ||||||
|  |                     { | ||||||
|  |                         if (stream != null) | ||||||
|  |                         { | ||||||
|  |                             var picture = svg.Load(stream); | ||||||
|  | 
 | ||||||
|  |                             using (var image = SKImage.FromPicture(picture, picture.CullRect.Size.ToSizeI())) | ||||||
|  |                             using (var data = image.Encode(SKEncodedImageFormat.Jpeg, 80)) | ||||||
|  |                             { | ||||||
|  |                                 var ms = new MemoryStream(); | ||||||
|  | 
 | ||||||
|  |                                 if (data != null && !data.IsEmpty) | ||||||
|  |                                 { | ||||||
|  |                                     data.SaveTo(ms); | ||||||
|  |                                     ms.Seek(0, SeekOrigin.Begin); | ||||||
|  |                                     ms.Position = 0; | ||||||
|  |                                     view.Source = ImageSource.FromStream(() => ms); | ||||||
|  |                                 } | ||||||
|  |                             } | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                 }, req); | ||||||
|  | 
 | ||||||
|  |             } | ||||||
|  |             catch (Exception ex) | ||||||
|  |             { | ||||||
|  |                 Debug.WriteLine($"Failed to render svg: {ex}"); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										21
									
								
								AideDeJeu/AideDeJeu/MarkdownView/MarkdownStyle.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								AideDeJeu/AideDeJeu/MarkdownView/MarkdownStyle.cs
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,21 @@ | ||||||
|  | namespace Xam.Forms.Markdown | ||||||
|  | { | ||||||
|  |     using Xamarin.Forms; | ||||||
|  | 
 | ||||||
|  |     public class MarkdownStyle | ||||||
|  |     { | ||||||
|  |         public FontAttributes Attributes { get; set; } = FontAttributes.None; | ||||||
|  | 
 | ||||||
|  |         public float FontSize { get; set; } = 12; | ||||||
|  | 
 | ||||||
|  |         public Color ForegroundColor { get; set; } = Color.Black; | ||||||
|  | 
 | ||||||
|  |         public Color BackgroundColor { get; set; } = Color.Transparent; | ||||||
|  | 
 | ||||||
|  |         public Color BorderColor { get; set; } | ||||||
|  | 
 | ||||||
|  |         public float BorderSize { get; set; } | ||||||
|  | 
 | ||||||
|  |         public string FontFamily { get; set; } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										204
									
								
								AideDeJeu/AideDeJeu/MarkdownView/MarkdownTheme.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										204
									
								
								AideDeJeu/AideDeJeu/MarkdownView/MarkdownTheme.cs
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,204 @@ | ||||||
|  |  | ||||||
|  | namespace Xam.Forms.Markdown | ||||||
|  | { | ||||||
|  |     using Xamarin.Forms; | ||||||
|  | 
 | ||||||
|  |     public class MarkdownTheme | ||||||
|  |     { | ||||||
|  |         public MarkdownTheme() | ||||||
|  |         { | ||||||
|  |             this.Paragraph = new MarkdownStyle | ||||||
|  |             { | ||||||
|  |                 Attributes = FontAttributes.None, | ||||||
|  |                 BackgroundColor = Color.White, | ||||||
|  |                 FontSize = 12, | ||||||
|  |             }; | ||||||
|  | 
 | ||||||
|  |             this.Heading1 = new MarkdownStyle | ||||||
|  |             { | ||||||
|  |                 Attributes = FontAttributes.Bold, | ||||||
|  |                 BorderSize = 1, | ||||||
|  |                 FontSize = 26, | ||||||
|  |             }; | ||||||
|  | 
 | ||||||
|  |             this.Heading2 = new MarkdownStyle | ||||||
|  |             { | ||||||
|  |                 Attributes = FontAttributes.Bold, | ||||||
|  |                 BorderSize = 1, | ||||||
|  |                 FontSize = 22, | ||||||
|  |             }; | ||||||
|  | 
 | ||||||
|  |             this.Heading3 = new MarkdownStyle | ||||||
|  |             { | ||||||
|  |                 Attributes = FontAttributes.Bold, | ||||||
|  |                 FontSize = 20, | ||||||
|  |             }; | ||||||
|  | 
 | ||||||
|  |             this.Heading4 = new MarkdownStyle | ||||||
|  |             { | ||||||
|  |                 Attributes = FontAttributes.Bold, | ||||||
|  |                 FontSize = 18, | ||||||
|  |             }; | ||||||
|  | 
 | ||||||
|  |             this.Heading5 = new MarkdownStyle | ||||||
|  |             { | ||||||
|  |                 Attributes = FontAttributes.Bold, | ||||||
|  |                 FontSize = 16, | ||||||
|  |             }; | ||||||
|  | 
 | ||||||
|  |             this.Heading6 = new MarkdownStyle | ||||||
|  |             { | ||||||
|  |                 Attributes = FontAttributes.Bold, | ||||||
|  |                 FontSize = 14, | ||||||
|  |             }; | ||||||
|  | 
 | ||||||
|  |             this.Link = new MarkdownStyle | ||||||
|  |             { | ||||||
|  |                 Attributes = FontAttributes.None, | ||||||
|  |                 FontSize = 12, | ||||||
|  |             }; | ||||||
|  | 
 | ||||||
|  |             this.Code = new MarkdownStyle | ||||||
|  |             { | ||||||
|  |                 Attributes = FontAttributes.None, | ||||||
|  |                 FontSize = 12, | ||||||
|  |             }; | ||||||
|  | 
 | ||||||
|  |             this.Quote = new MarkdownStyle | ||||||
|  |             { | ||||||
|  |                 Attributes = FontAttributes.None, | ||||||
|  |                 BorderSize = 4, | ||||||
|  |                 FontSize = 12, | ||||||
|  |                 BackgroundColor = Color.Gray.MultiplyAlpha(.1), | ||||||
|  |             }; | ||||||
|  | 
 | ||||||
|  |             this.Separator = new MarkdownStyle | ||||||
|  |             { | ||||||
|  |                 BorderSize = 2, | ||||||
|  |             }; | ||||||
|  | 
 | ||||||
|  |             this.TableHeader = new MarkdownStyle | ||||||
|  |             { | ||||||
|  |                 Attributes = FontAttributes.Bold, | ||||||
|  |                 FontSize = 12, | ||||||
|  |                 BorderSize = 1, | ||||||
|  |                 ForegroundColor = Color.White, | ||||||
|  |                 BackgroundColor = Color.Silver, | ||||||
|  |             }; | ||||||
|  | 
 | ||||||
|  |             // Platform specific properties | ||||||
|  |             switch (Device.RuntimePlatform) | ||||||
|  |             { | ||||||
|  |                 case Device.iOS: | ||||||
|  |                     Code.FontFamily = "Courier"; | ||||||
|  |                     break; | ||||||
|  | 
 | ||||||
|  |                 case Device.Android: | ||||||
|  |                     Code.FontFamily = "monospace"; | ||||||
|  |                     break; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public Color BackgroundColor { get; set; } | ||||||
|  | 
 | ||||||
|  |         public MarkdownStyle Paragraph { get; set; }  | ||||||
|  | 
 | ||||||
|  |         public MarkdownStyle Heading1 { get; set; }  | ||||||
|  | 
 | ||||||
|  |         public MarkdownStyle Heading2 { get; set; }  | ||||||
|  | 
 | ||||||
|  |         public MarkdownStyle Heading3 { get; set; }  | ||||||
|  | 
 | ||||||
|  |         public MarkdownStyle Heading4 { get; set; }  | ||||||
|  | 
 | ||||||
|  |         public MarkdownStyle Heading5 { get; set; } | ||||||
|  | 
 | ||||||
|  |         public MarkdownStyle Heading6 { get; set; } | ||||||
|  | 
 | ||||||
|  |         public MarkdownStyle Quote { get; set; } | ||||||
|  | 
 | ||||||
|  |         public MarkdownStyle Separator { get; set; } | ||||||
|  | 
 | ||||||
|  |         public MarkdownStyle Link { get; set; } | ||||||
|  | 
 | ||||||
|  |         public MarkdownStyle Code { get; set; } | ||||||
|  | 
 | ||||||
|  |         public MarkdownStyle TableHeader { get; set; } | ||||||
|  | 
 | ||||||
|  |         public float Margin { get; set; } = 10; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public class LightMarkdownTheme : MarkdownTheme | ||||||
|  |     { | ||||||
|  |         public LightMarkdownTheme() | ||||||
|  |         { | ||||||
|  |             this.BackgroundColor = DefaultBackgroundColor; | ||||||
|  |             this.Paragraph.ForegroundColor = DefaultTextColor; | ||||||
|  |             this.Heading1.ForegroundColor = DefaultTextColor; | ||||||
|  |             this.Heading1.BorderColor = DefaultSeparatorColor; | ||||||
|  |             this.Heading2.ForegroundColor = DefaultTextColor; | ||||||
|  |             this.Heading2.BorderColor = DefaultSeparatorColor; | ||||||
|  |             this.Heading3.ForegroundColor = DefaultTextColor; | ||||||
|  |             this.Heading4.ForegroundColor = DefaultTextColor; | ||||||
|  |             this.Heading5.ForegroundColor = DefaultTextColor; | ||||||
|  |             this.Heading6.ForegroundColor = DefaultTextColor; | ||||||
|  |             this.Link.ForegroundColor = DefaultAccentColor; | ||||||
|  |             this.Code.ForegroundColor = DefaultTextColor; | ||||||
|  |             this.Code.BackgroundColor = DefaultCodeBackground; | ||||||
|  |             this.Quote.ForegroundColor = DefaultQuoteTextColor; | ||||||
|  |             this.Quote.BorderColor = DefaultQuoteBorderColor; | ||||||
|  |             this.Separator.BorderColor = DefaultSeparatorColor; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public static readonly Color DefaultBackgroundColor = Color.FromHex("#ffffff"); | ||||||
|  | 
 | ||||||
|  |         public static readonly Color DefaultAccentColor = Color.FromHex("#0366d6"); | ||||||
|  | 
 | ||||||
|  |         public static readonly Color DefaultTextColor = Color.FromHex("#24292e"); | ||||||
|  | 
 | ||||||
|  |         public static readonly Color DefaultCodeBackground = Color.FromHex("#f6f8fa"); | ||||||
|  | 
 | ||||||
|  |         public static readonly Color DefaultSeparatorColor = Color.FromHex("#eaecef"); | ||||||
|  | 
 | ||||||
|  |         public static readonly Color DefaultQuoteTextColor = Color.FromHex("#6a737d"); | ||||||
|  | 
 | ||||||
|  |         public static readonly Color DefaultQuoteBorderColor = Color.FromHex("#dfe2e5"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public class DarkMarkdownTheme : MarkdownTheme | ||||||
|  |     { | ||||||
|  |         public DarkMarkdownTheme() | ||||||
|  |         { | ||||||
|  |             this.BackgroundColor = DefaultBackgroundColor; | ||||||
|  |             this.Paragraph.ForegroundColor = DefaultTextColor; | ||||||
|  |             this.Heading1.ForegroundColor = DefaultTextColor; | ||||||
|  |             this.Heading1.BorderColor = DefaultSeparatorColor; | ||||||
|  |             this.Heading2.ForegroundColor = DefaultTextColor; | ||||||
|  |             this.Heading2.BorderColor = DefaultSeparatorColor; | ||||||
|  |             this.Heading3.ForegroundColor = DefaultTextColor; | ||||||
|  |             this.Heading4.ForegroundColor = DefaultTextColor; | ||||||
|  |             this.Heading5.ForegroundColor = DefaultTextColor; | ||||||
|  |             this.Heading6.ForegroundColor = DefaultTextColor; | ||||||
|  |             this.Link.ForegroundColor = DefaultAccentColor; | ||||||
|  |             this.Code.ForegroundColor = DefaultTextColor; | ||||||
|  |             this.Code.BackgroundColor = DefaultCodeBackground; | ||||||
|  |             this.Quote.ForegroundColor = DefaultQuoteTextColor; | ||||||
|  |             this.Quote.BorderColor = DefaultQuoteBorderColor; | ||||||
|  |             this.Separator.BorderColor = DefaultSeparatorColor; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public static readonly Color DefaultBackgroundColor = Color.FromHex("#2b303b"); | ||||||
|  | 
 | ||||||
|  |         public static readonly Color DefaultAccentColor = Color.FromHex("#d08770"); | ||||||
|  | 
 | ||||||
|  |         public static readonly Color DefaultTextColor = Color.FromHex("#eff1f5"); | ||||||
|  | 
 | ||||||
|  |         public static readonly Color DefaultCodeBackground = Color.FromHex("#4f5b66"); | ||||||
|  | 
 | ||||||
|  |         public static readonly Color DefaultSeparatorColor = Color.FromHex("#65737e"); | ||||||
|  | 
 | ||||||
|  |         public static readonly Color DefaultQuoteTextColor = Color.FromHex("#a7adba"); | ||||||
|  | 
 | ||||||
|  |         public static readonly Color DefaultQuoteBorderColor = Color.FromHex("#a7adba"); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										570
									
								
								AideDeJeu/AideDeJeu/MarkdownView/MarkdownView.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										570
									
								
								AideDeJeu/AideDeJeu/MarkdownView/MarkdownView.cs
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,570 @@ | ||||||
|  | namespace Xam.Forms.Markdown | ||||||
|  | { | ||||||
|  |     using System.Linq; | ||||||
|  |     using Markdig.Syntax; | ||||||
|  |     using Markdig.Syntax.Inlines; | ||||||
|  |     using Xamarin.Forms; | ||||||
|  |     using System; | ||||||
|  |     using System.Collections.Generic; | ||||||
|  |     using System.Diagnostics; | ||||||
|  |     using System.IO; | ||||||
|  |     using Extensions; | ||||||
|  |     using Markdig; | ||||||
|  | 
 | ||||||
|  |     public class MarkdownView : ContentView | ||||||
|  |     { | ||||||
|  |         public Action<string> NavigateToLink { get; set; } = (s) => Device.OpenUri(new Uri(s)); | ||||||
|  | 
 | ||||||
|  |         public static MarkdownTheme Global = new LightMarkdownTheme(); | ||||||
|  | 
 | ||||||
|  |         public string Markdown | ||||||
|  |         { | ||||||
|  |             get { return (string)GetValue(MarkdownProperty); } | ||||||
|  |             set { SetValue(MarkdownProperty, value); } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public static readonly BindableProperty MarkdownProperty = BindableProperty.Create(nameof(Markdown), typeof(string), typeof(MarkdownView), null, propertyChanged: OnMarkdownChanged); | ||||||
|  | 
 | ||||||
|  |         public string RelativeUrlHost | ||||||
|  |         { | ||||||
|  |             get { return (string)GetValue(RelativeUrlHostProperty); } | ||||||
|  |             set { SetValue(RelativeUrlHostProperty, value); } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public static readonly BindableProperty RelativeUrlHostProperty = BindableProperty.Create(nameof(RelativeUrlHost), typeof(string), typeof(MarkdownView), null, propertyChanged: OnMarkdownChanged); | ||||||
|  | 
 | ||||||
|  |         public MarkdownTheme Theme | ||||||
|  |         { | ||||||
|  |             get { return (MarkdownTheme)GetValue(ThemeProperty); } | ||||||
|  |             set { SetValue(ThemeProperty, value); } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public static readonly BindableProperty ThemeProperty = BindableProperty.Create(nameof(Theme), typeof(MarkdownTheme), typeof(MarkdownView), Global, propertyChanged: OnMarkdownChanged); | ||||||
|  | 
 | ||||||
|  |         private bool isQuoted; | ||||||
|  | 
 | ||||||
|  |         private List<View> queuedViews = new List<View>(); | ||||||
|  | 
 | ||||||
|  |         static void OnMarkdownChanged(BindableObject bindable, object oldValue, object newValue) | ||||||
|  |         { | ||||||
|  |             var view = bindable as MarkdownView; | ||||||
|  |             view.RenderMarkdown(); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         private StackLayout stack; | ||||||
|  | 
 | ||||||
|  |         private List<KeyValuePair<string, string>> links = new List<KeyValuePair<string, string>>(); | ||||||
|  | 
 | ||||||
|  |         private void RenderMarkdown() | ||||||
|  |         { | ||||||
|  |             stack = new StackLayout() | ||||||
|  |             { | ||||||
|  |                 Spacing = this.Theme.Margin, | ||||||
|  |             }; | ||||||
|  | 
 | ||||||
|  |             this.Padding = this.Theme.Margin; | ||||||
|  | 
 | ||||||
|  |             this.BackgroundColor = this.Theme.BackgroundColor; | ||||||
|  | 
 | ||||||
|  |             if(!string.IsNullOrEmpty(this.Markdown)) | ||||||
|  |             { | ||||||
|  |                 var pipeline = new Markdig.MarkdownPipelineBuilder().UsePipeTables().Build(); | ||||||
|  |                 var parsed = Markdig.Markdown.Parse(this.Markdown, pipeline); | ||||||
|  |                 this.Render(parsed.AsEnumerable()); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             this.Content = stack; | ||||||
|  | 
 | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         private void Render(IEnumerable<Block> blocks) | ||||||
|  |         { | ||||||
|  |             foreach (var block in blocks) | ||||||
|  |             { | ||||||
|  |                 this.Render(block); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         private void AttachLinks(View view) | ||||||
|  |         { | ||||||
|  |             if (links.Any()) | ||||||
|  |             { | ||||||
|  |                 var blockLinks = links; | ||||||
|  |                 view.GestureRecognizers.Add(new TapGestureRecognizer | ||||||
|  |                 { | ||||||
|  |                     Command = new Command(async () =>  | ||||||
|  |                     { | ||||||
|  |                         try | ||||||
|  |                         { | ||||||
|  |                             if (blockLinks.Count > 1) | ||||||
|  |                             { | ||||||
|  |                                 var result = await Application.Current.MainPage.DisplayActionSheet("Open link", "Cancel", null, blockLinks.Select(x => x.Key).ToArray()); | ||||||
|  |                                 var link = blockLinks.FirstOrDefault(x => x.Key == result); | ||||||
|  |                                 NavigateToLink(link.Value); | ||||||
|  |                             } | ||||||
|  |                             else | ||||||
|  |                             { | ||||||
|  |                                 NavigateToLink(blockLinks.First().Value); | ||||||
|  |                             } | ||||||
|  |                         } | ||||||
|  |                         catch (Exception) { } | ||||||
|  |                     }), | ||||||
|  |                 }); | ||||||
|  | 
 | ||||||
|  |                 links = new List<KeyValuePair<string, string>>(); | ||||||
|  |             }  | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         #region Rendering blocks | ||||||
|  | 
 | ||||||
|  |         private void Render(Block block) | ||||||
|  |         { | ||||||
|  |             switch (block) | ||||||
|  |             { | ||||||
|  |                 case HeadingBlock heading: | ||||||
|  |                     Render(heading); | ||||||
|  |                     break; | ||||||
|  | 
 | ||||||
|  |                 case ParagraphBlock paragraph: | ||||||
|  |                     Render(paragraph); | ||||||
|  |                     break; | ||||||
|  | 
 | ||||||
|  |                 case QuoteBlock quote: | ||||||
|  |                     Render(quote); | ||||||
|  |                     break; | ||||||
|  | 
 | ||||||
|  |                 case CodeBlock code: | ||||||
|  |                     Render(code); | ||||||
|  |                     break; | ||||||
|  | 
 | ||||||
|  |                 case ListBlock list: | ||||||
|  |                     Render(list); | ||||||
|  |                     break; | ||||||
|  | 
 | ||||||
|  |                 case ThematicBreakBlock thematicBreak: | ||||||
|  |                     Render(thematicBreak); | ||||||
|  |                     break; | ||||||
|  | 
 | ||||||
|  |                 case HtmlBlock html: | ||||||
|  |                     Render(html); | ||||||
|  |                     break; | ||||||
|  | 
 | ||||||
|  |                 case Markdig.Extensions.Tables.Table table: | ||||||
|  |                     Render(table); | ||||||
|  |                     break; | ||||||
|  | 
 | ||||||
|  |                 default: | ||||||
|  |                     Debug.WriteLine($"Can't render {block.GetType()} blocks."); | ||||||
|  |                     break; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             if(queuedViews.Any()) | ||||||
|  |             { | ||||||
|  |                 foreach (var view in queuedViews) | ||||||
|  |                 { | ||||||
|  |                     this.stack.Children.Add(view); | ||||||
|  |                 } | ||||||
|  |                 queuedViews.Clear(); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         private int listScope; | ||||||
|  | 
 | ||||||
|  |         private void Render(ThematicBreakBlock block) | ||||||
|  |         { | ||||||
|  |             var style = this.Theme.Separator; | ||||||
|  | 
 | ||||||
|  |             if (style.BorderSize > 0) | ||||||
|  |             { | ||||||
|  |                 stack.Children.Add(new BoxView | ||||||
|  |                 { | ||||||
|  |                     HeightRequest = style.BorderSize, | ||||||
|  |                     BackgroundColor = style.BorderColor, | ||||||
|  |                 }); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         private void Render(ListBlock block) | ||||||
|  |         { | ||||||
|  |             listScope++; | ||||||
|  | 
 | ||||||
|  |             for (int i = 0; i < block.Count(); i++) | ||||||
|  |             { | ||||||
|  |                 var item = block.ElementAt(i); | ||||||
|  | 
 | ||||||
|  |                 if (item is ListItemBlock itemBlock) | ||||||
|  |                 { | ||||||
|  |                     this.Render(block, i + 1, itemBlock); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             listScope--; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         private void Render(ListBlock parent, int index, ListItemBlock block) | ||||||
|  |         { | ||||||
|  |             var initialStack = this.stack; | ||||||
|  | 
 | ||||||
|  |             this.stack = new StackLayout() | ||||||
|  |             { | ||||||
|  |                 Spacing = this.Theme.Margin, | ||||||
|  |             }; | ||||||
|  | 
 | ||||||
|  |             this.Render(block.AsEnumerable()); | ||||||
|  | 
 | ||||||
|  |             var horizontalStack = new StackLayout | ||||||
|  |             { | ||||||
|  |                 Orientation = StackOrientation.Horizontal, | ||||||
|  |                 Margin = new Thickness(listScope * this.Theme.Margin, 0, 0, 0), | ||||||
|  |             }; | ||||||
|  | 
 | ||||||
|  |             View bullet; | ||||||
|  | 
 | ||||||
|  |             if (parent.IsOrdered) | ||||||
|  |             { | ||||||
|  |                 bullet = new Label | ||||||
|  |                 { | ||||||
|  |                     Text = $"{index}.", | ||||||
|  |                     FontSize = this.Theme.Paragraph.FontSize, | ||||||
|  |                     TextColor = this.Theme.Paragraph.ForegroundColor, | ||||||
|  |                     VerticalOptions = LayoutOptions.Start, | ||||||
|  |                     HorizontalOptions = LayoutOptions.End, | ||||||
|  |                 }; | ||||||
|  |             } | ||||||
|  |             else | ||||||
|  |             { | ||||||
|  |                 bullet = new BoxView | ||||||
|  |                 { | ||||||
|  |                     WidthRequest = 4, | ||||||
|  |                     HeightRequest = 4, | ||||||
|  |                     Margin = new Thickness(0, 6, 0, 0), | ||||||
|  |                     BackgroundColor = this.Theme.Paragraph.ForegroundColor, | ||||||
|  |                     VerticalOptions = LayoutOptions.Start, | ||||||
|  |                     HorizontalOptions = LayoutOptions.Center, | ||||||
|  |                 }; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             horizontalStack.Children.Add(bullet); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |             horizontalStack.Children.Add(this.stack); | ||||||
|  |             initialStack.Children.Add(horizontalStack); | ||||||
|  | 
 | ||||||
|  |             this.stack = initialStack; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         private void Render(HeadingBlock block) | ||||||
|  |         { | ||||||
|  |             MarkdownStyle style; | ||||||
|  | 
 | ||||||
|  |             switch (block.Level) | ||||||
|  |             { | ||||||
|  |                 case 1: | ||||||
|  |                     style = this.Theme.Heading1; | ||||||
|  |                     break; | ||||||
|  |                 case 2: | ||||||
|  |                     style = this.Theme.Heading2; | ||||||
|  |                     break; | ||||||
|  |                 case 3: | ||||||
|  |                     style = this.Theme.Heading3; | ||||||
|  |                     break; | ||||||
|  |                 case 4: | ||||||
|  |                     style = this.Theme.Heading4; | ||||||
|  |                     break; | ||||||
|  |                 case 5: | ||||||
|  |                     style = this.Theme.Heading5; | ||||||
|  |                     break; | ||||||
|  |                 default: | ||||||
|  |                     style = this.Theme.Heading6; | ||||||
|  |                     break; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             var foregroundColor = isQuoted ? this.Theme.Quote.ForegroundColor : style.ForegroundColor; | ||||||
|  | 
 | ||||||
|  |             var label = new Label | ||||||
|  |             { | ||||||
|  |                 FormattedText = CreateFormatted(block.Inline, style.FontFamily, style.Attributes, foregroundColor, style.BackgroundColor, style.FontSize), | ||||||
|  |             }; | ||||||
|  | 
 | ||||||
|  |             AttachLinks(label); | ||||||
|  | 
 | ||||||
|  |             if (style.BorderSize > 0) | ||||||
|  |             { | ||||||
|  |                 var headingStack = new StackLayout(); | ||||||
|  |                 headingStack.Children.Add(label); | ||||||
|  |                 headingStack.Children.Add(new BoxView | ||||||
|  |                 { | ||||||
|  |                     HeightRequest = style.BorderSize, | ||||||
|  |                     BackgroundColor = style.BorderColor, | ||||||
|  |                 }); | ||||||
|  |                 stack.Children.Add(headingStack); | ||||||
|  |             } | ||||||
|  |             else | ||||||
|  |             { | ||||||
|  |                 stack.Children.Add(label); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         private void Render(ParagraphBlock block) | ||||||
|  |         { | ||||||
|  |             var style = this.Theme.Paragraph; | ||||||
|  |             var foregroundColor = isQuoted ? this.Theme.Quote.ForegroundColor : style.ForegroundColor; | ||||||
|  |             var label = new Label | ||||||
|  |             { | ||||||
|  |                 FormattedText = CreateFormatted(block.Inline, style.FontFamily, style.Attributes, foregroundColor, style.BackgroundColor, style.FontSize), | ||||||
|  |             }; | ||||||
|  |             AttachLinks(label); | ||||||
|  |             this.stack.Children.Add(label); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         private void Render(HtmlBlock block) | ||||||
|  |         { | ||||||
|  |             // ? | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         private void Render(QuoteBlock block) | ||||||
|  |         { | ||||||
|  |             var initialIsQuoted = this.isQuoted; | ||||||
|  |             var initialStack = this.stack; | ||||||
|  | 
 | ||||||
|  |             this.isQuoted = true; | ||||||
|  |             this.stack = new StackLayout() | ||||||
|  |             { | ||||||
|  |                 Spacing = this.Theme.Margin, | ||||||
|  |             }; | ||||||
|  | 
 | ||||||
|  |             var style = this.Theme.Quote; | ||||||
|  | 
 | ||||||
|  |             if (style.BorderSize > 0) | ||||||
|  |             { | ||||||
|  |                 var horizontalStack = new StackLayout() | ||||||
|  |                 { | ||||||
|  |                     Orientation = StackOrientation.Horizontal, | ||||||
|  |                     BackgroundColor = this.Theme.Quote.BackgroundColor, | ||||||
|  |                 }; | ||||||
|  | 
 | ||||||
|  |                 horizontalStack.Children.Add(new BoxView() | ||||||
|  |                 { | ||||||
|  |                     WidthRequest = style.BorderSize, | ||||||
|  |                     BackgroundColor = style.BorderColor, | ||||||
|  |                 }); | ||||||
|  | 
 | ||||||
|  |                 horizontalStack.Children.Add(this.stack); | ||||||
|  |                 initialStack.Children.Add(horizontalStack); | ||||||
|  |             } | ||||||
|  |             else | ||||||
|  |             { | ||||||
|  |                 stack.BackgroundColor = this.Theme.Quote.BackgroundColor; | ||||||
|  |                 initialStack.Children.Add(this.stack); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             this.Render(block.AsEnumerable()); | ||||||
|  | 
 | ||||||
|  |             this.isQuoted = initialIsQuoted; | ||||||
|  |             this.stack = initialStack; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         private void Render(CodeBlock block) | ||||||
|  |         { | ||||||
|  |             var style = this.Theme.Code; | ||||||
|  |             var label = new Label | ||||||
|  |             { | ||||||
|  |                 TextColor = style.ForegroundColor, | ||||||
|  |                 FontAttributes = style.Attributes, | ||||||
|  |                 FontFamily = style.FontFamily, | ||||||
|  |                 FontSize = style.FontSize, | ||||||
|  |                 Text = string.Join(Environment.NewLine, block.Lines), | ||||||
|  |             }; | ||||||
|  |             stack.Children.Add(new Frame() | ||||||
|  |             { | ||||||
|  |                 CornerRadius = 3, | ||||||
|  |                 HasShadow = false, | ||||||
|  |                 Padding = this.Theme.Margin, | ||||||
|  |                 BackgroundColor = style.BackgroundColor, | ||||||
|  |                 Content = label | ||||||
|  |             }); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         private void Render(Markdig.Extensions.Tables.Table tableBlock) | ||||||
|  |         { | ||||||
|  |             var scroll = new ScrollView() { HorizontalScrollBarVisibility = ScrollBarVisibility.Default, Orientation = ScrollOrientation.Horizontal }; | ||||||
|  |             var grid = new Grid() { HorizontalOptions = LayoutOptions.Start, Margin = 0, Padding = 1, BackgroundColor = Theme.TableHeader.BackgroundColor, RowSpacing = 1, ColumnSpacing = 1 }; | ||||||
|  | 
 | ||||||
|  |             int top = 0; | ||||||
|  |             int maxColumns = 0; | ||||||
|  |             foreach (Markdig.Extensions.Tables.TableRow row in tableBlock) | ||||||
|  |             { | ||||||
|  |                 int left = 0; | ||||||
|  |                 foreach(Markdig.Extensions.Tables.TableCell cell in row) | ||||||
|  |                 { | ||||||
|  |                     foreach (var blockpar in cell) | ||||||
|  |                     { | ||||||
|  |                         var par = blockpar as Markdig.Syntax.ParagraphBlock; | ||||||
|  |                         var style = row.IsHeader ? Theme.TableHeader : Theme.Paragraph; | ||||||
|  |                         var frame = new Frame | ||||||
|  |                         { | ||||||
|  |                             BackgroundColor = style.BackgroundColor, | ||||||
|  |                             Margin = 1, | ||||||
|  |                             Padding = 5, | ||||||
|  |                         }; | ||||||
|  |                         var label = new Label | ||||||
|  |                         { | ||||||
|  |                             FormattedText = CreateFormatted(par.Inline, style.FontFamily, style.Attributes, style.ForegroundColor, style.BackgroundColor, style.FontSize), | ||||||
|  |                             HorizontalOptions = LayoutOptions.CenterAndExpand, | ||||||
|  |                             BackgroundColor = style.BackgroundColor, | ||||||
|  |                             VerticalTextAlignment = TextAlignment.Center, | ||||||
|  |                             HorizontalTextAlignment = TextAlignment.Center, | ||||||
|  |                         }; | ||||||
|  |                         frame.Content = label; | ||||||
|  |                         AttachLinks(label); | ||||||
|  |                         grid.Children.Add(frame, left, top); | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     left++; | ||||||
|  |                     maxColumns = Math.Max(maxColumns, left); | ||||||
|  |                 } | ||||||
|  |                 grid.RowDefinitions.Add(new RowDefinition { Height= GridLength.Auto }); | ||||||
|  |                 top++; | ||||||
|  |             } | ||||||
|  |             for (int i = 0; i < maxColumns; i++) | ||||||
|  |             { | ||||||
|  |                 grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto }); | ||||||
|  |             } | ||||||
|  |             double? gridHeight = null; | ||||||
|  |             grid.SizeChanged += (object sender, EventArgs e) =>  | ||||||
|  |             { | ||||||
|  |                 if (gridHeight == null) | ||||||
|  |                 { | ||||||
|  |                     gridHeight = grid.HeightRequest = grid.Height; | ||||||
|  |                 } | ||||||
|  |                 else | ||||||
|  |                 { | ||||||
|  |                     grid.HeightRequest = gridHeight.Value; | ||||||
|  |                 } | ||||||
|  |             }; | ||||||
|  | 
 | ||||||
|  |             //grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) }); | ||||||
|  |             //grid.RowDefinitions.Add(new RowDefinition { Height= new GridLength(1, GridUnitType.Star) }); | ||||||
|  |             stack.Children.Add(scroll); | ||||||
|  |             scroll.Content = grid; | ||||||
|  |             //grid.WidthRequest = 1000; | ||||||
|  |             scroll.ForceLayout(); | ||||||
|  |             this.UpdateChildrenLayout(); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |         private FormattedString CreateFormatted(ContainerInline inlines, string family, FontAttributes attributes, Color foregroundColor, Color backgroundColor, float size) | ||||||
|  |         { | ||||||
|  |             var fs = new FormattedString(); | ||||||
|  | 
 | ||||||
|  |             foreach (var inline in inlines) | ||||||
|  |             { | ||||||
|  |                 var spans = CreateSpans(inline, family, attributes, foregroundColor, backgroundColor, size); | ||||||
|  |                 if (spans != null) | ||||||
|  |                 { | ||||||
|  |                     foreach (var span in spans) | ||||||
|  |                     { | ||||||
|  |                         fs.Spans.Add(span); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             return fs; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         private Span[] CreateSpans(Inline inline, string family, FontAttributes attributes, Color foregroundColor, Color backgroundColor, float size) | ||||||
|  |         { | ||||||
|  |             switch (inline) | ||||||
|  |             { | ||||||
|  |                 case LiteralInline literal: | ||||||
|  |                     return new[] | ||||||
|  |                     { | ||||||
|  |                         new Span | ||||||
|  |                         { | ||||||
|  |                             Text = literal.Content.Text.Substring(literal.Content.Start, literal.Content.Length), | ||||||
|  |                             FontAttributes = attributes, | ||||||
|  |                             ForegroundColor = foregroundColor, | ||||||
|  |                             BackgroundColor = backgroundColor, | ||||||
|  |                             FontSize = size, | ||||||
|  |                             FontFamily = family, | ||||||
|  |                         } | ||||||
|  |                     }; | ||||||
|  | 
 | ||||||
|  |                 case EmphasisInline emphasis: | ||||||
|  |                     var childAttributes = attributes | (emphasis.IsDouble ? FontAttributes.Bold : FontAttributes.Italic); | ||||||
|  |                     return emphasis.SelectMany(x => CreateSpans(x, family, childAttributes, foregroundColor, backgroundColor, size)).ToArray(); | ||||||
|  | 
 | ||||||
|  |                 case LineBreakInline breakline: | ||||||
|  |                     return new[] { new Span { Text = "\n" } }; | ||||||
|  | 
 | ||||||
|  |                 case LinkInline link: | ||||||
|  | 
 | ||||||
|  |                     var url = link.Url; | ||||||
|  | 
 | ||||||
|  |                     if (!(url.StartsWith("http://") || url.StartsWith("https://"))) | ||||||
|  |                     { | ||||||
|  |                         url = $"{this.RelativeUrlHost?.TrimEnd('/')}/{url.TrimStart('/')}"; | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     if(link.IsImage) | ||||||
|  |                     { | ||||||
|  |                         var image = new Image(); | ||||||
|  | 
 | ||||||
|  |                         if(Path.GetExtension(url) == ".svg") | ||||||
|  |                         { | ||||||
|  |                             image.RenderSvg(url); | ||||||
|  |                         } | ||||||
|  |                         else | ||||||
|  |                         { | ||||||
|  |                             image.Source = url; | ||||||
|  |                         } | ||||||
|  | 
 | ||||||
|  |                         queuedViews.Add(image); | ||||||
|  |                         return new Span[0]; | ||||||
|  |                     } | ||||||
|  |                     else | ||||||
|  |                     { | ||||||
|  |                         var spans = link.SelectMany(x => CreateSpans(x, this.Theme.Link.FontFamily ?? family, this.Theme.Link.Attributes, this.Theme.Link.ForegroundColor, this.Theme.Link.BackgroundColor, size)).ToArray(); | ||||||
|  |                         links.Add(new KeyValuePair<string, string>(string.Join("",spans.Select(x => x.Text)), url)); | ||||||
|  |                         return spans; | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                 case CodeInline code: | ||||||
|  |                     return new[] | ||||||
|  |                     { | ||||||
|  |                         new Span() | ||||||
|  |                         { | ||||||
|  |                             Text="\u2002", | ||||||
|  |                             FontSize = size, | ||||||
|  |                             FontFamily = this.Theme.Code.FontFamily, | ||||||
|  |                             ForegroundColor = this.Theme.Code.ForegroundColor, | ||||||
|  |                             BackgroundColor = this.Theme.Code.BackgroundColor | ||||||
|  |                         }, | ||||||
|  |                         new Span | ||||||
|  |                         { | ||||||
|  |                             Text = code.Content, | ||||||
|  |                             FontAttributes = this.Theme.Code.Attributes, | ||||||
|  |                             FontSize = size, | ||||||
|  |                             FontFamily = this.Theme.Code.FontFamily, | ||||||
|  |                             ForegroundColor = this.Theme.Code.ForegroundColor, | ||||||
|  |                             BackgroundColor = this.Theme.Code.BackgroundColor | ||||||
|  |                         }, | ||||||
|  |                         new Span() | ||||||
|  |                         { | ||||||
|  |                             Text="\u2002", | ||||||
|  |                             FontSize = size, | ||||||
|  |                             FontFamily = this.Theme.Code.FontFamily, | ||||||
|  |                             ForegroundColor = this.Theme.Code.ForegroundColor, | ||||||
|  |                             BackgroundColor = this.Theme.Code.BackgroundColor | ||||||
|  |                         }, | ||||||
|  |                     }; | ||||||
|  | 
 | ||||||
|  |                 default: | ||||||
|  |                     Debug.WriteLine($"Can't render {inline.GetType()} inlines."); | ||||||
|  |                     return null; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         #endregion | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -3,7 +3,7 @@ | ||||||
|              xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" |              xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" | ||||||
|              xmlns:tools="clr-namespace:AideDeJeu.Tools" |              xmlns:tools="clr-namespace:AideDeJeu.Tools" | ||||||
|              xmlns:skia="clr-namespace:SkiaSharp.Views.Forms;assembly=SkiaSharp.Views.Forms" |              xmlns:skia="clr-namespace:SkiaSharp.Views.Forms;assembly=SkiaSharp.Views.Forms" | ||||||
|              xmlns:mdview="clr-namespace:Xam.Forms.Markdown;assembly=Xam.Forms.MarkdownView" |              xmlns:mdview="clr-namespace:Xam.Forms.Markdown" | ||||||
|              x:Class="AideDeJeu.Views.MonsterDetailPage" |              x:Class="AideDeJeu.Views.MonsterDetailPage" | ||||||
|              Title="{Binding Title}"> |              Title="{Binding Title}"> | ||||||
|     <ContentPage.Resources> |     <ContentPage.Resources> | ||||||
|  |  | ||||||
|  | @ -2,7 +2,7 @@ | ||||||
| <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" | <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" | ||||||
|              xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" |              xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" | ||||||
|              xmlns:tools="clr-namespace:AideDeJeu.Tools" |              xmlns:tools="clr-namespace:AideDeJeu.Tools" | ||||||
|              xmlns:mdview="clr-namespace:Xam.Forms.Markdown;assembly=Xam.Forms.MarkdownView" |              xmlns:mdview="clr-namespace:Xam.Forms.Markdown" | ||||||
|              x:Class="AideDeJeu.Views.SpellDetailPage" |              x:Class="AideDeJeu.Views.SpellDetailPage" | ||||||
|              Title="{Binding Title}"> |              Title="{Binding Title}"> | ||||||
|     <ContentPage.Resources> |     <ContentPage.Resources> | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Yan Maniez
						Yan Maniez