Skip to content

Commit 47428c8

Browse files
committed
Built-ins to top
1 parent 8d75c5d commit 47428c8

File tree

3 files changed

+330
-324
lines changed

3 files changed

+330
-324
lines changed

pages/docs/functions.md

Lines changed: 51 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -7,55 +7,6 @@ description: Functions let you extend Markdoc to run custom code.
77

88
Functions enable you extend Markdoc with custom utilities, which let you transform your content and [variables](/docs/syntax#variables) at runtime.
99

10-
## Creating a custom function
11-
12-
To extend Markdoc with your own functions, first create custom function definitions:
13-
14-
```js
15-
const includes = {
16-
transform(parameters) {
17-
const [array, value] = Object.values(parameters);
18-
19-
return Array.isArray(array) ? array.includes(value) : false;
20-
}
21-
};
22-
23-
const uppercase = {
24-
transform(parameters) {
25-
const string = parameters[0];
26-
27-
return typeof string === 'string' ? string.toUpperCase() : string;
28-
}
29-
};
30-
```
31-
32-
Then, pass the functions to your [`Config` object](/docs/syntax#config)
33-
34-
```js
35-
const config = {
36-
functions: {
37-
includes,
38-
uppercase
39-
}
40-
};
41-
42-
const content = Markdoc.transform(ast, config);
43-
```
44-
45-
Finally, call the functions within your Markdoc content
46-
47-
{% markdoc-example %}
48-
49-
```md
50-
{% if includes($countries, "AR") %} 🇦🇷 {% /if %}
51-
{% if includes($countries, "AU") %} 🇦🇺 {% /if %}
52-
{% if includes($countries, "ES") %} 🇪🇸 {% /if %}
53-
{% if includes($countries, "JP") %} 🇯🇵 {% /if %}
54-
{% if includes($countries, "NG") %} 🇳🇬 {% /if %}
55-
{% if includes($countries, "US") %} 🇺🇸 {% /if %}
56-
```
57-
58-
{% /markdoc-example %}
5910

6011
## Built-in functions
6112

@@ -171,6 +122,57 @@ This function simply renders the value as a serialized JSON value in the documen
171122

172123
{% /markdoc-example %}
173124

125+
126+
## Creating a custom function
127+
128+
To extend Markdoc with your own functions, first create custom function definitions:
129+
130+
```js
131+
const includes = {
132+
transform(parameters) {
133+
const [array, value] = Object.values(parameters);
134+
135+
return Array.isArray(array) ? array.includes(value) : false;
136+
}
137+
};
138+
139+
const uppercase = {
140+
transform(parameters) {
141+
const string = parameters[0];
142+
143+
return typeof string === 'string' ? string.toUpperCase() : string;
144+
}
145+
};
146+
```
147+
148+
Then, pass the functions to your [`Config` object](/docs/syntax#config)
149+
150+
```js
151+
const config = {
152+
functions: {
153+
includes,
154+
uppercase
155+
}
156+
};
157+
158+
const content = Markdoc.transform(ast, config);
159+
```
160+
161+
Finally, call the functions within your Markdoc content
162+
163+
{% markdoc-example %}
164+
165+
```md
166+
{% if includes($countries, "AR") %} 🇦🇷 {% /if %}
167+
{% if includes($countries, "AU") %} 🇦🇺 {% /if %}
168+
{% if includes($countries, "ES") %} 🇪🇸 {% /if %}
169+
{% if includes($countries, "JP") %} 🇯🇵 {% /if %}
170+
{% if includes($countries, "NG") %} 🇳🇬 {% /if %}
171+
{% if includes($countries, "US") %} 🇺🇸 {% /if %}
172+
```
173+
174+
{% /markdoc-example %}
175+
174176
## Next steps
175177

176178
- [Validate your content](/docs/validation)

pages/docs/nodes.md

Lines changed: 129 additions & 127 deletions
Original file line numberDiff line numberDiff line change
@@ -7,133 +7,6 @@ description:
77

88
Markdoc nodes enable you to customize how your document renders without using any custom syntax—it consists entirely of Markdown. Customizing nodes lets you extend your implementation incrementally.
99

10-
## Customizing Markdoc nodes
11-
12-
Nodes are elements that Markdoc inherits from Markdown, specifically the [CommonMark specification](https://commonmark.org/).
13-
14-
You define custom nodes by passing a custom Node to your [`Config`](/docs/syntax#config), like:
15-
16-
```js
17-
import { heading } from './schema/Heading.markdoc';
18-
import * as components from './components';
19-
20-
const config = {
21-
nodes: {
22-
heading
23-
}
24-
};
25-
26-
const ast = Markdoc.parse(doc);
27-
const content = Markdoc.transform(ast, config);
28-
29-
const children = Markdoc.renderers.react(content, React, { components });
30-
```
31-
32-
where `heading` looks something like:
33-
34-
```js
35-
// ./schema/Heading.markdoc.js
36-
37-
import { Tag } from '@markdoc/markdoc';
38-
39-
// Or replace this with your own function
40-
function generateID(children, attributes) {
41-
if (attributes.id && typeof attributes.id === 'string') {
42-
return attributes.id;
43-
}
44-
return children
45-
.filter((child) => typeof child === 'string')
46-
.join(' ')
47-
.replace(/[?]/g, '')
48-
.replace(/\s+/g, '-')
49-
.toLowerCase();
50-
}
51-
52-
export const heading = {
53-
children: ['inline'],
54-
attributes: {
55-
id: { type: String },
56-
level: { type: Number, required: true, default: 1 }
57-
},
58-
transform(node, config) {
59-
const attributes = node.transformAttributes(config);
60-
const children = node.transformChildren(config);
61-
62-
const id = generateID(children, attributes);
63-
64-
return new Tag(
65-
`h${node.attributes['level']}`,
66-
{ ...attributes, id },
67-
children
68-
);
69-
}
70-
};
71-
```
72-
73-
After registering this custom node, you can then use it in your Markdoc, like:
74-
75-
{% side-by-side %}
76-
77-
{% markdoc-example %}
78-
79-
```md
80-
#### My header
81-
```
82-
83-
{% /markdoc-example %}
84-
85-
#### My header
86-
87-
{% /side-by-side %}
88-
89-
## Options
90-
91-
These are the optional fields you can use to customize your `Node`:
92-
93-
{% table %}
94-
95-
- Option
96-
- Type
97-
- Description {% width="40%" %}
98-
99-
---
100-
101-
- `render`
102-
- `string`
103-
- Name of the output (for example, HTML tag, React component name) to render
104-
105-
---
106-
107-
- `children`
108-
- `string[]`
109-
- Determines which tag or node types can be rendered as children of this node. Used in schema validation.
110-
111-
---
112-
113-
- `attributes`
114-
- `{ [string]: SchemaAttribute }`
115-
- Determines which [values (and their types)](/docs/attributes) can be passed to this node.
116-
117-
---
118-
119-
- `transform`
120-
- ```js
121-
(Ast.Node, ?Options) =>
122-
| RenderableTreeNode
123-
| RenderableTreeNode[]
124-
| null
125-
```
126-
- Customize the Markdoc transform function for this node, returning the custom output you want to eventually render. This is called during the [`transform` step](/docs/render#transform).
127-
128-
---
129-
130-
- `validate`
131-
- ```js
132-
(Node, ?Options) => ValidationError[];
133-
```
134-
- Extend Markdoc validation. This validates that the content meets validation requirements, and is called during the [`validate` step](/docs/render#validate)
135-
136-
{% /table %}
13710

13811
## Built-in nodes
13912

@@ -292,6 +165,135 @@ Markdoc comes out of the box with built-in nodes for each of the [CommonMark](ht
292165

293166
{% /table %}
294167

168+
169+
## Customizing Markdoc nodes
170+
171+
Nodes are elements that Markdoc inherits from Markdown, specifically the [CommonMark specification](https://commonmark.org/).
172+
173+
You define custom nodes by passing a custom Node to your [`Config`](/docs/syntax#config), like:
174+
175+
```js
176+
import { heading } from './schema/Heading.markdoc';
177+
import * as components from './components';
178+
179+
const config = {
180+
nodes: {
181+
heading
182+
}
183+
};
184+
185+
const ast = Markdoc.parse(doc);
186+
const content = Markdoc.transform(ast, config);
187+
188+
const children = Markdoc.renderers.react(content, React, { components });
189+
```
190+
191+
where `heading` looks something like:
192+
193+
```js
194+
// ./schema/Heading.markdoc.js
195+
196+
import { Tag } from '@markdoc/markdoc';
197+
198+
// Or replace this with your own function
199+
function generateID(children, attributes) {
200+
if (attributes.id && typeof attributes.id === 'string') {
201+
return attributes.id;
202+
}
203+
return children
204+
.filter((child) => typeof child === 'string')
205+
.join(' ')
206+
.replace(/[?]/g, '')
207+
.replace(/\s+/g, '-')
208+
.toLowerCase();
209+
}
210+
211+
export const heading = {
212+
children: ['inline'],
213+
attributes: {
214+
id: { type: String },
215+
level: { type: Number, required: true, default: 1 }
216+
},
217+
transform(node, config) {
218+
const attributes = node.transformAttributes(config);
219+
const children = node.transformChildren(config);
220+
221+
const id = generateID(children, attributes);
222+
223+
return new Tag(
224+
`h${node.attributes['level']}`,
225+
{ ...attributes, id },
226+
children
227+
);
228+
}
229+
};
230+
```
231+
232+
After registering this custom node, you can then use it in your Markdoc, like:
233+
234+
{% side-by-side %}
235+
236+
{% markdoc-example %}
237+
238+
```md
239+
#### My header
240+
```
241+
242+
{% /markdoc-example %}
243+
244+
#### My header
245+
246+
{% /side-by-side %}
247+
248+
## Options
249+
250+
These are the optional fields you can use to customize your `Node`:
251+
252+
{% table %}
253+
254+
- Option
255+
- Type
256+
- Description {% width="40%" %}
257+
258+
---
259+
260+
- `render`
261+
- `string`
262+
- Name of the output (for example, HTML tag, React component name) to render
263+
264+
---
265+
266+
- `children`
267+
- `string[]`
268+
- Determines which tag or node types can be rendered as children of this node. Used in schema validation.
269+
270+
---
271+
272+
- `attributes`
273+
- `{ [string]: SchemaAttribute }`
274+
- Determines which [values (and their types)](/docs/attributes) can be passed to this node.
275+
276+
---
277+
278+
- `transform`
279+
- ```js
280+
(Ast.Node, ?Options) =>
281+
| RenderableTreeNode
282+
| RenderableTreeNode[]
283+
| null
284+
```
285+
- Customize the Markdoc transform function for this node, returning the custom output you want to eventually render. This is called during the [`transform` step](/docs/render#transform).
286+
287+
---
288+
289+
- `validate`
290+
- ```js
291+
(Node, ?Options) => ValidationError[];
292+
```
293+
- Extend Markdoc validation. This validates that the content meets validation requirements, and is called during the [`validate` step](/docs/render#validate)
294+
295+
{% /table %}
296+
295297
## Next steps
296298
297299
- [Create custom tags](/docs/tags)

0 commit comments

Comments
 (0)