Skip to content

Commit 5d4c158

Browse files
committed
Add markdown settings file
markdown-it.settings.js files can be added to domstack websites and they let you customize or replace the markdownit instance.
1 parent 76e9994 commit 5d4c158

File tree

20 files changed

+756
-18
lines changed

20 files changed

+756
-18
lines changed

README.md

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -934,6 +934,59 @@ export default async function esbuildSettingsOverride (esbuildSettings) {
934934
}
935935
```
936936

937+
### `markdown-it.settings.js`
938+
939+
This is an optional file you can create anywhere.
940+
It should export a default sync or async function that accepts a single argument (the markdown-it instance configured by domstack) and returns a modified markdown-it instance.
941+
Use this to add custom markdown-it plugins or modify the parser configuration.
942+
Here are some examples:
943+
944+
```js
945+
// Add custom plugins
946+
import markdownItContainer from 'markdown-it-container'
947+
import markdownItPlantuml from 'markdown-it-plantuml'
948+
949+
export default async function markdownItSettingsOverride (md) {
950+
// Add custom plugins
951+
md.use(markdownItContainer, 'spoiler', {
952+
validate: function(params) {
953+
return params.trim().match(/^spoiler\s+(.*)$/)
954+
},
955+
render: function (tokens, idx) {
956+
const m = tokens[idx].info.trim().match(/^spoiler\s+(.*)$/)
957+
if (tokens[idx].nesting === 1) {
958+
return '<details><summary>' + md.utils.escapeHtml(m[1]) + '</summary>\n'
959+
} else {
960+
return '</details>\n'
961+
}
962+
}
963+
})
964+
965+
md.use(markdownItPlantuml)
966+
967+
return md
968+
}
969+
```
970+
971+
```js
972+
// Replace with a completely new instance
973+
import markdownIt from 'markdown-it'
974+
975+
export default async function markdownItSettingsOverride (md) {
976+
// Create a new instance with different settings
977+
const newMd = markdownIt({
978+
html: false, // Disable HTML tags in source
979+
breaks: true, // Convert \n to <br>
980+
linkify: false, // Disable auto-linking
981+
})
982+
983+
// Add only the plugins you want
984+
newMd.use(myCustomPlugin)
985+
986+
return newMd
987+
}
988+
```
989+
937990
## Variables
938991

939992
Pages, Layouts, and `postVars` all receive an object with the following parameters:
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# Markdown-it Settings Example
2+
3+
This example demonstrates how to customize the markdown-it instance used for rendering Markdown content in DOMStack using the `markdown-it.settings.js` file.
4+
5+
## Features
6+
7+
- Custom containers for warnings, info boxes, and collapsible sections
8+
- Custom styling for code blocks
9+
- Example of how to add and configure markdown-it plugins
10+
11+
## How it Works
12+
13+
DOMStack now supports a `markdown-it.settings.js` file that allows you to customize the markdown-it instance. This file should export a default function that receives the default markdown-it instance and returns a modified instance.
14+
15+
```js
16+
export default async function markdownItSettingsOverride (md) {
17+
// Add plugins
18+
md.use(somePlugin)
19+
20+
// Customize renderers
21+
md.renderer.rules.someRule = function (tokens, idx, options, env, renderer) {
22+
// Custom rendering logic
23+
}
24+
25+
return md
26+
}
27+
```
28+
29+
## Running the Example
30+
31+
1. Clone the repository
32+
2. Run `npm install` from the project root
33+
3. Navigate to this example directory: `cd examples/markdown-settings`
34+
4. Run `npm run build` to build the site
35+
5. Open `dist/index.html` in your browser to see the results
36+
37+
## What to Look For
38+
39+
- `src/markdown-it.settings.js` - This file customizes the markdown-it instance with custom containers
40+
- `src/page.md` - This file demonstrates the custom markdown syntax
41+
- `src/style.css` - Contains styles for the custom containers
42+
43+
## Custom Container Examples
44+
45+
The example includes three custom containers:
46+
47+
### Warning Container
48+
49+
```markdown
50+
::: warning Security Notice
51+
This is a custom warning container.
52+
:::
53+
```
54+
55+
### Info Container
56+
57+
```markdown
58+
::: info Did you know?
59+
This is a custom info container.
60+
:::
61+
```
62+
63+
### Details Container (Collapsible)
64+
65+
```markdown
66+
::: details Click to expand
67+
This content is hidden by default.
68+
:::
69+
```
70+
71+
## Further Customization
72+
73+
You can add any markdown-it plugin or customize the rendering of any markdown element by modifying the `markdown-it.settings.js` file. This provides a powerful way to extend the markdown capabilities of your DOMStack site.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"name": "markdown-settings-example",
3+
"version": "1.0.0",
4+
"description": "Example demonstrating markdown-it.settings.js usage",
5+
"type": "module",
6+
"scripts": {
7+
"build": "domstack build src dist",
8+
"dev": "domstack dev src"
9+
},
10+
"devDependencies": {
11+
"domstack": "workspace:*",
12+
"markdown-it-container": "^4.0.0",
13+
"markdown-it-admonition": "^1.0.4"
14+
}
15+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import markdownItContainer from 'markdown-it-container'
2+
3+
/**
4+
* Customize the markdown-it instance with additional plugins
5+
* @param {import('markdown-it')} md - The markdown-it instance
6+
* @returns {import('markdown-it')} - The modified markdown-it instance
7+
*/
8+
export default async function markdownItSettingsOverride (md) {
9+
// Add custom container for warnings
10+
md.use(markdownItContainer, 'warning', {
11+
validate: function (params) {
12+
return params.trim().match(/^warning\s*(.*)$/)
13+
},
14+
render: function (tokens, idx) {
15+
const m = tokens[idx].info.trim().match(/^warning\s*(.*)$/)
16+
if (tokens[idx].nesting === 1) {
17+
const title = (m && m.length > 1) ? m[1] : 'Warning'
18+
return '<div class="custom-warning">\n<div class="warning-title">' + md.utils.escapeHtml(title) + '</div>\n<div class="warning-content">\n'
19+
} else {
20+
return '</div>\n</div>\n'
21+
}
22+
}
23+
})
24+
25+
// Add custom container for info boxes
26+
md.use(markdownItContainer, 'info', {
27+
validate: function (params) {
28+
return params.trim().match(/^info\s*(.*)$/)
29+
},
30+
render: function (tokens, idx) {
31+
const m = tokens[idx].info.trim().match(/^info\s*(.*)$/)
32+
if (tokens[idx].nesting === 1) {
33+
const title = (m && m.length > 1) ? m[1] : 'Info'
34+
return '<div class="custom-info">\n<div class="info-title">' + md.utils.escapeHtml(title) + '</div>\n<div class="info-content">\n'
35+
} else {
36+
return '</div>\n</div>\n'
37+
}
38+
}
39+
})
40+
41+
// Add custom container for collapsible sections
42+
md.use(markdownItContainer, 'details', {
43+
validate: function (params) {
44+
return params.trim().match(/^details\s+(.*)$/)
45+
},
46+
render: function (tokens, idx) {
47+
const m = tokens[idx].info.trim().match(/^details\s+(.*)$/)
48+
if (tokens[idx].nesting === 1) {
49+
return '<details>\n<summary>' + md.utils.escapeHtml(m[1]) + '</summary>\n<div class="details-content">\n'
50+
} else {
51+
return '</div>\n</details>\n'
52+
}
53+
}
54+
})
55+
56+
// Customize existing renderer - add custom classes to code blocks
57+
md.renderer.rules.code_block = function (tokens, idx, options, env, renderer) {
58+
const token = tokens[idx]
59+
const content = token.content
60+
const langName = token.info || ''
61+
62+
return `<pre class="custom-code-block"><code class="language-${langName}">${md.utils.escapeHtml(content)}</code></pre>\n`
63+
}
64+
65+
return md
66+
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
---
2+
title: Markdown-it Settings Example
3+
layout: root
4+
---
5+
6+
# Markdown-it Settings Example
7+
8+
This page demonstrates custom markdown-it plugins configured via `markdown-it.settings.js`.
9+
10+
## Custom Containers
11+
12+
### Warning Container
13+
14+
::: warning Security Notice
15+
This is a custom warning container. It can be used to highlight important security information or other warnings.
16+
:::
17+
18+
::: warning
19+
This warning uses the default title.
20+
:::
21+
22+
### Info Container
23+
24+
::: info Did you know?
25+
Custom containers can make your documentation more expressive and easier to scan.
26+
:::
27+
28+
::: info
29+
Info boxes are great for tips and additional context.
30+
:::
31+
32+
### Details Container
33+
34+
::: details Click to expand more information
35+
This content is hidden by default and can be revealed by clicking the summary.
36+
37+
You can include any markdown content here:
38+
- Lists
39+
- **Bold text**
40+
- `code snippets`
41+
- And more!
42+
:::
43+
44+
::: details Advanced Configuration
45+
The `markdown-it.settings.js` file allows you to:
46+
1. Add custom plugins
47+
2. Modify existing renderers
48+
3. Configure parser options
49+
4. Create entirely new markdown syntaxes
50+
:::
51+
52+
## Custom Code Block Styling
53+
54+
The code blocks below have custom classes applied:
55+
56+
```javascript
57+
// This code block has a custom class
58+
const greeting = "Hello from custom markdown-it settings!";
59+
console.log(greeting);
60+
```
61+
62+
```python
63+
# Python code also gets the custom treatment
64+
def greet(name):
65+
return f"Hello, {name}!"
66+
```
67+
68+
## How It Works
69+
70+
The `markdown-it.settings.js` file exports a function that receives the default markdown-it instance and returns a modified version. This allows you to:
71+
72+
- Add third-party plugins
73+
- Create custom containers
74+
- Override default renderers
75+
- Configure parsing options
76+
77+
Check out the `markdown-it.settings.js` file in this example to see how these customizations are implemented.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
export default function rootLayout ({ title, styles, scripts, children }) {
2+
return /* html */ `<!DOCTYPE html>
3+
<html lang="en">
4+
<head>
5+
<meta charset="UTF-8">
6+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
7+
<title>${title || 'Markdown-it Settings Example'}</title>
8+
${styles.map(style => `<link rel="stylesheet" href="${style}">`).join('\n ')}
9+
</head>
10+
<body>
11+
<main>
12+
${children}
13+
</main>
14+
${scripts.map(script => `<script type="module" src="${script}"></script>`).join('\n ')}
15+
</body>
16+
</html>`
17+
}

0 commit comments

Comments
 (0)