diff --git a/QuickLook.Plugin/QuickLook.Plugin.MarkdownViewer/MarkdownPanel.cs b/QuickLook.Plugin/QuickLook.Plugin.MarkdownViewer/MarkdownPanel.cs index 1438cdcc9..26dc9206e 100644 --- a/QuickLook.Plugin/QuickLook.Plugin.MarkdownViewer/MarkdownPanel.cs +++ b/QuickLook.Plugin/QuickLook.Plugin.MarkdownViewer/MarkdownPanel.cs @@ -96,9 +96,13 @@ protected string GenerateMarkdownHtml(string path) var tocShortcut = SettingHelper.Get("ToggleTocKey", "Ctrl+Shift+L", "QuickLook.Plugin.MarkdownViewer"); - var html = template.Replace("{{content}}", content) - .Replace("{{rtl}}", isRtl ? "rtl" : "ltr") - .Replace("{{tocShortcut}}", tocShortcut); + // Base64 keeps the source intact through HTML parsing (entities, newlines, + // and literal closing textarea tags would otherwise be altered or truncated) + var contentBase64 = Convert.ToBase64String(Encoding.UTF8.GetBytes(content)); + + var html = template.Replace("{{rtl}}", isRtl ? "rtl" : "ltr") + .Replace("{{tocShortcut}}", tocShortcut) + .Replace("{{contentBase64}}", contentBase64); return html; } diff --git a/QuickLook.Plugin/QuickLook.Plugin.MarkdownViewer/Resources/md2html.html b/QuickLook.Plugin/QuickLook.Plugin.MarkdownViewer/Resources/md2html.html index 920254c7b..cbb0b4e60 100644 --- a/QuickLook.Plugin/QuickLook.Plugin.MarkdownViewer/Resources/md2html.html +++ b/QuickLook.Plugin/QuickLook.Plugin.MarkdownViewer/Resources/md2html.html @@ -207,15 +207,122 @@ border: 1px solid var(--borderColor-default); color: var(--fgColor-default); } + + /* Raw source toggle */ + #raw-toggle { + position: fixed; + top: 8px; + right: 12px; + z-index: 10000; + + display: inline-flex; + align-items: center; + justify-content: center; + width: 30px; + height: 30px; + padding: 0; + + border: 1px solid var(--borderColor-default); + border-radius: 6px; + background: var(--bgColor-muted); + color: var(--fgColor-default); + cursor: pointer; + opacity: 0.75; + transition: opacity 0.15s ease, background-color 0.15s ease; + } + + #raw-toggle:hover { + opacity: 1; + background: var(--bgColor-neutral-muted); + } + + #raw-toggle:focus-visible { + outline: 2px solid var(--fgColor-accent); + outline-offset: 2px; + } + + #raw-toggle .icon-rendered { + display: none; + } + + body.source-mode #raw-toggle .icon-source { + display: none; + } + + body.source-mode #raw-toggle .icon-rendered { + display: block; + } + + html[dir="rtl"] #raw-toggle { + right: auto; + left: 12px; + } + + #raw-source { + display: none; + margin: 0 auto; + padding: 2.5rem 1rem 1rem; + box-sizing: border-box; + + background-color: var(--bgColor-default); + color: var(--fgColor-default); + font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, + "Liberation Mono", monospace; + font-size: 12px; + line-height: 1.45; + white-space: pre-wrap; + overflow-wrap: anywhere; + tab-size: 4; + } + + body.source-mode .container { + display: none; + } + + body.source-mode #raw-source { + display: block; + } - + + +