
Security News
Deno 2.2 Improves Dependency Management and Expands Node.js Compatibility
Deno 2.2 enhances Node.js compatibility, improves dependency management, adds OpenTelemetry support, and expands linting and task automation for developers.
@deskeen/markdown
Advanced tools
This Markdown-to-HTML parser uses a custom, lightweight, Markdown syntax.
It allows to create: italic, bold, strikethrough and superscript texts, headers, links, images, videos, inline codes, multiline codes, unordered lists, ordered lists, nested lists, horizontal lines, quotes and references.
const parser = require('@deskeen/markdown')
const html = parser.parse('some markdown text').innerHTML
// html === '<p>some markdown text</p>'
This package can be added to your Node.js dependencies by running:
npm install @deskeen/markdown`
To import the parser to your JavaScript code, use:
const parser = require('@deskeen/markdown')
To parse a text and transform it into HTML code, use:
const htmlCode = parser.parse('some markdown text').innerHTML
The parser has been tested on Node.js v10+ but it may be working on previous Node.js versions too.
parse(markdownText[, options])
An option object can be passed to the parser.
Available options are:
allowHeader
: Whether headers are allowed. Defaults to true
.allowLink
: Whether links are allowed. Defaults to true
.allowImage
: Whether images are allowed. Defaults to true
.allowImageStyle
: Whether inline image styles are allowed. Defaults to false
.allowCode
: Whether inline codes are allowed. Defaults to true
.allowMultilineCode
: Whether multiline codes are allowed. Defaults to true
.allowUnorderedList
: Whether unordered lists are allowed. Defaults to true
.allowUnorderedNestedList
: Whether unordered nested lists are allowed. Defaults to true
.allowOrderedList
: Whether ordered lists are allowed. Defaults to true
.allowOrderedNestedList
: Whether ordered nested lists are allowed. Defaults to true
.allowHorizontalLine
: Whether horizontal lines are allowed. Defaults to true
.allowQuote
: Whether quotes are allowed. Defaults to true
.allowReference
: Whether references are allowed. Defaults to true
.maxHeader
: Max header level. Number from 1 to 6 included. e.g. 2 means authorized header tags are <h1>
and <h2>
. Defaults to 6.Callback functions can be passed to the options as well. They allow to edit the output element (e.g. add custom attributes).
Available callbacks are:
onHeader
: Function called when a header is parsed.onLink
: Function called when a link is parsed.onImage
: Function called when an image is parsed.onVideo
: Function called when a video is parsed.onCode
: Function called when an inline code is parsed.onMultilineCode
: Function called when a multiline code is parsed. The second argument is the (optional) language name.onUnorderedList
: Function called when a unordered list is parsed.onOrderedList
: Function called when an ordered list is parsed.onHorizontalLine
: Function called when a horizontal line is parsed.onQuote
: Function called when a quote is parsed.onReference
: Function called when a reference is parsed. The second argument contains the reference.The first argument of the callbacks is always the parsed element:
function onXXX(element) {
// Your logic here
// e.g.: element.className = 'css-class'
}
The parser returns a custom Element
that is similar to a DOM Element in the browser.
Available properties are:
tagName
: Tag name of the element. MDNid
: id attribute of the element. MDNclassName
: Class attribute of the element. MDNattributes
: Element attributes. MDNchildren
: List of children. MDNfirstChild
: First child. MDNlastChild
: Last child. MDNtextContent
: Text of the element and its descendants. MDNhasAttribute(attrName)
: Returns whether the element has the specified attribute. MDNsetAttribute(attrName, attrValue)
: Adds an attribute to the element. MDNgetAttribute(attrName)
: Returns an element attribute. MDNremoveAttribute(attrName)
: Removes an element attribute. MDNinnerHTML
: Returns the HTML markup of the elements contained in the element. MDNouterHTML
: Returns the HTML markup of the element and its descendants. MDNNew elements can be created by using the Element
class:
const parser = require('@deskeen/markdown')
const Element = parser.Element
const myDivElement = new Element('div')
Type | Markdown syntax |
---|---|
Italic text | *Italic text* |
Bold text | **Bold text** |
Bold-italic text | ***Bold-italic text*** |
Strikethrough text | ~~Strikethrough text~~ |
Superscript text | ^Superscript |
Header | # Header |
Link | [Link text](link_url) |
Image and Video |  |
Unordered list | - List item |
Unoredered nested list | 2 spaces |
Ordered list | + Ordered list item |
Ordered nested list | 3 spaces |
Horizontal Line | \n\n---\n\n |
Code | `Code text` |
Quote | > Quote |
Reference | Reference[^1] |
Escape character | \# Header not parsed |
An italic text is surrounded by a single star (*
).
Example
This is an *italic text*
<p>This is an <em>italic text</em></p>
A bold text is surrounded by two stars (**
).
Example
This is an **italic text**
<p>This is an <strong>italic text</strong></p>
A bold and italic text is surrounded by three stars (***
).
Example
This is a ***bold and italic text***
<p>This is a <strong><em>bold and italic text</em></strong></p>
A strikethrough text is surrounded by two tildes (~~
).
Example
This is a ~~strikethrough text~~
<p>This is a <s>strikethrough text</s></p>
A superscript text starts with a circumflex (^
) and ends with a space or a newline. A superscript text with spaces can be surrounded by parenthesis (( )
)
Example
This is a ^superscript text
<p>This is a <sup>superscript</sup> text</p>
Example with parenthesis
This is a ^(superscript text)
<p>This is a <sup>superscript text</sup></p>
A single newline adds the text to the last paragraph. Two newlines create a new paragraph.
Example with a single newline
First line of text.
Second line of text.
<p>First line of text.<br>Second line of text.</p>
Example with two newlines
First line of text.
Second line of text.
<p>First line of text.</p>
<p>Second line of text.</p>
A header starts with one to six hashes (#
) followed by a space.
Example
# Title level 1
## Title level 2
### Title level 3
#### Title level 4
##### Title level 5
###### Title level 6
<h1>Title level 1</h1>
<h2>Title level 2</h2>
<h3>Title level 3</h3>
<h4>Title level 4</h4>
<h5>Title level 5</h5>
<h6>Title level 6</h6>
A link is made up of two parts. The text surrounded by square brackets ([]
) followed by an URL surrounded by round brackets (( )
). i.e. [Link](url)
Example
This is a [link](https://example.com)
<p>This is a <a href="https://example.com">link</a></p>
An image starts with an exclamation mark (!
) followed by the caption surrounded by square brackets ([]
), followed by the URL surrounded by round brackets (( )
). i.e. 
CSS instructions can be added to the end, surrounded by curly brackets ({ }
). Instructions are separated by a semicolon (;
). Parser flag allowImageStyle
must be turned on to make it work.
Images set on a separate line and inline images have different HTML outputs.
Example of an inline image
This is an 
<p>This is an <img src="https://example.com/some_image.png" alt="inline image"></p>
Example of an image on a single line

<figure>
<img src="https://example.com/some_image.png" alt="">
<figcaption>Image only on a line</figcaption>
</figure>
Example of an image with inline style
{height: 100px; width: 100px}
<figure style="height: 100px; width: 100px">
<img src="https://example.com/some_image.png" alt="">
<figcaption>Image with inline style</figcaption>
</figure>
Videos work the same way as images, i.e. ![caption][video_url]
.
Example
![my caption][https://example.com/some_video.mp4]
<figure>
<video controls="">
<source src="https://example.com/some_video.mp4" type="video/mp4">
</video>
<figcaption>my caption</figcaption>
</figure>
Unordered list items start with a dash (-
) followed by a space.
Newlines can be inserted within a list item by starting the line with two spaces.
Nested list items start with at least two spaces, followed by a dash and another space. Only one unordered nested list is allowed.
Example
- Item 1
- Item 2
- Item 3
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
Example with a newline within an item
- Item 1
Following Item 1
- Item 2
<ul>
<li>Item 1<br>Following Item 1</li>
<li>Item 2</li>
</ul>
Example with nested list
- Item 1
- Item 1.1
- Item 1.2
- Item 2
<ul>
<li>
Item 1
<ul>
<li>Item 1.1</li>
<li>Item 1.2</li>
</ul>
</li>
<li>Item 2</li>
</ul>
Ordered list items start with a number, followed by a period (.
) and a space.
Newlines can be inserted within a list item by starting the line with three spaces.
Nested list items start with at least three spaces, followed by a number and a space. Only one ordered nested list is allowed.
Example
1. Item 1
2. Item 2
3. Item 3
<ol>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ol>
Example with a newline within an item
1. Item 1
Following Item 1
2. Item 2
<ol>
<li>Item 1<br>Following Item 1</li>
<li>Item 2</li>
</ol>
Example with nested list
1. Item 1
1. Item 1.1
2. Item 1.2
2. Item 2
<ol>
<li>
Item 1
<ol>
<li>Item 1.1</li>
<li>Item 1.2</li>
</ol>
</li>
<li>Item 2</li>
</ol>
The numbers of the ordered list items are not taken into account. The list is rendered the same way whether the numbers are in order or not.
Example with numbers not in order
5. Item 1
1. Item 2
2. Item 3
1. Item 4
<ol>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
</ol>
A Horizontal line starts with an empty line, followed by three dashes (---
), followed by another empty line.
Example
Above horizontal line
---
Below horizontal line
<p>Above horizontal line</p>
<hr>
<p>Below horizontal line</p>
A technical text is surrounded by a single backtick (```)
Example
This is `some technical term`
<p>This is <code>some technical term</code></p>
A multiline code is surrounded by three backticks (```) set on separate lines.
The language name of the code can be added to the opening backticks. It is shown in the output HTML but it is passed to the onMultilineCode
callback. See example further down.
Example
\`\`\`
Some code line 1
Some code line 2
Some code line 3
\`\`\`
<pre><code>Some code line 1
Some code line 2
Some code line 3</code></pre>
Example with language name
\`\`\`javascript
console.log('Hello World!')
\`\`\`
<pre><code>console.log('Hello World!')</code></pre>
A quote starts with a "greater than" sign (>
).
Example
> Quote Line 1
> Quote Line 2
> Quote Line 3
<blockquote>
<p>
Quote Line 1
<br>
Quote Line 2
<br>
Quote Line 3
</p>
</blockquote>
A reference is made up of: An opening square bracket ([
), a circumflex (^
), a reference number and a closing square brackets (]
). e.g. [^1]
Example
This is the fist reference[^1].
And the second one[^2].
<p>This is the fist reference<a href="#reference1"><sup>1</sup></a>.</p>
<p>And the second one<a href="#reference2"><sup>2</sup></a>.</p>
The escape character is a backslash (\
). It can be used to tell the parser not to interpret Markdown syntax characters, i.e. *
, [
, `
, !
, #
, ~
, ^
and \
.
Example
This \*bold text\* is not converted into html.
<p>This *bold text* is not converted into html.</p>
Example 2
This backslash \ is not removed because it is not followed by a special character.
<p>This backslash \ is not removed because it is not followed by a special character.</p>
A tick (☑) means that the syntax should work on the platform.
Type | Syntax | GitHub | GitLab | |
---|---|---|---|---|
Italic | * | ☑ | ☑ | ☑ |
Bold | ** | ☑ | ☑ | ☑ |
Bold-italic | *** | ☑ | ☑ | ☑ |
Strikethrough | ~~ | ☑ | ☑ | ☑ |
Newline | \n | ☑ | ☑ | ☑ |
Paragraph | \n\n | ☑ | ☑ | ☑ |
Header | # | ☑ | ☑ | ☑ |
Link | []() | ☑ | ☑ | ☑ |
Image | ![]() | ☑ | ☑ | ☑ |
Un. list | - | ☑ | ☑ | ☑ |
Un. list \n | 2 spaces | ☑ | ☑ | ☑ |
Un. nested | 2 spaces | ☑ | ☑ | ☑ |
Ord. list | 1. | ☑ | ☑ | ☑ |
Ord. list \n | 3 spaces | ☑ | ☑ | ☑ |
Ord. nested | 3 spaces | ☑ | ☑ | ☑ |
Horiz. Line | \n---\n | ☑ | ☑ | ☑ |
Code | ` | ☑ | ☑ | ☑ |
MultiCode | ``` | ☑ | ☑ | ☑ |
Quote | > | ☑ | ☑ | ☑ |
Escape char | \ | ☑ | ☑ | ☑ |
Superscript | ^ | ⚠ <sup> | ☑ | ⚠ <sup> |
Subscript | N/A | ⚠ <sub> | N/A | ⚠ <sub> |
Reference | [^1] | ⚠ N/A | ⚠ N/A | ⚠ Diff. |
HTML | N/A | ⚠ Avail. | N/A | ⚠ Avail. |
Source: GitHub Markdown, Reddit Markdown, GitLab Markdown
The following syntaxes are NOT supported:
parseMarkdown('# Title 1', {
onHeader: element => {
// node.textContent === 'Title 1'
element.id = element.textContent.replace(/ /g, '-').toLowerCase()
}
}).innerHTML
<h1 id="title-1">Title 1</h1>
parseMarkdown('See [this page](https:/example.com)!', {
onLink: element => {
// element.getAttribute('href') === 'http:/example.com'
const href = element.getAttribute('href')
if (href.startsWith('https://MY_SITE.com') === false) {
element.setAttribute('target', '_blank')
}
}
}).innerHTML
<p>See <a href="https:/example.com" target="_blank">this page</a>!</p>
parseMarkdown('', {
onImage: element => {
// element.getAttribute('src') === 'beautiful_image.png'
if (element.hasAttribute('src')) {
const src = element.getAttribute('src')
if (src.startsWith('http') === false) {
element.setAttribute('src', 'https://example.com/' + src)
}
}
}
}).innerHTML
<figure>
<img src="https://example.com/beautiful_image.png" alt="">
<figcaption>Beautiful image</figcaption>
</figure>
parseMarkdown('This is body html tag: `<body>`', {
onCode: element => {
element.className = 'some-class'
}
}).innerHTML
<p>This is body html tag: <code class="some-class"><body></code></p>
const markdownText = '```json\n{"some_property":"foo","some_other_property":"bar"}\n```'
parseMarkdown(markdownText, {
onMultilineCode: (element, language) => {
if (language === 'json') {
// element is a <pre> tag that includes the <code> tag
const codeElement = element.firstChild
const codeText = codeElement.textContent
const jsonObject = JSON.parse(codeText)
codeElement.textContent = JSON.stringify(jsonObject, null, 2)
}
}
}).innerHTML
<pre><code>{
"some_property": "foo",
"some_other_property": "bar"
}</code></pre>
You can raise an issue and ask for help.
You can:
You can reach me at {my_firstname}@{my_name}.fr
MIT Licence - Copyright (c) Morgan Schmiedt
2.0.0 - 2020-08-21
🌟 New
allowUnorderedNestedList
, allowOrderedNestedList
, allowReference
options are added.Element.id
, Element.className
, Element.hasAttribute
, Element.getAttribute
, Element.setAttribute
and Element.removeAttribute
, Element.attributes
, Element.innerHTML
, Element.outerHTML
are added.⚠ Breaking changes
allowFootnote
becomes allowReference
.onFootnote
becomes onReference
.Element.attr
becomes Element.attributes
.Element.toHtml()
becomes Element.innerHTML
.Element.tagName
property is now read-only and returns the tag name in uppercase.Element.textContent
returns non-only the text of the Element, but also the text of its descendants.<br>
tag to the last paragraph.brOnBlankLine
option is removed.🔧 Changes
<p>
tag.<video>
HTML tags have now a controls
attribute by default.FAQs
Node.js Markdown to HTML Parser
The npm package @deskeen/markdown receives a total of 165 weekly downloads. As such, @deskeen/markdown popularity was classified as not popular.
We found that @deskeen/markdown demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Deno 2.2 enhances Node.js compatibility, improves dependency management, adds OpenTelemetry support, and expands linting and task automation for developers.
Security News
React's CRA deprecation announcement sparked community criticism over framework recommendations, leading to quick updates acknowledging build tools like Vite as valid alternatives.
Security News
Ransomware payment rates hit an all-time low in 2024 as law enforcement crackdowns, stronger defenses, and shifting policies make attacks riskier and less profitable.