Search code examples
xamarin.formstext-to-speechxamarin.essentials

Xamarin.Forms: Issue with text to speech feature for HTML data


I am using the Label for showing HTML data on UI with TextType="Html" property. That feature works well and on UI HTML content gets converted to normal text.

I am also implemented text to speech features using Xamarin Essentials. When the TTS function starts I am highlighting the corresponding text using span property.

When the TTS function starts, the normal text gets converted into HTML data. How I fix this issue?

Screenshot:

enter image description here

I have uploaded a sample project here for the reference.


Solution

  • It will be an expected effect because the content of string is html format .As a workaround , You could get the content of the html by using Regex .

    public static string GetHtmlText(string html)
    {
       html = System.Text.RegularExpressions.Regex.Replace(html, @"<\/*[^<>]*>", "", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
       html = html.Replace("\r\n", "").Replace("\r", "").Replace("&nbsp;", "").Replace(" ", "").Replace("\n\n\n", "\n");
        return html;
    }
    

    So you could improve the code like following :

    public partial class MainPage : ContentPage
    {
        string[] strList;
        public List<ChapterDetails> chapterDetails { get; set; }
        public MainPage()
        {
            InitializeComponent();
            //normal text
            //string content = "Each platform supports different locales,\n to speak back text in different languages and accents.\n Platforms have different codes and ways of specifying the locale, \n  which is why Xamarin provides a cross-platform Locale class and a way to query them with GetLocalesAsync.\n ";
    
            //html text from epub file
            chapterDetails = new List<ChapterDetails>();
            string fileName = "Alices-Adventures-in-wonderland.epub";
            var assembly = typeof(MainPage).GetTypeInfo().Assembly;
            Stream stream = assembly.GetManifestResourceStream($"{assembly.GetName().Name}.{fileName}");
            EpubBook epubBook = EpubReader.ReadBook(stream);
            foreach (EpubChapter chapter in epubBook.Chapters)
            {
                chapterDetails.Add(new ChapterDetails() { title = chapter.Title, htmlData = chapter.HtmlContent, subChapters = chapter.SubChapters });
            }
            string content = GetHtmlText(chapterDetails[0].htmlData);
            label.Text = content;
            string str = ".";
            char character = char.Parse(str);
            string str2 = ",";
            char character2 = char.Parse(str2);
            string str3 = "\n";
            char character3 = char.Parse(str3);
            strList = content.Split(new char[] { character, character2 , character3});
        }
    
    
        public static string GetHtmlText(string html)
        {
            html = System.Text.RegularExpressions.Regex.Replace(html, @"<\/*[^<>]*>", "", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
            html = html.Replace("\r\n", "").Replace("\r", "").Replace("&nbsp;", "").Replace(" ", "").Replace("\n\n\n", "\n");
            return html;
        }
    
        private async void ClickedButton(object Sender, EventArgs args)
        {
            for (int i = 0; i < strList.Length; i++)
            {
                
                if(!string.IsNullOrEmpty(strList[i]))
                {
                    string content = strList[i];
                    var formattedString = new FormattedString();
                    for (int j = 0; j < strList.Length; j++)
                    {
                        if (i == j)
                        {
                            formattedString.Spans.Add(new Span { Text = strList[j], ForegroundColor = Color.Black, BackgroundColor = Color.Gray });
                        }
                        else
                        {
                            formattedString.Spans.Add(new Span { Text = strList[j], ForegroundColor = Color.Black, });
                        }
                    }
    
                    label.FormattedText = formattedString;
                    label.TextType = TextType.Html;
                    await TextToSpeech.SpeakAsync(content);
                }
            }
        }
    }
    

    Note : In this way the style of css will not work any more . You need to set the style (font or color) in span by yourself .