diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 0000000..00fbe35 --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,38 @@ +version: 2 +jobs: + build_docs: + docker: + - image: circleci/python:3.6-stretch + steps: + # Get our data and merge with upstream + - run: sudo apt-get update + - checkout + + - restore_cache: + keys: + - cache-pip + + - run: pip install --user .[sphinx] + + - save_cache: + key: cache-pip + paths: + - ~/.cache/pip + + # Build the docs + - run: + name: Build docs to store + command: | + cd docs + make html + + - store_artifacts: + path: docs/_build/html/ + destination: html + + +workflows: + version: 2 + default: + jobs: + - build_docs diff --git a/docs/conf.py b/docs/conf.py index 53d823c..2937844 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -38,9 +38,9 @@ # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. -extensions = ["sphinx_togglebutton"] +extensions = ["myst_nb", "sphinx_togglebutton"] -togglebutton_selector = ".toggle, .secondtoggle" +# togglebutton_selector = ".toggle, .secondtoggle" # Add any paths that contain templates here, relative to this directory. templates_path = ["_templates"] diff --git a/docs/index.rst b/docs/index.rst index f992fcf..822cc42 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -7,23 +7,26 @@ sections of your page. For example, click the "+" button to the right: -.. note:: Here's a toggled admonition - :class: toggle +.. toggle:: + + .. note:: Here's a toggled admonition It was created with this code: -.. code:: rst +.. code-block:: rst - .. note:: Here's a toggled admonition - :class: toggle + .. toggle:: + + .. note:: Here's a toggled admonition - (admonition body here) +You can also add a title to your toggled block. The title will show up, +and the toggle button will change the block's content. For example: -And here's a code block: +.. toggle:: Toggle to see what's inside -.. container:: toggle + It's a code block! - .. code:: python + .. code-block:: python a = "wow, very python" print("this code should be toggle-able!") @@ -34,7 +37,7 @@ Installation You can install `sphinx-togglebutton` with `pip`: -.. code:: bash +.. code-block:: bash pip install sphinx-togglebutton @@ -47,7 +50,7 @@ to your extensions list. E.g.: -.. code:: python +.. code-block:: python extensions = [ ... @@ -55,12 +58,67 @@ E.g.: ... ] -Now, whenever you wish for an admonition to be toggle-able, add the -``:class: toggle`` parameter to the admonition directive that you use. + +The toggle directive +-------------------- + +To add toggle-able content, use the **toggle directive**. This directive +will wrap its content in a toggle-able container. You can call it like so: + +.. code-block:: rst + + .. toggle:: + + Here is my toggle-able content! + +The code above results in: + +.. toggle:: + + Here is my toggle-able content! + +You can also add titles to your toggle-able content: + +.. code-block:: rst + + .. toggle:: My title + + Here is my toggle-able content! + +Which results in: + + +.. toggle:: My title + + Here is my toggle-able content! + +To show the toggle-able content by default, use the ``:show:`` flag. + +.. code-block:: rst + + .. toggle:: + :show: + + Here is my toggle-able content! + +It results in the following: + +.. toggle:: + :show: + + Here is my toggle-able content! + + +Toggling content by adding classes +---------------------------------- + +You can also make elements toggle-able by adding the ``toggle`` class to +them. This can be done with admonitions and containers with the +``:class: my, classes`` keyword. For example, this code would create a toggle-able "note" admonition: -.. code:: rst +.. code-block:: rst .. note:: :class: toggle @@ -77,14 +135,9 @@ Here's how it looks: Clicking on the toggle button will toggle the item's visibility. -Show content by default ------------------------ +To show the content by default, add a ``toggle-shown`` class as well. -By default, all items with toggle buttons added to them will be hidden by -default. You may also **show the content by default**. To do so, add the -``toggle`` class *as well as* a ``toggle-shown`` class, like so: - -.. code:: rst +.. code-block:: rst .. note:: :class: toggle, toggle-shown @@ -98,28 +151,6 @@ This will generate the following block: This is my note. -Toggle any container of content -------------------------------- - -You can also use **containers** to add arbitrary toggle-able code. For example, -here's a container with an image inside: - -.. container:: toggle - - .. admonition:: Look at that, an image! - - .. image:: https://media.giphy.com/media/mW05nwEyXLP0Y/giphy.gif - -It was generated with this code: - -.. code:: rst - - .. container:: toggle - - .. admonition:: Look at that, an image! - - .. image:: https://media.giphy.com/media/mW05nwEyXLP0Y/giphy.gif - Here's how they look right after one another: .. note:: @@ -132,28 +163,14 @@ Here's how they look right after one another: This is my second. -Customize the selector words used to toggle content ---------------------------------------------------- - -``sphinx-togglebutton`` adds a toggle button to elements that are selected -by a CSS selection query. By default, this is ``.toggle``. You can customize -the query that is used with the following Sphinx parameter (in ``conf.py``): -.. code-block:: python - - togglebutton_selector = " +Configuration +============= -For example, the documentation with this site uses the following configuration -value: +You can control the "hint" text that is displayed next to togglebuttons when +their content is collapsed. To do so, use the following configuration variable +in your ``conf.py`` file: .. code-block:: python - togglebutton_selector = ".toggle, .secondtoggle" - -This means that any element with either of these classes will have toggle -buttons added to them. - -.. note:: - :class: secondtoggle - - A note with a ``.secondtoggle`` class. + togglebutton_hint = "My text" diff --git a/setup.py b/setup.py index 027a09f..82e4ec0 100644 --- a/setup.py +++ b/setup.py @@ -1,14 +1,20 @@ import os - +from pathlib import Path from setuptools import setup, find_packages -from sphinx_togglebutton import __version__ + +version = [ + line + for line in Path("sphinx_togglebutton/__init__.py").read_text().split() + if "__version__" in line +] +version = version[0].split(" = ")[-1] with open("./README.rst", "r") as ff: readme_text = ff.read() setup( name="sphinx-togglebutton", - version=__version__, + version=version, description="Add a toggle button to items on a page.", long_description=readme_text, long_description_content_type="text/x-rst", @@ -18,9 +24,9 @@ license="MIT License", packages=find_packages(), package_data={ - "sphinx_togglebutton": ["_static/togglebutton.css", "_static/togglebutton.js"] + "sphinx_togglebutton": ["_static/togglebutton.css_t", "_static/togglebutton.js"] }, - install_requires=["setuptools", "wheel", "sphinx"], - extras_require={"sphinx": ["sphinx"]}, + install_requires=["setuptools", "wheel", "sphinx", "docutils"], + extras_require={"sphinx": ["myst_nb"]}, classifiers=["License :: OSI Approved :: MIT License"], ) diff --git a/sphinx_togglebutton/__init__.py b/sphinx_togglebutton/__init__.py index 6ec0eb4..e45de75 100644 --- a/sphinx_togglebutton/__init__.py +++ b/sphinx_togglebutton/__init__.py @@ -1,5 +1,7 @@ """A small sphinx extension to add "toggle" buttons to items.""" import os +from docutils.parsers.rst import Directive, directives +from docutils import nodes __version__ = "0.0.3dev0" @@ -9,6 +11,11 @@ def st_static_path(app): app.config.html_static_path.append(static_path) +def add_to_context(app, config): + # Update the global context + config.html_context.update({'togglebutton_hint': config.togglebutton_hint}) + + # This function reads in a variable and inserts it into JavaScript def insert_custom_selection_config(app): # This is a configuration that you've specified for users in `conf.py` @@ -17,6 +24,34 @@ def insert_custom_selection_config(app): app.add_js_file(None, body=js_text) +class Toggle(Directive): + """Hide a block of markup text by wrapping it in a container.""" + + optional_arguments = 1 + final_argument_whitespace = True + has_content = True + + option_spec = {"id": directives.unchanged, "show": directives.flag} + + def run(self): + self.assert_has_content() + classes = ["toggle"] + if "show" in self.options: + classes.append("toggle-shown") + + if len(self.arguments) == 0: + parent = nodes.container(classes=classes) + self.state.nested_parse(self.content, self.content_offset, parent) + else: + parent = nodes.admonition(classes=["toggle-body"]) + title = nodes.title(self.arguments[0], self.arguments[0]) + body = nodes.container(classes=classes) + self.state.nested_parse(self.content, self.content_offset, body) + parent += title + parent += body + return [parent] + + # We connect this function to the step after the builder is initialized def setup(app): # Add our static path @@ -28,11 +63,13 @@ def setup(app): # Add the string we'll use to select items in the JS # Tell Sphinx about this configuration variable app.add_config_value("togglebutton_selector", ".toggle", "html") + app.add_config_value("togglebutton_hint", "Click to show", "html") app.add_js_file("togglebutton.js") # Run the function after the builder is initialized app.connect("builder-inited", insert_custom_selection_config) - + app.connect("config-inited", add_to_context) + app.add_directive("toggle", Toggle) return { "version": __version__, "parallel_read_safe": True, diff --git a/sphinx_togglebutton/_static/togglebutton.css b/sphinx_togglebutton/_static/togglebutton.css_t similarity index 62% rename from sphinx_togglebutton/_static/togglebutton.css rename to sphinx_togglebutton/_static/togglebutton.css_t index 5b8bd47..a9ac3d5 100644 --- a/sphinx_togglebutton/_static/togglebutton.css +++ b/sphinx_togglebutton/_static/togglebutton.css_t @@ -1,5 +1,9 @@ /* Visibility of the target */ -div.toggle-hidden { +.toggle { + transition: opacity .5s; +} + +.toggle-hidden { visibility: hidden; opacity: 0; height: 1.5em; @@ -7,6 +11,30 @@ div.toggle-hidden { padding: 0px !important; } +/* Toggle buttons inside admonitions so we see the title */ +.toggle-body { + position: relative; +} + +.toggle-body .admonition-title:after { + content: ""; +} + +.toggle-body button.toggle-button { + margin-right: 0.5em; + right: 0em; + position: absolute; + top: .3em; +} + +/* These should be totally hidden since they're inside an admonition */ + +.toggle-body .toggle-hidden * { + margin: 0em; + padding: 0em; +} + + /* General button style */ button.toggle-button { background: #999; @@ -24,10 +52,10 @@ button.toggle-button { } button.toggle-button.toggle-button-hidden:before { - content: "Click to show"; + content: "{{ togglebutton_hint }}"; position: absolute; - left: -7em; - bottom: .5em; + left: -6.5em; + bottom: .4em; } /* Plus / minus toggles */ diff --git a/sphinx_togglebutton/_static/togglebutton.js b/sphinx_togglebutton/_static/togglebutton.js index 0aecacd..894ef8a 100644 --- a/sphinx_togglebutton/_static/togglebutton.js +++ b/sphinx_togglebutton/_static/togglebutton.js @@ -24,6 +24,7 @@ var initToggleItems = () => { var toggleHidden = (button) => { target = button.dataset['target'] var itemToToggle = document.getElementById(target); + console.log(itemToToggle) if (itemToToggle.classList.contains("toggle-hidden")) { itemToToggle.classList.remove("toggle-hidden"); button.classList.remove("toggle-button-hidden");