BareGit
# MacroDown

MacroDown is a C++ Markdown processor that extends the CommonMark syntax with a powerful TeX-like macro system. It treats all markup elements as syntactic sugar for macro calls, allowing for extensive customization and extension.

## Features

*   **CommonMark Compatible**: Supports standard Markdown syntax like headers, lists, blockquotes, code blocks, emphasis, and links.
*   **Macro System**: unique TeX-like macro system (`%macro{arg1}{arg2}`) that powers the entire rendering process.
*   **Custom Markups**: Define custom prefix or delimited markup patterns that transform into macro calls.
*   **Customizable**: Define your own macros using the `%def` intrinsic.
*   **Two-Step Rendering**: Exposes the syntax tree for inspection or modification before rendering to HTML.

## How it Works

MacroDown uses a unified approach to document processing. Instead of having separate logic for every Markdown element, the parser first transforms standard Markdown syntax into an internal tree of macro calls.

For example:

*   `# Heading` is converted to `%h1{Heading}`
*   `*Emphasis*` is converted to `%em{Emphasis}`
*   `> Quote` is converted to `%quote{Quote}`

These macros are then evaluated using a standard library of definitions that produce the final HTML output. This architecture makes it incredibly easy to change the output of standard Markdown elements by simply redefining their corresponding macros.

## Building

MacroDown uses CMake for building. You will need a C++23 compliant compiler.

```bash
mkdir build
cd build
cmake ..
make
```

## Integration

### Using FetchContent

You can add MacroDown to your project using CMake's `FetchContent`.

```cmake
include(FetchContent)

FetchContent_Declare(
  macrodown
  GIT_REPOSITORY https://git.xeno.darksair.org/macrodown.git
  GIT_TAG master # Or a specific tag/commit
)

FetchContent_MakeAvailable(macrodown)

# Link to the library
target_link_libraries(your_target PRIVATE MacroDown::MacroDown)
```

## Usage

### CLI

You can use the `macrodown` executable to convert Markdown to HTML.

**From a file:**

```bash
./macrodown input.md > output.html
```

**From stdin:**

```bash
echo "# Hello World" | ./macrodown
```

### Library Interface

You can integrate MacroDown into your C++ projects using the `MacroDown` class.

```cpp
#include "macrodown.h"
#include <iostream>

int main() {
    macrodown::MacroDown md;

    std::string input = "# Hello\n\nThis is **MacroDown**.";

    // Step 1: Parse to Syntax Tree
    auto root = md.parse(input);

    // Step 2: Render to HTML
    std::string html = md.render(*root);

    std::cout << html << std::endl;
    return 0;
}
```

### Defining Macros

You can define macros directly in your Markdown document:

```markdown
%def[greet]{name}{Hello, %strong{%name}!}

%greet{World}
```

Output:
```html
<p>Hello, <strong>World</strong>!</p>
```

Or programmatically in C++:

```cpp
md.evaluator().define("greet", {"name"}, "Hello, %name!");
```

### Custom Markups

MacroDown allows you to define custom shorthand syntax that maps to macros.

#### Prefix Markups
Useful for tags or mentions. A prefix markup starts with a character and ends at a whitespace or punctuation boundary.

```cpp
// Transforms #test into %tag{test}
md.definePrefixMarkup({"#", "tag", ""});
md.evaluator().define("tag", {"content"}, "<span class=\"tag\">#%content</span>");
```

#### Delimited Markups
Useful for custom inline styles. A delimited markup starts and ends with the same character.

```cpp
// Transforms :important: into %highlight{important}
md.defineDelimitedMarkup({":", "highlight"});
md.evaluator().define("highlight", {"content"}, "<mark>%content</mark>");
```

## Testing

To run the unit tests:

```bash
cd build
./macrodown_test
```

## Project Structure

*   `include/`: Header files.
*   `src/`: Source code.
*   `tests/`: Unit and integration tests.
*   `design.md`: Detailed design document.