Guides

Transforms

Transforms receive the normalized AST after parsing and before rendering. They let you modify the content tree programmatically.

Using Transforms

Transforms are typically provided via plugins:

const plugin = {
  name: 'capitalize-headings',
  transform(ast) {
    // walk the tree, modify heading nodes
    return ast;
  },
};

const nizel = useNizel({ plugins: [plugin] });

AST Structure

The AST uses a normalized node format:

interface NizelNode {
  type: string;        // 'document', 'heading', 'paragraph', 'text', etc.
  children?: NizelNode[];
  text?: string;       // for text and code nodes
  level?: number;      // for headings
  depth?: number;      // nesting depth
  lang?: string;       // for fenced code blocks
  url?: string;        // for links and images
  title?: string;      // for links and images
  alt?: string;        // for images
  ordered?: boolean;   // for lists
  start?: number;      // for ordered lists
  bullet?: string;     // for list items
  info?: string;       // for code blocks
}

Common Transform Patterns

Modify All Headings

transform(ast) {
  // add a custom class to all headings
  walk(ast, (node) => {
    if (node.type === 'heading') {
      node.attr = { ...node.attr, class: `heading-${node.level}` };
    }
  });
  return ast;
}

Remove Nodes

transform(ast) {
  // remove all images
  walk(ast, (node) => {
    if (node.children) {
      node.children = node.children.filter(
        (child) => child.type !== 'image'
      );
    }
  });
  return ast;
}

Rewrite URLs

transform(ast) {
  walk(ast, (node) => {
    if (node.type === 'link' && node.url?.startsWith('http')) {
      node.url = `/proxy?url=${encodeURIComponent(node.url)}`;
    }
  });
  return ast;
}