A sensible Markdown parser for javascript
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Essential functions for converting markdown to HTML with support for intermediate processing and dialect selection.
Parse markdown text into a JsonML tree representation for intermediate processing.
/**
* Parse markdown text into JsonML tree representation
* @param {string} source - Markdown text to parse
* @param {string|Object} dialect - Dialect name ("Gruber", "Maruku") or dialect object (default: "Gruber")
* @returns {Array} JsonML tree representing markdown structure
*/
function parse(source, dialect);Usage Examples:
var markdown = require("markdown").markdown;
// Basic parsing
var tree = markdown.parse("Hello **World**!");
// Returns: ["markdown", {}, ["para", {}, "Hello ", ["strong", {}, "World"], "!"]]
// With Maruku dialect
var tree = markdown.parse("Hello **World**!\n{: .greeting}", "Maruku");
// Access references from parsed tree
var tree = markdown.parse("[Link text][ref]\n\n[ref]: http://example.com");
var references = tree[1].references;
console.log(references.ref.href); // "http://example.com"Convert markdown text or JsonML tree directly to HTML string with full processing.
/**
* Convert markdown text or JsonML tree directly to HTML string
* @param {string|Array} source - Markdown text or JsonML tree from parse()
* @param {string|Object} dialect - Dialect name ("Gruber", "Maruku") or dialect object (default: "Gruber")
* @param {Object} options - Processing options
* @param {Function} options.preprocessTreeNode - Function to preprocess tree nodes before HTML conversion
* @returns {string} Well-formed HTML string
*/
function toHTML(source, dialect, options);Usage Examples:
var markdown = require("markdown").markdown;
// Simple conversion
var html = markdown.toHTML("Hello **World**!");
// Returns: "<p>Hello <strong>World</strong>!</p>"
// With dialect selection
var html = markdown.toHTML("# Header\n\nContent", "Maruku");
// With preprocessing options
var html = markdown.toHTML("Hello **World**!", "Gruber", {
preprocessTreeNode: function(jsonml, references) {
// Custom preprocessing logic
return jsonml;
}
});
// Convert existing JsonML tree
var tree = markdown.parse("Hello **World**!");
var html = markdown.toHTML(tree);Convert markdown to HTML JsonML tree for custom processing before rendering.
/**
* Convert markdown to HTML JsonML tree for processing
* @param {string|Array} input - Markdown text or markdown JsonML tree from parse()
* @param {string|Object} dialect - Dialect name ("Gruber", "Maruku") or dialect object (default: "Gruber")
* @param {Object} options - Processing options
* @param {Function} options.preprocessTreeNode - Function to preprocess tree nodes during conversion
* @returns {Array} JsonML tree representing HTML structure
*/
function toHTMLTree(input, dialect, options);Usage Examples:
var markdown = require("markdown").markdown;
// Convert to HTML tree for processing
var htmlTree = markdown.toHTMLTree("Hello **World**!");
// Returns: ["html", {}, ["p", {}, "Hello ", ["strong", {}, "World"], "!"]]
// Process HTML tree (e.g., collect all links)
function collectLinks(jsonml) {
var links = [];
if (Array.isArray(jsonml)) {
if (jsonml[0] === "a") {
links.push(jsonml[1].href);
}
for (var i = 1; i < jsonml.length; i++) {
if (Array.isArray(jsonml[i])) {
links = links.concat(collectLinks(jsonml[i]));
}
}
}
return links;
}
var htmlTree = markdown.toHTMLTree("[Link](http://example.com)");
var links = collectLinks(htmlTree);
console.log(links); // ["http://example.com"]
// Render processed tree to HTML
var html = markdown.renderJsonML(htmlTree);Render JsonML tree to well-formed HTML/XML string with formatting options.
/**
* Render JsonML tree to well-formed HTML/XML string
* @param {Array} jsonml - JsonML array to render (from toHTMLTree or custom)
* @param {Object} options - Rendering options
* @param {boolean} options.root - Include root element in output (default: false)
* @returns {string} Well-formed HTML/XML string
*/
function renderJsonML(jsonml, options);Usage Examples:
var markdown = require("markdown").markdown;
// Basic rendering (excludes root element)
var htmlTree = ["html", {}, ["p", {}, "Hello World"]];
var html = markdown.renderJsonML(htmlTree);
// Returns: "<p>Hello World</p>"
// Include root element
var html = markdown.renderJsonML(htmlTree, { root: true });
// Returns: "<html><p>Hello World</p></html>"
// Custom JsonML construction
var customTree = [
"div",
{ class: "content", id: "main" },
["h1", {}, "Title"],
["p", {}, "Paragraph text"]
];
var html = markdown.renderJsonML(customTree, { root: true });
// Returns: '<div class="content" id="main"><h1>Title</h1><p>Paragraph text</p></div>'Example of using the three-stage architecture for custom processing:
var markdown = require("markdown").markdown;
// Stage 1: Parse markdown to markdown JsonML
var text = "[Markdown] is a simple [markup language]\n\n[markup language]: http://example.com";
var markdownTree = markdown.parse(text);
// Access and modify references
var refs = markdownTree[1].references;
if (!refs["markdown"]) {
refs["markdown"] = {
href: "http://en.wikipedia.org/wiki/Markdown"
};
}
// Stage 2: Convert to HTML JsonML
var htmlTree = markdown.toHTMLTree(markdownTree);
// Stage 3: Render to HTML string
var html = markdown.renderJsonML(htmlTree);
console.log(html);
// Result includes both original and added referencesThe core API functions handle errors as follows:
All functions return deterministic results for valid inputs and fail fast for invalid dialects.
Create enhanced string blocks with metadata for internal processing.
/**
* Create enhanced string block with metadata
* @param {string} block - Block content
* @param {string} trail - Trailing content (default: "\n\n")
* @param {number} line - Line number (optional)
* @returns {string} Enhanced string with trailing and lineNumber properties
*/
function mk_block(block, trail, line);Usage Examples:
var markdown = require("markdown").markdown;
// Create basic block
var block = markdown.mk_block("# Header", "\n\n");
console.log(block.toString()); // "# Header"
console.log(block.trailing); // "\n\n"
// Create block with line number
var block = markdown.mk_block("Paragraph text", "\n\n", 5);
console.log(block.lineNumber); // 5
// Used internally by block processing
var md = new markdown.Markdown();
var blocks = md.split_blocks("# Header\n\nParagraph");
// Each block is created with mk_block internallyNote: This is primarily an internal utility function used by the parser, but it's part of the public API and can be useful for custom dialect development.
Process inline content until a specific character is encountered, used internally by dialect processors.
/**
* Process inline content until specific character
* @param {string} text - Text to process for inline elements
* @param {string} want - Character to stop processing at
* @returns {Array|null} [consumed_length, nodes_array] or null if character not found
*/
function Markdown.DialectHelpers.inline_until_char(text, want);Usage Examples:
var markdown = require("markdown").markdown;
// Process inline content until closing bracket
var result = markdown.DialectHelpers.inline_until_char("text with **bold**]", "]");
if (result) {
console.log("Consumed characters:", result[0]); // Number of characters processed
console.log("Processed nodes:", result[1]); // Array of inline JsonML nodes
// result[1] might be: ["text with ", ["strong", {}, "bold"]]
}
// Used internally in custom dialect development
var customDialect = {
inline: {
"[": function(text) {
var content = markdown.DialectHelpers.inline_until_char(text.substr(1), "]");
if (content) {
return [
content[0] + 2, // +1 for opening [, +1 for closing ]
["custom_element", {}, content[1]]
];
}
return [1, "["];
}
}
};Note: This function is primarily used internally by link and image processing, but is exposed as part of the public API for custom dialect development.