@nrsk/shikigami
TypeScript icon, indicating that this package has built-in type declarations

1.2.1 • Public • Published

式神 shikigami

Build/Test Coverage NPM Supported Node Versions Semantic Release

Opinionated syntax highlighting with shiki for markdown-it.

Example of rendered code

Installation

Just use your favorite package manager.

npm i @nrsk/shikigami

This package comes both in CommonJS and ESM flavors. No additional steps required, just import or require it.

Usage

Note

No styles provided by default, so you need to style everything yourself, using classes described below. There's an example of CSS here using Tailwind.

Warning

Most likely this plugin is incompatible with other plugins that process fenced code blocks, e.g. markdown-it-attrs, which can be used to assign classes to elements and has similar syntax.

This package exposes a function named shikigami, which is a Promise, that resolves to a markdown-it plugin function. Hence, you must await it (or use .then syntax), and only then pass the resulting function to markdown-it.

Below is an example of usage.

import { shikigami, loadTheme } from '@nrsk/shikigami'
import md from 'markdown-it'

async function processMarkdown(input) {
  const parser = md('commonmark').use(
    await shikigami({
      withLanguage: true,
      withLineNumbers: true,
      highlightInvert: true,
      highlighter: {
        // All other shiki's highlighter options are available as well,
        // so you can load additional languages and so on.
        theme: await loadTheme('./theme/custom.json')
      }
    })
  )

  return parser.render(input)
}

Markdown syntax

This plugin introduces a simple syntax extension for fenced code blocks, that allows you to change plugin options in-place. Options defined this way have precedence over plugin options.

# Example

```typescript {{ <option>: <value>, <option>: <value>, ... }}
interface User {
  id: number
  firstName: string
  lastName: string
  role: string
}
```

Options

List of options that can be passed to shikigami function. Options allowed to be used directly in Markdown through syntax extension are marked accordingly.

openToken?: string

  • Default: {{
  • Allowed in Markdown: no

Use this option to change the opening token for extended Markdown syntax.

closeToken?: string

  • Default: }}
  • Allowed in Markdown: no

Use this option to change the closing token for extended Markdown syntax.

withLanguage?: boolean

  • Default: false
  • Allowed in Markdown: yes

Set to true to allow rendering a sibling <div> with a language-<languageId> class. This is useful when you want to show the language specified in your fenced code block.

withLineNumbers?: boolean

  • Default: false
  • Allowed in Markdown: yes

Set to true to render line numbers.

highlight?: Array<number | Array<number>>

  • Default: []
  • Allowed in Markdown: yes

Use this option to specify which lines or ranges of lines should be marked with specified highlighting class (or classes). These classes can be customized via highlightClasses and highlightRangeClasses options.

Examples

  • Highlight lines 5 and 7:

    {{ highlight: [5, 7] }}
    
  • Highlight lines 5, 7, and lines in range from 10 to 15:

    {{ highlight: [5, 7, [10, 15]] }}
    

highlightClasses?: Array<string>

  • Default: ['highlight']
  • Allowed in Markdown: no

Use this option to customize classes for highlighted lines.

highlightRangeClasses?: HighlightRangeClasses

  • Default: ['highlight-start', 'highlight-inner', 'highlight-end']
  • Allowed in Markdown: no

Use this option to customize classes for highlighted ranges. Must be a tuple of exactly three elements.

Explanation

  • The first class is assigned to the first line of a range.
  • The second class is assigned to all lines between the first and the last line of a range. This only applied if the range covers 3 and more lines.
  • The third class is assigned to the last line of a range.

Is this overkill? Probably...

highlightInvert?: boolean

  • Default: false
  • Allowed in Markdown: yes

Set to true to allow marking lines that are not highlighted with specified classes. These classes can be customised via highlightInvertClasses.

Note: this will work only if highlight option is set to a non-empty array of lines.

highlightInvertClasses?: Array<string>

  • Default: ['highlight-invert']
  • Allowed in Markdown: no

Use this option to customize classes for unhighlighted lines.

highlighter?: HighlighterOptions

  • Default: {}
  • Allowed in Markdown: no

Highlighter options which will be passed right into shiki's getHighlighter. See shiki documentation for available options.

API

Besides exposing the shikigami function, this plugin re-exports shiki's loadTheme just for convenience.

shikigami(userOptions?: ShikigamiOptions): Promise<PluginSimple>

Plugin factory function that resolves to a markdown-it plugin.

import { shikigami } from '@nrsk/shikigami'
import anchor from 'markdown-it-anchor'
import md from 'markdown-it'

async function processMarkdown(input) {
  return md('commonmark')
    .use(
      await shikigami({
        /** Plugin options. */
      })
    )
    .use(anchor)
    .render(input)
}

loadTheme(themePath: string): Promise<IShikiTheme>

Shiki's theme loader.

Todo

  • [ ] Tests.
  • [ ] Diffs support.

License

MIT.

Package Sidebar

Install

npm i @nrsk/shikigami

Weekly Downloads

1

Version

1.2.1

License

MIT

Unpacked Size

78.2 kB

Total Files

9

Last publish

Collaborators

  • norskeld