Skip to content

Commit 99f2521

Browse files
authored
ENH: Add social card previews (#88)
* First pass at adding social card previews * Refactor social card generation * Fixing tests * Document nox * Package data * Fix plt objects path * Add matplotlib to dev requirements * Run black * Fix path separator * Blackify everything * Extra strip * Strip image path * Oh god please fix it * Strips
1 parent 1c4aadb commit 99f2521

16 files changed

+575
-4
lines changed

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -286,4 +286,7 @@ $RECYCLE.BIN/
286286
# Windows shortcuts
287287
*.lnk
288288

289-
# End of https://www.toptal.com/developers/gitignore/api/windows,linux,python,pycharm,visualstudiocode
289+
# End of https://www.toptal.com/developers/gitignore/api/windows,linux,python,pycharm,visualstudiocode
290+
291+
# Assets that are built by sphinx
292+
docs/tmp

README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
[![Build](https://github.com/wpilibsuite/sphinxext-opengraph/workflows/Test%20and%20Deploy/badge.svg)](https://github.com/wpilibsuite/sphinxext-opengraph/actions)
44
[![Code style: Black](https://img.shields.io/badge/code%20style-Black-000000.svg)](https://github.com/psf/black)
55

6-
Sphinx extension to generate [Open Graph metadata](https://ogp.me/).
6+
Sphinx extension to generate [Open Graph metadata](https://ogp.me/) for each page of your documentation.
77

88
## Installation
99

@@ -30,6 +30,9 @@ Users hosting documentation on Read The Docs *do not* need to set any of the fol
3030
* Configure the amount of characters taken from a page. The default of 200 is probably good for most people. If something other than a number is used, it defaults back to 200.
3131
* `ogp_site_name`
3232
* This is not required. Name of the site. This is displayed above the title. Defaults to the Sphinx [`project`](https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-project) config value. Set to `False` to unset and use no default.
33+
* `ogp_social_cards`
34+
* Configuration for automatically creating social media card PNGs for each page.
35+
For more information, see [the social media cards docs](docs/source/socialcards.md).
3336
* `ogp_image`
3437
* This is not required. Link to image to show. Note that all relative paths are converted to be relative to the root of the html output as defined by `ogp_site_url`.
3538
* `ogp_image_alt`

dev-requirements.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
sphinx
2+
matplotlib
23
wheel==0.37.1
34
pytest==7.1.3
45
beautifulsoup4==4.11.1
5-
setuptools==65.4.1
6+
setuptools==65.4.1

docs/requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
myst-parser==0.18.1
22
furo==2022.9.29
33
sphinx==5.2.3
4+
sphinx-design
45
./
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
"""
2+
A helper script to test out what social previews look like.
3+
I should remove this when I'm happy with the result.
4+
"""
5+
# %load_ext autoreload
6+
# %autoreload 2
7+
8+
from pathlib import Path
9+
from textwrap import dedent
10+
from sphinxext.opengraph.socialcards import (
11+
render_social_card,
12+
MAX_CHAR_PAGE_TITLE,
13+
MAX_CHAR_DESCRIPTION,
14+
)
15+
import random
16+
17+
here = Path(__file__).parent
18+
19+
# Dummy lorem text
20+
lorem = """
21+
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum
22+
""".split() # noqa
23+
24+
kwargs_fig = dict(
25+
image=here / "../source/_static/og-logo.png",
26+
image_mini=here / "../../sphinxext/opengraph/_static/sphinx-logo-shadow.png",
27+
)
28+
29+
print("Generating previews of social media cards...")
30+
plt_objects = None
31+
embed_text = []
32+
for perm in range(20):
33+
# Create dummy text description and pagetitle for this iteration
34+
random.shuffle(lorem)
35+
title = " ".join(lorem[:100])
36+
title = title[: MAX_CHAR_PAGE_TITLE - 3] + "..."
37+
38+
random.shuffle(lorem)
39+
desc = " ".join(lorem[:100])
40+
desc = desc[: MAX_CHAR_DESCRIPTION - 3] + "..."
41+
42+
path_tmp = Path(here / "../tmp")
43+
path_tmp.mkdir(exist_ok=True)
44+
path_out = Path(path_tmp / f"num_{perm}.png")
45+
46+
plt_objects = render_social_card(
47+
path=path_out,
48+
site_title="Sphinx Social Card Demo",
49+
page_title=title,
50+
description=desc,
51+
siteurl="sphinxext-opengraph.readthedocs.io",
52+
plt_objects=plt_objects,
53+
kwargs_fig=kwargs_fig,
54+
)
55+
56+
path_examples_page_folder = here / ".."
57+
embed_text.append(
58+
dedent(
59+
f"""
60+
````{{grid-item}}
61+
```{{image}} ../{path_out.relative_to(path_examples_page_folder)}
62+
```
63+
````
64+
"""
65+
)
66+
)
67+
68+
embed_text = "\n".join(embed_text)
69+
embed_text = f"""
70+
`````{{grid}} 2
71+
:gutter: 5
72+
73+
{embed_text}
74+
`````
75+
"""
76+
77+
# Write markdown text that we can use to embed these images in the docs
78+
(here / "../tmp/embed.txt").write_text(embed_text)
79+
80+
print("Done generating previews of social media cards...")

docs/source/_static/og-logo.png

4.6 KB
Loading

docs/source/conf.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#
1313
import os
1414
import sys
15+
from subprocess import run
1516

1617
sys.path.insert(0, os.path.abspath("../.."))
1718

@@ -33,6 +34,7 @@
3334
# ones.
3435
extensions = [
3536
"myst_parser",
37+
"sphinx_design",
3638
"sphinxext.opengraph",
3739
]
3840

@@ -49,4 +51,23 @@
4951
# The theme to use for HTML and HTML Help pages. See the documentation for
5052
# a list of builtin themes.
5153
#
54+
html_title = "sphinxext-opengraph"
55+
html_logo = "_static/og-logo.png"
5256
html_theme = "furo"
57+
58+
59+
# -- Configuration for this theme --------------------------------------------
60+
61+
ogp_site_url = "https://sphinxext-opengraph.readthedocs.io/en/latest/"
62+
63+
# Configuration for testing but generally we use the defaults
64+
# Uncomment lines to see their effect.
65+
ogp_social_cards = {
66+
"site_url": "sphinxext-opengraph.readthedocs.io",
67+
# "image": "TODO: add another image to test",
68+
# "line_color": "#4078c0",
69+
}
70+
71+
# Generate sample social media preview images
72+
path_script = os.path.abspath("../script/generate_social_card_previews.py")
73+
run(f"python {path_script}", shell=True)

docs/source/index.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
11
```{include} ../../README.md
22
:relative-images:
3+
:relative-docs: docs/source
4+
```
5+
6+
```{toctree}
7+
:hidden:
8+
socialcards
39
```

docs/source/socialcards.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Social media card images
2+
3+
This extension will automatically generate a PNG meant for sharing documentation links on social media platforms.
4+
These cards display metadata about the page that you link to, and are meant to catch the attention of readers.
5+
6+
See [the opengraph.xyz website](https://www.opengraph.xyz/) for a way to preview what your social media cards look like.
7+
Here's an example of what the card for this page looks like:
8+
9+
% This is auto-generated at build time
10+
```{image} ../tmp//num_0.png
11+
:width: 500
12+
```
13+
14+
## Disable card images
15+
16+
To disable social media card images, use the following configuration:
17+
18+
```{code-block} python
19+
:caption: conf.py
20+
21+
ogp_social_cards = {
22+
"enable": False
23+
}
24+
```
25+
26+
## Customize the card
27+
28+
There are several customization options to change the text and look of the social media preview card.
29+
Below is a summary of these options.
30+
31+
- **`site_url`**: Set a custom site URL.
32+
- **`image`**: Over-ride the top-right image (by default, `html_logo` is used).
33+
- **`line_color`**: Color of the border line at the bottom of the card, in hex format.
34+
% TODO: add an over-ride for each part of the card.
35+
36+
## Example social cards
37+
38+
Below are several social cards to give an idea for how this extension behaves with different length and size of text.
39+
40+
```{include} ../tmp/embed.txt
41+
```

noxfile.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
"""
2+
Configuration to automatically run jobs and tests via `nox`.
3+
For example, to build the documentation with a live server:
4+
5+
nox -s docs -- live
6+
7+
List available jobs:
8+
9+
nox -l
10+
11+
ref: https://nox.thea.codes/
12+
"""
13+
import nox
14+
from shlex import split
15+
16+
nox.options.reuse_existing_virtualenvs = True
17+
18+
19+
@nox.session
20+
def docs(session):
21+
"""Build the documentation. Use `-- live` to build with a live server."""
22+
session.install("-e", ".")
23+
session.install("-r", "docs/requirements.txt")
24+
if "live" in session.posargs:
25+
session.install("ipython")
26+
session.install("sphinx-autobuild")
27+
session.run(*split("sphinx-autobuild -b html docs/source docs/build/html"))
28+
else:
29+
session.run(
30+
*split("sphinx-build -nW --keep-going -b html docs/source docs/build/html")
31+
)
32+
33+
34+
@nox.session
35+
def test(session):
36+
"""Run the test suite."""
37+
session.install(".")
38+
session.run(*(["pytest"] + session.posargs))

0 commit comments

Comments
 (0)