LoopKitBackend
Content Pipeline
Template rendering with optional Markdown, KaTeX, and code highlighting transforms
Overview
The content pipeline handles rendering note fields into card HTML. It consists of two stages:
- Template interpolation — Replace
{{FieldName}}placeholders with field values - Content transforms — Apply optional Markdown, math, code highlighting, and sanitization
Template Syntax
| Syntax | Description |
|---|---|
{{FieldName}} | Replace with the field's value |
{{#FieldName}}...{{/FieldName}} | Show content only if field is non-empty |
{{^FieldName}}...{{/FieldName}} | Show content only if field is empty |
{{FrontSide}} | Insert the rendered front (back template only) |
Example template:
{{Front}}
{{#Extra}}
<hr>
<small>{{Extra}}</small>
{{/Extra}}Creating a Pipeline
import {
createContentPipeline,
createMarkdownTransform,
createKatexTransform,
createCodeHighlightTransform,
createSanitizeTransform,
} from '@loopkit/nestjs';Basic Pipeline (No Transforms)
const pipeline = createContentPipeline();
// Only template interpolation — no Markdown, math, etc.Full Pipeline
import { parse } from 'marked';
import katex from 'katex';
import hljs from 'highlight.js';
import sanitize from 'sanitize-html';
const pipeline = createContentPipeline([
createMarkdownTransform({ parse }),
createKatexTransform(katex),
createCodeHighlightTransform(hljs),
createSanitizeTransform(sanitize), // Always last!
]);Built-in Transforms
createMarkdownTransform
function createMarkdownTransform(marked: {
parse: (src: string) => string;
}): ContentTransformConverts Markdown to HTML. Requires marked as a peer dependency.
createKatexTransform
function createKatexTransform(katex: {
renderToString: (tex: string, options?: Record<string, unknown>) => string;
}): ContentTransformRenders math expressions:
- Block math:
$$E = mc^2$$— rendered withdisplayMode: true - Inline math:
$x^2$— rendered withdisplayMode: false
createCodeHighlightTransform
function createCodeHighlightTransform(hljs: {
highlightAuto: (code: string) => { value: string };
}): ContentTransformHighlights code blocks using highlight.js auto-detection.
createSanitizeTransform
function createSanitizeTransform(
sanitize: (dirty: string) => string,
): ContentTransformSanitizes HTML to prevent XSS. Should always be the last transform in the pipeline.
ContentPipeline Interface
interface ContentPipeline {
transforms: ContentTransform[];
render(note: NoteBase, template: TemplateDef): RenderedCard;
}The render method:
- Builds a field map from the note's fields
- Interpolates the front template
- Applies all transforms to the front
- Interpolates the back template (with
{{FrontSide}}available) - Applies all transforms to the back
- Returns
{ front: string, back: string }
Template Interpolation
function interpolateTemplate(
template: string,
fields: Record<string, string>,
frontRendered?: string,
): stringThis function is also exported if you need standalone template processing.