Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NEW: Add sidenote and marginnote syntax #546

Merged
merged 48 commits into from
May 19, 2022
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
692f2f7
simple sidenote in footnote example
AakashGfude Mar 30, 2022
652f0c9
adding footnote in get started
AakashGfude Mar 30, 2022
ec9f164
replacing footnote and footnote reference with sidenote Node
AakashGfude Apr 5, 2022
4c51efc
added use_sidenotes config
AakashGfude Apr 5, 2022
3a955f1
adding comments and checks
AakashGfude Apr 6, 2022
9b128a3
undoing docs changes here
AakashGfude Apr 6, 2022
6c06065
removed use_sidenotes: True
AakashGfude Apr 6, 2022
eaad995
added marginnotes as well
AakashGfude Apr 7, 2022
41b52b2
Updating documentation about marginnotes
choldgraf Mar 16, 2022
426d77a
marginnote unique label
AakashGfude Apr 7, 2022
bcd7d29
color for clickable buttons
AakashGfude Apr 7, 2022
8743e2f
Merge branch 'master' into footnote-sidenote
AakashGfude Apr 8, 2022
9b2ddca
checking for latexbuilder
AakashGfude Apr 8, 2022
b783e9e
checking for html builder
AakashGfude Apr 8, 2022
a2ab275
removed latex handling in node
AakashGfude Apr 8, 2022
6b5d97b
formats = html
AakashGfude Apr 8, 2022
73a1da4
testing sidenotes and marginnotes
AakashGfude Apr 12, 2022
8cc71d9
adding pandoc-sidenote in docs
AakashGfude Apr 13, 2022
3195e22
Update docs/content-blocks.md
choldgraf Apr 25, 2022
7db02f1
Merge branch 'master' into footnote-sidenote
choldgraf Apr 25, 2022
e1800a6
Merge branch 'master' into footnote-sidenote
choldgraf Apr 25, 2022
83a5bc7
Update docs/content-blocks.md
AakashGfude May 9, 2022
75d40af
user-select
AakashGfude May 9, 2022
fa96ad5
Merge branch 'master' into footnote-sidenote
choldgraf May 9, 2022
dcfc91d
Merge branch 'footnote-sidenote' of https://github.com/AakashGfude/sp…
AakashGfude May 11, 2022
ac9dcab
nested footnotes/sidenotes
AakashGfude May 11, 2022
593c0a1
Update docs/reference/special-theme-elements.md
AakashGfude May 11, 2022
bb485b6
reducing indentation
AakashGfude May 11, 2022
77e2cdb
Update src/sphinx_book_theme/_transforms.py
AakashGfude May 11, 2022
037e36b
Update src/sphinx_book_theme/_transforms.py
AakashGfude May 11, 2022
ac408dd
merging
AakashGfude May 11, 2022
1a4a531
mobile for inside admonition
AakashGfude May 13, 2022
ff53668
Update src/sphinx_book_theme/_transforms.py
AakashGfude May 13, 2022
d7d1a0d
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 13, 2022
8098e03
Update src/sphinx_book_theme/_transforms.py
AakashGfude May 13, 2022
3319a18
Update src/sphinx_book_theme/_transforms.py
AakashGfude May 13, 2022
a3bfaa8
Update src/sphinx_book_theme/_transforms.py
AakashGfude May 13, 2022
b11129a
Update src/sphinx_book_theme/assets/styles/content/_margin.scss
AakashGfude May 13, 2022
a87245f
sidenoteNode docstring, renaming variables in transform, d-none
AakashGfude May 13, 2022
ceae725
resolving conflicts
AakashGfude May 13, 2022
f5efddf
added comments for foot_node
AakashGfude May 13, 2022
cb2da87
Update src/sphinx_book_theme/assets/styles/base/_base.scss
AakashGfude May 13, 2022
b6a9585
Merge branch 'master' into footnote-sidenote
choldgraf May 17, 2022
4282271
d-none
AakashGfude May 18, 2022
76aa1d8
keeping d-n for now
AakashGfude May 18, 2022
d2ea70a
Clean up docs and add examples
choldgraf May 19, 2022
9522bce
Popout -> margin
choldgraf May 19, 2022
293c8aa
Update src/sphinx_book_theme/assets/styles/base/_base.scss
choldgraf May 19, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@
"use_issues_button": True,
"use_repository_button": True,
"use_download_button": True,
"use_sidenotes": True,
"logo_only": True,
"show_toc_level": 2,
"announcement": (
Expand Down
204 changes: 131 additions & 73 deletions docs/content-blocks.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,32 +85,87 @@ but I'll stop here.
````
`````

## Sidebars
(margin:sidenote)=
## Sidenotes and marginnotes

This theme has support for [Tufte-stype margin / side notes](https://edwardtufte.github.io/tufte-css/).

Sidenotes are numbered, and behave like footnotes, except they live in the margin and don’t force the reader to jump their eye to the bottom of the page.
For example, here is a sidenote[^ex].
On narrow screens, sidenotes are hidden until a user clicks the number.
If you're on a mobile device, try clicking the sidenote number above.

[^ex]: Here's my sidenote text!

On narrow screens, this text won't show up unless you click the superscript number!

Marginnotes are not numbered, but behave the same way as sidenotes.
On mobile devices a symbol will be displayed that will display the marginnote when clicked[^exmn].
For example, there's a marginnote in the previous sentence, and you should see a symbol show to display it on mobile screens.

[^exmn]: {-} This is a margin note. Notice there isn’t a number preceding the note.

:::{seealso}
AakashGfude marked this conversation as resolved.
Show resolved Hide resolved
Sidenotes and marginnotes are inline content - you cannot use block-level content inside of these notes.
If you'd like to use block-level content in the margins, see [](margin:block).
:::

### Activate sidenotes and marginnotes

The theme activates sidenotes and marginnotes by over-riding footnote syntax to instead exist in the margin.

To convert your footnotes to *instead* be sidenotes/marginnotes, use this configuration:

```python
html_theme_options = {
...
"use_sidenotes": True,
...
}
```

This will turn your **footnotes** into **sidenotes** or **marginnotes**.

### Create a sidenote

For example, the following sentence defines a sidenote and its respective content:

There are two different kinds of sidebar-like content in `sphinx-book-theme`,
typical `{sidebar}` directives, as well as a theme-specific `{margin}` directive.
This section covers both. Both allow you to place extra content
separately from your main content.
```markdown
Here's my sentence and a sidenote[^sn1].

```{tip}
Sidebar content will generally overlap with the white space where your site's
table of contents lives. When the reader scrolls sidebar content into view, the
right TOC should hide itself automatically.
[^sn1]: And here's my sidenote content.
```

### Margin content
Here's my sentence and a sidenote[^sn1].

You can specify content that should exist in the right margin. This will behave
like a regular sidebar until the screen hits a certain width, at which point this
content will "pop out" to the right white space.
[^sn1]: And here's my sidenote content.

There are two ways to add content to the margin: via the `{margin}` directive, and via adding CSS classes to your own content.
### Create a marginnote

#### Use a `{margin}` directive to add margin content
Marginnotes are defined by adding `{-}` at the beginning of the content block.
For example, the following syntax defines a marginnote:

The `{margin}` directive allows you to create margin content with your own title and content block.
```markdown
Here's my sentence and a marginnote[^mn1].

[^mn1]: {-} And here's my marginnote content.
```

Here's my sentence and a marginnote[^mn1].

[^mn1]: {-} And here's my marginnote content.


(margin:block)=
## Block margin content with the `{margin}` directive

The `{margin}` directive allows you to create block-level margin content with an optional title.
It is a wrapper around the Sphinx `{sidebar}` directive, and largely does its magic via CSS classes (see below).

:::{seealso}
If you'd like in-line margin content with numbered references, see [](margin:sidenote).
:::

Here's how you can use the `{margin}` directive:

```{margin} **Here is my margin content**
Expand All @@ -123,7 +178,39 @@ Here is my margin content, it is pretty cool!
```
````

#### Use CSS classes to add margin content
## Figure captions in the margin

You can configure figures to use the margin for captions.
Here is a figure with a caption to the right.

```{figure} images/cool.jpg
---
width: 60%
figclass: margin-caption
alt: My figure text
name: myfig5
---
And here is my figure caption, if you look to the left, you can see that COOL is in big red letters. But you probably already noticed that, really I am just taking up space to see how the margin caption looks like when it is really long :-).
```

And the text that produced it:

````
```{figure} images/cool.jpg
---
width: 60%
figclass: margin-caption
alt: My figure text
name: myfig5
---
And here is my figure caption, if you look to the left, you can see that COOL is in big red letters. But you probably already noticed that, really I am just taking up space to see how the margin caption looks like when it is really long :-)
```
````

We can reference the figure with {ref}`this reference <myfig5>`. Or a numbered reference like
{numref}`myfig5`.

### CSS classes for custom margin content

You may also directly add CSS classes to elements on your page in order to make them behave like margin content.
To do so, add the `margin` CSS class to any element on the page.
Expand Down Expand Up @@ -174,65 +261,10 @@ And here is my figure caption
We can reference the figure with {ref}`myfig4`. Or a numbered reference like
{numref}`myfig4`.

#### Figure captions in the margin

You can configure figures to use the margin for captions.
Here is a figure with a caption to the right.

```{figure} images/cool.jpg
---
width: 60%
figclass: margin-caption
alt: My figure text
name: myfig5
---
And here is my figure caption, if you look to the left, you can see that COOL is in big red letters. But you probably already noticed that, really I am just taking up space to see how the margin caption looks like when it is really long :-).
```

And the text that produced it:

````
```{figure} images/cool.jpg
---
width: 60%
figclass: margin-caption
alt: My figure text
name: myfig5
---
And here is my figure caption, if you look to the left, you can see that COOL is in big red letters. But you probably already noticed that, really I am just taking up space to see how the margin caption looks like when it is really long :-)
```
````

We can reference the figure with {ref}`this reference <myfig5>`. Or a numbered reference like
{numref}`myfig5`.

### Content sidebars

Content sidebars exist in-line with your text, but allow the rest of the
page to flow around them, rather than moving to the right margin.
To add content sidebars, use this syntax:

````{sidebar} **My sidebar title**
```{note}
Here is my sidebar content, it is pretty cool!
```
![](images/cool.jpg)
````

Note how the content wraps around the sidebar to the right.
However, the sidebar text will still be in line with your content. There are
certain kinds of elements, such as "note" blocks and code cells, that may
clash with your sidebar. If this happens, try using a `{margin}` instead.

````
```{sidebar} **My sidebar title**
Here is my sidebar content, it is pretty cool!
```
````

### Adding content to margins and sidebars

Sidebar/margin content can include all kinds of things, such as code blocks:
Margin content can include all kinds of things, such as code blocks:

````{margin} Code blocks in margins
```python
Expand Down Expand Up @@ -266,6 +298,7 @@ Wow, a note with an image in a margin!
````
`````


## Full-width content

Full-width content extends into the right margin, making it stand out against
Expand All @@ -292,3 +325,28 @@ If you are using a Jupyter Notebook as inputs to your documentation using the
[MyST-NB extension](https://myst-nb.readthedocs.io/en/latest/), you can trigger
this behavior with a code cell by adding a `full-width` tag to the cell.
```


## Sidebars

Content sidebars exist in-line with your text, but allow the rest of the
page to flow around them, rather than moving to the right margin.
To add content sidebars, use this syntax:

````{sidebar} **My sidebar title**
```{note}
Here is my sidebar content, it is pretty cool!
```
![](images/cool.jpg)
````

Note how the content wraps around the sidebar to the right.
However, the sidebar text will still be in line with your content. There are
certain kinds of elements, such as "note" blocks and code cells, that may
clash with your sidebar. If this happens, try using a `{margin}` instead.

````
```{sidebar} **My sidebar title**
Here is my sidebar content, it is pretty cool!
```
````
12 changes: 11 additions & 1 deletion docs/reference/special-theme-elements.md
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,6 @@ And here is my figure caption, if you look to the left, you can see that COOL is
This note should not overlap with the margin caption!
:::


Entire figures in the margin:

```{figure} ../images/cool.jpg
Expand All @@ -271,6 +270,17 @@ alt: My figure text
This figure should be entirely in the margin.
```

## Sidenotes and marginnotes

Here's a sentence[^sn1] with multiple [^sn2] sidenotes.

[^sn1]: Test sidenote 1.
[^sn2]: Test sidenote 2.

Here's a sentence[^mn1] with multiple marginnotes[^mn2].

[^mn1]: {-} Test marginnote 1.
[^mn2]: {-} Test marginnote 2.

## Nested admonitions
AakashGfude marked this conversation as resolved.
Show resolved Hide resolved

Expand Down
12 changes: 10 additions & 2 deletions src/sphinx_book_theme/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@
from functools import lru_cache

from docutils.parsers.rst.directives.body import Sidebar
from docutils import nodes
from docutils import nodes as docutil_nodes
from sphinx.application import Sphinx
from sphinx.locale import get_translation
from sphinx.util import logging

from .nodes import SideNoteNode
from .header_buttons import prep_header_buttons, add_header_buttons
from .header_buttons.launch import add_launch_buttons
from ._transforms import HandleFootnoteTransform

__version__ = "0.3.2"
"""sphinx-book-theme version"""
Expand Down Expand Up @@ -43,7 +45,7 @@ def add_metadata_to_page(app, pagename, templatename, context, doctree):
# Add a shortened page text to the context using the sections text
if doctree:
description = ""
for section in doctree.traverse(nodes.section):
for section in doctree.traverse(docutil_nodes.section):
description += section.astext().replace("\n", " ")
description = description[:160]
context["page_description"] = description
Expand Down Expand Up @@ -177,6 +179,9 @@ def setup(app: Sphinx):
app.connect("html-page-context", add_metadata_to_page)
app.connect("html-page-context", hash_html_assets)

# Nodes
SideNoteNode.add_node(app)

# Header buttons
app.connect("html-page-context", prep_header_buttons)
app.connect("html-page-context", add_launch_buttons)
Expand All @@ -186,6 +191,9 @@ def setup(app: Sphinx):
# Directives
app.add_directive("margin", Margin)

# Post-transforms
app.add_post_transform(HandleFootnoteTransform)

# Update templates for sidebar
app.config.templates_path.append(os.path.join(theme_dir, "components"))

Expand Down
50 changes: 50 additions & 0 deletions src/sphinx_book_theme/_transforms.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
from sphinx.transforms.post_transforms import SphinxPostTransform
from typing import Any
from docutils import nodes as docutil_nodes
from .nodes import SideNoteNode


class HandleFootnoteTransform(SphinxPostTransform):

default_priority = 1

def apply(self, **kwargs: Any) -> None:
theme_options = self.env.config.html_theme_options
if theme_options.get("use_sidenotes", False) is True:
AakashGfude marked this conversation as resolved.
Show resolved Hide resolved
for node in self.document.traverse(docutil_nodes.footnote_reference):
parent = None
for ftnode in self.document.traverse(docutil_nodes.footnote):
# matching the footnote reference with footnote
if (
len(ftnode.attributes["backrefs"])
and ftnode.attributes["backrefs"][0]
== node.attributes["ids"][0]
):
parent = ftnode.parent
text = ftnode.children[1].astext()

sidenote = SideNoteNode()
para = docutil_nodes.inline()
label = ftnode.children[0].astext()
if text.startswith("{-}"):
# marginnotes
AakashGfude marked this conversation as resolved.
Show resolved Hide resolved
para.attributes["classes"].append("marginnote")
para.append(docutil_nodes.Text(text.replace("{-}", "")))

sidenote.attributes["names"].append(
f"marginnote-role-{label}"
)
else:
# sidenotes
AakashGfude marked this conversation as resolved.
Show resolved Hide resolved
superscript = docutil_nodes.superscript("", label)
para.attributes["classes"].append("sidenote")
para.extend([superscript, docutil_nodes.Text(text)])

sidenote.attributes["names"].append(
f"sidenote-role-{label}"
)
sidenote.append(superscript)
node.replace_self([sidenote, para])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess somewhere around here we'd need to look for a parent block and place the para in the parent instead of right next to the sidenote? Feels like this might be too much complexity to worry about this edge-case...

break
if parent:
parent.remove(ftnode)
2 changes: 2 additions & 0 deletions src/sphinx_book_theme/assets/scripts/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,8 @@ var initTocHide = () => {
// Set up the intersection observer to watch all margin content
let tocObserver = new IntersectionObserver(hideTocCallback);
const selectorClasses = [
"marginnote",
"sidenote",
"margin",
"margin-caption",
"full-width",
Expand Down
Loading