jp-markdown
v1.2.1
Published
Markdown-to-HTML parser with syntax-highlighted code blocks, line numbers, copy buttons, and Tailwind-friendly element styling.
Downloads
789
Maintainers
Readme
JP-MarkDown
A customizable Markdown → HTML parser for Node.js. Built on marked and highlight.js, with first-class support for styled code blocks, Tailwind-friendly element classes, and optional full-document export.
Perfect for docs sites, admin previews, and anywhere you need server-rendered markdown with polished output.
Install
npm install jp-markdownQuick start
const JPMarkDown = require('jp-markdown');
const parser = new JPMarkDown();
const html = parser.Parse('# Hello\n\nSome **bold** text.');
console.log(html);
// => <h1>Hello</h1><p>Some <strong>bold</strong> text.</p>Embed in an existing page (recommended)
When you already have your own layout and CSS, return an HTML fragment and let JP-MarkDown handle code styling separately:
const html = parser.Parse(markdown, {
fullDocument: false, // no <!DOCTYPE html> wrapper
includeStyle: false, // skip default document CSS
includeCodeStyle: true, // inject scoped code-block CSS
includeCodeScript: true, // enable copy-to-clipboard buttons
});This is the most common setup for Express, Next.js API routes, or any app that renders markdown into a template.
Code blocks
Fenced code blocks are syntax-highlighted with a GitHub Dark theme, line numbers, a language label, and a copy button.
Markdown input:
```js
const html = parser.Parse(markdown, {
fullDocument: false,
includeStyle: false,
});
```What you get:
- Syntax-highlighted tokens (via highlight.js)
- Language header (e.g.
JavaScript) - Line numbers
- One-click Copy button
- Scoped CSS injected when
includeCodeStyle: true
Supported language tags include js, ts, python, bash, json, html, css, and any language highlight.js recognizes. Unknown tags fall back to plain text.
Inline code
Inline `code` spans use your elementStyles.code classes if configured, otherwise the built-in jp-md-inline-code class.
Constructor options
Create one shared instance and reuse it across your app:
const parser = new JPMarkDown({
// Per-element Tailwind / CSS classes
elementStyles: {
h1: { class: 'text-4xl font-bold text-white mb-4' },
p: { class: 'text-gray-300 leading-relaxed mb-4' },
code: { class: 'bg-gray-900 text-green-400 px-1 rounded font-mono text-sm' },
a: { class: 'text-blue-400 underline' },
},
// Code block behaviour
codeCopyButton: true, // show copy button (default: true)
codeLineNumbers: true, // show line numbers (default: true)
// Document-level CSS (only when includeStyle + addCustomCSS are true)
addCustomCSS: false,
injectCSS: true,
customCSS: 'body { background: #111; }',
// Override individual token renderers
customRender: {
h1: (text) => `<h1 class="my-heading">${text}</h1>`,
},
});| Option | Default | Description |
|--------|---------|-------------|
| elementStyles | {} | Map of tag → { class, style } applied to headings, paragraphs, links, etc. |
| customRender | {} | Replace render functions for specific tags (h1–h6, p, a, codeblock, …) |
| codeCopyButton | true | Show copy button on fenced code blocks |
| codeLineNumbers | true | Show line numbers on fenced code blocks |
| addCustomCSS | false | Enable default document CSS injection |
| injectCSS | true | Prepend document CSS to fragment output |
| customCSS | '' | Extra CSS appended to the document style block |
| defaultCSS | built-in dark theme | Override the default document stylesheet |
| markedOptions | {} | Extra options passed to marked.setOptions() |
Parse options
parser.Parse(markdown, {
fullDocument: false,
includeStyle: false,
includeCodeStyle: true,
includeCodeScript: true,
title: 'My Document',
autoExport: false,
exportPath: './output.html',
});| Option | Default | Description |
|--------|---------|-------------|
| fullDocument | false | Wrap output in a full <!DOCTYPE html> document |
| includeStyle | true | Inject document CSS (requires addCustomCSS: true on the instance) |
| includeCodeStyle | true | Inject scoped code-block CSS — works even when includeStyle: false |
| includeCodeScript | true | Inject copy-button script (only when code blocks are present) |
| title | 'JP-MarkDown Document' | <title> used when fullDocument: true |
| autoExport | false | Write rendered HTML to disk |
| exportPath | './output.html' | File path used when autoExport: true |
External CSS & JS (no inline injection)
If you prefer to load assets once in your layout instead of injecting them per render:
const html = parser.Parse(markdown, {
fullDocument: false,
includeStyle: false,
includeCodeStyle: false, // don't inject <style>
includeCodeScript: false, // don't inject <script>
});Then in your HTML layout:
<link rel="stylesheet" href="/path/to/node_modules/jp-markdown/code.css">
<script src="/path/to/node_modules/jp-markdown/code.js" defer></script>Or copy those files into your static assets folder.
Alert blocks
JP-MarkDown supports custom alert syntax (in addition to standard markdown):
:::info
This is an informational message.
:::
:::warning
Be careful with this setting.
:::
:::danger
This action cannot be undone.
:::
:::note
A quick side note for the reader.
:::Each renders as a styled alert <div> with an icon and label.
Full HTML document export
Generate a standalone HTML file:
parser.Parse('# My Report\n\nContent here.', {
fullDocument: true,
includeStyle: true,
title: 'My Report',
autoExport: true,
exportPath: './report.html',
});
// => writes report.html and returns the HTML stringEnable document CSS on the instance first:
const parser = new JPMarkDown({ addCustomCSS: true });TypeScript
Type definitions are included:
import JPMarkDown from 'jp-markdown';
const parser = new JPMarkDown({
elementStyles: {
h1: { class: 'text-4xl font-bold' },
},
});
const html: string = parser.Parse('# Hello', {
fullDocument: false,
includeCodeStyle: true,
});Real-world example (Express / EJS)
// utils/markdown.js
const JPMarkDown = require('jp-markdown');
const parser = new JPMarkDown({
elementStyles: {
h1: { class: 'text-5xl font-black mb-6 text-white' },
p: { class: 'text-gray-300 mb-6 leading-relaxed' },
code: { class: 'bg-gray-900 text-green-400 px-1.5 py-0.5 rounded font-mono text-sm' },
},
});
function renderMarkdown(md) {
return parser.Parse(String(md || ''), {
fullDocument: false,
includeStyle: false,
includeCodeStyle: true,
includeCodeScript: true,
});
}
module.exports = { renderMarkdown };<!-- article.ejs -->
<article class="docs-article">
<%- articleHtml %>
</article>API summary
const JPMarkDown = require('jp-markdown');
// 1. Create a configured instance (reuse it)
const parser = new JPMarkDown(options);
// 2. Parse markdown to HTML
const html = parser.Parse(markdownString, parseOptions);Dependencies
- marked — Markdown parsing (GFM)
- highlight.js — Server-side syntax highlighting
License
MIT © Jipy
