11#!/usr/bin/env python
22"""Sphinx configuration file"""
33from __future__ import annotations
4+
45from functools import cache
56import logging
67from pathlib import Path
7- from textwrap import dedent
88from typing import Any , NamedTuple
9- import docutils .nodes
10- import os
119import re
1210import runpy
13- import sphinx .ext .autodoc
14- import sphinx .transforms
1511import sys
1612
1713from docutils import nodes
18- from docutils .nodes import literal
1914from sphinx .util .docutils import SphinxRole
2015
16+ HERE = Path (__file__ ).resolve ()
17+ REPO_LOCAL_ROOT = HERE .parent .parent
18+ ARCADE_MODULE = REPO_LOCAL_ROOT / "arcade"
19+ UTIL_DIR = REPO_LOCAL_ROOT / "util"
20+
21+ log = logging .getLogger ('conf.py' )
22+ logging .basicConfig (level = logging .INFO )
23+
24+ sys .path .insert (0 , str (REPO_LOCAL_ROOT ))
25+ sys .path .insert (0 , str (ARCADE_MODULE ))
26+ log .info (f"Inserted elements in system path: First two are now:" )
27+ for i in range (2 ):
28+ log .info (f" { i } : { sys .path [i ]!r} " )
29+
30+ from util .doc_helpers .real_filesystem import copy_media
31+
2132# As of pyglet==2.1.dev7, this is no longer set in pyglet/__init__.py
2233# because Jupyter / IPython always load Sphinx into sys.modules. See
2334# the following for more info:
2738
2839# --- Pre-processing Tasks
2940
30- log = logging .getLogger ('conf.py' )
31- logging .basicConfig (level = logging .INFO )
32-
33- HERE = Path (__file__ ).resolve ()
34- REPO_LOCAL_ROOT = HERE .parent .parent
35-
36- ARCADE_MODULE = REPO_LOCAL_ROOT / "arcade"
37- UTIL_DIR = REPO_LOCAL_ROOT / "util"
38-
41+ # Report our diagnostic info
3942log .info (f"Absolute path for our conf.py : { str (HERE )!r} " )
4043log .info (f"Absolute path for the repo root : { str (REPO_LOCAL_ROOT )!r} " )
4144log .info (f"Absolute path for the arcade module : { str (REPO_LOCAL_ROOT )!r} " )
4245log .info (f"Absolute path for the util dir : { str (UTIL_DIR )!r} " )
4346
4447# _temp_version = (REPO_LOCAL_ROOT / "arcade" / "VERSION").read_text().replace("-",'')
4548
46- sys .path .insert (0 , str (REPO_LOCAL_ROOT ))
47- sys .path .insert (0 , str (ARCADE_MODULE ))
48- log .info (f"Inserted elements in system path: First two are now:" )
49- for i in range (2 ):
50- log .info (f" { i } : { sys .path [i ]!r} " )
51-
5249# Don't change to
5350# from arcade.version import VERSION
5451# or read the docs build will fail.
5552from version import VERSION # pyright: ignore [reportMissingImports]
56- log .info (f"Got version { VERSION !r} " )
53+ log .info (f" Got version { VERSION !r} " )
5754
58- REPO_URL_BASE = "https://github.com/pythonarcade/arcade"
59- if 'dev' in VERSION :
60- GIT_REF = 'development'
61- log .info (f"Got .dev release: using { GIT_REF !r} " )
62- else :
55+
56+ # Check whether the version ends in an all-digit string
57+ VERSION_PARTS = []
58+ for part in VERSION .split ('.' ):
59+ if part .isdigit ():
60+ VERSION_PARTS .append (int (part ))
61+ else :
62+ VERSION_PARTS .append (part )
63+
64+ print ()
65+ if VERSION_PARTS [- 1 ].isdigit ():
6366 GIT_REF = VERSION
64- log .info (f"Got real release: using { GIT_REF !r} " )
67+ log .info (" !!!!! APPEARS TO BE A REAL RELEASE !!!!!" )
68+ else :
69+ GIT_REF = 'development'
70+ log .info (" - - - Building as a dev release - - -" )
71+
72+ print ()
73+ print (f" { GIT_REF = !r} " )
74+ print (f" { VERSION = !r} " )
75+ print ()
76+
6577
6678# We'll pass this to our generation scripts to initialize their globals
79+ REPO_URL_BASE = "https://github.com/pythonarcade/arcade"
6780FMT_URL_REF_BASE = f"{ REPO_URL_BASE } /blob/{ GIT_REF } "
81+
6882RESOURCE_GLOBALS = dict (
6983 GIT_REF = GIT_REF ,
7084 BASE_URL_REPO = REPO_URL_BASE ,
@@ -104,6 +118,22 @@ def run_util(filename, run_name="__main__", init_globals=None):
104118# Run the generate quick API index script
105119run_util ('../util/update_quick_index.py' )
106120
121+
122+ src_res_dir = ARCADE_MODULE / 'resources/assets'
123+ out_res_dir = REPO_LOCAL_ROOT / 'build/html/_static/assets'
124+
125+ # pending: post-3.0 cleanup to find the right source events to make this work?
126+ # if exc or app.builder.format != "html":
127+ # return
128+ # static_dir = (app.outdir / '_static').resolve()
129+ copy_what = { # pending: post-3.0 cleanup to tie this into resource generation correctly
130+ 'sounds' : ('*.wav' , '*.ogg' , '*.mp3' ),
131+ 'music' : ('*.wav' , '*.ogg' , '*.mp3' ),
132+ 'video' : ('*.mp4' , '*.webm' , )
133+ }
134+ copy_media (src_res_dir , out_res_dir , copy_what )
135+
136+
107137autodoc_inherit_docstrings = False
108138autodoc_default_options = {
109139 'members' : True ,
@@ -136,6 +166,12 @@ def run_util(filename, run_name="__main__", init_globals=None):
136166 'doc.extensions.prettyspecialmethods' , # Forker plugin for prettifying special methods
137167]
138168
169+ # pending: post-3.0 cleanup:
170+ # 1. Setting this breaks the CSS for both the plugin's buttons and our "custom" ones
171+ # 2. Since our custom ones are only on the gui page for now, it's okay
172+ # Note: tabler doesn't require attribution + it's the original theme for this icon set
173+ # copybutton_image_svg = (REPO_LOCAL_ROOT / "doc/_static/icons/tabler/copy.svg").read_text()
174+
139175# Add any paths that contain templates here, relative to this directory.
140176templates_path = ['_templates' ]
141177
@@ -272,7 +308,6 @@ def run_util(filename, run_name="__main__", init_globals=None):
272308rst_prolog = "\n " .join (PROLOG_PARTS )
273309
274310
275-
276311def strip_init_return_typehint (app , what , name , obj , options , signature , return_annotation ):
277312 # Prevent a the `-> None` annotation from appearing after classes.
278313 # This annotation comes from the `__init__`, but it renders on the class,
@@ -281,6 +316,7 @@ def strip_init_return_typehint(app, what, name, obj, options, signature, return_
281316 if what == "class" and return_annotation is None :
282317 return (signature , None )
283318
319+
284320def inspect_docstring_for_member (
285321 _app ,
286322 what : str ,
@@ -407,7 +443,6 @@ def on_autodoc_process_bases(app, name, obj, options, bases):
407443 bases [:] = [base for base in bases if base is not object ]
408444
409445
410-
411446class A (NamedTuple ):
412447 dirname : str
413448 comment : str = ""
@@ -439,7 +474,7 @@ def run(self) -> tuple[list[nodes.Node], list[nodes.system_message]]:
439474 '/api_docs/resources.html#' , page_id ]),
440475 )
441476
442- print ( "HALP? " , locals ())
477+ log . info ( " Attempted ResourceRole " , locals ())
443478 return [node ], []
444479
445480
@@ -452,6 +487,7 @@ def setup(app):
452487 print (f" { comment } " )
453488
454489 # Separate stylesheets loosely by category.
490+ # pending: sphinx >= 8.1.4 to remove the sphinx_static_file_temp_fix.py
455491 app .add_css_file ("css/colors.css" )
456492 app .add_css_file ("css/layout.css" )
457493 app .add_css_file ("css/custom.css" )
@@ -467,6 +503,8 @@ def setup(app):
467503 app .connect ('autodoc-process-bases' , on_autodoc_process_bases )
468504 # app.add_transform(Transform)
469505 app .add_role ('resource' , ResourceRole ())
506+ # Don't do anything that can fail on this event or it'll kill your build hard
507+ # app.connect('build-finished', throws_exception)
470508
471509# ------------------------------------------------------
472510# Old hacks that breaks the api docs. !!! DO NOT USE !!!
0 commit comments