# 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¶

This configuration enables syntax highlighting on code blocks and inline code blocks, and allows to include source code directly from other files. Add the following lines to mkdocs.yml:

markdown_extensions:
- pymdownx.highlight:
anchor_linenums: true
- pymdownx.inlinehilite
- pymdownx.snippets
- pymdownx.superfences


The following sections discuss how to use different syntax highlighting features with Pygments, the recommended highlighter, so they don't apply when using a JavaScript syntax highlighter.

### Code annotations¶

8.0.0 · Feature flag · Experimental

Code annotations offer a comfortable and friendly way to attach arbitrary content to specific sections of code blocks by adding numeric markers in block and inline comments in the language of the code block. Add the following to mkdocs.yml to enable them globally:

theme:
features:
- content.code.annotate # (1)!

1. I'm a code annotation! I can contain code, formatted text, images, ... basically anything that can be written in Markdown.
Enabling code annotations for a specific code block

If you don't want to enable code annotations globally, because you don't like the automatic inlining behavior, you can enable them for a specific code block by using a slightly different syntax based on the Attribute Lists extension:

 { .yaml .annotate }
# Code block content



Note that the language shortcode which has to come first must now also be prefixed by a ..

Insiders · insiders-4.4.0 · Experimental

In order to link to code annotations and share them more easily, Insiders adds an anchor link to each annotation automatically, which you can copy via right click or open in a new tab:

# (1)!

1. If you Cmd me, I'm rendered open in a new tab. You can also right-click me to copy link address to share me with others.

## Usage¶

Code blocks must be enclosed with two separate lines containing three backticks. To add syntax highlighting to those blocks, add the language shortcode directly after the opening block. See the list of available lexers to find the shortcode for a given language:

Code block
 py
import tensorflow as tf


import tensorflow as tf


7.3.6 · Experimental

In order to provide additional context, a custom title can be added to a code block by using the title="<custom title>" option directly after the shortcode, e.g. to display the name of a file:

Code block with title
 py title="bubble_sort.py"
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]


bubble_sort.py
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]


Code annotations can be placed anywhere in a code block where a comment for the language of the block can be placed, e.g. for JavaScript in #!js // ... and #!js /* ... */, for YAML in #!yaml # ..., etc.1:

Code block with annotation
 yaml
theme:
features:
- content.code.annotate # (1)


1.  :man_raising_hand: I'm a code annotation! I can contain code, __formatted
text__, images, ... basically anything that can be written in Markdown.

theme:
features:
- content.code.annotate # (1)

1. I'm a code annotation! I can contain code, formatted text, images, ... basically anything that can be written in Markdown.

Insiders · insiders-4.4.0 · Experimental

If you wish to strip the comment characters surrounding a code annotation, Insiders adds a new syntax that allows for just that. Simply add an ! after the closing parens of the code annotation:

Code block with annotation, stripped
 yaml
# (1)!


1.  Look ma, less line noise!

# (1)!

1. Look ma, less line noise!

Note that this only allows for a single code annotation to be rendered per comment. If you want to add multiple code annotations, comments cannot be stripped for technical reasons.

Line numbers can be added to a code block by using the linenums="<start>" option directly after the shortcode, whereas <start> represents the starting line number. A code block can start from a line number other than 1, which allows to split large code blocks for readability:

Code block with line numbers
 py 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]


 1 2 3 4 5 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 shortcode. Note that line counts start at 1, regardless of the starting line number specified as part of linenums:

Code block with highlighted lines
 py 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]


 1 2 3 4 5 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, syntax highlighting can be applied to inline code blocks by prefixing them with a shebang, i.e. #!, directly followed by the corresponding language shortcode.

Inline code block
The #!python range() function is used to generate a sequence of numbers.


The #!python range() function is used to generate a sequence of numbers.

### Embedding external files¶

When Snippets is enabled, content from other files (including source files) can be embedded by using the --8<-- notation directly from within a code block:

Code block with external content
 title=".browserslistrc"
--8<--​ ".browserslistrc"


.browserslistrc
last 4 years


## Customization¶

### Custom syntax theme¶

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:

• --md-code-hl-number-color
• --md-code-hl-special-color
• --md-code-hl-function-color
• --md-code-hl-constant-color
• --md-code-hl-keyword-color
• --md-code-hl-string-color
• --md-code-hl-name-color
• --md-code-hl-operator-color
• --md-code-hl-punctuation-color
• --md-code-hl-comment-color
• --md-code-hl-generic-color
• --md-code-hl-variable-color

Code block foreground, background and line highlight colors are defined via:

• --md-code-fg-color
• --md-code-bg-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, they use the same color. You can assign a new color by using an additional style sheet:

:root > * {
--md-code-hl-string-color: #0FF1CE;
}

extra_css:
- stylesheets/extra.css


If you want to tweak a specific type of string, e.g. #!js backticks, you can lookup the specific CSS class name in the syntax theme definition, and override it as part of your additional style sheet:

.highlight .sb {
color: #0FF1CE;
}

extra_css:
- stylesheets/extra.css


### Annotation tooltip width¶

If you have a lot of content hosted inside your code annotations, it can be a good idea to increase the width of the tooltip by adding the following as part of an additional style sheet:

:root {
--md-tooltip-width: 600px;
}

extra_css:
- stylesheets/extra.css


This will render annotations with a larger width:

# (1)!

1. Muuuuuuuuuuuuuuuch more space for content

### Annotations with numbers¶

Prior to 8.1.0, code annotations were rendered with markers showing the original number as used by the author. However, for technical reasons code annotation numbers restart each code block, which might lead to confusion. For this reason, code annotations now render as + signs which are rotated if they're open to denote that clicking them again will close them.

If you wish to revert to the prior behavior and display code annotation numbers, you can add an additional style sheet and copy and paste the following CSS:

.md-typeset .md-annotation__index > ::before {
content: attr(data-md-annotation-id);
}
.md-typeset :focus-within > .md-annotation__index > ::before {
transform: none;
}

extra_css:
- stylesheets/extra.css


1. Code annotations require syntax highlighting with Pygments – they're currently not compatible with JavaScript syntax highlighters, or languages that do not have comments in their grammar. However, we're actively working on supporting alternate ways of defining code annotations, allowing to always place code annotations at the end of lines.