diff --git a/CHANGES.rst b/CHANGES.rst index 4f881ac175c..732bc7a487c 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -92,6 +92,9 @@ Deprecated Features added -------------- +* #12474: Support type-dependent search result highlighting via CSS. + Patch by Tim Hoffmann. + Bugs fixed ---------- diff --git a/doc/_themes/sphinx13/static/sphinx13.css b/doc/_themes/sphinx13/static/sphinx13.css index 8bf98144a81..54e707e386c 100644 --- a/doc/_themes/sphinx13/static/sphinx13.css +++ b/doc/_themes/sphinx13/static/sphinx13.css @@ -694,3 +694,25 @@ div.sphinx-feature > p.admonition-title::before { justify-content: center; gap: 10px; } + +/* -- search results -------------------------------------------------------- */ + +ul.search { + padding-left: 30px; +} +ul.search li { + padding: 5px 0 5px 10px; + list-style-type: "\25A1"; /* Unicode: White Square */ +} +ul.search li.context-index { + list-style-type: "\1F4D1"; /* Unicode: Bookmark Tabs */ +} +ul.search li.context-object { + list-style-type: "\1F4E6"; /* Unicode: Package */ +} +ul.search li.context-title { + list-style-type: "\1F4C4"; /* Unicode: Page Facing Up */ +} +ul.search li.context-text { + list-style-type: "\1F4C4"; /* Unicode: Page Facing Up */ +} diff --git a/doc/development/html_themes/index.rst b/doc/development/html_themes/index.rst index 35a3b363a36..555f415a058 100644 --- a/doc/development/html_themes/index.rst +++ b/doc/development/html_themes/index.rst @@ -221,6 +221,60 @@ If your theme package contains two or more themes, please call ``sphinx.html_themes`` entry_points feature. +Styling with CSS +---------------- +The **stylesheets** setting allows to add custom CSS files to a theme. + +The structure of the HTML elements and their classes are currently not a +well-defined public API. Please infer them from inspecting the built HTML +pages. While we cannot guarantee full stability, they tend to be fairly +stable. + +Styling search result entries by category +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. versionadded:: 8.0 + +The search result items have classes indicating the context in which the +search term was found. You can use the CSS selectors: + +- ``ul.search li.context-index``: + If the search term is found in an index such as the glossary +- ``ul.search li.context-object``: + If the search term a code object such as a python function +- ``ul.search li.context-text``: + If the search term is found in plain documentation text +- ``ul.search li.context-title``: + If the search term is found in a heading + +The basic theme is intentional minimal and does not use them for styling. +Derived themes are encouraged to use these selectors as they see fit. +For example, the following code would add context-dependent icons to the +search result list: + +.. code-block:: css + + ul.search { + padding-left: 30px; + } + ul.search li { + padding: 5px 0 5px 10px; + list-style-type: "\25A1"; /* Unicode: White Square */ + } + ul.search li.context-index { + list-style-type: "\1F4D1"; /* Unicode: Bookmark Tabs */ + } + ul.search li.context-object { + list-style-type: "\1F4E6"; /* Unicode: Package */ + } + ul.search li.context-title { + list-style-type: "\1F4C4"; /* Unicode: Page Facing Up */ + } + ul.search li.context-text { + list-style-type: "\1F4C4"; /* Unicode: Page Facing Up */ + } + + Templating ---------- diff --git a/sphinx/themes/basic/static/basic.css.jinja b/sphinx/themes/basic/static/basic.css.jinja index 297b9bfaeff..53fbadb0b6a 100644 --- a/sphinx/themes/basic/static/basic.css.jinja +++ b/sphinx/themes/basic/static/basic.css.jinja @@ -115,15 +115,11 @@ img { /* -- search page ----------------------------------------------------------- */ ul.search { - margin: 10px 0 0 20px; - padding: 0; + margin-top: 10px; } ul.search li { - padding: 5px 0 5px 20px; - background-image: url(file.png); - background-repeat: no-repeat; - background-position: 0 7px; + padding: 5px 0; } ul.search li a { diff --git a/sphinx/themes/basic/static/searchtools.js b/sphinx/themes/basic/static/searchtools.js index b08d58c9b9b..f1ee12781c0 100644 --- a/sphinx/themes/basic/static/searchtools.js +++ b/sphinx/themes/basic/static/searchtools.js @@ -20,7 +20,7 @@ if (typeof Scorer === "undefined") { // and returns the new score. /* score: result => { - const [docname, title, anchor, descr, score, filename] = result + const [docname, title, anchor, descr, score, filename, context] = result return score }, */ @@ -47,6 +47,14 @@ if (typeof Scorer === "undefined") { }; } +// Global search result kind enum, used by themes to style search results. +class SearchResultContext { + static get index() { return "index"; } + static get object() { return "object"; } + static get text() { return "text"; } + static get title() { return "title"; } +} + const _removeChildren = (element) => { while (element && element.lastChild) element.removeChild(element.lastChild); }; @@ -64,9 +72,13 @@ const _displayItem = (item, searchTerms, highlightTerms) => { const showSearchSummary = DOCUMENTATION_OPTIONS.SHOW_SEARCH_SUMMARY; const contentRoot = document.documentElement.dataset.content_root; - const [docName, title, anchor, descr, score, _filename] = item; + const [docName, title, anchor, descr, score, _filename, context] = item; let listItem = document.createElement("li"); + // Add a class representing the item's type: + // can be used by a theme's CSS selector for styling + // See SearchResultContext for the class names. + listItem.classList.add(`context-${context}`); let requestUrl; let linkUrl; if (docBuilder === "dirhtml") { @@ -138,7 +150,7 @@ const _displayNextItem = ( else _finishSearch(resultCount); }; // Helper function used by query() to order search results. -// Each input is an array of [docname, title, anchor, descr, score, filename]. +// Each input is an array of [docname, title, anchor, descr, score, filename, context]. // Order the results by score (in opposite order of appearance, since the // `_displayNextItem` function uses pop() to retrieve items) and then alphabetically. const _orderResultsByScoreThenName = (a, b) => { @@ -248,6 +260,7 @@ const Search = { searchSummary.classList.add("search-summary"); searchSummary.innerText = ""; const searchList = document.createElement("ul"); + searchList.setAttribute("role", "list"); searchList.classList.add("search"); const out = document.getElementById("search-results"); @@ -318,7 +331,7 @@ const Search = { const indexEntries = Search._index.indexentries; // Collect multiple result groups to be sorted separately and then ordered. - // Each is an array of [docname, title, anchor, descr, score, filename]. + // Each is an array of [docname, title, anchor, descr, score, filename, context]. const normalResults = []; const nonMainIndexResults = []; @@ -337,6 +350,7 @@ const Search = { null, score + boost, filenames[file], + SearchResultContext.title, ]); } } @@ -354,6 +368,7 @@ const Search = { null, score, filenames[file], + SearchResultContext.index, ]; if (isMain) { normalResults.push(result); @@ -475,6 +490,7 @@ const Search = { descr, score, filenames[match[0]], + SearchResultContext.object, ]); }; Object.keys(objects).forEach((prefix) => @@ -585,6 +601,7 @@ const Search = { null, score, filenames[file], + SearchResultContext.text, ]); } return results; diff --git a/tests/js/searchtools.js b/tests/js/searchtools.js index c82c6f1f968..5ef1ea96588 100644 --- a/tests/js/searchtools.js +++ b/tests/js/searchtools.js @@ -38,7 +38,8 @@ describe('Basic html theme search', function() { "", null, 5, - "index.rst" + "index.rst", + "text" ]]; expect(Search.performTermsSearch(searchterms, excluded)).toEqual(hits); }); @@ -53,7 +54,9 @@ describe('Basic html theme search', function() { '', null, 15, - 'index.rst']]; + 'index.rst', + 'text' + ]]; expect(Search.performTermsSearch(searchterms, excluded)).toEqual(hits); }); @@ -68,7 +71,8 @@ describe('Basic html theme search', function() { "", null, 7, - "index.rst" + "index.rst", + "text" ]]; expect(Search.performTermsSearch(searchterms, excluded)).toEqual(hits); }); @@ -89,7 +93,8 @@ describe('Basic html theme search', function() { '', null, 16, - 'index.rst' + 'index.rst', + 'title' ] ]; expect(Search._performSearch(...searchParameters)).toEqual(hits);