Skip to main content

F2K Markdown source compiler: structured, composable .md → .f.md

Project description

fkmd — F2K Markdown

F2K Markdown Logo

中文文档

F2K Markdown is a Markdown source compiler designed for AI Agents and knowledge base maintenance. It lets you write Markdown like Python—bringing the modularity of programming languages to your documents.

In the AI Agent era, Markdown has become a new programming language, widely used in Agent Skills development, knowledge base construction, and system prompt management. However, as project complexity grows, plain text Markdown becomes hard to maintain:

  • Concept Duplication: The same terminology, version number, or configuration appears in multiple places, violating the Single Source of Truth (SSOT) principle.
  • Lack of Modularity: Unable to nest files, resulting in overly long files that are hard to read and reuse.
  • Tedious Formatting: Step numbers and heading levels require manual adjustment when reorganizing content.

F2K Markdown solves this by introducing a lightweight compilation mechanism:

  • Seamless Integration: Source files are ordinary .md files (identified by a #!fkmd header), and the compiled output is pure .f.md Markdown that any renderer or AI Agent can read natively.
  • Variables & Expressions: Embed Python variables or expressions directly in text using {python_expr}.
  • Code Block Execution: Execute Python logic within Markdown code blocks for data processing or environment initialization.
  • File Nesting: Embed other Markdown files with automatic heading level indentation for true document modularity.
  • Lenient Parsing: Syntax errors or undefined variables won't crash the compiler; they are output as plain text to ensure robustness.

Demo: Left is the source Markdown, right is the real-time compiled output

In the demo above: The left side shows the .md source file with variables and expressions, while the right side shows the .f.md output being compiled in real-time.


Installation

Install globally via uv (recommended):

uv tool install fkmd
# or install into your project
uv add fkmd

Alternatively, install from source:

git clone https://github.com/f2k-ai/f2k-markdown.git
cd f2k-markdown
uv sync
uv run fkmd --version

Quickstart

  1. Start the watcher in your document root:
cd your-document-root
fkmd watch .

Note: fkmd watch may prompt to upgrade existing .md files. This is optional but recommended. See CLI.

  1. Create a simple source file docs/hello.md:
#!fkmd 0.1
{name="World"}
# Hello {name}!
  1. The compiled output is automatically generated at .fkmd-output/docs/hello.f.md:
# Hello World!

For a real-world use case involving global variables, Python execution, and file embedding, see the Comprehensive Example below.


Syntax Cheatsheet

Inside any source .md file (with #!fkmd header):

Source Compiles to
#!fkmd 0.1 (stripped — must be the first line)
{name} str(name) from the entry-script namespace
{1 + 2} Any single-line Python expression evaluated at compile time
{name="a"} / {import math} A single-line Python statement
{{anything}} Literal {anything} (escape)
{@incr:section} DSL sugar: 1, 2, 3, … per counter name
{@doc:other.md,section="API"} DSL sugar: inlines other.md (or a specific section) with headings automatically shifted
```lang … ``` Markdown code blocks are exempt from parsing
```lang @fkmd … ``` Opt back in to {...} substitution inside a single fenced block
```python @exec … ``` Execute multi-line Python. Replaced by the last expression's value, or disappears if None

CLI

fkmd watch [WATCH_DIR] [-o OUTPUT_DIR] [-e ENTRY] [--once] [-y/--yes]
fkmd convert DIR
fkmd revert  PATH
  • fkmd watch: Continuously compile .md.f.md as files change.
  • fkmd convert: Safely upgrade plain .md files to fkmd sources. It adds the #!fkmd header and escapes existing braces (e.g., { to {{) to ensure your original content remains exactly unchanged after compilation.
  • fkmd revert: Strict inverse of fkmd convert. It strips the header and unescapes braces, restoring your files to their original plain Markdown state.

Programmatic API

fkmd is also a Python library. Use it when you want to compile sources in-memory without managing a file-system loop.

from fkmd import compile_string, compile_file, Compiler

# In-memory string → string
result = compile_string("hello {name}!", globals={"name": "World"})
print(result.text)             # "hello World!"

# Single file → write to a path
compile_file(
    "docs/api-reference.md",
    globals={"version": "1.2.3"},
    output="dist/api-reference.html.md",
)

# Long-lived Compiler
compiler = Compiler(entry=".fkmd-entry.py", base_dir="docs/")
result = compiler.compile_file("docs/system-prompt.md")

Comprehensive Example

Here is a full example demonstrating how to build a modular system prompt for an AI Agent using global variables, Python execution, and file embedding.

  1. Global Variables: Edit the entry script .fkmd-entry.py:
agent_name = "CodeCopilot"
  1. Main Document: Create your source file docs/00-quick-start.md:
#!fkmd 0.1 
{doc_version="v1.0"}
> Document Version: {doc_version}  -- local variable defined in this file
> Agent Name: {agent_name} -- global variable defined in .fkmd-entry.py
> Current Time: {import datetime; datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")}

# System Prompt

You are {agent_name}, an advanced AI coding assistant.

## {@incr:main}. Initial Setup

```python @exec
def test_api_connection():
    return "connected"
```

Your API connection status is: {test_api_connection()}.
**Do not proceed** if the status is not connected.

## {@incr:main}. Operating Procedures

### Step {@incr:agent_step}: Gather Context
Always read the relevant files first.

### Step {@incr:agent_step}: Plan
Formulate a plan before executing changes.

## {@incr:main}. API Reference
> Note: The embedded API documentation's heading levels are automatically aligned to sit under this section.

{@doc:00b-quick-start.md, section="API Endpoints"}
  1. Embedded Document: Create the embedded file docs/00b-quick-start.md:
#!fkmd 0.1
# API Endpoints
## GET `/api/v1/status`
Check health status.
  1. Compiled Output: The output will be automatically generated at .fkmd-output/docs/00-quick-start.f.md:
> Document Version: v1.0  -- local variable defined in this file
> Agent Name: CodeCopilot -- global variable defined in .fkmd-entry.py
> Current Time: 2026-05-15 17:36:02

# System Prompt

You are CodeCopilot, an advanced AI coding assistant.

## 1. Initial Setup

Your API connection status is: connected.
**Do not proceed** if the status is not connected.

## 2. Operating Procedures

### Step 1: Gather Context
Always read the relevant files first.

### Step 2: Plan
Formulate a plan before executing changes.

## 3. API Reference
> Note: The embedded API documentation's heading levels are automatically aligned to sit under this section.

### API Endpoints

#### GET `/api/v1/status`
Check health status.

Under the Hood

To understand how {python_expr} are evaluated, it helps to know the execution order during a compile pass:

  1. Entry Script Execution: Before any Markdown file is processed, the entry script (e.g., .fkmd-entry.py) is executed exactly once. Any variables, functions, or imports defined here become the shared global namespace for the entire compile pass.
  2. File Compilation: Each .md source file is then compiled. Each file gets its own fresh local namespace.
  3. Expression Evaluation: When the compiler encounters {expression} or a ```python @exec block, it evaluates the Python code using the file's local namespace backed by the shared global namespace. This means you can read global variables anywhere, but local assignments (like {doc_version="v1.0"}) remain isolated to that specific file.

Roadmap

See the roadmap for the detailed features and issues.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fkmd-0.1.0.tar.gz (39.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

fkmd-0.1.0-py3-none-any.whl (43.8 kB view details)

Uploaded Python 3

File details

Details for the file fkmd-0.1.0.tar.gz.

File metadata

  • Download URL: fkmd-0.1.0.tar.gz
  • Upload date:
  • Size: 39.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for fkmd-0.1.0.tar.gz
Algorithm Hash digest
SHA256 20bdef2c77cb430e2b2b842aa9e932c58318e065501780e9e888386431f49f2f
MD5 36014123d1dca1d5147c43db86334ba3
BLAKE2b-256 1cd4d3aa8e7bfa4111e789d7234c55cb6524e64ad85278651cc42c7e7fd0cdda

See more details on using hashes here.

Provenance

The following attestation bundles were made for fkmd-0.1.0.tar.gz:

Publisher: publish.yml on AlbertZSCreator/f2k-markdown

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file fkmd-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: fkmd-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 43.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for fkmd-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 8bbd9bcd83118c213d7ebadf3fc92569527457e0c8a838b93f5645b228e0900b
MD5 5752f9914ced500f752069d32efec7bf
BLAKE2b-256 59b3912afe0bc2b419aeb212b7da88c50b36bcd8919833021515522280985201

See more details on using hashes here.

Provenance

The following attestation bundles were made for fkmd-0.1.0-py3-none-any.whl:

Publisher: publish.yml on AlbertZSCreator/f2k-markdown

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page