Skip to content

Commit d0a47a9

Browse files
Deploying to main from @ amaranth-lang/amaranth-soc@5c43cf5 🚀
1 parent 5aed0db commit d0a47a9

12 files changed

+169
-103
lines changed

docs/amaranth-soc/latest/_static/basic.css

+5-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
*
55
* Sphinx stylesheet -- basic theme.
66
*
7-
* :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS.
7+
* :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS.
88
* :license: BSD, see LICENSE for details.
99
*
1010
*/
@@ -237,6 +237,10 @@ a.headerlink {
237237
visibility: hidden;
238238
}
239239

240+
a:visited {
241+
color: #551A8B;
242+
}
243+
240244
h1:hover > a.headerlink,
241245
h2:hover > a.headerlink,
242246
h3:hover > a.headerlink,

docs/amaranth-soc/latest/_static/doctools.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
*
55
* Base JavaScript utilities for all Sphinx HTML documentation.
66
*
7-
* :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS.
7+
* :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS.
88
* :license: BSD, see LICENSE for details.
99
*
1010
*/

docs/amaranth-soc/latest/_static/documentation_options.js

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
var DOCUMENTATION_OPTIONS = {
2-
URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'),
3-
VERSION: '0.1a1.dev23',
1+
const DOCUMENTATION_OPTIONS = {
2+
VERSION: '0.1a1.dev24',
43
LANGUAGE: 'en',
54
COLLAPSE_INDEX: false,
65
BUILDER: 'html',

docs/amaranth-soc/latest/_static/language_data.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,15 @@
55
* This script contains the language-specific data used by searchtools.js,
66
* namely the list of stopwords, stemmer, scorer and splitter.
77
*
8-
* :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS.
8+
* :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS.
99
* :license: BSD, see LICENSE for details.
1010
*
1111
*/
1212

1313
var stopwords = ["a", "and", "are", "as", "at", "be", "but", "by", "for", "if", "in", "into", "is", "it", "near", "no", "not", "of", "on", "or", "such", "that", "the", "their", "then", "there", "these", "they", "this", "to", "was", "will", "with"];
1414

1515

16-
/* Non-minified version is copied as a separate JS file, is available */
16+
/* Non-minified version is copied as a separate JS file, if available */
1717

1818
/**
1919
* Porter Stemmer

docs/amaranth-soc/latest/_static/searchtools.js

+122-69
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
*
55
* Sphinx JavaScript utilities for the full-text search.
66
*
7-
* :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS.
7+
* :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS.
88
* :license: BSD, see LICENSE for details.
99
*
1010
*/
@@ -57,12 +57,12 @@ const _removeChildren = (element) => {
5757
const _escapeRegExp = (string) =>
5858
string.replace(/[.*+\-?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string
5959

60-
const _displayItem = (item, searchTerms) => {
60+
const _displayItem = (item, searchTerms, highlightTerms) => {
6161
const docBuilder = DOCUMENTATION_OPTIONS.BUILDER;
62-
const docUrlRoot = DOCUMENTATION_OPTIONS.URL_ROOT;
6362
const docFileSuffix = DOCUMENTATION_OPTIONS.FILE_SUFFIX;
6463
const docLinkSuffix = DOCUMENTATION_OPTIONS.LINK_SUFFIX;
6564
const showSearchSummary = DOCUMENTATION_OPTIONS.SHOW_SEARCH_SUMMARY;
65+
const contentRoot = document.documentElement.dataset.content_root;
6666

6767
const [docName, title, anchor, descr, score, _filename] = item;
6868

@@ -75,28 +75,35 @@ const _displayItem = (item, searchTerms) => {
7575
if (dirname.match(/\/index\/$/))
7676
dirname = dirname.substring(0, dirname.length - 6);
7777
else if (dirname === "index/") dirname = "";
78-
requestUrl = docUrlRoot + dirname;
78+
requestUrl = contentRoot + dirname;
7979
linkUrl = requestUrl;
8080
} else {
8181
// normal html builders
82-
requestUrl = docUrlRoot + docName + docFileSuffix;
82+
requestUrl = contentRoot + docName + docFileSuffix;
8383
linkUrl = docName + docLinkSuffix;
8484
}
8585
let linkEl = listItem.appendChild(document.createElement("a"));
8686
linkEl.href = linkUrl + anchor;
8787
linkEl.dataset.score = score;
8888
linkEl.innerHTML = title;
89-
if (descr)
89+
if (descr) {
9090
listItem.appendChild(document.createElement("span")).innerHTML =
9191
" (" + descr + ")";
92+
// highlight search terms in the description
93+
if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js
94+
highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted"));
95+
}
9296
else if (showSearchSummary)
9397
fetch(requestUrl)
9498
.then((responseData) => responseData.text())
9599
.then((data) => {
96100
if (data)
97101
listItem.appendChild(
98-
Search.makeSearchSummary(data, searchTerms)
102+
Search.makeSearchSummary(data, searchTerms, anchor)
99103
);
104+
// highlight search terms in the summary
105+
if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js
106+
highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted"));
100107
});
101108
Search.output.appendChild(listItem);
102109
};
@@ -109,26 +116,43 @@ const _finishSearch = (resultCount) => {
109116
);
110117
else
111118
Search.status.innerText = _(
112-
`Search finished, found ${resultCount} page(s) matching the search query.`
113-
);
119+
"Search finished, found ${resultCount} page(s) matching the search query."
120+
).replace('${resultCount}', resultCount);
114121
};
115122
const _displayNextItem = (
116123
results,
117124
resultCount,
118-
searchTerms
125+
searchTerms,
126+
highlightTerms,
119127
) => {
120128
// results left, load the summary and display it
121129
// this is intended to be dynamic (don't sub resultsCount)
122130
if (results.length) {
123-
_displayItem(results.pop(), searchTerms);
131+
_displayItem(results.pop(), searchTerms, highlightTerms);
124132
setTimeout(
125-
() => _displayNextItem(results, resultCount, searchTerms),
133+
() => _displayNextItem(results, resultCount, searchTerms, highlightTerms),
126134
5
127135
);
128136
}
129137
// search finished, update title and status message
130138
else _finishSearch(resultCount);
131139
};
140+
// Helper function used by query() to order search results.
141+
// Each input is an array of [docname, title, anchor, descr, score, filename].
142+
// Order the results by score (in opposite order of appearance, since the
143+
// `_displayNextItem` function uses pop() to retrieve items) and then alphabetically.
144+
const _orderResultsByScoreThenName = (a, b) => {
145+
const leftScore = a[4];
146+
const rightScore = b[4];
147+
if (leftScore === rightScore) {
148+
// same score: sort alphabetically
149+
const leftTitle = a[1].toLowerCase();
150+
const rightTitle = b[1].toLowerCase();
151+
if (leftTitle === rightTitle) return 0;
152+
return leftTitle > rightTitle ? -1 : 1; // inverted is intentional
153+
}
154+
return leftScore > rightScore ? 1 : -1;
155+
};
132156

133157
/**
134158
* Default splitQuery function. Can be overridden in ``sphinx.search`` with a
@@ -152,13 +176,26 @@ const Search = {
152176
_queued_query: null,
153177
_pulse_status: -1,
154178

155-
htmlToText: (htmlString) => {
179+
htmlToText: (htmlString, anchor) => {
156180
const htmlElement = new DOMParser().parseFromString(htmlString, 'text/html');
157-
htmlElement.querySelectorAll(".headerlink").forEach((el) => { el.remove() });
181+
for (const removalQuery of [".headerlinks", "script", "style"]) {
182+
htmlElement.querySelectorAll(removalQuery).forEach((el) => { el.remove() });
183+
}
184+
if (anchor) {
185+
const anchorContent = htmlElement.querySelector(`[role="main"] ${anchor}`);
186+
if (anchorContent) return anchorContent.textContent;
187+
188+
console.warn(
189+
`Anchored content block not found. Sphinx search tries to obtain it via DOM query '[role=main] ${anchor}'. Check your theme or template.`
190+
);
191+
}
192+
193+
// if anchor not specified or not found, fall back to main content
158194
const docContent = htmlElement.querySelector('[role="main"]');
159-
if (docContent !== undefined) return docContent.textContent;
195+
if (docContent) return docContent.textContent;
196+
160197
console.warn(
161-
"Content block not found. Sphinx search tries to obtain it via '[role=main]'. Could you check your theme or template."
198+
"Content block not found. Sphinx search tries to obtain it via DOM query '[role=main]'. Check your theme or template."
162199
);
163200
return "";
164201
},
@@ -231,16 +268,7 @@ const Search = {
231268
else Search.deferQuery(query);
232269
},
233270

234-
/**
235-
* execute search (requires search index to be loaded)
236-
*/
237-
query: (query) => {
238-
const filenames = Search._index.filenames;
239-
const docNames = Search._index.docnames;
240-
const titles = Search._index.titles;
241-
const allTitles = Search._index.alltitles;
242-
const indexEntries = Search._index.indexentries;
243-
271+
_parseQuery: (query) => {
244272
// stem the search terms and add them to the correct list
245273
const stemmer = new Stemmer();
246274
const searchTerms = new Set();
@@ -276,16 +304,32 @@ const Search = {
276304
// console.info("required: ", [...searchTerms]);
277305
// console.info("excluded: ", [...excludedTerms]);
278306

279-
// array of [docname, title, anchor, descr, score, filename]
280-
let results = [];
307+
return [query, searchTerms, excludedTerms, highlightTerms, objectTerms];
308+
},
309+
310+
/**
311+
* execute search (requires search index to be loaded)
312+
*/
313+
_performSearch: (query, searchTerms, excludedTerms, highlightTerms, objectTerms) => {
314+
const filenames = Search._index.filenames;
315+
const docNames = Search._index.docnames;
316+
const titles = Search._index.titles;
317+
const allTitles = Search._index.alltitles;
318+
const indexEntries = Search._index.indexentries;
319+
320+
// Collect multiple result groups to be sorted separately and then ordered.
321+
// Each is an array of [docname, title, anchor, descr, score, filename].
322+
const normalResults = [];
323+
const nonMainIndexResults = [];
324+
281325
_removeChildren(document.getElementById("search-progress"));
282326

283-
const queryLower = query.toLowerCase();
327+
const queryLower = query.toLowerCase().trim();
284328
for (const [title, foundTitles] of Object.entries(allTitles)) {
285-
if (title.toLowerCase().includes(queryLower) && (queryLower.length >= title.length/2)) {
329+
if (title.toLowerCase().trim().includes(queryLower) && (queryLower.length >= title.length/2)) {
286330
for (const [file, id] of foundTitles) {
287331
let score = Math.round(100 * queryLower.length / title.length)
288-
results.push([
332+
normalResults.push([
289333
docNames[file],
290334
titles[file] !== title ? `${titles[file]} > ${title}` : title,
291335
id !== null ? "#" + id : "",
@@ -300,46 +344,47 @@ const Search = {
300344
// search for explicit entries in index directives
301345
for (const [entry, foundEntries] of Object.entries(indexEntries)) {
302346
if (entry.includes(queryLower) && (queryLower.length >= entry.length/2)) {
303-
for (const [file, id] of foundEntries) {
304-
let score = Math.round(100 * queryLower.length / entry.length)
305-
results.push([
347+
for (const [file, id, isMain] of foundEntries) {
348+
const score = Math.round(100 * queryLower.length / entry.length);
349+
const result = [
306350
docNames[file],
307351
titles[file],
308352
id ? "#" + id : "",
309353
null,
310354
score,
311355
filenames[file],
312-
]);
356+
];
357+
if (isMain) {
358+
normalResults.push(result);
359+
} else {
360+
nonMainIndexResults.push(result);
361+
}
313362
}
314363
}
315364
}
316365

317366
// lookup as object
318367
objectTerms.forEach((term) =>
319-
results.push(...Search.performObjectSearch(term, objectTerms))
368+
normalResults.push(...Search.performObjectSearch(term, objectTerms))
320369
);
321370

322371
// lookup as search terms in fulltext
323-
results.push(...Search.performTermsSearch(searchTerms, excludedTerms));
372+
normalResults.push(...Search.performTermsSearch(searchTerms, excludedTerms));
324373

325374
// let the scorer override scores with a custom scoring function
326-
if (Scorer.score) results.forEach((item) => (item[4] = Scorer.score(item)));
327-
328-
// now sort the results by score (in opposite order of appearance, since the
329-
// display function below uses pop() to retrieve items) and then
330-
// alphabetically
331-
results.sort((a, b) => {
332-
const leftScore = a[4];
333-
const rightScore = b[4];
334-
if (leftScore === rightScore) {
335-
// same score: sort alphabetically
336-
const leftTitle = a[1].toLowerCase();
337-
const rightTitle = b[1].toLowerCase();
338-
if (leftTitle === rightTitle) return 0;
339-
return leftTitle > rightTitle ? -1 : 1; // inverted is intentional
340-
}
341-
return leftScore > rightScore ? 1 : -1;
342-
});
375+
if (Scorer.score) {
376+
normalResults.forEach((item) => (item[4] = Scorer.score(item)));
377+
nonMainIndexResults.forEach((item) => (item[4] = Scorer.score(item)));
378+
}
379+
380+
// Sort each group of results by score and then alphabetically by name.
381+
normalResults.sort(_orderResultsByScoreThenName);
382+
nonMainIndexResults.sort(_orderResultsByScoreThenName);
383+
384+
// Combine the result groups in (reverse) order.
385+
// Non-main index entries are typically arbitrary cross-references,
386+
// so display them after other results.
387+
let results = [...nonMainIndexResults, ...normalResults];
343388

344389
// remove duplicate search results
345390
// note the reversing of results, so that in the case of duplicates, the highest-scoring entry is kept
@@ -353,14 +398,19 @@ const Search = {
353398
return acc;
354399
}, []);
355400

356-
results = results.reverse();
401+
return results.reverse();
402+
},
403+
404+
query: (query) => {
405+
const [searchQuery, searchTerms, excludedTerms, highlightTerms, objectTerms] = Search._parseQuery(query);
406+
const results = Search._performSearch(searchQuery, searchTerms, excludedTerms, highlightTerms, objectTerms);
357407

358408
// for debugging
359409
//Search.lastresults = results.slice(); // a copy
360410
// console.info("search results:", Search.lastresults);
361411

362412
// print the results
363-
_displayNextItem(results, results.length, searchTerms);
413+
_displayNextItem(results, results.length, searchTerms, highlightTerms);
364414
},
365415

366416
/**
@@ -458,14 +508,18 @@ const Search = {
458508
// add support for partial matches
459509
if (word.length > 2) {
460510
const escapedWord = _escapeRegExp(word);
461-
Object.keys(terms).forEach((term) => {
462-
if (term.match(escapedWord) && !terms[word])
463-
arr.push({ files: terms[term], score: Scorer.partialTerm });
464-
});
465-
Object.keys(titleTerms).forEach((term) => {
466-
if (term.match(escapedWord) && !titleTerms[word])
467-
arr.push({ files: titleTerms[word], score: Scorer.partialTitle });
468-
});
511+
if (!terms.hasOwnProperty(word)) {
512+
Object.keys(terms).forEach((term) => {
513+
if (term.match(escapedWord))
514+
arr.push({ files: terms[term], score: Scorer.partialTerm });
515+
});
516+
}
517+
if (!titleTerms.hasOwnProperty(word)) {
518+
Object.keys(titleTerms).forEach((term) => {
519+
if (term.match(escapedWord))
520+
arr.push({ files: titleTerms[term], score: Scorer.partialTitle });
521+
});
522+
}
469523
}
470524

471525
// no match but word was a required one
@@ -488,9 +542,8 @@ const Search = {
488542

489543
// create the mapping
490544
files.forEach((file) => {
491-
if (fileMap.has(file) && fileMap.get(file).indexOf(word) === -1)
492-
fileMap.get(file).push(word);
493-
else fileMap.set(file, [word]);
545+
if (!fileMap.has(file)) fileMap.set(file, [word]);
546+
else if (fileMap.get(file).indexOf(word) === -1) fileMap.get(file).push(word);
494547
});
495548
});
496549

@@ -541,8 +594,8 @@ const Search = {
541594
* search summary for a given text. keywords is a list
542595
* of stemmed words.
543596
*/
544-
makeSearchSummary: (htmlText, keywords) => {
545-
const text = Search.htmlToText(htmlText);
597+
makeSearchSummary: (htmlText, keywords, anchor) => {
598+
const text = Search.htmlToText(htmlText, anchor);
546599
if (text === "") return null;
547600

548601
const textLower = text.toLowerCase();

0 commit comments

Comments
 (0)