DOCS/Documentation Plugin

Documentation Plugin

The documentation plugin (@functional-examples/documentation) generates markdown documentation from scanned examples. It provides template-based generation, prose helpers for embedding code, and guide rendering with cross-example references.

Installation

npm install @functional-examples/documentation

Setup

import { createDocumentationPlugin } from '@functional-examples/documentation';
import { createJavaScriptPlugin } from '@functional-examples/javascript';
import type { Config } from 'functional-examples';

/**
 * Configuration demonstrating the documentation plugin.
 *
 * The documentation plugin:
 * - Adds the `generate` CLI command
 * - Enables template-based doc generation
 * - Provides prose helpers (file(), region())
 */
const config: Config = {
  plugins: [
    createJavaScriptPlugin(),
    createDocumentationPlugin({
      outputDir: 'generated-docs',
      format: 'markdown',
    }),
  ],
  scan: {
    include: ['src/**/*'],
    exclude: ['**/node_modules/**', '**/dist/**'],
  },
};

export default config;

Plugin Options

OptionTypeDefaultDescription
outputDirstring'docs'Directory for generated documentation
format'markdown' | 'mdoc''markdown'Output format
enableExtractorbooleanfalseEnable markdown file extraction

Generating Documentation

The documentation plugin adds the documentation CLI command:

#!/usr/bin/env bash
# Demonstrates generating documentation from scanned examples

cd "$(dirname "$0")"

# Generate markdown documentation from all scanned examples
npx functional-examples documentation

This renders templates for each scanned example, producing markdown files in the configured output directory.

What Gets Generated

Here's what the default template produces for a single example:

---
generated: true
---

# Sample for Documentation

A simple example demonstrating documentation generation

## `src/sample.ts`

### Region: `setup`

```typescript
import { readFileSync } from 'node:fs';

/**
 * Read and parse a configuration file.
 */
export function loadConfig(path: string): Record<string, unknown> {
  const content = readFileSync(path, 'utf-8');
  return JSON.parse(content);
}

Region: usage

// Load configuration from a JSON file
const config = loadConfig('config.json');
console.log('Loaded config:', config);

Notice the structure: frontmatter, title from metadata, description, then each file's regions rendered as fenced code blocks with syntax highlighting. This output is verified by a snapshot assertion in the example's test suite.

### Built-in vs Custom Templates

The plugin ships with a default template that renders example metadata, files, and regions. You can override templates via the `templates` option for custom formatting.

## Prose Helpers

When rendering guides or README files, the documentation plugin provides Eta template helpers:

### File Embedding

<%= example('my-example').file('path/to/file.ts') %>


Embeds the entire file contents as a fenced code block with syntax highlighting.

### Region Embedding

<%= example('my-example').region('regionName') %>


Embeds a named code region (marked with `#region` / `#endregion` in source).

## Guide Rendering

The documentation plugin powers the guide rendering system. Guides use Eta tags to reference live example code:

```markdown
Here's how to configure the scanner:

```typescript title="scan.ts"
/**
 * Basic example: Scanning for examples programmatically
 */
import { scan } from 'functional-examples';

async function main() {
  // scan() auto-discovers config and plugins
  const result = await scan();

  console.log(`Found ${result.examples.length} examples:`);
  for (const example of result.examples) {
    console.log(`  - ${example.title} (${example.id})`);
  }

  if (result.errors.length > 0) {
    console.log(`\n${result.errors.length} errors occurred:`);
    for (const error of result.errors) {
      console.log(`  - ${error.path}: ${error.message}`);
    }
  }
}

main().catch(console.error);


When rendered, the tag is replaced with the actual file contents from the scanned examples. This ensures documentation stays in sync with real code.

## Metadata Options

Examples can control documentation generation via the `docs` metadata field:

| Field | Type | Description |
|-------|------|-------------|
| `docs.skip` | `boolean` | Exclude this example from generated docs |
| `docs.outputName` | `string` | Override the output filename |
| `docs.template` | `string` | Use a specific template |
| `docs.hunks` | `object` | Configure which regions to include |

```yaml
# In meta.yml
docs:
  skip: true          # Don't generate a docs page for this example
  outputName: custom   # Use 'custom.md' instead of 'id.md'

See also: Plugin Authoring for creating plugins that contribute to docs, CI Integration for generating docs in CI.