A transpiler for literate programming in C (and other compiled languages).
Find a file
2026-01-12 18:09:10 +01:00
includes docs: update function reference links to use anchor fragments in headers 2026-01-12 17:42:40 +01:00
srcs docs: add documentation to each .c.md file 2026-01-12 16:22:13 +01:00
tests test: reorganize unit tests 2026-01-12 10:18:47 +01:00
.gitignore Initial commit 2026-01-11 23:31:11 +01:00
bootstrap.sh feat(build): add build instructions in README and convert sources to .c.md format 2026-01-12 14:54:49 +01:00
LICENSE Initial commit 2026-01-11 23:31:11 +01:00
Makefile feat(build): add build instructions in README and convert sources to .c.md format 2026-01-12 14:54:49 +01:00
README.md fix: dead link 2026-01-12 18:09:10 +01:00
sources.mk feat(build): add build instructions in README and convert sources to .c.md format 2026-01-12 14:54:49 +01:00

c-md

A transpiler for literate programming in C (and other compiled languages).

Write documentation and code in a single Markdown file. The transpiler extracts the code for compilation while keeping your source readable and well-documented.

Concept

Inspired by Donald Knuth's literate programming, c-md lets you write files like main.c.md that combine Markdown documentation with code blocks. The transpiler extracts the code into pure .c files ready for compilation.

File Format

Source files use the pattern <name>.<ext>.md:

main.c.md   ->  main.c
utils.h.md  ->  utils.h

Example: main.c.md

# Main Entry Point

This file contains the program entry point.
It initializes the system and starts the main loop.

## Dependencies

- stdlib.h for memory allocation
- stdio.h for I/O operations

## Implementation

'''c
#include <stdlib.h>
#include <stdio.h>

int main(void)
{
    printf("Hello, World\n");
    return 0;
}
'''

(Note: Use standard triple backticks ``` in actual files)

Usage

Options

-h, --help            Show help message
-e, --ext <ext>       Extension to extract (c, h, py, etc.)
-i, --input <file>    Input file (default: stdin)
-o, --output <file>   Output file (default: stdout)
-m, --map <file>      Generate line mapping file

Pipe Mode (stdin/stdout)

# Basic transpilation
cat main.c.md | c-md -e c > main.c

# With line mapping
cat main.c.md | c-md -e c -m build/maps/main.map > main.c

File Mode

# Basic transpilation
c-md -i main.c.md -o build/main.c

# With line mapping
c-md -i main.c.md -o build/main.c -m build/maps/main.map

# Extension auto-inferred from filename
c-md -i main.c.md -o build/main.c

Makefile Integration

BUILD_DIR = build
SRC_DIR = src

$(BUILD_DIR)/%.c: $(SRC_DIR)/%.c.md
	c-md -i $< -o $@ -m $(BUILD_DIR)/maps/$*.map

Code Block Filtering

The transpiler extracts only code blocks matching the specified extension.

For file main.c.md with -e c:

  • ```c blocks are extracted
  • ```python blocks are ignored
  • ``` blocks (no language) are ignored

Multiple matching code blocks are concatenated with a blank line separator.

Building

c-md is self-hosted (dogfooding). The source code is written in .c.md format and requires c-md itself to build.

First Build (Bootstrap)

After cloning or after make fclean, run the bootstrap script:

./bootstrap.sh
make

The bootstrap script builds c-md by traversing major version tags, starting from v1.0.0 (plain C sources) up to the current version.

Regular Build

Once c-md is available:

make          # build from .c.md sources
make clean    # remove build artifacts
make fclean   # remove everything including binary
make re       # rebuild from scratch

Line Mapping

The transpiler generates .map files that track the correspondence between source lines (.c.md) and output lines (.c). This enables:

  • Accurate error reporting back to original files
  • IDE/LSP integration (WIP)
  • Debugging with correct source locations

Status

v2.0.0 - Initial stable release self-hosted.

License

GPL3