Skip to content

Commit 8fdfb3d

Browse files
authored
Add options for proof directive title formatting (#163)
* Add options for proof directive title formatting Introduces new configuration options: proof_title_format, proof_number_weight, and proof_title_weight, allowing users to customize the format and font weight of proof directive titles. Documentation and CSS updated to reflect these changes, and directive logic now applies the user-defined title format.
1 parent 97cfc7b commit 8fdfb3d

7 files changed

Lines changed: 109 additions & 6 deletions

File tree

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# Changelog
22

3+
## Unreleased
4+
5+
### Added
6+
7+
- Options for customizing proof directive title format.
8+
39
## v0.3.0 (2025-10-20)
410

511
### NEW ✨

docs/source/options.md

Lines changed: 55 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# Options
22

3+
## Minimal color scheme
4+
35
This package has the option to choose a more **minimal** color scheme.
46

57
The aim is to create admonitions that are clearly different to the core text with
@@ -15,7 +17,7 @@ compared to the current default
1517

1618
To enable the `minimal` color scheme you can use the following.
1719

18-
## Jupyter Book Project
20+
### Jupyter Book Project
1921

2022
Add `proof_minimal_theme = True` to your `_config.yml`
2123

@@ -25,6 +27,57 @@ sphinx:
2527
proof_minimal_theme: true
2628
```
2729
28-
## Sphinx Project
30+
### Sphinx Project
2931
3032
Add `proof_minimal_theme = True` to your `conf.py`
33+
34+
## Title format
35+
36+
By default, the directive titles are formatted as `Name x.y.z (Title)`, where `Name` is the name of the directive (e.g., Proof, Theorem, Definition), `x.y.z` is the numbering of the directive, and `Title` is the optional title provided by the user.
37+
38+
If no title is provided, only `Name x.y.z` is displayed.
39+
40+
The font weight of the entire title (`Name x.y.z (Title)` or `Name x.y.z`) is set to `--pst-admonition-font-weight-heading` by default, which commonly results in a semi-bold appearance.
41+
42+
In the reminder we call the part `Name x.y.z` the "number" and the part `(Title)` the "title".
43+
44+
You can customize the title format using the `proof_title_format` option:
45+
46+
- This option allows you to define how the title should be displayed by using `%t` as a placeholder for the user-provided title.
47+
- The default format is ` (%t)`.
48+
- A value of an empty string will result in no title being displayed.
49+
- A `markdown` string can be used to format the title.
50+
- For example, ` *%t*` will emphasize the title and contain no brackets.
51+
52+
Note that the initial part of the title (i.e., `Name x.y.z`) is not customizable and will always be displayed.
53+
54+
The font weight of the title can be adjusted using the `proof_title_weight` option:
55+
56+
- Any valid CSS font-weight value can be used, such as `normal`, `bold`, `bolder`, `lighter`, or numeric values like `400`, `700`, etc.
57+
- Default value is `var(--pst-admonition-font-weight-heading)`.
58+
59+
The font weight of the number can be adjusted using the `proof_number_weight` option:
60+
- Any valid CSS font-weight value can be used, such as `normal`, `bold`, `bolder`, `lighter`, or numeric values like `400`, `700`, etc.
61+
- Default value is `var(--pst-admonition-font-weight-heading)`.
62+
63+
### Jupyter Book Project
64+
65+
Add `proof_title_format`, `proof_number_weight` and/or `proof_title_weight` to your `_config.yml`
66+
67+
```yaml
68+
sphinx:
69+
config:
70+
proof_title_format: " *%t*"
71+
proof_number_weight: "bold"
72+
proof_title_weight: "normal"
73+
```
74+
75+
### Sphinx Project
76+
77+
Add `proof_title_format`, `proof_number_weight` and/or `proof_title_weight` to your `conf.py`
78+
79+
```python
80+
proof_title_format = " *%t*"
81+
proof_number_weight = "bold"
82+
proof_title_weight = "normal"
83+
```

sphinx_proof/__init__.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,11 +76,35 @@ def copy_asset_files(app: Sphinx, exc: Union[bool, Exception]):
7676
if exc is None:
7777
for path in asset_files:
7878
copy_asset(path, str(Path(app.outdir).joinpath("_static").absolute()))
79+
# if needed, load css to memory,
80+
# adjust font-weight according to user's setting in config
81+
# and write to output static file
82+
if app.config.proof_number_weight or app.config.proof_title_weight:
83+
# only if at least one of the two options is set
84+
path = str(Path(app.outdir).joinpath("_static", "proof.css").absolute())
85+
with open(path, "r", encoding="utf-8") as f:
86+
css_content = f.read()
87+
if app.config.proof_number_weight:
88+
css_content = css_content.replace(
89+
"div.proof > p.admonition-title > span.caption-number {\n font-weight: var(--pst-admonition-font-weight-heading);\n}", # noqa: E501
90+
f"div.proof > p.admonition-title > span.caption-number {{\n font-weight: {app.config.proof_number_weight};\n}}", # noqa: E501
91+
)
92+
if app.config.proof_title_weight:
93+
css_content = css_content.replace(
94+
"div.proof > p.admonition-title {\n font-weight: var(--pst-admonition-font-weight-heading);\n}", # noqa: E501
95+
f"div.proof > p.admonition-title {{\n font-weight: {app.config.proof_title_weight};\n}}", # noqa: E501
96+
)
97+
out_path = Path(app.outdir).joinpath("_static", os.path.basename(path))
98+
with open(out_path, "w", encoding="utf-8") as f:
99+
f.write(css_content)
79100

80101

81102
def setup(app: Sphinx) -> Dict[str, Any]:
82103

83104
app.add_config_value("proof_minimal_theme", False, "html")
105+
app.add_config_value("proof_title_format", " (%t)", "html")
106+
app.add_config_value("proof_number_weight", "", "env")
107+
app.add_config_value("proof_title_weight", "", "env")
84108

85109
app.add_css_file("proof.css")
86110
app.connect("build-finished", copy_asset_files)

sphinx_proof/_static/minimal/proof.css

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,15 @@ div.proof > .admonition-title::before {
3838
content: none;
3939
}
4040

41+
/* Set font weights */
42+
div.proof > p.admonition-title {
43+
font-weight: var(--pst-admonition-font-weight-heading) !important;
44+
}
45+
46+
div.proof > p.admonition-title > span.caption-number {
47+
font-weight: var(--pst-admonition-font-weight-heading) !important;
48+
}
49+
4150
/*********************************************
4251
* Proof *
4352
*********************************************/

sphinx_proof/_static/proof.css

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,15 @@ div.proof p.admonition-title::before {
2323
content: none;
2424
}
2525

26+
/* Set font weights */
27+
div.proof > p.admonition-title {
28+
font-weight: var(--pst-admonition-font-weight-heading);
29+
}
30+
31+
div.proof > p.admonition-title > span.caption-number {
32+
font-weight: var(--pst-admonition-font-weight-heading);
33+
}
34+
2635
/*********************************************
2736
* Proof *
2837
*********************************************/

sphinx_proof/directive.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,9 @@ def run(self) -> List[Node]:
6666

6767
title_text = ""
6868
if self.arguments != []:
69-
title_text += f" ({self.arguments[0]})"
69+
title_format = self.config.proof_title_format
70+
title_text += title_format.replace("%t", self.arguments[0])
71+
# title_text += f" ({self.arguments[0]})"
7072

7173
textnodes, messages = self.state.inline_text(title_text, self.lineno)
7274

tests/conftest.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
import shutil
22
import pytest
33

4-
from sphinx.testing.path import path
4+
from pathlib import Path
55

66
pytest_plugins = "sphinx.testing.fixtures"
77

88

99
@pytest.fixture
1010
def rootdir(tmpdir):
11-
src = path(__file__).parent.abspath() / "books"
11+
src = Path(__file__).parent / "books"
1212
dst = tmpdir.join("books")
1313
shutil.copytree(src, dst)
14-
books = path(dst)
14+
books = Path(dst)
1515
yield books
1616
shutil.rmtree(dst)
1717

0 commit comments

Comments
 (0)