{"id":3025,"date":"2014-12-23T12:20:55","date_gmt":"2014-12-23T17:20:55","guid":{"rendered":"http:\/\/www.red-sweater.com\/blog\/?p=3025"},"modified":"2014-12-23T12:27:00","modified_gmt":"2014-12-23T17:27:00","slug":"marsedit-live-source-preview","status":"publish","type":"post","link":"https:\/\/redsweater.com\/blog\/3025\/marsedit-live-source-preview","title":{"rendered":"MarsEdit Live Source Preview"},"content":{"rendered":"<p>Recently a customer wrote asking whether I would consider adding a feature to <a href=\"http:\/\/www.red-sweater.com\/marsedit\/\">MarsEdit<\/a>, so that as you\u2019re writing a blog post, you could also keep an eye on exactly what the resulting HTML will look like. This feature would be handy for folks writing in Markdown or in the Rich Text editor, but also for folks writing in plain HTML, depending on what &#8220;preview filter&#8221; settings they have configured.<\/p>\n<p>I told the customer I could see the value of such a feature, and that I would consider it for a future update. But the idea stuck with me until I suddenly realized that in fact MarsEdit could support such a feature today, without any update to the app.<\/p>\n<p>Currently MarsEdit\u2019s editor supports writing in either plain-text markup such as HTML or Markdown, or in Rich text. In any of these cases, the final result can be previewed in MarsEdit\u2019s preview window, where the results of e.g. running Markdown or converting from rich text to HTML are shown in the context of a &#8220;preview template,&#8221; essentially a custom HTML document that users can tweak e.g. to <a href=\"http:\/\/www.red-sweater.com\/blog\/393\/perfect-preview-with-marsedit\">match the appearance of their blog<\/a>.<\/p>\n<p><img decoding=\"async\" src=\"http:\/\/www.red-sweater.com\/blog\/wp-content\/downloads\/2014\/12\/PreviewWindow.png\" alt=\"Preview window with default configuration\" title=\"PreviewWindow.png\" border=\"0\" width=\"430\" \/><\/p>\n<p>Because users can edit the template and add arbitrary HTML to the preview window\u2019s content, it occurred to me that JavaScript could be added to the template such that every change to window\u2019s content would be matched by a live display of the HTML being shown in that very window.<\/p>\n<p>MarsEdit\u2019s default preview template contains a body section that looks like this:<\/p>\n<pre>\n&lt;div style=\"padding:10px 20px;\">\n#body#\n#extended#\n&lt;\/div>\n<\/pre>\n<p>The #body# and #extended# placeholders are replaced with the actual content of the post while you are writing it. For the purposes of this proof-of-concept, I decided to just focus on the body text, since many people don\u2019t use &#8220;extended&#8221; entries. I added a bit of HTML in the template to hold the source view I plan to add:<\/p>\n<pre>\n&lt;hr>\n&lt;pre style=\"white-space:pre-wrap\">\n&lt;div id=\"sourceContent\" style=\"padding:10px 20px;\">\n&lt;\/div>\n&lt;\/pre>\n<\/pre>\n<p>Now the only trick remaining is to pay attention to changes and update the contents of the &#8220;sourceContent&#8221; div above with my content\u2019s HTML. This required a little inside-knowledge that would have been admittedly challenging to discover on one\u2019s own. The way MarEdit currently handles updates to the preview window content is to load the HTML template once, and then as you type, recompute and replace just the &#8220;body&#8221; of the HTML document. So I added a new script element outside the scope of the body tag, where it won\u2019t get replaced constantly:<\/p>\n<pre>\n&lt;script type=\"text\/javascript\">\n\tvar ignoreUpdates = false;\n\n\tfunction escapeHTML(theHTML) {\n\t\tvar escapedHTML = theHTML\n\t\tescapedHTML.replace(\"&\", \"&amp;amp;\");\n\t\tescapedHTML.replace(\"&lt;\", \"&amp;lt;\");\n\t\treturn escapedHTML;\n\t}\n\n\tfunction updateSource() {\n\t\tvar bodyDiv = document.getElementById(\"bodyText\");\n\t\tvar sourceDiv = document.getElementById(\"sourceContent\");\n\t\tif (bodyDiv && sourceDiv) {\n\t\t\tvar bodyHTML = bodyDiv.innerHTML;\n\t\t\tsourceDiv.innerText = escapeHTML(bodyHTML);\n\t\t}\n\t}\n\n\tdocument.addEventListener(\"DOMNodeInserted\", function(e) {\n\t\tif (ignoreUpdates == false) {\n\t\t\tignoreUpdates = true;\n\t\t\tupdateSource();\n\t\t\tignoreUpdates = false;\n\t\t}\n\t\t\n\t}, false);\n&lt;\/script>\n<\/pre>\n<p>I\u2019ll leave making sense of that JavaScript as an exercise for the (very) curious reader, but the gist of it is that it listens for changes to the structure of the HTML document, and when it notices that happening, it grabs all the HTML out of the &#8220;bodyText&#8221; div, converts it to escaped HTML source, and sets that on the new &#8220;sourceContent&#8221; div that I added to the template.<\/p>\n<p>Here\u2019s what the MarsEdit preview window looks like now, with the live source preview in effect:<\/p>\n<p><img decoding=\"async\" src=\"http:\/\/www.red-sweater.com\/blog\/wp-content\/downloads\/2014\/12\/PreviewWithSource1.png\" alt=\"Preview window with new source display\" title=\"PreviewWithSource.png\" border=\"0\" width=\"430\" \/><\/p>\n<p>While this isn\u2019t as polished as a dedicated feature for previewing source, I found it interesting that I was able to come up with a creative solution using only the powerful and flexible preview infrastructure of the app. If you\u2019re interested to try out the preview, you can <a href=\"http:\/\/www.red-sweater.com\/blog\/wp-content\/downloads\/2014\/12\/MarsEditSourcePreviewTemplate.txt\" title=\"MarsEditSourcePreviewTemplate.txt\" alt=\"Text file containing preview template for previewing live HTML conversion\">download it here<\/a>. Just copy and paste the text into MarsEdit\u2019s preview template editor.<\/p>\n<p>Let me know if you come are inspired to come up with any creative preview window solutions of your own!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Recently a customer wrote asking whether I would consider adding a feature to MarsEdit, so that as you\u2019re writing a blog post, you could also keep an eye on exactly what the resulting HTML will look like. This feature would be handy for folks writing in Markdown or in the Rich Text editor, but also [&hellip;]<\/p>\n","protected":false},"author":10,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[40],"tags":[],"class_list":["post-3025","post","type-post","status-publish","format-standard","hentry","category-marsedit"],"_links":{"self":[{"href":"https:\/\/redsweater.com\/blog\/wp-json\/wp\/v2\/posts\/3025","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/redsweater.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/redsweater.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/redsweater.com\/blog\/wp-json\/wp\/v2\/users\/10"}],"replies":[{"embeddable":true,"href":"https:\/\/redsweater.com\/blog\/wp-json\/wp\/v2\/comments?post=3025"}],"version-history":[{"count":3,"href":"https:\/\/redsweater.com\/blog\/wp-json\/wp\/v2\/posts\/3025\/revisions"}],"predecessor-version":[{"id":3028,"href":"https:\/\/redsweater.com\/blog\/wp-json\/wp\/v2\/posts\/3025\/revisions\/3028"}],"wp:attachment":[{"href":"https:\/\/redsweater.com\/blog\/wp-json\/wp\/v2\/media?parent=3025"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/redsweater.com\/blog\/wp-json\/wp\/v2\/categories?post=3025"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/redsweater.com\/blog\/wp-json\/wp\/v2\/tags?post=3025"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}