knitc
knitc
A literate programming engine for AsciiDoc documents, inspired by knitr. Parses AsciiDoc source blocks, executes code in 17 languages, and weaves results back into the output.
Built on crystal-asciidoctor for AsciiDoc parsing and conversion to HTML5, DocBook 5, and manpage formats.
Upstream README Highlights
The R package knitr is a general-purpose literate programming engine with lightweight APIs designed to give users full control of output without heavy coding work. knitc brings knitr's core capabilities to AsciiDoc: chunk options, multi-language engine dispatch, result caching, output hooks, code reuse via ref_label and <<label>>, inline expressions, parameterized documents, and tangle (code extraction). See vendor/knitr/README.md for the upstream submodule README.
Installation
git clone --recurse-submodules https://github.com/dsisnero/knitc.git
cd knitc
make install
crystal build src/cli.cr -o bin/knitc
Quick Start
knitc report.adoc # weave + convert to HTML
knitc report.adoc -o report.adoc # weave only (AsciiDoc output)
knitc report.adoc -b docbook5 # weave + convert to DocBook 5
knitc --tangle report.adoc # extract code to script
Example
Given report.adoc:
= My Report
The answer is knitc:ruby[puts 6 * 7].
[source,ruby]
----
names = ["Alice", "Bob", "Charlie"]
names.each { |n| puts n }
----
Running knitc report.adoc -o report-out.adoc produces:
= My Report
The answer is 42.
[source,ruby]
----
names = ["Alice", "Bob", "Charlie"]
names.each { |n| puts n }
----
....
## Alice
## Bob
## Charlie
....
CLI Reference
Usage: knitc [options] INPUT
-o OUTPUT, --output OUTPUT Output file path (.html or .adoc)
-b BACKEND, --backend BACKEND Output backend (html5, docbook5, manpage)
-p KEY=VALUE, --param KEY=VALUE Set document parameter
-s KEY=VALUE, --set KEY=VALUE Set global chunk default
-t, --tangle Extract code (like knitr's purl)
--documentation N Tangle documentation level (0=code, 1=headers, 2=text)
--cache-path DIR Cache directory
--root-dir DIR Working directory for code execution
-v, --version Show version
-h, --help Show help
Examples
# Weave and convert to HTML (default)
knitc input.adoc
# Weave only — produce AsciiDoc with results woven in
knitc input.adoc -o woven.adoc
# Convert to DocBook 5 XML
knitc input.adoc -b docbook5
# Pass parameters (substituted via AsciiDoc attributes + KNITC_PARAM_ env vars)
knitc input.adoc -p author=Alice -p version=2.0
# Set global chunk defaults (all chunks inherit unless overridden)
knitc input.adoc -s echo=false -s cache=true
# Execute code in a specific working directory
knitc input.adoc --root-dir /path/to/data
# Enable caching
knitc input.adoc --cache-path cache/
# Extract code (tangle / purl)
knitc --tangle input.adoc # code only
knitc --tangle --documentation 1 input.adoc # code + chunk labels
knitc --tangle --documentation 2 input.adoc # code + text as comments
Chunk Options
Options are set as AsciiDoc block attributes on source blocks:
[source,ruby,eval=true,echo=false,cache=true]
----
puts "Hello"
----
| Option | Default | Description |
|---|---|---|
eval |
true |
Execute the code block |
echo |
true |
Include source code in output |
results |
"markup" |
How to present results: markup, asis, hold, hide |
include |
true |
Include block (code + output) in final document |
cache |
false |
Cache results (true = level 3, or 1-3) |
collapse |
false |
Merge source and output into one block |
comment |
"##" |
Prefix for output lines |
error |
true |
Show errors in output |
warning |
true |
Show warnings in output |
message |
true |
Show messages in output |
engine |
(from lang) | Override language engine |
fig_path |
"figure/" |
Directory for generated figures |
fig_cap |
nil |
Figure caption |
linenums |
false |
Add %linenums to source block |
start |
nil |
Starting line number (with linenums) |
strip_white |
true |
Trim leading/trailing blank lines from source |
ref_label |
nil |
Prepend code from labeled chunk(s), semicolon-separated |
depends_on |
nil |
Cache dependency on other chunk label(s) |
child |
nil |
Path to child document to include |
purl |
true |
Include in tangle output |
timeout |
nil |
Kill engine after N seconds |
engine_path |
nil |
Custom interpreter path |
file |
nil |
Output file path (for cat engine) |
command |
nil |
Command to run (for exec engine) |
Engines
17 built-in language engines:
| Engine | Command | Flag |
|---|---|---|
bash |
bash |
-c |
sh |
bash |
-c |
ruby |
ruby |
-e |
python / python3 |
python3 |
-c |
crystal |
crystal |
eval |
perl |
perl |
-E |
node |
node |
-e |
php |
php |
-r |
scala |
scala |
-e |
zsh |
zsh |
-c |
verbatim |
— | Pass-through, no execution |
comment |
— | Returns nothing |
cat |
— | Writes code to file attribute path |
exec |
command attr |
Runs command with code as temp file |
asis |
— | Raw content pass-through |
embed |
— | Reads file path from code, returns contents |
Custom interpreter paths via engine_path attribute. Process timeout via timeout attribute (seconds).
Inline Expressions
Embed code results inline with knitc:lang[code]:
The answer is knitc:ruby[puts 6 * 7].
Today is knitc:bash[echo $(date +%Y-%m-%d)].
Code Reuse
ref_label
Prepend code from another labeled chunk:
[source,ruby,id=helpers,eval=false]
----
def greet(name) = "Hello " + name
----
[source,ruby,ref_label=helpers]
----
puts greet("World")
----
<
Expand a labeled chunk inline within code (preserves indentation):
[source,ruby,id=body,eval=false]
----
puts "inside"
----
[source,ruby]
----
def wrapper
<<body>>
end
wrapper
----
External Code Files
Read labeled sections from external scripts using ## ---- label ----:
# lib.rb
## ---- setup ----
x = 1
## ---- compute ----
puts x + 1
external = Knitc.read_chunks("lib.rb")
Knitc.knit(source, external_chunks: external)
Caching
Enable per-chunk with cache=true. Results are stored as JSON in the cache directory, keyed by MD5 hash of code + options. Dependency tracking via depends_on attribute cascades invalidation.
knitc input.adoc --cache-path cache/
Child Documents
Include and process sub-documents:
[source,knitc,child=chapter1.adoc]
----
----
Parameterized Documents
Pass parameters via CLI or API. Available as AsciiDoc attribute substitutions ({name}) and as KNITC_PARAM_* environment variables in engines:
knitc report.adoc -p title="Q3 Report" -p year=2026
Documentation
- Architecture — pipeline, modules, design decisions
- Development — setup, workflow, quality gates
- Coding Guidelines — conventions, porting rules
- Testing — spec structure, parity testing, fixtures
- PR Workflow — checklist, quality gates
- Parity Plan — knitr feature parity tracking
- Changelog — release history
Development
make install # install dependencies
make format # auto-format source
make lint # ameba linter
make test # crystal spec (208 specs)
make clean # remove build artifacts
Contributing
- Fork it (https://github.com/dsisnero/knitc/fork)
- Create your feature branch (
git checkout -b my-new-feature) - Commit your changes (
git commit -am 'Add some feature') - Push to the branch (
git push origin my-new-feature) - Create a new Pull Request
Contributors
- Dominic Sisneros - creator and maintainer
knitc
- 0
- 0
- 0
- 0
- 2
- 17 days ago
- June 17, 2026
MIT License
Sat, 20 Jun 2026 18:02:28 GMT