Skip to content

Commit

Permalink
feat: Add initial support for the ReadTheDocs theme
Browse files Browse the repository at this point in the history
Issue: #107
PR: #159
Co-authored-by: Reece Dunham <me@rdil.rocks>
  • Loading branch information
pawamoy and RDIL committed Dec 6, 2020
1 parent efb68e2 commit 1028115
Show file tree
Hide file tree
Showing 7 changed files with 158 additions and 13 deletions.
55 changes: 54 additions & 1 deletion docs/handlers/python.md
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,8 @@ plugins:

## Recommended style (Material)

Here are some CSS rules for the *Material for MkDocs* theme:
Here are some CSS rules for the
[*Material for MkDocs*](https://squidfunk.github.io/mkdocs-material/) theme:

```css
/* Indentation. */
Expand Down Expand Up @@ -317,3 +318,55 @@ td p {
margin-bottom: 0 !important;
}
```

## Recommended style (ReadTheDocs)

Here are some CSS rules for the built-in *ReadTheDocs* theme:

```css
/* Indentation. */
div.doc-contents:not(.first) {
padding-left: 25px;
border-left: 4px solid rgba(230, 230, 230);
margin-bottom: 60px;
}
/* Don't use vertical space on hidden ToC entries. */
.hidden-toc::before {
margin-top: 0 !important;
padding-top: 0 !important;
}
/* Don't show permalink of hidden ToC entries. */
.hidden-toc a.headerlink {
display: none;
}
/* Avoid breaking parameters name, etc. in table cells. */
td code {
word-break: normal !important;
}
/* For pieces of Markdown rendered in table cells. */
td p {
margin-top: 0 !important;
margin-bottom: 0 !important;
}
/* Avoid breaking code headings. */
.doc-heading code {
white-space: normal;
}
/* Improve rendering of parameters, returns and exceptions. */
.field-name {
min-width: 100px;
}
.field-name, .field-body {
border: none !important;
padding: 0 !important;
}
.field-list {
margin: 0 !important;
}
```
45 changes: 43 additions & 2 deletions src/mkdocstrings/handlers/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"""

import importlib
import re
import textwrap
from abc import ABC, abstractmethod
from pathlib import Path
Expand Down Expand Up @@ -67,10 +68,44 @@ def do_highlight(
result = highlighter.highlight(src=src, language=language, linestart=line_start, inline=inline)

if inline:
return do_mark_safe(result.text)
return do_mark_safe(f'<code class="highlight language-{language}">{result.text}</code>')
return do_mark_safe(result)


def do_js_highlight(
src: str,
guess_lang: bool = False, # noqa: W0613 (we must accept the same parameters as do_highlight)
language: str = None,
inline: bool = False,
dedent: bool = True,
line_nums: bool = False, # noqa: W0613
line_start: int = 1, # noqa: W0613
) -> str:
"""
Prepare a code-snippet for JS highlighting.
This function is used as a filter in Jinja templates.
Arguments:
src: The code to highlight.
guess_lang: Whether to guess the language or not.
language: Explicitly tell what language to use for highlighting.
inline: Whether to do inline highlighting.
dedent: Whether to dedent the code before highlighting it or not.
line_nums: Whether to add line numbers in the result.
line_start: The line number to start with.
Returns:
The code properly wrapped for later highlighting by JavaScript.
"""
if dedent:
src = textwrap.dedent(src)
if inline:
src = re.sub(r"\n\s*", "", src)
return do_mark_safe(f'<code class="highlight">{src}</code>')
return do_mark_safe(f'<div class="highlight {language or ""}"><pre><code>\n{src}\n</code></pre></div>')


def do_any(seq: Sequence, attribute: str = None) -> bool:
"""
Check if at least one of the item in the sequence evaluates to true.
Expand Down Expand Up @@ -129,10 +164,16 @@ def __init__(self, directory: str, theme: str, custom_templates: Optional[str] =
paths.append(themes_dir / self.fallback_theme)

self.env = Environment(autoescape=True, loader=FileSystemLoader(paths)) # type: ignore
self.env.filters["highlight"] = do_highlight
self.env.filters["any"] = do_any
self.env.globals["log"] = get_template_logger()

if theme == "readthedocs":
highlight_function = do_js_highlight
else:
highlight_function = do_highlight

self.env.filters["highlight"] = highlight_function

@abstractmethod
def render(self, data: Any, config: dict) -> str:
"""
Expand Down
8 changes: 3 additions & 5 deletions src/mkdocstrings/templates/python/material/function.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,10 @@
class="doc doc-heading"
data-toc-label="{{ function.name }}()">

<code class="highlight language-python">
{% filter highlight(language="python", inline=True) %}
{% if show_full_path %}{{ function.path }}{% else %}{{ function.name }}{% endif %}
{% filter highlight(language="python", inline=True) %}
{% with signature = function.signature %}{% include "signature.html" with context %}{% endwith %}
{% endfilter %}
</code>
{% with signature = function.signature %}{% include "signature.html" with context %}{% endwith %}
{% endfilter %}

{% with properties = function.properties %}
{% include "properties.html" with context %}
Expand Down
8 changes: 3 additions & 5 deletions src/mkdocstrings/templates/python/material/method.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,10 @@
class="doc doc-heading"
data-toc-label="{{ method.name }}()">

<code class="highlight language-python">
{% filter highlight(language="python", inline=True) %}
{% if show_full_path %}{{ method.path }}{% else %}{{ method.name }}{% endif %}
{% filter highlight(language="python", inline=True) %}
{% with signature = method.signature %}{% include "signature.html" with context %}{% endwith %}
{% endfilter %}
</code>
{% with signature = method.signature %}{% include "signature.html" with context %}{% endwith %}
{% endfilter %}

{% with properties = method.properties %}
{% include "properties.html" with context %}
Expand Down
19 changes: 19 additions & 0 deletions src/mkdocstrings/templates/python/readthedocs/exceptions.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{{ log.debug() }}
<table class="field-list">
<colgroup>
<col class="field-name" />
<col class="field-body" />
</colgroup>
<tbody valign="top">
<tr class="field">
<th class="field-name">Exceptions:</th>
<td class="field-body">
<ul class="first simple">
{% for exception in exceptions %}
<li>{{ ("`" + exception.annotation + "` – " + exception.description)|convert_markdown }}</li>
{% endfor %}
</ul>
</td>
</tr>
</tbody>
</table>
19 changes: 19 additions & 0 deletions src/mkdocstrings/templates/python/readthedocs/parameters.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{{ log.debug() }}
<table class="field-list">
<colgroup>
<col class="field-name" />
<col class="field-body" />
</colgroup>
<tbody valign="top">
<tr class="field">
<th class="field-name">Parameters:</th>
<td class="field-body">
<ul class="first simple">
{% for parameter in parameters %}
<li>{{ ("**" + parameter.name + "** (`" + parameter.annotation + "`) – " + parameter.description)|convert_markdown }}</li>
{% endfor %}
</ul>
</td>
</tr>
</tbody>
</table>
17 changes: 17 additions & 0 deletions src/mkdocstrings/templates/python/readthedocs/return.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{{ log.debug() }}
<table class="field-list">
<colgroup>
<col class="field-name" />
<col class="field-body" />
</colgroup>
<tbody valign="top">
<tr class="field">
<th class="field-name">Returns:</th>
<td class="field-body">
<ul class="first simple">
<li>{{ ("`" + return.annotation + "` – " + return.description)|convert_markdown }}</li>
</ul>
</td>
</tr>
</tbody>
</table>

0 comments on commit 1028115

Please sign in to comment.