1.0.0-alpha.6 • Published 4 months ago

antora-shiki-extension v1.0.0-alpha.6

Weekly downloads
-
License
MPL-2.0
Repository
github
Last release
4 months ago

Antora Shiki Extension

NPM version

Features

full-feature

This extension wants to make it easier to use Shiki in Antora projects. It offers the following features:

FeatureDescription
Build-time renderingWhen Antora renders the site it will already have the syntax highlighted code blocks. No javascript needed on client.
Full Shiki SupportAll Shiki Languages and Shiki Themes are supported.
Adds Asciidoc grammar to ShikiShiki does not offer an Asciidoc grammar. This extension adds the Asciidoc grammar to Shiki which is used by the Asciidoctor VS Code Extension.
Supports custom grammar for ShikiIt is possible to register your own grammar files for languages.
Multi-Theme SupportYou can define a different theme for each page or even multiple themes on one page.
Line NumberingYou can enable line numbering for each code block or for all pages by supporting the line number capabilities of Asciidoctor
Dynamic Line Number colorDepending on the used background color of the theme the line number color will be adjusted to be better readable.

Why Shiki instead of Highlight.js?

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.

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:

$ npm i antora-shiki-extension

Usage

Register the extension

After installing the shiki extension package, you need to register the 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.

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

antora-playbook.yml

antora:
  extensions:
    - '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

antora:
  extensions:
  - require: 'antora-vscode-extension'

asciidoc:
  attributes:
    source-highlighter: shiki

You may want to start with this syntax so you don’t have to remember to switch to it later when you want to specify configuration.

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

<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

<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.

Configuration

Minimal extension configuration

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

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 keyDetails
themeDefault: nord Set the default theme that should be used when no theme is defined on the asciidoc pages.
themesDefault: [] 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.
languagesDefault: ["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_languagesDefault: [] 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

### Default usage with default theme: nord

**Antora Playbook**

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

nord-default

Change default theme to darcula in Antora playbook

Antora Playbook

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

Result

dracula-default

Change theme on page level

Antora Playbook

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

Page level theme definition

= Page Title
:shiki-theme: dracula

Result

dracula-default

Change theme on single source block

Antora Playbook

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

Source Block theme definition


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

Result

dracula-single-block

Enable line numbers on source block

Antora Playbook

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

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

Result

linenumbers

Enable line numbers on specific page

Antora Playbook

antora:
  extensions:
    - require: 'antora-shiki-extension'
= Page Title
:shiki-line-numbers: true

Result

linenumbers

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

Enable line numbers on all pages

Antora Playbook

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

Disable line numbers on single source block

Antora Playbook

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

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

Result

nord-default

Disable line numbers on specific page

= Page Title
:shiki-line-numbers: false

Line numbers with specific beginning

Antora Playbook

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

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

Result

linenumbers-start

More informations

Acknowledgements

  • antora-lunr-extension that helped me to understand how to write an Antora extension and offered me a lot of inspiration.
  • Shiki project for their great work
  • Shiki PR that describes how create line numbers via css.

Trademarks

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