CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-markdown

A sensible Markdown parser for javascript

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

dialects.mddocs/

Dialects

Extensible parsing rule system supporting Gruber (default) and Maruku dialects with capabilities for custom dialect creation.

Capabilities

Built-in Dialects

Access to pre-defined parsing dialects with different feature sets.

/**
 * Built-in dialect objects
 * @property {Object} Markdown.dialects.Gruber - Default Gruber dialect following original markdown.pl
 * @property {Object} Markdown.dialects.Maruku - Extended Maruku dialect with additional features
 */
var Markdown.dialects.Gruber;
var Markdown.dialects.Maruku;

/**
 * Dialect structure
 * @typedef {Object} Dialect
 * @property {Object} block - Block-level processing rules
 * @property {Object} inline - Inline processing rules
 * @property {Array} block.__order__ - Processing order for block rules
 * @property {string} inline.__patterns__ - Compiled regex patterns for inline rules
 * @property {Function} inline.__call__ - Main inline processing function
 */

Usage Examples:

var { Markdown } = require("markdown").markdown;

// Use built-in dialects
var md1 = new Markdown(Markdown.dialects.Gruber);
var md2 = new Markdown(Markdown.dialects.Maruku);

// Access dialect properties
console.log(Object.keys(Markdown.dialects.Gruber.block));
// ["atxHeader", "setextHeader", "code", "horizRule", "lists", "blockquote", "referenceDefn", "para"]

console.log(Object.keys(Markdown.dialects.Maruku.block));
// Includes additional: ["document_meta", "block_meta", "definition_list", "table"]

Gruber Dialect Features

Default dialect implementing John Gruber's original markdown specification.

Block-level Rules:

  • atxHeader: ATX-style headers (# Header)
  • setextHeader: Setext-style headers (underlined)
  • code: Indented code blocks (4 spaces or 1 tab)
  • horizRule: Horizontal rules (---, ***, ___)
  • lists: Bulleted and numbered lists with nesting
  • blockquote: Blockquotes (> text)
  • referenceDefn: Link reference definitions
  • para: Paragraphs (fallback rule)

Inline Rules:

  • Strong emphasis: **text** and __text__
  • Emphasis: *text* and _text_
  • Links: [text](url) and [text][ref]
  • Images: ![alt](src) and ![alt][ref]
  • Inline code: `code`
  • Line breaks: Two spaces + newline
  • Autolinks: <http://example.com> and <email@example.com>
  • Backslash escapes: \* \_ etc.

Maruku Dialect Features

Extended dialect with additional markdown features beyond the original specification.

Additional Block-level Rules:

  • document_meta: Document metadata (Key: Value)
  • block_meta: Block attributes ({: .class #id})
  • definition_list: Definition lists (Term:\n: Definition)
  • table: Table syntax with alignment

Additional Inline Rules:

  • Inline meta: {: .class #id} for inline elements
  • Extended escapes: Additional escapable characters

Usage Examples:

var { toHTML } = require("markdown");

// Gruber dialect (default)
var html1 = toHTML("# Header\n\n**Bold** text");

// Maruku dialect with metadata
var html2 = toHTML("# Header {: .title}\n\n**Bold** text", "Maruku");

// Maruku tables
var table = `
| Header 1 | Header 2 |
|----------|----------|
| Cell 1   | Cell 2   |
`;
var html3 = toHTML(table, "Maruku");

Dialect Subclassing

Create custom dialects by extending existing ones.

/**
 * Create dialect subclass with prototype inheritance
 * @param {Object} d - Base dialect to extend
 * @returns {Object} New dialect with inherited block and inline processors
 */
function Markdown.subclassDialect(d);

Usage Examples:

var { Markdown } = require("markdown").markdown;

// Create custom dialect extending Gruber
var customDialect = Markdown.subclassDialect(Markdown.dialects.Gruber);

// Add custom block rule
customDialect.block.customBlock = function(block, next) {
  if (block.match(/^CUSTOM:/)) {
    return [["div", { class: "custom" }, block.substr(7)]];
  }
  return undefined;
};

// Add custom inline rule
customDialect.inline["@@"] = function(text) {
  var match = text.match(/^@@(.*?)@@/);
  if (match) {
    return [match[0].length, ["span", { class: "highlight" }, match[1]]];
  }
  return [2, "@@"];
};

// Rebuild patterns and order
Markdown.buildBlockOrder(customDialect.block);
Markdown.buildInlinePatterns(customDialect.inline);

// Use custom dialect
var md = new Markdown(customDialect);
var html = md.toTree("CUSTOM: Special content\n\nNormal @@highlighted@@ text");

Dialect Building Utilities

Utility functions for constructing and configuring dialects.

/**
 * Build processing order for block rules in dialect
 * @param {Object} d - Dialect block rules object
 * @modifies {Object} d - Adds __order__ property with rule names array
 */
function Markdown.buildBlockOrder(d);

/**
 * Build regex patterns for inline rules in dialect
 * @param {Object} d - Dialect inline rules object  
 * @modifies {Object} d - Adds __patterns__ property and wraps __call__ method
 */
function Markdown.buildInlinePatterns(d);

Usage Examples:

var customDialect = {
  block: {
    customRule1: function() { /* ... */ },
    customRule2: function() { /* ... */ },
    para: function() { /* fallback */ }
  },
  inline: {
    "**": function() { /* strong */ },
    "*": function() { /* em */ },
    __call__: function(text, patterns) { /* main processor */ }
  }
};

// Build the dialect configuration
Markdown.buildBlockOrder(customDialect.block);
// Sets: customDialect.block.__order__ = ["customRule1", "customRule2", "para"]

Markdown.buildInlinePatterns(customDialect.inline);
// Sets: customDialect.inline.__patterns__ = "\\*\\*|\\*"
// Wraps: customDialect.inline.__call__ with pattern parameter

Advanced Custom Dialect Example

Creating a comprehensive custom dialect with new syntax:

var { Markdown } = require("markdown").markdown;

// Create base dialect
var wikiDialect = Markdown.subclassDialect(Markdown.dialects.Gruber);

// Add wiki-style links: [[Page Name]]
wikiDialect.inline["[["] = function(text) {
  var match = text.match(/^\[\[(.*?)\]\]/);
  if (match) {
    var pageName = match[1];
    var href = "/wiki/" + pageName.replace(/\s+/g, "_");
    return [
      match[0].length,
      ["link", { href: href, class: "wiki-link" }, pageName]
    ];
  }
  return [2, "[["];
};

// Add note blocks: !!! Note: content
wikiDialect.block.noteBlock = function(block, next) {
  var match = block.match(/^!!!\s*(\w+):\s*(.*)/);
  if (match) {
    var noteType = match[1].toLowerCase();
    var content = match[2];
    return [[
      "div", 
      { class: "note note-" + noteType },
      ["strong", {}, match[1] + ": "],
      content
    ]];
  }
  return undefined;
};

// Configure the dialect
Markdown.buildBlockOrder(wikiDialect.block);
Markdown.buildInlinePatterns(wikiDialect.inline);

// Use the custom dialect
var md = new Markdown(wikiDialect);

var wikiText = `
# Wiki Page

See [[Other Page]] for details.

!!! Warning: This is important information.

Regular **markdown** still works.
`;

var html = md.toTree(wikiText);
// Produces HTML with wiki links and note blocks

Dialect Helper Functions

/**
 * Dialect helper utilities
 * @namespace Markdown.DialectHelpers
 */
var Markdown.DialectHelpers = {};

/**
 * Process inline content until specific character
 * @param {string} text - Text to process
 * @param {string} want - Character to stop at
 * @returns {Array|null} [consumed_length, nodes_array] or null if character not found
 */
Markdown.DialectHelpers.inline_until_char = function(text, want);

Usage Examples:

// Used internally by link processing
var result = Markdown.DialectHelpers.inline_until_char("text with **bold**]", "]");
if (result) {
  console.log("Consumed:", result[0]); // Characters consumed
  console.log("Nodes:", result[1]);    // Processed inline nodes
}

docs

command-line.md

core-api.md

dialects.md

index.md

markdown-class.md

tile.json