A transpiler for literate programming in C (and other compiled languages).
Find a file
2026-01-11 23:31:11 +01:00
includes Initial commit 2026-01-11 23:31:11 +01:00
srcs Initial commit 2026-01-11 23:31:11 +01:00
tests Initial commit 2026-01-11 23:31:11 +01:00
.gitignore Initial commit 2026-01-11 23:31:11 +01:00
LICENSE Initial commit 2026-01-11 23:31:11 +01:00
Makefile Initial commit 2026-01-11 23:31:11 +01:00
README.md Initial commit 2026-01-11 23:31:11 +01:00
sources.mk Initial commit 2026-01-11 23:31:11 +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)

Project Structure

c-md supports mixed projects with both documented (.c.md) and regular (.c) files:

project/
  srcs/
    main.c.md       <- documented source
    legacy.c        <- regular source
  includes/
    api.h.md        <- documented header
    types.h         <- regular header
  build/
    srcs/
      main.c        <- transpiled
      legacy.c      <- symlinked
    includes/
      api.h         <- transpiled
      types.h       <- symlinked
    objs/
      *.o
    maps/
      main.map      <- line mapping (for tooling)
      api.map

Usage

Options

-h, --help        Show help message
-e, --ext <ext>   Extension to filter
-t, --transpile   File mode: transpile <input>
-o <file>         Output file 
-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 -e c -t main.c.md -o build/main.c

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

Makefile Integration

BUILD_DIR = build
SRC_DIR = src

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

Code Block Rules

Only code blocks with a matching extension are extracted:

File: main.c.md (extension = c)

'''c           <- extracted (c == c)
int foo(void);
'''

'''bash        <- ignored (bash != c)
echo "hello"
'''

'''            <- ignored (no extension)
some text
'''

Multiple code blocks are concatenated with a blank line separator.

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

License

GPL3