Skip to main content

How Hooks Work

BeDoc’s hook system provides a powerful way to extend and customize the documentation process. Hooks allow actions (parsers and printers) to integrate external logic at specific points, enabling seamless enhancements without modifying the core action itself.

What This Means

  • Hooks are flexible extension points → Actions provide opportunities for external customization by calling hooks at strategic points.
  • Hooks enable dynamic behavior → Modify, enhance, or extend functionality in response to specific events.
  • Actions explicitly determine when and where hooks are available → BeDoc provides the mechanism, but actions define when hooks are called.

Example: A Printer Calling Hooks

Let’s look at a simplified example where a printer makes use of hooks to allow external modifications:

export const actions = [
{
meta: { action: "print", format: "wikitext" },

async run(module) {
const hook = this.hook ?? (async () => null);
const { START, END } = this.HOOKS ?? {};

// Ensure hooks are safely invoked to prevent runtime errors
await hook(START, module);

// Simulate processing
const processedContent = `Formatted content of ${module.moduleName}`;

// Allow external customization via the END hook
return await hook(END, {
moduleName: module.moduleName,
moduleContent: processedContent
}) ?? processedContent;
},
},
];

In this example:

  1. START and END hooks allow external modifications at key points.
  2. The action itself determines when the hooks are called.
  3. If a hook is not explicitly called by the action, it will never run.
  4. The hook call is safeguarded to prevent runtime errors if hooks are missing.

Example Hook File

Now let’s look at a hook file that enhances output formatting dynamically.

export const Hooks = {
print: {
async end(module) {
module.moduleContent += "\n{{Generated by BeDoc}}";
return module.moduleContent;
},
},
};

Here, the "end" hook enhances the final output, but only executes because the printer explicitly allows it.


Best Practices

1. Hooks Are Called, Not Implied

BeDoc does not automatically invoke hooks. Developers must explicitly call them within actions to integrate them into the workflow.

2. Guard Hook Calls to Prevent Errors

To avoid runtime errors, always safeguard hook calls in actions:

const hook = this.hook ?? (async () => null);
await hook(START, module);

This ensures that missing hooks do not break execution.

3. Keep Hooks Efficient

  • Use hooks where they add value. Too many hooks can add unnecessary complexity.
  • Group related logic together to avoid excessive, fragmented calls.

4. Ensure Hooks Modify Data Intelligently

A hook should return the same data structure it was given, with modifications applied in a way that doesn’t break downstream processes:

async enter(section) {
return { ...section, sectionContent: section.sectionContent.trim() };
}

This ensures a smooth flow while still allowing powerful modifications.


By leveraging hooks as enhancements rather than just modifications, developers can create adaptable, extensible documentation workflows that seamlessly integrate with evolving needs.