From d874316382d3413ab4b78c2563754b4b225cc525 Mon Sep 17 00:00:00 2001
From: Brendan <2bndy5@gmail.com>
Date: Tue, 19 Apr 2022 22:12:04 -0700
Subject: [PATCH] More extensions (#60)
* patch literal blocks captions; add result directive
* update docs for results directive
* add task-list directive and keys role
* add experimental button idea
* add in new demo CSS
* pleasing pylint
* ran black on button.py
* partial solution to content tabs in #56
* improve api doc signatures and code block captions
* pleasing stylelint
* pleasing pylint
* polish & remove experimental button.py
- CSS additions consolidated and revised
- result directive (and corresponding CSS)
- various improvements to the docs
* pleasing stylelint
* still pleasing stylelint
* hopefully the last stylelint fix
* [stylelint] WTH is with property ordering in scss
* adjust custon keys' CSS for chrome
* remove button testing CSS
* use descrptive directive name
* use snake casing for docutils node
* move a margin reset to typeset.scss
* review changes to kbd_keys.py
* use plain text for keys role in latex
* simplfy example CSS for custom task-list
* move rst-result CSS to _highlight.scss
* wrap each param in span & style said span
* [no ci] move comment to proper location
* condensed selectors = less deviation from upstream
* set autocrlf to input
* try overriding git global config for this repo
* override config for all files (not by core config)
---
.gitattributes | 10 +
docs/_static/extra_css.css | 42 ++-
docs/additional_samples.rst | 304 ++++++++++--------
docs/admonitions.rst | 155 ++++-----
docs/conf.py | 33 +-
docs/content_tabs.rst | 41 +--
docs/demo_api.rst | 152 +++++----
docs/index.rst | 8 +-
docs/keys.rst | 158 +++++++++
docs/mermaid_diagrams.rst | 121 ++-----
docs/requirements.txt | 1 +
docs/specimen.rst | 25 +-
docs/task_lists.rst | 161 ++++++++++
docs/test_py_module/test.py | 9 +-
sphinx_immaterial/__init__.py | 2 +
sphinx_immaterial/apidoc_formatting.py | 51 +++
sphinx_immaterial/content_tabs.py | 5 +-
sphinx_immaterial/kbd_keys.py | 94 ++++++
sphinx_immaterial/object_toc.py | 2 +-
sphinx_immaterial/task_lists.py | 95 ++++++
sphinx_immaterial/theme_result.py | 53 +++
src/assets/stylesheets/main/_api.scss | 8 +-
src/assets/stylesheets/main/_typeset.scss | 8 +
.../main/extensions/pymdownx/_highlight.scss | 19 +-
24 files changed, 1082 insertions(+), 475 deletions(-)
create mode 100644 .gitattributes
create mode 100644 docs/keys.rst
create mode 100644 docs/task_lists.rst
create mode 100644 sphinx_immaterial/kbd_keys.py
create mode 100644 sphinx_immaterial/task_lists.py
create mode 100644 sphinx_immaterial/theme_result.py
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 000000000..813e4309d
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,10 @@
+# We need to make sure that the remote and workspace line endings all use LF due to
+# linting and other reasons.
+
+# Set core.autocrlf to false in case people have this set differently.
+# If this is set to 'true' or 'input', then it overrides the eol option.
+* text autocrlf=false
+
+# This setting forces Git to normalize line endings to LF on checkin and
+# prevents conversion to CRLF when the file is checked out.
+* text eol=lf
diff --git a/docs/_static/extra_css.css b/docs/_static/extra_css.css
index bdce350a5..bfb5ad333 100644
--- a/docs/_static/extra_css.css
+++ b/docs/_static/extra_css.css
@@ -16,11 +16,51 @@
--md-icon__fa-gitlab: url('data:image/svg+xml;charset=utf-8,');
--md-icon__fa-gitkraken: url('data:image/svg+xml;charset=utf-8,');
--md-icon__fa-bitbucket: url('data:image/svg+xml;charset=utf-8,');
- --md-admonition-icon--pied-piper: url('data:image/svg+xml;charset=utf-8,')
+}
+
+/* ************************* my-special-key style ************************************* */
+
+.md-typeset kbd.key-my-special-key,
+.md-typeset kbd.key-git {
+ color: var(--md-primary-fg-color);
+ background: var(--md-accent-bg-color);
+}
+
+.md-typeset kbd.key-git::before {
+ content: "██";
+ -webkit-mask-image: var(--md-icon__fa-git);
+ -webkit-mask-repeat: no-repeat;
+ mask-image: var(--md-icon__fa-git);
+ mask-repeat: no-repeat;
+}
+
+.md-typeset kbd.key-my-special-key:hover,
+.md-typeset kbd.key-git:hover {
+ color: var(--md-accent-fg-color);
+}
+
+/* **************************** custom-task-list style rules *************************** */
+
+/* style for the unchecked checkboxes */
+.custom-task-list-style > ul > li > label .task-list-indicator::before {
+ -webkit-mask-image: var(--md-admonition-icon--failure);
+ mask-image: var(--md-admonition-icon--failure);
+ background-color: hsl(0, 72%, 55%);
+}
+
+/* style for the checked checkboxes */
+.custom-task-list-style>ul>.task-list-item>.task-list-control>[type="checkbox"]:checked+.task-list-indicator::before {
+ -webkit-mask-image: var(--md-admonition-icon--success);
+ mask-image: var(--md-admonition-icon--success);
+ background-color: hsl(122, 84%, 45%);
}
/* *************************** custom admonition style rules *************************** */
+:root {
+ --md-admonition-icon--pied-piper: url('data:image/svg+xml;charset=utf-8,')
+}
+
.md-typeset .admonition.pied-piper {
border-color: rgb(43, 155, 70);
}
diff --git a/docs/additional_samples.rst b/docs/additional_samples.rst
index 329508d16..480104f2a 100644
--- a/docs/additional_samples.rst
+++ b/docs/additional_samples.rst
@@ -7,7 +7,6 @@ Various examples of styling applied to Sphinx constructs. You can
view the `source <./_sources/examples.txt>`_ of this page to see the specific
reStructuredText used to create these examples.
-
Headings
========
This is a first level heading (``h1``).
@@ -23,79 +22,87 @@ This is a third level heading (``h3``).
Code
====
-The theme uses pygments for ``inline code text`` and
-::
- multiline
- code text
+.. rst-example::
+
+ The theme uses pygments for ``inline code text`` and
+ ::
+
+ multiline
+ code text
Here's an included example with line numbers.
-.. literalinclude:: ../sphinx_immaterial/autodoc_property_type.py
- :caption: source from this theme in *sphinx_immaterial/autodoc_property_type.py*
- :linenos:
+.. rst-example::
+
+ .. literalinclude:: ../sphinx_immaterial/autodoc_property_type.py
+ :caption: source from this theme in *sphinx_immaterial/autodoc_property_type.py*
+ :linenos:
It also works with existing Sphinx highlighting:
-.. code-block:: html
+.. rst-example::
+
+ .. code-block:: html
-
-
Hello World
-
+
+ Hello World
+
-.. code-block:: python
+ .. code-block:: python
- def hello():
- """Greet."""
- return "Hello World"
+ def hello():
+ """Greet."""
+ return "Hello World"
-.. code-block:: javascript
+ .. code-block:: javascript
- /**
- * Greet.
- */
- function hello(): {
- return "Hello World";
- }
+ /**
+ * Greet.
+ */
+ function hello(): {
+ return "Hello World";
+ }
Footnotes
=========
-I have footnoted a first item [#f1]_ and second item [#f2]_.
-This also references the second item [#f2]_.
-.. rubric:: Footnotes
-.. [#f1] My first footnote.
-.. [#f2] My second footnote.
+.. rst-example::
-Icons
-=====
-The following template HTML:
+ I have footnoted a first item [#f1]_ and second item [#f2]_.
+ This also references the second item [#f2]_.
-.. code-block:: html
+ .. rubric:: Footnotes
+ .. [#f1] My first footnote.
+ .. [#f2] My second footnote.
-
+Icons
+=====
-translates to a the site's icon:
+.. rst-example:: The following raw HTML
+ :output-prefix: translates to the icon:
-.. raw:: html
+ .. raw:: html
-
+
The material icon font provides hundreds to choose from. You can use the ```` tag or the
```` tag.
-.. raw:: html
+.. rst-example::
-
-
-
-
-
-
-
-
-
-
+ .. raw:: html
+
+
+
+
+
+
+
+
+
+
+
Tables
@@ -109,30 +116,32 @@ using ``.. cssclass:: custom-class`` and then add it to your configuration's
Grid
----
-A grid table:
-+------------------------+------------+----------+----------+
-| Header1 | Header2 | Header3 | Header4 |
-+========================+============+==========+==========+
-| row1, cell1 | cell2 | cell3 | cell4 |
-+------------------------+------------+----------+----------+
-| row2 ... | ... | ... | |
-+------------------------+------------+----------+----------+
-| ... | ... | ... | |
-+------------------------+------------+----------+----------+
+.. rst-example:: A grid table:
+
+ +------------------------+------------+----------+----------+
+ | Header1 | Header2 | Header3 | Header4 |
+ +========================+============+==========+==========+
+ | row1, cell1 | cell2 | cell3 | cell4 |
+ +------------------------+------------+----------+----------+
+ | row2 ... | ... | ... | |
+ +------------------------+------------+----------+----------+
+ | ... | ... | ... | |
+ +------------------------+------------+----------+----------+
Simple
------
-A simple table:
-===== ===== =======
-H1 H2 H3
-===== ===== =======
-cell1 cell2 cell3
-... ... ...
-... ... ...
-===== ===== =======
+.. rst-example:: A simple table:
+
+ ===== ===== =======
+ H1 H2 H3
+ ===== ===== =======
+ cell1 cell2 cell3
+ ... ... ...
+ ... ... ...
+ ===== ===== =======
User-styled Table
-----------------
@@ -146,80 +155,90 @@ User-styled Table
This is feature demonstration. There is no css for the plain class, and so
this is completely unstyled.
-.. cssclass:: plain
-===== ====== =======
-User Styled Table
-===== ====== =======
-cell1 cell2 cell3
-... ... ...
-... ... ...
-===== ====== =======
+.. rst-example::
+
+ .. cssclass:: plain
+
+ ===== ====== =======
+ User Styled Table
+ ===== ====== =======
+ cell1 cell2 cell3
+ ... ... ...
+ ... ... ...
+ ===== ====== =======
List Tables
-----------
-.. list-table:: A List Table
- :header-rows: 1
+.. rst-example::
+
+ .. list-table:: A List Table
+ :header-rows: 1
- * - Column 1
- - Column 2
- * - Item 1
- - Item 2
+ * - Column 1
+ - Column 2
+ * - Item 1
+ - Item 2
Alignment
~~~~~~~~~
-.. list-table:: Center Aligned
- :header-rows: 1
- :align: center
-
- * - Column 1
- - Column 2
- * - Item 1
- - Item 2
-
-
-.. list-table:: Right Aligned
- :widths: 15 10 30
- :header-rows: 1
- :align: right
-
- * - Treat
- - Quantity
- - Description
- * - Albatross
- - 2.99
- - On a stick!
- * - Crunchy Frog
- - 1.49
- - If we took the bones out
- * - Gannet Ripple
- - 1.99
- - On a stick!
+.. rst-example::
+
+ .. list-table:: Center Aligned
+ :header-rows: 1
+ :align: center
+
+ * - Column 1
+ - Column 2
+ * - Item 1
+ - Item 2
+
+
+.. rst-example::
+
+ .. list-table:: Right Aligned
+ :widths: 15 10 30
+ :header-rows: 1
+ :align: right
+
+ * - Treat
+ - Quantity
+ - Description
+ * - Albatross
+ - 2.99
+ - On a stick!
+ * - Crunchy Frog
+ - 1.49
+ - If we took the bones out
+ * - Gannet Ripple
+ - 1.99
+ - On a stick!
Code Documentation
==================
-An example Python function.
-.. py:function:: format_exception(etype, value, tb[, limit=None])
+.. rst-example:: An example Python function.
- Format the exception with a traceback.
+ .. py:function:: format_exception(etype, value, tb[, limit=None])
- :param etype: exception type
- :param value: exception value
- :param tb: traceback object
- :param limit: maximum number of stack frames to show
- :type limit: integer or None
- :rtype: list of strings
+ Format the exception with a traceback.
-An example JavaScript function.
+ :param etype: exception type
+ :param value: exception value
+ :param tb: traceback object
+ :param limit: maximum number of stack frames to show
+ :type limit: integer or None
+ :rtype: list of strings
-.. js:class:: MyAnimal(name[, age])
+.. rst-example:: An example JavaScript function.
- :param string name: The name of the animal
- :param number age: an optional age for the animal
+ .. js:class:: MyAnimal(name[, age])
+
+ :param string name: The name of the animal
+ :param number age: an optional age for the animal
Glossaries
==========
@@ -239,37 +258,44 @@ Glossaries
Math
====
-.. math::
+.. rst-example::
- (a + b)^2 = a^2 + 2ab + b^2
+ .. math::
- (a - b)^2 = a^2 - 2ab + b^2
+ (a + b)^2 = a^2 + 2ab + b^2
-.. math::
+ (a - b)^2 = a^2 - 2ab + b^2
- (a + b)^2 &= (a + b)(a + b) \\
- &= a^2 + 2ab + b^2
+.. rst-example::
+ .. math::
+
+ (a + b)^2 &= (a + b)(a + b) \\
+ &= a^2 + 2ab + b^2
-.. math::
- :nowrap:
+.. rst-example::
- \begin{eqnarray}
- y & = & ax^2 + bx + c \\
- f(x) & = & x^2 + 2xy + y^2
- \end{eqnarray}
+ .. math::
+ :nowrap:
+
+ \begin{eqnarray}
+ y & = & ax^2 + bx + c \\
+ f(x) & = & x^2 + 2xy + y^2
+ \end{eqnarray}
Production Lists
================
-.. productionlist::
- try_stmt: try1_stmt | try2_stmt
- try1_stmt: "try" ":" `suite`
- : ("except" [`expression` ["," `target`]] ":" `suite`)+
- : ["else" ":" `suite`]
- : ["finally" ":" `suite`]
- try2_stmt: "try" ":" `suite`
- : "finally" ":" `suite`
+.. rst-example::
+
+ .. productionlist::
+ try_stmt: try1_stmt | try2_stmt
+ try1_stmt: "try" ":" `suite`
+ : ("except" [`expression` ["," `target`]] ":" `suite`)+
+ : ["else" ":" `suite`]
+ : ["finally" ":" `suite`]
+ try2_stmt: "try" ":" `suite`
+ : "finally" ":" `suite`
Sub-pages
=========
diff --git a/docs/admonitions.rst b/docs/admonitions.rst
index b96c24a9a..fe476f067 100644
--- a/docs/admonitions.rst
+++ b/docs/admonitions.rst
@@ -11,22 +11,26 @@ Most of the admonitions that the mkdocs-material theme supports were "borrowed"
admonitions defined in the reStructuredText specifications. You may recognize them from
usage in other sphinx-based themes. They are:
-``note``, ``todo``, ``seealso``
+.. rst-example:: ``note``, ``todo``, ``seealso``
+
.. seealso::
This admonition is specific to Sphinx directives and not defined in the rST specifications
as you can `seealso`.
``note`` and ``todo`` are admonitions defined by the rST specifications.
-``tip``, ``hint``, ``important``
+.. rst-example:: ``tip``, ``hint``, ``important``
+
.. important::
It is **important** to correctly use admonitions.
-``attention``, ``caution``, ``warning``
+.. rst-example:: ``attention``, ``caution``, ``warning``
+
.. warning::
This is a **warning**.
-``danger``, ``error``
+.. rst-example:: ``danger``, ``error``
+
.. error::
You have made a grave **error**.
@@ -38,87 +42,69 @@ These admonitions can still be used, but the syntax is a little different becaus
on the generic admonition defined in the reStructuredText specifications.
To use the following admonitions' styles from the mkdocs-material theme, the rST syntax is
-shown inside the demonstrated admonition.
+shown to demonstrate using the ``:class:`` option of generic admonitions.
.. important::
The ``:class:`` options below (in the rST code blocks) must use lower case letters for the
styling to work. Otherwise, the admonition will look like a `note` (as that is the
default fallback style).
-``todo``, ``info``
+.. rst-example:: ``todo``, ``info``
+
.. admonition:: Info
:class: info
Thanks to the mkdocs-material theme, the ``todo`` class is also an alias of the
- ``info`` class when not using the ``.. todo::`` directive.
-
- .. code-block:: rst
+ ``info`` class when not using the `.. todo:: ` directive.
- .. admonition:: Info
- :class: info
+.. rst-example:: ``abstract``, ``summary``, ``tldr``
-``abstract``, ``summary``, ``tldr``
.. admonition:: TL;DR
:class: tldr
- .. code-block:: rst
+ The ``:class: tldr`` part is important.
- .. admonition:: TL;DR
- :class: tldr
+.. rst-example:: ``success``, ``check``, ``done``
-``success``, ``check``, ``done``
- .. admonition:: Done
+ .. admonition:: Accomplished
:class: done
- .. code-block:: rst
+ This style is used for ``success``, ``check``, ``done`` CSS classes.
- .. admonition:: Done
- :class: done
+.. rst-example:: ``question``, ``help``, ``faq``
-``question``, ``help``, ``faq``
.. admonition:: FAQ
:class: faq
- .. code-block:: rst
+ Helpful advice goes here.
- .. admonition:: FAQ
- :class: faq
+.. rst-example:: ``failure``, ``fail``, ``missing``
-``failure``, ``fail``, ``missing``
- .. admonition:: Missing
+ .. admonition:: Something Missing
:class: missing
- .. code-block:: rst
+ We expected some loss of feature-coverage.
- .. admonition:: Missing
- :class: missing
+.. rst-example:: ``bug``
-``bug``
- .. admonition:: Bug
+ .. admonition:: Known Bug
:class: bug
- .. code-block:: rst
+ Bug reported data/conclusion.
- .. admonition:: Bug
- :class: bug
+.. rst-example:: ``example``
-``example``
- .. admonition:: Example
+ .. admonition:: Example Admonition
:class: example
- .. code-block:: rst
+ Example Body.
- .. admonition:: Example
- :class: example
+.. rst-example:: ``cite``, ``quote``
-``cite``, ``quote``
- .. admonition:: Quote
+ .. admonition:: Unknown Quote
:class: quote
- .. code-block:: rst
-
- .. admonition:: Quote
- :class: quote
+ Somebody somewhere said something catchy.
Collapsible dropdown
*********************
@@ -136,27 +122,23 @@ The `sphinxcontrib-details-directive extension`_ should be added to conf.py's ex
extensions = ["sphinx_immaterial", "sphinxcontrib.details.directive"]
-
If the ``:class:`` option is not supplied to the ``details`` directive then the admonition
style falls back to a `note` admonition style.
-.. details:: Open by default
- :class: example
- :open:
+.. rst-example::
- .. code-block:: rst
+ .. details:: Open by default
+ :class: example
+ :open:
- .. details:: Open by default
- :class: example
- :open:
+ Use the ``:open:`` option as a flag to expand the admonition by default.
-.. details:: Closed by default
- :class: help
+.. rst-example::
- .. code-block:: rst
+ .. details:: Closed by default
+ :class: help
- .. details:: Closed by default
- :class: help
+ Without the ``:open:`` flag, the admonition is collapsed by default.
Removing the title
******************
@@ -168,25 +150,19 @@ The admonition's title can be removed if the ``md-admonition`` directive is not
any arguments. Because the ``md-admonition`` directive is an adaptation of the generic
``admonition`` directive, the ``class`` option is still respected.
-.. md-admonition::
- :class: error
-
- This example uses the styling of the ``error`` admonition
+.. rst-example::
- .. code-block:: rst
+ .. md-admonition::
+ :class: error
- .. md-admonition::
- :class: error
+ This example uses the styling of the ``error`` admonition
-.. md-admonition:: Using a title
- :class: help
+.. rst-example::
- This example uses the styling of the ``help`` admonition
+ .. md-admonition:: Using a title
+ :class: help
- .. code-block:: rst
-
- .. md-admonition:: Using a title
- :class: help
+ This example uses the styling of the ``help`` admonition
.. hint::
You can use the ``md-admonition`` directive in other themes by adding the theme's module to your
@@ -207,43 +183,26 @@ folder and add the new CSS to an additional style sheet.
.. md-tab-item:: rST code
- .. code-block:: rst
+ .. rst-example:: Pied Piper Example
+ :output-prefix:
.. admonition:: Pied Piper
- :class: pied-piper
+ :class: pied-piper
- Don't tell him you use spaces instead of tabs...
+ Don't tell him you use spaces instead of tabs...
.. md-tab-item:: CSS code
- .. code-block:: css
+ .. literalinclude:: _static/extra_css.css
+ :language: css
:caption: docs/_static/extra_css.css
-
- :root {
- --md-admonition-icon--pied-piper: url('data:image/svg+xml;charset=utf-8,')
- }
- .md-typeset .admonition.pied-piper {
- border-color: rgb(43, 155, 70);
- }
- .md-typeset .pied-piper > .admonition-title {
- background-color: rgba(43, 155, 70, 0.1);
- border-color: rgb(43, 155, 70);
- }
- .md-typeset .pied-piper > .admonition-title::before {
- background-color: rgb(43, 155, 70);
- -webkit-mask-image: var(--md-admonition-icon--pied-piper);
- mask-image: var(--md-admonition-icon--pied-piper);
- }
+ :start-at: /* *************************** custom admonition style rules
+ :end-before: /* **********
.. md-tab-item:: conf.py code
.. code-block:: python
+ :caption: docs/conf.py
html_static_path = ["_static"]
html_css_files = ["extra_css.css"]
-
-
-.. admonition:: Pied Piper
- :class: pied-piper
-
- Don't tell him you use spaces instead of tabs...
diff --git a/docs/conf.py b/docs/conf.py
index 212e58cc9..80dea063f 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -35,6 +35,8 @@
"sphinx.ext.mathjax",
"sphinx.ext.viewcode",
"sphinxcontrib.details.directive",
+ "sphinx_immaterial.theme_result",
+ "sphinx_immaterial.kbd_keys",
]
intersphinx_mapping = {
@@ -57,28 +59,27 @@
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]
-# -- Options for HTML output -------------------------------------------------
-
-# The theme to use for HTML and HTML Help pages. See the documentation for
-# a list of builtin themes.
+# -- sphinx_immaterial.keys extension options
#
+# optional key_map for example purposes
+keys_map = {"my-special-key": "Awesome Key", "git": ""}
+
+# -- Options for HTML output -------------------------------------------------
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named 'default.css' will overwrite the builtin 'default.css'.
html_static_path = ["_static"]
-html_css_files = [
- "extra_css.css",
- "https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css",
-]
+html_css_files = ["extra_css.css"]
+html_last_updated_fmt = ""
+html_title = "Sphinx-Immaterial"
+html_favicon = "_static/images/favicon.ico" # colored version of material/bookshelf.svg
+html_logo = "_static/images/Ybin.gif" # from https://gifer.com/en/Ybin
-# -- HTML theme settings ------------------------------------------------
+# -- HTML theme specific settings ------------------------------------------------
extensions.append("sphinx_immaterial")
-html_title = "Sphinx-Immaterial"
html_theme = "sphinx_immaterial"
-html_favicon = "_static/images/favicon.ico" # colored version of material/bookshelf.svg
-html_logo = "_static/images/Ybin.gif" # from https://gifer.com/en/Ybin
# material theme options (see theme.conf for more information)
html_theme_options = {
@@ -131,21 +132,17 @@
{
"version": "https://sphinx-immaterial.rtfd.io",
"title": "ReadTheDocs",
- "aliases": []
+ "aliases": [],
},
{
"version": "https://jbms.github.io/sphinx-immaterial",
"title": "Github Pages",
- "aliases": []
+ "aliases": [],
},
],
"toc_title_is_page_title": True,
} # end html_theme_options
-html_last_updated_fmt = ""
-html_use_index = False
-html_domain_indices = False
-
# ---- Other documentation options -------------------------
todo_include_todos = True
diff --git a/docs/content_tabs.rst b/docs/content_tabs.rst
index 85a2cbd66..140b7e236 100644
--- a/docs/content_tabs.rst
+++ b/docs/content_tabs.rst
@@ -42,7 +42,7 @@ the sphinx-immaterial theme provides its own directives to make use of content t
This directive supports ``:class:`` and ``:name:`` options to use custom CSS classes
and reference links (respectively).
- .. code-block:: rst
+ .. rst-example:: ``md-tab-set`` Example
.. md-tab-set::
:class: custom-tab-set-style
@@ -69,30 +69,6 @@ the sphinx-immaterial theme provides its own directives to make use of content t
:start-at: /* ************************ custom-tab-set-style
:end-before: /* *********************** custom-tab-item-style
- .. md-tab-set::
- :class: custom-tab-set-style
- :name: ref_this_tab_set
-
- .. md-tab-item:: Local Ref
-
- A reference to this tab set renders like so:
- `tab set description `.
-
- This syntax can only be used on the same page as the tab set.
-
- .. md-tab-item:: Cross-page Ref
-
- To cross-reference this tab set from a different page, use
- :ref:`tab set description `
-
- Clearly, this also works on the same page as the tab set.
-
- .. md-tab-item:: Custom CSS
-
- .. literalinclude:: _static/extra_css.css
- :language: css
- :start-at: /* ************************ custom-tab-set-style
- :end-before: /* *********************** custom-tab-item-style
.. rst:directive:: md-tab-item
@@ -108,7 +84,7 @@ the sphinx-immaterial theme provides its own directives to make use of content t
Use the ``:class:`` option to optionally provide custom CSS classes to the tab's content
(not the tab's label).
- .. code-block:: rst
+ .. rst-example:: ``md-tab-item`` Example
.. md-tab-set::
@@ -124,19 +100,6 @@ the sphinx-immaterial theme provides its own directives to make use of content t
:start-at: /* *********************** custom-tab-item-style
:end-before: /* ************************* inline icon stuff
- .. md-tab-set::
-
- .. md-tab-item:: Customized content
- :class: custom-tab-item-style
-
- This content could be styled differently from other page content.
-
- .. md-tab-item:: Custom CSS
-
- .. literalinclude:: _static/extra_css.css
- :language: css
- :start-at: /* *********************** custom-tab-item-style
- :end-before: /* ************************* inline icon stuff
Typical examples are seen in this documentations'
`Custom admonitions `_ and
diff --git a/docs/demo_api.rst b/docs/demo_api.rst
index 7b05937dd..6248d1875 100644
--- a/docs/demo_api.rst
+++ b/docs/demo_api.rst
@@ -7,56 +7,73 @@ sample API documentation and generated content
:mod:`test_py_module`
=====================
-.. automodule:: test_py_module.test
- :members:
- :private-members:
- :special-members:
+.. rst-example:: autodoc example
+ .. automodule:: test_py_module.test
+ :members:
+ :private-members:
+ :special-members:
C++ API
=======
-.. cpp:type:: MyType
+.. rst-example::
- Some type
+ .. cpp:type:: MyType
-.. cpp:function:: const MyType Foo(const MyType bar)
+ Some type
- Some function type thing
+.. rst-example::
-.. cpp:class:: template std::array
+ .. c:macro:: DEFAULT_LENGTH
- Some cpp class
+ .. cpp:function:: const MyType Foo(const MyType bar, uint8_t* arr, unsigned int len = DEFAULT_LENGTH, bool baz= false)
-.. cpp:member:: float Sphinx::version
+ Some function type thing
- The description of Sphinx::version.
+.. rst-example::
-.. cpp:var:: int version
+ .. cpp:class:: template std::array
- The description of version.
+ Some cpp class
-.. cpp:type:: std::vector List
+.. rst-example::
- The description of List type.
+ .. cpp:member:: float Sphinx::version
-.. cpp:enum:: MyEnum
+ The description of `Sphinx::version`.
- An unscoped enum.
+.. rst-example::
- .. cpp:enumerator:: A
+ .. cpp:var:: int version
-.. cpp:enum-class:: MyScopedEnum
+ The description of version.
- A scoped enum.
+.. rst-example::
- .. cpp:enumerator:: B
+ .. cpp:type:: std::vector List
-.. cpp:enum-struct:: protected MyScopedVisibilityEnum : std::underlying_type::type
+ The description of List type.
- A scoped enum with non-default visibility, and with a specified underlying type.
+.. rst-example::
- .. cpp:enumerator:: B
+ .. cpp:enum:: MyEnum
+
+ An unscoped enum.
+
+ .. cpp:enumerator:: A
+
+ .. cpp:enum-class:: MyScopedEnum
+
+ A scoped enum.
+
+ .. cpp:enumerator:: B
+
+ .. cpp:enum-struct:: protected MyScopedVisibilityEnum : std::underlying_type::type
+
+ A scoped enum with non-default visibility, and with a specified underlying type.
+
+ .. cpp:enumerator:: B
JavaScript API
@@ -66,74 +83,79 @@ JavaScript API
.. js:module:: module_a.submodule
-* Link to :js:class:`ModTopLevel`
+.. rst-example::
-.. js:class:: ModTopLevel
+ * Link to :js:class:`ModTopLevel`
- * Link to :js:meth:`mod_child_1`
- * Link to :js:meth:`ModTopLevel.mod_child_1`
+.. rst-example::
-.. js:method:: ModTopLevel.mod_child_1
+ .. js:class:: ModTopLevel
- * Link to :js:meth:`mod_child_2`
+ * Link to :js:meth:`mod_child_1`
+ * Link to :js:meth:`ModTopLevel.mod_child_1`
-.. js:method:: ModTopLevel.mod_child_2
+.. rst-example::
- * Link to :js:meth:`module_a.submodule.ModTopLevel.mod_child_1`
+ .. js:method:: ModTopLevel.mod_child_1
-.. js:module:: module_b.submodule
+ * Link to :js:meth:`mod_child_2`
-* Link to :js:class:`ModTopLevel`
+ .. js:method:: ModTopLevel.mod_child_2
-.. js:class:: ModNested
+ * Link to :js:meth:`module_a.submodule.ModTopLevel.mod_child_1`
- .. js:method:: nested_child_1
+.. rst-example::
- * Link to :js:meth:`nested_child_2`
-
- .. js:method:: nested_child_2
-
- * Link to :js:meth:`nested_child_1`
+ * Link to :js:class:`ModTopLevel`
+.. js:module:: module_b.submodule
-Generated Index
-===============
+.. rst-example::
-Part of the sphinx build process in generate and index file: :ref:`genindex`.
+ .. js:class:: ModNested
+ .. js:method:: nested_child_1
-Optional parameter args
-=======================
+ * Link to :js:meth:`nested_child_2`
-At this point optional parameters `cannot be generated from code`_.
-However, some projects will manually do it, like so:
+ .. js:method:: nested_child_2
-This example comes from `django-payments module docs`_.
+ * Link to :js:meth:`nested_child_1`
-.. class:: payments.dotpay.DotpayProvider(seller_id, pin[, channel=0[, lock=False], lang='pl'])
+ .. js:method:: getJSON(href, callback, priority[, err_back, flags])
- This backend implements payments using a popular Polish gateway, `Dotpay.pl `_.
+ :param string href: An URI to the location of the resource.
+ :param callback: Gets called with the object.
+ :param err_back:
+ Gets called in case the request fails. And a lot of other
+ text so we need multiple lines.
+ :throws SomeError: For whatever reason in that case.
+ :returns: Something.
- Due to API limitations there is no support for transferring purchased items.
+Generated Index
+===============
+.. rst-example::
- :param seller_id: Seller ID assigned by Dotpay
- :param pin: PIN assigned by Dotpay
- :param channel: Default payment channel (consult reference guide)
- :param lang: UI language
- :param lock: Whether to disable channels other than the default selected above
+ A generated index (:ref:`genindex`) is part of the Sphinx build process, unless
+ `html_use_index` is set to `False`.
-.. _cannot be generated from code: https://groups.google.com/forum/#!topic/sphinx-users/_qfsVT5Vxpw
-.. _django-payments module docs: http://django-payments.readthedocs.org/en/latest/modules.html#payments.authorizenet.AuthorizeNetProvide
+ Sphinx also allows indexing by domain (programming language), as seen in the
+ :ref:`modindex` for the demo Python module that is documented on this page.
+.. note::
+ This theme does not support a separate search page (usually referenced with
+ ``:ref:`search``), since the search is accessible in the site's navigation bar.
Data
====
-.. data:: Data_item_1
- Data_item_2
- Data_item_3
+.. rst-example::
+
+ .. data:: Data_item_1
+ Data_item_2
+ Data_item_3
- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce congue elit eu hendrerit mattis.
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce congue elit eu hendrerit mattis.
-Some data link :data:`Data_item_1`.
+ Some data link :data:`Data_item_1`.
diff --git a/docs/index.rst b/docs/index.rst
index 1230d213b..d58f68dd7 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -56,12 +56,12 @@ Update your ``conf.py`` with the required changes:
There are a lot more ways to customize this theme. See :ref:`Customization`
or ``theme.conf`` for more details.
-.. admonition:: Settings used in this documentation
+.. details:: Settings used in this documentation
:class: example
.. literalinclude:: ./conf.py
- :start-at: # -- HTML theme settings ------------------------------------------------
- :end-before: # ---- Other documentation options -------------------------
+ :start-at: # -- HTML theme specific settings
+ :end-before: # ---- Other documentation options
.. toctree::
@@ -71,6 +71,8 @@ or ``theme.conf`` for more details.
admonitions
content_tabs
mermaid_diagrams
+ task_lists
+ keys
.. toctree::
:caption: Examples and Uses
diff --git a/docs/keys.rst b/docs/keys.rst
new file mode 100644
index 000000000..40fbaf713
--- /dev/null
+++ b/docs/keys.rst
@@ -0,0 +1,158 @@
+Keys extension
+==============
+
+.. _pymdownx.keys: https://facelessuser.github.io/pymdown-extensions/extensions/keys/
+
+This extension is meant to mimic the python markdown extension, `pymdownx.keys`_.
+
+It simply adds a role to invoke inline usage of keyboard keys with custom CSS provided by
+the sphinx-immaterial theme.
+
+.. details:: CSS is not included with this extension
+ :class: success
+
+ To add CSS to a theme that does not support this extension, try using:
+
+ .. code-block:: CSS
+
+ kbd[class^="key-"] {
+ background-color: var(--md-typeset-kbd-color);
+ border-radius: 0.1rem;
+ box-shadow: 0 0.1rem 0 0.05rem var(--md-typeset-kbd-border-color), 0 0.1rem 0 var(--md-typeset-kbd-border-color), 0 -0.1rem 0.2rem var(--md-typeset-kbd-accent-color) inset;
+ color: var(--md-default-fg-color);
+ display: inline-block;
+ font-size: 0.75em;
+ padding: 0 0.6666666667em;
+ vertical-align: text-top;
+ word-break: break-word;
+ font-feature-settings: "kern";
+ font-family: var(--md-code-font-family);
+ }
+
+ .keys span {
+ color: var(--md-default-fg-color--light);
+ padding: 0 0.2em;
+ }
+
+.. _pymdownx-keys-req:
+
+Markdown extension pre-requisite
+--------------------------------
+
+This pre-requisite does not mean Markdown support is enabled. However, this extension
+does import the ``pymdownx.keymap_db`` module to use for the `keys_map` option's defaults.
+
+To use this extension, the pymdownx package needs to be installed.
+
+.. code-block:: shell
+
+ python -m pip install pymdown-extensions
+
+And be sure to include the extension in your conf.py file.
+
+.. code-block:: python
+
+ extensions = ["sphinx_immaterial.kbd_keys"]
+
+.. _keys_extension_role:
+
+Keys extension role
+-----------------------
+
+.. rst:role:: keys
+
+ The value of this role is interpreted as a keyboard key name. Each role invocation can
+ describe multiple keys pressed simultaneously using the `keys_separator`.
+
+ .. rst-example::
+
+ :keys:`ctrl+alt+tab`
+
+ :keys:`caps-lock`, :keys:`left-cmd+shift+a`, :keys:`backspace`
+
+Keys extension configuration
+-------------------------------------
+
+These variables can be used to control the :rst:role:`keys` role behavior from the Sphinx
+project's conf.py file.
+
+.. confval:: keys_strict
+
+ The containing span element can strictly follow HTML5 specifications by using the
+ ``kbd`` tag instead of a ``span`` tag.
+
+ The sphinx-immaterial theme does not adhere to the HTML5 strictness, therefore this
+ `bool` option is disabled (`False`) by default.
+
+.. confval:: keys_class
+
+ The class attribute `str` value used in the containing span element. Defaults to ``"keys"``.
+
+ Only change this if needed for your theme. The sphinx-immaterial theme is configured to use
+ the default value.
+
+.. confval:: keys_separator
+
+ The `str` value used as the delimiter between keys. Defaults to ``"+"``.
+
+ Changing this also requires changing the text provided to the :rst:role:`keys` role.
+
+.. confval:: keys_map
+
+ An additional `dict` where ``key: value`` pairs consist of:
+
+ .. csv-table::
+ :header: key, value
+
+ aliased key-\ **name** inputs (preferably a CSS friendly name), displayed output `str`
+
+ By default the english mappings are included from the `pymdownx package `.
+
+ .. seealso::
+ The tables in
+ `pymdownx.keys`_ docs in `Extending/Modifying Key-Map Index
+ `_.
+
+ .. md-tab-set::
+
+ .. md-tab-item:: conf.py
+
+ Define the key name and give it a `str` value to display.
+
+ In our case, "Awesome Key" will be shown for ``:keys:`my-special-key```.
+
+ .. literalinclude:: conf.py
+ :language: python
+ :start-at: # -- sphinx_immaterial.keys extension options
+ :end-before: # --
+
+ .. md-tab-item:: CSS code
+
+ Remember to prepend ``key-`` to whatever the `keys_map` key was. In our case,
+ ``my-special-key`` turns into ``key-my-special-key``.
+
+ .. literalinclude:: _static/extra_css.css
+ :language: css
+ :start-at: /* ************************* my-special-key style
+ :end-before: /* **************************** custom-task-list style rules
+
+
+ .. md-tab-item:: rST code
+
+ Specify the key using a known name in the `keys_map` index.
+
+ In our case, ``my-special-key`` to fetch the display text from `keys_map`.
+
+ .. rst-example::
+
+ :keys:`my-special-key` + :keys:`git` = :keys:`git+my-special-key`
+
+
+ Use of spaces in a key name will result in CSS class that has hyphens instead of
+ spaces in a lower case form of the given text. Therefore, entering
+ ``My Special Key`` ignores the `keys_map` but still uses the
+ ``key-my-special-key`` CSS class.
+
+ .. rst-example::
+
+ :keys:`My Special Key` + :keys:`Git` = :keys:`Git+My Special Key`
diff --git a/docs/mermaid_diagrams.rst b/docs/mermaid_diagrams.rst
index 59328cf65..599244f70 100644
--- a/docs/mermaid_diagrams.rst
+++ b/docs/mermaid_diagrams.rst
@@ -4,7 +4,8 @@ Mermaid diagrams
================
.. note::
- Use of this feature has no affect or affiliation with sphinx's graphviz implementation.
+ Use of this feature has no affect or affiliation with sphinx's
+ :py:mod:`graphviz ` implementation.
The mkdocs-material theme is equipped to make use of diagrams generated (during page load time)
with `mermaid.js`_. Although, its implementation relies on a markdown extension that does not get
@@ -15,15 +16,24 @@ directive that exposes the underlying implementation in mkdocs-material theme.
.. rst:directive:option:: class
:type: string
-
+
A space delimited list of qualified names that get used as the HTML element's
``class`` attribute.
+ .. hint::
+ You can use this option to specify ``text-align`` property via the following
+ CSS classes:
+
+ - ``align-right`` sets the ``text-align`` property to ``right``.
+ - ``align-left`` sets the ``text-align`` property to ``left``.
+ - ``align-center`` sets the ``text-align`` property to ``center``.
+
+
.. rst:directive:option:: name
:type: string
-
+
A qualified name that get used as the HTML element's ``id`` attribute.
-
+
Use the `ref` role to reference the element by name.
The `md-mermaid` directive's ``:class:`` and ``:name:`` options can be used
@@ -34,16 +44,22 @@ directive that exposes the underlying implementation in mkdocs-material theme.
.. md-admonition::
:class: missing
-
+
While all `mermaid.js`_ features should work out-of-the-box, this theme will currently only
- adjust the fonts and colors for `flowcharts`_, `sequence diagrams `,
- `class diagrams `, `state diagrams `, and
- `entity-relationship diagrams `.
+ adjust the fonts and colors for the following types of diagrams:
+
+ .. rst-example:: References linking directly to a diagram's ``:name:``
+
+ - `flowcharts`_
+ - `sequence diagrams `
+ - `class diagrams `
+ - `state diagrams `
+ - `entity-relationship diagrams `
Using flowcharts
----------------
-.. code-block:: rst
+.. rst-example::
.. md-mermaid::
:name: flowcharts
@@ -55,20 +71,10 @@ Using flowcharts
D --> B;
B ---->|No| E[Yay!];
-.. md-mermaid::
- :name: flowcharts
-
- graph LR
- A[Start] --> B{Error?};
- B -->|Yes| C[Hmm...];
- C --> D[Debug];
- D --> B;
- B ---->|No| E[Yay!];
-
Using sequence diagrams
-----------------------
-.. code-block:: rst
+.. rst-example::
.. md-mermaid::
:name: sequence-diagrams
@@ -83,23 +89,10 @@ Using sequence diagrams
John->>Bob: How about you?
Bob-->>John: Jolly good!
-.. md-mermaid::
- :name: sequence-diagrams
-
- sequenceDiagram
- Alice->>John: Hello John, how are you?
- loop Healthcheck
- John->>John: Fight against hypochondria
- end
- Note right of John: Rational thoughts!
- John-->>Alice: Great!
- John->>Bob: How about you?
- Bob-->>John: Jolly good!
-
Using state diagrams
--------------------
-.. code-block:: rst
+.. rst-example::
.. md-mermaid::
:name: state-diagrams
@@ -116,26 +109,11 @@ Using state diagrams
join_state --> State4
State4 --> [*]
-.. md-mermaid::
- :name: state-diagrams
-
- stateDiagram-v2
- state fork_state <>
- [*] --> fork_state
- fork_state --> State2
- fork_state --> State3
-
- state join_state <>
- State2 --> join_state
- State3 --> join_state
- join_state --> State4
- State4 --> [*]
Using class diagrams
--------------------
-
-.. code-block:: rst
+.. rst-example::
.. md-mermaid::
:name: class-diagrams
@@ -164,44 +142,13 @@ Using class diagrams
+int postalCode
+String country
-validate()
- +outputAsLabel()
+ +outputAsLabel()
}
-.. md-mermaid::
- :name: class-diagrams
-
- classDiagram
- Person <|-- Student
- Person <|-- Professor
- Person : +String name
- Person : +String phoneNumber
- Person : +String emailAddress
- Person: +purchaseParkingPass()
- Address "1" <-- "0..1" Person:lives at
- class Student{
- +int studentNumber
- +int averageMark
- +isEligibleToEnrol()
- +getSeminarsTaken()
- }
- class Professor{
- +int salary
- }
- class Address{
- +String street
- +String city
- +String state
- +int postalCode
- +String country
- -validate()
- +outputAsLabel()
- }
-
Using entity-relationship diagrams
----------------------------------
-
-.. code-block:: rst
+.. rst-example::
.. md-mermaid::
:name: entity-relationship-diagrams
@@ -210,11 +157,3 @@ Using entity-relationship diagrams
CUSTOMER ||--o{ ORDER : places
ORDER ||--|{ LINE-ITEM : contains
CUSTOMER }|..|{ DELIVERY-ADDRESS : uses
-
-.. md-mermaid::
- :name: entity-relationship-diagrams
-
- erDiagram
- CUSTOMER ||--o{ ORDER : places
- ORDER ||--|{ LINE-ITEM : contains
- CUSTOMER }|..|{ DELIVERY-ADDRESS : uses
diff --git a/docs/requirements.txt b/docs/requirements.txt
index 4f1766b22..fa20fb5bf 100644
--- a/docs/requirements.txt
+++ b/docs/requirements.txt
@@ -1,3 +1,4 @@
# The sphinx docs theme to use
sphinx_immaterial
sphinxcontrib-details-directive
+pymdown-extensions
diff --git a/docs/specimen.rst b/docs/specimen.rst
index 4682d2cb0..d5515527e 100644
--- a/docs/specimen.rst
+++ b/docs/specimen.rst
@@ -373,23 +373,28 @@ Images
Default Alignment
~~~~~~~~~~~~~~~~~
+.. rst-example::
-.. image:: desert-flower.jpg
- :alt: Default image
+ .. image:: desert-flower.jpg
+ :alt: Default image
Center Alignment
~~~~~~~~~~~~~~~~
-.. image:: desert-flower.jpg
- :alt: Centered Image, 80% scale
- :scale: 80%
- :align: center
+.. rst-example::
+
+ .. image:: desert-flower.jpg
+ :alt: Centered Image, 80% scale
+ :scale: 80%
+ :align: center
Right Alignment
~~~~~~~~~~~~~~~
-.. image:: desert-flower.jpg
- :alt: Right Image, 60% scale
- :scale: 60%
- :align: right
+.. rst-example::
+
+ .. image:: desert-flower.jpg
+ :alt: Right Image, 60% scale
+ :scale: 60%
+ :align: right
Math again
----------
diff --git a/docs/task_lists.rst b/docs/task_lists.rst
new file mode 100644
index 000000000..6d7dcc144
--- /dev/null
+++ b/docs/task_lists.rst
@@ -0,0 +1,161 @@
+Task Lists
+==============
+
+This Sphinx extension mimics the HTML output of the ``pymdownx.tasklist`` Markdown
+extension, which allows for the definition of task lists. With this extension and the
+mkdocs-material theme's CSS, you can make list items prefixed with ``[ ]`` to render an unchecked
+checkbox or ``[x]`` to render a checked checkbox.
+
+This extension can be optionally be used in other sphinx theme's that support checkboxes.
+
+.. code-block:: python
+ :caption: This is already done in sphinx-immaterial theme:
+
+ extensions = ["sphinx_immaterial.task_lists"]
+
+.. details:: CSS not included with extension
+ :class: check
+
+ The CSS for checkboxes is not included with this extension. Rather, the CSS is served from the
+ sphinx-immaterial theme (which is inherited from mkdocs-material theme).
+
+ To use this extension with a theme that has no CSS support, try adding your own CSS:
+
+ .. code-block:: css
+
+ :root {
+ --md-task-list-icon: url('data:image/svg+xml;charset=utf-8,');
+ --md-task-list-icon--checked: url('data:image/svg+xml;charset=utf-8,');
+ }
+
+ /* style for the unchecked checkboxes */
+ .task-list-indicator::before {
+ -webkit-mask-image: var(--md-task-list-icon);
+ mask-image: var(--md-task-list-icon);
+ background-color: hsla(232deg, 75%, 90%, 0.12);
+
+ content: "";
+ height: 1.25em;
+ -webkit-mask-repeat: no-repeat;
+ mask-repeat: no-repeat;
+ -webkit-mask-size: contain;
+ mask-size: contain;
+ position: absolute;
+ top: .15em;
+ width: 1.25em;
+ }
+
+ /* style for the checked checkboxes */
+ .task-list-control > [type="checkbox"]:checked + .task-list-indicator::before {
+ -webkit-mask-image: var(--md-task-list-icon--checked);
+ mask-image: var(--md-task-list-icon--checked);
+ background-color: hsl(122deg, 84%, 45%);
+ }
+
+Config variables
+----------------
+
+.. confval:: custom_checkbox
+
+ A global conf.py `bool` variable to enable custom CSS for all checkboxes shown. Default is `False`.
+
+.. confval:: clickable_checkbox
+
+ A global conf.py `bool` variable to enable user interaction with the checkboxes shown. Default is `False`.
+
+ .. note::
+ If this option is used, then any user changes will not be saved.
+
+``task-list`` Directive
+-----------------------
+
+.. rst:directive:: task-list
+
+ This directive traverses the immediate list's items and adds a checkbox according to
+ GitHub Flavored MarkDown.
+
+
+ .. rst:directive:option:: class
+ :type: string
+
+ A space delimited list of qualified names that get used as the HTMl element's
+ ``class`` attribute.
+
+ The ``class`` option is only applied to the containing ``div`` element.
+
+ .. md-tab-set::
+
+ .. md-tab-item:: rST code
+
+ .. rst-example:: Custom icons scoped to immediate list only (not child lists)
+
+ .. task-list::
+ :class: custom-task-list-style
+ :custom:
+
+ + [ ] Custom unchecked checkbox
+ + [x] Custom checked checkbox
+
+ .. task-list::
+ :custom:
+
+ * [ ] A goal for a task.
+ * [x] A fulfilled goal.
+
+ .. md-tab-item:: CSS Hint
+
+ .. literalinclude:: _static/extra_css.css
+ :language: css
+ :start-at: /* **************************** custom-task-list style rules
+ :end-before: /* *************************** custom admonition style rules
+
+ .. rst:directive:option:: name
+ :type: string
+
+ A qualified name that get used as the HTML element's ``name`` attribute.
+
+ The ``name`` option is only applied to the containing ``div`` element.
+ Use the `ref` role to reference the element by name.
+
+ .. rst:directive:option:: custom
+ :type: flag
+
+ Allow custom styled checkboxes. Default is `False` unless `custom_checkbox` is enabled.
+
+ .. rst:directive:option:: clickable
+ :type: flag
+
+ Allow user interaction with checkboxes. Default is `False` unless `clickable_checkbox` is enabled.
+
+ .. note::
+ If this option is used, then any user changes will not be saved.
+
+Task List Example
+-----------------
+
+The following `task-list` example demonstrates nested `task-list`.
+Notice that indentation is important with reStructuredText lists.
+
+.. rst-example:: A feature spanning ``task-list`` example
+
+ .. task-list::
+ :name: task_list_example
+ :custom:
+
+ 1. [x] Task A
+ 2. [ ] Task B
+
+ .. task-list::
+ :clickable:
+
+ * [x] Task B1
+ * [x] Task B2
+ * [] Task B3
+
+ A rogue paragraph with a reference to
+ the `parent task_list `.
+
+ - A list item without a checkbox.
+ - [ ] Another bullet point.
+
+ 3. [ ] Task C
diff --git a/docs/test_py_module/test.py b/docs/test_py_module/test.py
index f47b9840c..58ebd4ffb 100644
--- a/docs/test_py_module/test.py
+++ b/docs/test_py_module/test.py
@@ -1,5 +1,6 @@
# -*- coding: utf-8 -*-
"""Test Module for sphinx_rtd_theme."""
+from typing import Union
class Foo:
@@ -45,11 +46,11 @@ def __init__(self, qux, spam=False):
"""Start the Foo.
:param qux: The first argument to initialize class.
- :type qux: string
+ :type qux: str
:param spam: Spam me yes or no...
:type spam: bool
-
"""
+
#: Doc comment for instance attribute qux.
self.qux = 3
@@ -111,3 +112,7 @@ def another_function(self, a, b, **kwargs):
This is deprecated since 3.0
"""
return sum(kwargs.values()) / len(kwargs), a + b
+
+def func(long: int, param: str, args: None, flags: bool, lists: Union[list, tuple]):
+ """A function with many parameters."""
+ return None
diff --git a/sphinx_immaterial/__init__.py b/sphinx_immaterial/__init__.py
index 803f9926e..a36df7c7c 100644
--- a/sphinx_immaterial/__init__.py
+++ b/sphinx_immaterial/__init__.py
@@ -317,6 +317,8 @@ def setup(app):
app.setup_extension("sphinx_immaterial.md_admonition")
app.setup_extension("sphinx_immaterial.content_tabs")
app.setup_extension("sphinx_immaterial.mermaid_diagrams")
+ app.setup_extension("sphinx_immaterial.task_lists")
+
# patch the details directive's run method
monkey_patch_details_run()
diff --git a/sphinx_immaterial/apidoc_formatting.py b/sphinx_immaterial/apidoc_formatting.py
index 9747133ec..a169b2624 100644
--- a/sphinx_immaterial/apidoc_formatting.py
+++ b/sphinx_immaterial/apidoc_formatting.py
@@ -147,6 +147,8 @@ def depart_desc_type(self, node: sphinx.addnodes.desc_type) -> None:
def visit_desc_signature(self, node: sphinx.addnodes.desc_signature) -> None:
node_text = node.astext()
+ # add highlight to invoke syntax highlighting in CSS
+ node["classes"].append("highlight")
if len(node_text) > SIGNATURE_WRAP_LENGTH:
node["classes"].append("sig-wrap")
super().visit_desc_signature(node)
@@ -165,6 +167,14 @@ def depart_desc_parameterlist(
_, close_paren = node.get("parens", ("(", ")"))
self.body[-1] = self.body[-1].replace(")", close_paren)
+ def visit_desc_parameter(self, node: sphinx.addnodes.desc_parameter) -> None:
+ self.body.append('')
+ super().visit_desc_parameter(node)
+
+ def depart_desc_parameter(self, node: sphinx.addnodes.desc_parameter) -> None:
+ super().depart_desc_parameter(node)
+ self.body.append("")
+
def depart_field_name(self, node: docutils.nodes.Element) -> None:
self.add_permalink_ref(node, _("Permalink to this headline"))
super().depart_field_name(node)
@@ -174,6 +184,47 @@ def depart_term(self, node: docutils.nodes.Element) -> None:
self.add_permalink_ref(node, _("Permalink to this definition"))
super().depart_term(node)
+ def visit_caption(self, node: docutils.nodes.Element) -> None:
+ attributes = {"class": "caption-text"}
+ if isinstance(node.parent, docutils.nodes.container) and node.parent.get(
+ "literal_block"
+ ):
+ # add highlight class to caption's div container.
+ # This is needed to trigger mkdocs-material CSS rule `.highlight .filename`
+ self.body.append('
')
+ # append a CSS class to trigger mkdocs-material theme's caption CSS style
+ attributes["class"] += " filename"
+ else:
+ super().visit_caption(node)
+ self.add_fignumber(node.parent)
+ self.body.append(self.starttag(node, "span", **attributes))
+
+ def depart_caption(self, node: docutils.nodes.Element) -> None:
+ if not isinstance(
+ node.parent, docutils.nodes.container
+ ) and not node.parent.get("literal_block"):
+ # only append ending tag if parent is not a literal-block.
+ # Because all elements in the caption should be within a span element
+ self.body.append("")
+
+ # append permalink if available
+ if isinstance(node.parent, docutils.nodes.container) and node.parent.get(
+ "literal_block"
+ ):
+ self.add_permalink_ref(node.parent, _("Permalink to this code"))
+ self.body.append("") # done; add closing tag
+ elif isinstance(node.parent, docutils.nodes.figure):
+ self.add_permalink_ref(node.parent, _("Permalink to this image"))
+ elif node.parent.get("toctree"):
+ self.add_permalink_ref(node.parent.parent, _("Permalink to this toctree"))
+
+ if isinstance(node.parent, docutils.nodes.container) and node.parent.get(
+ "literal_block"
+ ):
+ self.body.append("
\n")
+ else:
+ super().depart_caption(node)
+
def _monkey_patch_python_get_signature_prefix(
directive_cls: Type[sphinx.domains.python.PyObject],
diff --git a/sphinx_immaterial/content_tabs.py b/sphinx_immaterial/content_tabs.py
index 07b200b45..17e982aab 100644
--- a/sphinx_immaterial/content_tabs.py
+++ b/sphinx_immaterial/content_tabs.py
@@ -91,9 +91,7 @@ def run(self) -> List[nodes.Node]:
# add tab label
textnodes, _ = self.state.inline_text(self.arguments[0], self.lineno)
- tab_label = nodes.rubric(
- self.arguments[0], *textnodes, classes=["tabbed-label"]
- )
+ tab_label = nodes.rubric("", "", *textnodes, classes=["tabbed-label"])
self.add_name(tab_label)
tab_item += tab_label
@@ -152,6 +150,7 @@ def visit_tab_set(self: HTMLTranslator, node: content_tab_set):
# create:
label_node = content_tab_label(
+ "",
"",
*tab_label.children,
input_id=tab_item_identity,
diff --git a/sphinx_immaterial/kbd_keys.py b/sphinx_immaterial/kbd_keys.py
new file mode 100644
index 000000000..6b35e0ca4
--- /dev/null
+++ b/sphinx_immaterial/kbd_keys.py
@@ -0,0 +1,94 @@
+from typing import List, Tuple
+from docutils import nodes
+from sphinx.application import Sphinx
+from sphinx.config import Config
+from sphinx.writers.html import HTMLTranslator
+from sphinx.util.logging import getLogger
+
+LOGGER = getLogger(__name__)
+
+try:
+ import pymdownx.keymap_db as keys_db
+except ImportError:
+ LOGGER.info(
+ "Could not import `keymap_db` module from `pymdownx` package.\n "
+ "Please ensure `pymdown-extensions` is installed.\n "
+ "The `:keys:` role has no default key map."
+ )
+ keys_db = None
+
+
+class kbd_node(nodes.TextElement):
+ pass
+
+
+def map_filter(key: str, user_map: dict) -> Tuple[str, str]:
+ display = key.title()
+ cls = key.replace("_", "-").replace(" ", "-").lower()
+ if key in user_map.keys():
+ display = user_map[key]
+ if keys_db is not None:
+ if key in keys_db.aliases:
+ display = keys_db.keymap[keys_db.aliases[key]]
+ cls = keys_db.aliases[key]
+ return (cls, display)
+
+
+def visit_kbd(self: HTMLTranslator, node: kbd_node):
+ tag = "kbd" if self.builder.config["keys_strict"] else "span"
+ self.body.append(f'<{tag} class="' + f'{self.builder.config["keys_class"]}"')
+ keys = node.rawsource.split(self.builder.config["keys_separator"])
+
+ keys_out = ">"
+ for i, key in enumerate(keys):
+ cls, text = map_filter(key.strip().lower(), self.builder.config["keys_map"])
+ keys_out += f'{text}'
+ if i + 1 != len(keys):
+ keys_out += f'{self.builder.config["keys_separator"]}'
+ self.body.append(keys_out)
+
+
+def depart_kbd(self, node):
+ tag = "kbd" if self.builder.config["keys_strict"] else "span"
+ self.body.append(f"{tag}>")
+
+
+def visit_kbd_latex(self, node):
+ keys = node.rawsource.split(self.builder.config["keys_separator"])
+ for i, key in enumerate(keys):
+ _, text = map_filter(key.strip().lower(), self.builder.config["keys_map"])
+ self.body.append(text)
+ if i + 1 < len(keys):
+ self.body.append(f' {self.builder.config["keys_separator"]} ')
+
+
+def depart_kbd_latex(self, node):
+ pass
+
+
+def keys_role(
+ role, rawtext, text, lineno, inliner, options={}, content=[]
+) -> Tuple[List[nodes.Node], List[str]]:
+ keys_div = kbd_node(text)
+ return [keys_div], []
+
+
+def _config_inited(app: Sphinx, config: Config) -> None:
+ """Merge default `keys_db.keymap` with user-specified `keys_map` role option."""
+ if keys_db is not None and app.config["keys_map"].keys():
+ keys_db.keymap.update(**app.config["keys_map"])
+ app.config["keys_map"] = keys_db.keymap
+
+
+def setup(app: Sphinx):
+ app.add_config_value("keys_class", "keys", rebuild=True, types=str)
+ app.add_config_value("keys_strict", False, rebuild=True, types=bool)
+ app.add_config_value("keys_separator", "+", rebuild=True, types=str)
+ app.add_config_value("keys_map", {}, rebuild=True, types=dict)
+ app.add_role("keys", keys_role)
+ app.connect("config-inited", _config_inited)
+ app.add_node(
+ kbd_node,
+ html=(visit_kbd, depart_kbd),
+ latex=(visit_kbd_latex, depart_kbd_latex),
+ )
diff --git a/sphinx_immaterial/object_toc.py b/sphinx_immaterial/object_toc.py
index 936971f57..3de92dc63 100644
--- a/sphinx_immaterial/object_toc.py
+++ b/sphinx_immaterial/object_toc.py
@@ -15,7 +15,7 @@ def _monkey_patch_toc_tree_process_doc(app: sphinx.application.Sphinx):
"""
TocTreeCollector = sphinx.environment.collectors.toctree.TocTreeCollector
- # Apply the monkey pach
+ # Apply the monkey patch
orig_process_doc = TocTreeCollector.process_doc
def _make_section_from_desc(
diff --git a/sphinx_immaterial/task_lists.py b/sphinx_immaterial/task_lists.py
new file mode 100644
index 000000000..409c25984
--- /dev/null
+++ b/sphinx_immaterial/task_lists.py
@@ -0,0 +1,95 @@
+"""A custom directive that allows using checkboxes for lists"""
+from typing import List
+from docutils import nodes
+from docutils.parsers.rst import directives
+from sphinx.util.docutils import SphinxDirective
+from sphinx.application import Sphinx
+from sphinx.writers.html import HTMLTranslator
+
+
+def visit_checkbox_label(self: HTMLTranslator, node: nodes.Node):
+ attributes = {}
+ if node["custom"]:
+ attributes = {"class": "task-list-control"}
+ self.body.append(self.starttag(node, "label", **attributes))
+ self.body.append('")
+ if node["custom"]:
+ self.body.append('')
+
+
+def depart_checkbox_label(self: HTMLTranslator, node: nodes.Node):
+ self.body.append("")
+
+
+class checkbox_label(nodes.container):
+ pass
+
+
+class TaskListDirective(SphinxDirective):
+ """a special directive"""
+
+ has_content = True
+ optional_arguments = 4
+ option_spec = {
+ "name": directives.unchanged,
+ "class": directives.class_option,
+ "custom": directives.flag,
+ "clickable": directives.flag,
+ }
+
+ def run(self) -> List[nodes.Node]:
+ """Run the directive."""
+ self.assert_has_content()
+ task_list = nodes.container(
+ "", is_div=True, classes=self.options.get("class", [])
+ )
+ if self.options.get("name", ""):
+ self.add_name(task_list)
+ clickable = "clickable" in self.options or self.config["clickable_checkbox"]
+ custom = "custom" in self.options or self.config["custom_checkbox"]
+ self.state.nested_parse(self.content, self.content_offset, task_list)
+ self.set_source_info(task_list)
+
+ def first_matching(obj, cls_t):
+ return obj.first_child_matching_class(cls_t)
+
+ for child in task_list.children:
+ if isinstance(child, nodes.list_item):
+ child["classes"] = ["task-list"]
+
+ for li_ in child.children:
+ if isinstance(li_, nodes.list_item):
+ if li_.astext().startswith("["):
+ li_["classes"] = ["task-list-item"]
+ checked = li_.astext().lower().startswith("[x]")
+ first_para = first_matching(li_, nodes.paragraph)
+ if first_para is not None:
+ first_text = first_matching(li_[first_para], nodes.Text)
+ li_[first_para][first_text] = li_[first_para][
+ first_text
+ ].lstrip("[x] ")
+ li_[first_para][first_text] = li_[first_para][
+ first_text
+ ].lstrip("[ ] ")
+ checkbox = checkbox_label(
+ "",
+ custom=custom,
+ disabled=not clickable,
+ checked=checked,
+ )
+ li_.insert(0, checkbox)
+
+ return [task_list]
+
+
+def setup(app: Sphinx):
+ """Setup the extension."""
+ app.add_directive("task-list", TaskListDirective)
+ app.add_node(checkbox_label, html=(visit_checkbox_label, depart_checkbox_label))
+ app.add_config_value("custom_checkbox", False, rebuild="html", types=bool)
+ app.add_config_value("clickable_checkbox", False, rebuild="html", types=bool)
diff --git a/sphinx_immaterial/theme_result.py b/sphinx_immaterial/theme_result.py
new file mode 100644
index 000000000..b1f41eb24
--- /dev/null
+++ b/sphinx_immaterial/theme_result.py
@@ -0,0 +1,53 @@
+"""A directive designed to reduce example snippets duplication."""
+from docutils.parsers.rst import directives
+from docutils import nodes
+from sphinx.util.docutils import SphinxDirective
+from sphinx.directives.code import container_wrapper
+
+
+class ResultsDirective(SphinxDirective):
+ """Takes content as a rst code snippet and renders it after outputting it as a
+ literal code-block."""
+
+ has_content = True
+ optional_arguments = 1
+ final_argument_whitespace = True
+ option_spec = {
+ "class": directives.class_option,
+ "name": directives.unchanged,
+ "output-prefix": directives.unchanged,
+ }
+
+ def run(self):
+ """Run the directive."""
+ container_node = nodes.container(
+ "", classes=self.options.get("class", []) + ["results"]
+ )
+ code = "\n".join(self.content)
+ literal_node = nodes.literal_block(code, code)
+ literal_node["language"] = "rst"
+ if self.arguments:
+ literal_node = container_wrapper(self, literal_node, self.arguments[0])
+ container_node += literal_node
+
+ if "output-prefix" in self.options:
+ out_prefix = nodes.container("", classes=["results-prefix"])
+ prefix = self.options.get("output-prefix", "")
+ if not prefix:
+ prefix = "Which renders the following content:"
+ textnodes, _ = self.state.inline_text(prefix, self.lineno)
+ out_prefix += textnodes
+ container_node += out_prefix
+
+ # the `result` CSS class is theme specific (as used by mkdocs-material theme)
+ results_div = nodes.container("", classes=["result"])
+ self.state.nested_parse(self.content, self.content_offset, results_div)
+ container_node += results_div
+
+ self.set_source_info(container_node)
+ self.add_name(container_node)
+ return [container_node]
+
+
+def setup(app):
+ app.add_directive("rst-example", ResultsDirective)
diff --git a/src/assets/stylesheets/main/_api.scss b/src/assets/stylesheets/main/_api.scss
index 0d9fb8eed..03b027bed 100644
--- a/src/assets/stylesheets/main/_api.scss
+++ b/src/assets/stylesheets/main/_api.scss
@@ -45,7 +45,7 @@ $objinfo-icon-size: 16px;
font-weight: 700;
}
- a.reference > .sig-name {
+ a.reference > span {
color: var(--md-typeset-a-color);
&:hover {
@@ -65,9 +65,9 @@ $objinfo-icon-size: 16px;
color: var(--md-accent-fg-color);
}
+ // Ensure each parameter starts on a new line and is indented.
&.sig-wrap {
- .sig-param {
- // Ensure each parameter starts on a new line and is indented.
+ .sig-param-decl {
&::before {
white-space: pre;
// 5 spaces below result in 4 spaces of indent.
@@ -76,7 +76,7 @@ $objinfo-icon-size: 16px;
}
}
- .sig-param + .sig-paren {
+ .sig-paren:last-of-type {
// Ensure the final paren starts on a new line
&::before {
white-space: pre;
diff --git a/src/assets/stylesheets/main/_typeset.scss b/src/assets/stylesheets/main/_typeset.scss
index 336985544..af5bdf822 100644
--- a/src/assets/stylesheets/main/_typeset.scss
+++ b/src/assets/stylesheets/main/_typeset.scss
@@ -256,6 +256,14 @@ kbd {
}
}
+ // sphinx-immaterial: reset margin for code-blocks with a caption
+ .code-block-caption + .notranslate {
+ pre,
+ .highlighttable {
+ margin-top: 0;
+ }
+ }
+
// Keyboard key
kbd {
display: inline-block;
diff --git a/src/assets/stylesheets/main/extensions/pymdownx/_highlight.scss b/src/assets/stylesheets/main/extensions/pymdownx/_highlight.scss
index de8ecf923..0ae683473 100644
--- a/src/assets/stylesheets/main/extensions/pymdownx/_highlight.scss
+++ b/src/assets/stylesheets/main/extensions/pymdownx/_highlight.scss
@@ -322,7 +322,10 @@
}
// Code block result container
- :is(.highlight, .highlighttable) + .result {
+ // sphinx-immaterial: altered to support
+ // 1. docutils classes (.literal-block-wrapper, div[class^="highlight-"])
+ // 2. rst-result directive's output-prefix (.results-prefix)
+ :is(.highlight, .highlighttable, .literal-block-wrapper, div[class^="highlight-"], .results-prefix) + .result {
margin-top: calc(-1em + #{px2em(-2px)});
padding: 0 px2em(16px);
overflow: visible;
@@ -338,6 +341,20 @@
content: "";
}
}
+
+ // sphinx-immaterial: reset margin for rst-result directive's output-prefix
+ .results .results-prefix + .result {
+ margin-top: 0;
+ }
+
+ // sphinx-immaterial: use modified style from span.filename (see above)
+ .results .results-prefix {
+ margin-top: -1em;
+ padding: px2em(9px, 13.6px) px2em(16px, 13.6px);
+ font-weight: 700;
+ font-size: px2em(13.6px);
+ background-color: var(--md-code-bg-color);
+ }
}
// ----------------------------------------------------------------------------