By request: what’s my workflow for writing books? Steps, tools, etc.
Writing with the Leanpub platform
A long time ago I noticed that testing-advocate Chris Hartjes published his books on Leanpub. When I had the idea of writing a book about the Symfony framework, I tried this platform and it was a good match. You can write your book in Markdown, commit the manuscript to a GitHub repository, and push the button to publish a new version. Leanpub will generate EPUB and PDF versions for you. Readers can be updated about releases via email or a notification on the website.
While publishing multiple books like this, I kept running into these limitations:
- Even though writing a book like this feels a lot like writing code (make a change, push, deploy), what’s missing is a continuous integration step where we can verify that the book is “correct”.
- With the Leanpub Markdown setup you can include
.mdchapter files from your main
Book.txtfile, but you can’t include files from those
.mdfiles. This makes it hard to create a nested folder structure for chapters, sections, and code samples.
- If you include source code in a book, it has to be formatted to be readable and to fit on a page, and parts have to be skipped or abbreviated. Still, you want the code to be correct. For this you want to run tests on the code, but you can’t run tests on incomplete or abbreviated code samples. I no longer wanted to copy/paste working code and format it manually for presentation purposes.
- The code samples should be tested, but they should also be analyzed with PHPStan, and they should be upgrade-able to newer
PHP versions. The go-to tool for this is Rector. I want to have these tools available in my book projects by default.
- When I include the output of tools like PHPUnit in the book, I don’t want to copy/paste it from the terminal either. When I make a change to the code, the output should be regenerated automatically and included in the book.
A manuscript pre-processor
To overcome all these problems I created a pre-processor tool that allows me to do things that aren’t possible with Leanpub’s Markdown (or Markua, their variation on Markdown), but that eventually result in a manuscript directory that Leanpub can turn into an actual book. This means that nowadays I write in “Matthias-Flavored Markua” 😉 And that I have a continously-integrated book-writing process which uses PHPUnit for tests, PHPStan for static analysis, Rector for automated refactoring, and ECS for the coding standard. The pre-processor tool is hand-written in PHP. Given that it has to process Markua, it contains a Markua parser which leverages the awesome Parsica library.
Some of the things the tool can do:
- You can add special comments to code samples that influence the final look when included in the manuscript, e.g.
// skip-endto create an ellipsis (
// ...) or
// crop-endto remove lines from the beginning and end of an included file.
- You can create a cover image with Gimp, and the tool will convert the
.xcffile to a
.pngfile that matches Leanpub’s expectations.
- You can include
.mdfiles from any other
.mdfile. In the end, everything will be compiled into a single
- When you regenerate this manuscript, it’s easy to see which parts have been changed, which allows you to spot parts that were changed by mistake, or that no longer work because of a different output from PHPUnit, etc.
- You can collect all external links and generate a link registry for it, so the book will never have broken links.
- You can include code from a package in
vendor/and reformat it according to the style used for the other code samples.
- And so on! The project is yet another example of the amazing powers that will be unleashed if you have access to an Abstract Syntax Tree for a language, in this case Markua.
The path towards releasing a new book
For me, a new book always starts with an idea, which I immediately judge for its capability of becoming a book (as opposed to a blog post, or series of blog posts). In a sense, every idea can become a book, but it has to be interesting, I should be able to build on my own exp
Truncated by Planet PHP, read more at the original (another 8937 bytes)