Skip to content

Commit bf59ae8

Browse files
committed
✨ Add article-info directive
1 parent a15afa3 commit bf59ae8

File tree

13 files changed

+321
-91
lines changed

13 files changed

+321
-91
lines changed

MANIFEST.in

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,5 @@ include README.md
1919
include sphinx_design/py.typed
2020
include sphinx_design/compiled/style.min.css
2121
include sphinx_design/compiled/sd_tabs.js
22-
include sphinx_design/compiled/opticon_LICENSE
23-
include sphinx_design/compiled/opticons.json
22+
include sphinx_design/compiled/octicon_LICENSE
23+
include sphinx_design/compiled/octicons.json

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ grids items cannot contain headers; is this in anyway possible with docutils str
4848

4949
naming of directives/roles: standard prefix?
5050

51+
why are cards setup with "word-wrap: break-word;"?
52+
5153
check grid-items and tab-items are inside parents (or auto-wrap?)
5254

5355
handle latex

docs/images/mugshot.jpeg

238 KB
Loading

docs/index.md

Lines changed: 84 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,19 @@
11
# sphinx-design
22

3+
```{article-info}
4+
:avatar: images/mugshot.jpeg
5+
:avatar-link: https://github.com/chrisjsewell
6+
:author: "[Chris Sewell](https://github.com/chrisjsewell)"
7+
:date: "{sub-ref}`today`"
8+
:read-time: "{sub-ref}`wordcount-minutes` min read"
9+
```
10+
311
A sphinx extension for designing beautiful, size responsive web components.
412

513
Created with inspiration from [Bootstrap](https://getbootstrap.com/) (v5), [Material Design](https://material.io) and [Material-UI](https://material-ui.com/) design frameworks.
614

15+
(cards)=
16+
717
## Cards
818

919
:::{card} Align Center
@@ -32,6 +42,8 @@ Content
3242

3343
paragraph
3444

45+
(grids)=
46+
3547
## Grids
3648

3749
::::{grid} 1 2 2 3
@@ -159,67 +171,7 @@ E
159171

160172
::::::
161173

162-
(badges)=
163-
164-
## Badges
165-
166-
- {bdg}`plain badge`
167-
- {bdg-primary}`primary` {bdg-primary-line}`primary-line`
168-
- {bdg-secondary}`secondary` {bdg-secondary-line}`secondary-line`
169-
- {bdg-success}`success` {bdg-success-line}`success-line`
170-
- {bdg-info}`info` {bdg-info-line}`info-line`
171-
- {bdg-warning}`warning` {bdg-warning-line}`warning-line`
172-
- {bdg-danger}`danger` {bdg-danger-line}`danger-line`
173-
- {bdg-light}`light` {bdg-light-line}`light-line`
174-
- {bdg-dark}`dark` {bdg-dark-line}`dark-line`
175-
176-
{bdg-link-primary}`name <https://example.com>`
177-
178-
{bdg-link-primary-line}`name <https://example.com>`
179-
180-
{bdg-ref-primary}`badges`
181-
182-
(buttons)=
183-
184-
### Buttons
185-
186-
```{button-link} https://example.com
187-
```
188-
189-
```{button-ref} buttons
190-
```
191-
192-
```{button-link} https://example.com
193-
Button text
194-
```
195-
196-
```{button-ref} buttons
197-
Button text
198-
```
199-
200-
```{button-link} https://example.com
201-
:color: primary
202-
```
203-
204-
```{button-link} https://example.com
205-
:color: primary
206-
:outline:
207-
```
208-
209-
```{button-link} https://example.com
210-
:color: secondary
211-
:expand:
212-
```
213-
214-
:::{card} Card with an expanded button
215-
:hover:
216-
217-
```{button-link} https://example.com
218-
:color: info
219-
:click-parent:
220-
```
221-
222-
:::
174+
(dropdown)=
223175

224176
## Dropdown
225177

@@ -261,11 +213,7 @@ Dropdown content
261213

262214
:::::
263215

264-
## Icons
265-
266-
Some {opticon-16}`report;sd-text-info` middle {opticon-24}`report` more text
267-
268-
{fas}`spinner;sd-bg-primary sd-bg-text-primary fa-2x`
216+
(tabs)=
269217

270218
## Tabs
271219

@@ -356,3 +304,73 @@ Content 2
356304
:::::
357305

358306
::::::
307+
308+
(badges)=
309+
310+
## Badges
311+
312+
- {bdg}`plain badge`
313+
- {bdg-primary}`primary` {bdg-primary-line}`primary-line`
314+
- {bdg-secondary}`secondary` {bdg-secondary-line}`secondary-line`
315+
- {bdg-success}`success` {bdg-success-line}`success-line`
316+
- {bdg-info}`info` {bdg-info-line}`info-line`
317+
- {bdg-warning}`warning` {bdg-warning-line}`warning-line`
318+
- {bdg-danger}`danger` {bdg-danger-line}`danger-line`
319+
- {bdg-light}`light` {bdg-light-line}`light-line`
320+
- {bdg-dark}`dark` {bdg-dark-line}`dark-line`
321+
322+
{bdg-link-primary}`name <https://example.com>`
323+
324+
{bdg-link-primary-line}`name <https://example.com>`
325+
326+
{bdg-ref-primary}`badges`
327+
328+
(buttons)=
329+
330+
## Buttons
331+
332+
```{button-link} https://example.com
333+
```
334+
335+
```{button-ref} buttons
336+
```
337+
338+
```{button-link} https://example.com
339+
Button text
340+
```
341+
342+
```{button-ref} buttons
343+
Button text
344+
```
345+
346+
```{button-link} https://example.com
347+
:color: primary
348+
```
349+
350+
```{button-link} https://example.com
351+
:color: primary
352+
:outline:
353+
```
354+
355+
```{button-link} https://example.com
356+
:color: secondary
357+
:expand:
358+
```
359+
360+
:::{card} Card with an expanded button
361+
:hover:
362+
363+
```{button-link} https://example.com
364+
:color: info
365+
:click-parent:
366+
```
367+
368+
:::
369+
370+
(icons)=
371+
372+
## Icons
373+
374+
Some {octicon-16}`report;sd-text-info` middle {octicon-24}`report` more text
375+
376+
{fas}`spinner;sd-bg-primary sd-bg-text-primary fa-2x`

sphinx_design/article_info.py

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
from typing import List, Optional
2+
3+
from docutils import nodes
4+
from docutils.parsers.rst import directives
5+
from sphinx.application import Sphinx
6+
from sphinx.util.docutils import SphinxDirective
7+
8+
from .icons import get_octicon
9+
from .shared import create_component
10+
11+
12+
def setup_article_info(app: Sphinx):
13+
"""Setup the article information components."""
14+
app.add_directive("article-info", ArticleInfoDirective)
15+
16+
17+
class ArticleInfoDirective(SphinxDirective):
18+
""" """
19+
20+
has_content = False
21+
required_arguments = 0
22+
optional_arguments = 0
23+
option_spec = {
24+
"avatar": directives.uri,
25+
"avatar-alt": directives.unchanged,
26+
"avatar-link": directives.uri,
27+
"author": directives.unchanged_required,
28+
"date": directives.unchanged_required,
29+
"read-time": directives.unchanged_required,
30+
"class": directives.class_option,
31+
}
32+
33+
def _parse_text(
34+
self, text: str, icon: Optional[nodes.Node] = None, parse: bool = False
35+
) -> nodes.Node:
36+
"""Parse the text."""
37+
if not parse:
38+
output = ([icon] if icon else []) + [nodes.Text(text)]
39+
else:
40+
text_nodes, _ = self.state.inline_text(text, self.lineno)
41+
text_nodes = ([icon] if icon else []) + text_nodes
42+
para = nodes.paragraph("", "", *text_nodes, classes=["sd-p-0", "sd-m-0"])
43+
self.set_source_info(para)
44+
output = [para]
45+
return output
46+
47+
def run(self) -> List[nodes.Node]:
48+
"""Run the directive."""
49+
parse_fields = True # parse field text
50+
51+
top_grid = create_component(
52+
"grid-container",
53+
[
54+
"sd-container-fluid",
55+
"sd-sphinx-override",
56+
"sd-p-0",
57+
"sd-mt-2",
58+
"sd-mb-4",
59+
]
60+
+ self.options.get("class", []),
61+
)
62+
self.set_source_info(top_grid)
63+
64+
top_row = create_component(
65+
"grid-row",
66+
[
67+
"sd-row",
68+
"sd-row-cols-2",
69+
"sd-g-1",
70+
],
71+
)
72+
self.set_source_info(top_row)
73+
top_grid += top_row
74+
75+
avatar_uri = self.options.get("avatar")
76+
if avatar_uri:
77+
avatar_column = create_component(
78+
"grid-item",
79+
["sd-col", "sd-col-auto", "sd-d-flex", "sd-align-items-center"],
80+
)
81+
self.set_source_info(avatar_column)
82+
avatar_image = nodes.image(
83+
"",
84+
uri=avatar_uri,
85+
alt=self.options.get("avatar-alt", ""),
86+
classes=["sd-avatar-sm"],
87+
)
88+
self.set_source_info(avatar_image)
89+
if self.options.get("avatar-link"):
90+
avatar_link = nodes.reference(
91+
"", "", refuri=self.options.get("avatar-link")
92+
)
93+
avatar_link += avatar_image
94+
avatar_image = avatar_link
95+
avatar_column += avatar_image
96+
top_row += avatar_column
97+
98+
info_column = create_component(
99+
"grid-item",
100+
["sd-col", "sd-d-flex", "sd-align-items-center"],
101+
)
102+
self.set_source_info(info_column)
103+
top_row += info_column
104+
105+
info_grid = create_component(
106+
"grid-container",
107+
[
108+
"sd-container-fluid",
109+
"sd-sphinx-override",
110+
],
111+
)
112+
self.set_source_info(info_grid)
113+
info_column += info_grid
114+
115+
info_row = create_component(
116+
"grid-row",
117+
[
118+
"sd-row",
119+
"sd-row-cols-2",
120+
"sd-row-cols-xs-2",
121+
"sd-row-cols-sm-3",
122+
"sd-row-cols-md-3",
123+
"sd-row-cols-lg-3",
124+
"sd-gx-3",
125+
"sd-gy-1",
126+
],
127+
)
128+
self.set_source_info(info_row)
129+
info_grid += info_row
130+
131+
author_text = self.options.get("author")
132+
if author_text:
133+
author_column = create_component(
134+
"grid-item",
135+
["sd-col", "sd-col-auto", "sd-d-flex", "sd-align-items-center"],
136+
)
137+
self.set_source_info(author_column)
138+
author_nodes = self._parse_text(author_text, parse=parse_fields)
139+
author_column.extend(author_nodes)
140+
info_row += author_column
141+
142+
date_text = self.options.get("date")
143+
if date_text:
144+
date_column = create_component(
145+
"grid-item",
146+
["sd-col", "sd-col-auto", "sd-d-flex", "sd-align-items-center"],
147+
)
148+
self.set_source_info(date_column)
149+
date_icon = nodes.raw(
150+
"",
151+
nodes.Text(get_octicon("calendar", size=16)),
152+
classes=["sd-pr-2"],
153+
format="html",
154+
)
155+
date_nodes = self._parse_text(date_text, icon=date_icon, parse=parse_fields)
156+
date_column.extend(date_nodes)
157+
info_row += date_column
158+
159+
read_time_text = self.options.get("read-time")
160+
if read_time_text:
161+
read_time_column = create_component(
162+
"grid-item",
163+
["sd-col", "sd-col-auto", "sd-d-flex", "sd-align-items-center"],
164+
)
165+
self.set_source_info(read_time_column)
166+
read_time_icon = nodes.raw(
167+
"",
168+
nodes.Text(get_octicon("clock", size=16)),
169+
classes=["sd-pr-2"],
170+
format="html",
171+
)
172+
read_time_nodes = self._parse_text(
173+
read_time_text, icon=read_time_icon, parse=parse_fields
174+
)
175+
read_time_column.extend(read_time_nodes)
176+
info_row += read_time_column
177+
178+
return [top_grid]
File renamed without changes.
File renamed without changes.

sphinx_design/compiled/style.min.css

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)