# antora-shiki-extension

> An antora extension to use shiki as a build-time syntax highligher.

Latest version **1.0.0** (published 2025-02-23) · MPL-2.0 license · 0 weekly downloads

## Install

```sh
npm install antora-shiki-extension
pnpm add antora-shiki-extension
yarn add antora-shiki-extension
bun add antora-shiki-extension
```

## Health

**Score 30/100 (F)** — status: maintenance-mode.

Positive: esm support; no vulnerabilities.

Warnings: low downloads; no types.

Negative: stale; low maintenance score.

## Facts

| | |
|---|---|
| Version | 1.0.0 |
| Published | 2025-02-23 |
| First published | 2024-01-06 |
| Weekly downloads | 0 |
| License | MPL-2.0 |
| TypeScript types | none |
| Module format | ESM + CommonJS |
| Node | >=16.0.0 |
| Dependencies | 7 |
| Unpacked size | 234.9 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 11 |
| Author | Lasse Knudsen |
| Maintainers | lask79 |
| Keywords | antora, shiki, extension, highliging, syntax highligher |

## Links

- npm: https://www.npmjs.com/package/antora-shiki-extension
- Repository: https://github.com/lask79/antora-shiki-extension
- Homepage: https://github.com/lask79/antora-shiki-extension#readme
- Issues: https://github.com/lask79/antora-shiki-extension/issues
- npm.io page: https://npm.io/package/antora-shiki-extension

## Dependencies (7)

- [jsdom](https://npm.io/package/jsdom.md) ~17.0
- [shiki](https://npm.io/package/shiki.md) 0.14.7
- [browserify](https://npm.io/package/browserify.md) ~17.0.0
- [handlebars](https://npm.io/package/handlebars.md) ^4.7.8
- [browser-pack-flat](https://npm.io/package/browser-pack-flat.md) ~3.4
- [@browserify/uglifyify](https://npm.io/package/@browserify/uglifyify.md) ~6.0.0
- [asciidoctor-external-callout](https://npm.io/package/asciidoctor-external-callout.md) ^1.2.1

## Alternatives

- [@oh-my-pi/pi-natives](https://npm.io/package/@oh-my-pi/pi-natives.md) — 51.8K weekly downloads
- [@capgo/capacitor-light-sensor](https://npm.io/package/@capgo/capacitor-light-sensor.md) — 3.0K weekly downloads
- [@heyhuynhgiabuu/pi-diff](https://npm.io/package/@heyhuynhgiabuu/pi-diff.md) — 492 weekly downloads
- [@lotsa/verdant-lang-asm](https://npm.io/package/@lotsa/verdant-lang-asm.md) — 38 weekly downloads
- [new-era-syntax](https://npm.io/package/new-era-syntax.md) — 20 weekly downloads

## Recent versions

- 1.0.0 (latest) — 2025-02-23
- 1.0.0-alpha.6 — 2024-01-14
- 1.0.0-alpha.5 — 2024-01-07
- 1.0.0-alpha.4 — 2024-01-06
- 1.0.0-alpha.3 — 2024-01-06
- 1.0.0-alpha.2 — 2024-01-06
- 1.0.0-alpha.1 — 2024-01-06

## README

# Antora Shiki Extension

![NPM version](docs/modules/ROOT/images/https://img.shields.io/npm/v/antora-shiki-extension.svg)

## Features

![full-feature](docs/modules/ROOT/images/full-feature.png)

This extension wants to make it easier to use [Shiki](https://github.com/shikijs/shiki/) in [Antora](https://docs.antora.org/antora/3.1) projects. It offers the following features:

| Feature | Description |
| --- | --- |
| Build-time rendering | When `Antora` renders the site it will already have the syntax highlighted code blocks. No javascript needed on client. |
| Full Shiki Support | All [Shiki Languages](https://github.com/shikijs/shiki/blob/main/docs/languages.md) and [Shiki Themes](https://github.com/shikijs/shiki/blob/main/docs/themes.md) are supported. |
| Adds Asciidoc grammar to Shiki | Shiki does not offer an Asciidoc grammar. This extension adds the Asciidoc grammar to Shiki which is used by the [Asciidoctor VS Code Extension](https://github.com/asciidoctor/asciidoctor-vscode). |
| Supports custom grammar for Shiki | It is possible to register your own grammar files for languages. |
| Multi-Theme Support | You can define a different theme for each page or even multiple themes on one page. |
| Line Numbering | You can enable line numbering for each code block or for all pages by supporting the line number capabilities of [Asciidoctor](https://docs.asciidoctor.org/asciidoc/latest/verbatim/source-highlighter/#enable-line-numbering) |
| Dynamic Line Number color | Depending on the used background color of the theme the line number color will be adjusted to be better readable. |
| Customizable Callout Styling | Customize the appearance of callouts (conums) with theme-aware colors and optional borders. Colors automatically adjust based on the theme’s background for optimal readability. |

## Why Shiki instead of Highlight.js?

[Shiki](https://github.com/shikijs/shiki/) is a syntax highlighter powered by the same language grammars used in Visual Studio Code, ensuring accurate and consistent code coloring.
It offers a wide range of themes and can tokenize code in any language that VS Code supports, making it highly versatile. Unlike many highlighters, Shiki pre-processes code into colored HTML at build time, offering improved performance and consistency across different environments.

**Benefits**

* **Accurate Syntax Highlighting**: Shiki uses the same language grammars as Visual Studio Code, ensuring highly accurate and consistent syntax highlighting.
* **Build-Time Rendering**: Shiki processes code into colored HTML at build time, which can improve page load performance and ensures consistent rendering across different browsers and environments.
* **Wide Range of Themes**: Shiki supports a broad array of themes directly from Visual Studio Code, offering more variety and customization options.
* **Consistent with VS Code**: Developers familiar with Visual Studio Code will find Shiki’s highlighting consistent with their development environment, making it easier to integrate into documentation or blogs.
* **Extensive Language Support**: Shiki can tokenize code in any language supported by VS Code, offering extensive language support.
* **Minimal Client-Side Processing**: Since Shiki does the heavy lifting at build time, there is minimal processing required on the client-side, leading to better performance especially on less powerful devices.

**📌 NOTE**\
At the moment only Shiki in version 0.14.1 is supported. 
We have to evaluate if the newer Shiki versions can be used as well.

## Prerequisites

In order to use this extension, you must be using at least Node.js 16 and Antora 3.
We assume you’ve already set up an Antora playbook file (i.e., _antora-playbook.yml_) to build your site.

## Installation

Begin by installing the extension package into your [playbook project](https://docs.antora.org/antora/3.1/playbook/use-an-existing-playbook-project/):

```console
$ npm i antora-shiki-extension
```

## Usage

### Register the extension

After installing the shiki extension package, you need to [register the extension](https://docs.antora.org/antora/3.1/extend/register-extension/) with Antora.

To register the extension, you’ll add an entry that cites the name of the package to the `antora.extensions` key in your [Antora playbook file](https://docs.antora.org/antora/3.1/playbook/).

Open the Antora playbook file and add the extension as follows:

**antora-playbook.yml**

```yaml
antora:
  extensions:
    - require: 'antora-shiki-extension' #<1>

asciidoc:
  attributes:
    source-highlighter: shiki #<2>
```
1. Register the antora extension
2. Set the source-highlighter to shiki

In order to specify configuration keys for the extension, you must change the entry to a map syntax.
When using the map syntax, the package name must be preceded by the `require` key, as shown here:

**antora-playbook.yml**

```yaml
antora:
  extensions:
  - require: 'antora-shiki-extension'

asciidoc:
  attributes:
    source-highlighter: shiki
```

### Configuration Options

The extension supports the following configuration options:

| Option | Default | Description |
| --- | --- | --- |
| theme | nord | The default theme to use for syntax highlighting |
| themes | [] | Additional themes to load |
| languages | [asciidoc, java, js, shell, bash, console, zsh, yaml, xml, diff] | Languages to support |
| use_line_numbers | false | Enable line numbers globally |
| conums_override | true | Enable custom styling for callouts (conums) |
| conums_bg_color | auto | Background color for callouts. If not specified, uses a dimmed version of the theme’s foreground color |
| conums_fg_color | auto | Foreground color for callouts. If not specified, automatically chooses black or white based on background brightness |
| conums_show_border | false | Whether to show a border around callouts |

#### Callout Styling

When `conums_override` is enabled (default), the extension provides theme-aware callout styling:

* By default, callouts use a background color derived from the theme’s foreground color
* The text color is automatically chosen to ensure readability
* Borders are disabled by default but can be enabled with `conums_show_border: true`
* You can override both background and foreground colors using `conums_bg_color` and `conums_fg_color`

Example configuration with custom colors:

```yaml
antora:
  extensions:
    - require: 'antora-shiki-extension'
      conums_override: true             # Enable custom styling
      conums_bg_color: '#4a5568'        # Dark slate background
      conums_fg_color: '#ffffff'        # White text
      conums_show_border: true          # Show borders
```

**📌 NOTE**\
If you simply want to use the callout style defined in your custom antora css please simply set `conums_override` to false.

### Add handlebars templates

You have to change 1 file in your Antora UI bundle or by overwriting it via supplemental-ui:

* add `{{> shiki-styles }}` to `partials/head-styles.hbs`

#### Add to head-styles.hbs

**head-styles.hbs**

```html
<link rel="stylesheet" href="{{{uiRootPath}}}/css/site.css">
{{> shiki-styles }}
```

`{{> shiki-styles }}` will be replaced with the content of the file `shiki-styles.hbs` that provided by this extension.

**shiki-styles.hbs**

```html
<link rel="stylesheet" href="{{{uiRootPath}}}/css/shiki.css">
```

The `shiki.css` file contains some shiki specific styles that are needed to render the code blocks correctly and overrides some styles defined in the [Antora UI Default](https://docs.antora.org/antora-ui-default/).

## Configuration

**Minimal extension configuration**

```yaml
antora:
  extensions:
    - require: 'antora-shiki-extension'
      # theme: nord
      # themes: []
      # languages: ["asciidoc", "bash", "console", "diff", "java", "js", "shell", "yaml", "xml", "zsh"]
      # use_line_numbers: false
```

**Full extension configuration**

```yaml
antora:
  extensions:
    - require: "antora-shiki-extension"
      theme: "darcula" # default: "nord"
      themes: ["material-theme", "dracula", "slack-dark", "github-light"] # default: []
      languages: # default: see this list
        - bash
        - console
        - diff
        - java
        - js
        - shell
      register_languages: # default: []
        - id: 'xml'
          scope_name: 'text.xml'
          grammar_path: ./relative-path-to-grammar-file
          alias: ['xml']
      use_line_numbers: true # default: false
```

### Overview

| Configuration key | Details |
| --- | --- |
| theme | Default: `nord` Set the default theme that should be used when no theme is defined on the asciidoc pages. |
| themes | Default: [] Defines all themes that should be loaded into the highlighter. Those can then be used on the asciidoc pages by defining the `shiki-theme` attribute. |
| languages | Default: `["asciidoc", "bash", "console", "diff", "java", "js", "shell", "yaml", "xml", "zsh"]` Defines which languages are known to `shiki`. NOTE: The id of the registered language must not be put into the `languages` array. The languages list is for defining the default languages provided by shiki. The `register_languages` array is for adding additional languages. |
| register_languages | Default: `[]` Defines an array of additional languages that should be registered to `shiki`. The array must contain objects with the following keys: id:: The id of the language scope_name:: The scope name of the language (see grammar file) grammar_path:: The path to the grammar file (relative to the playbook) alias (optional):: An array of aliases for the language (see grammar file or add additional) .Example |
```
- id: 'xml'
  scope_name: 'text.xml'
  grammar_path: ./relative-path-to-grammar-file
  alias: ['xml']
` NOTE: The id of the registered language must not be put into the `languages` array. The languages list is for defining the default languages provided by shiki. The `register_languages` array is for adding additional languages. |
| use_line_numbers | Default: `false` If set to true it will always use line numbers for all code blocks. You can also enable line numbers for each code block. Check [here](https://docs.asciidoctor.org/asciidoc/latest/verbatim/source-highlighter/#enable-line-numbering). |

### Examples

## How it works

### Process

The extension is called by Antora during the build process. It will then do the following steps:

* validate the configuration
* create the asciidoctor syntax highlighter for shiki and register it
* pass the extension context (logger, config, etc.) to the asciidoctor syntax highlighter
* copy the shiki.css to the uiCatalog
* copy the shiki-styles.hbs to the uiCatalog
* renders each asciidoc page with source blocks (ShikiSyntaxHighlighter)
  * calculate the current theme based on the page attributes (`shiki-theme`) and the configuration
  * generate the html code for the source block by using the shiki highligher
  * get the background color from the used theme
  * calculate if line numbers should be used
  * calculate the line number color based on the background color
  * remove the generated surrounding `<pre><code>` elements
  * create new `<pre><code>` elements with the calculated background color and the generated html code
    * sets css variables on &lt;pre>: `--shiki-background-color`

## Use Cases

The following use cases will be shown:

* Default usage with default theme: `nord`
* Change default theme to `darcula` in `Antora` playbook
* Change theme on page level
* Change theme on single source block
* Enable line numbers on source block
* Enable line numbers on specific page
* Enable line numbers on all pages
* Line numbers with specific beginning
* Disable line numbers on single source block
* Disable line numbers on specific page
* Use custom CSS styling for callouts
* Use theme-aware callout colors with border
* Use custom callout colors
* Use dark theme callout colors

### Use custom CSS styling for callouts

**Antora Playbook**

```yaml
antora:
  extensions:
    - require: 'antora-shiki-extension'
      conums_override: false          # Use your custom CSS styling
```

### Use theme-aware callout colors with border

**Antora Playbook**

```yaml
antora:
  extensions:
    - require: 'antora-shiki-extension'
      conums_show_border: true        # Add borders to callouts
```

### Use custom callout colors

**Antora Playbook**

```yaml
antora:
  extensions:
    - require: 'antora-shiki-extension'
      conums_bg_color: '#2563eb'      # Blue background
      conums_fg_color: '#ffffff'      # White text
```

### Use dark theme callout colors

**Antora Playbook**

```yaml
antora:
  extensions:
    - require: 'antora-shiki-extension'
      conums_bg_color: '#1e293b'      # Dark slate background
      conums_fg_color: '#94a3b8'      # Light gray text
      conums_show_border: true        # Add subtle border
```

### Default usage with default theme: nord

**Antora Playbook**

```yaml
antora:
  extensions:
    - require: 'antora-shiki-extension'
```

![nord-default](docs/modules/ROOT/images/nord-default.png)

### Change default theme to `darcula` in `Antora` playbook

**Antora Playbook**

```yaml
antora:
  extensions:
    - require: 'antora-shiki-extension'
      theme: 'dracula'
```

**Result**

![dracula-default](docs/modules/ROOT/images/dracula-default.png)

### Change theme on page level

**Antora Playbook**

```yaml
antora:
  extensions:
    - require: 'antora-shiki-extension'
```

**Page level theme definition**

```asciidoc
= Page Title
:shiki-theme: dracula
```

**Result**

![dracula-default](docs/modules/ROOT/images/dracula-default.png)

### Change theme on single source block

**Antora Playbook**

```yaml
antora:
  extensions:
    - require: 'antora-shiki-extension'
```

**Source Block theme definition**

-------
```javascript
function helloWorld() {
  console.log('Hello World');
}
```
-------

**Result**

![dracula-single-block](docs/modules/ROOT/images/dracula-single-block.png)

### Enable line numbers on source block

**Antora Playbook**

```yaml
antora:
  extensions:
    - require: 'antora-shiki-extension'
```

-------
```javascript
function helloWorld() {
  console.log('Hello World');
}
```
-------

**Result**

![linenumbers](docs/modules/ROOT/images/linenumbers.png)

### Enable line numbers on specific page

**Antora Playbook**

```yaml
antora:
  extensions:
    - require: 'antora-shiki-extension'
```

```asciidoc
= Page Title
:shiki-line-numbers: true
```

**Result**

![linenumbers](docs/modules/ROOT/images/linenumbers.png)

You can also unset it via `!shiki-line-numbers:` like the theme.

### Enable line numbers on all pages

**Antora Playbook**

```yaml
antora:
  extensions:
    - require: 'antora-shiki-extension'
      use_line_numbers: true
```

### Disable line numbers on single source block

**Antora Playbook**

```yaml
antora:
  extensions:
    - require: 'antora-shiki-extension'
      use_line_numbers: true
```

-------
```javascript
function helloWorld() {
  console.log('Hello World');
}
```
-------

**Result**

![nord-default](docs/modules/ROOT/images/nord-default.png)

### Disable line numbers on specific page

```asciidoc
= Page Title
:shiki-line-numbers: false
```

### Line numbers with specific beginning

**Antora Playbook**

```yaml
antora:
  extensions:
    - require: 'antora-shiki-extension'
```

-------
```javascript
function helloWorld() {
  console.log('Hello World');
}
```
-------

**Result**

![linenumbers-start](docs/modules/ROOT/images/linenumbers-start.png)

## More informations

* [Playground for Shiki Themes](https://shiki-play.matsu.io/play). Please check it out if you want to know what is possible.

## Acknowledgements

* [antora-lunr-extension](https://gitlab.com/antora/antora-lunr-extension) that helped me to understand how to write an Antora extension and offered me a lot of inspiration.
* [Shiki](https://github.com/shikijs/shiki/) project for their great work
* [Shiki PR](https://github.com/shikijs/shiki/issues/3) that describes how create line numbers via css.

## Trademarks

AsciiDoc(R) is a trademark of the Eclipse Foundation, Inc.

---
_Source: https://npm.io/package/antora-shiki-extension · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
