Skip to content
Brett Terpstra edited this page Dec 6, 2025 · 1 revision

C API

Apex provides a simple C API for programmatic Markdown to HTML conversion.

Overview

The Apex C API is thread-safe and designed for integration into C and C++ applications. All functions are declared in apex/apex.h.

Core Types

apex_mode_t

Processor compatibility modes:

typedef enum {
    APEX_MODE_COMMONMARK = 0,      /* Pure CommonMark spec */
    APEX_MODE_GFM = 1,              /* GitHub Flavored Markdown */
    APEX_MODE_MULTIMARKDOWN = 2,    /* MultiMarkdown compatibility */
    APEX_MODE_KRAMDOWN = 3,         /* Kramdown compatibility */
    APEX_MODE_UNIFIED = 4           /* All features enabled */
} apex_mode_t;

apex_options

Configuration structure for processing:

typedef struct {
    apex_mode_t mode;

    /* Feature flags */
    bool enable_tables;
    bool enable_footnotes;
    bool enable_definition_lists;
    bool enable_smart_typography;
    bool enable_math;
    bool enable_critic_markup;
    bool enable_wiki_links;
    bool enable_task_lists;
    bool enable_attributes;
    bool enable_callouts;
    bool enable_marked_extensions;

    /* Critic markup mode */
    int critic_mode;  /* 0=accept, 1=reject, 2=markup (default) */

    /* Metadata handling */
    bool strip_metadata;
    bool enable_metadata_variables;

    /* File inclusion */
    bool enable_file_includes;
    int max_include_depth;
    const char *base_directory;

    /* Output options */
    bool unsafe;  /* Allow raw HTML */
    bool validate_utf8;
    bool github_pre_lang;
    bool standalone;  /* Generate complete HTML document */
    bool pretty;      /* Pretty-print HTML */
    const char *stylesheet_path;
    const char *document_title;

    /* Line break handling */
    bool hardbreaks;  /* Treat newlines as hard breaks */
    bool nobreaks;    /* Render soft breaks as spaces */

    /* Header ID generation */
    bool generate_header_ids;
    bool header_anchors;  /* Generate <a> tags instead of id attributes */
    int id_format;  /* 0=GFM, 1=MMD, 2=Kramdown */

    /* Table options */
    bool relaxed_tables;
} apex_options;

Core Functions

apex_options_default

Get default options with all features enabled (unified mode).

apex_options apex_options_default(void);

Returns: Default options structure

Example:

apex_options opts = apex_options_default();
opts.enable_math = true;
opts.pretty = true;

apex_options_for_mode

Get options configured for a specific processor mode.

apex_options apex_options_for_mode(apex_mode_t mode);

Parameters:

  • mode - Desired processor mode

Returns: Options configured for the specified mode

Example:

apex_options gfm_opts = apex_options_for_mode(APEX_MODE_GFM);
apex_options mmd_opts = apex_options_for_mode(APEX_MODE_MULTIMARKDOWN);

apex_markdown_to_html

Main conversion function - converts Markdown to HTML.

char *apex_markdown_to_html(const char *markdown, size_t len,
                            const apex_options *options);

Parameters:

  • markdown - Input Markdown text (UTF-8)
  • len - Length of input text (use strlen() if null-terminated)
  • options - Processing options (NULL for defaults)

Returns: Newly allocated HTML string (must be freed with apex_free_string), or NULL on error

Example:

const char *markdown = "# Hello\n\nThis is **bold**.";
apex_options opts = apex_options_default();
char *html = apex_markdown_to_html(markdown, strlen(markdown), &opts);

if (html) {
    printf("%s\n", html);
    apex_free_string(html);
}

apex_free_string

Free a string allocated by Apex.

void apex_free_string(char *str);

Parameters:

  • str - String to free (can be NULL, safe to call on NULL)

Example:

char *html = apex_markdown_to_html(markdown, len, NULL);
// Use html...
apex_free_string(html);

apex_wrap_html_document

Wrap HTML content in a complete HTML5 document structure.

char *apex_wrap_html_document(const char *content, const char *title,
                              const char *stylesheet_path);

Parameters:

  • content - HTML content to wrap
  • title - Document title (NULL for default "Document")
  • stylesheet_path - Path to CSS file to link (NULL for none)

Returns: Newly allocated HTML document string (must be freed with apex_free_string)

Example:

char *fragment = apex_markdown_to_html(markdown, len, &opts);
char *document = apex_wrap_html_document(fragment, "My Document", "style.css");
apex_free_string(fragment);
// Use document...
apex_free_string(document);

apex_pretty_print_html

Pretty-print HTML with proper indentation.

char *apex_pretty_print_html(const char *html);

Parameters:

  • html - HTML to format

Returns: Newly allocated formatted HTML string (must be freed with apex_free_string)

Example:

char *html = apex_markdown_to_html(markdown, len, &opts);
char *pretty = apex_pretty_print_html(html);
apex_free_string(html);
// Use pretty...
apex_free_string(pretty);

Version Functions

apex_version_string

Get version string.

const char *apex_version_string(void);

Returns: Version string (e.g., "0.1.0")

apex_version_major / apex_version_minor / apex_version_patch

Get individual version components.

int apex_version_major(void);
int apex_version_minor(void);
int apex_version_patch(void);

Returns: Version component as integer

Complete Example

#include <apex/apex.h>
#include <stdio.h>
#include <string.h>

int main() {
    const char *markdown =
        "---\n"
        "title: Test Document\n"
        "author: John Doe\n"
        "---\n"
        "\n"
        "# [%title]\n"
        "\n"
        "By [%author]\n"
        "\n"
        "This has **bold** and a [[WikiLink]].\n"
        "\n"
        "Math: $E = mc^2$\n";

    // Use unified mode with all features
    apex_options opts = apex_options_for_mode(APEX_MODE_UNIFIED);
    opts.pretty = true;
    opts.standalone = true;
    opts.document_title = "Test Document";

    // Convert to HTML
    char *html = apex_markdown_to_html(markdown, strlen(markdown), &opts);

    if (html) {
        printf("%s\n", html);
        apex_free_string(html);
        return 0;
    } else {
        fprintf(stderr, "Conversion failed\n");
        return 1;
    }
}

Compiling and Linking

With CMake

# In your CMakeLists.txt
find_package(apex REQUIRED)
target_link_libraries(your_app apex)

Manual Compilation

# Compile
gcc -c -I/usr/local/include your_app.c

# Link
gcc your_app.o -L/usr/local/lib -lapex -o your_app

# Run (may need library path)
DYLD_LIBRARY_PATH=/usr/local/lib ./your_app  # macOS
LD_LIBRARY_PATH=/usr/local/lib ./your_app    # Linux

Static Linking

gcc your_app.c -I/usr/local/include -L/usr/local/lib -lapex -static -o your_app

Thread Safety

Apex is thread-safe as long as:

  1. Each thread uses its own apex_options structure
  2. Document nodes are not shared between threads
  3. The conversion function can be called from multiple threads simultaneously

Example:

// Thread-safe: each thread has its own options
void *thread_func(void *arg) {
    apex_options opts = apex_options_default();
    char *html = apex_markdown_to_html(markdown, len, &opts);
    // Use html...
    apex_free_string(html);
    return NULL;
}

Memory Management

  • All strings returned by Apex must be freed with apex_free_string()
  • apex_options structures are typically stack-allocated (no freeing needed)
  • Safe to call apex_free_string(NULL)
  • Always check return values before use

Error Handling

  • Functions return NULL or empty strings on error
  • Check return values before use
  • Errors are generally due to:
    • Memory allocation failures
    • Invalid input
    • Missing dependencies

Example:

char *html = apex_markdown_to_html(markdown, len, &opts);
if (!html) {
    fprintf(stderr, "Conversion failed\n");
    return 1;
}
// Use html...
apex_free_string(html);

Performance Tips

  1. Reuse options: Create apex_options once and reuse for multiple conversions
  2. Provide accurate length: Avoid unnecessary strlen() calls
  3. Disable unused features: Turn off extensions you don't need
  4. Batch processing: Process multiple documents in parallel (thread-safe)

Example:

// Good: reuse options
apex_options opts = apex_options_default();
for (int i = 0; i < count; i++) {
    char *html = apex_markdown_to_html(docs[i], lens[i], &opts);
    // Process...
    apex_free_string(html);
}

Related

Quick Links

Clone this wiki locally