Skip to content

Commit 931514b

Browse files
committed
Add Sphinx CI
1 parent 63b05de commit 931514b

File tree

3 files changed

+114
-25
lines changed

3 files changed

+114
-25
lines changed
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
name: Build Sphinx Documentation
2+
3+
on:
4+
pull_request:
5+
branches: [main]
6+
7+
jobs:
8+
sphinx-build:
9+
runs-on: ubuntu-latest
10+
steps:
11+
- name: Checkout repository
12+
uses: actions/checkout@v4
13+
with:
14+
submodules: 'recursive'
15+
16+
- name: Set up Python
17+
uses: actions/setup-python@v5
18+
with:
19+
python-version: '3.10'
20+
cache: 'pip'
21+
22+
- name: Install dependencies
23+
run: |
24+
python -m pip install --upgrade pip
25+
pip install -r requirements.txt
26+
27+
- name: Build Sphinx Documentation
28+
run: |
29+
cd docs
30+
# Run Sphinx build to catch issues
31+
# -D build_toctree=True enables toctree processing to verify all docs are included
32+
python -m sphinx -b html . _build/html
33+
34+
- name: Check for broken links to external sites
35+
run: |
36+
cd docs
37+
# Run linkcheck builder to find broken links
38+
python -m sphinx -b linkcheck . _build/linkcheck

docs/_ext/generate_toc_html.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,6 @@ def process_document(env, docname, parent_maxdepth=1, processed_docs=None):
9393

9494
# First check for commented toctree
9595
doc_path = env.doc2path(docname)
96-
logger.info(f"Checking for commented toctree in {doc_path}")
9796
with open(doc_path, 'r', encoding='utf-8') as f:
9897
content = f.read()
9998

@@ -137,7 +136,6 @@ def process_document(env, docname, parent_maxdepth=1, processed_docs=None):
137136

138137
# Then process uncommented toctrees
139138
uncommented_toctrees = list(doctree.traverse(addnodes.toctree))
140-
logger.info(f"Found {len(uncommented_toctrees)} uncommented toctrees in {docname}")
141139
for node in uncommented_toctrees:
142140
caption = node.get('caption')
143141
maxdepth = node.get('maxdepth', parent_maxdepth)

docs/conf.py

Lines changed: 76 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -14,24 +14,25 @@
1414
sys.path.insert(0, os.path.abspath('.')) # For finding _ext
1515
sys.path.insert(0, os.path.abspath('..'))
1616

17-
def source_read_handler(app, docname, source):
17+
def uncomment_toctrees(app, docname, source):
1818
content = source[0]
1919
# Regex to find the comment block and extract its content
2020
pattern = re.compile(r'<!-- RTD-TOC-START\s*(.*?)\s*RTD-TOC-END -->', re.DOTALL)
21-
21+
2222
def uncomment_toc(match):
2323
return match.group(1) # Return only the content inside the comments
2424

2525
# Replace the comment block with its uncommented content
2626
new_content = pattern.sub(uncomment_toc, content)
27+
2728
source[0] = new_content
2829

2930
def handle_utf16le_files(app, docname, source):
3031
doc_path = Path(app.env.doc2path(docname))
3132

3233
with open(doc_path, 'rb') as f:
3334
content_bytes = f.read()
34-
35+
3536
# Check for UTF-16LE BOM (FF FE)
3637
if content_bytes.startswith(b'\xff\xfe'):
3738
# Decode from UTF-16LE
@@ -41,23 +42,47 @@ def handle_utf16le_files(app, docname, source):
4142
# Set the source content
4243
source[0] = content
4344

45+
def add_orphan_directive(app, docname, source):
46+
content = source[0]
47+
# Check if the document already has "orphan: true"
48+
if 'orphan: true' in content:
49+
return
50+
51+
# Check if the document starts with YAML frontmatter
52+
if content.strip().startswith('---'):
53+
# Find the end of frontmatter
54+
lines = content.split('\n')
55+
frontmatter_end = -1
56+
for i in range(1, len(lines)):
57+
if lines[i].strip() == '---':
58+
frontmatter_end = i
59+
break
60+
61+
# Insert orphan: true at the end of the frontmatter
62+
if frontmatter_end != -1:
63+
lines.insert(frontmatter_end - 1, 'orphan: true')
64+
source[0] = '\n'.join(lines)
65+
else:
66+
# No frontmatter, add frontmatter with "orphan: true"
67+
source[0] = '---\norphan: true\n---\n' + content
68+
4469
def latex_block_to_inline(app, docname, source):
4570
content = source[0]
4671
# Replace $$ with $ for inline math, but only when not part of a block
4772
# First find all block math ($$...$$) on their own lines
4873
block_matches = re.finditer(r'^\s*\$\$(.*?)\$\$\s*$', content, re.MULTILINE | re.DOTALL)
4974
block_positions = [(m.start(), m.end()) for m in block_matches]
50-
75+
5176
# Now find all $$ pairs
5277
all_matches = list(re.finditer(r'\$\$(.*?)\$\$', content, re.DOTALL))
53-
78+
5479
# Filter to only inline matches by checking if they overlap with any block matches
5580
def is_inline(match):
5681
pos = match.span()
5782
return not any(block_start <= pos[0] <= block_end for block_start, block_end in block_positions)
58-
83+
5984
inline_matches = [m for m in all_matches if is_inline(m)]
60-
85+
6186
# Replace inline $$ with $ working backwards to preserve positions
6287
for match in reversed(inline_matches):
6388
start, end = match.span()
@@ -66,8 +91,22 @@ def is_inline(match):
6691
source[0] = content
6792

6893
def setup(app):
69-
# Processing toctrees is really slow, O(n^2), so we will leave them commented out
70-
# app.connect('source-read', source_read_handler)
94+
# Register custom configuration value
95+
app.add_config_value('build_toctree', False, 'env', [bool])
96+
97+
# Check if we want to build toctrees for validation
98+
# This can be set via: sphinx-build -D build_toctree=true
99+
build_toctree = getattr(app.config, 'build_toctree', False)
100+
101+
if build_toctree:
102+
# Enable toctree processing to verify all docs are included
103+
app.connect('source-read', uncomment_toctrees)
104+
else:
105+
# When not building toctrees, add :orphan: to documents to suppress toctree warnings
106+
# Processing toctrees is really slow, so we leave them commented out in normal builds
107+
# and build the TOC a different way
108+
app.connect('source-read', add_orphan_directive)
109+
71110
app.connect('source-read', latex_block_to_inline)
72111
app.connect('source-read', handle_utf16le_files)
73112

@@ -98,25 +137,24 @@ def setup(app):
98137
# Debugging flag for verbose output
99138
verbose = True
100139

101-
intersphinx_mapping = {
102-
'python': ('https://docs.python.org/3/', None),
103-
'sphinx': ('https://www.sphinx-doc.org/en/master/', None),
104-
}
105-
intersphinx_disabled_domains = ['std']
106-
107140
templates_path = ['_templates']
108141
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store', 'index.md',
142+
'external/slang/CONTRIBUTING.md',
143+
'external/slang/README.md',
144+
'external/slang/docs/README.md',
109145
'external/slang/docs/stdlib-doc.md',
146+
'external/slang/examples/README.md',
110147
'external/slang/external',
148+
'external/slangpy',
149+
'getting-started.md',
111150
]
112-
include_patterns = ['index.rst', '*.md',
113-
"external/slang/docs/user-guide/*.md",
114-
"external/slang/docs/command-line-slangc-reference.md",
115-
"external/core-module-reference/index.md",
116-
"external/core-module-reference/attributes/**",
117-
"external/core-module-reference/global-decls/**",
118-
"external/core-module-reference/interfaces/**",
119-
"external/core-module-reference/types/**",
151+
152+
include_patterns = [
153+
'index.rst',
154+
'*.md',
155+
'*.rst',
156+
'**/*.md',
157+
'**/*.rst',
120158
]
121159

122160
# Configure myst-parser for markdown files
@@ -133,6 +171,21 @@ def setup(app):
133171
myst_heading_anchors = 3
134172
myst_title_to_header = True
135173

174+
# Suppress specific warnings
175+
suppress_warnings = ["myst.header", "myst.xref_missing", "myst.xref_ambiguous"]
176+
177+
linkcheck_anchors = False
178+
linkcheck_ignore = [
179+
r"https://github.com/your-name/.*",
180+
r"http://claude.ai/code",
181+
r"http://libllvm\.so.*",
182+
r"http://libLLVM\.so.*",
183+
r"http://slang\.so.*",
184+
]
185+
linkcheck_rate_limit_timeout = 30.0
186+
linkcheck_report_timeouts_as_broken = True
187+
linkcheck_retries = 3
188+
136189
# -- Options for HTML output -------------------------------------------------
137190
# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output
138191

0 commit comments

Comments
 (0)