`preload-js` for custom highlightjs/ace support
Author: dalanceCreated Sep 4, 2026Updated Sep 4, 2026
LabelsC-enhancement
Problem
This is a part of #3124.
Now there is no way to override highlightjs/ace language without theme override. About custom highlightjs, some issues had been opened previously (ex. #2505, #657, #1459), but this issue aims for a complete resolution of both highlightjs and ace.
If this issue is resolved, user can easily add custom language playground by the way of #3124.
Proposed Solution
- add
preload-jsfield tobook.toml - change load order and insert
preload-js
+ <script src="{{ resource "highlight.js" }}"></script>
{{#if playground_js}}
<script src="{{ resource "ace.js" }}"></script>
<script src="{{ resource "mode-rust.js" }}"></script>
+ {{/if}}
+
+ {{#each preload_js}}
+ <script src="{{ resource this }}"></script>
+ {{/each}}
+
+ {{#if playground_js}}
<script src="{{ resource "editor.js" }}"></script>
<script src="{{ resource "theme-dawn.js" }}"></script>
<script src="{{ resource "theme-tomorrow_night.js" }}"></script>
@@
<script src="{{ resource "clipboard.min.js" }}"></script>
- <script src="{{ resource "highlight.js" }}"></script>
<script src="{{ resource "book.js" }}"></script>
- change ace mode by
language
+ function playground_mode(editable) {
+ const cls = Array.from(editable.classList)
+ .find(c => c.startsWith("language-"));
+ return cls ? "ace/mode/" + cls.slice("language-".length)
+ : "ace/mode/rust";
+ }
+
Array.from(document.querySelectorAll('.editable')).forEach(function(editable) {
@@
- editor.getSession().setMode("ace/mode/rust");
+ editor.getSession().setMode(playground_mode(editable));
By this change, user can specify custom language syntax like below, and they are effective because they are load after highlight.js, ace.js and before book.js.
[output.html]
preload-js = ["hljs-example.js", "mode-example.js"]
Notes
No response
Source: rust-lang/mdBook