15 KiB
template |
---|
overrides/main.html |
Code blocks
Code blocks and examples are an essential part of technical project documentation. Material for MkDocs provides different ways to set up syntax highlighting for code blocks, either during build time using Pygments or during runtime using a JavaScript syntax highlighter.
Configuration
Highlight
:octicons-file-code-24: Source · :octicons-workflow-24: Extension · :octicons-zap-24: Supersedes: CodeHilite
The Highlight extension, which is part of Python Markdown Extensions, integrates with Material for MkDocs and provides several options for configuring syntax highlighting of code blocks:
use_pygments
{ #use-pygments }-
:octicons-milestone-24: Default:
true
– This option allows to control whether highlighting should be carried out during build time by Pygments or runtime with a JavaScript highlighter. Remember to add the necessary additional stylesheets and JavaScript if you want to use the latter:=== "Pygments"
``` yaml markdown_extensions: - pymdownx.highlight - pymdownx.superfences ```
=== "JavaScript"
``` yaml markdown_extensions: - pymdownx.highlight: use_pygments: false ```
??? example "Syntax highlighting with Highlight.js"
[Highlight.js][8] can be integrated by creating an [additional JavaScript][7] file initializing the highlighter and including the respective stylesheet and JavaScript from a [CDN][9] serving Highlight.js in `mkdocs.yml`: === "docs/javascripts/config.js" ``` js document$.subscribe(() => { hljs.highlightAll() }) ``` === "mkdocs.yml" ``` yaml extra_javascript: - https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.7.2/highlight.min.js - javascripts/config.js extra_css: - https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.7.2/styles/default.min.css ``` Note that Highlight.js has no affiliation with the Highlight extension.
linenums
{ #linenums }-
:octicons-milestone-24: Default:
false
– This option will add line numbers to all code blocks. If you wish to add line numbers to some, but not all code blocks, consult the section on adding line numbers later in this document, which also contains some tips on working with line numbers:markdown_extensions: - pymdownx.highlight: linenums: true
linenums_style
{ #linenums-style }-
:octicons-milestone-24: Default:
table
– The Highlight extension provides three ways to add line numbers, all of which are supported by Material for MkDocs. Whiletable
wraps a code block in a table,inline
andpymdownx-inline
render line numbers as part of the line itself:markdown_extensions: - pymdownx.highlight: linenums_style: pymdownx-inline
Note that
inline
will put line numbers next to the actual code, which means that they will be included when selecting text with the cursor or copying a code block to the clipboard. Thus, the usage oftable
orpymdownx-inline
is recommended.
Material for MkDocs doesn't provide official support for the other options of this extension, so they may be supported but might yield unexpected results. Use them at your own risk.
InlineHilite
:octicons-file-code-24: Source · :octicons-workflow-24: Extension
The InlineHilite extension, which is part of Python Markdown
Extensions also integrates with Material for MkDocs and adds support for
syntax highlighting of inline code blocks. It's built on top of the
Highlight extension and can be enabled via mkdocs.yml
:
markdown_extensions:
- pymdownx.inlinehilite
See the section on inline code blocks for usage information.
Keys
:octicons-file-code-24: Source · :octicons-workflow-24: Extension
The Keys extension, which is part of Python Markdown Extensions,
allows for inserting keyboard keys, e.g. ++ctrl+alt+delete++ , and
can be enabled via mkdocs.yml
:
markdown_extensions:
- pymdownx.keys
SuperFences
The SuperFences extension, which is also part of Python Markdown Extensions, allows for the nesting of code blocks inside other blocks, and is therefore strongly recommended:
markdown_extensions:
- pymdownx.superfences
Snippets
The Snippets extension, which is also part of Python Markdown
Extensions, allows to insert content from other files or other, regular
content, and can be enabled via mkdocs.yml
:
markdown_extensions:
- pymdownx.snippets
Usage
This section discusses how to use different syntax highlighting features with Pygments – the default highlighter – so they don't apply when using a JavaScript syntax highlighter.
Specifying the language
Code blocks must be enclosed with two separate lines containing three backticks. To add code highlighting to those blocks, add the language short name directly after the opening block. See the list of available lexers to find the short name for a given language.
Example:
``` python
import tensorflow as tf
```
Result:
import tensorflow as tf
Adding annotations
:octicons-file-code-24: Source · :octicons-beaker-24: Experimental · :octicons-heart-fill-24:{ .mdx-heart } Insiders only{ .mdx-insiders }
Annotations offer a comfortable and friendly way to attach explanations to
arbitrary sections of code blocks by adding simple markers within block/inline
comments that refer to items of a list following the code block, i.e. (1)
,
(2)
, etc. Material for MkDocs detaches the list from the flow of the document,
injects the content of each list item into a tooltip, and links each list marker
to the corresponding tooltip.
In order to opt-in to annotation support, a slightly different syntax is
required – just add the respective language short code and the .annotate
class, after the three backticks.
Note that annotations can be placed anywhere in a code block where a comment
for the language can be placed, which for JavaScript is // (1)
and
/* (2) */
, for Yaml # (3)
, etc.
Example:
``` { .js .annotate }
document$.subscribe(function() { // (1)
var tables = document.querySelectorAll(/* (2) */ "article table")
tables.forEach(function(table) {
new Tablesort(table)
})
})
```
1. ...
2. ...
Result:
document$.subscribe(function() { // (1)
var tables = document.querySelectorAll(/* (2) */ "article table")
tables.forEach(function(table) {
new Tablesort(table) // (3)
})
})
-
Annotations can contain arbitrary content which is shown when the marker is focussed, including any kind of formatting, links, admonitions, details, and even diagrams:
graph LR A[I'm] --> B{a} --> C[diagram];
:octicons-light-bulb-16: Tip: You can use ++tab++ to navigate annotations.
-
Annotations can be placed anywhere in a code block were a comment for the underlying language can be placed.
=== "Python"
``` python # (1) ```
=== "JavaScript"
``` js // (2) /* (2) */ ```
=== "Lua"
``` lua -- (3) ```
We're working on a solution for languages without comments, which will be available shortly.
-
Of course, this can be combined with line numbers, highlighting and all other code block related features.
Annotations require syntax highlighting with Pygments – they're currently not compatible with other JavaScript-based syntax highlighters. Support may be added later on.
Adding line numbers
Line numbers can be added to a code block by using the linenums="<start>"
option directly after the short name, whereas <start>
represents the starting
line number. A code block can start from a line number other than 1
, which
allows splitting large code blocks for readability.
Example:
``` python linenums="1"
def bubble_sort(items):
for i in range(len(items)):
for j in range(len(items) - 1 - i):
if items[j] > items[j + 1]:
items[j], items[j + 1] = items[j + 1], items[j]
```
Result:
def bubble_sort(items):
for i in range(len(items)):
for j in range(len(items) - 1 - i):
if items[j] > items[j + 1]:
items[j], items[j + 1] = items[j + 1], items[j]
Highlighting specific lines
Specific lines can be highlighted by passing the line numbers to the hl_lines
argument placed right after the language short name. Note that line counts start
at 1
, regardless of the starting line number specified as part of linenums
.
Example:
``` python hl_lines="2 3"
def bubble_sort(items):
for i in range(len(items)):
for j in range(len(items) - 1 - i):
if items[j] > items[j + 1]:
items[j], items[j + 1] = items[j + 1], items[j]
```
Result:
def bubble_sort(items):
for i in range(len(items)):
for j in range(len(items) - 1 - i):
if items[j] > items[j + 1]:
items[j], items[j + 1] = items[j + 1], items[j]
Highlighting inline code blocks
When InlineHilite is enabled, inline code blocks can be highlighted by
prefixing them with a shebang-like sequence, i.e. #!
, directly followed by
the language short name.
Example:
The `#!python range()` function is used to generate a sequence of numbers.
Result:
The #!python range()
function is used to generate a sequence of numbers.
Adding keyboard keys
When Keys is enabled, keyboard keys can be rendered with a simple syntax. Consult the Python Markdown Extensions documentation to learn about all available key codes.
Example:
++ctrl+alt+del++
Result:
++ctrl+alt+del++
Embedding external files
Also known as transcludes or file transclusion in MultiMarkdown.
When Snippets is enabled, content from other files can be embedded, which is especially useful to reference and embed the contents of source files directly into your project documentation.
Example:
```
--8<-- ".browserslistrc"
```
Result:
last 4 years
Note that Snippets is not limited to code blocks, but can be used anywhere from a document to move repeating content to separate files, which is also explained in the official documentation.
Customization
Custom syntax theme
:octicons-file-code-24: Source · :octicons-mortar-board-24: Difficulty: easy
If Pygments is used, Material for MkDocs provides the styles for code blocks, which are built with a custom and well-balanced palette that works equally well for both color schemes:
- :material-checkbox-blank-circle:{ style="color: var(--md-code-hl-number-color) " }
--md-code-hl-number-color
- :material-checkbox-blank-circle:{ style="color: var(--md-code-hl-special-color) " }
--md-code-hl-special-color
- :material-checkbox-blank-circle:{ style="color: var(--md-code-hl-function-color) " }
--md-code-hl-function-color
- :material-checkbox-blank-circle:{ style="color: var(--md-code-hl-constant-color) " }
--md-code-hl-constant-color
- :material-checkbox-blank-circle:{ style="color: var(--md-code-hl-keyword-color) " }
--md-code-hl-keyword-color
- :material-checkbox-blank-circle:{ style="color: var(--md-code-hl-string-color) " }
--md-code-hl-string-color
- :material-checkbox-blank-circle:{ style="color: var(--md-code-hl-name-color) " }
--md-code-hl-name-color
- :material-checkbox-blank-circle:{ style="color: var(--md-code-hl-operator-color) " }
--md-code-hl-operator-color
- :material-checkbox-blank-circle:{ style="color: var(--md-code-hl-punctuation-color) " }
--md-code-hl-punctuation-color
- :material-checkbox-blank-circle:{ style="color: var(--md-code-hl-comment-color) " }
--md-code-hl-comment-color
- :material-checkbox-blank-circle:{ style="color: var(--md-code-hl-generic-color) " }
--md-code-hl-generic-color
- :material-checkbox-blank-circle:{ style="color: var(--md-code-hl-variable-color) " }
--md-code-hl-variable-color
Code block foreground, background and line highlight colors are defined via:
- :material-checkbox-blank-circle:{ style="color: var(--md-code-fg-color) " }
--md-code-fg-color
- :material-checkbox-blank-circle:{ style="color: var(--md-code-bg-color) " }
--md-code-bg-color
- :material-checkbox-blank-circle:{ style="color: var(--md-code-hl-color) " }
--md-code-hl-color
Let's say you want to change the color of #!js "strings"
. While there are
several types of string tokens, Material for MkDocs assigns a single color
to most of them.
Create an additional stylesheet, and add:
:root > * {
--md-code-hl-string-color: #0FF1CE;
}
If you want to tweak a specific type of string, i.e. #!js `backticks`
, you
can lookup the specific class name in the syntax theme definition, and
override it as part of your additional stylesheet:
.highlight .sb {
color: #0FF1CE;
}