-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathconf.py
More file actions
196 lines (166 loc) · 7.87 KB
/
Copy pathconf.py
File metadata and controls
196 lines (166 loc) · 7.87 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
# Configuration file for the Sphinx documentation builder.
#
# For the full list of built-in configuration values, see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html
import os
import re
import sys
sys.path.insert(0, os.path.abspath('..'))
# -- Project information -----------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
project = 'TROPT'
copyright = '2025-2026, Matan Ben-Tov'
author = 'Matan Ben-Tov'
from importlib.metadata import PackageNotFoundError, version as _pkg_version
try:
release = _pkg_version("tropt")
except PackageNotFoundError:
release = "0.0.0"
version = ".".join(release.split(".")[:2])
# -- General configuration ---------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.napoleon',
'sphinx.ext.viewcode',
'sphinx_autodoc_typehints',
'sphinx_copybutton',
'sphinx_codeautolink',
'sphinx_design',
'myst_parser',
# SEO: emits sitemap.xml + per-page Open Graph / Twitter card meta tags.
# Both extensions need `html_baseurl` (set below) to produce absolute URLs.
'sphinx_sitemap',
'sphinxext.opengraph',
]
# sphinx-copybutton: strip shell prompts and Python REPL prefixes so the
# clipboard receives runnable code only.
copybutton_prompt_text = r">>> |\.\.\. |\$ |# "
copybutton_prompt_is_regexp = True
# sphinx-codeautolink: turn identifiers in code blocks into links to the
# autodoc API reference. `concat_default=True` chains code blocks within a
# single page (like a notebook), so later blocks can resolve names imported
# in earlier ones.
codeautolink_concat_default = True
# MyST: enable colon-fence so sphinx-design directives (`:::{grid}` etc.) and
# admonitions work in .md guides.
myst_enable_extensions = ["colon_fence", "deflist", "attrs_inline"]
myst_heading_anchors = 3
autodoc_mock_imports = ['sentence_transformers', 'wandb', 'livelossplot', 'openai', 'litellm', 'IPython', 'tqdm', 'transformers', 'accelerate', 'huggingface_hub', 'datasets', 'PIL', 'diffusers', 'trackio']
autodoc_typehints = "description"
templates_path = ['_templates']
exclude_patterns = []
language = 'en'
# -- Options for HTML output -------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output
html_theme = 'pydata_sphinx_theme'
html_static_path = ['_static']
html_css_files = ['custom.css']
html_js_files = ['skip_auto_theme.js', 'landing.js']
html_favicon = '_static/favicon.svg'
# -- SEO ---------------------------------------------------------------------
# Canonical URL of the deployed docs. sphinx-sitemap and sphinxext-opengraph
# both read this; without it they silently produce relative URLs (which
# Twitter/LinkedIn/Slack won't accept for og:url and og:image).
html_baseurl = "https://tropt.dev/"
# Crisper window title — strips the noisy "TROPT 0.0.1a1 documentation" suffix.
# Sphinx renders <title> as "{page_h1} — {html_title}", so setting this to the
# tagline gives "TROPT — Textual Trigger Optimization Toolbox" on the landing
# page and "<topic> — Textual Trigger Optimization Toolbox" elsewhere.
html_title = "Textual Trigger Optimization Toolbox"
# Pull robots.txt into the build output (extra_path copies files verbatim into
# the html dir). The file lives at docs/robots.txt; extra_path copies it
# verbatim so it lands at the SITE ROOT (tropt.dev/robots.txt) which is where
# crawlers look for it — placement inside _static/ wouldn't be discoverable.
html_extra_path = ['robots.txt']
# sphinx-sitemap config — emits sitemap.xml at the docs root.
# `sitemap_url_scheme` template: {link} = relative URL of each page.
sitemap_url_scheme = "{link}"
# sphinxext-opengraph — auto-generates og:title, og:description, og:url, plus
# Twitter Card tags. og:image is set globally; per-page overrides go via the
# MyST `myst.html_meta` front-matter (see index.md).
ogp_site_url = html_baseurl
ogp_site_name = "TROPT — Textual Trigger Optimization Toolbox"
ogp_image = html_baseurl + "_static/og-image.png"
ogp_image_alt = "TROPT — Textual Trigger Optimization Toolbox"
ogp_type = "website"
ogp_enable_meta_description = True
# Generate <meta name="twitter:card" content="summary_large_image"> so the
# preview is the wide card layout (not the small thumbnail variant).
ogp_social_cards = {"enable": False} # don't auto-render; we ship our own.
ogp_custom_meta_tags = [
'<meta name="twitter:card" content="summary_large_image">',
'<meta name="twitter:site" content="@matanbentov">',
]
html_theme_options = {
"logo": {
"image_light": "_static/logo.svg",
"image_dark": "_static/logo.svg",
},
"show_toc_level": 2,
"navbar_align": "left",
"secondary_sidebar_items": {
"**": ["page-toc", "edit-this-page"],
"index": [],
},
# New visitors land in light mode. Theme switcher is kept so users can
# opt into dark mode; we just override the switcher's JS below to skip
# the "auto" (system-selected) state — light ↔ dark only.
"default_mode": "light",
# Compact single-line footer — see docs/_templates/footer-tropt.html.
# Drops the default copyright / sphinx-version / theme-version stack.
"footer_start": [],
"footer_center": ["footer-tropt"],
"footer_end": [],
# GitHub icon in the top-right of the navbar (GEPA-style).
"icon_links": [
{
"name": "GitHub",
"url": "https://github.com/matanbt/TROPT",
"icon": "fa-brands fa-github",
"type": "fontawesome",
},
],
}
# Landing page: hide the primary (left) sidebar so the hero spans full width.
html_sidebars = {
"index": [],
}
# -- LLM-friendly artifacts --------------------------------------------------
# Expose raw Markdown sources alongside rendered HTML so coding agents can
# fetch the source-of-truth Markdown without a lossy HTML→MD round-trip.
# Also publish docs/llms.txt at the docs root per https://llmstxt.org/.
def _copy_llm_artifacts(app, exception):
if exception is not None:
return
import shutil
# Raw guide markdown: docs/guides/*.md -> _build/html/guides/*.md
guides_src = os.path.join(app.srcdir, 'guides')
guides_dst = os.path.join(app.outdir, 'guides')
if os.path.isdir(guides_src) and os.path.isdir(guides_dst):
for fname in os.listdir(guides_src):
if fname.endswith('.md'):
shutil.copy2(os.path.join(guides_src, fname),
os.path.join(guides_dst, fname))
# llms.txt at the docs root
llms_src = os.path.join(app.srcdir, 'llms.txt')
if os.path.isfile(llms_src):
shutil.copy2(llms_src, os.path.join(app.outdir, 'llms.txt'))
# docs/api/recipe_hub.rst inlines tropt/recipe_hub/README.md via `.. include::`
# so the registry can't drift from source. The README targets GitHub: its
# relative `[FOO.py](FOO.py)` links become broken Sphinx cross-references and
# its leading `---` becomes a transition warning. Sanitize on the `include-read`
# event (Sphinx >= 8.0) so it runs for every build path, not just build_docs.py.
def _sanitize_recipe_hub_readme(app, relative_path, parent_docname, content):
if not str(relative_path).replace("\\", "/").endswith("recipe_hub/README.md"):
return
def _strip_self_link(match):
text, target = match.group(1), match.group(2)
return f"`{target}`" if text.strip("`").strip() == target else match.group(0)
text = re.sub( # relative self-links [FOO.py](FOO.py) -> `FOO.py`
r"\[([^\]]+)\]\((?!https?:|/|#)([^)]+\.(?:py|md))\)", _strip_self_link, content[0]
)
content[0] = re.sub(r"\n---\n", "\n\n", text, count=1) # drop first divider
def setup(app):
app.connect('build-finished', _copy_llm_artifacts)
app.connect('include-read', _sanitize_recipe_hub_readme)