Git2024-03-28T17:39:17Zhttps://d.moonfire.us/tags/git/D. MoonfireCreative Commons Attribution-NonCommercial-ShareAlike 4.0 InternationalFirst Steps Using MfGames Writing (GitLab, NPM)2018-08-22T05:00:00Zhttps://d.moonfire.us/blog/2018/08/22/mfgames-writing-init/The initial steps for setting up a new project for publication.
<p>Getting started with <a href="/tags/mfgames-writing/">MfGames Writing</a> can be a bit overwhelming. This is the beginning of how to get started. These directions are mainly focused toward technical users who already have a basic skill in Git.</p>
<h1>Series</h1>
<p>I appear to be writing a short series of post about the tools I use for publication and writing.</p>
<ol>
<li><a href="/blog/2018/08/13/publishing-processes/">Semantic Versions and Releases</a>: Why semantic versioning helps with the writing process.</li>
<li><a href="/blog/2018/08/21/mfgames-writing-reasons/">Evolution of MfGames Writing</a>: A brief history and reasoning behind the tools.</li>
<li>First Steps Using MfGames Writing: How to get started with a project.</li>
<li><a href="/blog/2018/08/23/mfgames-writing-content/">Adding Content to MfGames Writing</a>: Adding front and back matter to novels.</li>
<li><a href="/blog/2018/08/24/mfgames-writing-docker-and-ci/">Working with MfGames Writing, CI, and Docker</a>: Adding automatic building with commits.</li>
<li><a href="/blog/2018/08/25/mfgames-writing-formats/">Additional Formats for MfGames Writing</a>: How to create PDF, MOBI, DOCX, and HTML versions.</li>
<li><a href="/blog/2018/08/26/mfgames-writing-themes/">Theming for MfGames Writing</a>: A light introduction on how to customize the output.</li>
<li><a href="/blog/2018/08/27/mfgames-writing-releases/">Integrating Semantic Versioning into MfGames Writing</a>: Tying semantic releases into the process.</li>
</ol>
<h1>Setting up Git</h1>
<p>I always start by creating a new Git project on <a href="https://gitlab.com/">GitLab</a>. You can do the same with GitHub, BitBucket, or just locally. Since I'm focusing on the tools, I'm going to assume you know how to create those projects.</p>
<pre><code class="language-shell">$ git checkout https://oauth2:SecretPassword@gitlab.com/dmoonfire/test-project.git
... stuff happens
$ cd test-project
</code></pre>
<p>You could create a new folder, it doens't really matter.</p>
<pre><code class="language-shell">$ mkdir test-project
$ cd test-project
$ git init
</code></pre>
<h1>Setting up .gitignore</h1>
<p>The way builds work, there are quite a few files that will be generated that wouldn't be checked into the repository. This is one thing that makes NPM so powerful. To avoid that, we create a <code>.gitignore</code> file that ignores those files.</p>
<pre><code># Emacs and VI creates these files and I'm too lazy to turn it off.
*~
\#*
.#*
# This is the output of the various build processes.
*.pdf
*.mobi
*.epub
*.docx
# Sometimes I use `build` for my output but most of the time I just put it in the root.
build/
# This is where Node/NPM puts its file.
node_modules/
</code></pre>
<h1>Setting up .editorconfig</h1>
<p><a href="https://editorconfig.org/">EditorConfig</a> is a tool for providing some consistency in formatting. For novels, it doesn't make sense but I like to have it there to make sure the supporting files are consistent. This is an optional file, I just like having it.</p>
<pre><code># EditorConfig is awesome: http://EditorConfig.org
# top-most EditorConfig file
root = true
[*]
charset = utf-8
end_of_line = lf
indent_brace_style = K&R
indent_size = 4
indent_style = space
insert_final_newline = true
max_line_length = 80
tab_width = 4
trim_trailing_whitespace = true
curly_bracket_next_line = false
[*.{js,ts}]
quote_type = double
[*.yaml]
indent_size = 2
tab_width = 2
[package.json]
indent_size = 2
tab_width = 2
</code></pre>
<h1>Setting up package.json</h1>
<p>The versioning and management comes from <code>package.json</code>. This is the file that says <em>which</em> version of which utilities to use. Now, you can use <code>npm init</code> to figure it out but this is the basic file.</p>
<pre><code class="language-json">{
"name": "test-project",
"private": true,
"version": "0.0.0"
}
</code></pre>
<p>There is other stuff, but these are the key parts. The name is the <em>slug</em> of the file. For me, it is always the name of the folder in the website and the Git repository. I also use this to build my website, so it is a pretty consistent format. You can call it whatever you want and change it as you need.</p>
<p>The <code>private</code> is to prevent you from accidently publishing your novel on <a href="https://www.npmjs.com/">NPM</a>.</p>
<p>Finally the <code>version</code> is used for the <a href="/blog/2018/08/13/publishing-processes/">semantic release</a> and populates data on the legal page of the resulting book. In general, I start with “0.0.0” and then bump it to “1.0.0” when I finalize the book and publish it for the first time.</p>
<h1>Write a Chapter</h1>
<p>Now, we need somethig to put into the story or novel. Since I've started this, I organize even my short story into chapters. To do that, you can put it anywhere, but I always put my chapters in (unoriginally) the <code>chapters/</code> folder. I also use two-digit numbers with zero padding so it sorts correctly (this is useful). You can see this at <a href="https://gitlab.com/fedran/sand-and-blood/">Sand and Blood's Git Repository</a>.</p>
<p>For example, <code>chapters/chapter-01.md</code>:</p>
<pre><code class="language-markdown">---
title: Mistakes Were Made
---
It was a bright and terribly sunny day.
I didn't like it.
</code></pre>
<h1>Setting up publication.yaml</h1>
<p>Because of the flexibility (if you don't want to use <code>chapters/</code>, want to spread it out across deeper folders), nothing is automatic when it comes to formatting the books. To control it, we have a simple file called <code>publication.yaml</code> which tells the system <em>how</em> to create the output. This would go at the top-level file.</p>
<pre><code class="language-yaml">metadata:
title: Test Project
author: D. Moonfire
language: en
theme: "@mfgames-writing/clean"
outputDirectory: .
outputFilename: test-project-{{edition.version}}.{{edition.editionName}}
editions:
epub: # This is the edition.editionName.
format: "@mfgames-writing/epub2"
contents:
- element: chapter
number: 1
directory: chapters
source: /^chapter-\d+.md$/
start: true
page: 1
</code></pre>
<p>Now, since this file is the core of MfGames Writing, it needs a bunch of details.</p>
<h2>Liquid</h2>
<p>Many of the fields use <a href="https://shopify.github.io/liquid/">Liquid</a> templates. That is the stuff between <code>{{</code> and <code>}}</code>. The main reason we use it is so we can simplify some of our logic. For example, instead of putting <code>outputFilename</code> in every edition, we can use variables to fill it in. Also, we can substitute <code>{{ edition.version }}`` to have the version from the </code>package.json<code>file. The</code>{{edition.editionName}}<code>will have</code>epub<code>for the</code>epub:<code>line. This means it wil produce a file</code>test-project-0.0.0.epub` when it runs.</p>
<h2>Theme</h2>
<p>The formatting is driven around the idea of a “theme”. Right now, there are only three themes. Two are private or require custom fonts, the other is <a href="https://www.npmjs.com/package/@mfgames-writing/clean">@mfgames-writing/clean</a> which is a utilitarian theme based on SASS and some templates. These themes are used to create a consistent style. I also have more specialized themes:</p>
<ul>
<li><a href="https://www.npmjs.com/package/@fedran/writing-theme/">Fedran</a>: For the books and stories at <a href="https://fedran.com/">https://fedran.com/</a>. This also is used for my print books.</li>
<li><a href="https://www.npmjs.com/package/@typewriter-press/efferding-writing-theme">Efferding</a>: For Randy Roeder's <a href="https://typewriter.press/randy-roeder/sins-of-intent/">Sins of Intent</a> and the sequel coming out next month.</li>
</ul>
<p>Both of these have custom fonts (Corda and Mr. Eaves) with a bit of logic. I could easily see this being expanded by anyone to create a gallery of formatting for books. Right now, I'm focusing on these three because they are functional enough.</p>
<p>See the later post on theme specifics.</p>
<h2>Editions</h2>
<p>Editions are basically versions of the output. For <em>Sand and Blood</em>, I have one for EPUB, HTML, and PDF. MOBI and DOCX are generated from those three sources. You can have any number of editions, different file names, different output directories, even different variables like ISBN numbers.</p>
<h2>Content</h2>
<p>Content is what goes into the file. Right now, we only have a single element, all the files in the chapter folder.</p>
<pre><code class="language-yaml">- element: chapter
number: 1
directory: chapters
source: /^chapter-\d+.md$/
start: true
page: 1
</code></pre>
<p>The <code>element</code> tells the theme how to format it. Later examples will include more but you can have things like <code>preface</code> or <code>appendix</code> or titles and the like.</p>
<p>The <code>number</code> property basically is used if you want to have “Chapter 1” in the theme but with a custom title. If your chapter is just “One”, “Two”, “Three”, you wouldn't define this. My books do since I use chapter titles.</p>
<p>The <code>directory</code> and <code>source</code> work together to figure out which files are to be included.</p>
<p><code>start</code> is used by EPUB and MOBI to figure out where to automatically navigate when the reader first goes into the page.</p>
<p>Finally <code>page</code> is used by the PDF system to restart page numbering. Usually this would be left blank.</p>
<h1>Installing Tools</h1>
<p>At this point, I have a minimum novel project. Time to make it actually produce something. Like in the <a href="/blog/2018/08/21/mfgames-writing-reasons/">previous</a>, everything is self-contained in the directory. We use <code>npm</code> to install the packages needed to build the project.</p>
<pre><code class="language-shell">$ npm install @mfgames-writing/format @mfgames-writing/clean @mfgames-writing/epub2
</code></pre>
<p>The <code>@mfgames-writing/format</code> provides the command-line tools and does the work. There is also the “clean” theme and a third for the output (EPUB2).</p>
<p>Once these install, running the output should work with the following command.</p>
<pre><code class="language-shell">$ npx mfgames-writing-format build
... lots of colorful output
$ ls *.epub
test-project-0.0.0.epub
</code></pre>
<p>If all goes well, you'll see <code>test-project-0.0.0.epub</code> in the root directory. It won't pass <code>epubcheck</code> check (we are missing a few things), but this is the basics of the publishing system.</p>
Setting up a writing project on GitLab2015-05-09T05:00:00Zhttps://d.moonfire.us/blog/2015/05/09/gitlab-projects/One advantage of writing novels in Markdown is that I can use Git to manage to projects. However, having only a local Git on my laptop is risky, so having a remote Git repository helps preventing losing data. Here is how to get a project up on GitLab.<p>As I've mentioned on my blog before, I write novels using <a href="http://daringfireball.net/projects/markdown/syntax">Markdown</a>. I also keep everything in a <a href="http://git-scm.com/">Git</a> repository which helps prevent me from overwriting chapters or giving me a chance to commit changes while at the family cabin.</p>
<p>The biggest advantage of Git is the ability to coordinate writing between two computers (laptop and basement). This requires a third computer, a remote repository, to handle working between the two machines. Until a few months ago, I used a SSH host to handle them.</p>
<p>Then I found out that <a href="https://gitlab.com/">GitLab</a> had much of the features of my favorite (and just about everyone else) host, <a href="https://github.com/">GitHub</a>. The main difference is GitLab is open-sourced and less popular while GitHub a private company, closed-source, but <em>very</em> popular.</p>
<p>I really like GitHub, mainly because of their interface. But they don't allow for private repositories. And I like to keep my novels private until they are released under <a href="http://creativecommons.org/">Creative Commons</a>.</p>
<p>Fortunately, GitLab allows for unlimited private repositories. Also, they have a <a href="https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/README.md">omnibus edition</a> which lets someone like me (somewhat technical) host their own private version outside of a third-party's server. That isn't important for many people, the GitLab hosted version is probably good for many writers.</p>
<h1>Setting up a project</h1>
<p><em>You can click on the images for larger versions.</em></p>
<p><a style="width: 260px; clear: right; float: right; margin-left: 1em; margin-bottom: 1em;" href="sand-and-ash-setup.png"><img class="img-responsive post-img-link" src="sand-and-ash-setup.png" alt="GitLab Setup" height="420" width="244" /></a></p>
<p>Setting up projects is pretty easy. Create an account over at GitLab and select “New Repository”. This will ask some basic information, the only thing I enter is a <em>slug</em>, a name with dashes, that identifies the project. For example, my novel <a href="/tags/sand-and-ash/">Sand and Ash</a> would have a slug of “sand-and-ash”.</p>
<p>Also make sure the project remains as “Private” which means only people you explicitly give access to the project can do so.</p>
<p><a style="width: 260px; clear: right; float: right; margin-left: 1em; margin-bottom: 1em;" href="sand-and-ash-gitlab.png"><img class="img-responsive post-img-link" src="sand-and-ash-gitlab.png" alt="GitLab example #1" height="259" width="118" /></a></p>
<p>Once you set up a project, this brings you to the dashboard. This is where you can list all the files in the project, or view the check-ins. You can also use “merge requests,” which I haven't had a chance to investigate. In theory, you could have an editor work on sections and then push out those changes for you to review.</p>
<p>The other aspects of use are milestones and issues. I use both of these pretty frequently to keep track of things to do before publication (or updates if you happen to need an update).</p>
<h1>Milestones</h1>
<p><a style="width: 260px; clear: right; float: right; margin-left: 1em; margin-bottom: 1em;" href="sand-and-ash-milestones-1.png"><img class="img-responsive post-img-link" src="sand-and-ash-milestone-1.png" alt="GitLab example #2" height="324" width="214"/></a></p>
<p><a style="width: 260px; clear: right; float: right; margin-left: 1em; margin-bottom: 1em;" href="sand-and-ash-milestones-2.png"><img class="img-responsive post-img-link" src="sand-and-ash-milestones-2.png" alt="GitLab example #3" height="420" width="244" /></a></p>
<p>Milestones are significant points in the novel's life. I use <a href="http://semver.org/">Semantic Versioning</a> to identify the versions of the novel with 1.0.0 being the first release. Before that, I start with a number of them that represent the first three rounds of edits (0.1.0, 0.2.0, and 0.3.0), the one-off rounds (say clean up quotations or look for echo words), alpha readers (0.4.0), editor rounds (0.5.0 through 0.8.0), and final beta reading (0.9.0 and higher).</p>
<p>Setting up a milestone is pretty easy. Click on the “Milestones” lists all the milestones and then click on “New Milestone”. From there, you can enter a milestone, you give it a name (“v1.0.0” for the initial release) and a short description. I'd love to have a due date, but I can't publish reliably enough for that so I don't pick one. That way, it won't nag me about failing to meet my self-imposed deadline.</p>
<h1>Issues</h1>
<p><a style="width: 260px; clear: right; float: right; margin-left: 1em; margin-bottom: 1em;" href="sand-and-ash-issues-1.png"><img class="img-responsive post-img-link" src="sand-and-ash-issues-1.png" alt="GitLab example #4" height="327" width="138" /></a></p>
<p><a style="width: 260px; clear: right; float: right; margin-left: 1em; margin-bottom: 1em;" href="sand-and-ash-issues-2.png"><img class="img-responsive post-img-link" src="sand-and-ash-issues-2.png" alt="GitLab example #5" height="328" width="252" /></a></p>
<p><a style="width: 260px; clear: right; float: right; margin-left: 1em; margin-bottom: 1em;" href="sand-and-ash-issues-3.png"><img class="img-responsive post-img-link" src="sand-and-ash-issues-3.png" alt="GitLab example #6" height="324" width="253" /></a></p>
<p><a style="width: 260px; clear: right; float: right; margin-left: 1em; margin-bottom: 1em;" href="sand-and-ash-issues-4.png"><img class="img-responsive post-img-link" src="sand-and-ash-issues-4.png" alt="GitLab example #7" height="326" width="248" /></a></p>
<p><a style="width: 260px; clear: right; float: right; margin-left: 1em; margin-bottom: 1em;" href="sand-and-ash-issues-5.png"><img class="img-responsive post-img-link" src="sand-and-ash-issues-5.png" alt="GitLab example #8" height="326" width="172" /></a></p>
<p><a style="width: 260px; clear: right; float: right; margin-left: 1em; margin-bottom: 1em;" href="sand-and-ash-issues-6.png"><img class="img-responsive post-img-link" src="sand-and-ash-issues-6.png" alt="GitLab example #7" height="326" width="252" /></a></p>
<p>Issues are done the same way as Milestones, but an issue can have a milestone associated with it which is why I do those first. It may not make sense to do issues, but I find them very helpful with the little things that always get lost. The easy issues are “get editing done” and “create a cover”, those can be assigned to a milestone without a problem.</p>
<p>In other times, while I'm working on the story, I'll realize that I need to go through the entire document and fix one specific item. When I realize these things, I'm either in the process of writing something else or I can't focus on it. For these situations, I'll create an issue to go through the book later and then I don't have to worry about forgetting it.</p>
<p>Some examples:</p>
<ul>
<li>Make sure Rutejìmo has his weapon from chapter 18 on</li>
<li>Create the epigraphs at the beginning of the chapters</li>
<li>Enter the epigraphs into the wiki site</li>
<li>Correct a character's name because it was confusing with another one</li>
<li>Back-fill foreshadowing for something</li>
<li>Add details about a city.</li>
</ul>
<p>One really nice feature of GitLab is that one issue can reference another one. If you type an octothorpe ("#"), the system will present a drop-down list of existing issues. There is some search by typing to reduce the list. This comes in handy if you have an issue that depends on another one (updating the wiki requires details being written).</p>
<p>While entering issues, you can use Markdown to create links, bold, italic, and even include images. Most of it is pretty easy if you use the editor bar (images are drag-and-drop).</p>
<p>When I create issues, many times I assign them to a milestone if I know it. For example, “updating the wiki site” is a v1.0.0 milestone. I noticed that the earlier releases will get 10-20 issues assigned to them but the later ones get more precise. They also focus on different things. “Assign ISBN” is a much later task compared to “Make sure he has green eyes.”</p>
<p>One nice thing about tracking tasks and items like this is that I get a list of things that I've done and ones that I have left to do. I found that some evidence of forward momentum helps in those moments when I'm most discouraged about writing ("I'm never going to finish…").</p>
<p>This a technical way of managing books and writing. For me, this works out pretty well because I use the same tools for programming. I'm also easily distracted (e.g., have too many projects), so being able to track the little things that go into writing something like a novel.</p>
Reorganizing my Git writing repository2014-10-05T05:00:00Zhttps://d.moonfire.us/blog/2014/10/05/reorganization-git-story-repo/Last night, I completely reorganized my writing repository to get around some limitations of Git.<p>As some of you may know, I use <a href="http://git-scm.com/">Git</a> to organize my writing. After years of accidentally overwriting a good chapter with an old one or trying to coordinate changes from two separate machines, I got into source control for writing; it worked for programming, why not my novels?</p>
<h1>The submodule approach</h1>
<p>Well, I've had a couple iterations of trying to get the “perfect” Git setup for my writing. Earlier this year, I broke apart the novels into submodules but left the bulk of my writing in the main repository (called <code>stories</code>). This meant I had a <code>sand-and-blood</code>, <code>sand-and-ash</code>, and <code>sand-and-bone</code> repository as submodules in the appropriate location of the <code>stories</code> repo (dmoonfire/fedran, if you are curious).</p>
<p>My reasons came while I was working on <span class="missing-link" data-path="/tags/sand-and-blood">Sand and Blood</span> covers. Since I checked in as I went, the size of the repository quickly became too large for my website to handle. I could download up to 50 MiB repo without too much trouble, but when it got into the 900 MiB range, I couldn't clone the repository anymore.</p>
<p>I had already worked with <a href="http://git-scm.com/book/en/Git-Tools-Submodules">submodules</a> before, so I thought they would be a perfect thing for the novels. I spent a pair of nights pulling out the five current WIP novels into a submodule, mainly by cloning the repo and using various commands to carve them out. It also took a while because I have a <em>lot</em> of project branches (41 beyond <code>master</code>) which represent every work-in-progress or semi-completed work I've done. Pulling out binaries from every branch was a painful process to say the least.</p>
<p>The submodule approach worked out fairly well, but I quickly found out some of its limitations. Because of how Git implements submodules, its inevitably shows up in other branches. It also has additional work.</p>
<p>To give an example. Assume I'm on my <code>sand-and-ash</code> branch and I'm happily working in the <code>dmoonfire/fedran/sand-and-ash</code> directory making changes. When I'm done, I've committed them and pushed up.</p>
<p>When I got up a level, to <code>dmoonfire/fedran</code>, I have to do a second commit to commit the submodule's position in the <code>stories</code> repository. It was a little extra work, but it kept the two isolated.</p>
<p>The real problem came when I switched to the <code>sand-and-blood</code> branch. The directory <code>dmoonfire/fedran/sand-and-ash</code> is still there and pointing to a repoistory (the <code>sand-and-ash</code> one), but I have to tell the <code>sand-and-blood</code> branch about it, otherwise it will show as an untracked file.</p>
<p>My two choices were to either add the <code>dmoonfire/fedran/sand-and-ash</code> directory to the <code>.gitignore</code> file of the <code>sand-and-blood</code> branch. (Okay, there are a lot of filenames in this post, sorry about that.)</p>
<p>The other approach is to add the submodule to the other branches so they didn't show as changes. Which worked until I made another change to the submodule and then I had to update it on <em>every</em> other branch to reflect the changes.</p>
<h1>Isolating covers instead</h1>
<p>Last night, I got tired of jumping through the hoops of submodules. I realized the entire reason I wanted to isolate the novels was to handle the covers. So, I decided to make a <code>covers</code> repository instead, put it into the root of the <code>stories</code> working directory and then add it to the <code>.gitignore</code>. This means that the <code>stories</code> repository doesn't officially know about the <code>covers</code> repository, but I can still reference it via soft links into <code>covers</code>.</p>
<p>The advantage of this approach is all the writing (actual words) are still managed in the same repository. This means when I switch branches, the stuff in <code>sand-and-ash</code> branch (not repo now) goes away until I go back. There isn't any cruft that drags on between the individual branches that has nothing to do with the current branch.</p>
<p>It isn't very elegant to have covers separated, but I only need covers when I'm formatting ebooks.</p>
<h1>Losing history</h1>
<p>One of the side effects of breaking apart the repository and pulling them back together is that I'm losing history data. I kept most of the commit histories intact, but now I can't really do a graph of total words written over a month or time. Since I can't tell if anyone actual read my posts when I documented them, I decided to accept that lose.</p>
<h1>BFG</h1>
<p>I mentioned that splitting apart the repositories was a lot of work. When I combined them back together, I was preparing myself for a lot of work. Then, I found <a href="http://rtyley.github.io/bfg-repo-cleaner/">BFG Repo Cleaner</a>. This is a Scala (a language I don't know) tool that works better than <code>git filter-branch</code> in a lot of ways.</p>
<p>I ended up using BFG to remove most of the cover images from the repository along with the large files. This let me trim the final <code>stories</code> repository from 1.9 GiB to 20 MiB. The <code>covers</code> repository is at a nice 419 MiB, but that is also acceptable since I use it so infrequently.</p>
<p>If you have to remove files, directories, or large objects from your repository, it looks like BFG is something to seriously consider.</p>
Author Intrusion - A black triangle CLI2014-08-02T05:00:00Zhttps://d.moonfire.us/blog/2014/08/02/author-intrusion-cli-and-black-triangle/I reached the first visible moment in Author Intrusion with command-line tool that does one thing, convert Markdown into DocBook formats.<p>Over the last week, I've been working on the current version of <a href="/tags/author-intrusion/">Author Intrusion</a>. It can get pretty discouraging since there is so much to do, so I'm focusing on a single task at a time and building out along the way so I will <em>hopefully</em> get a complete project by the end.</p>
<h1>Formatting</h1>
<p>One of the hardest things about coding is the GUI. There are so many things for getting events hooked up and the interface running smoothly. Being that GUIs are my weakest area of code, plus the state of the cross-platform .NET UI libraries is still a little weak, I'm going to work on other things.</p>
<p>I ended up deciding on project IO. For those who have read my blog in the post, you probably remember that I spend a lot of time working on automated the creation of ebooks and print from my source documents. Not to mention a lot of time working on creating a format that works the way I like to work.</p>
<p>That lead into my first goal: transforming a source project into another format. Eventually, this is going to lead into system used to create ODT, Microsoft Word, EPUB, MOBI, and everything else. Not to mention importing from other formats.</p>
<p>While I'm going to eventually have a GUI interface for it, I can also write a command-line interface (CLI) version which lets me get the functionality written without getting distracted by the GUI.</p>
<h1>Progress</h1>
<p>This weekend, I actually saw the beginning of my ideas show up. The initial framework for converting a <a href="http://daringfireball.net/projects/markdown/">Markdown</a> file into <a href="http://www.docbook.org/tdg5/en/html/docbook.html">DocBook 5</a> worked via the CLI.</p>
<pre><code class="language-shell">$ aicli transform sample.markdown sample.xml
</code></pre>
<p>I went with <code>aicli</code> (Author Intrusion CLI) for the tool. The interface is inspired by <a href="http://git-scm.com/">Git</a> with sub-commands and a somewhat flexible way of adding new tools.</p>
<p>The cool part is that the above command actually worked. It doesn't look like much, but there weeks of effort to get to that point. It's a <a href="http://philosophistry.com/archives/2009/01/what-is-a-black.html">black triangle</a> moment in this development.</p>
<h1>Formats</h1>
<p>I arranged the file formats into, creatively enough, <code>IBufferFormat</code> objects. They are discovered via an <a href="http://en.wikipedia.org/wiki/Inversion_of_control">IoC</a> container (<a href="http://docs.structuremap.net/">StructureMap</a>) and represent a single type of input or output.</p>
<p>The initial ones to get the above code working were:</p>
<ul>
<li>Markdown (input only)</li>
<li>DocBook (output only)</li>
</ul>
<p>I'll get these to be both input and output, that way anyone can use either Markdown or DocBook files for their primary project format. I'll also use these for the output formats:</p>
<ul>
<li>EPUB</li>
<li>MOBI</li>
<li>Libreoffice (ODT)</li>
<li>Microsoft Word (DOCX)</li>
</ul>
<h1>And it has options too!</h1>
<p>Yeah, the other bit I like is the single configurable option.</p>
<pre><code class="language-shell">$ aicli transform sample.markdown sample.xml -ORootElement=chapter
</code></pre>
<p>There may be more, but that puts me one step closer to replacing <code>mfgames-creole docbook</code> that I originally wrote for <a href="https://github.com/dmoonfire/mfgames-writing-python">MfGames Writing Python</a>.</p>