The MultiMarkdown ToC

Do you ever feel like you’re never finished? I do, and I’m not happy with the fact that I haven’t been able to make Scrivener trigger the mmd-xslt script following a compile to MultiMarkdown HTML. Fine. As with the original XML epiphany, I knew there had to be code to perform an XSLT transformation in PHP on the server. Certainly there is, and my content-doc.php content template has further evolved into an XSLT transformation powerhouse. If a custom variable is provided with a path to the XSLT file on disk, and that files exists, the code transforms the XML using the provided XSLT style sheet. Here is a snippet:

Notes

Something to take note of in the PHP code. transformToDoc returns a DOMDocument object and the $xml variable contains a SimpleXMLElement object returned by the simplexml_load_file() method. If you recall, we insert the XML into the page by echoing the proper child element using the asXml() method. Therefore in order to leave that code intact, I import the DOMDocument back into $xml.

To snippet or not to snippet

My last post spoke of the need to use a snippet of XHTML in order to include it in a WordPress Page. This rule was short-lived. Why am I recanting my story? I switched to MultiMarkdown 3 and attempted the use its XSLT transformation capabilities; something of which requires an entire XHTML file (well-formed XML). The process in which one attempts an XSLT transformation with MMD3 is not an easy one at first glance. This is largely because I have yet to see how Scrivener can trigger MMD3 to perform the task at the completion of a successful compile. In order for Scrivener to be aware of the presence of MMD3 (Scrivener ships with MMD 2), an install of the MMD 3 Support package is required. This package installs in /Library/Application Support/MultiMarkdown. Scrivener is inherently aware of the files in this location, and makes use of them in lieu of the MMD 2 files contained within its app package. One small problem, according to the MMD 3 docs, the XHTML XSLT metadata tag has been removed from the spec.

In the absence of the XHTML XSLT: xhtml-toc-h2.xslt metadata tag, I had to run the mmd-xslt utility from the command line — run it from within its bin/ directory when you do. This script transforms the XHTML file into one that includes a ToC at the top. In my drive towards a successful transformation, I realized that if I had a well-formed XML document, then surely there were commands in PHP that would allow me to gain a reference to the BODY node, and inject it and its inner XML into the WordPress Page output. Sure enough, the necessary functions exist. I did however go back to scratch with the template files. I created a dupe of page.php and content-page.php (doc.php and content-doc.php respectively), and modified the content-doc.php thusly:

Please take note of the use of libxml_use_internal_errors(true);. I’m keeping the page from showing error in the output. IMHO, it’s a security issue if you expose internal paths to the outside world. Now, back to bending MMD 3 and Scrivener to match my particular requirements. Thanks.

Learning

I’ve been working on this app spec for weeks at work. In an effort to improve on what I’d accomplished, I reached out to my friend, and one of the smartest people I know, Peter Becan. I wanted him to teach me how to do it right. Peter’s been doing this sort of thing for a lot longer than I have, and has a particular knack for it. Learning to correctly prepare an application specification is harder than learning to program, IMHO.

As my spec writing progressed, I’d email Peter PDF output from Scrivener as I accumulate enough new content worthy of a dispatch. marked, which I’m using to preview MultiMarkdown markup in my Scrivener document, generates the formatted PDFs. I realize that as time progresses, keeping Peter in the loop requires a different method. In order to keep him informed, and not have to email him a new PDF every so often, I needed to make use of the web to post the formatted output.

Scrivener

Scrivener supports outputting HTML generated by the MultiMarkdown processor as a Compile For target. There are instructions on how to use MultiMarkdown with Scrivener here, however the instruction appear out of date. I’m using Scrivener 2.2 and some of the preferences mentioned in the instruction have either moved, or no longer exist. Luckily, by setting options using MultiMarkdown metadata and a simple change in the compile settings, I obtained the necessary output.

For posterity’s sake, what I did not find was MultiMarkdown Settings… under the File menu

Two things are necessary to produce the desired output for inclusion in a WordPress page. First, as mentioned in the instructions, I had to enable the exporting of Titles for both Documents and Groups within Scrivener. You do this by checking the check box under Title in the Formatting options of the Compilation Settings sheet.

Second, I opted to use a Meta-Data file at the very top of my Scrivener doc to coerce the MultiMarkdown processor to produce the necessary output. The metadata fields that I use are:

The key is the Format field. What that does is instruct the MultiMarkdown processor to only create the HTML for the given markup and not an entire XHTML page. Clearly if I am including the output in a WordPress page, only the HTML associated with the MultiMarkdown markup is necessary; the cruft associated with a well-formed XHTML page (i.e. HEAD, BODY, etc.) would be in the way. With all the correct metadata and settings in place, I use Compile… with a Compile For of MultiMarkdown -> HTML and save that in its own subfolder within my source tree.

Git

Git. Love it or hate it, it’s the linchpin in the operation. My Git repo resides on the same server as my WordPress installation. Having that scenario started me thinking about how I would get the HTML snippet residing within the repo into a place that I could serve just that content and not the entire source tree. I started Googling update website with git, and sure enough I found what I was looking for. After sifting through several top results, I found that this was the best answer.

I have an addendum to those instructions. For the remote path, I used a file:// path pointing to the path of the real repo on the server. Found that here.

The key to copying the HTML to a place I can include it from is using a post-receive hook in Git. Very simply put:

The post-receive hook runs after the entire process is completed and can be used to update other services or notify users. (taken from Pro Git)

However, if you follow the steps set out in the instructions, you’ll wind up with your entire repo in the web directory. While that may work in most cases, it was not ideal for what I was trying to do. Next pass at Google had me looking for ways to only checkout a subset of the entire repo. The key to that is something entitled a sparse checkout. I used the steps outlined here to only checkout the folder (and it’s content) that contained the HTML snippet. One exception however about the sparse checkout instructions, you will need to include a ‘*’ at the end of the path. Otherwise you will receive from Git:

error: Sparse checkout leaves no entry on working directory

For my “local” repo on the server, I picked a spot outside of the root of the WordPress installation to checkout the files to.

WordPress

Last step in the process. How do I insert a snippet of HTML that resides on disk into a WordPress page? Create your own page template and use a custom field. In the end, this was rather easy, once I learned how to do it. This page at the WordPress codex explains how to create the custom template and where to upload it to your server. Scroll down a bit till you get to the Using Custom Fields section. For this, I’m using a custom field called doc_path. Here is my custom template named docs.php:

This allows me to specify the full path to the HTML snippet on disk that I want included in the WordPress page.

Make sure, as I forgot this the first time I saved my new Page, to set the template for the Page to your custom template like this:

Final Output

Because the application I’m writing the spec for is proprietary, I can’t share the real fruits of my labor with you. However, what I did do is create another page containing a snippet of sample.html from the MultiMarkdown source at github. My sample page is here. P.S. Yes, I am aware that the sample page has a broken image link.