BIT-101
Bill Gates touched my MacBook Pro
Back in late 2022, through the start of 2023, I wrote fourteen blog posts in a series called “Coding Curves”. That’s still up on the 2017-2023 version of this blog:
https://bit-101.com/2017/2022/11/coding-curves/
My intention was always to compile these into a book. I’d wanted to write this book for a LONG time, and started it multiple times. Only by writing it post by post and publishing it piecemeal was I able to get it out. But three years went by and the book form never emerged. Part of it was plain inertia and procrastination, but there were also technical hurdles.
One issue was that the original posts were written in WordPress. Converting that to EPUB/PDF meant probably converting it to markdown first, then running it through pandoc to create the final book. Or, I could grab the HTML that WordPress generated and try to use pandoc on that, but There was SO MUCH excess HTML and CSS added, that I didn’t feel great about that.
But since then I’d converted that whole site to markdown and used Hugo to publish it as a static site. So now I had the markdown. It still needed a lot of cleanup, but it was doable.
The second big issue was that, while I’d previously self-published Playing With Chaos using pandoc, my build process was really cumbersome, and 13 years out of date. I hesitate to admit this, but the book build was written in Ant! You remember Ant? It’s basically “make” or “just” but the build file is written in XML. Yikes!
It was also very tailored to creating books for publishing on Amazon Kindle. It used a proprietary kindlegen.exe command line app (yes, Windows) and a handful of custom Python scripts to massage the table of contents into shape. I really didn’t want to look at this.
But when I finally got up the courage, I found that I could strip it way, way down. In fact, I could do the entire build with just pandoc. It was just a matter of passing all the markdown files to pandoc and outputting the result to an EPUB. There were a few command line switches for things like generating a table of contents, adding a cover image, embedded font, and CSS file. But no other scripts or tools in the toolchain. Great. (Needless to say, I am no longer using Ant, either. Moved it over to just.)
Cleaning up the markdown was a pain. All the images carried through the original WordPress image tags that had multiple sizes of the same image listed. And a ton of punctuation characters - quotes, dashes, greater than, less than, etc. - were expanded to HTML entities. I became somewhat of an expert with sed which allowed me to clean all of that up across all of the chapter files. But even after that, it took a lot of manual clean up to get it into shape. And then I had to grab all the right images from the site and put them in the book folder and make sure they were all correctly linked.
All that was just clean up. After that began the editing.
First, spell check, grammar check, my own custom script to find “weasel words” - cliches that don’t add any value to the text.
And checking all the pseudocode to make sure it was correct. To do this, I made a little app that allowed me to paste in the pseudocode from the book and with relatively few adjustments, let me run it in Go using my own existing libraries. I’m not talking about transcoding or transpiling. I made function definitions that matched the pseudocode functions. These were wrappers for the real functionality in my library. For example, here are a few:
func canvas(w, h float64) {
width = w
height = h
context = cairo.CreateContext(w, h)
context.ClearWhite()
context.SetSourceBlack()
context.SetLineWidth(0.5)
}
func lineTo(x, y float64) {
context.LineTo(x, y)
}
func moveTo(x, y float64) {
context.MoveTo(x, y)
}
func stroke() {
context.Stroke()
}
I also made a bunch of aliases to things, and “global” vars.
var (
cos = math.Cos
sin = math.Sin
tan = math.Tan
sqrt = math.Sqrt
atan2 = math.Atan2
acos = math.Acos
width, height float64
context *cairo.Context
)
Then, I could paste in a pseudocode example straight from the book, like this:
canvas(800, 800)
moveTo(100, 100)
lineTo(700, 700)
stroke()
And that would just work!
All this saved me from having to re-write each snippet in some other language in order to test it. I could actually run most of the pseudocode as-is.
After all that, I just had a lot of re-writing to do. Making it read more like a book, not a bunch of blog posts. Removed extraneous passages and awkward wording, added better examples and explanations where needed, generated new code samples and images where called for. In some cases, I rewrote almost entire chapters, with all new code and images.
I also removed all the animation examples, sadly. I imagine there are ways to embed animations in some ebook formats, but I didn’t want to go there.
All of this took several weeks. Whole weekends would fly by when that’s almost all I did. But I’m at the end of it. It’s in great shape, but I’m going through one more pass of the whole book cover to cover and making sure everything is clear and sounds right. I hope to get through that in another week or so.
I considered adding a few more chapters. There are some topics I think would fit in well - stuff I discovered in the past few years. But I decided to release it as-is. As an ebook, I can easily add more chapters later and release an updated version.
The plan is to release it on Gumroad, alongside Playing With Chaos. DRM-free, EPUB, PDF and AZW3. Watch this space.