npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

mark-to-jsonml

v0.5.2

Published

Parse markdown into JsonML

Downloads

59

Readme

mark-to-jsonml

Parse markdown into JsonML

  • Easy to add custom markdown syntax
    • With automatic inline parsing
  • Supports common markdown specs and other extensions
    • Which includes: table, footnote, table of content and more

If you want to use it in React

Installation

npm install mark-to-jsonml --save

Example

const { Parser, makeTestResult, inspect } = require('mark-to-jsonml');

const markdown = `{toc}
# hello parser!
* first
* second **bold ~~and strike~~** plain
 * nested
  1. deeply *nested*
  1. and ordered
## try _this!_
\`\`\`javascript
console.log("hello mark-to-jsonml!");
\`\`\`
@@@@`;

// string {String}: remaining string to parse
// isTest {Boolean}: true if test mode (pre-parse mode)
function parseMyRuler(string, isTest) {
  const RULER = /^@{3,}$/gm;
  const result = RULER.exec(string);

  // you should return the test result on the test mode.
  if (isTest) return makeTestResult(RULER, result);
  if (!result) return null;

  return ['my_ruler'];
}

const parser = new Parser({ parseToc: true });
parser.addBlockParser(parseMyRuler, true);

const parsed = parser.parse(markdown);
console.log(inspect(parsed));    

Output

[ 'markdown',
  { tocParsed: true, footnoteParsed: false },
  [ 'toc',
    [ 'toc-item', { level: 1, number: '1.' }, 'hello parser!' ],
    [ 'toc-item',
      { level: 2, number: '1.1.' },
      'try ',
      [ 'u', 'this!' ] ] ],
  [ 'h', { number: '1.', level: 1 }, 'hello parser!' ],
  [ 'ul',
    [ 'li', 'first' ],
    [ 'li',
      'second ',
      [ 'b', 'bold ', [ 's', 'and strike' ] ],
      ' plain',
      [ 'ul',
        [ 'li',
          'nested',
          [ 'ol',
            [ 'li', 'deeply ', [ 'i', 'nested' ] ],
            [ 'li', 'and ordered' ] ] ] ] ] ],
  [ 'h', { number: '1.1.', level: 2 }, 'try ', [ 'u', 'this!' ] ],
  [ 'codeblock',
    { lang: 'javascript' },
    'console.log("hello mark-to-jsonml!");\n' ],
  [ 'my_ruler' ] ]

How it parse Markdown into JsonML elements

Block elements

Heading

['h', { level, number }, ...]

Table of content

['toc', // an wrapping element
  ['toc-item', { level, number }, ...] // items corresponding to the heading
]

Table

['table', 
  ['thead', 
    ['tr', ['td', ...]]
  ], 
  ['tbody', 
    ['tr', ['td', ...]]
  ]
]

List (Unordered and ordered)

['ul', ['li', ...], ['li', ...]] // unordered list
['ol', ['li', ...], ['li', ...]] // ordered list

Block quote

['blockquote', ...]

Code block

['codeblock', { lang }, ...]

Paragraph

['p', ...]

Horizontal ruler

['hr', ...]

Inline elements

Inline code

['code', ...]

Link

URL starts with http:// or https:// will be recognized as a link

['a', { href }, ...]

Text decoration (bold, strike, italic, underline)

['b', ...] // bold
['s', ...] // strike
['i', ...] // italic
['u', ...] // underline

API

Class: Parser

new Parser(options)

  • options {Object}
    • includeRoot {Boolean}: Parsed result contains root element markdown with some props
    • includeHeadingNumber {Boolean}: Parsed heading prop contains number field (eg, 1, 2, 2.1)
    • parseNewLine {Boolean}: Parse new line as br
    • parseToc {Boolean}: Parse table of content pattern with tocPattern
    • parseFootnote {Boolean}: Parse footnote pattern with footnotePattern
    • tocPattern {String}: Specify table of content regexp pattern
    • footnotePattern {String}: Specify footnote regexp pattern

parse(mdtext)

Parse markdown text into JsonML

  • returns {Object}: Parsed result

addBlockParser(blockParser, isTerminal=false)

Add custom block element parse function.

A block element is an element that cannot contain other block element, but can contain inline elements.

  • blockParser {Function}: A custom parser function
  • isTerminal {Boolean}: true if you don't want inline parsing inside (like codeblock)

addInlineParser(inlineParser, isTerminal=false)

Add custom inline element parse function.

An inline element is an element that cannot contain other block element, but can contain other inline elements.

  • inlineParser {Function}: A custom parser function
  • isTerminal {Boolean}: true if you don't want inline parsing inside (like inline code)

function: makeTestResult(re, result, priority=0)

Inside your custom parser, you can use this function to make test result and return if your custom parser uses regexp. Note that you should return test result only if the parser is running with the test mode.

  • re {RegExp}: RegExp object used inside your custom parser
  • result {Object}: Executed result of RegExp
  • priority {Integer}: Lower value means highest priority
    • priority used only when more than one parsers are competing (which means multiple parser return same index)

Note on custom syntax parser

The parser(this library itself) will call your custom parser in two different mode. 1. Test mode (pre-parse mode) and 2. Parse mode.

In test mode (pre-parse mode), you should return whether you can parse the given string and some information.

In parse mode, you should return parsed actual JsonML element. All the other things are done automatically, including inline element parsing. See below for details.

  • In test mode (pre-parse mode):
    • Return null if you can't parse.
    • Return {index, lastIndex, priority} if you can parse.
      • index {Integer}: The position of given string that parser can parse.
      • lastIndex {Integer}: The next position after the parser has finished parse.
      • priority {Integer}: Priority is used when two or more parser returns same index in test mode. If you want more higher priority than others, return less than zero. Otherwise, just use 0.
  • In parse mode:
    • Return the JsonML element.