Reveal.js writer: add idiomatic highlight.js support.

Closes #11420.

When using `--syntax-highlighting=idiomatic` with reveal.js output,
pandoc now generates HTML compatible with reveal.js's built-in
highlight.js plugin:

- Code blocks use `<pre><code class="language-X">` format
- The template loads highlight.js CSS, JS, and RevealHighlight plugin
- Theme defaults to "monokai", configurable via `highlightjs-theme`
   variable

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
John MacFarlane
2026-01-25 13:17:12 +00:00
parent d62fa112c1
commit f0991cfcbb
4 changed files with 70 additions and 18 deletions
+7
View File
@@ -2968,6 +2968,13 @@ pandoc](#slide-shows).
: additional attributes for the title slide of reveal.js slide shows.
See [background in reveal.js, beamer, and pptx] for an example.
`highlightjs-theme`
: highlight.js theme for code highlighting when using
`--syntax-highlighting=idiomatic` with reveal.js (defaults to
`monokai`). See the [highlight.js demo page] for available themes.
[highlight.js demo page]: https://highlightjs.org/demo
All [reveal.js configuration options] are available as variables.
To turn off boolean flags that default to true in reveal.js, use `0`.
+9
View File
@@ -29,6 +29,9 @@ $if(theme)$
$else$
<link rel="stylesheet" href="$revealjs-url$/dist/theme/black.css" id="theme">
$endif$
$if(highlight-js)$
<link rel="stylesheet" href="$revealjs-url$/plugin/highlight/$highlightjs-theme$.css">
$endif$
$for(css)$
<link rel="stylesheet" href="$css$"/>
$endfor$
@@ -87,6 +90,9 @@ $body$
$if(mathjax)$
<script src="$revealjs-url$/plugin/math/math.js"></script>
$endif$
$if(highlight-js)$
<script src="$revealjs-url$/plugin/highlight/highlight.js"></script>
$endif$
<script>
@@ -320,6 +326,9 @@ $endif$
plugins: [
$if(mathjax)$
RevealMath,
$endif$
$if(highlight-js)$
RevealHighlight,
$endif$
RevealNotes,
RevealSearch,
+39 -18
View File
@@ -437,7 +437,13 @@ pandocToHtml opts (Pandoc meta blocks) = do
defField "scrollProgress" True .
defField "scrollActivationWidth" ("0" :: Doc Text) .
defField "scrollSnap" ("mandatory" :: Doc Text) .
defField "scrollLayout" ("full" :: Doc Text)
defField "scrollLayout" ("full" :: Doc Text) .
(case writerHighlightMethod opts of
IdiomaticHighlighting
| slideVariant == RevealJsSlides ->
defField "highlight-js" True .
defField "highlightjs-theme" ("monokai" :: Doc Text)
_ -> id)
else id) .
defField "document-css" (isNothing mCss && slideVariant == NoSlides) .
defField "quotes" (stQuotes st) .
@@ -941,6 +947,7 @@ blockToHtmlInner _ HorizontalRule = do
return $ if html5 then H5.hr else H.hr
blockToHtmlInner opts (CodeBlock (id',classes,keyvals) rawCode) = do
html5 <- gets stHtml5
slideVariant <- gets stSlideVariant
id'' <- if T.null id'
then do
modify $ \st -> st{ stCodeBlockNum = stCodeBlockNum st + 1 }
@@ -958,23 +965,37 @@ blockToHtmlInner opts (CodeBlock (id',classes,keyvals) rawCode) = do
adjCode = if tolhs
then T.unlines . map ("> " <>) . T.lines $ rawCode
else rawCode
highlighted = highlight (writerSyntaxMap opts)
(if html5 then formatHtmlBlock else formatHtml4Block)
(id'',classes',keyvals) adjCode
hlCode = case writerHighlightMethod opts of
Skylighting _ -> highlighted
DefaultHighlighting -> highlighted
_ -> Left ""
case hlCode of
Left msg -> do
unless (T.null msg) $
report $ CouldNotHighlight msg
addAttrs opts (id',classes,keyvals)
$ H.pre $ H.code $ toHtml adjCode
Right h -> modify (\st -> st{ stHighlighting = True }) >>
-- we set writerIdentifierPrefix to "" since id'' already
-- includes it:
addAttrs opts{writerIdentifierPrefix = ""} (id'',[],keyvals) h
isIdiomaticRevealJs = slideVariant == RevealJsSlides &&
writerHighlightMethod opts == IdiomaticHighlighting
if isIdiomaticRevealJs
then do
-- For idiomatic reveal.js highlighting, put attributes on <code>
-- with language- prefix, and let highlight.js do the highlighting.
modify (\st -> st{ stHighlighting = True })
let (langClasses, otherClasses) = case classes' of
(lang:rest) -> (["language-" <> lang], rest)
[] -> ([], [])
codeAttrs = (id', langClasses ++ otherClasses, keyvals)
codeTag <- addAttrs opts codeAttrs $ H.code $ toHtml adjCode
return $ H.pre codeTag
else do
let highlighted = highlight (writerSyntaxMap opts)
(if html5 then formatHtmlBlock else formatHtml4Block)
(id'',classes',keyvals) adjCode
hlCode = case writerHighlightMethod opts of
Skylighting _ -> highlighted
DefaultHighlighting -> highlighted
_ -> Left ""
case hlCode of
Left msg -> do
unless (T.null msg) $
report $ CouldNotHighlight msg
addAttrs opts (id',classes,keyvals)
$ H.pre $ H.code $ toHtml adjCode
Right h -> modify (\st -> st{ stHighlighting = True }) >>
-- we set writerIdentifierPrefix to "" since id'' already
-- includes it:
addAttrs opts{writerIdentifierPrefix = ""} (id'',[],keyvals) h
blockToHtmlInner opts (BlockQuote blocks) = do
-- in S5, treat list in blockquote specially
-- if default is incremental, make it nonincremental;
+15
View File
@@ -0,0 +1,15 @@
````
% pandoc -t revealjs --syntax-highlighting=idiomatic
# Slide
```python
def hello():
print("Hello")
```
^D
<section id="slide" class="slide level1">
<h1>Slide</h1>
<pre><code class="language-python">def hello():
print(&quot;Hello&quot;)</code></pre>
</section>
````