diff --git a/docs/build/doctrees/environment.pickle b/docs/build/doctrees/environment.pickle index d5c50d5..38be255 100644 Binary files a/docs/build/doctrees/environment.pickle and b/docs/build/doctrees/environment.pickle differ diff --git a/docs/build/doctrees/errata.doctree b/docs/build/doctrees/errata.doctree index 1834ba5..39955de 100644 Binary files a/docs/build/doctrees/errata.doctree and b/docs/build/doctrees/errata.doctree differ diff --git a/docs/build/doctrees/index.doctree b/docs/build/doctrees/index.doctree index 03e78d6..b63ddc1 100644 Binary files a/docs/build/doctrees/index.doctree and b/docs/build/doctrees/index.doctree differ diff --git a/docs/build/doctrees/introduction.doctree b/docs/build/doctrees/introduction.doctree index f603c9d..08479c6 100644 Binary files a/docs/build/doctrees/introduction.doctree and b/docs/build/doctrees/introduction.doctree differ diff --git a/docs/build/doctrees/payroll_accounting.doctree b/docs/build/doctrees/payroll_accounting.doctree index cdb06b9..510db79 100644 Binary files a/docs/build/doctrees/payroll_accounting.doctree and b/docs/build/doctrees/payroll_accounting.doctree differ diff --git a/docs/build/doctrees/references.doctree b/docs/build/doctrees/references.doctree index 5533b6a..180cc52 100644 Binary files a/docs/build/doctrees/references.doctree and b/docs/build/doctrees/references.doctree differ diff --git a/docs/build/html/.buildinfo b/docs/build/html/.buildinfo index b64301a..a56e7bb 100644 --- a/docs/build/html/.buildinfo +++ b/docs/build/html/.buildinfo @@ -1,4 +1,4 @@ # Sphinx build info version 1 -# This file records the configuration used when building these files. When it is not found, a full rebuild will be done. -config: 9af8f26af39641003965e206825fa709 +# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. +config: 75a0f8b1a70e3b76aa41fc917232251c tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/docs/build/html/_sources/introduction.rst.txt b/docs/build/html/_sources/introduction.rst.txt index 1de8b34..e0e947e 100644 --- a/docs/build/html/_sources/introduction.rst.txt +++ b/docs/build/html/_sources/introduction.rst.txt @@ -9,16 +9,19 @@ Payroll Legal Framework The Canadian Payroll Administration system is designed to ensure compliance with the legal framework governing payroll in Canada. This includes adherence to federal and provincial regulations regarding employee compensation, deductions, and reporting requirements. The system is built to handle various payroll scenarios, including different employment types, tax calculations, and benefit deductions, while ensuring that all transactions are accurately recorded and reported in accordance with the law. -*********************** Payroll Accounting -*********************** +################## Payroll accounting is a critical component of the Canadian Payroll Administration system. It involves the systematic recording, analysis, and reporting of payroll transactions to ensure that all financial aspects of employee compensation are accurately reflected in the organization's financial statements. Payroll accounting includes the management of employee wages, tax withholdings, benefit deductions, and other payroll-related expenses. The system is designed to automate these processes, ensuring accuracy and compliance with Canadian payroll regulations. +"""""""""""""""""" -*********************** Journal Entries -*********************** +----------------- Journal entries are a key part of payroll accounting, as they document the financial impact of payroll transactions on the organization's accounts. Each payroll run generates a series of journal entries that reflect the distribution of wages, taxes, and deductions across various accounts. -These entries are essential for maintaining accurate financial records and ensuring that the organization's financial statements reflect the true cost of employee compensation. The Canadian Payroll Administration system automates the generation of these journal entries, reducing the risk of errors and ensuring compliance with accounting standards. \ No newline at end of file +These entries are essential for maintaining accurate financial records and ensuring that the organization's financial statements reflect the true cost of employee compensation. The Canadian Payroll Administration system automates the generation of these journal entries, reducing the risk of errors and ensuring compliance with accounting standards. +""""""""""""""""""""" + +| DR Payroll Expenses +| CR Payroll Payable \ No newline at end of file diff --git a/docs/build/html/_static/basic.css b/docs/build/html/_static/basic.css index 4738b2e..30fee9d 100644 --- a/docs/build/html/_static/basic.css +++ b/docs/build/html/_static/basic.css @@ -1,5 +1,12 @@ /* + * basic.css + * ~~~~~~~~~ + * * Sphinx stylesheet -- basic theme. + * + * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * */ /* -- main layout ----------------------------------------------------------- */ @@ -108,11 +115,15 @@ img { /* -- search page ----------------------------------------------------------- */ ul.search { - margin-top: 10px; + margin: 10px 0 0 20px; + padding: 0; } ul.search li { - padding: 5px 0; + padding: 5px 0 5px 20px; + background-image: url(file.png); + background-repeat: no-repeat; + background-position: 0 7px; } ul.search li a { @@ -741,6 +752,14 @@ abbr, acronym { cursor: help; } +.translated { + background-color: rgba(207, 255, 207, 0.2) +} + +.untranslated { + background-color: rgba(255, 207, 207, 0.2) +} + /* -- code displays --------------------------------------------------------- */ pre { diff --git a/docs/build/html/_static/classic.css b/docs/build/html/_static/classic.css index 8851cb7..9ad992b 100644 --- a/docs/build/html/_static/classic.css +++ b/docs/build/html/_static/classic.css @@ -1,5 +1,12 @@ /* + * classic.css_t + * ~~~~~~~~~~~~~ + * * Sphinx stylesheet -- classic theme. + * + * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * */ @import url("basic.css"); diff --git a/docs/build/html/_static/doctools.js b/docs/build/html/_static/doctools.js index 0398ebb..d06a71d 100644 --- a/docs/build/html/_static/doctools.js +++ b/docs/build/html/_static/doctools.js @@ -1,5 +1,12 @@ /* + * doctools.js + * ~~~~~~~~~~~ + * * Base JavaScript utilities for all Sphinx HTML documentation. + * + * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * */ "use strict"; diff --git a/docs/build/html/_static/language_data.js b/docs/build/html/_static/language_data.js index c7fe6c6..250f566 100644 --- a/docs/build/html/_static/language_data.js +++ b/docs/build/html/_static/language_data.js @@ -1,12 +1,19 @@ /* + * language_data.js + * ~~~~~~~~~~~~~~~~ + * * This script contains the language-specific data used by searchtools.js, * namely the list of stopwords, stemmer, scorer and splitter. + * + * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * */ 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"]; -/* Non-minified version is copied as a separate JS file, if available */ +/* Non-minified version is copied as a separate JS file, is available */ /** * Porter Stemmer diff --git a/docs/build/html/_static/pygments.css b/docs/build/html/_static/pygments.css index 5f2b0a2..0d49244 100644 --- a/docs/build/html/_static/pygments.css +++ b/docs/build/html/_static/pygments.css @@ -6,26 +6,26 @@ span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: .highlight .hll { background-color: #ffffcc } .highlight { background: #eeffcc; } .highlight .c { color: #408090; font-style: italic } /* Comment */ -.highlight .err { border: 1px solid #F00 } /* Error */ +.highlight .err { border: 1px solid #FF0000 } /* Error */ .highlight .k { color: #007020; font-weight: bold } /* Keyword */ -.highlight .o { color: #666 } /* Operator */ +.highlight .o { color: #666666 } /* Operator */ .highlight .ch { color: #408090; font-style: italic } /* Comment.Hashbang */ .highlight .cm { color: #408090; font-style: italic } /* Comment.Multiline */ .highlight .cp { color: #007020 } /* Comment.Preproc */ .highlight .cpf { color: #408090; font-style: italic } /* Comment.PreprocFile */ .highlight .c1 { color: #408090; font-style: italic } /* Comment.Single */ -.highlight .cs { color: #408090; background-color: #FFF0F0 } /* Comment.Special */ +.highlight .cs { color: #408090; background-color: #fff0f0 } /* Comment.Special */ .highlight .gd { color: #A00000 } /* Generic.Deleted */ .highlight .ge { font-style: italic } /* Generic.Emph */ .highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */ -.highlight .gr { color: #F00 } /* Generic.Error */ +.highlight .gr { color: #FF0000 } /* Generic.Error */ .highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ .highlight .gi { color: #00A000 } /* Generic.Inserted */ -.highlight .go { color: #333 } /* Generic.Output */ -.highlight .gp { color: #C65D09; font-weight: bold } /* Generic.Prompt */ +.highlight .go { color: #333333 } /* Generic.Output */ +.highlight .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */ .highlight .gs { font-weight: bold } /* Generic.Strong */ .highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ -.highlight .gt { color: #04D } /* Generic.Traceback */ +.highlight .gt { color: #0044DD } /* Generic.Traceback */ .highlight .kc { color: #007020; font-weight: bold } /* Keyword.Constant */ .highlight .kd { color: #007020; font-weight: bold } /* Keyword.Declaration */ .highlight .kn { color: #007020; font-weight: bold } /* Keyword.Namespace */ @@ -33,43 +33,43 @@ span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: .highlight .kr { color: #007020; font-weight: bold } /* Keyword.Reserved */ .highlight .kt { color: #902000 } /* Keyword.Type */ .highlight .m { color: #208050 } /* Literal.Number */ -.highlight .s { color: #4070A0 } /* Literal.String */ -.highlight .na { color: #4070A0 } /* Name.Attribute */ +.highlight .s { color: #4070a0 } /* Literal.String */ +.highlight .na { color: #4070a0 } /* Name.Attribute */ .highlight .nb { color: #007020 } /* Name.Builtin */ -.highlight .nc { color: #0E84B5; font-weight: bold } /* Name.Class */ -.highlight .no { color: #60ADD5 } /* Name.Constant */ -.highlight .nd { color: #555; font-weight: bold } /* Name.Decorator */ -.highlight .ni { color: #D55537; font-weight: bold } /* Name.Entity */ +.highlight .nc { color: #0e84b5; font-weight: bold } /* Name.Class */ +.highlight .no { color: #60add5 } /* Name.Constant */ +.highlight .nd { color: #555555; font-weight: bold } /* Name.Decorator */ +.highlight .ni { color: #d55537; font-weight: bold } /* Name.Entity */ .highlight .ne { color: #007020 } /* Name.Exception */ -.highlight .nf { color: #06287E } /* Name.Function */ +.highlight .nf { color: #06287e } /* Name.Function */ .highlight .nl { color: #002070; font-weight: bold } /* Name.Label */ -.highlight .nn { color: #0E84B5; font-weight: bold } /* Name.Namespace */ +.highlight .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */ .highlight .nt { color: #062873; font-weight: bold } /* Name.Tag */ -.highlight .nv { color: #BB60D5 } /* Name.Variable */ +.highlight .nv { color: #bb60d5 } /* Name.Variable */ .highlight .ow { color: #007020; font-weight: bold } /* Operator.Word */ -.highlight .w { color: #BBB } /* Text.Whitespace */ +.highlight .w { color: #bbbbbb } /* Text.Whitespace */ .highlight .mb { color: #208050 } /* Literal.Number.Bin */ .highlight .mf { color: #208050 } /* Literal.Number.Float */ .highlight .mh { color: #208050 } /* Literal.Number.Hex */ .highlight .mi { color: #208050 } /* Literal.Number.Integer */ .highlight .mo { color: #208050 } /* Literal.Number.Oct */ -.highlight .sa { color: #4070A0 } /* Literal.String.Affix */ -.highlight .sb { color: #4070A0 } /* Literal.String.Backtick */ -.highlight .sc { color: #4070A0 } /* Literal.String.Char */ -.highlight .dl { color: #4070A0 } /* Literal.String.Delimiter */ -.highlight .sd { color: #4070A0; font-style: italic } /* Literal.String.Doc */ -.highlight .s2 { color: #4070A0 } /* Literal.String.Double */ -.highlight .se { color: #4070A0; font-weight: bold } /* Literal.String.Escape */ -.highlight .sh { color: #4070A0 } /* Literal.String.Heredoc */ -.highlight .si { color: #70A0D0; font-style: italic } /* Literal.String.Interpol */ -.highlight .sx { color: #C65D09 } /* Literal.String.Other */ +.highlight .sa { color: #4070a0 } /* Literal.String.Affix */ +.highlight .sb { color: #4070a0 } /* Literal.String.Backtick */ +.highlight .sc { color: #4070a0 } /* Literal.String.Char */ +.highlight .dl { color: #4070a0 } /* Literal.String.Delimiter */ +.highlight .sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */ +.highlight .s2 { color: #4070a0 } /* Literal.String.Double */ +.highlight .se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */ +.highlight .sh { color: #4070a0 } /* Literal.String.Heredoc */ +.highlight .si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */ +.highlight .sx { color: #c65d09 } /* Literal.String.Other */ .highlight .sr { color: #235388 } /* Literal.String.Regex */ -.highlight .s1 { color: #4070A0 } /* Literal.String.Single */ +.highlight .s1 { color: #4070a0 } /* Literal.String.Single */ .highlight .ss { color: #517918 } /* Literal.String.Symbol */ .highlight .bp { color: #007020 } /* Name.Builtin.Pseudo */ -.highlight .fm { color: #06287E } /* Name.Function.Magic */ -.highlight .vc { color: #BB60D5 } /* Name.Variable.Class */ -.highlight .vg { color: #BB60D5 } /* Name.Variable.Global */ -.highlight .vi { color: #BB60D5 } /* Name.Variable.Instance */ -.highlight .vm { color: #BB60D5 } /* Name.Variable.Magic */ +.highlight .fm { color: #06287e } /* Name.Function.Magic */ +.highlight .vc { color: #bb60d5 } /* Name.Variable.Class */ +.highlight .vg { color: #bb60d5 } /* Name.Variable.Global */ +.highlight .vi { color: #bb60d5 } /* Name.Variable.Instance */ +.highlight .vm { color: #bb60d5 } /* Name.Variable.Magic */ .highlight .il { color: #208050 } /* Literal.Number.Integer.Long */ \ No newline at end of file diff --git a/docs/build/html/_static/searchtools.js b/docs/build/html/_static/searchtools.js index 91f4be5..09d6458 100644 --- a/docs/build/html/_static/searchtools.js +++ b/docs/build/html/_static/searchtools.js @@ -1,5 +1,12 @@ /* + * searchtools.js + * ~~~~~~~~~~~~~~~~ + * * Sphinx JavaScript utilities for the full-text search. + * + * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * */ "use strict"; @@ -13,7 +20,7 @@ if (typeof Scorer === "undefined") { // and returns the new score. /* score: result => { - const [docname, title, anchor, descr, score, filename, kind] = result + const [docname, title, anchor, descr, score, filename] = result return score }, */ @@ -40,14 +47,6 @@ if (typeof Scorer === "undefined") { }; } -// Global search result kind enum, used by themes to style search results. -class SearchResultKind { - 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); }; @@ -63,15 +62,12 @@ const _displayItem = (item, searchTerms, highlightTerms) => { const docFileSuffix = DOCUMENTATION_OPTIONS.FILE_SUFFIX; const docLinkSuffix = DOCUMENTATION_OPTIONS.LINK_SUFFIX; const showSearchSummary = DOCUMENTATION_OPTIONS.SHOW_SEARCH_SUMMARY; - const contentRoot = document.documentElement.dataset.content_root; + const contentRoot = document.documentElement.dataset.content_root + ?? DOCUMENTATION_OPTIONS.URL_ROOT; - const [docName, title, anchor, descr, score, _filename, kind] = item; + const [docName, title, anchor, descr, score, _filename] = 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 SearchResultKind for the class names. - listItem.classList.add(`kind-${kind}`); let requestUrl; let linkUrl; if (docBuilder === "dirhtml") { @@ -104,7 +100,7 @@ const _displayItem = (item, searchTerms, highlightTerms) => { .then((data) => { if (data) listItem.appendChild( - Search.makeSearchSummary(data, searchTerms, anchor) + Search.makeSearchSummary(data, searchTerms) ); // highlight search terms in the summary if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js @@ -120,11 +116,9 @@ const _finishSearch = (resultCount) => { "Your search did not match any documents. Please make sure that all words are spelled correctly and that you've selected enough categories." ); else - Search.status.innerText = Documentation.ngettext( - "Search finished, found one page matching the search query.", - "Search finished, found ${resultCount} pages matching the search query.", - resultCount, - ).replace('${resultCount}', resultCount); + Search.status.innerText = _( + `Search finished, found ${resultCount} page(s) matching the search query.` + ); }; const _displayNextItem = ( results, @@ -144,22 +138,6 @@ const _displayNextItem = ( // search finished, update title and status message else _finishSearch(resultCount); }; -// Helper function used by query() to order search results. -// Each input is an array of [docname, title, anchor, descr, score, filename, kind]. -// 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) => { - const leftScore = a[4]; - const rightScore = b[4]; - if (leftScore === rightScore) { - // same score: sort alphabetically - const leftTitle = a[1].toLowerCase(); - const rightTitle = b[1].toLowerCase(); - if (leftTitle === rightTitle) return 0; - return leftTitle > rightTitle ? -1 : 1; // inverted is intentional - } - return leftScore > rightScore ? 1 : -1; -}; /** * Default splitQuery function. Can be overridden in ``sphinx.search`` with a @@ -183,26 +161,13 @@ const Search = { _queued_query: null, _pulse_status: -1, - htmlToText: (htmlString, anchor) => { + htmlToText: (htmlString) => { const htmlElement = new DOMParser().parseFromString(htmlString, 'text/html'); - for (const removalQuery of [".headerlink", "script", "style"]) { - htmlElement.querySelectorAll(removalQuery).forEach((el) => { el.remove() }); - } - if (anchor) { - const anchorContent = htmlElement.querySelector(`[role="main"] ${anchor}`); - if (anchorContent) return anchorContent.textContent; - - console.warn( - `Anchored content block not found. Sphinx search tries to obtain it via DOM query '[role=main] ${anchor}'. Check your theme or template.` - ); - } - - // if anchor not specified or not found, fall back to main content + htmlElement.querySelectorAll(".headerlink").forEach((el) => { el.remove() }); const docContent = htmlElement.querySelector('[role="main"]'); - if (docContent) return docContent.textContent; - + if (docContent !== undefined) return docContent.textContent; console.warn( - "Content block not found. Sphinx search tries to obtain it via DOM query '[role=main]'. Check your theme or template." + "Content block not found. Sphinx search tries to obtain it via '[role=main]'. Could you check your theme or template." ); return ""; }, @@ -255,7 +220,6 @@ 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"); @@ -276,7 +240,16 @@ const Search = { else Search.deferQuery(query); }, - _parseQuery: (query) => { + /** + * execute search (requires search index to be loaded) + */ + query: (query) => { + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const titles = Search._index.titles; + const allTitles = Search._index.alltitles; + const indexEntries = Search._index.indexentries; + // stem the search terms and add them to the correct list const stemmer = new Stemmer(); const searchTerms = new Set(); @@ -312,40 +285,22 @@ const Search = { // console.info("required: ", [...searchTerms]); // console.info("excluded: ", [...excludedTerms]); - return [query, searchTerms, excludedTerms, highlightTerms, objectTerms]; - }, - - /** - * execute search (requires search index to be loaded) - */ - _performSearch: (query, searchTerms, excludedTerms, highlightTerms, objectTerms) => { - const filenames = Search._index.filenames; - const docNames = Search._index.docnames; - const titles = Search._index.titles; - const allTitles = Search._index.alltitles; - 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, kind]. - const normalResults = []; - const nonMainIndexResults = []; - + // array of [docname, title, anchor, descr, score, filename] + let results = []; _removeChildren(document.getElementById("search-progress")); - const queryLower = query.toLowerCase().trim(); + const queryLower = query.toLowerCase(); for (const [title, foundTitles] of Object.entries(allTitles)) { - if (title.toLowerCase().trim().includes(queryLower) && (queryLower.length >= title.length/2)) { + if (title.toLowerCase().includes(queryLower) && (queryLower.length >= title.length/2)) { for (const [file, id] of foundTitles) { - const score = Math.round(Scorer.title * queryLower.length / title.length); - const boost = titles[file] === title ? 1 : 0; // add a boost for document titles - normalResults.push([ + let score = Math.round(100 * queryLower.length / title.length) + results.push([ docNames[file], titles[file] !== title ? `${titles[file]} > ${title}` : title, id !== null ? "#" + id : "", null, - score + boost, + score, filenames[file], - SearchResultKind.title, ]); } } @@ -354,48 +309,46 @@ const Search = { // search for explicit entries in index directives for (const [entry, foundEntries] of Object.entries(indexEntries)) { if (entry.includes(queryLower) && (queryLower.length >= entry.length/2)) { - for (const [file, id, isMain] of foundEntries) { - const score = Math.round(100 * queryLower.length / entry.length); - const result = [ + for (const [file, id] of foundEntries) { + let score = Math.round(100 * queryLower.length / entry.length) + results.push([ docNames[file], titles[file], id ? "#" + id : "", null, score, filenames[file], - SearchResultKind.index, - ]; - if (isMain) { - normalResults.push(result); - } else { - nonMainIndexResults.push(result); - } + ]); } } } // lookup as object objectTerms.forEach((term) => - normalResults.push(...Search.performObjectSearch(term, objectTerms)) + results.push(...Search.performObjectSearch(term, objectTerms)) ); // lookup as search terms in fulltext - normalResults.push(...Search.performTermsSearch(searchTerms, excludedTerms)); + results.push(...Search.performTermsSearch(searchTerms, excludedTerms)); // let the scorer override scores with a custom scoring function - if (Scorer.score) { - normalResults.forEach((item) => (item[4] = Scorer.score(item))); - nonMainIndexResults.forEach((item) => (item[4] = Scorer.score(item))); - } + if (Scorer.score) results.forEach((item) => (item[4] = Scorer.score(item))); - // Sort each group of results by score and then alphabetically by name. - normalResults.sort(_orderResultsByScoreThenName); - nonMainIndexResults.sort(_orderResultsByScoreThenName); - - // Combine the result groups in (reverse) order. - // Non-main index entries are typically arbitrary cross-references, - // so display them after other results. - let results = [...nonMainIndexResults, ...normalResults]; + // now sort the results by score (in opposite order of appearance, since the + // display function below uses pop() to retrieve items) and then + // alphabetically + results.sort((a, b) => { + const leftScore = a[4]; + const rightScore = b[4]; + if (leftScore === rightScore) { + // same score: sort alphabetically + const leftTitle = a[1].toLowerCase(); + const rightTitle = b[1].toLowerCase(); + if (leftTitle === rightTitle) return 0; + return leftTitle > rightTitle ? -1 : 1; // inverted is intentional + } + return leftScore > rightScore ? 1 : -1; + }); // remove duplicate search results // note the reversing of results, so that in the case of duplicates, the highest-scoring entry is kept @@ -409,12 +362,7 @@ const Search = { return acc; }, []); - return results.reverse(); - }, - - query: (query) => { - const [searchQuery, searchTerms, excludedTerms, highlightTerms, objectTerms] = Search._parseQuery(query); - const results = Search._performSearch(searchQuery, searchTerms, excludedTerms, highlightTerms, objectTerms); + results = results.reverse(); // for debugging //Search.lastresults = results.slice(); // a copy @@ -485,14 +433,16 @@ const Search = { descr, score, filenames[match[0]], - SearchResultKind.object, ]); }; - Object.keys(objects).forEach((prefix) => + Object.keys(objects).forEach((prefix) => { + if (!(objects[prefix] instanceof Array)) { + objects[prefix] = Object.entries(objects[prefix]).map(([name, match]) => [...match, name]); + } objects[prefix].forEach((array) => objectSearchCallback(prefix, array) - ) - ); + ); + }); return results; }, @@ -513,27 +463,21 @@ const Search = { // perform the search on the required terms searchTerms.forEach((word) => { const files = []; - // find documents, if any, containing the query word in their text/title term indices - // use Object.hasOwnProperty to avoid mismatching against prototype properties const arr = [ - { files: terms.hasOwnProperty(word) ? terms[word] : undefined, score: Scorer.term }, - { files: titleTerms.hasOwnProperty(word) ? titleTerms[word] : undefined, score: Scorer.title }, + { files: terms[word], score: Scorer.term }, + { files: titleTerms[word], score: Scorer.title }, ]; // add support for partial matches if (word.length > 2) { const escapedWord = _escapeRegExp(word); - if (!terms.hasOwnProperty(word)) { - Object.keys(terms).forEach((term) => { - if (term.match(escapedWord)) - arr.push({ files: terms[term], score: Scorer.partialTerm }); - }); - } - if (!titleTerms.hasOwnProperty(word)) { - Object.keys(titleTerms).forEach((term) => { - if (term.match(escapedWord)) - arr.push({ files: titleTerms[term], score: Scorer.partialTitle }); - }); - } + Object.keys(terms).forEach((term) => { + if (term.match(escapedWord) && !terms[word]) + arr.push({ files: terms[term], score: Scorer.partialTerm }); + }); + Object.keys(titleTerms).forEach((term) => { + if (term.match(escapedWord) && !titleTerms[word]) + arr.push({ files: titleTerms[word], score: Scorer.partialTitle }); + }); } // no match but word was a required one @@ -549,16 +493,16 @@ const Search = { // set score for the word in each file recordFiles.forEach((file) => { - if (!scoreMap.has(file)) scoreMap.set(file, new Map()); - const fileScores = scoreMap.get(file); - fileScores.set(word, record.score); + if (!scoreMap.has(file)) scoreMap.set(file, {}); + scoreMap.get(file)[word] = record.score; }); }); // create the mapping files.forEach((file) => { - if (!fileMap.has(file)) fileMap.set(file, [word]); - else if (fileMap.get(file).indexOf(word) === -1) fileMap.get(file).push(word); + if (fileMap.has(file) && fileMap.get(file).indexOf(word) === -1) + fileMap.get(file).push(word); + else fileMap.set(file, [word]); }); }); @@ -590,7 +534,7 @@ const Search = { break; // select one (max) score for the file. - const score = Math.max(...wordList.map((w) => scoreMap.get(file).get(w))); + const score = Math.max(...wordList.map((w) => scoreMap.get(file)[w])); // add result to the result list results.push([ docNames[file], @@ -599,7 +543,6 @@ const Search = { null, score, filenames[file], - SearchResultKind.text, ]); } return results; @@ -610,8 +553,8 @@ const Search = { * search summary for a given text. keywords is a list * of stemmed words. */ - makeSearchSummary: (htmlText, keywords, anchor) => { - const text = Search.htmlToText(htmlText, anchor); + makeSearchSummary: (htmlText, keywords) => { + const text = Search.htmlToText(htmlText); if (text === "") return null; const textLower = text.toLowerCase(); diff --git a/docs/build/html/_static/sidebar.js b/docs/build/html/_static/sidebar.js index ac7b39e..c5e2692 100644 --- a/docs/build/html/_static/sidebar.js +++ b/docs/build/html/_static/sidebar.js @@ -1,4 +1,7 @@ /* + * sidebar.js + * ~~~~~~~~~~ + * * This script makes the Sphinx sidebar collapsible. * * .sphinxsidebar contains .sphinxsidebarwrapper. This script adds @@ -13,6 +16,9 @@ * Once the browser is closed the cookie is deleted and the position * reset to the default (expanded). * + * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * */ const initialiseSidebar = () => { diff --git a/docs/build/html/errata.html b/docs/build/html/errata.html index df62df8..01a7914 100644 --- a/docs/build/html/errata.html +++ b/docs/build/html/errata.html @@ -6,18 +6,18 @@ 3. Errors and Errata — Canadian Payroll Administration HR documentation - - + + - + - - - - - - - - - - - - - - -