{"id":24829114,"url":"https://github.com/ljh131/mark-to-jsonml","last_synced_at":"2025-10-14T02:32:03.460Z","repository":{"id":25697986,"uuid":"105147660","full_name":"ljh131/mark-to-jsonml","owner":"ljh131","description":"Parse markdown into JsonML","archived":false,"fork":false,"pushed_at":"2023-03-04T04:50:29.000Z","size":768,"stargazers_count":6,"open_issues_count":7,"forks_count":2,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-01-20T01:37:01.345Z","etag":null,"topics":["jsonml","markdown","parser","textprocess"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ljh131.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-09-28T12:51:30.000Z","updated_at":"2021-08-29T05:31:25.000Z","dependencies_parsed_at":"2023-01-14T03:10:38.172Z","dependency_job_id":null,"html_url":"https://github.com/ljh131/mark-to-jsonml","commit_stats":null,"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ljh131%2Fmark-to-jsonml","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ljh131%2Fmark-to-jsonml/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ljh131%2Fmark-to-jsonml/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ljh131%2Fmark-to-jsonml/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ljh131","download_url":"https://codeload.github.com/ljh131/mark-to-jsonml/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":236436486,"owners_count":19148512,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["jsonml","markdown","parser","textprocess"],"created_at":"2025-01-30T23:03:57.355Z","updated_at":"2025-10-14T02:31:58.161Z","avatar_url":"https://github.com/ljh131.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# mark-to-jsonml\nParse markdown into [JsonML](http://www.jsonml.org/)\n\n* Easy to add custom markdown syntax\n  * With automatic inline parsing\n* Supports common markdown specs and other extensions\n  * Which includes: table, footnote, table of content and more\n\n## If you want to use it in React\n\n* [mark-to-react](https://github.com/ljh131/mark-to-react)\n\n# Installation\n```sh\nnpm install mark-to-jsonml --save\n```\n\n# Example\n```javascript\nconst { Parser, makeTestResult, inspect } = require('mark-to-jsonml');\n\nconst markdown = `{toc}\n# hello parser!\n* first\n* second **bold ~~and strike~~** plain\n * nested\n  1. deeply *nested*\n  1. and ordered\n## try _this!_\n\\`\\`\\`javascript\nconsole.log(\"hello mark-to-jsonml!\");\n\\`\\`\\`\n@@@@`;\n\n// string {String}: remaining string to parse\n// isTest {Boolean}: true if test mode (pre-parse mode)\nfunction parseMyRuler(string, isTest) {\n  const RULER = /^@{3,}$/gm;\n  const result = RULER.exec(string);\n\n  // you should return the test result on the test mode.\n  if (isTest) return makeTestResult(RULER, result);\n  if (!result) return null;\n\n  return ['my_ruler'];\n}\n\nconst parser = new Parser({ parseToc: true });\nparser.addBlockParser(parseMyRuler, true);\n\nconst parsed = parser.parse(markdown);\nconsole.log(inspect(parsed));    \n```\n\n## Output\n```javascript\n[ 'markdown',\n  { tocParsed: true, footnoteParsed: false },\n  [ 'toc',\n    [ 'toc-item', { level: 1, number: '1.' }, 'hello parser!' ],\n    [ 'toc-item',\n      { level: 2, number: '1.1.' },\n      'try ',\n      [ 'u', 'this!' ] ] ],\n  [ 'h', { number: '1.', level: 1 }, 'hello parser!' ],\n  [ 'ul',\n    [ 'li', 'first' ],\n    [ 'li',\n      'second ',\n      [ 'b', 'bold ', [ 's', 'and strike' ] ],\n      ' plain',\n      [ 'ul',\n        [ 'li',\n          'nested',\n          [ 'ol',\n            [ 'li', 'deeply ', [ 'i', 'nested' ] ],\n            [ 'li', 'and ordered' ] ] ] ] ] ],\n  [ 'h', { number: '1.1.', level: 2 }, 'try ', [ 'u', 'this!' ] ],\n  [ 'codeblock',\n    { lang: 'javascript' },\n    'console.log(\"hello mark-to-jsonml!\");\\n' ],\n  [ 'my_ruler' ] ]\n```\n\n# How it parse Markdown into JsonML elements\n\n## Block elements\n\n### Heading\n```\n['h', { level, number }, ...]\n```\n\n### Table of content\n```\n['toc', // an wrapping element\n  ['toc-item', { level, number }, ...] // items corresponding to the heading\n]\n```\n\n### Table\n```\n['table', \n  ['thead', \n    ['tr', ['td', ...]]\n  ], \n  ['tbody', \n    ['tr', ['td', ...]]\n  ]\n]\n```\n\n### List (Unordered and ordered)\n```\n['ul', ['li', ...], ['li', ...]] // unordered list\n['ol', ['li', ...], ['li', ...]] // ordered list\n```\n\n### Block quote \n```\n['blockquote', ...]\n```\n\n### Code block\n```\n['codeblock', { lang }, ...]\n```\n\n### Paragraph\n```\n['p', ...]\n```\n\n### Horizontal ruler \n```\n['hr', ...]\n```\n\n## Inline elements\n### Inline code \n```\n['code', ...]\n```\n\n### Link \nURL starts with http:// or https:// will be recognized as a link\n\n```\n['a', { href }, ...]\n```\n\n### Text decoration (bold, strike, italic, underline)\n```\n['b', ...] // bold\n['s', ...] // strike\n['i', ...] // italic\n['u', ...] // underline\n```\n\n# API\n## Class: Parser\n### new Parser(options)\n* `options` {Object}\n  * `includeRoot` {Boolean}: Parsed result contains root element `markdown` with some props\n  * `includeHeadingNumber` {Boolean}: Parsed heading prop contains number field (eg, 1, 2, 2.1)\n  * `parseNewLine` {Boolean}: Parse new line as `br`\n  * `parseToc` {Boolean}: Parse `table of content` pattern with `tocPattern` \n  * `parseFootnote` {Boolean}: Parse `footnote` pattern with `footnotePattern` \n  * `tocPattern` {String}: Specify `table of content` regexp pattern\n  * `footnotePattern` {String}: Specify `footnote` regexp pattern\n\n### parse(mdtext)\nParse markdown text into JsonML\n\n* returns {Object}: Parsed result\n\n### addBlockParser(blockParser, isTerminal=false)\nAdd custom block element parse function. \n\nA block element is an element that cannot contain other block element, but can contain inline elements.\n\n* `blockParser` {Function}: A custom parser function\n* `isTerminal` {Boolean}: true if you don't want inline parsing inside (like codeblock)\n\n### addInlineParser(inlineParser, isTerminal=false)\nAdd custom inline element parse function. \n\nAn inline element is an element that cannot contain other block element, but can contain other inline elements.\n\n* `inlineParser` {Function}: A custom parser function\n* `isTerminal` {Boolean}: true if you don't want inline parsing inside (like inline code)\n\n## function: makeTestResult(re, result, priority=0)\nInside 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.\n\n* `re` {RegExp}: RegExp object used inside your custom parser\n* `result` {Object}: Executed result of RegExp\n* `priority` {Integer}: Lower value means highest priority \n  * priority used only when more than one parsers are competing (which means multiple parser return same index)\n\n## Note on custom syntax parser\nThe parser(this library itself) will call your custom parser in two different mode. 1. Test mode (pre-parse mode) and 2. Parse mode. \n\nIn test mode (pre-parse mode), you should return whether you can parse the given string and some information. \n\nIn parse mode, you should return parsed actual JsonML element. All the other things are done automatically, including inline element parsing. See below for details.\n\n- In test mode (pre-parse mode):\n  - Return null if you can't parse.\n  - Return `{index, lastIndex, priority}` if you can parse. \n    - index {Integer}: The position of given string that parser can parse.\n    - lastIndex {Integer}: The next position after the parser has finished parse.\n    - 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. \n- In parse mode:\n  - Return the JsonML element.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fljh131%2Fmark-to-jsonml","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fljh131%2Fmark-to-jsonml","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fljh131%2Fmark-to-jsonml/lists"}