Diff of /Docs/conf.py [000000] .. [38ba34]

Switch to unified view

a b/Docs/conf.py
1
# -- Project information -----------------------------------------------------
2
import os
3
import re
4
import subprocess
5
import sys
6
from datetime import datetime
7
from pathlib import Path
8
9
sys.path.insert(0, os.path.abspath("exts"))
10
sys.path.insert(0, os.path.abspath("tools"))
11
12
13
current_year = os.environ.get("YEAR", datetime.now().year)
14
15
16
project = "AMMR"
17
copyright = f"{current_year}, AnyBody Technology"
18
author = "AnyBody Technology"
19
# language = "fr"  # For testing language translations
20
21
22
def tagged_commit():
23
    """Check if we are on a tagged commit"""
24
    try:
25
        subprocess.check_call(
26
            ["git", "describe", "--tags", "--exact-match", "HEAD"],
27
            stdout=subprocess.DEVNULL,
28
            stderr=subprocess.DEVNULL,
29
        )
30
    except subprocess.CalledProcessError:
31
        return False
32
    else:
33
        return True
34
35
36
if tags.has("offline"):
37
    # building offline version
38
    pass
39
40
41
if not tagged_commit() and not tags.has("offline"):
42
    tags.add("draft")
43
44
# `todo` and `todoList` produce output, else they produce nothing.
45
todo_include_todos = tags.has("draft")
46
47
48
master_doc = "index"
49
50
# -- General configuration ---------------------------------------------------
51
52
# Add any Sphinx extension module names here, as strings. They can be
53
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
54
# ones.
55
extensions = [
56
    "sphinx.ext.intersphinx",
57
    "sphinx.ext.viewcode",
58
    "sphinx.ext.intersphinx",
59
    "sphinx.ext.todo",
60
    "sphinx.ext.mathjax",
61
    "sphinx.ext.githubpages",
62
    "myst_parser",
63
    "ammr_directives",
64
    "sphinxext.opengraph",
65
    "sphinx_design",
66
    "sphinx_togglebutton",
67
    "sphinx_copybutton",
68
69
    # "sphinxcontrib.youtube",
70
    # "sphinx_copybutton",
71
    # "sphinx_design",
72
    # "sphinx_examples",
73
    # "sphinx_tabs.tabs",
74
    # "sphinx_togglebutton",
75
    # "sphinxcontrib.bibtex",
76
    # "sphinxext.opengraph",
77
    # For the kitchen sink
78
    # "sphinx.ext.todo",
79
]
80
81
82
myst_enable_extensions = [
83
    "colon_fence",
84
    "deflist",
85
    "fieldlist",
86
    "dollarmath",
87
    "amsmath",
88
    "html_image",
89
    "substitution",
90
    "attrs_inline",
91
]
92
93
# Add any paths that contain templates here, relative to this directory.
94
# templates_path = ["_templates"]
95
96
97
source_suffix = [".rst", ".md"]
98
99
# List of patterns, relative to source directory, that match files and
100
# directories to ignore when looking for source files.
101
# This pattern also affects html_static_path and html_extra_path.
102
exclude_patterns = [
103
    "_build",
104
    "README.md",
105
    "Thumbs.db",
106
    ".DS_Store",
107
    "exts",
108
    "auto_examples",
109
    ".pixi",
110
]
111
112
# The name of the Pygments (syntax highlighting) style to use.
113
highlight_language = "AnyScriptDoc"
114
pygments_style = "AnyScript"
115
116
ams_version = os.environ.get("AMS_VERSION", "8.1.0")
117
if not re.match(r"^\d\.\d\.\d", ams_version):
118
    raise ValueError("Wrong format for AMS version, environment variable")
119
ams_version_short = ams_version.rpartition(".")[0]
120
ams_version_x = ams_version_short + ".x"
121
122
123
ammr_version = os.environ.get("AMMR_VERSION", None)
124
if ammr_version is None:
125
    AMMR_VERSION_RE = re.compile(r'.*AMMR_VERSION\s"(?P<version>.*)"')
126
    with open("../AMMR.version.any") as fh:
127
        match = AMMR_VERSION_RE.search(fh.read())
128
        if match:
129
            ammr_version = match.groupdict()["version"]
130
        else:
131
            raise Exception("Could not parse AMMR version")
132
133
134
if not re.match(r"^\d\.\d\.\d", ammr_version):
135
    raise ValueError("Wrong format for AMMR version, environment variable")
136
137
ammr_version_short = ammr_version.rpartition(".")[0]
138
139
rst_epilog = f"""
140
141
.. |AMS| replace:: AnyBody Modeling System™
142
.. |AMS_VERSION_X| replace:: {ams_version_x}
143
.. |AMS_VERSION| replace:: {ams_version}
144
.. |AMS_VERSION_SHORT| replace:: {ams_version_short}
145
.. |AMMR_VERSION_SHORT| replace:: {ammr_version_short}
146
.. |AMMR_VERSION| replace:: {ammr_version}
147
.. |AMMR_DEMO_INST_DIR| replace:: :literal:`~/Documents/{ams_version_x}/AMMR.v{ammr_version}-Demo`
148
.. |CURRENT_YEAR| replace:: {current_year}
149
.. |WHAT_IS_NEW| replace:: :ref:`What's new in AMMR {ammr_version} <whats-new>`
150
.. |DOI| image:: https://zenodo.org/badge/DOI/10.5281/zenodo.10527958.svg
151
                 :target: https://doi.org/10.5281/zenodo.10527958
152
"""
153
154
myst_substitutions = {
155
    "AMS": "AnyBody Modeling System™",
156
    "AMS_VERSION_X": ams_version_x,
157
    "AMS_VERSION": ams_version_x,
158
    "AMS_VERSION_SHORT": ams_version_short,
159
    "AMMR_VERSION_SHORT": ams_version_short,
160
    "AMMR_VERSION": ammr_version,
161
    "CURRENT_YEAR": current_year,
162
    "AMMR_DEMO_INST_DIR": f"`~/Documents/{ams_version_x}/AMMR.v{ammr_version}-Demo`",
163
    "DOI": "[![DOI image](https://zenodo.org/badge/DOI/10.5281/zenodo.10527958.svg)](https://doi.org/10.5281/zenodo.10527958)",
164
    "WHAT_IS_NEW": f"{{ref}}`What's new in AMMR {ammr_version} <whats-new>`",
165
    "WHAT_IS_NEW2": f"{{material-outlined}}`update;1em` New in AMMR {ammr_version}",
166
}
167
168
169
no_index = """
170
.. meta::
171
   :robots: noindex
172
"""
173
myst_html_meta = {}
174
175
if tags.has("draft"):
176
    rst_epilog = rst_epilog + no_index
177
    myst_html_meta["robots"] = "noindex"
178
179
github_doc_root = "https://github.com/AnyBody/ammr/tree/master/Docs"
180
181
version = f"{ammr_version_short}"
182
# The full version, including alpha/beta/rc tags.
183
release = f"{ammr_version}"
184
185
if tags.has("draft") and not release.endswith("beta"):
186
    release = release + "-beta"
187
188
189
190
191
192
# suppress_warnings = ["myst.domains", "ref.ref"]
193
194
numfig = True
195
196
197
198
# -- Options for HTML output -------------------------------------------------
199
200
# The theme to use for HTML and HTML Help pages.  See the documentation for
201
# a list of builtin themes.
202
#
203
html_theme = "sphinx_book_theme"
204
# html_logo = "_static/logo-wide.svg"
205
html_title = f"{project} v{release} Documentation"
206
html_copy_source = False
207
# html_favicon = "_static/logo-square.svg"
208
html_last_updated_fmt = ""
209
210
# html_sidebars = {
211
#     "reference/blog/*": [
212
#         "navbar-logo.html",
213
#         "search-field.html",
214
#         "ablog/postcard.html",
215
#         "ablog/recentposts.html",
216
#         "ablog/tagcloud.html",
217
#         "ablog/categories.html",
218
#         "ablog/archives.html",
219
#         "sbt-sidebar-nav.html",
220
#     ]
221
# }
222
# Add any paths that contain custom static files (such as style sheets) here,
223
# relative to this directory. They are copied after the builtin static files,
224
# so a file named "default.css" will overwrite the builtin "default.css".
225
html_static_path = ["_static", "body/_static"]
226
html_css_files = ["_static/custom.css"]
227
228
229
html_logo = "_static/AMMR.svg"
230
html_favicon = "_static/favicon.ico"
231
232
233
html_theme_options = {
234
    "path_to_docs": "Docs",
235
    "repository_url": "https://github.com/anybody/ammr",
236
    "repository_branch": "master",
237
    "use_edit_page_button": True,
238
    "use_source_button": True,
239
    "use_issues_button": False,
240
    "use_repository_button": True,
241
    "use_download_button": False,
242
243
    "home_page_in_toc": False,
244
    "show_toc_level": 1,
245
246
    "pygment_light_style": "AnyScript",
247
    "pygment_dark_style": "stata-dark",
248
249
250
    # "use_sidenotes": True,
251
    # "announcement": (
252
    #     "⚠️The latest release refactored our HTML, "
253
    #     "so double-check your custom CSS rules!⚠️"
254
    # ),
255
    "logo": {
256
        "image_dark": "_static/AMMR.svg",
257
        # "text": html_title,  # Uncomment to try text with logo
258
    },
259
    "icon_links": [
260
        # {
261
        #     "name": "AnyBody Technology",
262
        #     "url": "https://anybodytech.com/",
263
        #     # "icon": "_static/ebp-logo.png",
264
        #     "type": "local",
265
        # },
266
        # {
267
        #     "name": "GitHub",
268
        #     "url": "https://github.com/anybody/ammr",
269
        #     "icon": "fa-brands fa-github",
270
        # },
271
    ],
272
    # For testing
273
    # "use_fullscreen_button": False,
274
    # "home_page_in_toc": True,
275
    # "extra_footer": "<a href='https://google.com'>Test</a>",  # DEPRECATED KEY
276
    # "show_navbar_depth": 2,
277
    # Testing layout areas
278
    # "navbar_start": ["test.html"],
279
    # "navbar_center": ["test.html"],
280
    # "navbar_end": ["test.html"],
281
    # "navbar_persistent": ["test.html"],
282
    # "footer_start": ["test.html"],
283
    # "footer_end": ["test.html"]
284
}
285
286
bibtex_bibfiles = ["references.bib"]
287
# To test that style looks good with common bibtex config
288
bibtex_reference_style = "author_year"
289
bibtex_default_style = "plain"
290
numpydoc_show_class_members = False  # for automodule:: urllib.parse stub file issue
291
linkcheck_ignore = [
292
    "http://someurl/release",  # This is a fake link
293
    "https://doi.org",  # These don't resolve properly and cause SSL issues
294
]
295
296
297
298
intersphinx_mapping = {}
299
if tags.has("offline"):
300
    # Todo. Find a way to link to offline html versions.
301
    intersphinx_mapping["tutorials"] = ("https://anyscript.org/tutorials/", None)
302
else:
303
    if tags.has("draft"):
304
        intersphinx_mapping["tutorials"] = (
305
            "https://anyscript.org/tutorials/beta/",
306
            None,
307
        )
308
    else:
309
        intersphinx_mapping["tutorials"] = ("https://anyscript.org/tutorials/", None)
310
311
312
313
# sphinxext.opengraph
314
# ogp_social_cards = {
315
#     "image": "_static/logo-square.png",
316
# }
317
318
ogp_site_url = "https://anyscript.org/"
319
ogp_site_name = "AMMR Documentation"
320
ogp_image = "https://anyscript.org/ammr/_static/AMMR_Logo.png"
321
ogp_use_first_image = True  # if not found defaults to 'ogp_image'
322
323
324
# Generate gallery files
325
import frontmatter
326
import jinja2
327
328
gallery = {}
329
galleryfolders = [x for x in Path("Applications").iterdir() if x.is_dir()]
330
for folder in galleryfolders:
331
    gallery[folder] = []
332
    for file in sorted(folder.glob("*.md"), key=lambda x: x.name.upper()):
333
        post = frontmatter.load(file)
334
        if "gallery_title" in post:
335
            gallery[folder].append(
336
                {
337
                    "doc": file.with_suffix("").as_posix(),
338
                    "title": post["gallery_title"],
339
                    "image": post["gallery_image"],
340
                }
341
            )
342
343
344
with open("Applications/gallery.txt.jinja2") as fh:
345
    gallery_template = jinja2.Template(fh.read())
346
347
for folder, section in gallery.items():
348
    gallery_txt = folder / "gallery.txt"
349
    content = gallery_template.render(examples=section)
350
    with open(gallery_txt, encoding="utf8") as fh:
351
        previous_content = fh.read()
352
    if content != previous_content:
353
        with open(gallery_txt, "w", encoding="utf8") as fh:
354
            fh.write(content)
355
356
# Run the python file "tools/generate_class_template_docs.py"
357
# to generate the class template documentation
358
359
import generate_class_template_docs
360
361
generate_class_template_docs.run_all()
362
363
364
user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
365
366
linkcheck_ignore = [
367
    r".*linkcheck_ignore",
368
    "https://doi.org/10.1115/1.4037100",  # asme.org prevents the linkcheck
369
    "https://doi.org/10.1115/1.4052115",  # asme.org prevents the linkcheck
370
    "https://dx.doi.org/10.1115/1.4001678",  # asme.org prevents the linkcheck
371
    "https://dx.doi.org/10.1115/1.4029258",  # asme.org prevents the linkcheck
372
    "https://doi.org/10.1080/10255842.2020.1851367",  # tandfonline.com prevents the linkcheck
373
    "https://dx.doi.org/10.1002/jor.20255",  # wiley.com prevents the linkcheck
374
    "https://doi.org/10.1016/j.clinbiomech.2006.10.003",  # clinbiomech.com prevents the linkcheck
375
    "https://doi.org/10.1002/jor.25267",  # wiley.com prevents the linkcheck
376
    "https://web.archive.org*",  # web.archive.org is currently down due to hacking atacks
377
    "https://doi.org/10.5281/zenodo.15094590", # version not released yet
378
]
379
380
linkcheck_allowed_redirects = {
381
    "https://doi.org.*": ".*",
382
    "https://dx.doi.org.*": ".*",
383
    "https://www.anybodytech.com/download/anybodysetup.*": ".*",
384
}
385
386
def setup(app):
387
   ...