My Docs

logo

A script converts markdown to html

NPM Version NPM Downloads Minizip Contributors License

#Features

  • Support Syntax Highlighting
  • Support Github Alert
  • Support Emoji
  • Support Table of Contents
  • Support Mermaid
  • Support Katex
  • Support Twoslash powered by Shiki

Demo

#API

--i: input file
--o: output file
--t: title
--g: github link
md

#CLI

  • Option 1
npx convert-markdown-to-html@latest --i README.md --o docs/index.html --t "Convert Markdown to HTML" --g "https://github.com/hunghg255/convert-markdown-to-html"
bash
  • Option 2
npm i convert-markdown-to-html@latest --save-dev
bash
  • Config (file package.json)
package.json
{
  ...
  "scripts": {
    ...
    "gen-docs": "convert-markdown-to-html --i README.md --o docs/index.html --t \"Convert Markdown to HTML\" --g \"https://github.com/hunghg255/convert-markdown-to-html\""
  },
  ...
}
json

#Install

import { markdownToDocs } from 'convert-markdown-to-html';

declare const markdownToDocs: (
  isTwoSlash: boolean;
  title: string;
  description?: string;
  logo?: string;
  socialLinks?: {
      icon?: 'twitter' | 'github';
      url?: string;
  }[];
  footer?: {
      message?: string;
      copyright?: string;
  };
  head?: Array<[string, Record<string, string>]>;
) => Promise<string>;

const markdownContent = `# Hello World`;
const html = markdownToDocs(markdownContent, {
  isTwoSlash: true,

  title: 'My Docs',
  description: 'My awesome documentation',

  logo: '',

  socialLinks: [
    {
      icon: 'twitter',
      url: 'https://github.com',
    },
    {
      icon: 'github',
      url: 'https://github.com',
    },
  ],
  footer: {
    message: 'Released under the MIT License',
    copyright: 'Copyright © 2023-present Hunghg255',
  },

  head: [
    [
      'link',
      { rel: 'icon', type: 'image/png', href: 'https://hung.thedev.id/images/patak-banner.jpg' },
    ],
    ['meta', { property: 'og:type', content: 'website' }],
    ['meta', { property: 'og:title', content: ogTitle }],
    ['meta', { property: 'og:image', content: ogImage }],
    ['meta', { property: 'og:url', content: ogUrl }],
    ['meta', { property: 'og:description', content: ogDescription }],
    ['meta', { name: 'twitter:card', content: 'summary_large_image' }],
    ['meta', { name: 'twitter:site', content: '@hunghg255' }],
    ['meta', { name: 'theme-color', content: '#7eaf90' }],
  ],
});
ts

#Demo

Code Markdown

  • Code Highlight
console.log(1);
console.log(1);
console.log(1);
console.log(1);
console.log(1);
js
console.log(1);
console.log(1);
console.log(1);
js
  • Code Group

npm
yarn
pnpm
bun
 npm install @nuxtjs/html-validator --save-dev
bash
 yarn add @nuxtjs/html-validator --dev
bash
 pnpm i -D @nuxtjs/html-validator
bash
 bun install @nuxtjs/html-validator --save-dev
bash

js
ts
const a = 2;
js
const a: number = 2;
ts

  • Github Alert

Note

Highlights information that users should take into account, even when skimming.

Tip

Optional information to help a user be more successful.

Important

Crucial information necessary for users to succeed.

Warning

Critical content demanding immediate user attention due to potential risks.

Caution

Negative potential consequences of an action.

  • Mention

HUNGHG255

  • Katex
equation description
B=0\nabla \cdot \vec{\mathbf{B}} = 0 divergence of B\vec{\mathbf{B}} is zero
×E+1cBt=0\nabla \times \vec{\mathbf{E}}\, +\, \frac1c\, \frac{\partial\vec{\mathbf{B}}}{\partial t} = \vec{\mathbf{0}} curl of E\vec{\mathbf{E}} is proportional to the rate of change of B\vec{\mathbf{B}}
×B1cEt=4πcjE=4πρ\nabla \times \vec{\mathbf{B}} -\, \frac1c\, \frac{\partial\vec{\mathbf{E}}}{\partial t} = \frac{4\pi}{c}\vec{\mathbf{j}} \nabla \cdot \vec{\mathbf{E}} = 4 \pi \rho wha?

x3+y3=z3x^3 + y^3 = z^3

1313=1\frac{\bcancel{\frac13}}{\bcancel{\frac13}} = 1

(a+b)2=(a+b)(a+b)=a2+ab+ba+b2=a2+2ab+b2\begin{aligned} (a+b)^2 &= (a+b)(a+b) \\ &= a^2 + ab + ba + b^2 \\ &= a^2 + 2ab + b^2 \end{aligned}

21+21+21\cfrac{2}{1+\cfrac{2}{1+\cfrac{2}{1}}}

P    QP\implies Q

a+<b>+ca + \lt b\gt + c

k=1nak\sum\nolimits_{k=1}^n a_k

ab+cd+ef+gh\frac ab + {\scriptscriptstyle \frac cd + \frac ef} + \frac gh

1<i<31j<5aij\sum_{ \substack{ 1\lt i\lt 3 \\ 1\le j\lt 5 }} a_{ij}

x++xn times\underbrace{x + \cdots + x}_{n\rm\ times}

(a+bcd)\left(\vcenter{\frac{a+b}{\dfrac{c}{d}}}\right)

x+5y=0x+\xcancel{5y}=0

abcdefghi\def\arraystretch{1.5} \begin{array}{c:c:c} a & b & c \\ \hline d & e & f \\ \hdashline g & h & i \end{array}

  • Mermaid
sequenceDiagram
    box Local
    participant Working Directory
    participant Staging Area
    participant Local Repo
    end
    box Remote
    participant Remote Repo
    end
    Working Directory->>Staging Area: git add
    Staging Area->>Local Repo: git commit
    Local Repo->>Remote Repo: git push
    Remote Repo->>Local Repo: git fetch
    Local Repo->>Working Directory: git merge
    Remote Repo->>Working Directory: git pull
    Remote Repo->>Local Repo: git clone
    Local Repo->>Working Directory: git checkout
  • Twoslash
blog.ts
import const MarkdownIt: MarkdownItConstructor

Main parser/renderer class.

Usage
// node.js, "classic" way:
var MarkdownIt = require('markdown-it'),
    md = new MarkdownIt();
var result = md.render('# markdown-it rulezz!');

// node.js, the same, but with sugar:
var md = require('markdown-it')();
var result = md.render('# markdown-it rulezz!');

// browser without AMD, added to "window" on script load
// Note, there are no dash.
var md = window.markdownit();
var result = md.render('# markdown-it rulezz!');

Single line rendering, without paragraph wrap:

var md = require('markdown-it')();
var result = md.renderInline('__markdown-it__ rulezz!');
Example
// commonmark mode
var md = require('markdown-it')('commonmark');

// default mode
var md = require('markdown-it')();

// enable everything
var md = require('markdown-it')({
  html: true,
  linkify: true,
  typographer: true
});
Syntax highlighting
var hljs = require('highlight.js') // https://highlightjs.org/

var md = require('markdown-it')({
  highlight: function (str, lang) {
    if (lang && hljs.getLanguage(lang)) {
      try {
        return hljs.highlight(lang, str, true).value;
      } catch (__) {}
    }

    return ''; // use external default escaping
  }
});

Or with full wrapper override (if you need assign class to <pre>):

var hljs = require('highlight.js') // https://highlightjs.org/

// Actual default values
var md = require('markdown-it')({
  highlight: function (str, lang) {
    if (lang && hljs.getLanguage(lang)) {
      try {
        return '<pre class="hljs"><code>' +
               hljs.highlight(lang, str, true).value +
               '</code></pre>';
      } catch (__) {}
    }

    return '<pre class="hljs"><code>' + md.utils.escapeHtml(str) + '</code></pre>';
  }
});
MarkdownIt
from 'markdown-it';
var console: Consoleconsole.Console.log(...data: any[]): voidlog(1); var console: Consoleconsole.
Console.log(...data: any[]): void
log
(2);
ts
blog.ts
import { function getHighlighterCore(options?: HighlighterCoreOptions): Promise<HighlighterCore>

Create a Shiki core highlighter instance, with no languages or themes bundled. Wasm and each language and theme must be loaded manually.

getHighlighterCore
} from '@shikijs/core';
const const highlighter: HighlighterCorehighlighter = await function getHighlighterCore(options?: HighlighterCoreOptions | undefined): Promise<HighlighterCore>

Create a Shiki core highlighter instance, with no languages or themes bundled. Wasm and each language and theme must be loaded manually.

getHighlighterCore
({});
import { function transformerTwoslash(options?: VitePressPluginTwoslashOptions): ShikiTransformer export transformerTwoslash

Create a Shiki transformer for VitePress to enable twoslash integration

Add this to markdown.codeTransformers in .vitepress/config.ts

transformerTwoslash
as function transformerTwoslashVue(options?: VitePressPluginTwoslashOptions): ShikiTransformer

Create a Shiki transformer for VitePress to enable twoslash integration

Add this to markdown.codeTransformers in .vitepress/config.ts

transformerTwoslashVue
} from '@shikijs/vitepress-twoslash';
import { function rendererRich(options?: RendererRichOptions): TwoslashRenderer

An alternative renderer that providers better prefixed class names, with syntax highlight for the info text.

rendererRich
, function transformerTwoslash(options?: TransformerTwoslashIndexOptions): _shikijs_core_dist_chunk_tokens_mjs.A

Factory function to create a Shiki transformer for twoslash integrations.

transformerTwoslash
} from '@shikijs/twoslash';
function transformerTwoslash(options?: TransformerTwoslashIndexOptions | undefined): ShikiTransformer

Factory function to create a Shiki transformer for twoslash integrations.

transformerTwoslash
({
TransformerTwoslashOptions.renderer?: TwoslashRenderer | undefined

Custom renderers to decide how each info should be rendered

renderer
: function rendererRich(options?: RendererRichOptions | undefined): TwoslashRenderer

An alternative renderer that providers better prefixed class names, with syntax highlight for the info text.

rendererRich
(), // <--
TransformerTwoslashOptions.explicitTrigger?: boolean | RegExp | undefined

Requires twoslash to be presented in the code block meta to apply this transformer

@defaultfalse
explicitTrigger
: true, // <--
}); import { function transformerNotationDiff(options?: TransformerNotationDiffOptions): ShikiTransformer

Use [!code ++] and [!code --] to mark added and removed lines.

transformerNotationDiff
,
// ... } from '@shikijs/transformers'; const const code: "console.log('hello')"code = `console.log('hello')`;
ts
var Number: NumberConstructor

An object that represents a number of any kind. All JavaScript numbers are 64-bit floating-point numbers.

Number
.p
  • parseFloat
  • parseInt
  • prototype
NumberConstructor.parseInt(string: string, radix?: number | undefined): number

Converts A string to an integer.

@paramstring A string to convert into a number.@paramradix A value between 2 and 36 that specifies the base of the number in string. If this argument is not supplied, strings with a prefix of '0x' are considered hexadecimal. All other strings are considered decimal.
arseInt
('123', 10);
ts
const const obj: {
    boo: number;
    bar: () => number;
    baz: string;
}obj = {
  boo: numberboo: 1,
  bar: () => numberbar: () => 2,
  baz: stringbaz: 'string',
};
const obj: {
    boo: number;
    bar: () => number;
    baz: string;
}obj.b
  • bar
  • baz
  • boo
boo: numberoo;
ts
const str: string = 1;
Type 'number' is not assignable to type 'string'.
str = 'Hello';
Cannot assign to 'str' because it is a constant.
ts
const const a: 1a = 1;
Custom log message
const const b: 1b = 1;
Custom error message
const const c: 1c = 1;
Custom warning message
const const d: 1d = 1;
Custom annotation message
ts
  • Block space
function block() {
  space();
  if (true) {
    table();
  }
}
ts
  • Word highlight
export function foo() {
  const msg = 'Hello World';
  console.log(msg); // prints Hello World
}
ts
const options = { foo: 'bar' };
options.foo = 'baz';
console.log(options.foo); // this one will not be highlighted
ts

#Mention