mirror of
				https://github.com/Nioux/AideDeJeu.git
				synced 2025-10-31 07:26:09 +00:00 
			
		
		
		
	ToSpeakableText
This commit is contained in:
		
							parent
							
								
									dc64a1f3da
								
							
						
					
					
						commit
						e4d6c9f542
					
				
					 1 changed files with 203 additions and 4 deletions
				
			
		|  | @ -1,5 +1,11 @@ | |||
| using AideDeJeuLib; | ||||
| using Markdig; | ||||
| using Markdig.Syntax; | ||||
| using Markdig.Syntax.Inlines; | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Diagnostics; | ||||
| using System.Linq; | ||||
| using System.Threading; | ||||
| using System.Threading.Tasks; | ||||
| using Xamarin.Forms; | ||||
|  | @ -43,12 +49,12 @@ namespace AideDeJeu.ViewModels | |||
|         private CancellationTokenSource _CancellationTokenSource = null; | ||||
|         public async Task ExecuteSpeakItemCommandAsync(Item item) | ||||
|         { | ||||
|             if(Speaking) | ||||
|             if (Speaking) | ||||
|             { | ||||
|                 ExecuteCancelSpeakCommand(); | ||||
|                 return; | ||||
|             } | ||||
|             var md = item.Markdown; | ||||
|             var md = MarkdownToSpeakableString(item.Markdown); | ||||
|             try | ||||
|             { | ||||
|                 _CancellationTokenSource = new CancellationTokenSource(); | ||||
|  | @ -56,7 +62,7 @@ namespace AideDeJeu.ViewModels | |||
|                 OnPropertyChanged(nameof(NotSpeaking)); | ||||
|                 await Xamarin.Essentials.TextToSpeech.SpeakAsync(md, _CancellationTokenSource.Token); | ||||
|             } | ||||
|             catch(Exception ex) | ||||
|             catch (Exception ex) | ||||
|             { | ||||
| 
 | ||||
|             } | ||||
|  | @ -73,5 +79,198 @@ namespace AideDeJeu.ViewModels | |||
|         { | ||||
|             _CancellationTokenSource?.Cancel(); | ||||
|         } | ||||
| 
 | ||||
|         public string MarkdownToSpeakableString(string md) | ||||
|         { | ||||
|             var pipeline = new Markdig.MarkdownPipelineBuilder().UseYamlFrontMatter().UsePipeTables().Build(); | ||||
|             var parsed = Markdig.Markdown.Parse(md, pipeline); | ||||
|             var speakable = Render(parsed.AsEnumerable()); | ||||
|             return speakable; | ||||
|         } | ||||
|         private string Render(IEnumerable<Block> blocks) | ||||
|         { | ||||
|             var phrases = ""; | ||||
|             foreach (var block in blocks) | ||||
|             { | ||||
|                 var phrase = this.Render(block); | ||||
|                 if (phrase != null) | ||||
|                 { | ||||
|                     phrases += phrase; | ||||
|                 } | ||||
|                 if (block.IsBreakable) | ||||
|                 { | ||||
|                     phrases += "\n"; | ||||
|                 } | ||||
|             } | ||||
|             return phrases; | ||||
|         } | ||||
| 
 | ||||
|         private string Render(Block block) | ||||
|         { | ||||
|             switch (block) | ||||
|             { | ||||
|                 case HeadingBlock heading: | ||||
|                     return Render(heading); | ||||
| 
 | ||||
|                 case ParagraphBlock paragraph: | ||||
|                     return Render(paragraph); | ||||
| 
 | ||||
|                 //case QuoteBlock quote: | ||||
|                 //    Render(quote); | ||||
|                 //    break; | ||||
| 
 | ||||
|                 //case CodeBlock code: | ||||
|                 //    Render(code); | ||||
|                 //    break; | ||||
| 
 | ||||
|                 case ListBlock list: | ||||
|                     return Render(list); | ||||
|                 //break; | ||||
| 
 | ||||
|                 //case ThematicBreakBlock thematicBreak: | ||||
|                 //    Render(thematicBreak); | ||||
|                 //    break; | ||||
| 
 | ||||
|                 //case HtmlBlock html: | ||||
|                 //    Render(html); | ||||
|                 //    break; | ||||
| 
 | ||||
|                 case Markdig.Extensions.Tables.Table table: | ||||
|                     return Render(table); | ||||
|                 //break; | ||||
| 
 | ||||
|                 default: | ||||
|                     Debug.WriteLine($"Can't render {block.GetType()} blocks."); | ||||
|                     return null; | ||||
|             } | ||||
| 
 | ||||
|             //if (queuedViews.Any()) | ||||
|             //{ | ||||
|             //    foreach (var view in queuedViews) | ||||
|             //    { | ||||
|             //        this.stack.Children.Add(view); | ||||
|             //    } | ||||
|             //    queuedViews.Clear(); | ||||
|             //} | ||||
|         } | ||||
| 
 | ||||
|         private string Render(HeadingBlock block) | ||||
|         { | ||||
|             return CreateFormatted(block.Inline); | ||||
|         } | ||||
| 
 | ||||
|         private string Render(ParagraphBlock block) | ||||
|         { | ||||
|             return CreateFormatted(block.Inline); | ||||
|         } | ||||
| 
 | ||||
|         private string Render(ListBlock block) | ||||
|         { | ||||
|             //listScope++; | ||||
| 
 | ||||
|             var views = ""; | ||||
|             for (int i = 0; i < block.Count(); i++) | ||||
|             { | ||||
|                 var item = block.ElementAt(i); | ||||
| 
 | ||||
|                 if (item is ListItemBlock itemBlock) | ||||
|                 { | ||||
|                     var subviews = Render(itemBlock); | ||||
|                     if (subviews != null) | ||||
|                     { | ||||
|                         views += subviews; | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             //listScope--; | ||||
|             return views; | ||||
|         } | ||||
| 
 | ||||
|         private string Render(ListItemBlock block) | ||||
|         { | ||||
|             var stack = ""; | ||||
| 
 | ||||
|             var subv = this.Render(block.AsEnumerable()); | ||||
|             subv.ToList().ForEach(v => stack += v); | ||||
| 
 | ||||
|             return stack; | ||||
|         } | ||||
| 
 | ||||
|         private string Render(Markdig.Extensions.Tables.Table tableBlock) | ||||
|         { | ||||
|             int maxColumns = 0; | ||||
|             foreach (Markdig.Extensions.Tables.TableRow row in tableBlock) | ||||
|             { | ||||
|                 maxColumns = Math.Max(maxColumns, row.Count); | ||||
|             } | ||||
| 
 | ||||
|             var table = ""; | ||||
|             foreach (Markdig.Extensions.Tables.TableRow row in tableBlock) | ||||
|             { | ||||
|                 foreach (Markdig.Extensions.Tables.TableCell cell in row) | ||||
|                 { | ||||
|                     var phrase = ""; | ||||
|                     foreach (var blockpar in cell) | ||||
|                     { | ||||
|                         var par = blockpar as Markdig.Syntax.ParagraphBlock; | ||||
|                         var blockPhrase = CreateFormatted(par.Inline); | ||||
|                         phrase += blockPhrase; | ||||
|                     } | ||||
|                     table += phrase; | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             return table; | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|         private string CreateFormatted(ContainerInline inlines) | ||||
|         { | ||||
|             var phrase = ""; | ||||
|             foreach (var inline in inlines) | ||||
|             { | ||||
|                 var spans = CreateChunks(inline); | ||||
|                 if (spans != null) | ||||
|                 { | ||||
|                     foreach (var span in spans) | ||||
|                     { | ||||
|                         phrase += span; | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             return phrase; | ||||
|         } | ||||
| 
 | ||||
|         private IEnumerable<string> CreateChunks(Inline inline) | ||||
|         { | ||||
|             switch (inline) | ||||
|             { | ||||
|                 case LiteralInline literal: | ||||
|                     return new string[] | ||||
|                     { | ||||
|                         literal.Content.Text.Substring(literal.Content.Start, literal.Content.Length) | ||||
|                     }; | ||||
|                 case EmphasisInline emphasis: | ||||
|                     var espans = emphasis.SelectMany(x => CreateChunks(x)); | ||||
|                     return espans.ToArray(); | ||||
| 
 | ||||
|                 case LineBreakInline breakline: | ||||
|                     return new string[] { "\n" }; | ||||
| 
 | ||||
|                 case LinkInline link: | ||||
|                     return link.SelectMany(x => CreateChunks(x)); | ||||
| 
 | ||||
|                 case CodeInline code: | ||||
| 
 | ||||
|                 case HtmlInline html: | ||||
| 
 | ||||
|                 default: | ||||
|                     return new string[] { }; | ||||
|             } | ||||
| 
 | ||||
| 
 | ||||
|         } | ||||
|     } | ||||
| } | ||||
| } | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Yan Maniez
						Yan Maniez