0
# Dialects
1
2
Extensible parsing rule system supporting Gruber (default) and Maruku dialects with capabilities for custom dialect creation.
3
4
## Capabilities
5
6
### Built-in Dialects
7
8
Access to pre-defined parsing dialects with different feature sets.
9
10
```javascript { .api }
11
/**
12
* Built-in dialect objects
13
* @property {Object} Markdown.dialects.Gruber - Default Gruber dialect following original markdown.pl
14
* @property {Object} Markdown.dialects.Maruku - Extended Maruku dialect with additional features
15
*/
16
var Markdown.dialects.Gruber;
17
var Markdown.dialects.Maruku;
18
19
/**
20
* Dialect structure
21
* @typedef {Object} Dialect
22
* @property {Object} block - Block-level processing rules
23
* @property {Object} inline - Inline processing rules
24
* @property {Array} block.__order__ - Processing order for block rules
25
* @property {string} inline.__patterns__ - Compiled regex patterns for inline rules
26
* @property {Function} inline.__call__ - Main inline processing function
27
*/
28
```
29
30
**Usage Examples:**
31
32
```javascript
33
var { Markdown } = require("markdown").markdown;
34
35
// Use built-in dialects
36
var md1 = new Markdown(Markdown.dialects.Gruber);
37
var md2 = new Markdown(Markdown.dialects.Maruku);
38
39
// Access dialect properties
40
console.log(Object.keys(Markdown.dialects.Gruber.block));
41
// ["atxHeader", "setextHeader", "code", "horizRule", "lists", "blockquote", "referenceDefn", "para"]
42
43
console.log(Object.keys(Markdown.dialects.Maruku.block));
44
// Includes additional: ["document_meta", "block_meta", "definition_list", "table"]
45
```
46
47
### Gruber Dialect Features
48
49
Default dialect implementing John Gruber's original markdown specification.
50
51
**Block-level Rules:**
52
- **atxHeader**: ATX-style headers (`# Header`)
53
- **setextHeader**: Setext-style headers (underlined)
54
- **code**: Indented code blocks (4 spaces or 1 tab)
55
- **horizRule**: Horizontal rules (`---`, `***`, `___`)
56
- **lists**: Bulleted and numbered lists with nesting
57
- **blockquote**: Blockquotes (`> text`)
58
- **referenceDefn**: Link reference definitions
59
- **para**: Paragraphs (fallback rule)
60
61
**Inline Rules:**
62
- **Strong emphasis**: `**text**` and `__text__`
63
- **Emphasis**: `*text*` and `_text_`
64
- **Links**: `[text](url)` and `[text][ref]`
65
- **Images**: `` and `![alt][ref]`
66
- **Inline code**: `` `code` ``
67
- **Line breaks**: Two spaces + newline
68
- **Autolinks**: `<http://example.com>` and `<email@example.com>`
69
- **Backslash escapes**: `\*` `\_` etc.
70
71
### Maruku Dialect Features
72
73
Extended dialect with additional markdown features beyond the original specification.
74
75
**Additional Block-level Rules:**
76
- **document_meta**: Document metadata (`Key: Value`)
77
- **block_meta**: Block attributes (`{: .class #id}`)
78
- **definition_list**: Definition lists (`Term:\n: Definition`)
79
- **table**: Table syntax with alignment
80
81
**Additional Inline Rules:**
82
- **Inline meta**: `{: .class #id}` for inline elements
83
- **Extended escapes**: Additional escapable characters
84
85
**Usage Examples:**
86
87
```javascript
88
var { toHTML } = require("markdown");
89
90
// Gruber dialect (default)
91
var html1 = toHTML("# Header\n\n**Bold** text");
92
93
// Maruku dialect with metadata
94
var html2 = toHTML("# Header {: .title}\n\n**Bold** text", "Maruku");
95
96
// Maruku tables
97
var table = `
98
| Header 1 | Header 2 |
99
|----------|----------|
100
| Cell 1 | Cell 2 |
101
`;
102
var html3 = toHTML(table, "Maruku");
103
```
104
105
### Dialect Subclassing
106
107
Create custom dialects by extending existing ones.
108
109
```javascript { .api }
110
/**
111
* Create dialect subclass with prototype inheritance
112
* @param {Object} d - Base dialect to extend
113
* @returns {Object} New dialect with inherited block and inline processors
114
*/
115
function Markdown.subclassDialect(d);
116
```
117
118
**Usage Examples:**
119
120
```javascript
121
var { Markdown } = require("markdown").markdown;
122
123
// Create custom dialect extending Gruber
124
var customDialect = Markdown.subclassDialect(Markdown.dialects.Gruber);
125
126
// Add custom block rule
127
customDialect.block.customBlock = function(block, next) {
128
if (block.match(/^CUSTOM:/)) {
129
return [["div", { class: "custom" }, block.substr(7)]];
130
}
131
return undefined;
132
};
133
134
// Add custom inline rule
135
customDialect.inline["@@"] = function(text) {
136
var match = text.match(/^@@(.*?)@@/);
137
if (match) {
138
return [match[0].length, ["span", { class: "highlight" }, match[1]]];
139
}
140
return [2, "@@"];
141
};
142
143
// Rebuild patterns and order
144
Markdown.buildBlockOrder(customDialect.block);
145
Markdown.buildInlinePatterns(customDialect.inline);
146
147
// Use custom dialect
148
var md = new Markdown(customDialect);
149
var html = md.toTree("CUSTOM: Special content\n\nNormal @@highlighted@@ text");
150
```
151
152
### Dialect Building Utilities
153
154
Utility functions for constructing and configuring dialects.
155
156
```javascript { .api }
157
/**
158
* Build processing order for block rules in dialect
159
* @param {Object} d - Dialect block rules object
160
* @modifies {Object} d - Adds __order__ property with rule names array
161
*/
162
function Markdown.buildBlockOrder(d);
163
164
/**
165
* Build regex patterns for inline rules in dialect
166
* @param {Object} d - Dialect inline rules object
167
* @modifies {Object} d - Adds __patterns__ property and wraps __call__ method
168
*/
169
function Markdown.buildInlinePatterns(d);
170
```
171
172
**Usage Examples:**
173
174
```javascript
175
var customDialect = {
176
block: {
177
customRule1: function() { /* ... */ },
178
customRule2: function() { /* ... */ },
179
para: function() { /* fallback */ }
180
},
181
inline: {
182
"**": function() { /* strong */ },
183
"*": function() { /* em */ },
184
__call__: function(text, patterns) { /* main processor */ }
185
}
186
};
187
188
// Build the dialect configuration
189
Markdown.buildBlockOrder(customDialect.block);
190
// Sets: customDialect.block.__order__ = ["customRule1", "customRule2", "para"]
191
192
Markdown.buildInlinePatterns(customDialect.inline);
193
// Sets: customDialect.inline.__patterns__ = "\\*\\*|\\*"
194
// Wraps: customDialect.inline.__call__ with pattern parameter
195
```
196
197
### Advanced Custom Dialect Example
198
199
Creating a comprehensive custom dialect with new syntax:
200
201
```javascript
202
var { Markdown } = require("markdown").markdown;
203
204
// Create base dialect
205
var wikiDialect = Markdown.subclassDialect(Markdown.dialects.Gruber);
206
207
// Add wiki-style links: [[Page Name]]
208
wikiDialect.inline["[["] = function(text) {
209
var match = text.match(/^\[\[(.*?)\]\]/);
210
if (match) {
211
var pageName = match[1];
212
var href = "/wiki/" + pageName.replace(/\s+/g, "_");
213
return [
214
match[0].length,
215
["link", { href: href, class: "wiki-link" }, pageName]
216
];
217
}
218
return [2, "[["];
219
};
220
221
// Add note blocks: !!! Note: content
222
wikiDialect.block.noteBlock = function(block, next) {
223
var match = block.match(/^!!!\s*(\w+):\s*(.*)/);
224
if (match) {
225
var noteType = match[1].toLowerCase();
226
var content = match[2];
227
return [[
228
"div",
229
{ class: "note note-" + noteType },
230
["strong", {}, match[1] + ": "],
231
content
232
]];
233
}
234
return undefined;
235
};
236
237
// Configure the dialect
238
Markdown.buildBlockOrder(wikiDialect.block);
239
Markdown.buildInlinePatterns(wikiDialect.inline);
240
241
// Use the custom dialect
242
var md = new Markdown(wikiDialect);
243
244
var wikiText = `
245
# Wiki Page
246
247
See [[Other Page]] for details.
248
249
!!! Warning: This is important information.
250
251
Regular **markdown** still works.
252
`;
253
254
var html = md.toTree(wikiText);
255
// Produces HTML with wiki links and note blocks
256
```
257
258
## Dialect Helper Functions
259
260
```javascript { .api }
261
/**
262
* Dialect helper utilities
263
* @namespace Markdown.DialectHelpers
264
*/
265
var Markdown.DialectHelpers = {};
266
267
/**
268
* Process inline content until specific character
269
* @param {string} text - Text to process
270
* @param {string} want - Character to stop at
271
* @returns {Array|null} [consumed_length, nodes_array] or null if character not found
272
*/
273
Markdown.DialectHelpers.inline_until_char = function(text, want);
274
```
275
276
**Usage Examples:**
277
278
```javascript
279
// Used internally by link processing
280
var result = Markdown.DialectHelpers.inline_until_char("text with **bold**]", "]");
281
if (result) {
282
console.log("Consumed:", result[0]); // Characters consumed
283
console.log("Nodes:", result[1]); // Processed inline nodes
284
}
285
```