mdpp

package module
v0.9.6 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 22, 2025 License: MIT Imports: 19 Imported by: 0

README

mdpp(1)

Markdown preprocessor for cross-file code, table, title synchronization, and file inclusion. Processing is idempotent.

INSTALLATION

Pre-built binaries are available at Releases.

Build from source:

go install github.com/knaka/mdpp/cmd/mdpp@latest

SYNOPSIS

Concatenate the rewritten results and output to standard output:

mdpp input1.md input2.md >output.md

In-place rewriting:

mdpp -i rewritten1.md rewritten2.md

DESCRIPTION

mdpp(1) is a Markdown preprocessor that synchronizes code blocks, tables, and link titles across files, and includes external Markdown files using special HTML comment directives. It is designed for use in documentation build pipelines or as an editor integration to keep Markdown content up-to-date with source files and other Markdown documents.

Supported Directives
+SYNC_TITLE / +TITLE

Replaces the link text with the title from the target Markdown file.

The title is determined in the following order of priority:

  1. The title property in YAML Front Matter
  2. The only H1 (#) heading in the document (if there is exactly one)
  3. The file name (without extension)

Input:

[link text](docs/hello.md)<!-- +SYNC_TITLE -->

Output:

[Hello document](docs/hello.md)<!-- +SYNC_TITLE -->
+MILLER / +MLR

Processes the table above the directive using a Miller script. This feature is inspired by the #+TBLFM: ... line comment of Emacs Org-mode.

Input:

| Item | Unit Price | Quantity | Total |
| --- | --- | --- | --- |
| Apple | 2.5 | 12 | 0 |
| Banana | 2.0 | 5 | 0 |
| Orange | 1.2 | 8 | 0 |

<!-- +MLR:
  $Total = ${Unit Price} * $Quantity;
-->

Output:

| Item | Unit Price | Quantity | Total |
| --- | --- | --- | --- |
| Apple | 2.5 | 12 | 30 |
| Banana | 2.0 | 5 | 10 |
| Orange | 1.2 | 8 | 9.6 |

<!-- +MLR:
  $Total = ${Unit Price} * $Quantity;
-->
+INCLUDE ... +END

Includes the content of an external Markdown file.

Input:

<!-- +INCLUDE: path/to/another.md -->
<!-- +END -->

Output (after running mdpp):

<!-- +INCLUDE: path/to/another.md -->
## Content from another.md

This is the content of `another.md`.
<!-- +END -->

Features:

  • Nested inclusion: Files included with +INCLUDE can contain their own +INCLUDE directives, supporting multiple levels of nesting.
  • Cycle detection: The processor automatically detects and prevents infinite loops when files include each other in a cycle.

Limitations:

  • Indented directives: The +INCLUDE and +END directives must be at the beginning of their lines (ignoring leading/trailing whitespace). Indented directives within code blocks or blockquotes are not supported.
  • Relative path resolution: When including a file from another directory, relative paths within the included content (such as image paths) are not automatically resolved relative to the included file's location. They remain relative to the main document's directory.
+CODE

Inserts the contents of an external file into a fenced or indented code block.

Input (fenced code block):

```
foo
bar
```

<!-- +CODE: path/to/file.c -->

Output (after running mdpp):

```
#include <stdio.h>

int main(int argc, char** argv) {
    printf("Hello, World!\n");
    return 0;
}
```

<!-- +CODE: path/to/file.c -->

Input (indented code block):

    int x = 0;
    printf("%d", x);

<!-- +CODE: path/to/file.c -->

Output (indented code block):

    #include <stdio.h>
    
    int main(int argc, char** argv) {
        printf("Hello, World!\n");
        return 0;
    }

<!-- +CODE: path/to/file.c -->

USAGE EXAMPLES

  • Write to standard output:

    mdpp README.md >README.out.md
    
  • In-place update (for editor integration):

    mdpp -i README.md
    

For in-place usage, VSCode's plugin “Run on Save” can automatically run mdpp when saving a Markdown file. Example settings:

"emeraldwalk.runonsave": {
  "commands": [
    {
      "match": "\\.md$",
      "cmd": "mdpp -i ${file}"
    }
  ]
},

NOTES

  • Directives must be written as HTML comments immediately after the relevant code block, table block, or link inline-element.
  • For +INCLUDE directives, both +INCLUDE and +END comments must be at the beginning of their lines (ignoring leading/trailing whitespace).
  • Directive names are case-insensitive.
  • The output preserves the directive comments, so repeated runs are idempotent.
  • Title extraction uses the following priority:
    1. The title property in YAML Front Matter
    2. The only H1 (#) heading in the document (if there is exactly one)
    3. The file name (without extension)

LICENSE

MIT License

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Process added in v0.9.2

func Process(sourceMD []byte, writer io.Writer, dirPathOpt *string) error

Process parses the source markdown, detects directives in HTML comments, applies modifications, and writes the result to the writer. If dirPathOpt is not nil, it changes the working directory to that path before processing.

Supported directives:

  • INCLUDE ... END : Include the content of an external Markdown file.
  • SYNC_TITLE | TITLE : Extract the title from the linked Markdown file and use it as the link title.
  • MLR | MILLER : Processes the table above the comment using a Miller script.
  • CODE : Reads the content of the file specified and writes it as a code block.

Planned features:

  • H1INCLUDE, H2INCLUDE, ...
  • TBLFM (?)

func SetDebug added in v0.9.2

func SetDebug(d bool)

SetDebug sets the debug mode for the package.

Types

This section is empty.

Directories

Path Synopsis
cmd
mdpp command
Main for mdpp, a Markdown preprocessor
Main for mdpp, a Markdown preprocessor
ext
Package ext is ext
Package ext is ext

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL