Michael HönnigMichael Hönnig

When blogging about software development, it’s often helpful to include snippets of source code examples to the prosa. Even if we took these examples from working code, sooner or later they might break. E.g. a search & replace got applied to reserved words in the snippets. Such is very confusing for the readers because they want to learn from the examples, if these don’t even compile?

A great practice is including the snippets automatically from real source code files. Then we can check these files for correctness using a compiler and unit tests. AsciiDoctor can do this with AsciiDoc documents, which are the source article format of my JBake blog.

Here an example for what we want to achieve:

function example(number1, number2) {
    return `${number1} + ${number2} = ${parseInt(number1) + parseInt(number2)}`
}

Let’s see in detail how it can be done with JBake.

Given Some Example-Source-Code

Given, we have some piece of working source code which we want to embed in a blog article as well as a unit test.

the whole source code file
function example(number1, number2) {
    return `${number1} + ${number2} = ${parseInt(number1) + parseInt(number2)}`
}

// test cases
assertEquals('12 + 30 = 42', example(12, 30))

// test helper
// - check when using a unit test framwork becomes more appropriate!
function assertEquals(expected, actual) {
    if (actual !== expected) {
        console.log('example broken: ' + __filename)
        console.log(`   expected '${expected}', but got: '${actual}'`)
        process.exit(1)
    }
}

As you can see, a kind of unit test is included in the source code. If things are getting more complicated, we might need a unit testing framework.

Testing the Source Code

To test my code examples, I’ve created a batch job which simply executes the files:

find content/ -name "*.js" | xargs --max-lines=1 node

This finds all Java-Script files below my content directory and runs node on each. For other programming languages, similar solutions can be applied.

Including the Example Snippet into the Document

In my AsciiDoc document I only want to render the example snippet without the tags and without the test. Again, how it should look like:

function example(number1, number2) {
    return `${number1} + ${number2} = ${parseInt(number1) + parseInt(number2)}`
}

Now see, how such can be accomplished:

I put related files in sub-folders below my articles, e.g. img for images and src for source files. For example, this article is in content/blog/2020/2020-10-26-jbake-asciidoc-render-snippets-from-source-code.adoc, and the related source code from above is in content/blog/2020/2020-10-26-some-source-code.js.

This way I can include this file into my AsciiDoc-document with a relative path:

AsciiDoc snippet to include the JavaScript example from above:
[source,js]
----
include::src/2020-10-26-some-source-code.js[tag=exampleCode]
----

That’s all - happy blogging, with working source code snippets!

More information on these partial inclides can be found in the AsciiDoctor user manual.

By the way, even the AsciiDoc plugin for IntelliJ IDEA can display such includes and has autocompletion for the tag names.