public void ScrollToEditorLine(int editorLineNumber = -1, bool updateCodeBlocks = false, bool noScrollTimeout = false, bool noScrollTopAdjustment = false)

        {
            var doc = PreviewBrowserInterop.GetWindow(WebBrowser);

            if (doc == null)
            {
                return;
            }

            var interop = new PreviewBrowserInterop(doc);

            var editor = Window.GetActiveMarkdownEditor();

            if (editor == null)
            {
                return;
            }

            if (editorLineNumber < 0)
            {
                editorLineNumber = editor.GetLineNumber();
            }


            string lineText = null;

            // TODO: We need to get Header Ids
            var headerId = string.Empty; // headers may not have pragma lines

            if (editorLineNumber > -1)
            {
                lineText = editor.GetLine(editorLineNumber).Trim();

                if (lineText.StartsWith("#") && lineText.Contains("# ")) // it's header
                {
                    lineText = lineText.TrimStart(new[] { ' ', '#', '\t' });
                    headerId = LinkHelper.UrilizeAsGfm(lineText);
                }
            }

            if (editor.MarkdownDocument.EditorSyntax == "markdown")
            {
                interop.ScrollToPragmaLine(editorLineNumber, headerId, noScrollTimeout, noScrollTopAdjustment);
            }
            else if (editor.MarkdownDocument.EditorSyntax == "html")
            {
                interop.ScrollToHtmlBlock(lineText ?? editor.GetLine(editorLineNumber));
            }
        }
        private void PreviewBrowserOnLoadCompleted(object sender, NavigationEventArgs e)
        {
            if (e.Uri == null)
            {
                return;
            }

            string url = e.Uri.ToString();

            if (!url.Contains("_MarkdownMonster_Preview") && !url.Contains("__untitled.htm"))
            {
                return;
            }

            bool shouldScrollToEditor = WebBrowser.Tag != null && WebBrowser.Tag.ToString() == "EDITORSCROLL";

            WebBrowser.Tag = null;

            PreviewBrowserInterop  interop = null;
            MarkdownDocumentEditor editor  = null;

            try
            {
                editor  = Window.GetActiveMarkdownEditor();
                interop = new PreviewBrowserInterop(PreviewBrowserInterop.GetWindow(WebBrowser));

                interop.InitializeInterop(editor);
                interop.SetHighlightTimeout(Model.Configuration.Editor.PreviewHighlightTimeout);

                //window.previewer.highlightTimeout = Model.Configuration.Editor.PreviewHighlightTimeout;

                if (shouldScrollToEditor)
                {
                    try
                    {
                        // scroll preview to selected line
                        if (mmApp.Configuration.PreviewSyncMode == PreviewSyncMode.EditorAndPreview ||
                            mmApp.Configuration.PreviewSyncMode == PreviewSyncMode.EditorToPreview)
                        {
                            int lineno = editor.GetLineNumber();
                            if (lineno > -1)
                            {
                                string headerId = string.Empty;
                                var    lineText = editor.GetCurrentLine().Trim();
                                if (lineText.StartsWith("#") && lineText.Contains("# ")) // it's header
                                {
                                    lineText = lineText.TrimStart(new[] { ' ', '#', '\t' });
                                    headerId = LinkHelper.UrilizeAsGfm(lineText);
                                }

                                if (editor.MarkdownDocument.EditorSyntax == "markdown")
                                {
                                    interop.ScrollToPragmaLine(lineno, headerId);
                                }
                                else if (editor.MarkdownDocument.EditorSyntax == "html")
                                {
                                    interop.ScrollToHtmlBlock(lineText);
                                }
                            }
                        }
                    }
                    catch
                    {
                        /* ignore scroll error */
                    }
                }
            }
            catch
            {
                // try again after a short wait
                Model.Window.Dispatcher.Delay(500, (i) =>
                {
                    var introp = i as PreviewBrowserInterop;
                    try
                    {
                        introp.InitializeInterop(editor);
                        introp.SetHighlightTimeout(Model.Configuration.Editor.PreviewHighlightTimeout);
                    }
                    catch
                    {
                        //mmApp.Log("Preview InitializeInterop failed: " + url, ex);
                    }
                }, interop);
            }
        }
        public void PreviewMarkdown(MarkdownDocumentEditor editor = null,
                                    bool keepScrollPosition       = false,
                                    bool showInBrowser            = false,
                                    string renderedHtml           = null,
                                    int editorLineNumber          = -1)
        {
            try
            {
                // only render if the preview is actually visible and rendering in Preview Browser
                if (!Model.IsPreviewBrowserVisible && !showInBrowser)
                {
                    return;
                }

                if (editor == null)
                {
                    editor = Window.GetActiveMarkdownEditor();
                }

                if (editor == null)
                {
                    return;
                }

                var doc = editor.MarkdownDocument;
                var ext = Path.GetExtension(doc.Filename).ToLower().Replace(".", "");

                string mappedTo = "markdown";

                if (!string.IsNullOrEmpty(renderedHtml))
                {
                    mappedTo = "html";
                    ext      = null;
                }
                else
                {
                    mappedTo = editor.MarkdownDocument.EditorSyntax;
                }


                PreviewBrowserInterop interop = null;
                if (string.IsNullOrEmpty(ext) || mappedTo == "markdown" || mappedTo == "html")
                {
                    if (!showInBrowser)
                    {
                        if (keepScrollPosition)
                        {
                            interop = new PreviewBrowserInterop(PreviewBrowserInterop.GetWindow(WebBrowser));
                        }
                        else
                        {
                            Window.ShowPreviewBrowser(false, false);
                        }
                    }

                    if (mappedTo == "html")
                    {
                        if (string.IsNullOrEmpty(renderedHtml))
                        {
                            renderedHtml = doc.CurrentText;
                        }

                        if (!doc.WriteFile(doc.HtmlRenderFilename, renderedHtml))
                        {
                            // need a way to clear browser window
                            return;
                        }

                        renderedHtml = StringUtils.ExtractString(renderedHtml,
                                                                 "<!-- Markdown Monster Content -->",
                                                                 "<!-- End Markdown Monster Content -->");
                    }
                    else
                    {
                        // Fix up `/` or `~/` Web RootPaths via `webRootPath: <path>` in YAML header
                        // Specify a physical or relative path that `\` or `~\` maps to
                        doc.GetPreviewWebRootPath();

                        bool usePragma = !showInBrowser && mmApp.Configuration.PreviewSyncMode != PreviewSyncMode.None;
                        if (string.IsNullOrEmpty(renderedHtml))
                        {
                            renderedHtml = doc.RenderHtmlToFile(usePragmaLines: usePragma);
                        }

                        if (renderedHtml == null)
                        {
                            Window.ShowStatusError($"Access denied: {Path.GetFileName(doc.Filename)}");
                            // need a way to clear browser window

                            return;
                        }

                        // Handle raw URLs to render
                        if (renderedHtml.StartsWith("http") && StringUtils.CountLines(renderedHtml) == 1)
                        {
                            WebBrowser.Navigate(new Uri(renderedHtml));
                            Window.ShowPreviewBrowser();
                            return;
                        }

                        renderedHtml = StringUtils.ExtractString(renderedHtml,
                                                                 "<!-- Markdown Monster Content -->",
                                                                 "<!-- End Markdown Monster Content -->");
                    }

                    if (showInBrowser)
                    {
                        var url = doc.HtmlRenderFilename;
                        mmFileUtils.ShowExternalBrowser(url);
                        return;
                    }

                    WebBrowser.Cursor      = Cursors.None;
                    WebBrowser.ForceCursor = true;

                    // if content contains <script> tags we must do a full page refresh
                    bool forceRefresh = renderedHtml != null && renderedHtml.Contains("<script ");


                    if (keepScrollPosition && !mmApp.Configuration.AlwaysUsePreviewRefresh && !forceRefresh)
                    {
                        string browserUrl   = WebBrowser.Source.ToString().ToLower();
                        string documentFile = "file:///" +
                                              doc.HtmlRenderFilename.Replace('\\', '/')
                                              .ToLower();
                        if (browserUrl == documentFile)
                        {
                            if (string.IsNullOrEmpty(renderedHtml))
                            {
                                PreviewMarkdown(editor, false, false); // fully reload document
                            }
                            else
                            {
                                try
                                {
                                    try
                                    {
                                        // scroll preview to selected line
                                        if (mmApp.Configuration.PreviewSyncMode == PreviewSyncMode.EditorAndPreview ||
                                            mmApp.Configuration.PreviewSyncMode == PreviewSyncMode.EditorToPreview ||
                                            mmApp.Configuration.PreviewSyncMode == PreviewSyncMode.NavigationOnly)
                                        {
                                            int highlightLineNo = editorLineNumber;
                                            if (editorLineNumber < 0)
                                            {
                                                highlightLineNo  = editor.GetLineNumber();
                                                editorLineNumber = highlightLineNo;
                                            }
                                            if (renderedHtml.Length < 100000)
                                            {
                                                highlightLineNo = 0; // no special handling render all code snippets
                                            }
                                            var lineText = editor.GetLine(editorLineNumber).Trim();

                                            if (mmApp.Configuration.PreviewSyncMode != PreviewSyncMode.NavigationOnly)
                                            {
                                                interop.UpdateDocumentContent(renderedHtml, highlightLineNo);
                                            }

                                            // TODO: We need to get Header Ids
                                            var headerId = string.Empty; // headers may not have pragma lines
                                            if (editorLineNumber > -1)
                                            {
                                                if (lineText.StartsWith("#") && lineText.Contains("# ")) // it's header
                                                {
                                                    lineText = lineText.TrimStart(new[] { ' ', '#', '\t' });
                                                    headerId = LinkHelper.UrilizeAsGfm(lineText);
                                                }
                                            }

                                            if (editor.MarkdownDocument.EditorSyntax == "markdown")
                                            {
                                                interop.ScrollToPragmaLine(editorLineNumber, headerId);
                                            }
                                            else if (editor.MarkdownDocument.EditorSyntax == "html")
                                            {
                                                interop.ScrollToHtmlBlock(lineText);
                                            }
                                        }
                                        else
                                        {
                                            interop.UpdateDocumentContent(renderedHtml, 0);
                                        }
                                    }
                                    catch
                                    {
                                        /* ignore scroll error */
                                    }
                                }
                                catch
                                {
                                    // Refresh doesn't fire Navigate event again so
                                    // the page is not getting initiallized properly
                                    //PreviewBrowser.Refresh(true);
                                    WebBrowser.Tag = "EDITORSCROLL";
                                    WebBrowser.Navigate(new Uri(doc.HtmlRenderFilename));
                                }
                            }

                            return;
                        }
                    }

                    WebBrowser.Tag = "EDITORSCROLL";
                    WebBrowser.Navigate(new Uri(doc.HtmlRenderFilename));
                    return;
                }

                // not a markdown or HTML document to preview
                Window.ShowPreviewBrowser(true, keepScrollPosition);
            }
            catch (Exception ex)
            {
                //mmApp.Log("PreviewMarkdown failed (Exception captured - continuing)", ex);
                Debug.WriteLine("PreviewMarkdown failed (Exception captured - continuing): " + ex.Message, ex);
            }
        }
        private void PreviewBrowserOnLoadCompleted(object sender, NavigationEventArgs e)
        {
            if (e.Uri == null)
            {
                return;
            }

            string url = e.Uri.ToString();

            if (!url.Contains("_MarkdownMonster_Preview") && !url.Contains("__untitled.htm"))
            {
                return;
            }

            bool shouldScrollToEditor = WebBrowser.Tag != null && WebBrowser.Tag.ToString() == "EDITORSCROLL";

            WebBrowser.Tag = null;

            PreviewBrowserInterop  interop = null;
            MarkdownDocumentEditor editor  = null;

            try
            {
                editor  = Window.GetActiveMarkdownEditor();
                interop = new PreviewBrowserInterop(PreviewBrowserInterop.GetWindow(WebBrowser));

                //ReflectionUtils.
                //dom.documentElement.scrollTop = editor.MarkdownDocument.LastEditorLineNumber;

                interop.InitializeInterop(editor);
                interop.SetHighlightTimeout(Model.Configuration.Editor.PreviewHighlightTimeout);

                //window.previewer.highlightTimeout = Model.Configuration.Editor.PreviewHighlightTimeout;

                if (shouldScrollToEditor)
                {
                    try
                    {
                        // scroll preview to selected line
                        if (mmApp.Configuration.PreviewSyncMode == PreviewSyncMode.EditorAndPreview ||
                            mmApp.Configuration.PreviewSyncMode == PreviewSyncMode.EditorToPreview)
                        {
                            int lineno = editor.GetLineNumber();
                            if (lineno > -1)
                            {
                                interop.ScrollToPragmaLine(lineno);
                            }
                        }
                    }
                    catch
                    {
                        /* ignore scroll error */
                    }
                }
            }
            catch
            {
                // try again after a short wait
                Model.Window.Dispatcher.Delay(500, (i) =>
                {
                    var introp = i as PreviewBrowserInterop;
                    try
                    {
                        introp.InitializeInterop(editor);
                        introp.SetHighlightTimeout(Model.Configuration.Editor.PreviewHighlightTimeout);
                    }
                    catch
                    {
                        //mmApp.Log("Preview InitializeInterop failed: " + url, ex);
                    }
                }, interop);
            }
        }