Annotation Transformers
Annotation transformers handle text styling and formatting within blocks. They work at the character level, handling things like bold, italic, code, etc.
Basic Structure
type AnnotationTransformer = {
transform: (params: {
text: string; // The text to transform
annotations?: Record<string, boolean>; // All annotations on this text
metadata?: any; // Additional context if needed
}) => Promise<string>;
}
These ensure consistent formatting throughout your document, regardless of which block the text appears in.
Simple Example
Here’s how you can create basic annotation transformers:
const annotationTransformers = {
// Makes text bold using **text**
bold: {
transform: async ({ text }) => `**${text}**`
},
// Makes text italic using *text*
italic: {
transform: async ({ text }) => `*${text}*`
},
// Creates inline code using `text`
code: {
transform: async ({ text }) => `\`${text}\``
}
};
Real-World Examples
- Flexible Text Formatting
// Transformer that can output either Markdown or HTML
const boldTransformer = {
transform: async ({ text, metadata }) => {
// Use HTML when specified in metadata
if (metadata?.html) {
return `<strong>${text}</strong>`;
}
// Default to Markdown
return `**${text}**`;
}
};
- Link Handling
const linkTransformer = {
transform: async ({ text, link }) => {
if (!link?.url) return text;
return `[${text}](${link.url})`;
}
};
- Math Equations
const equationTransformer = {
transform: async ({ text }) => {
return `$${text}$`; // Inline LaTeX format
}
};
The renderer processes these in order, so transformers should be designed to work together.
Example Usage
class MyRenderer extends BaseRendererPlugin {
constructor() {
super();
// Register annotation transformers
this.createAnnotationTransformers({
bold: {
transform: async ({ text }) => `**${text}**`
},
italic: {
transform: async ({ text }) => `*${text}*`
},
code: {
transform: async ({ text }) => `\`${text}\``
},
// NOTE: must include it's transformer if you since it's not considered as a annotation by the notion but
// to make sure that people have the control over the links transformation we allow them to add link as annotation transformer.
link: {
transform: async ({ text, link }) =>
link?.url ? `[${text}](${link.url})` : text
}
});
}
}
ℹ️
It’s better to define a link annotation transformer if you are building a custom renderer since it’s not considered as a annotation by the notion but
to make sure that people have the control over the links transformation we allow them to add link as annotation transformer.
Tips for Creating Annotation Transformers
Keep It Simple
- Each transformer should do one thing well
- Return just the transformed text
Handle Edge Cases
- Empty text
- Missing or invalid links
- Special characters that might need escaping
Consider Context
- Use metadata for your use case
- Check other annotations when needed
Common Use Cases
- Text styling (bold, italic, underline)
- Links and references
- Code formatting
- Math equations
- Custom inline elements