• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1title: CodeHilite Extension
2
3# CodeHilite
4
5## Summary
6
7The CodeHilite extension adds code/syntax highlighting to standard
8Python-Markdown code blocks using [Pygments][].
9
10[Pygments]: http://pygments.org/
11
12This extension is included in the standard Markdown library.
13
14## Setup
15
16### Step 1: Download and Install Pygments
17
18You will also need to [download][dl] and install the Pygments package on your
19`PYTHONPATH`. The CodeHilite extension will produce HTML output without
20Pygments, but it won't highlight anything (same behavior as setting
21`use_pygments` to `False`).
22
23[dl]: http://pygments.org/download/
24
25### Step 2: Add CSS Classes
26
27You will need to define the appropriate CSS classes with appropriate rules.
28The CSS rules either need to be defined in or linked from the header of your
29HTML templates. Pygments can generate CSS rules for you. Just run the following
30command from the command line:
31
32```bash
33pygmentize -S default -f html -a .codehilite > styles.css
34```
35
36If you are using a different `css_class` (default: `.codehilite`), then
37set the value of the `-a` option to that class name. The CSS rules will be
38written to the `styles.css` file which you can copy to your site and link from
39your HTML templates.
40
41If you would like to use a different theme, swap out `default` for the desired
42theme. For a list of themes installed on your system (additional themes can be
43installed via Pygments plugins), run the following command:
44
45```bash
46pygmentize -L style
47```
48
49See Pygments' excellent [documentation] for more details. If no language is
50defined, Pygments will attempt to guess the language. When that fails, the code
51block will not be highlighted.
52
53!!! seealso "See Also"
54
55    GitHub user [richeland] has provided a number of different [CSS style
56    sheets][rich] which work with Pygments along with a [preview] of each theme.
57    The `css_class` used is `.highlight`. Therefore, one would need to override the
58    [`css_class`](#css_class) option when using richeland's CSS styles. However, the
59    Python-Markdown project makes no guarantee that richeland's CSS styles will
60    work with the version of Pygments you are using. To ensure complete
61    compatibility, you should generate the CSS rules from your own installation
62    of Pygments.
63
64[richeland]: https://github.com/richleland
65[rich]: https://github.com/richleland/pygments-css
66[preview]: https://richleland.github.io/pygments-css/
67[documentation]: http://pygments.org/docs/
68
69## Syntax
70
71The CodeHilite extension follows the same [syntax][] as regular Markdown code
72blocks, with one exception. The highlighter needs to know what language to use for
73the code block. There are three ways to tell the highlighter what language the
74code block contains and each one has a different result.
75
76!!! Note
77    The format of the language identifier only effects the display of line numbers
78    if `linenums` is set to `None` (the default). If set to `True` or `False`
79    (see [Usage](#usage) below) the format of the identifier has no effect on the
80    display of line numbers -- it only serves as a means to define the language
81    of the code block.
82
83[syntax]: https://daringfireball.net/projects/markdown/syntax#precode
84
85### Shebang (with path)
86
87If the first line of the code block contains a shebang, the language is derived
88from that and line numbers are used.
89
90```md
91    #!/usr/bin/python
92    # Code goes here ...
93```
94
95Will result in:
96
97    #!/usr/bin/python
98    # Code goes here ...
99
100### Shebang (no path)
101
102If the first line contains a shebang, but the shebang line does not contain a
103path (a single `/` or even a space), then that line is removed from the code
104block before processing. Line numbers are used.
105
106```md
107    #!python
108    # Code goes here ...
109```
110
111Will result in:
112
113    #!python
114    # Code goes here ...
115
116### Colons
117
118If the first line begins with three or more colons, the text following the
119colons identifies the language. The first line is removed from the code block
120before processing and line numbers are not used.
121
122```md
123    :::python
124    # Code goes here ...
125```
126
127Will result in:
128
129    :::python
130    # Code goes here ...
131
132Certain lines can be selected for emphasis with the colon syntax. When
133using Pygments' default CSS styles, emphasized lines have a yellow background.
134This is useful to direct the reader's attention to specific lines.
135
136```md
137    :::python hl_lines="1 3"
138    # This line is emphasized
139    # This line isn't
140    # This line is emphasized
141```
142
143Will result in:
144
145    :::python hl_lines="1 3"
146    # This line is emphasized
147    # This line isn't
148    # This line is emphasized
149
150!!! Note
151    `hl_lines` is named for Pygments' option meaning "highlighted lines".
152
153### When No Language is Defined
154
155CodeHilite is completely backwards compatible so that if a code block is
156encountered that does not define a language, the block is simply wrapped in
157`<pre>` tags and output.
158
159```md
160    # Code goes here ...
161```
162
163Will result in:
164
165    # Code goes here ...
166
167Lets see the source for that:
168
169```html
170<div class="codehilite"><pre><code># Code goes here ...
171</code></pre></div>
172```
173
174!!! Note
175    When no language is defined, the Pygments highlighting engine will try to guess
176    the language (unless `guess_lang` is set to `False`). Upon failure, the same
177    behavior will happen as described above.
178
179## Usage
180
181See [Extensions](index.md) for general extension usage. Use `codehilite` as the
182name of the extension.
183
184See the [Library Reference](../reference.md#extensions) for information about
185configuring extensions.
186
187The following options are provided to configure the output:
188
189* **`linenums`**{ #linenums }:
190    An alias to Pygments' `linenos` formatter option. Possible values are `True` for yes, `False` for no and `None`
191    for auto. Defaults to `None`.
192
193    Using `True` will force every code block to have line numbers, even when
194    using colons (`:::`) for language identification.
195
196    Using `False` will turn off all line numbers, even when using shebangs
197    (`#!`) for language identification.
198
199* **`guess_lang`**{ #guess_lang }:
200    Automatic language detection. Defaults to `True`.
201
202    Using `False` will prevent Pygments from guessing the language, and thus
203    highlighting blocks only when you explicitly set the language.
204
205* **`css_class`**{ #css_class }:
206    An alias to Pygments `cssclass` formatter option. Set CSS class name for the wrapper `<div>` tag. Defaults to
207    `codehilite`.
208
209* **`pygments_style`**{ #pygments_style }:
210    Pygments HTML Formatter Style (`ColorScheme`). Defaults to `default`.
211
212    !!! Note
213        This is useful only when `noclasses` is set to `True`, otherwise the
214        CSS styles must be provided by the end user.
215
216* **`noclasses`**{ #noclasses }:
217    Use inline styles instead of CSS classes. Defaults to `False`.
218
219* **`use_pygments`**{ #use_pygments }:
220    Specifies the use of Pygments in generating the output.
221
222    If `True` (the default) and Pygments is available, CodeHilite will use
223    Pygments to analyze and format the output. Additionally, if using Pygments
224    &gt;= 2.4, the output will be wrapped in `<code>` tags, whereas earlier
225    versions will not.
226
227    Otherwise, Pygments will not be used. If a language is defined for a code block, it will be assigned to the
228    `<code>` tag as a class in the manner suggested by the [HTML5 spec][spec] and may be used by a JavaScript library
229    in the browser to highlight the code block. See the [`lang_prefix`](#lang_prefix) option to customize the prefix.
230
231* **`lang_prefix`**{ #lang_prefix }:
232    The prefix prepended to the language class assigned to the HTML `<code>` tag. Default: `language-`.
233
234* **`pygments_formatter`**{ #pygments_formatter }:
235    This option can be used to change the Pygments formatter used for highlighting code blocks. By default, this
236    is set to the string `'html'`, which means it'll use the default `HtmlFormatter` provided by Pygments.
237
238    This can be set to a string representing any of the other default formatters, or set to a formatter class (or
239    any callable).
240
241    The code's language is always passed to the formatter as an extra option `lang_str`, with the value formatted as
242    `{lang_prefix}{lang}`. If the language is unspecified, the language guessed by Pygments will be used. While
243    this option has no effect to the Pygments's builtin formatters, a user can make use of the language in their custom
244    formatter. See an example below.
245
246    To see what formatters are available and how to subclass an existing formatter, please visit [Pygments
247    documentation on this topic][pygments formatters].
248
249* Any other Pygments' options:
250
251    All other options are accepted and passed on to Pygments' lexer and formatter. Therefore,
252    valid options include any options which are accepted by the [html formatter] or
253    whichever [lexer] the code's language uses. Invalid options are ignored without error.
254
255A trivial example:
256
257```python
258markdown.markdown(some_text, extensions=['codehilite'])
259```
260
261To keep the code block's language in the Pygments generated HTML output, one can provide a custom Pygments formatter
262that takes the `lang_str` option. For example,
263
264```python
265from pygments.formatters import HtmlFormatter
266from markdown.extensions.codehilite import CodeHiliteExtension
267
268
269class CustomHtmlFormatter(HtmlFormatter):
270    def __init__(self, lang_str='', **options):
271        super().__init__(**options)
272        # lang_str has the value {lang_prefix}{lang}
273        # specified by the CodeHilite's options
274        self.lang_str = lang_str
275
276    def _wrap_code(self, source):
277        yield 0, f'<code class="{self.lang_str}">'
278        yield from source
279        yield 0, '</code>'
280
281
282some_text = '''\
283    :::python
284    print('hellow world')
285'''
286
287markdown.markdown(
288    some_text,
289    extensions=[CodeHiliteExtension(pygments_formatter=CustomHtmlFormatter)],
290)
291```
292
293The formatter above will output the following HTML structure for a code block:
294
295```html
296<div class="codehilite">
297    <pre>
298        <code class="language-python">
299        ...
300        </code>
301    </pre>
302</div>
303```
304
305[html formatter]: https://pygments.org/docs/formatters/#HtmlFormatter
306[lexer]: https://pygments.org/docs/lexers/
307[spec]: https://www.w3.org/TR/html5/text-level-semantics.html#the-code-element
308[pygments formatters]: https://pygments.org/docs/formatters/
309