marked/README.md
2018-02-25 14:18:59 -05:00

11 KiB

marked

NPM version NPM dependencies

Marked is

  1. built for speed.*
  2. a low-level markdown compiler that allows frequent parsing of large chunks of markdown without caching or blocking for long periods of time.**
  3. light-weight while implementing all markdown features from the supported flavors & specifications.***
  4. available as a command line interface and running in client- or server-side JavaScript projects.
  • * Still working on metrics for comparative analysis and definition.
  • ** As few dependencies as possible.
  • *** Strict compliance could result in slower processing when running comparative benchmarking.

Install

npm install marked --save

or if you want to use the marked CLI tool (not necessary when using npm run-scripts):

npm install -g marked

Usage

Minimal usage:

var marked = require('marked');
console.log(marked('I am using __markdown__.'));
// Outputs: <p>I am using <strong>markdown</strong>.</p>

Example setting options:

var marked = require('marked');
marked.setOptions({
  renderer: new marked.Renderer(),
  gfm: true,
  tables: true,
  breaks: false,
  pedantic: false,
  sanitize: false,
  smartLists: true,
  smartypants: false,
  xhtml: false
});

console.log(marked('I am using __markdown__.'));

Browser

<!doctype html>
<html>
<head>
  <meta charset="utf-8"/>
  <title>Marked in the browser</title>
  <script src="lib/marked.js"></script>
</head>
<body>
  <div id="content"></div>
  <script>
    document.getElementById('content').innerHTML =
      marked('# Marked in browser\n\nRendered by **marked**.');
  </script>
</body>
</html>

marked(markdownString [,options] [,callback])

markdownString

Type: string

String of markdown source to be compiled.

options

Type: object

Hash of options. Can also be set using the marked.setOptions method as seen above.

callback

Type: function

Function called when the markdownString has been fully parsed when using async highlighting. If the options argument is omitted, this can be used as the second argument.

Options

highlight

Type: function

A function to highlight code blocks. The first example below uses async highlighting with node-pygmentize-bundled, and the second is a synchronous example using highlight.js:

var marked = require('marked');

var markdownString = '```js\n console.log("hello"); \n```';

// Async highlighting with pygmentize-bundled
marked.setOptions({
  highlight: function (code, lang, callback) {
    require('pygmentize-bundled')({ lang: lang, format: 'html' }, code, function (err, result) {
      callback(err, result.toString());
    });
  }
});

// Using async version of marked
marked(markdownString, function (err, content) {
  if (err) throw err;
  console.log(content);
});

// Synchronous highlighting with highlight.js
marked.setOptions({
  highlight: function (code) {
    return require('highlight.js').highlightAuto(code).value;
  }
});

console.log(marked(markdownString));

highlight arguments

code

Type: string

The section of code to pass to the highlighter.

lang

Type: string

The programming language specified in the code block.

callback

Type: function

The callback function to call when using an async highlighter.

renderer

Type: object Default: new Renderer()

An object containing functions to render tokens to HTML.

Overriding renderer methods

The renderer option allows you to render tokens in a custom manner. Here is an example of overriding the default heading token rendering by adding an embedded anchor tag like on GitHub:

var marked = require('marked');
var renderer = new marked.Renderer();

renderer.heading = function (text, level) {
  var escapedText = text.toLowerCase().replace(/[^\w]+/g, '-');

  return '<h' + level + '><a name="' +
                escapedText +
                 '" class="anchor" href="#' +
                 escapedText +
                 '"><span class="header-link"></span></a>' +
                  text + '</h' + level + '>';
};

console.log(marked('# heading+', { renderer: renderer }));

This code will output the following HTML:

<h1>
  <a name="heading-" class="anchor" href="#heading-">
    <span class="header-link"></span>
  </a>
  heading+
</h1>

Block level renderer methods

  • code(string code, string language)
  • blockquote(string quote)
  • html(string html)
  • heading(string text, number level)
  • hr()
  • list(string body, boolean ordered)
  • listitem(string text)
  • paragraph(string text)
  • table(string header, string body)
  • tablerow(string content)
  • tablecell(string content, object flags)

flags has the following properties:

{
    header: true || false,
    align: 'center' || 'left' || 'right'
}

Inline level renderer methods

  • strong(string text)
  • em(string text)
  • codespan(string code)
  • br()
  • del(string text)
  • link(string href, string title, string text)
  • image(string href, string title, string text)
  • text(string text)

gfm

Type: boolean Default: true

Enable GitHub flavored markdown.

tables

Type: boolean Default: true

Enable GFM tables. This option requires the gfm option to be true.

breaks

Type: boolean Default: false

Enable GFM line breaks. This option requires the gfm option to be true.

pedantic

Type: boolean Default: false

Conform to obscure parts of markdown.pl as much as possible. Don't fix any of the original markdown bugs or poor behavior.

sanitize

Type: boolean Default: false

Sanitize the output. Ignore any HTML that has been input.

smartLists

Type: boolean Default: true

Use smarter list behavior than the original markdown. May eventually be default with the old behavior moved into pedantic.

smartypants

Type: boolean Default: false

Use "smart" typographic punctuation for things like quotes and dashes.

xhtml

Type: boolean Default: false

Self-close the tags for void elements (<br/>, <img/>, etc.) with a "/" as required by XHTML.

Access to lexer and parser

You also have direct access to the lexer and parser if you so desire.

var tokens = marked.lexer(text, options);
console.log(marked.parser(tokens));
var lexer = new marked.Lexer(options);
var tokens = lexer.lex(text);
console.log(tokens);
console.log(lexer.rules);

CLI

$ marked -o hello.html
hello world
^D
$ cat hello.html
<p>hello world</p>

Benchmarks

node v8.9.4

$ npm run bench
marked completed in 3408ms.
marked (gfm) completed in 3465ms.
marked (pedantic) completed in 3032ms.
showdown (reuse converter) completed in 21444ms.
showdown (new converter) completed in 23058ms.
markdown-it completed in 3364ms.
markdown.js completed in 12090ms.

Pro level

You also have direct access to the lexer and parser if you so desire.

var tokens = marked.lexer(text, options);
console.log(marked.parser(tokens));
var lexer = new marked.Lexer(options);
var tokens = lexer.lex(text);
console.log(tokens);
console.log(lexer.rules);
$ node
> require('marked').lexer('> i am using marked.')
[ { type: 'blockquote_start' },
  { type: 'paragraph',
    text: 'i am using marked.' },
  { type: 'blockquote_end' },
  links: {} ]

Contributing

  1. If the code in a pull request can have a test written for it, it should have it. (If the test already exists, please reference the test which should pass.)
  2. Do not merge your own. Mainly for collaborators and owners, please do not review and merge your own PRs.

Tests

The marked test suite is set up slightly strangely: test/new is for all tests that are not part of the original markdown.pl test suite (this is where your test should go if you make one). test/original is only for the original markdown.pl tests.

In other words, if you have a test to add, add it to test/new/. If your test uses a certain feature, for example, maybe it assumes GFM is not enabled, you can add front-matter to the top of your .md file

---
gfm: false
---

To run the tests:

npm run test

Contribution License Agreement

If you contribute code to this project, you are implicitly allowing your code to be distributed under the MIT license. You are also implicitly verifying that all code is your original work. </legalese>

Releasing

Master is always shippable: We try to merge PRs in such a way that master is the only branch to really be concerned about and master can always be released. This allows smoother flow between new fetures, bug fixes, and so on. (Almost a continuous deployment setup, without automation.)

Version naming: relatively standard [major].[minor].[patch] where major releases represent known breaking changes to the previous release, minor represent additions of new funcitonality without breaking changes, and patch releases represent changes meant to fix previously released functionality with no new functionality. Note: When the major is a zero, it means the library is still in a beta state wherein the major does not get updated; therefore, minor releases may introduce breaking changes, and patch releases may contain new features.

Release process:

  1. Check out library
  2. Make sure you are on the master branch
  3. Create release branch from master
  4. $ npm run build (builds minified version and whatnot)
  5. $ npm version [major|minor|patch] (updates package.json)
  6. $ npm publish (publishes package to NPM)
  7. Submit PR
  8. Merge PR (only time where submitter should be "allowed" to merge his or her own)
  9. Navigate to the "Releases" tab on the project main page -> "Draft new release"
  10. Add version number matching the one in the package.json file after publishing the release
  11. Make sure master is the branch from which the release will be made
  12. Add notes regarding what users should expect from the release
  13. Click "Publish release"

License

Copyright (c) 2011-2018, Christopher Jeffrey. (MIT License)

See LICENSE for more details.