Adding Custom Highlight.js Languages to Drupal CodeSnippet

Problem

The current version of the CKEditor Codesnippet plugin ships with a standard version of Highlight.js that has limited language support. Currently, it's also an older version (8.0).

While the Drupal CKEditor CodeSnippet module lets you configure the languages available in the editor codesnippet dropdown, if Highlight.js doesn't actually have the language you choose, then it will make a best-guess and use another language for the syntax highlighting.

So, what if you want to add support for languages that aren't included in that standard package, and you want to keep your composer-based installation?

Solution

Set up CKEditor Codesnippet Plugin for Composer Installation

If you don't already have the CKEditor Codesnippet plugin set up to install via Composer, you should do that first.  Follow the instructions here for drupal-library types, but modify everything for the Codesnippet plugin.

As an example, here's the package definition that I'm using:

{
    "type"    : "package",
    "package" : {
        "name"    : "ckeditor-plugin/codesnippet",
        "version" : "4.11.2",
        "type"    : "drupal-library",
        "dist"    : {
            "url"  : "https://download.ckeditor.com/codesnippet/releases/codesnippet_4.11.2.zip",
            "type" : "zip"
        }
    }
}

Override Highlight.js

The process for overriding Highlight.js is similar to that for installing other 3rd-party libraries, but with some extra steps.

Create & host your custom Highlight.js package

  1. Go to the Highlight.js download page, choose your language set, and download the zip file.
  2. Host that zip file somewhere on the web, or unzip it and put the contents in a repo.  For example, the language package that I'm currently using on my site is on GitHub.  This is required because—as far as I know—it's not possible to get the custom language pack zip file directly from the Highlight.js website with a simple URL; you have to actually submit the form.

Require the composer/installers package

Ensure the composer/installers package is required in your project:

$ composer require composer/installers

Define the custom package in composer.json

As with CKEditor plugins, you need to define a custom package in composer.json that refers to the Highlight.js language pack that you created above.

As an example, here's the package definition in my composer.json. Change the name, type, and url properties as needed for your Highlight.js package.  Or, if you want the same languages that are in mine, you can just use it as-is.

Some notes about the properties:
  • name can be anything that won't cause a conflict with another package.  You will use this value later when you tell Composer to require this package. 
  • type must be an existing Composer installer type, unless you install another Composer plugin.  By default, drupal-library types are installed in the libraries directory, but we'll override the installation directory for this package below.
  • url is the direct URL for retrieving the zip archive file.  For GitHub, you can obtain this value from the Clone or download button.
{
    "type"    : "package",
    "package" : {
        "name"    : "ckeditor-codesnippet-library/highlight",
        "version" : "dev-master",
        "type"    : "drupal-library",
        "dist"  : {
            "url" : "https://github.com/kentr/codesnippet-highlightjs/archive/master.zip",
            "type": "zip"
        }
    }
}

Declare the custom package type and the installation path

In the extras section of your composer.json, override the installation path for this custom package.  See the composer-installers documentation for more information.

For example, if your web files are in the web directory of your project root:

"extra": {
    "installer-paths": {
        "web/libraries/codesnippet/lib/highlight": ["ckeditor-codesnippet-library/highlight"],
    },
}

If you already have other values for installer-paths, prepend the new value to that section.  For example, if you're starting with the default Drupal Composer template, your installer-paths section will end up looking something like this:

"extra": {
    "installer-paths": {
        "web/libraries/codesnippet/lib/highlight": ["ckeditor-codesnippet-library/highlight"],
        "web/core": ["type:drupal-core"],
        "web/libraries/{$name}": ["type:drupal-library"],
        "web/modules/contrib/{$name}": ["type:drupal-module"],
        "web/profiles/contrib/{$name}": ["type:drupal-profile"],
        "web/themes/contrib/{$name}": ["type:drupal-theme"],
        "drush/Commands/{$name}": ["type:drupal-drush"]
    }
}

Tell Composer to require your new custom package

Now that you've defined the package and the installation path, you need to actually require the package in your project in the standard way:

$ composer require ckeditor-codesnippet-library/highlight

Now, composer should overwrite the existing libraries/codesnippet/lib/highlight directory with your custom language pack.

Using the new library

Configure the Drupal CodeSnippet module to enable any of your desired languages that the module offers.  

For D8, see Adding Language Options to Drupal CodeSnippet.

For D7, the CodeSnippet module has instructions for adding more languages to the configuration options.

Even if you don't add new options to the dropdown:  I've found that Highlight.js does a good job of automatically guessing the correct language.  If you leave the dialog selection at "<not set>", it will likely guess correctly.

Add new comment