Quickstart
Get started with datamark in under 5 minutes. Parse your first Markdown document into a typed object.
Parse your first Markdown document into a typed object in three steps. About 5 minutes.
Install
npm install datamarkFor validation, also install your schema library of choice:
npm install zodWrite your first format
Create a file that describes how your Markdown is structured:
import { datamark } from "datamark";
import { findAll, inlineText, textContent, isCodeBlock } from "datamark/parse";
import { frontmatter, heading, paragraph, codeBlock } from "datamark/stringify";
import * as z from "zod";
const PlanFrontmatterSchema = z.object({ id: z.string() });
const PlanSchema = z.object({
id: z.string(),
title: z.string(),
steps: z.array(
z.object({
description: z.string(),
scripts: z.array(z.string()),
})
),
});
const PlanFormat = datamark({
frontmatterSchema: PlanFrontmatterSchema,
schema: PlanSchema,
parse(doc) {
const id = doc.frontmatter.id;
const titleSection = doc.root.children.find((n) => n.type === "section") as any;
const title = titleSection ? inlineText(titleSection.heading.children) : "";
const steps = titleSection
? (titleSection.children.filter((n: any) => n.type === "section") as any[]).map(
(section) => {
const scripts = findAll(section, (n) => isCodeBlock(n, "javascript")).map(
(n: any) => n.value
);
const description = textContent(section).trim();
return { description, scripts };
}
)
: [];
return { id, title, steps };
},
stringify(data) {
let md = frontmatter({ id: data.id }) + heading(data.title) + "\n\n";
for (const step of data.steps) {
md += heading("Step", 2) + "\n\n" + paragraph(step.description) + "\n\n";
for (const script of step.scripts) {
md += codeBlock(script, "javascript") + "\n\n";
}
}
return md;
},
});
const planMarkdown = `---
id: plan-001
---
# Q3 Roadmap
## Step
Set up the project.
\`\`\`javascript
npm init -y
\`\`\`
## Step
Implement the core features.`;const result = PlanFormat.parse(planMarkdown);
console.log(result.id); // "plan-001"
console.log(result.title); // "Q3 Roadmap"
console.log(result.steps[0].description); // "Set up the project."Parse a document
import { PlanFormat } from "./plan-format";
const markdown = `---
id: plan-001
---
# Q3 Roadmap
## Set up project scaffolding
Install dependencies.
\`\`\`javascript
npm init -y
\`\`\`
## Implement core features
Build the main functionality.
`;
const result = PlanFormat.parse(markdown);
console.log(result);
// {
// id: "plan-001",
// title: "Q3 Roadmap",
// steps: [
// { title: "Set up project scaffolding", description: "Install dependencies.", scripts: ["npm init -y"] },
// { title: "Implement core features", description: "Build the main functionality.", scripts: [] },
// ],
// }What happened?
parseturned the raw Markdown string into a typed AST with a section tree.- Your
parsefunction traversed the AST using utility functions likefindAll,textContent, andisCodeBlock. - The section tree made it easy to iterate over H2-delimited sections.
- The final return value was validated against your Zod schema.
Where to go next
| Goal | Link |
|---|---|
| Understand how it works | The AST |
| Learn about the format system | Format SDK |
| Look up core functions | Parse SDK |
| See more examples | Examples |