Utilities/Sphinx: Give the Qt Help output a color scheme

The `qthelp` builder renders with Sphinx's `nonav` theme, so the color
scheme that `cmake.css` picks up from the `default` theme in the html
build is never generated for it.  The workaround that inlines the
`@import` in `cmake.css` silently falls back to `basic.css`, which
carries layout rules only, leaving the `.qch` pages with no styling of
their own.

Supply one, generated from a single template and two palettes.  Qt
Creator serves a documentation set's own `offline-dark.css` in place of
its `offline.css` or `offline-simple.css` when the Qt Creator theme is
dark, so link the stylesheet under one of those names and ship a dark
counterpart next to it.  Qt Creator 20 and older substitute only for
`offline-simple.css`, and request `offline.css` instead when the theme
is light, so install the light palette under both names.

The html build is unaffected: the extra stylesheet is linked, and its
static directory is added, only under the `qthelp` tag.
This commit is contained in:
Cristian Adam committed 2026-10-10 11:27:53 +02:00
1 parent 8b67addb02
commit 2c480ea4ff
5 files changed
+435

No files matched your search

+8
View File
@@ -0,0 +1,8 @@
qthelp-dark-theme
-----------------
* The Qt Help (``.qch``) rendition of the documentation now carries its own
color scheme. Previously it was rendered with layout rules only, because
the ``qthelp`` builder does not generate the color scheme that the HTML
documentation uses. A dark variant is shipped alongside it, which help
viewers such as Qt Creator use when their own theme is dark.
+6
View File
@@ -78,6 +78,7 @@ endif()
set(conf_docs "${CMake_SOURCE_DIR}/Help")
set(conf_path "${CMAKE_CURRENT_SOURCE_DIR}")
set(conf_qthelp_static "${CMAKE_CURRENT_BINARY_DIR}/static-qthelp")
set(conf_version "${CMake_VERSION_MAJOR}.${CMake_VERSION_MINOR}.${CMake_VERSION_PATCH}")
set(conf_release "${CMake_VERSION}")
configure_file(conf.py.in conf.py @ONLY)
@@ -139,6 +140,11 @@ if(SPHINX_QTHELP)
endif()
list(APPEND doc_formats qthelp)
# Generate the light and dark stylesheets, and tell `conf.py` to link them.
set(qthelp_css_outdir "${conf_qthelp_static}")
include("${CMAKE_CURRENT_SOURCE_DIR}/qthelp_css.cmake")
set(doc_qthelp_opts -t qthelp)
set(qthelp_post_commands
# Workaround for assistant prior to
# https://codereview.qt-project.org/#change,82250 in Qt 4.
+8
View File
@@ -91,6 +91,14 @@ html_theme_options = {
'codebgcolor': '#eeeeee',
'codetextcolor': '#333333',
}
if tags.has('qthelp'):
# The qthelp builder renders with the 'nonav' theme, which contributes no
# colors of its own, so link a stylesheet that supplies them. Name it
# 'offline-simple.css' because Qt Creator serves the 'offline-dark.css'
# next to it instead when the Qt Creator theme is dark.
html_static_path.append('@conf_qthelp_static@')
html_css_files = ['offline-simple.css']
html_title = 'CMake %s Documentation' % release
html_short_title = '%s Documentation' % release
html_favicon = '@conf_path@/static/cmake-favicon.ico'
+113
View File
@@ -0,0 +1,113 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file LICENSE.rst or https://cmake.org/licensing for details.
# Generate the stylesheets that the Qt Help (.qch) rendition of the
# documentation uses, from `static-qthelp/qthelp.css.in` and the two palettes
# below. The caller provides `qthelp_css_outdir`.
#
# Qt Creator serves a documentation set's own `offline-dark.css` in place of
# its `offline.css` or `offline-simple.css` when the Qt Creator theme is dark,
# so the pages link a stylesheet under one of those names and we ship a dark
# counterpart next to it. Qt Creator 20 and older only substitute for
# `offline-simple.css`, and request `offline.css` instead when the theme is
# light, so the light palette is installed under both names.
# Light palette, matching `html_theme_options` in `conf.py.in` and the
# Pygments style in `colors.py`.
set(qthelp_body_bg "#ffffff")
set(qthelp_body_fg "#444444")
set(qthelp_link "#2b63a8")
set(qthelp_link_visited "#2b63a8")
set(qthelp_head_bg "#f2f2f2")
set(qthelp_head_fg "#003564")
set(qthelp_head_border "#cccccc")
set(qthelp_headerlink "#3d8ff2")
set(qthelp_muted "#888888")
set(qthelp_pre_bg "#eeeeee")
set(qthelp_pre_fg "#333333")
set(qthelp_pre_border "#aacc99")
set(qthelp_code_bg "#ecf0f3")
set(qthelp_code_fg "#333333")
set(qthelp_literal_link_bg "#dfdfdf")
set(qthelp_topic_bg "#eeeeee")
set(qthelp_note_bg "#eeeeee")
set(qthelp_note_border "#cccccc")
set(qthelp_seealso_bg "#ffffcc")
set(qthelp_seealso_border "#ffff66")
set(qthelp_warning_bg "#ffe4e4")
set(qthelp_warning_border "#ff6666")
set(qthelp_border "#aaaaaa")
set(qthelp_hll_bg "#ffffcc")
set(qthelp_tok_comment "#408080")
set(qthelp_tok_operator "#555555")
set(qthelp_tok_string "#217a21")
set(qthelp_tok_number "#105030")
set(qthelp_tok_builtin "#333333")
set(qthelp_tok_function "#007020")
set(qthelp_tok_variable "#1080b0")
set(qthelp_tok_tag "#bb60d5")
set(qthelp_tok_constant "#4070a0")
set(qthelp_tok_entity "#70a020")
set(qthelp_tok_attribute "#906060")
set(qthelp_tok_label "#a0a000")
set(qthelp_tok_exception "#ff0000")
set(qthelp_tok_whitespace "#bbbbbb")
configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/static-qthelp/qthelp.css.in"
"${qthelp_css_outdir}/offline.css"
@ONLY
)
configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/static-qthelp/qthelp.css.in"
"${qthelp_css_outdir}/offline-simple.css"
@ONLY
)
# Dark palette. The background and foreground match the stylesheet that
# Qt Creator falls back to for documentation that ships no dark variant, so
# that the CMake pages sit well next to the Qt pages in the same help pane.
set(qthelp_body_bg "#262626")
set(qthelp_body_fg "#d0d0d0")
set(qthelp_link "#6ab0f3")
set(qthelp_link_visited "#6ab0f3")
set(qthelp_head_bg "#353637")
set(qthelp_head_fg "#a8c8ea")
set(qthelp_head_border "#4a4b4c")
set(qthelp_headerlink "#6ab0f3")
set(qthelp_muted "#9a9a9a")
set(qthelp_pre_bg "#2d2e2f")
set(qthelp_pre_fg "#d0d0d0")
set(qthelp_pre_border "#4e5a46")
set(qthelp_code_bg "#353637")
set(qthelp_code_fg "#d0d0d0")
set(qthelp_literal_link_bg "#3a3b3c")
set(qthelp_topic_bg "#2d2e2f")
set(qthelp_note_bg "#2d2e2f")
set(qthelp_note_border "#4a4b4c")
set(qthelp_seealso_bg "#39381f")
set(qthelp_seealso_border "#5c5a30")
set(qthelp_warning_bg "#3d2727")
set(qthelp_warning_border "#7a4040")
set(qthelp_border "#4a4b4c")
set(qthelp_hll_bg "#4a4a2a")
set(qthelp_tok_comment "#7fb7b7")
set(qthelp_tok_operator "#b0b0b0")
set(qthelp_tok_string "#6fc96f")
set(qthelp_tok_number "#5fc090")
set(qthelp_tok_builtin "#cccccc")
set(qthelp_tok_function "#5fc45f")
set(qthelp_tok_variable "#5fb8e8")
set(qthelp_tok_tag "#d79ae8")
set(qthelp_tok_constant "#85aee0")
set(qthelp_tok_entity "#a8d060")
set(qthelp_tok_attribute "#c89a9a")
set(qthelp_tok_label "#cfcf60")
set(qthelp_tok_exception "#ff6b6b")
set(qthelp_tok_whitespace "#555555")
configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/static-qthelp/qthelp.css.in"
"${qthelp_css_outdir}/offline-dark.css"
@ONLY
)
@@ -0,0 +1,300 @@
/* Style the Qt Help (.qch) rendition of the documentation.
*
* The qthelp builder uses Sphinx's "nonav" theme, so the color scheme that
* the "default" theme contributes to the html build is not generated here,
* leaving help viewers with just the layout rules of "basic.css". This
* template supplies a color scheme on top of them. It is configured twice:
* with a light palette into "offline.css" and "offline-simple.css", and with
* a dark palette into "offline-dark.css". Qt Creator serves the latter in
* place of the former when its own user interface theme is dark.
*
* Qt Creator's default help backend renders with litehtml, which supports
* much less CSS than a browser does, so keep the rules here simple.
*/
/* Undo the full-window layout of "cmake.css", which has no navigation bar or
footer to place in the qthelp output, and which litehtml cannot lay out. */
html,
body {
background-color: @qthelp_body_bg@;
}
body {
display: block;
min-height: 0;
margin: 0;
padding: 0;
font-family: sans-serif;
color: @qthelp_body_fg@;
}
div.document,
div.documentwrapper {
background-color: @qthelp_body_bg@;
}
/* "basic.css" caps the body width for the html build, where a sidebar takes
up the rest of the window. A help viewer has no sidebar, so use the whole
pane; it is usually narrow to begin with. */
div.body {
background-color: @qthelp_body_bg@;
color: @qthelp_body_fg@;
height: auto;
max-width: none;
padding: 0 20px 30px 20px;
}
/* -- hyperlinks ------------------------------------------------------------ */
a {
color: @qthelp_link@;
text-decoration: none;
}
a:visited {
color: @qthelp_link_visited@;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
/* -- headings -------------------------------------------------------------- */
div.body h1,
div.body h2,
div.body h3,
div.body h4,
div.body h5,
div.body h6 {
font-family: sans-serif;
background-color: @qthelp_head_bg@;
font-weight: normal;
color: @qthelp_head_fg@;
border-bottom: 1px solid @qthelp_head_border@;
margin: 20px -20px 10px -20px;
padding: 3px 0 3px 10px;
}
div.body h1 { margin-top: 0; font-size: 200%; }
div.body h2 { font-size: 160%; }
div.body h3 { font-size: 140%; }
div.body h4 { font-size: 120%; }
div.body h5 { font-size: 110%; }
div.body h6 { font-size: 100%; }
/* The section title links back to the table of contents. Keep it looking
like a heading rather than like a link. */
div.body h1 a.toc-backref,
div.body h2 a.toc-backref,
div.body h3 a.toc-backref,
div.body h4 a.toc-backref,
div.body h5 a.toc-backref,
div.body h6 a.toc-backref {
color: @qthelp_head_fg@;
text-decoration: none;
}
a.headerlink {
color: @qthelp_headerlink@;
font-size: 0.8em;
padding: 0 4px 0 4px;
text-decoration: none;
}
a.headerlink:hover {
background-color: @qthelp_headerlink@;
color: @qthelp_body_bg@;
}
/* -- body text ------------------------------------------------------------- */
div.body p,
div.body dd,
div.body li,
div.body blockquote {
line-height: 130%;
}
.versionmodified {
color: @qthelp_muted@;
}
/* -- code ------------------------------------------------------------------ */
pre {
padding: 5px;
background-color: @qthelp_pre_bg@;
color: @qthelp_pre_fg@;
line-height: 120%;
border: 1px solid @qthelp_pre_border@;
border-left: none;
border-right: none;
}
div.highlight {
background-color: @qthelp_pre_bg@;
}
code,
code.docutils.literal {
background-color: @qthelp_code_bg@;
color: @qthelp_code_fg@;
padding: 0 1px 0 1px;
font-size: 0.95em;
}
/* Cross-reference links are rendered as inline code; let the link color win. */
a code,
a code.docutils.literal {
color: @qthelp_link@;
}
th code {
background-color: inherit;
}
.literal-block a.reference.internal {
background-color: @qthelp_literal_link_bg@;
}
/* "signature" directive argument, styled like a <pre> block. */
.signature .sig {
background-color: @qthelp_pre_bg@;
color: @qthelp_pre_fg@;
border-color: @qthelp_pre_border@;
}
/* -- admonitions and topics ------------------------------------------------ */
nav.contents,
aside.topic,
div.topic {
background-color: @qthelp_topic_bg@;
border: 1px solid @qthelp_note_border@;
}
div.admonition,
div.note {
background-color: @qthelp_note_bg@;
border: 1px solid @qthelp_note_border@;
}
div.seealso {
background-color: @qthelp_seealso_bg@;
border: 1px solid @qthelp_seealso_border@;
}
div.warning {
background-color: @qthelp_warning_bg@;
border: 1px solid @qthelp_warning_border@;
}
p.admonition-title {
display: inline;
}
p.admonition-title:after {
content: ":";
}
div.admonition p.admonition-title + p {
display: inline;
}
div.outdated {
background-color: @qthelp_seealso_bg@;
color: @qthelp_body_fg@;
}
/* -- tables ---------------------------------------------------------------- */
table.docutils {
border-collapse: collapse;
}
table.docutils td,
table.docutils th {
border: 1px solid @qthelp_border@;
}
table.docutils th {
background-color: @qthelp_head_bg@;
color: @qthelp_head_fg@;
}
table.indextable tr.cap {
background-color: @qthelp_head_bg@;
}
/* The index and search result tables are layout-only. */
table.indextable td,
table.indextable th {
border: none;
}
hr {
border: 0;
border-top: 1px solid @qthelp_border@;
}
/* -- search highlighting --------------------------------------------------- */
.highlighted,
.highlight .hll {
background-color: @qthelp_hll_bg@;
}
/* -- syntax highlighting --------------------------------------------------- */
/* Overrides for "pygments.css", which is generated from `colors.py` with a
light background in mind and is linked ahead of this file. */
.highlight { background: @qthelp_pre_bg@; }
.highlight .c,
.highlight .ch,
.highlight .cm,
.highlight .cp,
.highlight .cpf,
.highlight .c1,
.highlight .cs { color: @qthelp_tok_comment@; }
.highlight .o,
.highlight .ow { color: @qthelp_tok_operator@; }
.highlight .s,
.highlight .sa,
.highlight .sb,
.highlight .sc,
.highlight .dl,
.highlight .sd,
.highlight .s2,
.highlight .se,
.highlight .sh,
.highlight .si,
.highlight .sx,
.highlight .sr,
.highlight .s1,
.highlight .ss { color: @qthelp_tok_string@; }
.highlight .m,
.highlight .mb,
.highlight .mf,
.highlight .mh,
.highlight .mi,
.highlight .mo,
.highlight .il { color: @qthelp_tok_number@; }
.highlight .nb,
.highlight .bp { color: @qthelp_tok_builtin@; }
.highlight .nf,
.highlight .fm { color: @qthelp_tok_function@; }
.highlight .nv,
.highlight .vc,
.highlight .vg,
.highlight .vi,
.highlight .vm { color: @qthelp_tok_variable@; }
.highlight .nt { color: @qthelp_tok_tag@; }
.highlight .no { color: @qthelp_tok_constant@; }
.highlight .ni { color: @qthelp_tok_entity@; }
.highlight .na { color: @qthelp_tok_attribute@; }
.highlight .nl { color: @qthelp_tok_label@; }
.highlight .ne { color: @qthelp_tok_exception@; }
.highlight .w { color: @qthelp_tok_whitespace@; }