How to Add Syntax Highlighting Support for New Languages in Quarkdown HTML
To add syntax highlighting for a new language in Quarkdown HTML, create a custom TypeScript entry file that registers the desired language with Highlight.js, then reconfigure the bundleHighlightJs Gradle task in quarkdown-html/build.gradle.kts to bundle this entry instead of the default common languages.
Quarkdown is a Markdown-based typesetting system that generates static HTML documents. By default, it ships with a subset of Highlight.js language definitions bundled at build time. To support additional languages—such as Dart, Crystal, or VHDL—you must extend this bundle by creating a custom entry point that explicitly imports and registers the language modules you need.
How Quarkdown Renders Code Blocks
The HTML rendering pipeline relies on two key components in the quarkdown-html module. First, BaseHtmlNodeRenderer.kt (lines 138-140) applies a CSS class to <code> elements based on the language specified in the document:
node.language?.let { "language-$it" }
Second, ThirdPartyLibrary.kt (lines 40-52) declares that Highlight.js should be injected whenever the document contains code blocks. The actual language definitions reside in a pre-built JavaScript file generated by the bundleHighlightJs task in build.gradle.kts (lines 78-102). By default, this task consumes highlight.js/lib/common.js, which contains only the most popular languages. To extend support, you must replace this input with a custom entry file.
Step 1: Create a Custom Highlight.js Entry File
Create a new TypeScript file at quarkdown-html/src/main/typescript/highlight-bundle.ts. This file imports the Highlight.js core, registers your specific language, and exports the configured instance:
// highlight-bundle.ts – custom entry point for the Highlight.js bundle
import hljs from "highlight.js/lib/core";
// Import the language definition you need (e.g., Dart)
import dart from "highlight.js/lib/languages/dart";
// Register it under the name you will use in Quarkdown
hljs.registerLanguage("dart", dart);
// You can register additional languages here
// import elixir from "highlight.js/lib/languages/elixir";
// hljs.registerLanguage("elixir", elixir);
export default hljs;
The string passed to registerLanguage (e.g., "dart") must exactly match the identifier you intend to use in your Quarkdown documents.
Step 2: Modify the Gradle Bundling Task
Update the bundleHighlightJs task in quarkdown-html/build.gradle.kts to use your custom entry file as the bundling source instead of the default common.js:
val bundleHighlightJs =
tasks.register<NpxTask>("bundleHighlightJs") {
group = "build"
description = "Bundles Highlight.js (including custom languages) into a single browser‑ready file"
dependsOn(tasks.npmInstall)
// Input is now our TypeScript entry file
inputs.file(projectDir.resolve("src/main/typescript/highlight-bundle.ts"))
outputs.file(nodeModules.resolve("highlight.js/dist/highlightjs.min.js"))
command.set("esbuild")
args.set(
listOf(
"src/main/typescript/highlight-bundle.ts", // <-- custom entry
"--bundle",
"--platform=browser",
"--format=iife",
"--global-name=hljs",
"--minify",
"--outfile=${nodeModules.resolve("highlight.js/dist/highlightjs.min.js")}",
)
)
}
This configuration uses esbuild to tree-shake and minify the Highlight.js core along with your registered language modules into a single file at highlight.js/dist/highlightjs.min.js.
Step 3: Build and Use the New Language
Rebuild the specific module to generate the updated JavaScript bundle:
./gradlew :quarkdown-html:bundleHighlightJs
Alternatively, run a full build:
./gradlew installDist
Once built, reference the language in your Quarkdown source using standard Markdown fenced code blocks:
```dart
void main() {
print('Hello, Quarkdown!');
}
Or using the Quarkdown function syntax:
```markdown
.code language:{dart}
void main() {
print('Hello, Quarkdown!');
}
The rendered HTML will contain <code class="hljs language-dart">, and the runtime script (code-highlighter.ts) will apply syntax highlighting when hljs.highlightAll() executes.
Summary
- Quarkdown generates HTML code blocks with a
language-<lang>class that Highlight.js consumes. - To add syntax highlighting support for new languages, create a TypeScript entry file that imports
highlight.js/lib/core, registers your language withhljs.registerLanguage(), and exports the instance. - Update
quarkdown-html/build.gradle.ktsto point thebundleHighlightJstask to your custom entry file instead ofhighlight.js/lib/common.js. - Rebuild with
./gradlew :quarkdown-html:bundleHighlightJsto produce the updatedhighlightjs.min.js. - Use the exact language identifier in Quarkdown documents via standard Markdown fences or the
.code language:{identifier}function.
Frequently Asked Questions
Can I add multiple languages to the same bundle?
Yes. You can import and register as many languages as needed within your highlight-bundle.ts file. Each call to hljs.registerLanguage() adds that language to the final bundle, making it available for use in any code block throughout your Quarkdown documents without increasing the number of HTTP requests.
Do I need to modify the Kotlin source code to support a new language?
No. The Kotlin rendering logic in BaseHtmlNodeRenderer.kt and ThirdPartyLibrary.kt is language-agnostic. It dynamically generates the language-<lang> class based on your document content. As long as the language is registered in the JavaScript bundle and the identifier matches, the highlighting will work without changes to the JVM code.
Why is my code block not highlighting after rebuilding?
First, verify that the language identifier in your Quarkdown document exactly matches the string used in hljs.registerLanguage() (case-sensitive). Second, confirm that you rebuilt the project after modifying build.gradle.kts so the new highlightjs.min.js is generated. Finally, check that the generated HTML contains the correct class structure (hljs language-<lang>) and that no browser console errors indicate a bundling failure.
Where is the final Highlight.js bundle located after building?
The bundleHighlightJs task writes the output to node_modules/highlight.js/dist/highlightjs.min.js within the quarkdown-html module. When you run ./gradlew installDist, this file is typically copied to build/install/lib/highlight.js/highlightjs.min.js in your distribution directory, where it is served as a static asset for HTML rendering.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →