• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2024 The Pigweed Authors
2#
3# Licensed under the Apache License, Version 2.0 (the "License"); you may not
4# use this file except in compliance with the License. You may obtain a copy of
5# the License at
6#
7#     https://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12# License for the specific language governing permissions and limitations under
13# the License.
14"""Generates a sitemap for pigweed.dev."""
15
16
17from sphinx.application import Sphinx
18
19
20def build_url(docname: str) -> str:
21    url = f'https://pigweed.dev/{docname}.html'
22    # The pigweed.dev production server redirects pages that end with
23    # `…/docs.html` to `…/`. E.g. `https://pigweed.dev/pw_string/docs.html`
24    # redirects to `https://pigweed.dev/pw_string/`. The latter is the version
25    # that should be recorded in the sitemap for optimal SEO. b/386257958
26    #
27    # Be careful not to clobber other files that end in `docs.html` such
28    # as `https://pigweed.dev/targets/rp2040/target_docs.html`.
29    #
30    # The server also redirects pages that end in `…/index.html`.
31    redirects = [
32        '/docs.html',
33        '/index.html',
34    ]
35    for pattern in redirects:
36        if url.endswith(pattern):
37            end = url.rfind(pattern)
38            url = url[0:end]
39            url += '/'
40    return url
41
42
43def generate_sitemap(app: Sphinx, exception: Exception | None) -> None:
44    urls = []
45    for docname in app.project.docnames:
46        urls.append(build_url(docname))
47    urls.sort()
48    sitemap = '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">\n'
49    for url in urls:
50        sitemap += f'  <url><loc>{url}</loc></url>\n'
51    sitemap += '</urlset>\n'
52    with open(f'{app.outdir}/sitemap.xml', 'w') as f:
53        f.write(sitemap)
54
55
56def setup(app: Sphinx) -> dict[str, bool]:
57    app.connect('build-finished', generate_sitemap)
58    return {
59        'parallel_read_safe': True,
60        'parallel_write_safe': True,
61    }
62