├── .backstage ├── changelog.cjs ├── create_package.cjs ├── get_tag.cjs ├── set_version.cjs ├── version.cjs └── version_main_package.cjs ├── .cargo └── config.toml ├── .cloudcannon ├── postbuild └── prebuild ├── .github ├── dependabot.yml └── workflows │ ├── dependabot.yml │ ├── release.yml │ └── test.yml ├── .gitignore ├── .shellcheckrc ├── .vscode └── settings.json ├── CHANGELOG.md ├── CONTRIBUTING.md ├── Cargo.lock ├── Cargo.toml ├── LICENSE ├── README.md ├── SECURITY.md ├── docs ├── assets │ └── css │ │ └── extras.scss ├── content │ ├── _index.md │ └── docs │ │ ├── _index.md │ │ ├── api-reference.md │ │ ├── api.md │ │ ├── config-options.md │ │ ├── config-sources.md │ │ ├── default-ui-filtering.md │ │ ├── default-ui-metadata.md │ │ ├── filtering.md │ │ ├── highlight-config.md │ │ ├── highlighting.md │ │ ├── hosting.md │ │ ├── implementation-service.md │ │ ├── indexing.md │ │ ├── installation.md │ │ ├── js-api-filtering.md │ │ ├── js-api-metadata.md │ │ ├── js-api-sorting.md │ │ ├── metadata.md │ │ ├── multilingual.md │ │ ├── multisite.md │ │ ├── node-api.md │ │ ├── playground.md │ │ ├── py-api.md │ │ ├── ranking.md │ │ ├── resources.md │ │ ├── running-pagefind.md │ │ ├── search-config.md │ │ ├── sorts.md │ │ ├── sub-results.md │ │ ├── ui-usage.md │ │ ├── ui.md │ │ ├── v1-migration.md │ │ └── weighting.md ├── data │ ├── banner.yml │ ├── footer.yml │ ├── meta.yml │ ├── nav.yml │ └── theme.yml ├── go.mod ├── go.sum ├── hugo.toml ├── layouts │ ├── partials │ │ ├── docnav-list.html │ │ ├── docnav.html │ │ └── extra_head.html │ └── shortcodes │ │ ├── card.html │ │ ├── how_to.html │ │ └── resource.html ├── package-lock.json ├── package.json └── static │ ├── bell.svg │ ├── cloudcannon.svg │ ├── github.svg │ ├── godot.svg │ ├── mdn.svg │ ├── meta │ ├── android-chrome-192x192.png │ ├── android-chrome-256x256.png │ ├── apple-touch-icon.png │ ├── browserconfig.xml │ ├── favicon-16x16.png │ ├── favicon-32x32.png │ ├── favicon.ico │ ├── mstile-150x150.png │ ├── safari-pinned-tab.svg │ └── site.webmanifest │ ├── og.png │ ├── pagefind-dark.svg │ ├── pagefind.svg │ └── xkcd.png ├── pagefind ├── Cargo.toml ├── integration_tests │ ├── _macros │ │ ├── node.toolproof.macro.yml │ │ ├── python.toolproof.macro.yml │ │ ├── run.toolproof.macro.yml │ │ ├── run_failing.toolproof.macro.yml │ │ ├── run_failing_with_flags.toolproof.macro.yml │ │ └── run_with_flags.toolproof.macro.yml │ ├── anchors │ │ ├── background.toolproof.yml │ │ ├── pagefind-extracts-page-anchor-text-where-it-makes-sense.toolproof.yml │ │ ├── pagefind-respects-data-pagefind-ignore-inside-anchors.toolproof.yml │ │ ├── pagefind-returns-all-page-anchors-in-the-fragment.toolproof.yml │ │ ├── pagefind-returns-all-word-locations-in-the-fragment.toolproof.yml │ │ ├── pagefind-returns-full-content-without-anchors.toolproof.yml │ │ ├── pagefind-returns-page-anchor-content-in-the-fragment.toolproof.yml │ │ └── pagefind-returns-subresults-based-on-headings.toolproof.yml │ ├── anchors_example │ │ ├── background.toolproof.yml │ │ └── pagefind-returns-subresults-for-an-example-page.toolproof.yml │ ├── base │ │ ├── background.toolproof.yml │ │ ├── preload-indexes-then-search-for-a-word.toolproof.yml │ │ ├── return-all-results.toolproof.yml │ │ ├── search-for-a-word.toolproof.yml │ │ └── stable-output.toolproof.yml │ ├── build_options │ │ ├── background.toolproof.yml │ │ ├── complex-exclusionary-file-glob-can-be-configured.toolproof.yml │ │ ├── file-glob-can-be-configured.toolproof.yml │ │ ├── output-path-can-be-configured-relative-to-cwd.toolproof.yml │ │ ├── output-path-can-be-configured-with-an-absolute-path.toolproof.yml │ │ ├── output-path-can-be-configured.toolproof.yml │ │ ├── root-selector-can-be-configured.toolproof.yml │ │ └── source-folder-can-be-configured.toolproof.yml │ ├── characters │ │ ├── background.toolproof.yml │ │ ├── pagefind-can-search-for-a-hyphenated-phrase.toolproof.yml │ │ ├── pagefind-does-not-return-results-for-queries-that-normalize-to-nothing.toolproof.yml │ │ ├── pagefind-doesn-t-match-html-entities-as-their-text.toolproof.yml │ │ ├── pagefind-handles-html-entities-in-inline-meta.toolproof.yml │ │ ├── pagefind-handles-html-entities-in-meta.toolproof.yml │ │ ├── pagefind-matches-custom-characters.toolproof.yml │ │ ├── pagefind-matches-emoji.toolproof.yml │ │ ├── pagefind-matches-special-characters.toolproof.yml │ │ └── punctuated-compound-words-are-indexed-per-word.toolproof.yml │ ├── compound_filtering │ │ ├── background.toolproof.yml │ │ ├── filtering-to-a-complex-nested-filter.toolproof.yml │ │ ├── filtering-to-any-of-a-set-of-values-and-another-filter.toolproof.yml │ │ ├── filtering-to-any-of-a-set-of-values-or-another-filter.toolproof.yml │ │ ├── filtering-to-any-of-a-single-filter.toolproof.yml │ │ ├── filtering-with-an-exclusion.toolproof.yml │ │ ├── filtering-with-nested-exclusions.toolproof.yml │ │ └── filtering-with-top-level-exclusion.toolproof.yml │ ├── config_sources │ │ ├── settings-can-be-pulled-from-command-line-flags.toolproof.yml │ │ ├── settings-can-be-pulled-from-environment-variables.toolproof.yml │ │ ├── settings-can-be-pulled-from-json-configuration-files.toolproof.yml │ │ ├── settings-can-be-pulled-from-multiple-sources.toolproof.yml │ │ ├── settings-can-be-pulled-from-toml-configuration-files.toolproof.yml │ │ └── settings-can-be-pulled-from-yaml-configuration-files.toolproof.yml │ ├── debounce │ │ ├── background.toolproof.yml │ │ ├── debounce-repeated-search-calls.toolproof.yml │ │ └── debounce-with-options.toolproof.yml │ ├── edge_cases │ │ ├── anchors-do-not-leak-through-metadata.toolproof.yml │ │ ├── background.toolproof.yml │ │ ├── pagefind-doesn-t-error-on-parsing-ambiguities.toolproof.yml │ │ ├── pagefind-finds-a-data-pagefind-body-when-elements-sit-outside-of-the-main-html-element.toolproof.yml │ │ ├── pagefind-handles-non-breaking-spaces-in-segmented-language-pages.toolproof.yml │ │ └── pagefind-multilingual-sub-results.toolproof.yml │ ├── exact_phrase │ │ ├── background.toolproof.yml │ │ ├── exact-matches-will-be-discouraged-across-element-boundaries.toolproof.yml │ │ └── searching-in-quotes-will-return-pages-with-exact-matches.toolproof.yml │ ├── exclusions │ │ ├── background.toolproof.yml │ │ ├── custom-selectors-can-be-excluded-as-an-option.toolproof.yml │ │ ├── elements-within-search-regions-can-be-excluded-from-indexing-and-excerpts.toolproof.yml │ │ ├── some-elements-are-excluded-automatically.toolproof.yml │ │ └── tagged-elements-inside-ignored-elements-can-be-ignored.toolproof.yml │ ├── filtering │ │ ├── all-results-are-returned-with-no-filters.toolproof.yml │ │ ├── background.toolproof.yml │ │ ├── filter-counts-are-returned-for-a-given-search-term.toolproof.yml │ │ ├── filtering-on-a-search-term-with-no-results-returns-nothing.toolproof.yml │ │ ├── filtering-on-tagged-elements.toolproof.yml │ │ ├── filtering-on-tagged-values.toolproof.yml │ │ ├── filtering-returns-multiple-results.toolproof.yml │ │ ├── filtering-with-an--empty--bogus-filter-does-nothing.toolproof.yml │ │ ├── filtering-with-an-empty-array-returns-all-results.toolproof.yml │ │ ├── filtering-without-search-term-returns-an-unprocessed-excerpt.toolproof.yml │ │ ├── filtering-without-search-term-returns-only-filter.toolproof.yml │ │ ├── filters-can-be-retrieved.toolproof.yml │ │ ├── non-existent-filters-return-no-results.toolproof.yml │ │ ├── non-existent-values-return-no-results.toolproof.yml │ │ ├── total-filter-counts-are-returned-for-a-given-search-term.toolproof.yml │ │ └── total-unfiltered-result-counts-are-given-for-a-filtered-search-term.toolproof.yml │ ├── frozen-pre-1.0 │ │ ├── base │ │ │ ├── background.toolproof.yml │ │ │ ├── legacy-preload-indexes-then-search-for-a-word.toolproof.yml │ │ │ └── legacy-search-for-a-word.toolproof.yml │ │ ├── build_options │ │ │ ├── background.toolproof.yml │ │ │ ├── legacy-complex-exclusionary-file-glob-can-be-configured.toolproof.yml │ │ │ ├── legacy-file-glob-can-be-configured.toolproof.yml │ │ │ ├── legacy-output-path-can-be-configured-with-an-absolute-path.toolproof.yml │ │ │ ├── legacy-output-path-can-be-configured.toolproof.yml │ │ │ ├── legacy-root-selector-can-be-configured.toolproof.yml │ │ │ └── legacy-source-folder-can-be-configured.toolproof.yml │ │ ├── config_sources │ │ │ ├── legacy-settings-can-be-pulled-from-command-line-flags.toolproof.yml │ │ │ ├── legacy-settings-can-be-pulled-from-environment-variables.toolproof.yml │ │ │ ├── legacy-settings-can-be-pulled-from-json-configuration-files.toolproof.yml │ │ │ ├── legacy-settings-can-be-pulled-from-multiple-sources.toolproof.yml │ │ │ ├── legacy-settings-can-be-pulled-from-toml-configuration-files.toolproof.yml │ │ │ └── legacy-settings-can-be-pulled-from-yaml-configuration-files.toolproof.yml │ │ ├── modular_ui │ │ │ └── modular_ui_base │ │ │ │ ├── background.toolproof.yml │ │ │ │ ├── legacy-pagefind-modular-ui-loads.toolproof.yml │ │ │ │ └── legacy-pagefind-modular-ui-searches.toolproof.yml │ │ ├── multilingual │ │ │ ├── background.toolproof.yml │ │ │ ├── legacy-pagefind-can-be-configured-to-lump-all-languages-together.toolproof.yml │ │ │ ├── legacy-pagefind-keeps-dialects-separate.toolproof.yml │ │ │ ├── legacy-pagefind-merges-omitted-languages-into-the-primary-language.toolproof.yml │ │ │ ├── legacy-pagefind-searches-for-english-with-english-stemming.toolproof.yml │ │ │ ├── legacy-pagefind-searches-for-portuguese-with-portuguese-stemming.toolproof.yml │ │ │ └── legacy-pagefind-searches-for-unknown-languages-with-no-stemming.toolproof.yml │ │ ├── multisite │ │ │ └── multisite_base │ │ │ │ ├── background.toolproof.yml │ │ │ │ ├── legacy-pagefind-can-search-across-multiple-sites.toolproof.yml │ │ │ │ └── legacy-pagefind-ui-can-search-across-multiple-sites.toolproof.yml │ │ ├── sanity │ │ │ ├── legacy-cli-tests-are-working.toolproof.yml │ │ │ └── legacy-web-tests-are-working.toolproof.yml │ │ ├── search_options │ │ │ ├── background.toolproof.yml │ │ │ ├── legacy-base-url-auto-detects-the-default-directory-being-moved.toolproof.yml │ │ │ ├── legacy-base-url-can-be-configured.toolproof.yml │ │ │ └── legacy-keep-index-url-can-be-configured.toolproof.yml │ │ └── ui │ │ │ └── ui_base │ │ │ ├── background.toolproof.yml │ │ │ ├── legacy-pagefind-ui-loads.toolproof.yml │ │ │ └── legacy-pagefind-ui-searches.toolproof.yml │ ├── highlighting │ │ ├── highlighting_results │ │ │ ├── background.toolproof.yml │ │ │ ├── highlight-script-is-loaded.toolproof.yml │ │ │ ├── highlight-script-marks-correctly.toolproof.yml │ │ │ ├── highlight-script-options-work.toolproof.yml │ │ │ └── highlight-script-stays-within-pagefind-body.toolproof.yml │ │ └── highlighting_search │ │ │ ├── background.toolproof.yml │ │ │ ├── multiple-query-parameters-are-inserted-through-the-js-api.toolproof.yml │ │ │ ├── query-parameters-can-be-inserted-through-the-js-api.toolproof.yml │ │ │ └── query-parameters-don-t-conflict-with-subresult-anchors.toolproof.yml │ ├── index_chunking │ │ ├── background.toolproof.yml │ │ └── searches-that-don-t-match-a-chunk-will-load-the-closest-chunk.toolproof.yml │ ├── indexing │ │ ├── background.toolproof.yml │ │ ├── html-attributes-can-be-indexed.toolproof.yml │ │ └── indexing-can-be-limited-to-a-given-element.toolproof.yml │ ├── input_quirks │ │ ├── background.toolproof.yml │ │ └── index-gzipped-input-files.toolproof.yml │ ├── log_levels │ │ ├── error_logs.toolproof.yml │ │ └── success_logs.toolproof.yml │ ├── metadata │ │ ├── background.toolproof.yml │ │ ├── default-metadata-can-be-defined.toolproof.yml │ │ ├── search-results-return-complex-metadata.toolproof.yml │ │ ├── search-results-return-generic-information-about-the-page.toolproof.yml │ │ ├── search-results-return-highlighted-search-excerpt.toolproof.yml │ │ ├── search-results-return-nicely-formatted-content.toolproof.yml │ │ ├── search-results-return-tagged-filters.toolproof.yml │ │ ├── search-results-return-tagged-metadata.toolproof.yml │ │ └── title-metadata-falls-back-to-the-title-element.toolproof.yml │ ├── modular_ui │ │ └── modular_ui_base │ │ │ ├── background.toolproof.yml │ │ │ ├── pagefind-modular-ui-loads.toolproof.yml │ │ │ └── pagefind-modular-ui-searches.toolproof.yml │ ├── multilingual │ │ ├── background.toolproof.yml │ │ ├── pagefind-can-be-configured-to-lump-all-languages-together.toolproof.yml │ │ ├── pagefind-can-be-destroyed-and-re-initialized.toolproof.yml │ │ ├── pagefind-keeps-dialects-separate.toolproof.yml │ │ ├── pagefind-merges-omitted-languages-into-the-primary-language.toolproof.yml │ │ ├── pagefind-searches-for-english-with-english-stemming.toolproof.yml │ │ ├── pagefind-searches-for-portuguese-with-portuguese-stemming.toolproof.yml │ │ └── pagefind-searches-for-unknown-languages-with-no-stemming.toolproof.yml │ ├── multisite │ │ ├── multisite_base │ │ │ ├── background.toolproof.yml │ │ │ ├── pagefind-can-search-across-discrete-domains.toolproof.yml │ │ │ ├── pagefind-can-search-across-multiple-basic-sites.toolproof.yml │ │ │ ├── pagefind-ui-can-search-across-discrete-domains.toolproof.yml │ │ │ └── pagefind-ui-can-search-across-multiple-sites.toolproof.yml │ │ ├── multisite_filters │ │ │ ├── background.toolproof.yml │ │ │ ├── pagefind-can-search-across-multiple-sites-with-common-filters.toolproof.yml │ │ │ ├── pagefind-can-search-across-multiple-sites-with-synthetic-filters.toolproof.yml │ │ │ └── pagefind-can-search-across-multiple-sites-with-unique-filters.toolproof.yml │ │ ├── multisite_lang │ │ │ ├── background.toolproof.yml │ │ │ ├── language-of-merged-indexes-can-be-selected.toolproof.yml │ │ │ └── pagefind-picks-the-same-language-across-multiple-sites.toolproof.yml │ │ └── multisite_sort │ │ │ ├── background.toolproof.yml │ │ │ ├── multiple-indexes-can-be-weighted-separately.toolproof.yml │ │ │ └── pages-are-scored-correctly-across-indexes.toolproof.yml │ ├── node_api │ │ └── node_base │ │ │ ├── an-index-is-not-consumed-on-write.toolproof.yml │ │ │ ├── background.toolproof.yml │ │ │ ├── build-a-blended-index-to-memory-via-the-api.toolproof.yml │ │ │ ├── build-a-synthetic-index-to-disk-via-the-api.toolproof.yml │ │ │ ├── build-a-synthetic-index-to-memory-via-the-api.toolproof.yml │ │ │ ├── build-a-synthetic-index-with-overridden-urls-to-disk-via-the-api.toolproof.yml │ │ │ ├── build-a-true-index-to-disk-via-the-api.toolproof.yml │ │ │ ├── build-an-index-to-a-custom-disk-location-via-the-api.toolproof.yml │ │ │ ├── close-the-pagefind-backend.toolproof.yml │ │ │ ├── force-language-takes-precedence-over-records.toolproof.yml │ │ │ ├── pagefind-empty-index-returns-assets.toolproof.yml │ │ │ ├── pagefind-error-handling.toolproof.yml │ │ │ ├── pagefind-playground-via-api.toolproof.yml │ │ │ └── pagefind-service-config.toolproof.yml │ ├── partial_matching │ │ ├── background.toolproof.yml │ │ └── search-will-return-pages-that-match---out-of---words.toolproof.yml │ ├── playground │ │ └── pagefind-ui-can-programmatically-filter.toolproof.yml │ ├── python_api │ │ ├── background.toolproof.yml │ │ ├── py-an-index-is-not-consumed-on-write.toolproof.yml │ │ ├── py-build-a-blended-index-to-memory-via-the-api.toolproof.yml │ │ ├── py-build-a-synthetic-index-to-disk-via-the-api.toolproof.yml │ │ ├── py-build-a-synthetic-index-to-memory-via-the-api.toolproof.yml │ │ ├── py-build-a-synthetic-index-with-overridden-urls-to-disk-via-the-api.toolproof.yml │ │ ├── py-build-a-true-index-to-disk-via-the-api.toolproof.yml │ │ ├── py-build-an-index-to-a-custom-disk-location-via-the-api.toolproof.yml │ │ ├── py-close-the-pagefind-backend.toolproof.yml │ │ ├── py-force-language-takes-precedence-over-records.toolproof.yml │ │ ├── py-pagefind-empty-index-returns-assets.toolproof.yml │ │ ├── py-pagefind-error-handling.toolproof.yml │ │ ├── py-pagefind-playground-via-api.toolproof.yml │ │ └── py-pagefind-service-config.toolproof.yml │ ├── sanity │ │ ├── cli-tests-are-working.toolproof.yml │ │ └── web-tests-are-working.toolproof.yml │ ├── scoring_custom │ │ ├── background.toolproof.yml │ │ ├── page-length-ranking-can-be-configured.toolproof.yml │ │ ├── term-frequency-vs-raw-count-can-be-configured.toolproof.yml │ │ ├── term-saturation-can-be-configured.toolproof.yml │ │ └── term-similarity-ranking-can-be-configured.toolproof.yml │ ├── scoring_defaults │ │ ├── background.toolproof.yml │ │ ├── search-results-are-ranked-by-word-frequency.toolproof.yml │ │ └── search-terms-in-close-proximity-rank-higher-in-results.toolproof.yml │ ├── search_options │ │ ├── background.toolproof.yml │ │ ├── base-url-auto-detects-the-default-directory-being-moved.toolproof.yml │ │ ├── base-url-can-be-configured.toolproof.yml │ │ └── keep-index-url-can-be-configured.toolproof.yml │ ├── sentences │ │ ├── background.toolproof.yml │ │ ├── pagefind-doesn-t-join-inline-elements-as-sentences.toolproof.yml │ │ ├── pagefind-ignores-redundant-zero-width-spaces.toolproof.yml │ │ ├── pagefind-joins-block-elements-as-sentences.toolproof.yml │ │ └── pagefind-treats-br-tags-as-spaces.toolproof.yml │ ├── sorting │ │ ├── background.toolproof.yml │ │ ├── pagefind-can-sort-results-by-an-alphabetical-attribute.toolproof.yml │ │ ├── pagefind-can-sort-results-by-an-automatically-detected-float.toolproof.yml │ │ ├── pagefind-can-sort-results-by-an-automatically-detected-integer.toolproof.yml │ │ ├── pagefind-can-sort-results-by-mixed-floats-and-integers.toolproof.yml │ │ └── pagefind-excludes-pages-that-aren-t-tagged-with-the-provided-sort-option.toolproof.yml │ ├── stemming │ │ ├── background.toolproof.yml │ │ ├── search-is-case-independent.toolproof.yml │ │ ├── search-is-punctuation-independent.toolproof.yml │ │ ├── searching-for-a-word-will-match-against-the-stem-of-that-word.toolproof.yml │ │ ├── searching-will-backtrack-a-word-to-find-a-prefix.toolproof.yml │ │ └── searching-will-backtrack-a-word-to-find-a-stem.toolproof.yml │ ├── suggestions │ │ ├── background.toolproof.yml │ │ ├── search-results-will-be-returned-for-all-extensions-of-the-word.toolproof.yml │ │ └── spelling-correction-can-be-returned-for-the-unique-words-in-the-dataset.toolproof.yml │ ├── ui │ │ ├── ui_base │ │ │ ├── background.toolproof.yml │ │ │ ├── pagefind-ui-can-programmatically-filter.toolproof.yml │ │ │ ├── pagefind-ui-loads.toolproof.yml │ │ │ └── pagefind-ui-searches.toolproof.yml │ │ ├── ui_highlight │ │ │ ├── background.toolproof.yml │ │ │ ├── pagefind-ui-adds-highlight-query-params.toolproof.yml │ │ │ ├── pagefind-ui-does-not-add-highlight-query-params-by-default.toolproof.yml │ │ │ └── pagefind-ui-uses-custom-highlight-query-param-name.toolproof.yml │ │ ├── ui_hooks │ │ │ ├── background.toolproof.yml │ │ │ ├── pagefind-ui-can-provide-a-hook-to-process-results.toolproof.yml │ │ │ └── pagefind-ui-can-provide-a-hook-to-process-search-terms.toolproof.yml │ │ ├── ui_scoring │ │ │ ├── background.toolproof.yml │ │ │ └── pagefind-ui-can-customize-scoring.toolproof.yml │ │ └── ui_strings │ │ │ ├── background.toolproof.yml │ │ │ ├── pagefind-ui-can-load-custom-translations.toolproof.yml │ │ │ └── pagefind-ui-loads-automatic-translations.toolproof.yml │ ├── urls │ │ ├── background.toolproof.yml │ │ └── tag-pages-as-external-urls.toolproof.yml │ └── weighting │ │ ├── background.toolproof.yml │ │ ├── compound-words-are-implicitly-weighted-lower.toolproof.yml │ │ ├── compound-words-matched-as-full-words-use-the-full-weight.toolproof.yml │ │ ├── compound-words-prefixes-prioritise-the-lower-weight.toolproof.yml │ │ ├── compound-words-sum-to-a-full-weight.toolproof.yml │ │ ├── headings-are-automatically-favoured-over-standard-text.toolproof.yml │ │ ├── text-can-be-explicitly-weighted-higher.toolproof.yml │ │ ├── text-can-be-explicitly-weighted-lower.toolproof.yml │ │ └── zero-weighted-compound-words-have-zero-score.toolproof.yml └── src │ ├── fossick │ ├── mod.rs │ ├── parser.rs │ └── splitting.rs │ ├── fragments │ └── mod.rs │ ├── index │ ├── index_filter.rs │ ├── index_metadata.rs │ ├── index_words.rs │ └── mod.rs │ ├── lib.rs │ ├── logging.rs │ ├── main.rs │ ├── options.rs │ ├── output │ ├── entry.rs │ └── mod.rs │ ├── playground.rs │ ├── runner.rs │ ├── serve.rs │ ├── service │ ├── api.rs │ ├── mod.rs │ ├── requests.rs │ └── responses.rs │ └── utils.rs ├── pagefind_playground ├── _build.js ├── _build_common.js ├── _serve.js ├── lib │ ├── Playground.svelte │ ├── defaults.ts │ ├── panels │ │ ├── PinnedResults.svelte │ │ ├── RankingPresets.svelte │ │ ├── RankingSettings.svelte │ │ ├── Result.svelte │ │ ├── Results.svelte │ │ ├── Search.svelte │ │ └── TopBar.svelte │ └── playground.ts ├── local_prep.sh ├── output │ └── playground │ │ └── index.html ├── package-lock.json ├── package.json ├── tsconfig.json └── types │ └── index.d.ts ├── pagefind_stem ├── Cargo.toml ├── build.js └── src │ ├── lib.rs │ └── snowball │ ├── algorithms │ ├── arabic.rs │ ├── armenian.rs │ ├── basque.rs │ ├── catalan.rs │ ├── danish.rs │ ├── dutch.rs │ ├── english.rs │ ├── finnish.rs │ ├── french.rs │ ├── german.rs │ ├── german2.rs │ ├── greek.rs │ ├── hindi.rs │ ├── hungarian.rs │ ├── indonesian.rs │ ├── irish.rs │ ├── italian.rs │ ├── kraaij_pohlmann.rs │ ├── lithuanian.rs │ ├── lovins.rs │ ├── mod.rs │ ├── nepali.rs │ ├── norwegian.rs │ ├── porter.rs │ ├── portuguese.rs │ ├── romanian.rs │ ├── russian.rs │ ├── serbian.rs │ ├── spanish.rs │ ├── swedish.rs │ ├── tamil.rs │ ├── turkish.rs │ └── yiddish.rs │ ├── among.rs │ ├── mod.rs │ └── snowball_env.rs ├── pagefind_ui ├── default │ ├── .npmrc │ ├── README.md │ ├── _dev_files │ │ ├── index.html │ │ ├── pagefind │ │ │ └── _pagefind_stub.ts │ │ └── water.css │ ├── build.js │ ├── package-lock.json │ ├── package.json │ ├── svelte │ │ ├── filters.svelte │ │ ├── reset.svelte │ │ ├── result.svelte │ │ ├── result_with_subs.svelte │ │ └── ui.svelte │ ├── tsconfig.json │ ├── ui-core.js │ └── ui.js ├── modular │ ├── .npmrc │ ├── README.md │ ├── _dev_files │ │ └── index.html │ ├── build.js │ ├── components │ │ ├── filterPills.js │ │ ├── input.js │ │ ├── resultList.js │ │ └── summary.js │ ├── css │ │ └── ui.css │ ├── helpers │ │ └── element-builder.js │ ├── modular-core.js │ ├── modular.js │ ├── package-lock.json │ ├── package.json │ └── tsconfig.json └── translations │ ├── af.json │ ├── ar.json │ ├── bn.json │ ├── ca.json │ ├── cs.json │ ├── da.json │ ├── de.json │ ├── en.json │ ├── es.json │ ├── fa.json │ ├── fi.json │ ├── fr.json │ ├── gl.json │ ├── he.json │ ├── hi.json │ ├── hr.json │ ├── hu.json │ ├── id.json │ ├── it.json │ ├── ja.json │ ├── ko.json │ ├── mi.json │ ├── my.json │ ├── nl.json │ ├── no.json │ ├── pl.json │ ├── pt.json │ ├── ro.json │ ├── ru.json │ ├── sr.json │ ├── sv.json │ ├── sw.json │ ├── ta.json │ ├── th.json │ ├── tr.json │ ├── uk.json │ ├── vi.json │ ├── zh-cn.json │ ├── zh-tw.json │ └── zh.json ├── pagefind_web ├── .vscode │ └── settings.json ├── Cargo.lock ├── Cargo.toml ├── build.js ├── local_build.sh ├── local_debug_build.sh ├── local_fast_build.sh ├── local_fast_debug_build.sh └── src │ ├── filter.rs │ ├── filter_index.rs │ ├── index.rs │ ├── lib.rs │ ├── metadata.rs │ ├── search.rs │ └── util.rs ├── pagefind_web_js ├── build.js ├── lib │ ├── coupled_search.ts │ ├── excerpt.ts │ ├── gz.js │ ├── highlight.ts │ ├── public_search_api.ts │ └── sub_results.ts ├── package-lock.json ├── package.json ├── tests │ └── excerpt.test.ts ├── tsconfig.json └── types │ ├── index.d.ts │ └── internal.d.ts ├── toolproof.yml └── wrappers ├── node ├── .npmrc ├── LICENSE │ ├── LICENSE │ └── LICENSE-vscode-ripgrep ├── README.md ├── jsconfig.json ├── lib │ ├── encoding.js │ ├── index.js │ ├── resolveBinary.js │ ├── runner │ │ └── bin.cjs │ └── service.js ├── package-lock.json ├── package.json ├── tsconfig.json └── types │ ├── index.d.ts │ └── internal.d.ts ├── python ├── .editorconfig ├── .gitignore ├── README.md ├── poetry.lock ├── poetry.toml ├── pyproject.toml ├── scripts │ ├── __init__.py │ ├── build │ │ ├── __init__.py │ │ ├── all_binary_only_wheels.py │ │ ├── api_package.py │ │ ├── binary_only_wheel.py │ │ ├── download_verification.py │ │ ├── get_pagefind_release.py │ │ └── versioning.py │ ├── ci │ │ ├── cog │ │ │ ├── check.sh │ │ │ ├── files.sh │ │ │ └── update.sh │ │ ├── github │ │ │ ├── README.md │ │ │ ├── activate_venv.sh │ │ │ ├── add_src_to_pythonpath.py │ │ │ ├── debug_python_paths.sh │ │ │ ├── install_dev_dependencies.sh │ │ │ ├── integration_tests.sh │ │ │ └── setup_poetry.sh │ │ ├── python_lints.sh │ │ └── shellcheck.sh │ └── publish_to_test_pypi.sh └── src │ ├── pagefind │ ├── __init__.py │ ├── __main__.py │ ├── index │ │ └── __init__.py │ ├── py.typed │ └── service │ │ ├── __init__.py │ │ └── types.py │ ├── pagefind_python_bin │ ├── README.md │ ├── __init__.py │ └── __main__.py │ └── tests │ ├── README.md │ └── integration.py └── tester ├── package-lock.json ├── package.json └── tester.js /.backstage/create_package.cjs: -------------------------------------------------------------------------------- 1 | const fs = require("fs"); 2 | const path = require("path"); 3 | 4 | const cwd = process.cwd(); 5 | const package_name = `@pagefind/${path.basename(cwd)}`; 6 | const [os, cpu] = process.argv.slice(2); 7 | 8 | if (!os || !cpu) { 9 | console.error("Script os and cpu as positional arguments"); 10 | process.exit(1); 11 | } 12 | 13 | fs.writeFileSync(path.join(cwd, "package.json"), JSON.stringify({ 14 | name: package_name, 15 | version: "0.0.0", 16 | description: `The platform-specific binary for pagefind on ${os}/${cpu}`, 17 | license: "MIT", 18 | repository: { 19 | type: "git", 20 | url: "git+https://github.com/cloudcannon/pagefind.git" 21 | }, 22 | author: "CloudCannon", 23 | os: [os], 24 | cpu: [cpu], 25 | })); 26 | 27 | fs.writeFileSync(path.join(cwd, "README.md"), `# Pagefind 28 | 29 | The platform-specific binary for pagefind on ${os}/${cpu} 30 | `); -------------------------------------------------------------------------------- /.backstage/get_tag.cjs: -------------------------------------------------------------------------------- 1 | const version = process.env.GIT_VERSION; 2 | 3 | if (!version) { 4 | console.error("Script expected a GIT_VERSION environment variable"); 5 | process.exit(1); 6 | } 7 | 8 | // Only allow latest tag if we are releasing a major/minor/patch 9 | if (/^\d+\.\d+\.\d+$/.test(version)) { 10 | console.log("latest"); 11 | process.exit(0); 12 | } 13 | 14 | // Use the suffix as the tag. i.e. `0.11.0-rc5` -> `rc` 15 | const suffix = version.match(/^\d+\.\d+\.\d+-([a-z]+)/i)?.[1]; 16 | if (suffix) { 17 | console.log(suffix.toLowerCase()); 18 | process.exit(0); 19 | } 20 | 21 | // Fall back to an unknown tag for safety 22 | console.log("unknown"); -------------------------------------------------------------------------------- /.backstage/version_main_package.cjs: -------------------------------------------------------------------------------- 1 | const fs = require("fs"); 2 | const path = require("path"); 3 | 4 | const version = process.env.GIT_VERSION; 5 | if (!version) { 6 | console.error("Script expected a GIT_VERSION environment variable"); 7 | process.exit(1); 8 | } 9 | 10 | const pkg = path.join(__dirname, "../wrappers/node/package.json"); 11 | 12 | const pkg_contents = JSON.parse(fs.readFileSync(pkg, { encoding: "utf-8" })); 13 | for (const dep of Object.keys(pkg_contents.optionalDependencies).filter(dep => dep.startsWith("@pagefind"))) { 14 | pkg_contents.optionalDependencies[dep] = version; 15 | } 16 | 17 | console.log(JSON.stringify(pkg_contents.optionalDependencies, null, 2)); 18 | 19 | fs.writeFileSync(pkg, JSON.stringify(pkg_contents, null, 2)); 20 | -------------------------------------------------------------------------------- /.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [target.x86_64-pc-windows-msvc] 2 | rustflags = ["-Ctarget-feature=+crt-static"] 3 | -------------------------------------------------------------------------------- /.cloudcannon/postbuild: -------------------------------------------------------------------------------- 1 | npx -y pagefind@alpha --site docs/public --write-playground 2 | -------------------------------------------------------------------------------- /.cloudcannon/prebuild: -------------------------------------------------------------------------------- 1 | export HUGO_PAGEFIND_DOCS_VERSION=$(node ./.backstage/set_version.cjs) 2 | echo "Building documentation for $HUGO_PAGEFIND_DOCS_VERSION" 3 | cd docs && npm i -------------------------------------------------------------------------------- /.github/workflows/dependabot.yml: -------------------------------------------------------------------------------- 1 | name: auto-merge 2 | 3 | on: 4 | pull_request_target 5 | 6 | jobs: 7 | auto-merge: 8 | runs-on: ubuntu-latest 9 | if: ${{ github.actor == 'dependabot[bot]' }} 10 | steps: 11 | - uses: actions/checkout@v4 12 | - name: Get Token 13 | id: get_workflow_token 14 | uses: peter-murray/workflow-application-token-action@v2 15 | with: 16 | application_id: ${{ secrets.CC_OSS_BOT_ID }} 17 | application_private_key: ${{ secrets.CC_OSS_BOT_PEM }} 18 | - uses: fastify/github-action-merge-dependabot@v3 19 | with: 20 | github-token: ${{ steps.get_workflow_token.outputs.token }} 21 | target: minor 22 | approve-only: true 23 | - name: Enable auto-merge for Dependabot PR 24 | run: gh pr merge --auto --merge "$PR_URL" 25 | env: 26 | PR_URL: ${{ github.event.pull_request.html_url }} 27 | GITHUB_TOKEN: ${{ steps.get_workflow_token.outputs.token }} 28 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Custom 2 | public 3 | .DS_Store 4 | .hugo_build.lock 5 | _gen 6 | pagefind_ui/default/_dev_files/_pagefind/ui.* 7 | pagefind_ui/default/_dev_files/_pagefind/pagefind.js 8 | pagefind_ui/default/_dev_files/pagefind/ui.* 9 | pagefind_ui/default/_dev_files/pagefind/pagefind.js 10 | pagefind_ui/default/css 11 | pagefind_ui/modular/_dev_files/_pagefind/modular.* 12 | pagefind_ui/modular/_dev_files/_pagefind/pagefind.js 13 | pagefind_ui/modular/_dev_files/pagefind/modular.* 14 | pagefind_ui/modular/_dev_files/pagefind/pagefind.js 15 | 16 | pagefind_playground/output/* 17 | !pagefind_playground/output/playground/ 18 | pagefind_playground/output/playground/pagefind-playground.css 19 | pagefind_playground/output/playground/pagefind-playground.js 20 | 21 | npm_dist 22 | 23 | # Generated by Cargo 24 | # will have compiled files and executables 25 | debug/ 26 | target/ 27 | 28 | # wasm-pack's dir 29 | pkg/ 30 | 31 | # These are backup files generated by rustfmt 32 | **/*.rs.bk 33 | 34 | # MSVC Windows builds of rustc generate these, which store debugging information 35 | *.pdb 36 | 37 | # Our vendoring directories 38 | vendor 39 | 40 | # Node 41 | node_modules 42 | 43 | # Python 44 | __pycache__/ 45 | *.pyc 46 | dist 47 | *.whl 48 | *.egg-info 49 | *.log 50 | -------------------------------------------------------------------------------- /.shellcheckrc: -------------------------------------------------------------------------------- 1 | external-sources=true 2 | source-path=SCRIPTDIR 3 | disable=SC2002 4 | # SC2002: ignore "useless cat" warning: starting pipes with `cat` improves composability 5 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "rust-analyzer.showUnlinkedFileNotification": false, 3 | "python.analysis.typeCheckingMode": "standard", 4 | "[python]": { 5 | "editor.formatOnSave": true, 6 | "editor.defaultFormatter": "charliermarsh.ruff" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | 3 | members = ["pagefind", "pagefind_stem"] 4 | exclude = ["pagefind_web"] 5 | resolver = "2" 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2022 CloudCannon 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Pagefind 2 | 3 | Pagefind is a fully static search library that aims to perform well on large sites, while using as little of your users’ bandwidth as possible, and without hosting any infrastructure. 4 | 5 | The full documentation on using Pagefind can be found at https://pagefind.app/. 6 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Reporting a Vulnerability 4 | 5 | To report a suspected vulnerability, please either: 6 | 7 | - Privately report a vulnerability through GitHub at https://github.com/CloudCannon/pagefind/security 8 | - Email support@cloudcannon.com. 9 | 10 | Please do not report any suspected vulnerabilities through public issues. 11 | 12 | ## Supported versions 13 | 14 | Only the latest major version of Pagefind will be supported with security updates. 15 | -------------------------------------------------------------------------------- /docs/content/docs/api-reference.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Search API Reference" 3 | nav_title: "Search API Reference" 4 | nav_section: References 5 | weight: 71 6 | --- 7 | 8 | This documentation is a work in process! 9 | 10 | The types returned by Pagefind's JavaScript search API can currently be seen here: [pagefind_web_js/types/index.d.ts](https://github.com/CloudCannon/pagefind/blob/production-docs/pagefind_web_js/types/index.d.ts) 11 | -------------------------------------------------------------------------------- /docs/content/docs/config-sources.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Pagefind CLI configuration sources" 3 | nav_title: "CLI config sources" 4 | nav_section: References 5 | weight: 50 6 | --- 7 | 8 | Pagefind can be configured through CLI flags, environment variables, or configuration files. Values will be merged from all sources, with CLI flags overriding environment variables, and environment variables overriding configuration files. 9 | 10 | ## Config files 11 | 12 | Pagefind will look for a `pagefind.toml`, `pagefind.yml`, `pagefind.yaml`, or `pagefind.json` file in the directory that you have run the command in. 13 | 14 | ```yaml 15 | # pagefind.yml 16 | site: public 17 | output_subdir: pagefind 18 | ``` 19 | ```bash 20 | npx pagefind 21 | ``` 22 | 23 | ## Environment variables 24 | 25 | Pagefind will load any values via a `PAGEFIND_*` environment variable. 26 | 27 | ```bash 28 | export PAGEFIND_OUTPUT_SUBDIR="pagefind" 29 | PAGEFIND_SITE="public" npx pagefind 30 | ``` 31 | 32 | ## CLI flags 33 | 34 | Pagefind can be passed CLI flags directly. 35 | 36 | ```bash 37 | npx pagefind --site public --output-subdir pagefind 38 | ``` 39 | -------------------------------------------------------------------------------- /docs/content/docs/default-ui-filtering.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Filtering results with the Pagefind Default UI" 3 | nav_title: "Filtering with the Default UI" 4 | nav_section: Filtering 5 | weight: 11 6 | --- 7 | 8 | Pagefind's Default UI supports filters and will show them in a sidebar if they are present in your index. 9 | 10 | The Default UI will also show a count beside each filter, representing the number of results available within that filter, taking the current search term and toggled filters into account. 11 | By default, filters with no remaining pages will still be shown. This can be disabled by setting the [`showEmptyFilters`](/docs/ui/#show-empty-filters) option to `false`. 12 | 13 | Currently, the Default UI treats all filters as "AND" filters, meaning pages will only be shown if they match all toggled filters. 14 | -------------------------------------------------------------------------------- /docs/content/docs/default-ui-metadata.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Showing metadata in the Pagefind Default UI" 3 | nav_title: "Metadata in the Default UI" 4 | nav_section: Metadata 5 | weight: 11 6 | --- 7 | 8 | Pagefind's Default UI uses the default metadata keys to customize the way results are displayed. The following metadata items are used in the Default UI: 9 | 10 | - The title of each search result uses the `title` key from the page metadata 11 | - The image beside each search result uses the `image` and `image_alt` keys from the page metadata 12 | - The url of each search result may be overridden by specifying a `url` key in the page metadata 13 | 14 | Any other metadata key-value pairs you assign to pages will be shown below the search result. -------------------------------------------------------------------------------- /docs/content/docs/implementation-service.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Implementation service for Pagefind" 3 | nav_title: "Implementation service for Pagefind" 4 | nav_section: Resources 5 | weight: 100 6 | --- 7 | 8 | Pagefind's goal is to provide the best out of the box experience, while providing hooks and integrations that allow you to customize your own search experience. 9 | 10 | For companies and individuals looking for a hand with this process, CloudCannon’s dedicated development team is available to help with implementing Pagefind on your static site — no matter which SSG, CMS, or host you use. 11 | 12 | Beginning with a personalized consultation, the CloudCannon development team will make sure Pagefind suits your needs, create a design to match your brand guidelines, and ensure your new site search is tuned for your users, with the latest Pagefind features and updates. 13 | 14 | [Find out more on CloudCannon's website](https://cloudcannon.com/pagefind-implementation/). 15 | -------------------------------------------------------------------------------- /docs/content/docs/js-api-metadata.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Getting metadata with the Pagefind JavaScript API" 3 | nav_title: "Metadata in the JS API" 4 | nav_section: Metadata 5 | weight: 12 6 | --- 7 | 8 | Pagefind's JavaScript API returns the metadata of your pages automatically alongside your search result data. 9 | 10 | ## Getting metadata from a search result 11 | 12 | {{< diffcode >}} 13 | ```js 14 | const pagefind = await import("/pagefind/pagefind.js"); 15 | const search = await pagefind.search("static"); 16 | +const oneResult = await search.results[0].data(); 17 | ``` 18 | {{< /diffcode >}} 19 | 20 | Here, `oneResult` will contain: 21 | 22 | {{< diffcode >}} 23 | ```js 24 | { 25 | /* ... other result keys ... */ 26 | "url": "/url-of-the-page/", 27 | "excerpt": "A small snippet of the static content, with the search term(s) highlighted in <mark> elements.", 28 | ~ "meta": { 29 | ~ "title": "The title from the first h1 element on the page", 30 | ~ "image": "/weka.png", 31 | ~ "my-custom-key": "My custom metadata content", 32 | ~ } 33 | } 34 | ``` 35 | {{< /diffcode >}} -------------------------------------------------------------------------------- /docs/content/docs/js-api-sorting.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Sorting using the Pagefind JavaScript API" 3 | nav_title: "Sorting with the JS API" 4 | nav_section: Sorting 5 | weight: 21 6 | --- 7 | 8 | Pagefind's JavaScript API supports sorting your content when searching. Doing so will override the default rankings, and will return all matching results sorted by the given attribute. 9 | 10 | ## Sorting as part of a search 11 | 12 | If pages on your site have been tagged with [sort attributes](/docs/sorts/), a `sort` object can be provided to Pagefind when searching: 13 | 14 | {{< diffcode >}} 15 | ```js 16 | const search = await pagefind.search("static", { 17 | + sort: { 18 | + date: "asc" 19 | + } 20 | }); 21 | ``` 22 | {{< /diffcode >}} 23 | 24 | This object should contain one key, matching a `data-pagefind-sort` attribute, and specify either `asc` for ascending or `desc` for descending sort order. 25 | -------------------------------------------------------------------------------- /docs/content/docs/playground.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Pagefind Playground" 3 | nav_title: "Pagefind Playground" 4 | nav_section: References 5 | weight: 72 6 | --- 7 | 8 | Pagefind provides a playground page that can be used to take a deeper look into how Pagefind searches your content. 9 | You can explore the playground for this documentation site at [/pagefind/playground/](/pagefind/playground/). 10 | 11 | Use the playground to: 12 | - Determine the ideal ranking parameters to configure for your content. 13 | - Debug any issues with how your content is being searched. 14 | - Explore all data returned from Pagefind for your content. 15 | 16 | The playground is always available at `/pagefind/playground/` when running Pagefind with the [serve](/docs/config-options/#serve) option, e.g. with `--serve` via the Pagefind CLI. 17 | 18 | Setting the [write playground](/docs/config-options/#write-playground) option when indexing will write the playground files to your bundle, allowing them to be hosted as part of your site. 19 | -------------------------------------------------------------------------------- /docs/data/banner.yml: -------------------------------------------------------------------------------- 1 | enable_banner: true 2 | html: "✨ Pagefind is now 1.0! Read the release notes, and view the migration guide." 3 | id: release-v1.0.0 4 | show_until: 2024-06-06T00:00:00Z -------------------------------------------------------------------------------- /docs/data/footer.yml: -------------------------------------------------------------------------------- 1 | footer_width: contain 2 | footer_links: 3 | - url_path: https://cloudcannon.com/ 4 | image_path: /cloudcannon.svg 5 | image_alt_text: cloudcannon -------------------------------------------------------------------------------- /docs/data/meta.yml: -------------------------------------------------------------------------------- 1 | project_name: Pagefind — Static low-bandwidth search at scale 2 | default_og_image: /og.png 3 | favicon: 4 | small_icon: /meta/favicon-16x16.png 5 | large_icon: /meta/favicon-32x32.png 6 | apple_touch_icon: /meta/apple-touch-icon.png 7 | shortcut_icon: /meta/favicon.ico -------------------------------------------------------------------------------- /docs/data/nav.yml: -------------------------------------------------------------------------------- 1 | side_nav_title: Docs 2 | nav_links: 3 | - link_title: GitHub 4 | link_url: https://github.com/cloudcannon/pagefind 5 | link_label: Local 6 | link_icon_path: /github.svg 7 | logo: 8 | logo_heading: Pagefind 9 | logo_image: /pagefind.svg 10 | logo_image_dark: /pagefind-dark.svg -------------------------------------------------------------------------------- /docs/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/cloudcannon/pagefind/docs 2 | 3 | go 1.18 4 | 5 | require github.com/bglw/alto-as-module v0.0.0-20250122004256-c19367ece8ca // indirect 6 | -------------------------------------------------------------------------------- /docs/hugo.toml: -------------------------------------------------------------------------------- 1 | baseURL = 'https://pagefind.app/' 2 | languageCode = 'en-us' 3 | title = 'Pagefind' 4 | summaryLength = 30 5 | disableKinds = ["taxonomy"] 6 | 7 | [markup] 8 | highlight.noClasses = false 9 | 10 | [markup.goldmark.renderer] 11 | # ensures html inside markdown is allowed to render 12 | unsafe = true 13 | 14 | [[module.imports]] 15 | path = 'github.com/bglw/alto-as-module' 16 | -------------------------------------------------------------------------------- /docs/layouts/partials/docnav.html: -------------------------------------------------------------------------------- 1 | {{ $page := . }} 2 | 3 | -------------------------------------------------------------------------------- /docs/layouts/partials/extra_head.html: -------------------------------------------------------------------------------- 1 | {{ $style := resources.Get "css/extras.scss" | toCSS | minify | fingerprint }} 2 | -------------------------------------------------------------------------------- /docs/layouts/shortcodes/card.html: -------------------------------------------------------------------------------- 1 | 2 | {{ .Get 3 |
4 |

{{ .Get "title" }}

5 | {{ .Get "url" }} 6 |
7 |
-------------------------------------------------------------------------------- /docs/layouts/shortcodes/how_to.html: -------------------------------------------------------------------------------- 1 |
19 | 20 | 21 | ## {{ .Get "label" }} 22 | 23 | 24 |
25 | 26 | {{ .Inner }} 27 | 28 |
29 |
30 | -------------------------------------------------------------------------------- /docs/layouts/shortcodes/resource.html: -------------------------------------------------------------------------------- 1 | {{ .Get "title" }}
2 | 3 | {{ with .Get "date" }}{{.}} • {{ end }} 4 | {{ .Get "site" }} 5 | {{ with .Get "archive_url" }}• archive{{ end }} 6 | {{ with .Get "translated_url" }}• translated{{ end }} 7 | -------------------------------------------------------------------------------- /docs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "docs", 3 | "private": true, 4 | "dependencies": { 5 | "alpinejs": "^3.13.0" 6 | } 7 | } -------------------------------------------------------------------------------- /docs/static/bell.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/static/github.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /docs/static/meta/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudCannon/pagefind/d7d0b3a0f0eb12661cd2eb894ad02f10687a4ca0/docs/static/meta/android-chrome-192x192.png -------------------------------------------------------------------------------- /docs/static/meta/android-chrome-256x256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudCannon/pagefind/d7d0b3a0f0eb12661cd2eb894ad02f10687a4ca0/docs/static/meta/android-chrome-256x256.png -------------------------------------------------------------------------------- /docs/static/meta/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudCannon/pagefind/d7d0b3a0f0eb12661cd2eb894ad02f10687a4ca0/docs/static/meta/apple-touch-icon.png -------------------------------------------------------------------------------- /docs/static/meta/browserconfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | #da532c 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /docs/static/meta/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudCannon/pagefind/d7d0b3a0f0eb12661cd2eb894ad02f10687a4ca0/docs/static/meta/favicon-16x16.png -------------------------------------------------------------------------------- /docs/static/meta/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudCannon/pagefind/d7d0b3a0f0eb12661cd2eb894ad02f10687a4ca0/docs/static/meta/favicon-32x32.png -------------------------------------------------------------------------------- /docs/static/meta/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudCannon/pagefind/d7d0b3a0f0eb12661cd2eb894ad02f10687a4ca0/docs/static/meta/favicon.ico -------------------------------------------------------------------------------- /docs/static/meta/mstile-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudCannon/pagefind/d7d0b3a0f0eb12661cd2eb894ad02f10687a4ca0/docs/static/meta/mstile-150x150.png -------------------------------------------------------------------------------- /docs/static/meta/site.webmanifest: -------------------------------------------------------------------------------- 1 | { 2 | "name": "", 3 | "short_name": "", 4 | "icons": [ 5 | { 6 | "src": "/meta/android-chrome-192x192.png", 7 | "sizes": "192x192", 8 | "type": "image/png" 9 | }, 10 | { 11 | "src": "/meta/android-chrome-256x256.png", 12 | "sizes": "256x256", 13 | "type": "image/png" 14 | } 15 | ], 16 | "theme_color": "#ffffff", 17 | "background_color": "#ffffff", 18 | "display": "standalone" 19 | } 20 | -------------------------------------------------------------------------------- /docs/static/og.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudCannon/pagefind/d7d0b3a0f0eb12661cd2eb894ad02f10687a4ca0/docs/static/og.png -------------------------------------------------------------------------------- /docs/static/xkcd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudCannon/pagefind/d7d0b3a0f0eb12661cd2eb894ad02f10687a4ca0/docs/static/xkcd.png -------------------------------------------------------------------------------- /pagefind/integration_tests/_macros/node.toolproof.macro.yml: -------------------------------------------------------------------------------- 1 | macro: I run Pagefind Node as {file} in {dir} 2 | steps: 3 | - I run "cd %dir% && npm i && PAGEFIND_BINARY_PATH=%toolproof_process_directory%/target/%pagefind_mode%/pagefind node %file%" 4 | -------------------------------------------------------------------------------- /pagefind/integration_tests/_macros/python.toolproof.macro.yml: -------------------------------------------------------------------------------- 1 | macro: I run Pagefind Python as {file} in {dir} 2 | steps: 3 | - I run "cd %dir% && PAGEFIND_BINARY_PATH=%toolproof_process_directory%/target/%pagefind_mode%/pagefind python3 %file%" 4 | -------------------------------------------------------------------------------- /pagefind/integration_tests/_macros/run.toolproof.macro.yml: -------------------------------------------------------------------------------- 1 | macro: I run Pagefind 2 | steps: 3 | - I run "%toolproof_process_directory%/target/%pagefind_mode%/pagefind" 4 | -------------------------------------------------------------------------------- /pagefind/integration_tests/_macros/run_failing.toolproof.macro.yml: -------------------------------------------------------------------------------- 1 | macro: I run a failing Pagefind 2 | steps: 3 | - I run "%toolproof_process_directory%/target/%pagefind_mode%/pagefind" and expect it to fail 4 | -------------------------------------------------------------------------------- /pagefind/integration_tests/_macros/run_failing_with_flags.toolproof.macro.yml: -------------------------------------------------------------------------------- 1 | macro: I run a failing Pagefind with {flags} 2 | steps: 3 | - I run "%toolproof_process_directory%/target/%pagefind_mode%/pagefind %flags%" and expect it to fail 4 | -------------------------------------------------------------------------------- /pagefind/integration_tests/_macros/run_with_flags.toolproof.macro.yml: -------------------------------------------------------------------------------- 1 | macro: I run Pagefind with {flags} 2 | steps: 3 | - I run "%toolproof_process_directory%/target/%pagefind_mode%/pagefind %flags%" 4 | -------------------------------------------------------------------------------- /pagefind/integration_tests/anchors/pagefind-respects-data-pagefind-ignore-inside-anchors.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: Anchors > Pagefind respects data-pagefind-ignore inside anchors 2 | steps: 3 | - ref: ./background.toolproof.yml 4 | - step: In my browser, I evaluate {js} 5 | js: |- 6 | let pagefind = await import("/pagefind/pagefind.js"); 7 | 8 | let search = await pagefind.search("symbiosis"); 9 | let searchdata = await search.results[0].data(); 10 | document.querySelector('[data-search]').innerHTML = ` 11 | 14 | `; 15 | - step: In my browser, the console should be empty 16 | - step: In my browser, I evaluate {js} 17 | js: >- 18 | let val = await 19 | toolproof.querySelector("[data-search]>ul>li:nth-of-type(1)"); 20 | 21 | toolproof.assert_eq(val.innerHTML, `/repr/#repr-heading: My Heading about 22 | Symbiosis / 'My Heading about Symbiosis.'`); 23 | -------------------------------------------------------------------------------- /pagefind/integration_tests/anchors/pagefind-returns-all-page-anchors-in-the-fragment.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: Anchors > Pagefind returns all page anchors in the fragment 2 | steps: 3 | - ref: ./background.toolproof.yml 4 | - step: In my browser, I evaluate {js} 5 | js: >- 6 | let pagefind = await import("/pagefind/pagefind.js"); 7 | 8 | 9 | let search = await pagefind.search("pageone"); 10 | 11 | let searchdata = await search.results[0].data(); 12 | 13 | document.querySelector('[data-search]').innerText = 14 | searchdata.anchors.map(a => `${a.element}#${a.id}: ${a.location}`).join(', 15 | '); 16 | - step: In my browser, the console should be empty 17 | - step: In my browser, I evaluate {js} 18 | js: >- 19 | let val = await toolproof.querySelector("[data-search]"); 20 | 21 | toolproof.assert_eq(val.innerHTML, `h2#cats: 3, ul#list: 4, li#ali: 5, 22 | h2#pagefind: 8`); 23 | -------------------------------------------------------------------------------- /pagefind/integration_tests/anchors/pagefind-returns-all-word-locations-in-the-fragment.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: Anchors > Pagefind returns all word locations in the fragment 2 | steps: 3 | - ref: ./background.toolproof.yml 4 | - step: In my browser, I evaluate {js} 5 | js: >- 6 | let pagefind = await import("/pagefind/pagefind.js"); 7 | 8 | 9 | let search = await pagefind.search("pageone"); 10 | 11 | let searchdata = await search.results[0].data(); 12 | 13 | document.querySelector('[data-search]').innerText = 14 | searchdata.locations.join(', '); 15 | - step: In my browser, the console should be empty 16 | - step: In my browser, I evaluate {js} 17 | js: |- 18 | let val = await toolproof.querySelector("[data-search]"); 19 | toolproof.assert_eq(val.innerHTML, `0, 9`); 20 | -------------------------------------------------------------------------------- /pagefind/integration_tests/anchors/pagefind-returns-full-content-without-anchors.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: Anchors > Pagefind returns full content without anchors 2 | steps: 3 | - ref: ./background.toolproof.yml 4 | - step: In my browser, I evaluate {js} 5 | js: |- 6 | let pagefind = await import("/pagefind/pagefind.js"); 7 | 8 | let search = await pagefind.search("pageone"); 9 | let searchdata = await search.results[0].data(); 10 | document.querySelector('[data-search]').innerText = searchdata.content; 11 | - step: In my browser, the console should be empty 12 | - step: In my browser, I evaluate {js} 13 | js: >- 14 | let val = await toolproof.querySelector("[data-search]"); 15 | 16 | toolproof.assert_eq(val.innerHTML, `PageOne, from Pagefind. Cats. Cheeka. 17 | Ali. Theodore. Smudge. Pagefind. PageOne, again, from Pagefind.`); 18 | -------------------------------------------------------------------------------- /pagefind/integration_tests/anchors/pagefind-returns-page-anchor-content-in-the-fragment.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: Anchors > Pagefind returns page anchor content in the fragment 2 | steps: 3 | - ref: ./background.toolproof.yml 4 | - step: In my browser, I evaluate {js} 5 | js: >- 6 | let pagefind = await import("/pagefind/pagefind.js"); 7 | 8 | 9 | let search = await pagefind.search("pageone"); 10 | 11 | let searchdata = await search.results[0].data(); 12 | 13 | document.querySelector('[data-search]').innerText = 14 | searchdata.anchors.map(a => `#${a.id}: '${a.text}'`).join(', '); 15 | - step: In my browser, the console should be empty 16 | - step: In my browser, I evaluate {js} 17 | js: >- 18 | let val = await toolproof.querySelector("[data-search]"); 19 | 20 | toolproof.assert_eq(val.innerHTML, `#cats: 'Cats', #list: '', #ali: 'Ali', 21 | #pagefind: 'Pagefind'`); 22 | -------------------------------------------------------------------------------- /pagefind/integration_tests/base/background.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: base > Base Tests > Background 2 | type: reference 3 | steps: 4 | - step: I have the environment variable "PAGEFIND_SITE" set to "public" 5 | - step: I have a "public/index.html" file with the content {html} 6 | html: >- 7 |

Nothing

9 | -------------------------------------------------------------------------------- /pagefind/integration_tests/base/preload-indexes-then-search-for-a-word.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: Base Tests > Preload indexes then search for a word 2 | steps: 3 | - ref: ./background.toolproof.yml 4 | - step: I have a "public/cat/index.html" file with the content {html} 5 | html: >- 6 |

world

8 | - macro: I run Pagefind 9 | - step: stdout should contain "Running Pagefind" 10 | - step: The file "public/pagefind/pagefind.js" should not be empty 11 | - step: I serve the directory "public" 12 | - step: In my browser, I load "/" 13 | - step: In my browser, I evaluate {js} 14 | js: |- 15 | let pagefind = await import("/pagefind/pagefind.js"); 16 | 17 | await pagefind.preload("wo"); 18 | let search = await pagefind.search("world"); 19 | 20 | let data = await search.results[0].data(); 21 | document.querySelector('[data-url]').innerText = data.url; 22 | - step: In my browser, the console should be empty 23 | - step: In my browser, I evaluate {js} 24 | js: |- 25 | let val = await toolproof.querySelector("[data-url]"); 26 | toolproof.assert_eq(val.innerHTML, `/cat/`); 27 | -------------------------------------------------------------------------------- /pagefind/integration_tests/base/return-all-results.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: Base Tests > Return all results 2 | steps: 3 | - ref: ./background.toolproof.yml 4 | - step: I have a "public/cat/index.html" file with the content {html} 5 | html: >- 6 |

world

8 | - macro: I run Pagefind 9 | - step: stdout should contain "Running Pagefind" 10 | - step: The file "public/pagefind/pagefind.js" should not be empty 11 | - step: I serve the directory "public" 12 | - step: In my browser, I load "/" 13 | - step: In my browser, I evaluate {js} 14 | js: >- 15 | let pagefind = await import("/pagefind/pagefind.js"); 16 | 17 | 18 | let search = await pagefind.search(null); 19 | 20 | 21 | let pages = await Promise.all(search.results.map(r => r.data())); 22 | 23 | document.querySelector('[data-url]').innerText = pages.map(p => 24 | p.url).sort().join(", "); 25 | - step: In my browser, the console should be empty 26 | - step: In my browser, I evaluate {js} 27 | js: |- 28 | let val = await toolproof.querySelector("[data-url]"); 29 | toolproof.assert_eq(val.innerHTML, `/, /cat/`); 30 | -------------------------------------------------------------------------------- /pagefind/integration_tests/base/search-for-a-word.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: Base Tests > Search for a word 2 | steps: 3 | - ref: ./background.toolproof.yml 4 | - step: I have a "public/cat/index.html" file with the content {html} 5 | html: >- 6 |

world

8 | - macro: I run Pagefind 9 | - step: stdout should contain "Running Pagefind" 10 | - step: The file "public/pagefind/pagefind.js" should not be empty 11 | - step: I serve the directory "public" 12 | - step: In my browser, I load "/" 13 | - step: In my browser, I evaluate {js} 14 | js: |- 15 | let pagefind = await import("/pagefind/pagefind.js"); 16 | 17 | let search = await pagefind.search("world"); 18 | 19 | let data = await search.results[0].data(); 20 | document.querySelector('[data-url]').innerText = data.url; 21 | - step: In my browser, the console should be empty 22 | - step: In my browser, I evaluate {js} 23 | js: |- 24 | let val = await toolproof.querySelector("[data-url]"); 25 | toolproof.assert_eq(val.innerHTML, `/cat/`); 26 | -------------------------------------------------------------------------------- /pagefind/integration_tests/build_options/background.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: build_options > Build Options > Background 2 | type: reference 3 | steps: 4 | - step: I have the environment variable "PAGEFIND_SITE" set to "public" 5 | -------------------------------------------------------------------------------- /pagefind/integration_tests/characters/background.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: characters > Character Tests > Background 2 | type: reference 3 | steps: 4 | - step: I have the environment variable "PAGEFIND_SITE" set to "public" 5 | - step: I have a "public/index.html" file with the content {html} 6 | html: >- 7 |

Nothing

9 | -------------------------------------------------------------------------------- /pagefind/integration_tests/characters/pagefind-can-search-for-a-hyphenated-phrase.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: Character Tests > Pagefind can search for a hyphenated phrase 2 | steps: 3 | - ref: ./background.toolproof.yml 4 | - step: I have a "public/ds/index.html" file with the content {html} 5 | html: >- 6 |

The 7 | beet-root

8 | - macro: I run Pagefind 9 | - step: stdout should contain "Running Pagefind" 10 | - step: The file "public/pagefind/pagefind.js" should not be empty 11 | - step: I serve the directory "public" 12 | - step: In my browser, I load "/" 13 | - step: In my browser, I evaluate {js} 14 | js: >- 15 | let pagefind = await import("/pagefind/pagefind.js"); 16 | 17 | 18 | let search = await pagefind.search("beet-root"); 19 | 20 | 21 | let pages = await Promise.all(search.results.map(r => r.data())); 22 | 23 | document.querySelector('[data-result]').innerText = pages.map(p => 24 | p.url).join(", "); 25 | - step: In my browser, the console should be empty 26 | - step: In my browser, I evaluate {js} 27 | js: |- 28 | let val = await toolproof.querySelector("[data-result]"); 29 | toolproof.assert_eq(val.innerHTML, `/ds/`); 30 | -------------------------------------------------------------------------------- /pagefind/integration_tests/characters/pagefind-doesn-t-match-html-entities-as-their-text.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: Character Tests > Pagefind doesn't match HTML entities as their text 2 | steps: 3 | - ref: ./background.toolproof.yml 4 | - step: I have a "public/apiary/index.html" file with the content {html} 5 | html: >- 6 |

The 7 | "bees"

8 | - macro: I run Pagefind 9 | - step: stdout should contain "Running Pagefind" 10 | - step: The file "public/pagefind/pagefind.js" should not be empty 11 | - step: I serve the directory "public" 12 | - step: In my browser, I load "/" 13 | - step: In my browser, I evaluate {js} 14 | js: >- 15 | let pagefind = await import("/pagefind/pagefind.js"); 16 | 17 | 18 | let search = await pagefind.search("bees"); 19 | 20 | 21 | let pages = await Promise.all(search.results.map(r => r.data())); 22 | 23 | document.querySelector('[data-result]').innerText = pages.map(p => 24 | p.content).join(", "); 25 | - step: In my browser, the console should be empty 26 | - step: In my browser, I evaluate {js} 27 | js: |- 28 | let val = await toolproof.querySelector("[data-result]"); 29 | toolproof.assert_eq(val.innerHTML, `The "bees"`); 30 | -------------------------------------------------------------------------------- /pagefind/integration_tests/characters/pagefind-matches-special-characters.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: Character Tests > Pagefind matches special characters 2 | steps: 3 | - ref: ./background.toolproof.yml 4 | - step: I have a "public/apiary/index.html" file with the content {html} 5 | html: >- 6 |

Béës

8 | - macro: I run Pagefind 9 | - step: stdout should contain "Running Pagefind" 10 | - step: The file "public/pagefind/pagefind.js" should not be empty 11 | - step: I serve the directory "public" 12 | - step: In my browser, I load "/" 13 | - step: In my browser, I evaluate {js} 14 | js: >- 15 | let pagefind = await import("/pagefind/pagefind.js"); 16 | 17 | 18 | let search = await pagefind.search("Béës"); 19 | 20 | 21 | let pages = await Promise.all(search.results.map(r => r.data())); 22 | 23 | document.querySelector('[data-result]').innerText = pages.map(p => 24 | p.url).join(", "); 25 | - step: In my browser, the console should be empty 26 | - step: In my browser, I evaluate {js} 27 | js: |- 28 | let val = await toolproof.querySelector("[data-result]"); 29 | toolproof.assert_eq(val.innerHTML, `/apiary/`); 30 | -------------------------------------------------------------------------------- /pagefind/integration_tests/compound_filtering/filtering-to-a-complex-nested-filter.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: Filtering > Filtering to a complex nested filter 2 | steps: 3 | - ref: ./background.toolproof.yml 4 | - step: In my browser, I evaluate {js} 5 | js: |- 6 | await test(pagefind.search("Cat", { 7 | filters: { 8 | any: [{ 9 | color: { 10 | any: [{ 11 | any: ["Tabby"] 12 | }, { 13 | all: ["Black", "White", "Orange"] 14 | }] 15 | } 16 | }, { 17 | mood: { 18 | all: ["Nervous", "Pining"] 19 | } 20 | }] 21 | } 22 | })); 23 | - step: In my browser, the console should be empty 24 | - step: In my browser, I evaluate {js} 25 | js: |- 26 | let val = await toolproof.querySelector("[data-results]"); 27 | toolproof.assert_eq(val.innerHTML, `/ali/, /grey/, /treacle/`); 28 | -------------------------------------------------------------------------------- /pagefind/integration_tests/compound_filtering/filtering-to-any-of-a-set-of-values-or-another-filter.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: Filtering > Filtering to any of a set of values or another filter 2 | steps: 3 | - ref: ./background.toolproof.yml 4 | - step: In my browser, I evaluate {js} 5 | js: |- 6 | await test(pagefind.search("Cat", { 7 | filters: { 8 | any: { 9 | color: { 10 | any: ["Black", "Orange"] 11 | }, 12 | mood: "Angry" 13 | } 14 | } 15 | })); 16 | - step: In my browser, the console should be empty 17 | - step: In my browser, I evaluate {js} 18 | js: >- 19 | let val = await toolproof.querySelector("[data-results]"); 20 | 21 | toolproof.assert_eq(val.innerHTML, `/ali/, /cheeka/, /smudge/, /theodore/, 22 | /treacle/`); 23 | -------------------------------------------------------------------------------- /pagefind/integration_tests/compound_filtering/filtering-to-any-of-a-single-filter.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: Filtering > Filtering to any of a single filter 2 | steps: 3 | - ref: ./background.toolproof.yml 4 | - step: In my browser, I evaluate {js} 5 | js: |- 6 | await test(pagefind.search("Cat", { 7 | filters: { 8 | color: { 9 | any: ["Black", "Orange"] 10 | } 11 | } 12 | })); 13 | - step: In my browser, the console should be empty 14 | - step: In my browser, I evaluate {js} 15 | js: >- 16 | let val = await toolproof.querySelector("[data-results]"); 17 | 18 | toolproof.assert_eq(val.innerHTML, `/cheeka/, /smudge/, /theodore/, 19 | /treacle/`); 20 | -------------------------------------------------------------------------------- /pagefind/integration_tests/compound_filtering/filtering-with-an-exclusion.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: Filtering > Filtering with an exclusion 2 | steps: 3 | - ref: ./background.toolproof.yml 4 | - step: In my browser, I evaluate {js} 5 | js: |- 6 | await test(pagefind.search("Cat", { 7 | filters: { 8 | color: { 9 | any: ["Black", "Orange"] 10 | }, 11 | mood: { 12 | not: "Lazy" 13 | } 14 | } 15 | })); 16 | - step: In my browser, the console should be empty 17 | - step: In my browser, I evaluate {js} 18 | js: |- 19 | let val = await toolproof.querySelector("[data-results]"); 20 | toolproof.assert_eq(val.innerHTML, `/smudge/, /theodore/`); 21 | -------------------------------------------------------------------------------- /pagefind/integration_tests/compound_filtering/filtering-with-top-level-exclusion.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: Filtering > Filtering with top-level exclusion 2 | steps: 3 | - ref: ./background.toolproof.yml 4 | - step: In my browser, I evaluate {js} 5 | js: |- 6 | await test(pagefind.search("Cat", { 7 | filters: { 8 | none: [ 9 | { 10 | color: { 11 | any: ["Orange", "White"] 12 | } 13 | }, 14 | { 15 | mood: "Angry" 16 | } 17 | ] 18 | } 19 | })); 20 | - step: In my browser, the console should be empty 21 | - step: In my browser, I evaluate {js} 22 | js: |- 23 | let val = await toolproof.querySelector("[data-results]"); 24 | toolproof.assert_eq(val.innerHTML, `/grey/`); 25 | -------------------------------------------------------------------------------- /pagefind/integration_tests/config_sources/settings-can-be-pulled-from-command-line-flags.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: Config Sources > Settings can be pulled from command-line flags 2 | steps: 3 | - step: I have a "public/index.html" file with the content {html} 4 | html: >- 5 |

Hello.

7 | - macro: I run Pagefind with "--site public" 8 | - step: stdout should contain "Running Pagefind" 9 | - step: The file "public/pagefind/pagefind.js" should not be empty 10 | -------------------------------------------------------------------------------- /pagefind/integration_tests/config_sources/settings-can-be-pulled-from-environment-variables.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: Config Sources > Settings can be pulled from environment variables 2 | steps: 3 | - step: I have a "public/index.html" file with the content {html} 4 | html: >- 5 |

Hello.

7 | - step: I have the environment variable "PAGEFIND_SITE" set to "public" 8 | - macro: I run Pagefind 9 | - step: stdout should contain "Running Pagefind" 10 | - step: The file "public/pagefind/pagefind.js" should not be empty 11 | -------------------------------------------------------------------------------- /pagefind/integration_tests/config_sources/settings-can-be-pulled-from-json-configuration-files.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: Config Sources > Settings can be pulled from JSON configuration files 2 | steps: 3 | - step: I have a "public/index.html" file with the content {html} 4 | html: >- 5 |

Hello.

7 | - step: I have a "pagefind.json" file with the content {json} 8 | json: |- 9 | { 10 | "site": "public" 11 | } 12 | - macro: I run Pagefind 13 | - step: stdout should contain "Running Pagefind" 14 | - step: The file "public/pagefind/pagefind.js" should not be empty 15 | -------------------------------------------------------------------------------- /pagefind/integration_tests/config_sources/settings-can-be-pulled-from-multiple-sources.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: Config Sources > Settings can be pulled from multiple sources 2 | steps: 3 | - step: I have a "public/index.html" file with the content {html} 4 | html: >- 5 |

Hello.

7 | - step: I have a "pagefind.json" file with the content {json} 8 | json: |- 9 | { 10 | "site": "public" 11 | } 12 | - macro: I run Pagefind with "--output-subdir _out" 13 | - step: stdout should contain "Running Pagefind" 14 | - step: The file "public/_out/pagefind.js" should not be empty 15 | -------------------------------------------------------------------------------- /pagefind/integration_tests/config_sources/settings-can-be-pulled-from-toml-configuration-files.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: Config Sources > Settings can be pulled from TOML configuration files 2 | steps: 3 | - step: I have a "public/index.html" file with the content {html} 4 | html: >- 5 |

Hello.

7 | - step: I have a "pagefind.toml" file with the content {toml} 8 | toml: site = "public" 9 | - macro: I run Pagefind 10 | - step: stdout should contain "Running Pagefind" 11 | - step: The file "public/pagefind/pagefind.js" should not be empty 12 | -------------------------------------------------------------------------------- /pagefind/integration_tests/config_sources/settings-can-be-pulled-from-yaml-configuration-files.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: Config Sources > Settings can be pulled from YAML configuration files 2 | steps: 3 | - step: I have a "public/index.html" file with the content {html} 4 | html: >- 5 |

Hello.

7 | - step: I have a "pagefind.yml" file with the content {yml} 8 | yml: "site: public" 9 | - macro: I run Pagefind 10 | - step: stdout should contain "Running Pagefind" 11 | - step: The file "public/pagefind/pagefind.js" should not be empty 12 | -------------------------------------------------------------------------------- /pagefind/integration_tests/debounce/background.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: debounce > Debounced Searches > Background 2 | type: reference 3 | steps: 4 | - step: I have the environment variable "PAGEFIND_SITE" set to "public" 5 | - step: I have a "public/index.html" file with the content {html} 6 | html: >- 7 |

Nothing

9 | 10 |

Nothing

11 | -------------------------------------------------------------------------------- /pagefind/integration_tests/edge_cases/background.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: edge_cases > Graceful Pagefind Errors > Background 2 | type: reference 3 | steps: 4 | - step: I have the environment variable "PAGEFIND_SITE" set to "public" 5 | - step: I have a "public/index.html" file with the content {html} 6 | html: >- 7 |

Nothing

9 | -------------------------------------------------------------------------------- /pagefind/integration_tests/exact_phrase/background.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: exact_phrase > Exact Phrase Matching > Background 2 | type: reference 3 | steps: 4 | - step: I have the environment variable "PAGEFIND_SITE" set to "public" 5 | - step: I have a "public/index.html" file with the content {html} 6 | html: >- 7 |

Nothing

9 | 10 |

Nothing

11 | -------------------------------------------------------------------------------- /pagefind/integration_tests/exclusions/background.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: exclusions > Exclusions > Background 2 | type: reference 3 | steps: 4 | - step: I have the environment variable "PAGEFIND_SITE" set to "public" 5 | -------------------------------------------------------------------------------- /pagefind/integration_tests/filtering/all-results-are-returned-with-no-filters.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: Filtering > All results are returned with no filters 2 | steps: 3 | - ref: ./background.toolproof.yml 4 | - step: In my browser, I evaluate {js} 5 | js: >- 6 | let pagefind = await import("/pagefind/pagefind.js"); 7 | 8 | 9 | let search = await pagefind.search("Cat"); 10 | 11 | let data = await Promise.all(search.results.map(result => result.data())); 12 | 13 | 14 | document.querySelector('[data-results]').innerText = data.map(d => 15 | d.url).sort().join(', '); 16 | - step: In my browser, the console should be empty 17 | - step: In my browser, I evaluate {js} 18 | js: |- 19 | let val = await toolproof.querySelector("[data-results]"); 20 | toolproof.assert_eq(val.innerHTML, `/ali/, /cheeka/, /theodore/`); 21 | -------------------------------------------------------------------------------- /pagefind/integration_tests/filtering/filter-counts-are-returned-for-a-given-search-term.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: Filtering > Filter counts are returned for a given search term 2 | steps: 3 | - ref: ./background.toolproof.yml 4 | - step: In my browser, I evaluate {js} 5 | js: |- 6 | let pagefind = await import("/pagefind/pagefind.js"); 7 | 8 | await pagefind.filters(); // Load filters 9 | let search = await pagefind.search("Ali"); 10 | let strings = Object.entries(search.filters).map(([filter, values]) => { 11 | values = Object.entries(values).map(([value, count]) => { 12 | return `${value}(${count})`; 13 | }) 14 | return `${filter}:[${values.join(", ")}]`; 15 | }); 16 | 17 | document.querySelector('[data-results]').innerText = strings.join(' '); 18 | - step: In my browser, the console should be empty 19 | - step: In my browser, I evaluate {js} 20 | js: >- 21 | let val = await toolproof.querySelector("[data-results]"); 22 | 23 | toolproof.assert_eq(val.innerHTML, `color:[Black(0), Orange(0), Tabby(1), 24 | White(0)] mood:[Angry(1)]`); 25 | -------------------------------------------------------------------------------- /pagefind/integration_tests/filtering/filtering-on-a-search-term-with-no-results-returns-nothing.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: Filtering > Filtering on a search term with no results returns nothing 2 | steps: 3 | - ref: ./background.toolproof.yml 4 | - step: In my browser, I evaluate {js} 5 | js: >- 6 | let pagefind = await import("/pagefind/pagefind.js"); 7 | 8 | 9 | let search = await pagefind.search("Pontification", { 10 | filters: { 11 | color: "Orange" 12 | } 13 | }); 14 | 15 | 16 | document.querySelector('[data-results]').innerText = 17 | search.results.length; 18 | - step: In my browser, the console should be empty 19 | - step: In my browser, I evaluate {js} 20 | js: |- 21 | let val = await toolproof.querySelector("[data-results]"); 22 | toolproof.assert_eq(val.innerHTML, `0`); 23 | -------------------------------------------------------------------------------- /pagefind/integration_tests/filtering/filtering-on-tagged-elements.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: Filtering > Filtering on tagged elements 2 | steps: 3 | - ref: ./background.toolproof.yml 4 | - step: In my browser, I evaluate {js} 5 | js: >- 6 | let pagefind = await import("/pagefind/pagefind.js"); 7 | 8 | 9 | let search = await pagefind.search("Cat", { 10 | filters: { 11 | color: "Orange" 12 | } 13 | }); 14 | 15 | let data = await Promise.all(search.results.map(result => result.data())); 16 | 17 | 18 | document.querySelector('[data-results]').innerText = data.map(d => 19 | d.url).sort().join(', '); 20 | - step: In my browser, the console should be empty 21 | - step: In my browser, I evaluate {js} 22 | js: |- 23 | let val = await toolproof.querySelector("[data-results]"); 24 | toolproof.assert_eq(val.innerHTML, `/theodore/`); 25 | -------------------------------------------------------------------------------- /pagefind/integration_tests/filtering/filtering-on-tagged-values.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: Filtering > Filtering on tagged values 2 | steps: 3 | - ref: ./background.toolproof.yml 4 | - step: In my browser, I evaluate {js} 5 | js: >- 6 | let pagefind = await import("/pagefind/pagefind.js"); 7 | 8 | 9 | let search = await pagefind.search("Cat", { 10 | filters: { 11 | color: "Tabby" 12 | } 13 | }); 14 | 15 | let data = await Promise.all(search.results.map(result => result.data())); 16 | 17 | 18 | document.querySelector('[data-results]').innerText = data.map(d => 19 | d.url).sort().join(', '); 20 | - step: In my browser, the console should be empty 21 | - step: In my browser, I evaluate {js} 22 | js: |- 23 | let val = await toolproof.querySelector("[data-results]"); 24 | toolproof.assert_eq(val.innerHTML, `/ali/`); 25 | -------------------------------------------------------------------------------- /pagefind/integration_tests/filtering/filtering-returns-multiple-results.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: Filtering > Filtering returns multiple results 2 | steps: 3 | - ref: ./background.toolproof.yml 4 | - step: In my browser, I evaluate {js} 5 | js: >- 6 | let pagefind = await import("/pagefind/pagefind.js"); 7 | 8 | 9 | let search = await pagefind.search("Cat", { 10 | filters: { 11 | color: "White" 12 | } 13 | }); 14 | 15 | let data = await Promise.all(search.results.map(result => result.data())); 16 | 17 | 18 | document.querySelector('[data-results]').innerText = data.map(d => 19 | d.url).sort().join(', '); 20 | - step: In my browser, the console should be empty 21 | - step: In my browser, I evaluate {js} 22 | js: |- 23 | let val = await toolproof.querySelector("[data-results]"); 24 | toolproof.assert_eq(val.innerHTML, `/cheeka/, /theodore/`); 25 | -------------------------------------------------------------------------------- /pagefind/integration_tests/filtering/filtering-with-an--empty--bogus-filter-does-nothing.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: Filtering > Filtering with an _empty_ bogus filter does nothing 2 | steps: 3 | - ref: ./background.toolproof.yml 4 | - step: In my browser, I evaluate {js} 5 | js: >- 6 | let pagefind = await import("/pagefind/pagefind.js"); 7 | 8 | 9 | let search = await pagefind.search("Cat", { 10 | filters: { 11 | something_nonexistent: [] 12 | } 13 | }); 14 | 15 | let data = await Promise.all(search.results.map(result => result.data())); 16 | 17 | 18 | document.querySelector('[data-results]').innerText = data.map(d => 19 | d.url).sort().join(', '); 20 | - step: In my browser, the console should be empty 21 | - step: In my browser, I evaluate {js} 22 | js: |- 23 | let val = await toolproof.querySelector("[data-results]"); 24 | toolproof.assert_eq(val.innerHTML, `/ali/, /cheeka/, /theodore/`); 25 | -------------------------------------------------------------------------------- /pagefind/integration_tests/filtering/filtering-with-an-empty-array-returns-all-results.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: Filtering > Filtering with an empty array returns all results 2 | steps: 3 | - ref: ./background.toolproof.yml 4 | - step: In my browser, I evaluate {js} 5 | js: >- 6 | let pagefind = await import("/pagefind/pagefind.js"); 7 | 8 | 9 | let search = await pagefind.search("Cat", { 10 | filters: { 11 | color: [] 12 | } 13 | }); 14 | 15 | let data = await Promise.all(search.results.map(result => result.data())); 16 | 17 | 18 | document.querySelector('[data-results]').innerText = data.map(d => 19 | d.url).sort().join(', '); 20 | - step: In my browser, the console should be empty 21 | - step: In my browser, I evaluate {js} 22 | js: |- 23 | let val = await toolproof.querySelector("[data-results]"); 24 | toolproof.assert_eq(val.innerHTML, `/ali/, /cheeka/, /theodore/`); 25 | -------------------------------------------------------------------------------- /pagefind/integration_tests/filtering/filtering-without-search-term-returns-an-unprocessed-excerpt.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: Filtering > Filtering without search term returns an unprocessed excerpt 2 | steps: 3 | - ref: ./background.toolproof.yml 4 | - step: In my browser, I evaluate {js} 5 | js: >- 6 | let pagefind = await import("/pagefind/pagefind.js"); 7 | 8 | 9 | // Run a search so that some index words are loaded 10 | 11 | let unused = await pagefind.search("cat"); 12 | 13 | 14 | let search = await pagefind.search(null, { 15 | filters: { 16 | color: ["Black", "White"] 17 | } 18 | }); 19 | 20 | let data = await Promise.all(search.results.map(result => result.data())); 21 | 22 | 23 | document.querySelector('[data-results]').innerText = data.map(d => 24 | d.excerpt).join(', '); 25 | - step: In my browser, the console should be empty 26 | - step: In my browser, I evaluate {js} 27 | js: |- 28 | let val = await toolproof.querySelector("[data-results]"); 29 | toolproof.assert_eq(val.innerHTML, `Black White Cat.`); 30 | -------------------------------------------------------------------------------- /pagefind/integration_tests/filtering/filtering-without-search-term-returns-only-filter.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: Filtering > Filtering without search term returns only filter 2 | steps: 3 | - ref: ./background.toolproof.yml 4 | - step: In my browser, I evaluate {js} 5 | js: >- 6 | let pagefind = await import("/pagefind/pagefind.js"); 7 | 8 | 9 | let search = await pagefind.search(null, { 10 | filters: { 11 | color: "White" 12 | } 13 | }); 14 | 15 | let data = await Promise.all(search.results.map(result => result.data())); 16 | 17 | 18 | document.querySelector('[data-results]').innerText = data.map(d => 19 | d.url).sort().join(', '); 20 | - step: In my browser, the console should be empty 21 | - step: In my browser, I evaluate {js} 22 | js: |- 23 | let val = await toolproof.querySelector("[data-results]"); 24 | toolproof.assert_eq(val.innerHTML, `/cheeka/, /theodore/`); 25 | -------------------------------------------------------------------------------- /pagefind/integration_tests/filtering/filters-can-be-retrieved.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: Filtering > Filters can be retrieved 2 | steps: 3 | - ref: ./background.toolproof.yml 4 | - step: In my browser, I evaluate {js} 5 | js: |- 6 | let pagefind = await import("/pagefind/pagefind.js"); 7 | 8 | let filters = await pagefind.filters(); 9 | let strings = Object.entries(filters).map(([filter, values]) => { 10 | values = Object.entries(values).map(([value, count]) => { 11 | return `${value}(${count})`; 12 | }) 13 | return `${filter}:[${values.join(", ")}]`; 14 | }); 15 | 16 | document.querySelector('[data-results]').innerText = strings.join(' '); 17 | - step: In my browser, the console should be empty 18 | - step: In my browser, I evaluate {js} 19 | js: >- 20 | let val = await toolproof.querySelector("[data-results]"); 21 | 22 | toolproof.assert_eq(val.innerHTML, `color:[Black(1), Orange(1), Tabby(1), 23 | White(2)] mood:[Angry(1)]`); 24 | -------------------------------------------------------------------------------- /pagefind/integration_tests/filtering/non-existent-filters-return-no-results.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: Filtering > Non-existent filters return no results 2 | steps: 3 | - ref: ./background.toolproof.yml 4 | - step: In my browser, I evaluate {js} 5 | js: >- 6 | let pagefind = await import("/pagefind/pagefind.js"); 7 | 8 | 9 | let search = await pagefind.search("Cat", { 10 | filters: { 11 | name: "Ali" 12 | } 13 | }); 14 | 15 | 16 | document.querySelector('[data-results]').innerText = 17 | search.results.length; 18 | - step: In my browser, the console should be empty 19 | - step: In my browser, I evaluate {js} 20 | js: |- 21 | let val = await toolproof.querySelector("[data-results]"); 22 | toolproof.assert_eq(val.innerHTML, `0`); 23 | -------------------------------------------------------------------------------- /pagefind/integration_tests/filtering/non-existent-values-return-no-results.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: Filtering > Non-existent values return no results 2 | steps: 3 | - ref: ./background.toolproof.yml 4 | - step: In my browser, I evaluate {js} 5 | js: >- 6 | let pagefind = await import("/pagefind/pagefind.js"); 7 | 8 | 9 | let search = await pagefind.search("Cat", { 10 | filters: { 11 | color: "Green" 12 | } 13 | }); 14 | 15 | 16 | document.querySelector('[data-results]').innerText = 17 | search.results.length; 18 | - step: In my browser, the console should be empty 19 | - step: In my browser, I evaluate {js} 20 | js: |- 21 | let val = await toolproof.querySelector("[data-results]"); 22 | toolproof.assert_eq(val.innerHTML, `0`); 23 | -------------------------------------------------------------------------------- /pagefind/integration_tests/filtering/total-filter-counts-are-returned-for-a-given-search-term.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: Filtering > Total filter counts are returned for a given search term 2 | steps: 3 | - ref: ./background.toolproof.yml 4 | - step: In my browser, I evaluate {js} 5 | js: >- 6 | let pagefind = await import("/pagefind/pagefind.js"); 7 | 8 | 9 | await pagefind.filters(); // Load filters 10 | 11 | let search = await pagefind.search("Cat", { 12 | filters: { 13 | color: "White" 14 | } 15 | }); 16 | 17 | let strings = Object.entries(search.totalFilters).map(([filter, values]) 18 | => { 19 | values = Object.entries(values).map(([value, count]) => { 20 | return `${value}(${count})`; 21 | }) 22 | return `${filter}:[${values.join(", ")}]`; 23 | }); 24 | 25 | 26 | document.querySelector('[data-results]').innerText = strings.join(' '); 27 | - step: In my browser, the console should be empty 28 | - step: In my browser, I evaluate {js} 29 | js: >- 30 | let val = await toolproof.querySelector("[data-results]"); 31 | 32 | toolproof.assert_eq(val.innerHTML, `color:[Black(1), Orange(1), Tabby(1), 33 | White(2)] mood:[Angry(1)]`); 34 | -------------------------------------------------------------------------------- /pagefind/integration_tests/filtering/total-unfiltered-result-counts-are-given-for-a-filtered-search-term.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: >- 2 | Filtering > Total unfiltered result counts are given for a filtered search 3 | term 4 | steps: 5 | - ref: ./background.toolproof.yml 6 | - step: In my browser, I evaluate {js} 7 | js: >- 8 | let pagefind = await import("/pagefind/pagefind.js"); 9 | 10 | 11 | await pagefind.filters(); // Load filters 12 | 13 | let search = await pagefind.search("Ali", { 14 | filters: { 15 | color: "Orange" 16 | } 17 | }); 18 | 19 | document.querySelector('[data-results]').innerText = 20 | `results:${search.results.length} total:${search.unfilteredResultCount}`; 21 | - step: In my browser, the console should be empty 22 | - step: In my browser, I evaluate {js} 23 | js: |- 24 | let val = await toolproof.querySelector("[data-results]"); 25 | toolproof.assert_eq(val.innerHTML, `results:0 total:1`); 26 | -------------------------------------------------------------------------------- /pagefind/integration_tests/frozen-pre-1.0/base/background.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: frozen-pre-1.0/base > Base Tests > Background 2 | type: reference 3 | steps: 4 | - step: I have the environment variable "PAGEFIND_SOURCE" set to "public" 5 | - step: I have a "public/index.html" file with the content {html} 6 | html: >- 7 |

Nothing

9 | -------------------------------------------------------------------------------- /pagefind/integration_tests/frozen-pre-1.0/base/legacy-search-for-a-word.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: Base Tests > LEGACY Search for a word 2 | steps: 3 | - ref: ./background.toolproof.yml 4 | - step: I have a "public/cat/index.html" file with the content {html} 5 | html: >- 6 | 8 | 9 |

world

10 | - macro: I run Pagefind 11 | - step: stdout should contain "Running Pagefind" 12 | - step: stderr should contain "pre-1.0 compatibility mode" 13 | - step: The file "public/_pagefind/pagefind.js" should not be empty 14 | - step: I serve the directory "public" 15 | - step: In my browser, I load "/" 16 | - step: In my browser, I evaluate {js} 17 | js: |- 18 | let pagefind = await import("/_pagefind/pagefind.js"); 19 | 20 | let search = await pagefind.search("world"); 21 | 22 | let data = await search.results[0].data(); 23 | document.querySelector('[data-url]').innerText = data.url; 24 | - step: In my browser, the console should be empty 25 | - step: In my browser, I evaluate {js} 26 | js: |- 27 | let val = await toolproof.querySelector("[data-url]"); 28 | toolproof.assert_eq(val.innerHTML, `/cat/`); 29 | -------------------------------------------------------------------------------- /pagefind/integration_tests/frozen-pre-1.0/build_options/background.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: frozen-pre-1.0/build_options > Build Options > Background 2 | type: reference 3 | steps: 4 | - step: I have the environment variable "PAGEFIND_SOURCE" set to "public" 5 | -------------------------------------------------------------------------------- /pagefind/integration_tests/frozen-pre-1.0/config_sources/legacy-settings-can-be-pulled-from-command-line-flags.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: Config Sources > LEGACY Settings can be pulled from command-line flags 2 | steps: 3 | - step: I have a "public/index.html" file with the content {html} 4 | html: >- 5 | 7 | 8 |

Hello.

9 | - macro: I run Pagefind with "--source public" 10 | - step: stdout should contain "Running Pagefind" 11 | - step: stderr should contain "pre-1.0 compatibility mode" 12 | - step: The file "public/_pagefind/pagefind.js" should not be empty 13 | -------------------------------------------------------------------------------- /pagefind/integration_tests/frozen-pre-1.0/config_sources/legacy-settings-can-be-pulled-from-environment-variables.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: Config Sources > LEGACY Settings can be pulled from environment variables 2 | steps: 3 | - step: I have a "public/index.html" file with the content {html} 4 | html: >- 5 | 7 | 8 |

Hello.

9 | - step: I have the environment variable "PAGEFIND_SOURCE" set to "public" 10 | - macro: I run Pagefind 11 | - step: stdout should contain "Running Pagefind" 12 | - step: stderr should contain "pre-1.0 compatibility mode" 13 | - step: The file "public/_pagefind/pagefind.js" should not be empty 14 | -------------------------------------------------------------------------------- /pagefind/integration_tests/frozen-pre-1.0/config_sources/legacy-settings-can-be-pulled-from-json-configuration-files.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: Config Sources > LEGACY Settings can be pulled from JSON configuration files 2 | steps: 3 | - step: I have a "public/index.html" file with the content {html} 4 | html: >- 5 | 7 | 8 |

Hello.

9 | - step: I have a "pagefind.json" file with the content {json} 10 | json: |- 11 | { 12 | "source": "public" 13 | } 14 | - macro: I run Pagefind 15 | - step: stdout should contain "Running Pagefind" 16 | - step: stderr should contain "pre-1.0 compatibility mode" 17 | - step: The file "public/_pagefind/pagefind.js" should not be empty 18 | -------------------------------------------------------------------------------- /pagefind/integration_tests/frozen-pre-1.0/config_sources/legacy-settings-can-be-pulled-from-multiple-sources.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: Config Sources > LEGACY Settings can be pulled from multiple sources 2 | steps: 3 | - step: I have a "public/index.html" file with the content {html} 4 | html: >- 5 | 7 | 8 |

Hello.

9 | - step: I have a "pagefind.json" file with the content {json} 10 | json: |- 11 | { 12 | "source": "public" 13 | } 14 | - macro: I run Pagefind with "--bundle-dir _out" 15 | - step: stdout should contain "Running Pagefind" 16 | - step: The file "public/_out/pagefind.js" should not be empty 17 | -------------------------------------------------------------------------------- /pagefind/integration_tests/frozen-pre-1.0/config_sources/legacy-settings-can-be-pulled-from-toml-configuration-files.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: Config Sources > LEGACY Settings can be pulled from TOML configuration files 2 | steps: 3 | - step: I have a "public/index.html" file with the content {html} 4 | html: >- 5 | 7 | 8 |

Hello.

9 | - step: I have a "pagefind.toml" file with the content {toml} 10 | toml: source = "public" 11 | - macro: I run Pagefind 12 | - step: stdout should contain "Running Pagefind" 13 | - step: stderr should contain "pre-1.0 compatibility mode" 14 | - step: The file "public/_pagefind/pagefind.js" should not be empty 15 | -------------------------------------------------------------------------------- /pagefind/integration_tests/frozen-pre-1.0/config_sources/legacy-settings-can-be-pulled-from-yaml-configuration-files.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: Config Sources > LEGACY Settings can be pulled from YAML configuration files 2 | steps: 3 | - step: I have a "public/index.html" file with the content {html} 4 | html: >- 5 | 7 | 8 |

Hello.

9 | - step: I have a "pagefind.yml" file with the content {yml} 10 | yml: 'source: public' 11 | - macro: I run Pagefind 12 | - step: stdout should contain "Running Pagefind" 13 | - step: stderr should contain "pre-1.0 compatibility mode" 14 | - step: The file "public/_pagefind/pagefind.js" should not be empty 15 | -------------------------------------------------------------------------------- /pagefind/integration_tests/frozen-pre-1.0/modular_ui/modular_ui_base/background.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: frozen-pre-1.0/modular_ui/modular_ui_base > Base Modular UI Tests > Background 2 | type: reference 3 | steps: 4 | - step: I have the environment variable "PAGEFIND_SOURCE" set to "public" 5 | - step: I have a "public/index.html" file with the content {html} 6 | html: |- 7 | 8 |
9 |
10 | 11 | 12 | 24 | -------------------------------------------------------------------------------- /pagefind/integration_tests/frozen-pre-1.0/modular_ui/modular_ui_base/legacy-pagefind-modular-ui-loads.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: Base Modular UI Tests > LEGACY Pagefind Modular UI loads 2 | steps: 3 | - ref: ./background.toolproof.yml 4 | - step: I have a "public/cat/index.html" file with the content {html} 5 | html: >- 6 |

world

8 | - macro: I run Pagefind 9 | - step: stdout should contain "Running Pagefind" 10 | - step: stderr should contain "pre-1.0 compatibility mode" 11 | - step: The file "public/_pagefind/pagefind.js" should not be empty 12 | - step: I serve the directory "public" 13 | - step: In my browser, I load "/" 14 | - step: In my browser, the console should be empty 15 | - step: In my browser, I evaluate {js} 16 | js: |- 17 | let el = await toolproof.querySelector("#search input"); 18 | toolproof.assert(el); 19 | -------------------------------------------------------------------------------- /pagefind/integration_tests/frozen-pre-1.0/modular_ui/modular_ui_base/legacy-pagefind-modular-ui-searches.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: Base Modular UI Tests > LEGACY Pagefind Modular UI searches 2 | steps: 3 | - ref: ./background.toolproof.yml 4 | - step: I have a "public/cat/index.html" file with the content {html} 5 | html: >- 6 |

world

8 | - macro: I run Pagefind 9 | - step: stdout should contain "Running Pagefind" 10 | - step: stderr should contain "pre-1.0 compatibility mode" 11 | - step: The file "public/_pagefind/pagefind.js" should not be empty 12 | - step: I serve the directory "public" 13 | - step: In my browser, I load "/" 14 | - step: In my browser, I evaluate {js} 15 | js: |- 16 | let e = new Event('input', {bubbles:true, cancelable:true}); 17 | document.querySelector("#search input").value = "world"; 18 | document.querySelector("#search input").dispatchEvent(e); 19 | - step: In my browser, the console should be empty 20 | - step: In my browser, I evaluate {js} 21 | js: |- 22 | let val = await toolproof.querySelector(".pagefind-modular-list-link"); 23 | toolproof.assert_eq(val.innerHTML, `world`); 24 | -------------------------------------------------------------------------------- /pagefind/integration_tests/frozen-pre-1.0/multilingual/background.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: frozen-pre-1.0/multilingual > Multilingual > Background 2 | type: reference 3 | steps: 4 | - step: I have the environment variable "PAGEFIND_SOURCE" set to "public" 5 | - step: I have a "public/en/index.html" file with the content {html} 6 | html: |- 7 | 8 | 9 | 10 | Document 11 | 12 | 13 | 14 |

I am some English documentation

15 | 16 | 17 | - step: I have a "public/pt-br/index.html" file with the content {html} 18 | html: |- 19 | 20 | 21 | 22 | Document 23 | 24 | 25 |

I am a Portuguese document (trust me — quilométricas — see?)

26 | 27 | 28 | -------------------------------------------------------------------------------- /pagefind/integration_tests/frozen-pre-1.0/multisite/multisite_base/background.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: frozen-pre-1.0/multisite/multisite_base > Multisite Search > Background 2 | type: reference 3 | steps: 4 | - step: I have a "root/index.html" file with the content {html} 5 | html: >- 6 |

Nothing

8 | - step: I have a "root/website_a/hello/index.html" file with the content {html} 9 | html: >- 10 | 12 | 13 |

web web world PAGEFIND_ROOT_SELECTOR

14 | - step: I have a "root/website_b/lorem/index.html" file with the content {html} 15 | html: >- 16 | 18 | 19 |

web ipsum

20 | -------------------------------------------------------------------------------- /pagefind/integration_tests/frozen-pre-1.0/sanity/legacy-cli-tests-are-working.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: Sanity Tests > LEGACY CLI tests are working 2 | steps: 3 | - step: I have a "public/index.html" file with the content {html} 4 | html: >- 5 | 7 |

Nothing

8 | - macro: I run Pagefind with "--source public" 9 | - step: stdout should contain "Running Pagefind" 10 | - step: stderr should contain "pre-1.0 compatibility mode" 11 | - step: stderr should contain "The `source` option is deprecated" 12 | -------------------------------------------------------------------------------- /pagefind/integration_tests/frozen-pre-1.0/sanity/legacy-web-tests-are-working.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: Sanity Tests > LEGACY Web tests are working 2 | steps: 3 | - step: I have a "public/index.html" file with the content {html} 4 | html: >- 5 |

Hello!

7 | - step: I serve the directory "public" 8 | - step: In my browser, I load "/" 9 | - step: In my browser, I evaluate {js} 10 | js: |- 11 | let val = await toolproof.querySelector("h1"); 12 | toolproof.assert_eq(val.innerHTML, `Hello!`); 13 | -------------------------------------------------------------------------------- /pagefind/integration_tests/frozen-pre-1.0/search_options/background.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: frozen-pre-1.0/search_options > Search Options > Background 2 | type: reference 3 | steps: 4 | - step: I have the environment variable "PAGEFIND_SOURCE" set to "public" 5 | -------------------------------------------------------------------------------- /pagefind/integration_tests/frozen-pre-1.0/ui/ui_base/background.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: frozen-pre-1.0/ui/ui_base > Base UI Tests > Background 2 | type: reference 3 | steps: 4 | - step: I have the environment variable "PAGEFIND_SOURCE" set to "public" 5 | - step: I have a "public/index.html" file with the content {html} 6 | html: |- 7 | 8 | 9 | 10 | 13 | -------------------------------------------------------------------------------- /pagefind/integration_tests/frozen-pre-1.0/ui/ui_base/legacy-pagefind-ui-loads.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: Base UI Tests > LEGACY Pagefind UI loads 2 | steps: 3 | - ref: ./background.toolproof.yml 4 | - step: I have a "public/cat/index.html" file with the content {html} 5 | html: >- 6 |

world

8 | - macro: I run Pagefind 9 | - step: stdout should contain "Running Pagefind" 10 | - step: stderr should contain "pre-1.0 compatibility mode" 11 | - step: The file "public/_pagefind/pagefind.js" should not be empty 12 | - step: I serve the directory "public" 13 | - step: In my browser, I load "/" 14 | - step: In my browser, the console should be empty 15 | - step: In my browser, I evaluate {js} 16 | js: |- 17 | let el = await toolproof.querySelector(".pagefind-ui"); 18 | toolproof.assert(el); 19 | -------------------------------------------------------------------------------- /pagefind/integration_tests/frozen-pre-1.0/ui/ui_base/legacy-pagefind-ui-searches.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: Base UI Tests > LEGACY Pagefind UI searches 2 | steps: 3 | - ref: ./background.toolproof.yml 4 | - step: I have a "public/cat/index.html" file with the content {html} 5 | html: >- 6 |

world

8 | - macro: I run Pagefind 9 | - step: stdout should contain "Running Pagefind" 10 | - step: stderr should contain "pre-1.0 compatibility mode" 11 | - step: The file "public/_pagefind/pagefind.js" should not be empty 12 | - step: I serve the directory "public" 13 | - step: In my browser, I load "/" 14 | - step: In my browser, I evaluate {js} 15 | js: window.pui.triggerSearch("world"); 16 | - step: In my browser, the console should be empty 17 | - step: In my browser, I evaluate {js} 18 | js: |- 19 | let val = await toolproof.querySelector(".pagefind-ui__result-link"); 20 | toolproof.assert_eq(val.innerHTML, `world`); 21 | -------------------------------------------------------------------------------- /pagefind/integration_tests/highlighting/highlighting_results/highlight-script-is-loaded.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: Highlighting Result Tests > Highlight script is loaded 2 | steps: 3 | - ref: ./background.toolproof.yml 4 | - step: In my browser, I load "/words/" 5 | - step: In my browser, I evaluate {js} 6 | js: await new Promise(r => setTimeout(r, 200)); 7 | - step: The file "public/pagefind/pagefind-highlight.js" should not be empty 8 | - step: In my browser, the console should be empty 9 | -------------------------------------------------------------------------------- /pagefind/integration_tests/highlighting/highlighting_search/background.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: highlighting/highlighting_search > Highlighting Search Tests > Background 2 | type: reference 3 | steps: 4 | - step: I have the environment variable "PAGEFIND_SITE" set to "public" 5 | - step: I have a "public/index.html" file with the content {html} 6 | html: >- 7 |

Nothing

9 | - step: I have a "public/a/index.html" file with the content {html} 10 | html: >- 11 |

Hello 12 | World

13 | - step: I have a "public/b/index.html" file with the content {html} 14 | html: >- 15 |

Second

17 | 18 |

Second Page

19 | -------------------------------------------------------------------------------- /pagefind/integration_tests/highlighting/highlighting_search/multiple-query-parameters-are-inserted-through-the-js-api.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: >- 2 | Highlighting Search Tests > Multiple query parameters are inserted through the 3 | JS API 4 | steps: 5 | - ref: ./background.toolproof.yml 6 | - macro: I run Pagefind 7 | - step: stdout should contain "Running Pagefind" 8 | - step: The file "public/pagefind/pagefind.js" should not be empty 9 | - step: I serve the directory "public" 10 | - step: In my browser, I load "/" 11 | - step: In my browser, I evaluate {js} 12 | js: |- 13 | let pagefind = await import("/pagefind/pagefind.js"); 14 | await pagefind.options({ highlightParam: "hi" }); 15 | 16 | let search = await pagefind.search("hello world"); 17 | 18 | let data = await search.results[0].data(); 19 | document.querySelector('[data-url]').innerText = data.url; 20 | - step: In my browser, the console should be empty 21 | - step: In my browser, I evaluate {js} 22 | js: |- 23 | let val = await toolproof.querySelector("[data-url]"); 24 | toolproof.assert_eq(val.innerHTML, `/a/?hi=hello&hi=world`); 25 | -------------------------------------------------------------------------------- /pagefind/integration_tests/highlighting/highlighting_search/query-parameters-can-be-inserted-through-the-js-api.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: >- 2 | Highlighting Search Tests > Query parameters can be inserted through the JS 3 | API 4 | steps: 5 | - ref: ./background.toolproof.yml 6 | - macro: I run Pagefind 7 | - step: stdout should contain "Running Pagefind" 8 | - step: The file "public/pagefind/pagefind.js" should not be empty 9 | - step: I serve the directory "public" 10 | - step: In my browser, I load "/" 11 | - step: In my browser, I evaluate {js} 12 | js: |- 13 | let pagefind = await import("/pagefind/pagefind.js"); 14 | await pagefind.options({ highlightParam: "hi" }); 15 | 16 | let search = await pagefind.search("world"); 17 | 18 | let data = await search.results[0].data(); 19 | document.querySelector('[data-url]').innerText = data.url; 20 | - step: In my browser, the console should be empty 21 | - step: In my browser, I evaluate {js} 22 | js: |- 23 | let val = await toolproof.querySelector("[data-url]"); 24 | toolproof.assert_eq(val.innerHTML, `/a/?hi=world`); 25 | -------------------------------------------------------------------------------- /pagefind/integration_tests/highlighting/highlighting_search/query-parameters-don-t-conflict-with-subresult-anchors.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: >- 2 | Highlighting Search Tests > Query parameters don't conflict with subresult 3 | anchors 4 | steps: 5 | - ref: ./background.toolproof.yml 6 | - macro: I run Pagefind 7 | - step: stdout should contain "Running Pagefind" 8 | - step: The file "public/pagefind/pagefind.js" should not be empty 9 | - step: I serve the directory "public" 10 | - step: In my browser, I load "/" 11 | - step: In my browser, I evaluate {js} 12 | js: |- 13 | let pagefind = await import("/pagefind/pagefind.js"); 14 | await pagefind.options({ highlightParam: "hi" }); 15 | 16 | let search = await pagefind.search("second"); 17 | 18 | let data = await search.results[0].data(); 19 | document.querySelector('[data-url]').innerText = data.sub_results[0].url; 20 | - step: In my browser, the console should be empty 21 | - step: In my browser, I evaluate {js} 22 | js: |- 23 | let val = await toolproof.querySelector("[data-url]"); 24 | toolproof.assert_eq(val.innerHTML, `/b/?hi=second#second`); 25 | -------------------------------------------------------------------------------- /pagefind/integration_tests/index_chunking/background.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: index_chunking > Index Chunking > Background 2 | type: reference 3 | steps: 4 | - step: I have the environment variable "PAGEFIND_SITE" set to "public" 5 | - step: I have a "public/index.html" file with the content {html} 6 | html: |- 7 | 10 | -------------------------------------------------------------------------------- /pagefind/integration_tests/indexing/background.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: indexing > Indexing > Background 2 | type: reference 3 | steps: 4 | - step: I have the environment variable "PAGEFIND_SITE" set to "public" 5 | -------------------------------------------------------------------------------- /pagefind/integration_tests/input_quirks/background.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: input_quirks > Input Quirk Tests > Background 2 | type: reference 3 | steps: 4 | - step: I have the environment variable "PAGEFIND_SITE" set to "public" 5 | - step: I have the environment variable "PAGEFIND_verbose" set to "true" 6 | - step: I have a "public/index.html" file with the content {html} 7 | html: >- 8 |

Nothing

10 | -------------------------------------------------------------------------------- /pagefind/integration_tests/input_quirks/index-gzipped-input-files.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: Input Quirk Tests > Index gzipped input files 2 | steps: 3 | - ref: ./background.toolproof.yml 4 | - step: I have a "public/cat/index.html" file with the content {html} 5 | html: >- 6 |

Hello 7 | World

8 | - step: >- 9 | I run "gzip public/cat/index.html && mv public/cat/index.html.gz 10 | public/cat/index.html" 11 | - macro: I run Pagefind 12 | - step: stdout should contain "Running Pagefind" 13 | - step: The file "public/pagefind/pagefind.js" should not be empty 14 | - step: I serve the directory "public" 15 | - step: In my browser, I load "/" 16 | - step: In my browser, I evaluate {js} 17 | js: |- 18 | let pagefind = await import("/pagefind/pagefind.js"); 19 | 20 | let search = await pagefind.search("world"); 21 | 22 | let data = await search.results[0].data(); 23 | document.querySelector('[data-title]').innerText = data.meta.title; 24 | - step: In my browser, the console should be empty 25 | - step: In my browser, I evaluate {js} 26 | js: |- 27 | let val = await toolproof.querySelector("[data-title]"); 28 | toolproof.assert_eq(val.innerHTML, `Hello World`); 29 | -------------------------------------------------------------------------------- /pagefind/integration_tests/log_levels/error_logs.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: Log level > error logs 2 | steps: 3 | - step: I have the environment variable "PAGEFIND_SITE" set to "public" 4 | 5 | - macro: I run a failing Pagefind with "--verbose" 6 | - "stdout should contain 'Found 0 files'" 7 | - "stderr should contain 'Error: Pagefind was not able to build an index'" 8 | 9 | - macro: I run a failing Pagefind with "--quiet" 10 | - "stdout should be empty" 11 | - "stderr should contain 'Error: Pagefind was not able to build an index'" 12 | 13 | - macro: I run a failing Pagefind with "--silent" 14 | - "stdout should be empty" 15 | - "stderr should contain 'Error: Pagefind was not able to build an index'" 16 | -------------------------------------------------------------------------------- /pagefind/integration_tests/log_levels/success_logs.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: Log level > success logs 2 | steps: 3 | - step: I have the environment variable "PAGEFIND_SITE" set to "public" 4 | - step: I have a "public/index.html" file with the content {html} 5 | html: >- 6 |

Nothing

8 | - step: I have a "public/cat/index.html" file with the content {html} 9 | html: >- 10 |

world

Hello

12 | - step: I have a "public/no-lang/index.html" file with the content {html} 13 | html: >- 14 |

world

15 | 16 | - macro: I run Pagefind with "--verbose" 17 | - "stdout should contain 'unknown: 1 page'" 18 | - 'stderr should contain ''data-pagefind-ignore value of "misc" is not valid''' 19 | 20 | - macro: I run Pagefind with "--quiet && echo done" 21 | - "stdout should be exactly 'done\n'" 22 | - 'stderr should contain ''data-pagefind-ignore value of "misc" is not valid''' 23 | 24 | - macro: I run Pagefind with "--silent && echo complete" 25 | - "stdout should be exactly 'complete\n'" 26 | - stderr should be empty 27 | -------------------------------------------------------------------------------- /pagefind/integration_tests/metadata/default-metadata-can-be-defined.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: Metadata > Default metadata can be defined 2 | steps: 3 | - ref: ./background.toolproof.yml 4 | - step: In my browser, I evaluate {js} 5 | js: |- 6 | let pagefind = await import("/pagefind/pagefind.js"); 7 | 8 | let search = await pagefind.search("dog"); 9 | 10 | let data = await search.results[0].data(); 11 | document.querySelector('[data-result]').innerText = [ 12 | data.meta.title, 13 | data.meta.image, 14 | data.meta.animal, 15 | data.meta.vegetable, 16 | data.meta.mineral, 17 | ].join(' | '); 18 | - step: In my browser, the console should be empty 19 | - step: In my browser, I evaluate {js} 20 | js: >- 21 | let val = await toolproof.querySelector("[data-result]"); 22 | 23 | toolproof.assert_eq(val.innerHTML, `Dog Post. | /puppy.jpg | dog | generic 24 | | generic`); 25 | -------------------------------------------------------------------------------- /pagefind/integration_tests/metadata/search-results-return-complex-metadata.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: Metadata > Search results return complex metadata 2 | steps: 3 | - ref: ./background.toolproof.yml 4 | - step: In my browser, I evaluate {js} 5 | js: >- 6 | let pagefind = await import("/pagefind/pagefind.js"); 7 | 8 | 9 | let search = await pagefind.search("cat"); 10 | 11 | 12 | let data = await search.results[0].data(); 13 | 14 | document.querySelector('[data-result]').innerText = data.meta.footer + " — 15 | " + data.meta.footer_alt; 16 | - step: In my browser, the console should be empty 17 | - step: In my browser, I evaluate {js} 18 | js: >- 19 | let val = await toolproof.querySelector("[data-result]"); 20 | 21 | toolproof.assert_eq(val.innerHTML, `/cat-footer.png — cat footer 22 | picture`); 23 | -------------------------------------------------------------------------------- /pagefind/integration_tests/metadata/search-results-return-generic-information-about-the-page.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: Metadata > Search results return generic information about the page 2 | steps: 3 | - ref: ./background.toolproof.yml 4 | - step: In my browser, I evaluate {js} 5 | js: >- 6 | let pagefind = await import("/pagefind/pagefind.js"); 7 | 8 | 9 | let search = await pagefind.search("cat"); 10 | 11 | 12 | let data = await search.results[0].data(); 13 | 14 | document.querySelector('[data-result]').innerText = data.meta.title; 15 | 16 | document.querySelector('[data-result-two]').innerText = 17 | `${data.meta.image} | ${data.meta.image_alt}`; 18 | - step: In my browser, the console should be empty 19 | - step: In my browser, I evaluate {js} 20 | js: |- 21 | let val = await toolproof.querySelector("[data-result]"); 22 | toolproof.assert_eq(val.innerHTML, `Cat Post.`); 23 | - step: In my browser, I evaluate {js} 24 | js: |- 25 | let val = await toolproof.querySelector("[data-result-two]"); 26 | toolproof.assert_eq(val.innerHTML, `/cat.png | cat picture`); 27 | -------------------------------------------------------------------------------- /pagefind/integration_tests/metadata/search-results-return-highlighted-search-excerpt.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: Metadata > Search results return highlighted search excerpt 2 | steps: 3 | - ref: ./background.toolproof.yml 4 | - step: In my browser, I evaluate {js} 5 | js: |- 6 | let pagefind = await import("/pagefind/pagefind.js"); 7 | 8 | let search = await pagefind.search("feline"); 9 | 10 | let data = await search.results[0].data(); 11 | document.querySelector('[data-result]').innerText = data.excerpt; 12 | - step: In my browser, the console should be empty 13 | - step: In my browser, I evaluate {js} 14 | js: >- 15 | let val = await toolproof.querySelector("[data-result]"); 16 | 17 | toolproof.assert_eq(val.innerHTML, `Cat Post. A post about the 18 | <mark>'felines'.</mark> This post has some gnarly things to 19 | test the fragment formatting.`); 20 | -------------------------------------------------------------------------------- /pagefind/integration_tests/metadata/search-results-return-nicely-formatted-content.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: Metadata > Search results return nicely formatted content 2 | steps: 3 | - ref: ./background.toolproof.yml 4 | - step: In my browser, I evaluate {js} 5 | js: |- 6 | let pagefind = await import("/pagefind/pagefind.js"); 7 | 8 | let search = await pagefind.search("feline"); 9 | 10 | let data = await search.results[0].data(); 11 | document.querySelector('[data-result]').innerText = data.content; 12 | - step: In my browser, the console should be empty 13 | - step: In my browser, I evaluate {js} 14 | js: >- 15 | let val = await toolproof.querySelector("[data-result]"); 16 | 17 | toolproof.assert_eq(val.innerHTML, `Cat Post. A post about the 'felines'. 18 | This post has some gnarly things to test the fragment formatting.`); 19 | -------------------------------------------------------------------------------- /pagefind/integration_tests/metadata/search-results-return-tagged-filters.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: Metadata > Search results return tagged filters 2 | steps: 3 | - ref: ./background.toolproof.yml 4 | - step: In my browser, I evaluate {js} 5 | js: >- 6 | let pagefind = await import("/pagefind/pagefind.js"); 7 | 8 | 9 | let search = await pagefind.search("cat"); 10 | 11 | 12 | let data = await search.results[0].data(); 13 | 14 | document.querySelector('[data-result]').innerText = 15 | Object.entries(data.filters).map(([f, v]) => `${f}: ${v}`).sort().join(', 16 | '); 17 | - step: In my browser, the console should be empty 18 | - step: In my browser, I evaluate {js} 19 | js: |- 20 | let val = await toolproof.querySelector("[data-result]"); 21 | toolproof.assert_eq(val.innerHTML, `animal: cats, title: Cat Post.`); 22 | -------------------------------------------------------------------------------- /pagefind/integration_tests/metadata/search-results-return-tagged-metadata.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: Metadata > Search results return tagged metadata 2 | steps: 3 | - ref: ./background.toolproof.yml 4 | - step: In my browser, I evaluate {js} 5 | js: >- 6 | let pagefind = await import("/pagefind/pagefind.js"); 7 | 8 | 9 | let search = await pagefind.search("cat"); 10 | 11 | 12 | let data = await search.results[0].data(); 13 | 14 | document.querySelector('[data-result]').innerText = 15 | data.meta["social-image"] + " — " + data.meta.adjective; 16 | - step: In my browser, the console should be empty 17 | - step: In my browser, I evaluate {js} 18 | js: |- 19 | let val = await toolproof.querySelector("[data-result]"); 20 | toolproof.assert_eq(val.innerHTML, `/kitty.jpg — gnarly`); 21 | -------------------------------------------------------------------------------- /pagefind/integration_tests/metadata/title-metadata-falls-back-to-the-title-element.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: Metadata > Title metadata falls back to the title element 2 | steps: 3 | - ref: ./background.toolproof.yml 4 | - step: In my browser, I evaluate {js} 5 | js: >- 6 | let pagefind = await import("/pagefind/pagefind.js"); 7 | 8 | 9 | let search = await pagefind.search("NZ"); 10 | 11 | 12 | let data = await Promise.all(search.results.map(result => result.data())); 13 | 14 | document.querySelector('[data-result]').innerText = data.map(d => 15 | d.meta.title).sort().join(', '); 16 | - step: In my browser, the console should be empty 17 | - step: In my browser, I evaluate {js} 18 | js: |- 19 | let val = await toolproof.querySelector("[data-result]"); 20 | toolproof.assert_eq(val.innerHTML, `Website | Kaka, Website | Kea`); 21 | -------------------------------------------------------------------------------- /pagefind/integration_tests/modular_ui/modular_ui_base/background.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: modular_ui/modular_ui_base > Base Modular UI Tests > Background 2 | type: reference 3 | steps: 4 | - step: I have the environment variable "PAGEFIND_SITE" set to "public" 5 | - step: I have a "public/index.html" file with the content {html} 6 | html: |- 7 | 8 |
9 |
10 | 11 | 12 | 24 | -------------------------------------------------------------------------------- /pagefind/integration_tests/modular_ui/modular_ui_base/pagefind-modular-ui-loads.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: Base Modular UI Tests > Pagefind Modular UI loads 2 | steps: 3 | - ref: ./background.toolproof.yml 4 | - step: I have a "public/cat/index.html" file with the content {html} 5 | html: >- 6 |

world

8 | - macro: I run Pagefind 9 | - step: stdout should contain "Running Pagefind" 10 | - step: The file "public/pagefind/pagefind.js" should not be empty 11 | - step: I serve the directory "public" 12 | - step: In my browser, I load "/" 13 | - step: In my browser, the console should be empty 14 | - step: In my browser, I evaluate {js} 15 | js: |- 16 | let el = await toolproof.querySelector("#search input"); 17 | toolproof.assert(el); 18 | -------------------------------------------------------------------------------- /pagefind/integration_tests/modular_ui/modular_ui_base/pagefind-modular-ui-searches.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: Base Modular UI Tests > Pagefind Modular UI searches 2 | steps: 3 | - ref: ./background.toolproof.yml 4 | - step: I have a "public/cat/index.html" file with the content {html} 5 | html: >- 6 |

world

8 | - macro: I run Pagefind 9 | - step: stdout should contain "Running Pagefind" 10 | - step: The file "public/pagefind/pagefind.js" should not be empty 11 | - step: I serve the directory "public" 12 | - step: In my browser, I load "/" 13 | - step: In my browser, I evaluate {js} 14 | js: |- 15 | let e = new Event('input', {bubbles:true, cancelable:true}); 16 | document.querySelector("#search input").value = "world"; 17 | document.querySelector("#search input").dispatchEvent(e); 18 | - step: In my browser, the console should be empty 19 | - step: In my browser, I evaluate {js} 20 | js: |- 21 | let val = await toolproof.querySelector(".pagefind-modular-list-link"); 22 | toolproof.assert_eq(val.innerHTML, `world`); 23 | -------------------------------------------------------------------------------- /pagefind/integration_tests/multilingual/background.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: multilingual > Multilingual > Background 2 | type: reference 3 | steps: 4 | - step: I have the environment variable "PAGEFIND_SITE" set to "public" 5 | - step: I have a "public/en/index.html" file with the content {html} 6 | html: |- 7 | 8 | 9 | 10 | Document 11 | 12 | 13 |

I am some English documentation

14 | 15 | 16 | - step: I have a "public/pt-br/index.html" file with the content {html} 17 | html: |- 18 | 19 | 20 | 21 | Document 22 | 23 | 24 |

I am a Portuguese document (trust me — quilométricas — see?)

25 | 26 | 27 | -------------------------------------------------------------------------------- /pagefind/integration_tests/multisite/multisite_base/background.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: multisite/multisite_base > Multisite Search > Background 2 | type: reference 3 | steps: 4 | - step: I have a "root/index.html" file with the content {html} 5 | html: >- 6 |

Nothing

8 | - step: I have a "root/website_a/hello/index.html" file with the content {html} 9 | html: >- 10 |

web web world web 11 | PAGEFIND_ROOT_SELECTOR

12 | - step: I have a "root/website_b/lorem/index.html" file with the content {html} 13 | html: >- 14 |

web 15 | ipsum

16 | -------------------------------------------------------------------------------- /pagefind/integration_tests/multisite/multisite_filters/pagefind-can-search-across-multiple-sites-with-common-filters.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: >- 2 | Multisite Filters > Pagefind can search across multiple sites with common 3 | filters 4 | steps: 5 | - ref: ./background.toolproof.yml 6 | - step: In my browser, I evaluate {js} 7 | js: >- 8 | let pagefind = await import("/website_a/pagefind/pagefind.js"); 9 | 10 | await pagefind.mergeIndex("/website_b/pagefind/"); 11 | 12 | 13 | let search = await pagefind.search("web", { 14 | filters: { 15 | fruit: "apple" 16 | } 17 | }); 18 | 19 | 20 | let pages = await Promise.all(search.results.map(r => r.data())); 21 | 22 | document.querySelector('[data-result]').innerText = pages.map(p => 23 | p.url).join(", "); 24 | - step: In my browser, the console should be empty 25 | - step: In my browser, I evaluate {js} 26 | js: |- 27 | let val = await toolproof.querySelector("[data-result]"); 28 | toolproof.assert_eq(val.innerHTML, `/website_a/hello/`); 29 | -------------------------------------------------------------------------------- /pagefind/integration_tests/multisite/multisite_filters/pagefind-can-search-across-multiple-sites-with-unique-filters.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: >- 2 | Multisite Filters > Pagefind can search across multiple sites with unique 3 | filters 4 | steps: 5 | - ref: ./background.toolproof.yml 6 | - step: In my browser, I evaluate {js} 7 | js: >- 8 | let pagefind = await import("/website_a/pagefind/pagefind.js"); 9 | 10 | await pagefind.mergeIndex("/website_b/pagefind/"); 11 | 12 | 13 | let search = await pagefind.search("web", { 14 | filters: { 15 | emote: "happy" 16 | } 17 | }); 18 | 19 | 20 | let pages = await Promise.all(search.results.map(r => r.data())); 21 | 22 | document.querySelector('[data-result]').innerText = pages.map(p => 23 | p.url).join(", "); 24 | - step: In my browser, the console should be empty 25 | - step: In my browser, I evaluate {js} 26 | js: |- 27 | let val = await toolproof.querySelector("[data-result]"); 28 | toolproof.assert_eq(val.innerHTML, `/website_b/lorem/`); 29 | -------------------------------------------------------------------------------- /pagefind/integration_tests/node_api/node_base/background.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: node_api/node_base > Node API Base Tests > Background 2 | type: reference 3 | steps: 4 | - step: I have a "public/index.html" file with the content {html} 5 | html: >- 6 |

Nothing

8 | - step: I have a "public/package.json" file with the content {json} 9 | json: |- 10 | { 11 | "name": "test", 12 | "type": "module", 13 | "version": "1.0.0", 14 | "main": "index.js", 15 | "dependencies": { 16 | "pagefind": "file:%toolproof_process_directory%/wrappers/node" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /pagefind/integration_tests/node_api/node_base/close-the-pagefind-backend.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: Node API Base Tests > Close the Pagefind backend 2 | platforms: 3 | - linux 4 | - mac 5 | 6 | steps: 7 | - ref: ./background.toolproof.yml 8 | - step: I have a "public/index.js" file with the content {js} 9 | js: |2- 10 | import * as pagefind from "pagefind"; 11 | 12 | const run = async () => { 13 | const { index } = await pagefind.createIndex(); 14 | const { errors, files } = await index.getFiles(); 15 | console.log(files.map(f => f.path).join(', ')); 16 | await pagefind.close(); 17 | const { errors: es } = await index.getFiles(); 18 | console.log(`After close: ${es.join(',')}`); 19 | } 20 | run(); 21 | - macro: I run Pagefind Node as "index.js" in "public" 22 | - step: stdout should contain "pagefind.js" 23 | - step: >- 24 | stdout should contain "After close: Invalid index, does not yet exist in 25 | the Pagefind service" 26 | -------------------------------------------------------------------------------- /pagefind/integration_tests/node_api/node_base/pagefind-empty-index-returns-assets.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: Node API Base Tests > Pagefind empty index returns assets 2 | platforms: 3 | - linux 4 | - mac 5 | 6 | steps: 7 | - ref: ./background.toolproof.yml 8 | - step: I have a "public/index.js" file with the content {js} 9 | js: |2- 10 | import * as pagefind from "pagefind"; 11 | 12 | const run = async () => { 13 | const { index } = await pagefind.createIndex(); 14 | const { errors, files } = await index.getFiles(); 15 | console.log(files.map(f => f.path).join(', ')); 16 | } 17 | run(); 18 | - macro: I run Pagefind Node as "index.js" in "public" 19 | - step: stdout should contain "pagefind.js" 20 | - step: stdout should contain "pagefind-ui.js" 21 | - step: stdout should contain "pagefind-ui.css" 22 | - step: stdout should contain "pagefind-modular-ui.js" 23 | - step: stdout should contain "pagefind-modular-ui.css" 24 | - step: stdout should contain "wasm.unknown.pagefind" 25 | -------------------------------------------------------------------------------- /pagefind/integration_tests/node_api/node_base/pagefind-error-handling.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: Node API Base Tests > Pagefind error handling 2 | platforms: 3 | - linux 4 | - mac 5 | 6 | steps: 7 | - ref: ./background.toolproof.yml 8 | - step: I have a "public/index.js" file with the content {js} 9 | js: |2- 10 | import * as pagefind from "pagefind"; 11 | 12 | const bad = async () => { 13 | const { index } = await pagefind.createIndex(); 14 | await index.deleteIndex(); 15 | const { errors, files } = await index.getFiles(); 16 | console.log(JSON.stringify(errors)); 17 | 18 | try { 19 | const response = await pagefind.createIndex({ 20 | rootSelector: 5 21 | }); 22 | } catch(e) { 23 | console.log(e.toString()); 24 | } 25 | } 26 | bad(); 27 | - macro: I run Pagefind Node as "index.js" in "public" 28 | - step: 'stdout should contain "invalid type: integer `5`"' 29 | - step: >- 30 | stdout should contain "Index has been deleted from the Pagefind service 31 | and no longer exists" 32 | -------------------------------------------------------------------------------- /pagefind/integration_tests/partial_matching/background.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: partial_matching > Partial Matching > Background 2 | type: reference 3 | steps: 4 | - step: I have the environment variable "PAGEFIND_SITE" set to "public" 5 | -------------------------------------------------------------------------------- /pagefind/integration_tests/python_api/background.toolproof.yml: -------------------------------------------------------------------------------- 1 | # Requirements: 2 | # venv 3 | # python>=3.11 4 | 5 | name: Python API Setup 6 | type: reference 7 | steps: 8 | - step: I have a "public/index.html" file with the content {html} 9 | html: >- 10 |

Nothing

12 | - step: I run 'python3 -m venv "$PWD/.venv"' 13 | -------------------------------------------------------------------------------- /pagefind/integration_tests/python_api/py-close-the-pagefind-backend.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: Python API > Close the Pagefind backend 2 | platforms: 3 | - linux 4 | - mac 5 | 6 | steps: 7 | - ref: ./background.toolproof.yml 8 | - step: I have a "public/run.py" file with the content {python} 9 | python: |2- 10 | import sys 11 | sys.path.append('%toolproof_process_directory%/wrappers/python/src') 12 | 13 | import asyncio 14 | import json 15 | import logging 16 | import os 17 | from pagefind.index import PagefindIndex, IndexConfig 18 | 19 | async def main(): 20 | async with PagefindIndex() as index: 21 | files = await index.get_files() 22 | 23 | for file in files: 24 | print(file["path"]) 25 | 26 | await index.delete_index() 27 | 28 | try: 29 | files = await index.get_files() 30 | except AssertionError: 31 | print("errored getting files after close") 32 | 33 | if __name__ == "__main__": 34 | asyncio.run(main()) 35 | - macro: I run Pagefind Python as "run.py" in "public" 36 | - step: stdout should contain "pagefind.js" 37 | - step: stdout should contain "pagefind-ui.js" 38 | - step: stdout should contain "errored getting files after close" 39 | -------------------------------------------------------------------------------- /pagefind/integration_tests/sanity/cli-tests-are-working.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: Sanity Tests > CLI tests are working 2 | steps: 3 | - step: I have a "public/index.html" file with the content {html} 4 | html:

a

5 | - macro: I run Pagefind with "--site public" 6 | - step: stdout should contain "Running Pagefind" 7 | -------------------------------------------------------------------------------- /pagefind/integration_tests/sanity/web-tests-are-working.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: Sanity Tests > Web tests are working 2 | steps: 3 | - step: I have a "public/index.html" file with the content {html} 4 | html: >- 5 |

Hello!

7 | - step: I serve the directory "public" 8 | - step: In my browser, I load "/" 9 | - step: In my browser, I evaluate {js} 10 | js: |- 11 | let val = await toolproof.querySelector("h1"); 12 | toolproof.assert_eq(val.innerHTML, `Hello!`); 13 | -------------------------------------------------------------------------------- /pagefind/integration_tests/scoring_defaults/background.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: scoring_defaults > Result Scoring > Background 2 | type: reference 3 | steps: 4 | - step: I have the environment variable "PAGEFIND_SITE" set to "public" 5 | - step: I have a "public/index.html" file with the content {html} 6 | html: |- 7 | 11 | - step: I have a "public/cat/index.html" file with the content {html} 12 | html: >- 13 |

Happy cat post, that 14 | later mentions dogs in the context of cats

15 | - step: I have a "public/dog/index.html" file with the content {html} 16 | html: >- 17 |

A post about dogs vs 18 | cats (but mainly dogs)

19 | - macro: I run Pagefind 20 | - step: stdout should contain "Running Pagefind" 21 | - step: I serve the directory "public" 22 | - step: In my browser, I load "/" 23 | -------------------------------------------------------------------------------- /pagefind/integration_tests/search_options/background.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: search_options > Search Options > Background 2 | type: reference 3 | steps: 4 | - step: I have the environment variable "PAGEFIND_SITE" set to "public" 5 | -------------------------------------------------------------------------------- /pagefind/integration_tests/sentences/background.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: sentences > Sentence Building Tests > Background 2 | type: reference 3 | steps: 4 | - step: I have the environment variable "PAGEFIND_SITE" set to "public" 5 | - step: I have a "public/index.html" file with the content {html} 6 | html: >- 7 |

Nothing

9 | -------------------------------------------------------------------------------- /pagefind/integration_tests/sentences/pagefind-joins-block-elements-as-sentences.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: Sentence Building Tests > Pagefind joins block elements as sentences 2 | steps: 3 | - ref: ./background.toolproof.yml 4 | - step: I have a "public/apiary/index.html" file with the content {html} 5 | html: >- 6 |

Hello

World

8 | - macro: I run Pagefind 9 | - step: stdout should contain "Running Pagefind" 10 | - step: The file "public/pagefind/pagefind.js" should not be empty 11 | - step: I serve the directory "public" 12 | - step: In my browser, I load "/" 13 | - step: In my browser, I evaluate {js} 14 | js: >- 15 | let pagefind = await import("/pagefind/pagefind.js"); 16 | 17 | 18 | let search = await pagefind.search("h"); 19 | 20 | 21 | let pages = await Promise.all(search.results.map(r => r.data())); 22 | 23 | document.querySelector('[data-result]').innerText = pages.map(p => 24 | p.content).join(", "); 25 | - step: In my browser, the console should be empty 26 | - step: In my browser, I evaluate {js} 27 | js: |- 28 | let val = await toolproof.querySelector("[data-result]"); 29 | toolproof.assert_eq(val.innerHTML, `Hello. World.`); 30 | -------------------------------------------------------------------------------- /pagefind/integration_tests/sentences/pagefind-treats-br-tags-as-spaces.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: Sentence Building Tests > Pagefind treats br tags as spaces 2 | steps: 3 | - ref: ./background.toolproof.yml 4 | - step: I have a "public/apiary/index.html" file with the content {html} 5 | html: >- 6 |

Hello
World

8 | - macro: I run Pagefind 9 | - step: stdout should contain "Running Pagefind" 10 | - step: The file "public/pagefind/pagefind.js" should not be empty 11 | - step: I serve the directory "public" 12 | - step: In my browser, I load "/" 13 | - step: In my browser, I evaluate {js} 14 | js: >- 15 | let pagefind = await import("/pagefind/pagefind.js"); 16 | 17 | 18 | let search = await pagefind.search("w"); 19 | 20 | 21 | let pages = await Promise.all(search.results.map(r => r.data())); 22 | 23 | document.querySelector('[data-result]').innerText = pages.map(p => 24 | p.content).join(", "); 25 | - step: In my browser, the console should be empty 26 | - step: In my browser, I evaluate {js} 27 | js: |- 28 | let val = await toolproof.querySelector("[data-result]"); 29 | toolproof.assert_eq(val.innerHTML, `Hello World.`); 30 | -------------------------------------------------------------------------------- /pagefind/integration_tests/stemming/background.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: stemming > Word Stemming > Background 2 | type: reference 3 | steps: 4 | - step: I have the environment variable "PAGEFIND_SITE" set to "public" 5 | - step: I have a "public/index.html" file with the content {html} 6 | html: |- 7 | 10 | -------------------------------------------------------------------------------- /pagefind/integration_tests/stemming/search-is-case-independent.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: Word Stemming > Search is case independent 2 | steps: 3 | - ref: ./background.toolproof.yml 4 | - step: I have a "public/cat/index.html" file with the content {html} 5 | html: >- 6 |

the cat is 7 | Meowing

8 | - macro: I run Pagefind 9 | - step: stdout should contain "Running Pagefind" 10 | - step: The file "public/pagefind/pagefind.js" should not be empty 11 | - step: I serve the directory "public" 12 | - step: In my browser, I load "/" 13 | - step: In my browser, I evaluate {js} 14 | js: |- 15 | let pagefind = await import("/pagefind/pagefind.js"); 16 | 17 | let search = await pagefind.search("meOWings"); 18 | 19 | let data = await search.results[0].data(); 20 | document.querySelector('[data-result]').innerText = data.url; 21 | - step: In my browser, the console should be empty 22 | - step: In my browser, I evaluate {js} 23 | js: |- 24 | let val = await toolproof.querySelector("[data-result]"); 25 | toolproof.assert_eq(val.innerHTML, `/cat/`); 26 | -------------------------------------------------------------------------------- /pagefind/integration_tests/stemming/search-is-punctuation-independent.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: Word Stemming > Search is punctuation independent 2 | steps: 3 | - ref: ./background.toolproof.yml 4 | - step: I have a "public/apple/index.html" file with the content {html} 5 | html: >- 6 |

My laptop doesn't 7 | have a USB-A port

8 | - macro: I run Pagefind 9 | - step: stdout should contain "Running Pagefind" 10 | - step: The file "public/pagefind/pagefind.js" should not be empty 11 | - step: I serve the directory "public" 12 | - step: In my browser, I load "/" 13 | - step: In my browser, I evaluate {js} 14 | js: |- 15 | let pagefind = await import("/pagefind/pagefind.js"); 16 | 17 | let search = await pagefind.search("usb[a"); 18 | 19 | let data = await search.results[0].data(); 20 | document.querySelector('[data-result]').innerText = data.url; 21 | - step: In my browser, the console should be empty 22 | - step: In my browser, I evaluate {js} 23 | js: |- 24 | let val = await toolproof.querySelector("[data-result]"); 25 | toolproof.assert_eq(val.innerHTML, `/apple/`); 26 | -------------------------------------------------------------------------------- /pagefind/integration_tests/stemming/searching-for-a-word-will-match-against-the-stem-of-that-word.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: Word Stemming > Searching for a word will match against the stem of that word 2 | steps: 3 | - ref: ./background.toolproof.yml 4 | - step: I have a "public/cat/index.html" file with the content {html} 5 | html: >- 6 |

the cat is 7 | meowing

8 | - macro: I run Pagefind 9 | - step: stdout should contain "Running Pagefind" 10 | - step: The file "public/pagefind/pagefind.js" should not be empty 11 | - step: I serve the directory "public" 12 | - step: In my browser, I load "/" 13 | - step: In my browser, I evaluate {js} 14 | js: |- 15 | let pagefind = await import("/pagefind/pagefind.js"); 16 | 17 | let search = await pagefind.search("meowed"); 18 | 19 | let data = await search.results[0].data(); 20 | document.querySelector('[data-result]').innerText = data.url; 21 | - step: In my browser, the console should be empty 22 | - step: In my browser, I evaluate {js} 23 | js: |- 24 | let val = await toolproof.querySelector("[data-result]"); 25 | toolproof.assert_eq(val.innerHTML, `/cat/`); 26 | -------------------------------------------------------------------------------- /pagefind/integration_tests/suggestions/background.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: suggestions > Spellcheck > Background 2 | type: reference 3 | steps: 4 | - step: I have the environment variable "PAGEFIND_SITE" set to "public" 5 | - step: I have a "public/index.html" file with the content {html} 6 | html: |- 7 | 10 | -------------------------------------------------------------------------------- /pagefind/integration_tests/suggestions/spelling-correction-can-be-returned-for-the-unique-words-in-the-dataset.toolproof.yml: -------------------------------------------------------------------------------- 1 | #TODO: This is an intentionally skipped test — add skipping to toolproof. 2 | 3 | type: reference 4 | name: >- 5 | Spellcheck > Spelling correction can be returned for the unique words in the 6 | dataset 7 | steps: 8 | - ref: ./background.toolproof.yml 9 | -------------------------------------------------------------------------------- /pagefind/integration_tests/ui/ui_base/background.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: ui/ui_base > Base UI Tests > Background 2 | type: reference 3 | steps: 4 | - step: I have the environment variable "PAGEFIND_SITE" set to "public" 5 | - step: I have a "public/index.html" file with the content {html} 6 | html: |- 7 | 8 | 9 | 10 | 13 | -------------------------------------------------------------------------------- /pagefind/integration_tests/ui/ui_base/pagefind-ui-loads.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: Base UI Tests > Pagefind UI loads 2 | steps: 3 | - ref: ./background.toolproof.yml 4 | - step: I have a "public/cat/index.html" file with the content {html} 5 | html: >- 6 |

world

8 | - macro: I run Pagefind 9 | - step: stdout should contain "Running Pagefind" 10 | - step: The file "public/pagefind/pagefind.js" should not be empty 11 | - step: I serve the directory "public" 12 | - step: In my browser, I load "/" 13 | - step: In my browser, the console should be empty 14 | - step: In my browser, I evaluate {js} 15 | js: |- 16 | let el = await toolproof.querySelector(".pagefind-ui"); 17 | toolproof.assert(el); 18 | -------------------------------------------------------------------------------- /pagefind/integration_tests/ui/ui_base/pagefind-ui-searches.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: Base UI Tests > Pagefind UI searches 2 | steps: 3 | - ref: ./background.toolproof.yml 4 | - step: I have a "public/cat/index.html" file with the content {html} 5 | html: >- 6 |

world

8 | - macro: I run Pagefind 9 | - step: stdout should contain "Running Pagefind" 10 | - step: The file "public/pagefind/pagefind.js" should not be empty 11 | - step: I serve the directory "public" 12 | - step: In my browser, I load "/" 13 | - step: In my browser, I evaluate {js} 14 | js: window.pui.triggerSearch("world"); 15 | - step: In my browser, the console should be empty 16 | - step: In my browser, I evaluate {js} 17 | js: |- 18 | let val = await toolproof.querySelector(".pagefind-ui__result-link"); 19 | toolproof.assert_eq(val.innerHTML, `world`); 20 | -------------------------------------------------------------------------------- /pagefind/integration_tests/ui/ui_highlight/background.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: ui/ui_highlight > Base UI Tests > Background 2 | type: reference 3 | steps: 4 | - step: I have the environment variable "PAGEFIND_SITE" set to "public" 5 | -------------------------------------------------------------------------------- /pagefind/integration_tests/ui/ui_hooks/background.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: ui/ui_hooks > UI Hooks > Background 2 | type: reference 3 | steps: 4 | - step: I have the environment variable "PAGEFIND_SITE" set to "public" 5 | -------------------------------------------------------------------------------- /pagefind/integration_tests/ui/ui_scoring/background.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: ui/ui_scoring > UI Scoring > Background 2 | type: reference 3 | steps: 4 | - step: I have the environment variable "PAGEFIND_SITE" set to "public" 5 | -------------------------------------------------------------------------------- /pagefind/integration_tests/ui/ui_strings/background.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: ui/ui_strings > UI Test Strings > Background 2 | type: reference 3 | steps: 4 | - step: I have the environment variable "PAGEFIND_SITE" set to "public" 5 | -------------------------------------------------------------------------------- /pagefind/integration_tests/urls/background.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: urls > URL tests > Background 2 | type: reference 3 | steps: 4 | - step: I have the environment variable "PAGEFIND_SITE" set to "public" 5 | - step: I have a "public/index.html" file with the content {html} 6 | html: >- 7 |

Nothing

9 | - step: I have a "public/package.json" file with the content {json} 10 | json: |- 11 | { 12 | "name": "test", 13 | "type": "module", 14 | "version": "1.0.0", 15 | "main": "index.js", 16 | "dependencies": { 17 | "pagefind": "file:%toolproof_process_directory%/wrappers/node" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /pagefind/integration_tests/weighting/background.toolproof.yml: -------------------------------------------------------------------------------- 1 | name: weighting > Word Weighting > Background 2 | type: reference 3 | steps: 4 | - step: I have the environment variable "PAGEFIND_SITE" set to "public" 5 | - step: I have a "public/index.html" file with the content {html} 6 | html: >- 7 |

no 8 | results

9 | -------------------------------------------------------------------------------- /pagefind/src/fragments/mod.rs: -------------------------------------------------------------------------------- 1 | use std::collections::BTreeMap; 2 | 3 | use serde::Serialize; 4 | 5 | #[derive(Serialize, Debug, Clone)] 6 | pub struct PageAnchorData { 7 | pub element: String, 8 | pub id: String, 9 | pub text: String, 10 | pub location: u32, 11 | } 12 | 13 | #[derive(Serialize, Debug, Clone)] 14 | pub struct PageFragmentData { 15 | pub url: String, 16 | pub content: String, 17 | pub word_count: usize, 18 | pub filters: BTreeMap>, 19 | pub meta: BTreeMap, 20 | pub anchors: Vec, 21 | } 22 | 23 | #[derive(Debug, Clone)] 24 | pub struct PageFragment { 25 | pub page_number: usize, 26 | pub data: PageFragmentData, 27 | } 28 | -------------------------------------------------------------------------------- /pagefind/src/index/index_filter.rs: -------------------------------------------------------------------------------- 1 | use minicbor::Encode; 2 | 3 | /// The filter index chunks in `pagefind/filter/` 4 | 5 | /// A single filter index chunk: `pagefind/filter/*.pf_filter` 6 | #[derive(Encode)] 7 | pub struct FilterIndex { 8 | #[n(0)] 9 | pub filter: String, 10 | #[n(1)] 11 | pub values: Vec, 12 | } 13 | 14 | /// A single filter value as an inverse index of all locations on the site 15 | #[derive(Encode, Clone, Debug)] 16 | pub struct PackedValue { 17 | #[n(0)] 18 | pub value: String, 19 | #[n(1)] 20 | pub pages: Vec, // Won't exceed u32 but saves us some into()s 21 | } 22 | -------------------------------------------------------------------------------- /pagefind/src/index/index_words.rs: -------------------------------------------------------------------------------- 1 | use minicbor::Encode; 2 | 3 | /// The word index chunks in `pagefind/index/` 4 | 5 | /// A single word index chunk: `pagefind/index/*.pf_index` 6 | #[derive(Encode)] 7 | pub struct WordIndex { 8 | #[n(0)] 9 | pub words: Vec, 10 | } 11 | 12 | /// A single word as an inverse index of all locations on the site 13 | #[derive(Encode, Clone, Debug)] 14 | pub struct PackedWord { 15 | #[n(0)] 16 | pub word: String, 17 | #[n(1)] 18 | pub pages: Vec, 19 | } 20 | 21 | /// A set of locations on a given page 22 | #[derive(Encode, Clone, Debug)] 23 | pub struct PackedPage { 24 | #[n(0)] 25 | pub page_number: usize, // Won't exceed u32 but saves us some into()s 26 | #[n(1)] 27 | pub locs: Vec, 28 | } 29 | -------------------------------------------------------------------------------- /pagefind/src/main.rs: -------------------------------------------------------------------------------- 1 | use pagefind::runner::run_indexer; 2 | 3 | #[tokio::main] 4 | async fn main() { 5 | match run_indexer().await { 6 | Ok(_) => { /* success */ } 7 | Err(msg) => { 8 | eprintln!("{msg}"); 9 | std::process::exit(1); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /pagefind/src/output/entry.rs: -------------------------------------------------------------------------------- 1 | use hashbrown::HashMap; 2 | 3 | use serde::Serialize; 4 | 5 | #[derive(Serialize, Debug)] 6 | pub struct PagefindEntryMeta { 7 | pub version: &'static str, 8 | pub languages: HashMap, 9 | pub include_characters: Vec, 10 | } 11 | 12 | #[derive(Serialize, Debug)] 13 | pub struct PagefindEntryLanguage { 14 | pub hash: String, 15 | pub wasm: Option, 16 | pub page_count: usize, 17 | } 18 | -------------------------------------------------------------------------------- /pagefind/src/playground.rs: -------------------------------------------------------------------------------- 1 | pub const PLAYGROUND_HTML: &str = include_str!(concat!( 2 | env!("CARGO_MANIFEST_DIR"), 3 | "/vendor/playground/index.html" 4 | )); 5 | 6 | pub const PLAYGROUND_CSS: &str = include_str!(concat!( 7 | env!("CARGO_MANIFEST_DIR"), 8 | "/vendor/playground/pagefind-playground.css" 9 | )); 10 | 11 | pub const PLAYGROUND_JS: &str = concat!( 12 | "const pagefind_version = \"", 13 | env!("CARGO_PKG_VERSION"), 14 | "\";", 15 | include_str!(concat!( 16 | env!("CARGO_MANIFEST_DIR"), 17 | "/vendor/playground/pagefind-playground.js" 18 | )) 19 | ); 20 | -------------------------------------------------------------------------------- /pagefind/src/service/responses.rs: -------------------------------------------------------------------------------- 1 | use std::collections::BTreeMap; 2 | 3 | use serde::{Deserialize, Serialize}; 4 | 5 | #[derive(Debug, Deserialize, Serialize)] 6 | pub(super) struct ServiceResponse { 7 | pub(super) message_id: Option, 8 | pub(super) payload: ResponseAction, 9 | } 10 | 11 | #[derive(Debug, Deserialize, Serialize)] 12 | #[serde(tag = "type")] 13 | pub(super) enum ResponseAction { 14 | Error { 15 | original_message: Option, 16 | message: String, 17 | }, 18 | NewIndex { 19 | index_id: u32, 20 | }, 21 | IndexedFile { 22 | page_word_count: u32, 23 | page_url: String, 24 | page_meta: BTreeMap, 25 | }, 26 | IndexedDir { 27 | page_count: u32, 28 | }, 29 | BuildIndex {}, 30 | WriteFiles { 31 | output_path: String, 32 | }, 33 | GetFiles { 34 | files: Vec, 35 | }, 36 | DeleteIndex {}, 37 | } 38 | 39 | #[derive(Debug, Deserialize, Serialize)] 40 | pub struct SyntheticFileResponse { 41 | pub path: String, 42 | pub content: String, 43 | } 44 | -------------------------------------------------------------------------------- /pagefind/src/utils.rs: -------------------------------------------------------------------------------- 1 | use sha1::{Digest, Sha1}; 2 | 3 | /// Symbols that count as part of a word 4 | /// (specifically, the "Punctuation, Connector" Unicode category) 5 | pub const WORD_SYMBOLS: [char; 10] = ['_', '‿', '⁀', '⁔', '︳', '︴', '﹍', '﹎', '﹏', '_']; 6 | 7 | pub fn full_hash(bytes: &[u8]) -> String { 8 | let mut hasher = Sha1::new(); 9 | hasher.update(bytes); 10 | hasher 11 | .finalize() 12 | .iter() 13 | .map(|b| format!("{:x?}", b)) 14 | .collect::>() 15 | .join("") 16 | } 17 | -------------------------------------------------------------------------------- /pagefind_playground/_build.js: -------------------------------------------------------------------------------- 1 | import esbuild from "esbuild"; 2 | import path from "path"; 3 | import fs from "fs"; 4 | import { fileURLToPath } from "url"; 5 | import { commonOptions } from "./_build_common.js"; 6 | 7 | const __dirname = path.dirname(fileURLToPath(import.meta.url)); 8 | 9 | const build = async () => { 10 | const esbuildOptions = { 11 | ...commonOptions(""), 12 | write: true, 13 | minify: true, 14 | conditions: ["svelte", "browser", "production"], 15 | }; 16 | const compiled = await esbuild.build(esbuildOptions); 17 | console.log(`Build: `, compiled); 18 | 19 | const vendorDir = path.join(__dirname, `../pagefind/vendor/`); 20 | try { 21 | fs.mkdirSync(vendorDir); 22 | } catch {} 23 | 24 | fs.cpSync( 25 | path.join(__dirname, `output/playground`), 26 | path.join(vendorDir, `playground`), 27 | { recursive: true }, 28 | ); 29 | }; 30 | 31 | build(); 32 | -------------------------------------------------------------------------------- /pagefind_playground/_serve.js: -------------------------------------------------------------------------------- 1 | import esbuild from "esbuild"; 2 | import path from "path"; 3 | import { fileURLToPath } from "url"; 4 | import { commonOptions } from "./_build_common.js"; 5 | 6 | const __dirname = path.dirname(fileURLToPath(import.meta.url)); 7 | 8 | const serve = async () => { 9 | const esbuildOptions = { 10 | ...commonOptions("const pagefind_version = 'PLAYGROUND';"), 11 | conditions: ["svelte", "browser", "development"], 12 | }; 13 | 14 | const context = await esbuild.context(esbuildOptions); 15 | const server = await context.serve({ 16 | servedir: path.join(__dirname, "output"), 17 | }); 18 | console.log( 19 | `Serving the playground http://localhost:${server.port}/playground/`, 20 | ); 21 | }; 22 | 23 | serve(); 24 | -------------------------------------------------------------------------------- /pagefind_playground/lib/defaults.ts: -------------------------------------------------------------------------------- 1 | export const pagefindRankingDefaults = { 2 | termSimilarity: 1.0, 3 | pageLength: 0.75, 4 | termSaturation: 1.4, 5 | termFrequency: 1.0, 6 | }; 7 | -------------------------------------------------------------------------------- /pagefind_playground/lib/panels/PinnedResults.svelte: -------------------------------------------------------------------------------- 1 | 15 | 16 |
    17 | {#each pinnedResults as result (result.last_result.id)} 18 | 23 | toggleResultPin(result.position, result.last_result)} 24 | /> 25 | {/each} 26 |
27 | 28 | 35 | -------------------------------------------------------------------------------- /pagefind_playground/lib/panels/Results.svelte: -------------------------------------------------------------------------------- 1 | 17 | 18 |
    19 | {#each results as result, i (result.id)} 20 | r.last_result.id == result.id)} 24 | toggleResultPin={() => toggleResultPin(i, result)} 25 | /> 26 | {/each} 27 |
28 | 29 | 36 | -------------------------------------------------------------------------------- /pagefind_playground/lib/playground.ts: -------------------------------------------------------------------------------- 1 | import PlaygroundSvelte from "./Playground.svelte"; 2 | import { mount } from "svelte"; 3 | 4 | declare var pagefind_version: string; 5 | 6 | document.addEventListener("DOMContentLoaded", () => { 7 | const dom = document.querySelector("#playground")!; 8 | mount(PlaygroundSvelte, { 9 | target: dom, 10 | props: { pagefindVersion: pagefind_version }, 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /pagefind_playground/local_prep.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | 4 | # This script runs Pagefind on the Pagefind documentation to generate 5 | # an index that can be used to test the playground. 6 | 7 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" 8 | 9 | echo "Building Pagefind Hugo documentation site" 10 | cd "$SCRIPT_DIR/../docs" 11 | if ! command -v go &> /dev/null; then 12 | echo "Golang is not installed, please install Golang to proceed." 13 | exit 1 14 | fi 15 | if ! command -v hugo &> /dev/null; then 16 | echo "Hugo is not installed, please install Hugo to proceed." 17 | exit 1 18 | fi 19 | 20 | npm i 21 | hugo 22 | 23 | cd "$SCRIPT_DIR" 24 | 25 | echo "Removing old index files" 26 | echo "The following files/directories will be deleted:" 27 | find output -mindepth 1 -maxdepth 1 ! -name 'playground' -print 28 | echo "Do you want to proceed with deletion? (yes/no)" 29 | read confirmation 30 | 31 | if [ "$confirmation" = "yes" ]; then 32 | find output -mindepth 1 -maxdepth 1 ! -name 'playground' -execdir rm -rf {} + 33 | else 34 | echo "Cancelling build script." 35 | exit 1 36 | fi 37 | 38 | echo "Running Pagefind" 39 | ../target/release/pagefind --site "../docs/public" --output-path "output" 40 | -------------------------------------------------------------------------------- /pagefind_playground/output/playground/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Pagefind Playground 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /pagefind_playground/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "pagefind_playground", 3 | "type": "module", 4 | "private": true, 5 | "scripts": { 6 | "test": "echo \"Error: no test specified\" && exit 1", 7 | "start": "node _serve.js", 8 | "build": "node _build.js" 9 | }, 10 | "dependencies": { 11 | "@tsconfig/svelte": "^5.0.4", 12 | "@types/node": "^22.10.5", 13 | "esbuild": "^0.24.2", 14 | "esbuild-svelte": "^0.9.0", 15 | "svelte": "^5.17.1", 16 | "svelte-preprocess": "^6.0.3", 17 | "typescript": "^5.7.2" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /pagefind_playground/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@tsconfig/svelte/tsconfig.json", 3 | "compilerOptions": { 4 | "verbatimModuleSyntax": true, 5 | "target": "esnext", 6 | "types": ["svelte"], 7 | "strict": true, 8 | "lib": ["esnext", "dom"], 9 | "moduleResolution": "node", 10 | "esModuleInterop": true, 11 | "skipLibCheck": true 12 | }, 13 | "include": ["lib/playground.ts", "types/index.d.ts"], 14 | "exclude": ["node_modules/**"] 15 | } 16 | -------------------------------------------------------------------------------- /pagefind_playground/types/index.d.ts: -------------------------------------------------------------------------------- 1 | import "../../pagefind_web_js/types/index"; 2 | 3 | export {}; 4 | 5 | declare global { 6 | type PinnedPagefindSearchResult = { 7 | last_result: PagefindSearchResult; 8 | position: number; 9 | }; 10 | } 11 | -------------------------------------------------------------------------------- /pagefind_stem/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "pagefind_stem" 3 | version = "0.2.0" 4 | # Imports would have to change for a newer edition, 5 | # and I don't want to have to edit snowball's rust files 6 | edition = "2015" 7 | description = "Snowball stemming algorithms repackaged for Rust, with languages behind feature flags." 8 | license = "MIT" 9 | 10 | [dependencies] 11 | 12 | [features] 13 | arabic = [] 14 | armenian = [] 15 | basque = [] 16 | catalan = [] 17 | danish = [] 18 | dutch = [] 19 | english = [] 20 | finnish = [] 21 | french = [] 22 | german = [] 23 | german2 = [] 24 | greek = [] 25 | hindi = [] 26 | hungarian = [] 27 | indonesian = [] 28 | irish = [] 29 | italian = [] 30 | kraaij_pohlmann = [] 31 | lithuanian = [] 32 | lovins = [] 33 | nepali = [] 34 | norwegian = [] 35 | porter = [] 36 | portuguese = [] 37 | romanian = [] 38 | russian = [] 39 | serbian = [] 40 | spanish = [] 41 | swedish = [] 42 | tamil = [] 43 | turkish = [] 44 | yiddish = [] 45 | -------------------------------------------------------------------------------- /pagefind_stem/src/snowball/among.rs: -------------------------------------------------------------------------------- 1 | use snowball::SnowballEnv; 2 | 3 | pub struct Among(pub &'static str, 4 | pub i32, 5 | pub i32, 6 | pub Option<&'static (dyn Fn(&mut SnowballEnv, &mut T) -> bool + Sync)>); 7 | -------------------------------------------------------------------------------- /pagefind_stem/src/snowball/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod algorithms; 2 | mod among; 3 | mod snowball_env; 4 | 5 | pub use snowball::among::Among; 6 | pub use snowball::snowball_env::SnowballEnv; 7 | -------------------------------------------------------------------------------- /pagefind_ui/default/.npmrc: -------------------------------------------------------------------------------- 1 | //registry.npmjs.org/:_authToken=${NPM_TOKEN} -------------------------------------------------------------------------------- /pagefind_ui/default/README.md: -------------------------------------------------------------------------------- 1 | # Pagefind Default UI 2 | 3 | 4 | Pagefind is a fully static search library that aims to perform well on large sites, while using as little of your users' bandwidth as possible. 5 | 6 | Pagefind runs after any static site generator and automatically indexes the built static files. Pagefind then outputs a static search bundle to your website, and exposes a JavaScript search API that can be used anywhere on your site. 7 | 8 | See the [Pagefind Documentation](https://pagefind.app/) for full usage. 9 | 10 | Quick usage: 11 | 12 | > These code snippets assume you have already indexed your website with the Pagefind CLI. 13 | 14 | ```js 15 | import { PagefindUI } from '@pagefind/default-ui' 16 | 17 | window.addEventListener('DOMContentLoaded', (event) => { 18 | new PagefindUI({ element: "#search" }); 19 | }); 20 | ``` 21 | 22 | With a bundler configuration that supports CSS: 23 | 24 | ```js 25 | import { PagefindUI } from '@pagefind/default-ui' 26 | import styles from "@pagefind/default-ui/css/ui.css"; 27 | 28 | window.addEventListener('DOMContentLoaded', (event) => { 29 | new PagefindUI({ element: "#search" }); 30 | }); 31 | ``` 32 | 33 | For all configuration options, see the [Pagefind Documentation](https://pagefind.app/). -------------------------------------------------------------------------------- /pagefind_ui/default/_dev_files/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Pagefind Local Dev Suite 10 | 11 | 12 |

Hello World from the local dev suite

13 |
14 | Shortcuts 15 |

Searches for words ending in y will return no results

16 |

Searches containing r will have a sub-result for the page itself

17 |

Searches containing d will have sub-results for anchors

18 |

Searches containing m will have metadata

19 |
20 | 21 | 22 | 25 | 26 | -------------------------------------------------------------------------------- /pagefind_ui/default/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@pagefind/default-ui", 3 | "version": "0.0.0", 4 | "type": "module", 5 | "main": "npm_dist/cjs/ui-core.cjs", 6 | "module": "npm_dist/mjs/ui-core.mjs", 7 | "scripts": { 8 | "start": "PAGEFIND_DEV=true node ./build.js", 9 | "build": "node ./build.js" 10 | }, 11 | "author": "Cloudcannon", 12 | "license": "MIT", 13 | "devDependencies": { 14 | "bcp-47": "^2.1.0", 15 | "esbuild": "^0.18.2", 16 | "esbuild-plugin-import-glob": "^0.1.1", 17 | "esbuild-svelte": "^0.7.3", 18 | "svelte": "^3.59.1", 19 | "typescript": "^5.1.3" 20 | }, 21 | "files": [ 22 | "npm_dist/**", 23 | "css/ui.css", 24 | "ui.js", 25 | "ui-core.js", 26 | "svelte/**" 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /pagefind_ui/default/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": [ 3 | "npm_dist/**/*.cjs", 4 | "npm_dist/**/*.mjs" 5 | ], 6 | "compilerOptions": { 7 | "declaration": true, 8 | "emitDeclarationOnly": true, 9 | "allowJs": true 10 | } 11 | } -------------------------------------------------------------------------------- /pagefind_ui/default/ui.js: -------------------------------------------------------------------------------- 1 | import { PagefindUI } from "./ui-core"; 2 | 3 | window.PagefindUI = PagefindUI; -------------------------------------------------------------------------------- /pagefind_ui/modular/.npmrc: -------------------------------------------------------------------------------- 1 | //registry.npmjs.org/:_authToken=${NPM_TOKEN} -------------------------------------------------------------------------------- /pagefind_ui/modular/helpers/element-builder.js: -------------------------------------------------------------------------------- 1 | export default class El { 2 | constructor(tagname) { 3 | this.element = document.createElement(tagname); 4 | } 5 | 6 | id(s) { 7 | this.element.id = s; 8 | return this; 9 | } 10 | 11 | class(s) { 12 | this.element.classList.add(s); 13 | return this; 14 | } 15 | 16 | attrs(obj) { 17 | for (const [k,v] of Object.entries(obj)) { 18 | this.element.setAttribute(k, v); 19 | } 20 | return this; 21 | } 22 | 23 | text(t) { 24 | this.element.innerText = t; 25 | return this; 26 | } 27 | 28 | html(t) { 29 | this.element.innerHTML = t; 30 | return this; 31 | } 32 | 33 | handle(e, f) { 34 | this.element.addEventListener(e, f); 35 | return this; 36 | } 37 | 38 | addTo(el) { 39 | if (el instanceof El) { 40 | el.element.appendChild(this.element); 41 | } else { 42 | el.appendChild(this.element); 43 | } 44 | return this.element; 45 | } 46 | } -------------------------------------------------------------------------------- /pagefind_ui/modular/modular.js: -------------------------------------------------------------------------------- 1 | import * as PMUI from "./modular-core"; 2 | 3 | window.PagefindModularUI = PMUI; -------------------------------------------------------------------------------- /pagefind_ui/modular/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@pagefind/modular-ui", 3 | "version": "0.0.0", 4 | "type": "module", 5 | "main": "npm_dist/cjs/modular-core.cjs", 6 | "module": "npm_dist/mjs/modular-core.mjs", 7 | "scripts": { 8 | "start": "PAGEFIND_DEV=true node ./build.js", 9 | "build": "node ./build.js" 10 | }, 11 | "author": "Cloudcannon", 12 | "license": "MIT", 13 | "devDependencies": { 14 | "bcp-47": "^2.1.0", 15 | "esbuild": "^0.19.0", 16 | "esbuild-plugin-import-glob": "^0.1.1", 17 | "typescript": "^5.2.2" 18 | }, 19 | "files": [ 20 | "npm_dist/**", 21 | "css/ui.css", 22 | "modular.js", 23 | "modular-core.js", 24 | "components/**", 25 | "helpers/**" 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /pagefind_ui/modular/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": [ 3 | "npm_dist/**/*.cjs", 4 | "npm_dist/**/*.mjs" 5 | ], 6 | "compilerOptions": { 7 | "declaration": true, 8 | "emitDeclarationOnly": true, 9 | "allowJs": true 10 | } 11 | } -------------------------------------------------------------------------------- /pagefind_ui/translations/af.json: -------------------------------------------------------------------------------- 1 | { 2 | "thanks_to": "Jan Claasen ", 3 | "comments": "", 4 | "direction": "ltr", 5 | "strings": { 6 | "placeholder": "Soek", 7 | "clear_search": "Opruim", 8 | "load_more": "Laai nog resultate", 9 | "search_label": "Soek hierdie webwerf", 10 | "filters_label": "Filters", 11 | "zero_results": "Geen resultate vir [SEARCH_TERM]", 12 | "many_results": "[COUNT] resultate vir [SEARCH_TERM]", 13 | "one_result": "[COUNT] resultate vir [SEARCH_TERM]", 14 | "alt_search": "Geen resultate vir [SEARCH_TERM]. Toon resultate vir [DIFFERENT_TERM] in plaas daarvan", 15 | "search_suggestion": "Geen resultate vir [SEARCH_TERM]. Probeer eerder een van die volgende terme:", 16 | "searching": "Soek vir [SEARCH_TERM]" 17 | } 18 | } -------------------------------------------------------------------------------- /pagefind_ui/translations/ar.json: -------------------------------------------------------------------------------- 1 | { 2 | "thanks_to": "Jermanuts", 3 | "comments": "", 4 | "direction": "rtl", 5 | "strings": { 6 | "placeholder": "بحث", 7 | "clear_search": "امسح", 8 | "load_more": "حمِّل المزيد من النتائج", 9 | "search_label": "ابحث في هذا الموقع", 10 | "filters_label": "تصفيات", 11 | "zero_results": "لا توجد نتائج ل [SEARCH_TERM]", 12 | "many_results": "[COUNT] نتائج ل [SEARCH_TERM]", 13 | "one_result": "[COUNT] نتيجة ل [SEARCH_TERM]", 14 | "alt_search": "لا توجد نتائج ل [SEARCH_TERM]. يعرض النتائج ل [DIFFERENT_TERM] بدلاً من ذلك", 15 | "search_suggestion": "لا توجد نتائج ل [SEARCH_TERM]. جرب أحد عمليات البحث التالية:", 16 | "searching": "يبحث عن [SEARCH_TERM]..." 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /pagefind_ui/translations/bn.json: -------------------------------------------------------------------------------- 1 | { 2 | "thanks_to": "Maruf Alom ", 3 | "comments": "", 4 | "direction": "ltr", 5 | "strings": { 6 | "placeholder": "অনুসন্ধান করুন", 7 | "clear_search": "মুছে ফেলুন", 8 | "load_more": "আরো ফলাফল দেখুন", 9 | "search_label": "এই ওয়েবসাইটে অনুসন্ধান করুন", 10 | "filters_label": "ফিল্টার", 11 | "zero_results": "[SEARCH_TERM] এর জন্য কিছু খুঁজে পাওয়া যায়নি", 12 | "many_results": "[COUNT]-টি ফলাফল পাওয়া গিয়েছে [SEARCH_TERM] এর জন্য", 13 | "one_result": "[COUNT]-টি ফলাফল পাওয়া গিয়েছে [SEARCH_TERM] এর জন্য", 14 | "alt_search": "কোন কিছু খুঁজে পাওয়া যায়নি [SEARCH_TERM] এর জন্য. পরিবর্তে [DIFFERENT_TERM] এর জন্য দেখানো হচ্ছে", 15 | "search_suggestion": "কোন কিছু খুঁজে পাওয়া যায়নি [SEARCH_TERM] এর বিষয়ে. নিন্মের বিষয়বস্তু খুঁজে দেখুন:", 16 | "searching": "অনুসন্ধান চলছে [SEARCH_TERM]..." 17 | } 18 | } -------------------------------------------------------------------------------- /pagefind_ui/translations/ca.json: -------------------------------------------------------------------------------- 1 | { 2 | "thanks_to": "Pablo Villaverde ", 3 | "comments": "", 4 | "direction": "ltr", 5 | "strings": { 6 | "placeholder": "Cerca", 7 | "clear_search": "Netejar", 8 | "load_more": "Veure més resultats", 9 | "search_label": "Cerca en aquest lloc", 10 | "filters_label": "Filtres", 11 | "zero_results": "No es van trobar resultats per [SEARCH_TERM]", 12 | "many_results": "[COUNT] resultats trobats per [SEARCH_TERM]", 13 | "one_result": "[COUNT] resultat trobat per [SEARCH_TERM]", 14 | "alt_search": "No es van trobar resultats per [SEARCH_TERM]. Mostrant al seu lloc resultats per [DIFFERENT_TERM]", 15 | "search_suggestion": "No es van trobar resultats per [SEARCH_TERM]. Proveu una de les cerques següents:", 16 | "searching": "Cercant [SEARCH_TERM]..." 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /pagefind_ui/translations/cs.json: -------------------------------------------------------------------------------- 1 | { 2 | "thanks_to": "Dalibor Hon ", 3 | "comments": "", 4 | "direction": "ltr", 5 | "strings": { 6 | "placeholder": "Hledat", 7 | "clear_search": "Smazat", 8 | "load_more": "Načíst další výsledky", 9 | "search_label": "Prohledat tuto stránku", 10 | "filters_label": "Filtry", 11 | "zero_results": "Žádné výsledky pro [SEARCH_TERM]", 12 | "many_results": "[COUNT] výsledků pro [SEARCH_TERM]", 13 | "one_result": "[COUNT] výsledek pro [SEARCH_TERM]", 14 | "alt_search": "Žádné výsledky pro [SEARCH_TERM]. Zobrazují se výsledky pro [DIFFERENT_TERM]", 15 | "search_suggestion": "Žádné výsledky pro [SEARCH_TERM]. Související výsledky hledání:", 16 | "searching": "Hledám [SEARCH_TERM]..." 17 | } 18 | } -------------------------------------------------------------------------------- /pagefind_ui/translations/da.json: -------------------------------------------------------------------------------- 1 | { 2 | "thanks_to": "Jonas Smedegaard ", 3 | "comments": "", 4 | "direction": "ltr", 5 | "strings": { 6 | "placeholder": "Søg", 7 | "clear_search": "Nulstil", 8 | "load_more": "Indlæs flere resultater", 9 | "search_label": "Søg på dette website", 10 | "filters_label": "Filtre", 11 | "zero_results": "Ingen resultater for [SEARCH_TERM]", 12 | "many_results": "[COUNT] resultater for [SEARCH_TERM]", 13 | "one_result": "[COUNT] resultat for [SEARCH_TERM]", 14 | "alt_search": "Ingen resultater for [SEARCH_TERM]. Viser resultater for [DIFFERENT_TERM] i stedet", 15 | "search_suggestion": "Ingen resultater for [SEARCH_TERM]. Prøv et af disse søgeord i stedet:", 16 | "searching": "Søger efter [SEARCH_TERM]..." 17 | } 18 | } -------------------------------------------------------------------------------- /pagefind_ui/translations/de.json: -------------------------------------------------------------------------------- 1 | { 2 | "thanks_to": "Jan Claasen ", 3 | "comments": "", 4 | "direction": "ltr", 5 | "strings": { 6 | "placeholder": "Suche", 7 | "clear_search": "Löschen", 8 | "load_more": "Mehr Ergebnisse laden", 9 | "search_label": "Suche diese Seite", 10 | "filters_label": "Filter", 11 | "zero_results": "Keine Ergebnisse für [SEARCH_TERM]", 12 | "many_results": "[COUNT] Ergebnisse für [SEARCH_TERM]", 13 | "one_result": "[COUNT] Ergebnis für [SEARCH_TERM]", 14 | "alt_search": "Keine Ergebnisse für [SEARCH_TERM]. Stattdessen werden Ergebnisse für [DIFFERENT_TERM] angezeigt", 15 | "search_suggestion": "Keine Ergebnisse für [SEARCH_TERM]. Versuchen Sie eine der folgenden Suchen:", 16 | "searching": "Suche für [SEARCH_TERM]" 17 | } 18 | } -------------------------------------------------------------------------------- /pagefind_ui/translations/en.json: -------------------------------------------------------------------------------- 1 | { 2 | "thanks_to": "Liam Bigelow ", 3 | "comments": "", 4 | "direction": "ltr", 5 | "strings": { 6 | "placeholder": "Search", 7 | "clear_search": "Clear", 8 | "load_more": "Load more results", 9 | "search_label": "Search this site", 10 | "filters_label": "Filters", 11 | "zero_results": "No results for [SEARCH_TERM]", 12 | "many_results": "[COUNT] results for [SEARCH_TERM]", 13 | "one_result": "[COUNT] result for [SEARCH_TERM]", 14 | "alt_search": "No results for [SEARCH_TERM]. Showing results for [DIFFERENT_TERM] instead", 15 | "search_suggestion": "No results for [SEARCH_TERM]. Try one of the following searches:", 16 | "searching": "Searching for [SEARCH_TERM]..." 17 | } 18 | } -------------------------------------------------------------------------------- /pagefind_ui/translations/es.json: -------------------------------------------------------------------------------- 1 | { 2 | "thanks_to": "Pablo Villaverde ", 3 | "comments": "", 4 | "direction": "ltr", 5 | "strings": { 6 | "placeholder": "Buscar", 7 | "clear_search": "Limpiar", 8 | "load_more": "Ver más resultados", 9 | "search_label": "Buscar en este sitio", 10 | "filters_label": "Filtros", 11 | "zero_results": "No se encontraron resultados para [SEARCH_TERM]", 12 | "many_results": "[COUNT] resultados encontrados para [SEARCH_TERM]", 13 | "one_result": "[COUNT] resultado encontrado para [SEARCH_TERM]", 14 | "alt_search": "No se encontraron resultados para [SEARCH_TERM]. Mostrando en su lugar resultados para [DIFFERENT_TERM]", 15 | "search_suggestion": "No se encontraron resultados para [SEARCH_TERM]. Prueba una de las siguientes búsquedas:", 16 | "searching": "Buscando [SEARCH_TERM]..." 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /pagefind_ui/translations/fa.json: -------------------------------------------------------------------------------- 1 | { 2 | "thanks_to": "Ali Khaleqi Yekta ", 3 | "comments": "", 4 | "direction": "rtl", 5 | "strings": { 6 | "placeholder": "جستجو", 7 | "clear_search": "پاکسازی", 8 | "load_more": "بارگذاری نتایج بیشتر", 9 | "search_label": "جستجو در سایت", 10 | "filters_label": "فیلترها", 11 | "zero_results": "نتیجه‌ای برای [SEARCH_TERM] یافت نشد", 12 | "many_results": "[COUNT] نتیجه برای [SEARCH_TERM] یافت شد", 13 | "one_result": "[COUNT] نتیجه برای [SEARCH_TERM] یافت شد", 14 | "alt_search": "نتیجه‌ای برای [SEARCH_TERM] یافت نشد. در عوض نتایج برای [DIFFERENT_TERM] نمایش داده می‌شود", 15 | "search_suggestion": "نتیجه‌ای برای [SEARCH_TERM] یافت نشد. یکی از جستجوهای زیر را امتحان کنید:", 16 | "searching": "در حال جستجوی [SEARCH_TERM]..." 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /pagefind_ui/translations/fi.json: -------------------------------------------------------------------------------- 1 | { 2 | "thanks_to": "Valtteri Laitinen ", 3 | "comments": "", 4 | "direction": "ltr", 5 | "strings": { 6 | "placeholder": "Haku", 7 | "clear_search": "Tyhjennä", 8 | "load_more": "Lataa lisää tuloksia", 9 | "search_label": "Hae tältä sivustolta", 10 | "filters_label": "Suodattimet", 11 | "zero_results": "Ei tuloksia haulle [SEARCH_TERM]", 12 | "many_results": "[COUNT] tulosta haulle [SEARCH_TERM]", 13 | "one_result": "[COUNT] tulos haulle [SEARCH_TERM]", 14 | "alt_search": "Ei tuloksia haulle [SEARCH_TERM]. Näytetään tulokset sen sijaan haulle [DIFFERENT_TERM]", 15 | "search_suggestion": "Ei tuloksia haulle [SEARCH_TERM]. Kokeile jotain seuraavista:", 16 | "searching": "Haetaan [SEARCH_TERM]..." 17 | } 18 | } -------------------------------------------------------------------------------- /pagefind_ui/translations/fr.json: -------------------------------------------------------------------------------- 1 | { 2 | "thanks_to": "Nicolas Friedli ", 3 | "comments": "", 4 | "direction": "ltr", 5 | "strings": { 6 | "placeholder": "Rechercher", 7 | "clear_search": "Nettoyer", 8 | "load_more": "Charger plus de résultats", 9 | "search_label": "Recherche sur ce site", 10 | "filters_label": "Filtres", 11 | "zero_results": "Pas de résultat pour [SEARCH_TERM]", 12 | "many_results": "[COUNT] résultats pour [SEARCH_TERM]", 13 | "one_result": "[COUNT] résultat pour [SEARCH_TERM]", 14 | "alt_search": "Pas de résultat pour [SEARCH_TERM]. Montre les résultats pour [DIFFERENT_TERM] à la place", 15 | "search_suggestion": "Pas de résultat pour [SEARCH_TERM]. Essayer une des recherches suivantes:", 16 | "searching": "Recherche [SEARCH_TERM]..." 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /pagefind_ui/translations/gl.json: -------------------------------------------------------------------------------- 1 | { 2 | "thanks_to": "Pablo Villaverde ", 3 | "comments": "", 4 | "direction": "ltr", 5 | "strings": { 6 | "placeholder": "Buscar", 7 | "clear_search": "Limpar", 8 | "load_more": "Ver máis resultados", 9 | "search_label": "Buscar neste sitio", 10 | "filters_label": "Filtros", 11 | "zero_results": "Non se atoparon resultados para [SEARCH_TERM]", 12 | "many_results": "[COUNT] resultados atopados para [SEARCH_TERM]", 13 | "one_result": "[COUNT] resultado atopado para [SEARCH_TERM]", 14 | "alt_search": "Non se atoparon resultados para [SEARCH_TERM]. Amosando no seu lugar resultados para [DIFFERENT_TERM]", 15 | "search_suggestion": "Non se atoparon resultados para [SEARCH_TERM]. Probe unha das seguintes pesquisas:", 16 | "searching": "Buscando [SEARCH_TERM]..." 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /pagefind_ui/translations/he.json: -------------------------------------------------------------------------------- 1 | { 2 | "thanks_to": "Nir Tamir ", 3 | "comments": "", 4 | "direction": "rtl", 5 | "strings": { 6 | "placeholder": "חיפוש", 7 | "clear_search": "ניקוי", 8 | "load_more": "עוד תוצאות", 9 | "search_label": "חיפוש באתר זה", 10 | "filters_label": "מסננים", 11 | "zero_results": "לא נמצאו תוצאות עבור [SEARCH_TERM]", 12 | "many_results": "נמצאו [COUNT] תוצאות עבור [SEARCH_TERM]", 13 | "one_result": "נמצאה תוצאה אחת עבור [SEARCH_TERM]", 14 | "alt_search": "לא נמצאו תוצאות עבור [SEARCH_TERM]. מוצגות תוצאות עבור [DIFFERENT_TERM]", 15 | "search_suggestion": "לא נמצאו תוצאות עבור [SEARCH_TERM]. נסו אחד מהחיפושים הבאים:", 16 | "searching": "מחפש את [SEARCH_TERM]..." 17 | } 18 | } -------------------------------------------------------------------------------- /pagefind_ui/translations/hi.json: -------------------------------------------------------------------------------- 1 | { 2 | "thanks_to": "Amit Yadav ", 3 | "comments": "", 4 | "direction": "ltr", 5 | "strings": { 6 | "placeholder": "खोजें", 7 | "clear_search": "साफ करें", 8 | "load_more": "और अधिक परिणाम लोड करें", 9 | "search_label": "इस साइट में खोजें", 10 | "filters_label": "फ़िल्टर", 11 | "zero_results": "कोई परिणाम [SEARCH_TERM] के लिए नहीं मिला", 12 | "many_results": "[COUNT] परिणाम [SEARCH_TERM] के लिए मिले", 13 | "one_result": "[COUNT] परिणाम [SEARCH_TERM] के लिए मिला", 14 | "alt_search": "[SEARCH_TERM] के लिए कोई परिणाम नहीं मिला। इसके बजाय [DIFFERENT_TERM] के लिए परिणाम दिखा रहा है", 15 | "search_suggestion": "[SEARCH_TERM] के लिए कोई परिणाम नहीं मिला। निम्नलिखित खोजों में से कोई एक आज़माएं:", 16 | "searching": "[SEARCH_TERM] की खोज की जा रही है..." 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /pagefind_ui/translations/hr.json: -------------------------------------------------------------------------------- 1 | { 2 | "thanks_to": "Diomed ", 3 | "comments": "", 4 | "direction": "ltr", 5 | "strings": { 6 | "placeholder": "Traži", 7 | "clear_search": "Očisti", 8 | "load_more": "Učitaj više rezultata", 9 | "search_label": "Pretraži ovu stranicu", 10 | "filters_label": "Filteri", 11 | "zero_results": "Nema rezultata za [SEARCH_TERM]", 12 | "many_results": "[COUNT] rezultata za [SEARCH_TERM]", 13 | "one_result": "[COUNT] rezultat za [SEARCH_TERM]", 14 | "alt_search": "Nema rezultata za [SEARCH_TERM]. Prikazujem rezultate za [DIFFERENT_TERM]", 15 | "search_suggestion": "Nema rezultata za [SEARCH_TERM]. Pokušaj s jednom od ovih pretraga:", 16 | "searching": "Pretražujem [SEARCH_TERM]..." 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /pagefind_ui/translations/hu.json: -------------------------------------------------------------------------------- 1 | { 2 | "thanks_to": "Adam Laki ", 3 | "comments": "", 4 | "direction": "ltr", 5 | "strings": { 6 | "placeholder": "Keresés", 7 | "clear_search": "Törlés", 8 | "load_more": "További találatok betöltése", 9 | "search_label": "Keresés az oldalon", 10 | "filters_label": "Szűrés", 11 | "zero_results": "Nincs találat a(z) [SEARCH_TERM] kifejezésre", 12 | "many_results": "[COUNT] db találat a(z) [SEARCH_TERM] kifejezésre", 13 | "one_result": "[COUNT] db találat a(z) [SEARCH_TERM] kifejezésre", 14 | "alt_search": "Nincs találat a(z) [SEARCH_TERM] kifejezésre. Találatok mutatása inkább a(z) [DIFFERENT_TERM] kifejezésre", 15 | "search_suggestion": "Nincs találat a(z) [SEARCH_TERM] kifejezésre. Próbáld meg a következő keresések egyikét:", 16 | "searching": "Keresés a(z) [SEARCH_TERM] kifejezésre..." 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /pagefind_ui/translations/id.json: -------------------------------------------------------------------------------- 1 | { 2 | "thanks_to": "Nixentric", 3 | "comments": "", 4 | "direction": "ltr", 5 | "strings": { 6 | "placeholder": "Cari", 7 | "clear_search": "Bersihkan", 8 | "load_more": "Muat lebih banyak hasil", 9 | "search_label": "Telusuri situs ini", 10 | "filters_label": "Filter", 11 | "zero_results": "[SEARCH_TERM] tidak ditemukan", 12 | "many_results": "Ditemukan [COUNT] hasil untuk [SEARCH_TERM]", 13 | "one_result": "Ditemukan [COUNT] hasil untuk [SEARCH_TERM]", 14 | "alt_search": "[SEARCH_TERM] tidak ditemukan. Menampilkan hasil [DIFFERENT_TERM] sebagai gantinya", 15 | "search_suggestion": "[SEARCH_TERM] tidak ditemukan. Coba salah satu pencarian berikut ini:", 16 | "searching": "Mencari [SEARCH_TERM]..." 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /pagefind_ui/translations/it.json: -------------------------------------------------------------------------------- 1 | { 2 | "thanks_to": "Cosette Bruhns Alonso, Andrew Janco ", 3 | "comments": "", 4 | "direction": "ltr", 5 | "strings": { 6 | "placeholder": "Cerca", 7 | "clear_search": "Cancella la cronologia", 8 | "load_more": "Mostra più risultati", 9 | "search_label": "Cerca nel sito", 10 | "filters_label": "Filtri di ricerca", 11 | "zero_results": "Nessun risultato per [SEARCH_TERM]", 12 | "many_results": "[COUNT] risultati per [SEARCH_TERM]", 13 | "one_result": "[COUNT] risultato per [SEARCH_TERM]", 14 | "alt_search": "Nessun risultato per [SEARCH_TERM]. Mostrando risultati per [DIFFERENT_TERM] come alternativa.", 15 | "search_suggestion": "Nessun risultato per [SEARCH_TERM]. Prova una delle seguenti ricerche:", 16 | "searching": "Cercando [SEARCH_TERM]..." 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /pagefind_ui/translations/ja.json: -------------------------------------------------------------------------------- 1 | { 2 | "thanks_to": "Tate", 3 | "comments": "", 4 | "direction": "ltr", 5 | "strings": { 6 | "placeholder": "検索", 7 | "clear_search": "クリア", 8 | "load_more": "次を読み込む", 9 | "search_label": "このサイトを検索", 10 | "filters_label": "フィルタ", 11 | "zero_results": "[SEARCH_TERM]の検索に一致する情報はありませんでした", 12 | "many_results": "[SEARCH_TERM]の[COUNT]件の検索結果", 13 | "one_result": "[SEARCH_TERM]の[COUNT]件の検索結果", 14 | "alt_search": "[SEARCH_TERM]の検索に一致する情報はありませんでした。[DIFFERENT_TERM]の検索結果を表示しています", 15 | "search_suggestion": "[SEARCH_TERM]の検索に一致する情報はありませんでした。次のいずれかの検索を試してください", 16 | "searching": "[SEARCH_TERM]を検索しています" 17 | } 18 | } -------------------------------------------------------------------------------- /pagefind_ui/translations/ko.json: -------------------------------------------------------------------------------- 1 | { 2 | "thanks_to": "Seokho Son ", 3 | "comments": "", 4 | "direction": "ltr", 5 | "strings": { 6 | "placeholder": "검색어", 7 | "clear_search": "비우기", 8 | "load_more": "검색 결과 더 보기", 9 | "search_label": "사이트 검색", 10 | "filters_label": "필터", 11 | "zero_results": "[SEARCH_TERM]에 대한 결과 없음", 12 | "many_results": "[SEARCH_TERM]에 대한 결과 [COUNT]건", 13 | "one_result": "[SEARCH_TERM]에 대한 결과 [COUNT]건", 14 | "alt_search": "[SEARCH_TERM]에 대한 결과 없음. [DIFFERENT_TERM]에 대한 결과", 15 | "search_suggestion": "[SEARCH_TERM]에 대한 결과 없음. 추천 검색어: ", 16 | "searching": "[SEARCH_TERM] 검색 중..." 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /pagefind_ui/translations/mi.json: -------------------------------------------------------------------------------- 1 | { 2 | "thanks_to": "", 3 | "comments": "", 4 | "direction": "ltr", 5 | "strings": { 6 | "placeholder": "Rapu", 7 | "clear_search": "Whakakore", 8 | "load_more": "Whakauta ētahi otinga kē", 9 | "search_label": "Rapu", 10 | "filters_label": "Tātari", 11 | "zero_results": "Otinga kore ki [SEARCH_TERM]", 12 | "many_results": "[COUNT] otinga ki [SEARCH_TERM]", 13 | "one_result": "[COUNT] otinga ki [SEARCH_TERM]", 14 | "alt_search": "Otinga kore ki [SEARCH_TERM]. Otinga kē ki [DIFFERENT_TERM]", 15 | "search_suggestion": "Otinga kore ki [SEARCH_TERM]. whakamātau ki ngā mea atu:", 16 | "searching": "Rapu ki [SEARCH_TERM]..." 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /pagefind_ui/translations/my.json: -------------------------------------------------------------------------------- 1 | { 2 | "thanks_to": "Harry Min Khant ", 3 | "comments": "", 4 | "direction": "ltr", 5 | "strings": { 6 | "placeholder": "ရှာရန်", 7 | "clear_search": "ရှာဖွေမှုကို ရှင်းလင်းပါ။", 8 | "load_more": "နောက်ထပ်ရလဒ်များကို တင်ပါ။", 9 | "search_label": "ဤဆိုက်တွင်ရှာဖွေပါ။", 10 | "filters_label": "စစ်ထုတ်မှုများ", 11 | "zero_results": "[SEARCH_TERM] အတွက် ရလဒ်များ မရှိပါ", 12 | "many_results": "[SEARCH_TERM] အတွက် ရလဒ် [COUNT] ခု", 13 | "one_result": "[SEARCH_TERM] အတွက် ရလဒ် [COUNT]", 14 | "alt_search": "[SEARCH_TERM] အတွက် ရလဒ်မရှိပါ။ ၎င်းအစား [DIFFERENT_TERM] အတွက် ရလဒ်များကို ပြသသည်။", 15 | "search_suggestion": "[SEARCH_TERM] အတွက် ရလဒ်မရှိပါ။ အောက်ပါရှာဖွေမှုများထဲမှ တစ်ခုကို စမ်းကြည့်ပါ:", 16 | "searching": "[SEARCH_TERM] ကို ရှာဖွေနေသည်..." 17 | } 18 | } -------------------------------------------------------------------------------- /pagefind_ui/translations/nl.json: -------------------------------------------------------------------------------- 1 | { 2 | "thanks_to": "Paul van Brouwershaven", 3 | "comments": "", 4 | "direction": "ltr", 5 | "strings": { 6 | "placeholder": "Zoeken", 7 | "clear_search": "Reset", 8 | "load_more": "Meer resultaten laden", 9 | "search_label": "Doorzoek deze site", 10 | "filters_label": "Filters", 11 | "zero_results": "Geen resultaten voor [SEARCH_TERM]", 12 | "many_results": "[COUNT] resultaten voor [SEARCH_TERM]", 13 | "one_result": "[COUNT] resultaat voor [SEARCH_TERM]", 14 | "alt_search": "Geen resultaten voor [SEARCH_TERM]. In plaats daarvan worden resultaten voor [DIFFERENT_TERM] weergegeven", 15 | "search_suggestion": "Geen resultaten voor [SEARCH_TERM]. Probeer een van de volgende zoekopdrachten:", 16 | "searching": "Zoeken naar [SEARCH_TERM]..." 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /pagefind_ui/translations/no.json: -------------------------------------------------------------------------------- 1 | { 2 | "thanks_to": "Christopher Wingate", 3 | "comments": "", 4 | "direction": "ltr", 5 | "strings": { 6 | "placeholder": "Søk", 7 | "clear_search": "Fjern", 8 | "load_more": "Last flere resultater", 9 | "search_label": "Søk på denne siden", 10 | "filters_label": "Filtre", 11 | "zero_results": "Ingen resultater for [SEARCH_TERM]", 12 | "many_results": "[COUNT] resultater for [SEARCH_TERM]", 13 | "one_result": "[COUNT] resultat for [SEARCH_TERM]", 14 | "alt_search": "Ingen resultater for [SEARCH_TERM]. Viser resultater for [DIFFERENT_TERM] i stedet", 15 | "search_suggestion": "Ingen resultater for [SEARCH_TERM]. Prøv en av disse søkeordene i stedet:", 16 | "searching": "Søker etter [SEARCH_TERM]" 17 | } 18 | } -------------------------------------------------------------------------------- /pagefind_ui/translations/pl.json: -------------------------------------------------------------------------------- 1 | { 2 | "thanks_to": "", 3 | "comments": "", 4 | "direction": "ltr", 5 | "strings": { 6 | "placeholder": "Szukaj", 7 | "clear_search": "Wyczyść", 8 | "load_more": "Załaduj więcej", 9 | "search_label": "Przeszukaj tę stronę", 10 | "filters_label": "Filtry", 11 | "zero_results": "Brak wyników dla [SEARCH_TERM]", 12 | "many_results": "[COUNT] wyników dla [SEARCH_TERM]", 13 | "one_result": "[COUNT] wynik dla [SEARCH_TERM]", 14 | "alt_search": "Brak wyników dla [SEARCH_TERM]. Wyświetlam wyniki dla [DIFFERENT_TERM]", 15 | "search_suggestion": "Brak wyników dla [SEARCH_TERM]. Pokrewne wyniki wyszukiwania:", 16 | "searching": "Szukam [SEARCH_TERM]..." 17 | } 18 | } -------------------------------------------------------------------------------- /pagefind_ui/translations/pt.json: -------------------------------------------------------------------------------- 1 | { 2 | "thanks_to": "Jonatah", 3 | "comments": "", 4 | "direction": "ltr", 5 | "strings": { 6 | "placeholder": "Pesquisar", 7 | "clear_search": "Limpar", 8 | "load_more": "Ver mais resultados", 9 | "search_label": "Pesquisar", 10 | "filters_label": "Filtros", 11 | "zero_results": "Nenhum resultado encontrado para [SEARCH_TERM]", 12 | "many_results": "[COUNT] resultados encontrados para [SEARCH_TERM]", 13 | "one_result": "[COUNT] resultado encontrado para [SEARCH_TERM]", 14 | "alt_search": "Nenhum resultado encontrado para [SEARCH_TERM]. Exibindo resultados para [DIFFERENT_TERM]", 15 | "search_suggestion": "Nenhum resultado encontrado para [SEARCH_TERM]. Tente uma das seguintes pesquisas:", 16 | "searching": "Pesquisando por [SEARCH_TERM]..." 17 | } 18 | } -------------------------------------------------------------------------------- /pagefind_ui/translations/ro.json: -------------------------------------------------------------------------------- 1 | { 2 | "thanks_to": "Bogdan Mateescu ", 3 | "comments": "", 4 | "direction": "ltr", 5 | "strings": { 6 | "placeholder": "Căutare", 7 | "clear_search": "Ştergeţi", 8 | "load_more": "Încărcați mai multe rezultate", 9 | "search_label": "Căutați în acest site", 10 | "filters_label": "Filtre", 11 | "zero_results": "Niciun rezultat pentru [SEARCH_TERM]", 12 | "many_results": "[COUNT] rezultate pentru [SEARCH_TERM]", 13 | "one_result": "[COUNT] rezultat pentru [SEARCH_TERM]", 14 | "alt_search": "Niciun rezultat pentru [SEARCH_TERM]. Se afișează în schimb rezultatele pentru [DIFFERENT_TERM]", 15 | "search_suggestion": "Niciun rezultat pentru [SEARCH_TERM]. Încercați una dintre următoarele căutări:", 16 | "searching": "Se caută după: [SEARCH_TERM]..." 17 | } 18 | } -------------------------------------------------------------------------------- /pagefind_ui/translations/ru.json: -------------------------------------------------------------------------------- 1 | { 2 | "thanks_to": "Aleksandr Gordeev", 3 | "comments": "", 4 | "direction": "ltr", 5 | "strings": { 6 | "placeholder": "Поиск", 7 | "clear_search": "Очистить поле", 8 | "load_more": "Загрузить еще", 9 | "search_label": "Поиск по сайту", 10 | "filters_label": "Фильтры", 11 | "zero_results": "Ничего не найдено по запросу: [SEARCH_TERM]", 12 | "many_results": "[COUNT] результатов по запросу: [SEARCH_TERM]", 13 | "one_result": "[COUNT] результат по запросу: [SEARCH_TERM]", 14 | "alt_search": "Ничего не найдено по запросу: [SEARCH_TERM]. Показаны результаты по запросу: [DIFFERENT_TERM]", 15 | "search_suggestion": "Ничего не найдено по запросу: [SEARCH_TERM]. Попробуйте один из следующих вариантов", 16 | "searching": "Поиск по запросу: [SEARCH_TERM]" 17 | } 18 | } -------------------------------------------------------------------------------- /pagefind_ui/translations/sr.json: -------------------------------------------------------------------------------- 1 | { 2 | "thanks_to": "Andrija Sagicc", 3 | "comments": "", 4 | "direction": "ltr", 5 | "strings": { 6 | "placeholder": "Претрага", 7 | "clear_search": "Брисање", 8 | "load_more": "Приказ више резултата", 9 | "search_label": "Претрага сајта", 10 | "filters_label": "Филтери", 11 | "zero_results": "Нема резултата за [SEARCH_TERM]", 12 | "many_results": "[COUNT] резултата за [SEARCH_TERM]", 13 | "one_result": "[COUNT] резултата за [SEARCH_TERM]", 14 | "alt_search": "Нема резултата за [SEARCH_TERM]. Приказ додатник резултата за [DIFFERENT_TERM]", 15 | "search_suggestion": "Нема резултата за [SEARCH_TERM]. Покушајте са неком од следећих претрага:", 16 | "searching": "Претрага термина [SEARCH_TERM]..." 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /pagefind_ui/translations/sv.json: -------------------------------------------------------------------------------- 1 | { 2 | "thanks_to": "Montazar Al-Jaber ", 3 | "comments": "", 4 | "direction": "ltr", 5 | "strings": { 6 | "placeholder": "Sök", 7 | "clear_search": "Rensa", 8 | "load_more": "Visa fler träffar", 9 | "search_label": "Sök på denna sida", 10 | "filters_label": "Filter", 11 | "zero_results": "[SEARCH_TERM] gav inga träffar", 12 | "many_results": "[SEARCH_TERM] gav [COUNT] träffar", 13 | "one_result": "[SEARCH_TERM] gav [COUNT] träff", 14 | "alt_search": "[SEARCH_TERM] gav inga träffar. Visar resultat för [DIFFERENT_TERM] istället", 15 | "search_suggestion": "[SEARCH_TERM] gav inga träffar. Försök igen med en av följande sökord:", 16 | "searching": "Söker efter [SEARCH_TERM]..." 17 | } 18 | } -------------------------------------------------------------------------------- /pagefind_ui/translations/sw.json: -------------------------------------------------------------------------------- 1 | { 2 | "thanks_to": "Anonymous", 3 | "comments": "", 4 | "direction": "ltr", 5 | "strings": { 6 | "placeholder": "Tafuta", 7 | "clear_search": "Futa", 8 | "load_more": "Pakia matokeo zaidi", 9 | "search_label": "Tafuta tovuti hii", 10 | "filters_label": "Vichujio", 11 | "zero_results": "Hakuna matokeo ya [SEARCH_TERM]", 12 | "many_results": "Matokeo [COUNT] ya [SEARCH_TERM]", 13 | "one_result": "Tokeo [COUNT] la [SEARCH_TERM]", 14 | "alt_search": "Hakuna mayokeo ya [SEARCH_TERM]. Badala yake, inaonyesha matokeo ya [DIFFERENT_TERM]", 15 | "search_suggestion": "Hakuna matokeo ya [SEARCH_TERM]. Jaribu mojawapo ya utafutaji ufuatao:", 16 | "searching": "Kutafuta [SEARCH_TERM]..." 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /pagefind_ui/translations/ta.json: -------------------------------------------------------------------------------- 1 | { 2 | "thanks_to": "", 3 | "comments": "", 4 | "direction": "ltr", 5 | "strings": { 6 | "placeholder": "தேடுக", 7 | "clear_search": "அழிக்குக", 8 | "load_more": "மேலும் முடிவுகளைக் காட்டுக", 9 | "search_label": "இந்த தளத்தில் தேடுக", 10 | "filters_label": "வடிகட்டல்கள்", 11 | "zero_results": "[SEARCH_TERM] க்கான முடிவுகள் இல்லை", 12 | "many_results": "[SEARCH_TERM] க்கான [COUNT] முடிவுகள்", 13 | "one_result": "[SEARCH_TERM] க்கான முடிவு", 14 | "alt_search": "[SEARCH_TERM] இத்தேடலுக்கான முடிவுகள் இல்லை, இந்த தேடல்களுக்கான ஒத்த முடிவுகள் [DIFFERENT_TERM]", 15 | "search_suggestion": "[SEARCH_TERM] இத் தேடலுக்கான முடிவுகள் இல்லை.இதற்கு பதிலீடான தேடல்களை தேடுக:", 16 | "searching": "[SEARCH_TERM] தேடப்படுகின்றது" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /pagefind_ui/translations/th.json: -------------------------------------------------------------------------------- 1 | { 2 | "thanks_to": "Patiphon Loetsuthakun ", 3 | "comments": "", 4 | "direction": "ltr", 5 | "strings": { 6 | "placeholder": "ค้นหา", 7 | "clear_search": "ล้าง", 8 | "load_more": "โหลดผลลัพธ์เพิ่มเติม", 9 | "search_label": "ค้นหาบนเว็บไซต์", 10 | "filters_label": "ตัวกรอง", 11 | "zero_results": "ไม่พบผลลัพธ์สำหรับ [SEARCH_TERM]", 12 | "many_results": "พบ [COUNT] ผลการค้นหาสำหรับ [SEARCH_TERM]", 13 | "one_result": "พบ [COUNT] ผลการค้นหาสำหรับ [SEARCH_TERM]", 14 | "alt_search": "ไม่พบผลลัพธ์สำหรับ [SEARCH_TERM] แสดงผลลัพธ์จากการค้นหา [DIFFERENT_TERM] แทน", 15 | "search_suggestion": "ไม่พบผลลัพธ์สำหรับ [SEARCH_TERM] ลองคำค้นหาเหล่านี้แทน:", 16 | "searching": "กำลังค้นหา [SEARCH_TERM]..." 17 | } 18 | } -------------------------------------------------------------------------------- /pagefind_ui/translations/tr.json: -------------------------------------------------------------------------------- 1 | { 2 | "thanks_to": "Taylan Özgür Bildik", 3 | "comments": "", 4 | "direction": "ltr", 5 | "strings": { 6 | "placeholder": "Araştır", 7 | "clear_search": "Temizle", 8 | "load_more": "Daha fazla sonuç", 9 | "search_label": "Site genelinde arama", 10 | "filters_label": "Filtreler", 11 | "zero_results": "[SEARCH_TERM] için sonuç yok", 12 | "many_results": "[SEARCH_TERM] için [COUNT] sonuç bulundu", 13 | "one_result": "[SEARCH_TERM] için [COUNT] sonuç bulundu", 14 | "alt_search": "[SEARCH_TERM] için sonuç yok. Bunun yerine [DIFFERENT_TERM] için sonuçlar gösteriliyor", 15 | "search_suggestion": "[SEARCH_TERM] için sonuç yok. Alternatif olarak aşağıdaki kelimelerden birini deneyebilirsiniz:", 16 | "searching": "[SEARCH_TERM] araştırılıyor..." 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /pagefind_ui/translations/uk.json: -------------------------------------------------------------------------------- 1 | { 2 | "thanks_to": "Vladyslav Lyshenko ", 3 | "comments": "", 4 | "direction": "ltr", 5 | "strings": { 6 | "placeholder": "Пошук", 7 | "clear_search": "Очистити поле", 8 | "load_more": "Завантажити ще", 9 | "search_label": "Пошук по сайту", 10 | "filters_label": "Фільтри", 11 | "zero_results": "Нічого не знайдено за запитом: [SEARCH_TERM]", 12 | "many_results": "[COUNT] результатів на запит: [SEARCH_TERM]", 13 | "one_result": "[COUNT] результат за запитом: [SEARCH_TERM]", 14 | "alt_search": "Нічого не знайдено на запит: [SEARCH_TERM]. Показано результати на запит: [DIFFERENT_TERM]", 15 | "search_suggestion": "Нічого не знайдено на запит: [SEARCH_TERM]. Спробуйте один із таких варіантів", 16 | "searching": "Пошук за запитом: [SEARCH_TERM]" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /pagefind_ui/translations/vi.json: -------------------------------------------------------------------------------- 1 | { 2 | "thanks_to": "Long Nhat Nguyen", 3 | "comments": "", 4 | "direction": "ltr", 5 | "strings": { 6 | "placeholder": "Tìm kiếm", 7 | "clear_search": "Xóa", 8 | "load_more": "Nhiều kết quả hơn", 9 | "search_label": "Tìm kiếm trong trang này", 10 | "filters_label": "Bộ lọc", 11 | "zero_results": "Không tìm thấy kết quả cho [SEARCH_TERM]", 12 | "many_results": "[COUNT] kết quả cho [SEARCH_TERM]", 13 | "one_result": "[COUNT] kết quả cho [SEARCH_TERM]", 14 | "alt_search": "Không tìm thấy kết quả cho [SEARCH_TERM]. Kiểm thị kết quả thay thế với [DIFFERENT_TERM]", 15 | "search_suggestion": "Không tìm thấy kết quả cho [SEARCH_TERM]. Thử một trong các tìm kiếm:", 16 | "searching": "Đang tìm kiếm cho [SEARCH_TERM]..." 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /pagefind_ui/translations/zh-cn.json: -------------------------------------------------------------------------------- 1 | { 2 | "thanks_to": "Amber Song", 3 | "comments": "", 4 | "direction": "ltr", 5 | "strings": { 6 | "placeholder": "搜索", 7 | "clear_search": "清除", 8 | "load_more": "加载更多结果", 9 | "search_label": "站内搜索", 10 | "filters_label": "筛选", 11 | "zero_results": "未找到 [SEARCH_TERM] 的相关结果", 12 | "many_results": "找到 [COUNT] 个 [SEARCH_TERM] 的相关结果", 13 | "one_result": "找到 [COUNT] 个 [SEARCH_TERM] 的相关结果", 14 | "alt_search": "未找到 [SEARCH_TERM] 的相关结果。改为显示 [DIFFERENT_TERM] 的相关结果", 15 | "search_suggestion": "未找到 [SEARCH_TERM] 的相关结果。请尝试以下搜索。", 16 | "searching": "正在搜索 [SEARCH_TERM]..." 17 | } 18 | } -------------------------------------------------------------------------------- /pagefind_ui/translations/zh-tw.json: -------------------------------------------------------------------------------- 1 | { 2 | "thanks_to": "Amber Song", 3 | "comments": "", 4 | "direction": "ltr", 5 | "strings": { 6 | "placeholder": "搜索", 7 | "clear_search": "清除", 8 | "load_more": "加載更多結果", 9 | "search_label": "站內搜索", 10 | "filters_label": "篩選", 11 | "zero_results": "未找到 [SEARCH_TERM] 的相關結果", 12 | "many_results": "找到 [COUNT] 個 [SEARCH_TERM] 的相關結果", 13 | "one_result": "找到 [COUNT] 個 [SEARCH_TERM] 的相關結果", 14 | "alt_search": "未找到 [SEARCH_TERM] 的相關結果。改為顯示 [DIFFERENT_TERM] 的相關結果", 15 | "search_suggestion": "未找到 [SEARCH_TERM] 的相關結果。請嘗試以下搜索。", 16 | "searching": "正在搜索 [SEARCH_TERM]..." 17 | } 18 | } -------------------------------------------------------------------------------- /pagefind_ui/translations/zh.json: -------------------------------------------------------------------------------- 1 | { 2 | "thanks_to": "Amber Song", 3 | "comments": "", 4 | "direction": "ltr", 5 | "strings": { 6 | "placeholder": "搜索", 7 | "clear_search": "清除", 8 | "load_more": "加载更多结果", 9 | "search_label": "站内搜索", 10 | "filters_label": "筛选", 11 | "zero_results": "未找到 [SEARCH_TERM] 的相关结果", 12 | "many_results": "找到 [COUNT] 个 [SEARCH_TERM] 的相关结果", 13 | "one_result": "找到 [COUNT] 个 [SEARCH_TERM] 的相关结果", 14 | "alt_search": "未找到 [SEARCH_TERM] 的相关结果。改为显示 [DIFFERENT_TERM] 的相关结果", 15 | "search_suggestion": "未找到 [SEARCH_TERM] 的相关结果。请尝试以下搜索。", 16 | "searching": "正在搜索 [SEARCH_TERM]..." 17 | } 18 | } -------------------------------------------------------------------------------- /pagefind_web/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "rust-analyzer.cargo.target": "wasm32-unknown-unknown", 3 | } -------------------------------------------------------------------------------- /pagefind_web/build.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs"); 2 | const path = require("path"); 3 | 4 | const web_js_file = path.join(__dirname, "pkg/pagefind_web.js"); 5 | let web_js = fs.readFileSync(web_js_file, { encoding: "utf-8" }); 6 | 7 | // document.currentScript.src breaks in the module context 8 | // and is never a code path we need, so we nix that from the 9 | // generated javascript. 10 | web_js = web_js.replace(/document\..?currentScript\..?src/, `"UNHANDLED"`); 11 | 12 | fs.writeFileSync(web_js_file, web_js); 13 | -------------------------------------------------------------------------------- /pagefind_web/local_debug_build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ./local_build.sh debug 4 | -------------------------------------------------------------------------------- /pagefind_web/local_fast_debug_build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ./local_fast_build.sh debug 4 | -------------------------------------------------------------------------------- /pagefind_web/src/util.rs: -------------------------------------------------------------------------------- 1 | macro_rules! debug { 2 | ($log:block) => {{ 3 | #[cfg(debug_assertions)] 4 | use crate::debug_log; 5 | #[cfg(debug_assertions)] 6 | debug_log(&$log); 7 | }}; 8 | } 9 | pub(crate) use debug; 10 | 11 | macro_rules! consume_fixed_arr { 12 | ($decoder:ident) => { 13 | $decoder.array()? 14 | }; 15 | } 16 | pub(crate) use consume_fixed_arr; 17 | 18 | macro_rules! consume_arr_len { 19 | ($decoder:ident) => { 20 | match $decoder.array()? { 21 | Some(n) => n, 22 | None => return Err(decode::Error::message("Array length not specified")), 23 | } 24 | }; 25 | } 26 | pub(crate) use consume_arr_len; 27 | 28 | macro_rules! consume_string { 29 | ($decoder:ident) => { 30 | $decoder.str()?.to_owned() 31 | }; 32 | } 33 | pub(crate) use consume_string; 34 | 35 | macro_rules! consume_num { 36 | ($decoder:ident) => { 37 | $decoder.u32()? 38 | }; 39 | } 40 | pub(crate) use consume_num; 41 | 42 | macro_rules! consume_inum { 43 | ($decoder:ident) => { 44 | $decoder.i32()? 45 | }; 46 | } 47 | pub(crate) use consume_inum; 48 | -------------------------------------------------------------------------------- /pagefind_web_js/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@pagefind/js", 3 | "version": "0.0.0", 4 | "type": "module", 5 | "main": "npm_dist/cjs/js-api.cjs", 6 | "module": "npm_dist/mjs/js-api.mjs", 7 | "scripts": { 8 | "build-coupled": "node ./build.js", 9 | "test": "ava" 10 | }, 11 | "author": "Cloudcannon", 12 | "license": "MIT", 13 | "devDependencies": { 14 | "ava": "^5.3.1", 15 | "esbuild": "^0.19.0", 16 | "tsx": "^3.12.8", 17 | "typescript": "^5.2.2" 18 | }, 19 | "files": [ 20 | "src/types/**" 21 | ], 22 | "ava": { 23 | "extensions": { 24 | "ts": "module" 25 | }, 26 | "nodeArguments": [ 27 | "--loader=tsx" 28 | ] 29 | }, 30 | "dependencies": { 31 | "@types/mark.js": "^8.11.8", 32 | "mark.js": "^8.11.1" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /pagefind_web_js/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowJs": true, 4 | "checkJs": true, 5 | "noEmit": true, 6 | "strict": true, 7 | "target": "es2020", 8 | "module": "es2022", 9 | "moduleResolution": "node", 10 | "allowSyntheticDefaultImports": true, 11 | "paths": { 12 | "pagefindWeb": [ 13 | "./types/index" 14 | ], 15 | "pagefindWebInternal": [ 16 | "./types/internal" 17 | ], 18 | }, 19 | "noUnusedLocals": true, 20 | "noUnusedParameters": true 21 | }, 22 | "include": [ 23 | "lib/**/*" 24 | ] 25 | } -------------------------------------------------------------------------------- /toolproof.yml: -------------------------------------------------------------------------------- 1 | # Run Toolproof tests from the root of the repo with `npx toolproof@latest` 2 | 3 | browser: chrome 4 | concurrency: 4 5 | timeout: 20 6 | browser_timeout: 16 7 | before_all: 8 | - command: cd pagefind && cargo build --release --features extended 9 | placeholders: 10 | pagefind_mode: release 11 | -------------------------------------------------------------------------------- /wrappers/node/.npmrc: -------------------------------------------------------------------------------- 1 | //registry.npmjs.org/:_authToken=${NPM_TOKEN} -------------------------------------------------------------------------------- /wrappers/node/LICENSE/LICENSE-vscode-ripgrep: -------------------------------------------------------------------------------- 1 | vscode-ripgrep 2 | 3 | Copyright (c) Microsoft Corporation 4 | 5 | All rights reserved. 6 | 7 | MIT License 8 | 9 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ""Software""), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 14 | -------------------------------------------------------------------------------- /wrappers/node/jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "resolveJsonModule": true, 4 | "lib": [ 5 | "esnext" 6 | ] 7 | } 8 | } -------------------------------------------------------------------------------- /wrappers/node/lib/encoding.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {string} b64 4 | * @returns {Uint8Array} 5 | */ 6 | export const decode = (b64) => { 7 | let binString; 8 | if (typeof Buffer !== "undefined" && typeof Buffer.from === "function") { 9 | return Buffer.from(b64, "base64"); 10 | } else if ( 11 | typeof window !== "undefined" && 12 | typeof window.atob === "function" 13 | ) { 14 | binString = window.atob(b64); 15 | } else if (typeof atob === "function") { 16 | binString = atob(b64); 17 | } else { 18 | throw new Error("Unable to decode base64 data"); 19 | } 20 | 21 | const size = binString.length; 22 | const bytes = new Uint8Array(size); 23 | for (let i = 0; i < size; i++) { 24 | bytes[i] = binString.charCodeAt(i); 25 | } 26 | return bytes; 27 | }; 28 | -------------------------------------------------------------------------------- /wrappers/node/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "pagefind", 3 | "version": "0.0.0", 4 | "type": "module", 5 | "description": "Implement search on any static website.", 6 | "bin": "lib/runner/bin.cjs", 7 | "main": "lib/index.js", 8 | "repository": { 9 | "type": "git", 10 | "url": "https://github.com/CloudCannon/pagefind" 11 | }, 12 | "exports": { 13 | ".": { 14 | "types": "./types/index.d.ts", 15 | "import": "./lib/index.js" 16 | } 17 | }, 18 | "types": "types/index.d.ts", 19 | "author": "CloudCannon", 20 | "license": "MIT", 21 | "optionalDependencies": { 22 | "@pagefind/linux-x64": "0.0.0", 23 | "@pagefind/linux-arm64": "0.0.0", 24 | "@pagefind/darwin-x64": "0.0.0", 25 | "@pagefind/darwin-arm64": "0.0.0", 26 | "@pagefind/windows-x64": "0.0.0" 27 | }, 28 | "keywords": [ 29 | "CloudCannon", 30 | "Cloud", 31 | "Cannon", 32 | "jamstack", 33 | "static", 34 | "search", 35 | "pagefind", 36 | "page", 37 | "find" 38 | ], 39 | "bugs": { 40 | "url": "https://github.com/CloudCannon/pagefind/issues" 41 | }, 42 | "homepage": "https://github.com/CloudCannon/pagefind#readme", 43 | "devDependencies": { 44 | "@types/node": "^20.4.5" 45 | } 46 | } -------------------------------------------------------------------------------- /wrappers/node/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowJs": true, 4 | "checkJs": true, 5 | "noEmit": true, 6 | "strict": true, 7 | "target": "es2020", 8 | "module": "es2022", 9 | "moduleResolution": "node", 10 | "allowSyntheticDefaultImports": true, 11 | "paths": { 12 | "pagefindService": [ 13 | "./types/index" 14 | ], 15 | "pagefindInternal": [ 16 | "./types/internal" 17 | ], 18 | }, 19 | "noUnusedLocals": true, 20 | "noUnusedParameters": true 21 | }, 22 | "include": [ 23 | "lib/**/*" 24 | ] 25 | } -------------------------------------------------------------------------------- /wrappers/python/.editorconfig: -------------------------------------------------------------------------------- 1 | [*.{py,toml}] 2 | indent_size = 4 3 | indent_style = space 4 | trim_trailing_whitespace = true 5 | insert_final_newline = true 6 | -------------------------------------------------------------------------------- /wrappers/python/.gitignore: -------------------------------------------------------------------------------- 1 | output 2 | # ^ from src/tests/integration.py 3 | -------------------------------------------------------------------------------- /wrappers/python/poetry.toml: -------------------------------------------------------------------------------- 1 | [virtualenvs] 2 | in-project = true 3 | -------------------------------------------------------------------------------- /wrappers/python/scripts/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudCannon/pagefind/d7d0b3a0f0eb12661cd2eb894ad02f10687a4ca0/wrappers/python/scripts/__init__.py -------------------------------------------------------------------------------- /wrappers/python/scripts/build/__init__.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import os 3 | from pathlib import Path 4 | 5 | this_file = Path(__file__) 6 | this_dir = Path(__file__).parent 7 | python_root = this_dir.parent.parent.resolve().absolute() 8 | dist_dir = python_root / "dist" 9 | vendor_dir = python_root / "vendor" 10 | 11 | 12 | def setup_logging() -> None: 13 | logging.basicConfig( 14 | level=os.environ.get("PAGEFIND_PYTHON_LOG_LEVEL") or logging.INFO 15 | ) 16 | -------------------------------------------------------------------------------- /wrappers/python/scripts/ci/cog/check.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -eu 3 | if [[ "${BASH_SOURCE[0]}" = */* ]]; then this_dir="${BASH_SOURCE[0]%/*}"; # bash 4 | else this_dir=.; 5 | fi 6 | # shellcheck source=./files.sh 7 | . "$this_dir"/files.sh 8 | cog -PUe --check "${files_to_cog[@]}" 9 | 10 | -------------------------------------------------------------------------------- /wrappers/python/scripts/ci/cog/files.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | export files_to_cog=( 3 | README.md 4 | src/pagefind/__init__.py 5 | ) 6 | # you can check this list by running `rg -l '\[\[\[cog' ./` in the repo root 7 | -------------------------------------------------------------------------------- /wrappers/python/scripts/ci/cog/update.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # shellcheck disable=SC2296 3 | if [[ "${BASH_SOURCE[0]}" = */* ]]; then this_dir="${BASH_SOURCE[0]%/*}"; # bash 4 | else this_dir=.; 5 | fi 6 | # shellcheck source=./files.sh 7 | . "$this_dir"/files.sh 8 | 9 | cog -PUre "${files_to_cog[@]}" 10 | -------------------------------------------------------------------------------- /wrappers/python/scripts/ci/github/README.md: -------------------------------------------------------------------------------- 1 | CI scripts that are specific to GitHub Actions. 2 | -------------------------------------------------------------------------------- /wrappers/python/scripts/ci/github/activate_venv.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -eu 3 | 4 | cd wrappers/python 5 | 6 | VIRTUAL_ENV="$PWD/.venv" 7 | echo "VIRTUAL_ENV=$VIRTUAL_ENV" >> "$GITHUB_ENV" 8 | 9 | if ! [ -d "$VIRTUAL_ENV" ]; then 10 | echo "No virtualenv found at $VIRTUAL_ENV" 11 | exit 127 12 | fi 13 | 14 | # Ensure binaries from the virtualenv are available at the start of $PATH 15 | # see https://docs.python.org/3/library/venv.html#creating-virtual-environments 16 | if [ -d "$VIRTUAL_ENV/bin" ]; then 17 | # on unix systems, virtualenv puts executables in .venv/bin 18 | venv_bin_path="$VIRTUAL_ENV/bin" 19 | elif [ -d "$VIRTUAL_ENV/Scripts" ]; then 20 | # on windows, virtualenv places executables in .venv/Scripts 21 | venv_bin_path="$VIRTUAL_ENV/Scripts" 22 | fi 23 | 24 | echo "$venv_bin_path" >> "$GITHUB_PATH" 25 | # see https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/workflow-commands-for-github-actions#adding-a-system-path 26 | -------------------------------------------------------------------------------- /wrappers/python/scripts/ci/github/add_src_to_pythonpath.py: -------------------------------------------------------------------------------- 1 | """ 2 | Prepend wrappers/python/src to PYTHONPATH. 3 | """ 4 | 5 | import os 6 | from pathlib import Path 7 | 8 | 9 | new_pythonpath = str(Path("src").absolute()) 10 | if old_pythonpath := os.environ.get("PYTHONPATH"): 11 | new_pythonpath = os.pathsep.join( 12 | [ # os.pathsep is ":" for unix, ";" for windows 13 | new_pythonpath, 14 | old_pythonpath, 15 | ] 16 | ) 17 | 18 | with open(os.environ["GITHUB_ENV"], "a") as f: 19 | f.write(f"PYTHONPATH={new_pythonpath}\n") 20 | -------------------------------------------------------------------------------- /wrappers/python/scripts/ci/github/debug_python_paths.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -eu 3 | cd wrappers/python 4 | 5 | echo "VIRTUAL_ENV=$VIRTUAL_ENV" 6 | 7 | # shellcheck disable=SC2016 8 | echo '$PATH:' 9 | echo "$PATH" | tr ':' '\n' | sed 's/^/ - /g' 10 | 11 | echo 12 | echo " python ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ " 13 | echo 14 | 15 | python --version 16 | command -v python 17 | command -v python3 18 | stat ./.venv/bin/python \ 19 | || stat ./.venv/Scripts/python.exe \ 20 | || echo "missing .venv/bin/python{.exe}" 21 | 22 | echo 23 | echo " poetry ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ " 24 | echo 25 | 26 | command -v poetry || echo "missing poetry" 27 | 28 | echo 29 | echo " mypy ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ " 30 | echo 31 | 32 | if ! command -v mypy; then 33 | if command -v mypy.exe; then 34 | echo "missing mypy, but found mypy.exe" 35 | else 36 | echo "missing mypy{.exe}" 37 | fi 38 | fi 39 | 40 | -------------------------------------------------------------------------------- /wrappers/python/scripts/ci/github/install_dev_dependencies.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -eu 3 | cd wrappers/python 4 | python3 -m poetry install --only=dev --no-root 5 | export VIRTUAL_ENV=$PWD/.venv 6 | # echo "VIRTUAL_ENV=$VIRTUAL_ENV" >> "$GITHUB_ENV" 7 | # echo "PATH=$VIRTUAL_ENV/bin:$PATH" >> "$GITHUB_ENV" 8 | -------------------------------------------------------------------------------- /wrappers/python/scripts/ci/github/setup_poetry.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -eu 3 | python3 -m pip install poetry 4 | 5 | # not using pipx since this is a CI environment that will be reset -- 6 | # there's not much risk of poetry's dependencies conflicting with ours 7 | 8 | # python3 -m pip install pipx 9 | # python3 -m pipx install poetry 10 | -------------------------------------------------------------------------------- /wrappers/python/scripts/ci/python_lints.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -eu 3 | mypy src scripts 4 | ruff check 5 | ruff format --check 6 | -------------------------------------------------------------------------------- /wrappers/python/scripts/ci/shellcheck.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -eu 3 | shellcheck 4 | -------------------------------------------------------------------------------- /wrappers/python/scripts/publish_to_test_pypi.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | export TWINE_REPOSITORY=testpypi 3 | export TWINE_USERNAME=__token__ 4 | export TWINE_PASSWORD="${TEST_PYPI_API_TOKEN:?missing TEST_PYPI_API_TOKEN}" 5 | python3 -m twine upload --verbose ./dist/* 6 | -------------------------------------------------------------------------------- /wrappers/python/src/pagefind/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # assume the python version is >= 3.9, which is the oldest LTS version with 3 | # more 2 months of life as of the time of writing, 2024-08-18 4 | 5 | 6 | # https://docs.python.org/3/reference/datamodel.html#async-context-managers 7 | # https://docs.python.org/3/library/contextlib.html#contextlib.asynccontextmanager 8 | 9 | # [[[cog 10 | # import tomllib # ok since the development environment must be python >= 3.11 11 | # from pathlib import Path 12 | # pyproject = Path("pyproject.toml") # note the CWD is the project root 13 | # assert pyproject.is_file(), f"expected {pyproject.absolute()} to be a file" 14 | # version = tomllib.load(pyproject.open("rb"))["tool"]["poetry"]["version"] 15 | # print(f'__version__ = "{version}"') 16 | # ]]] 17 | __version__ = "0.0.0a0" 18 | # [[[end]]] 19 | -------------------------------------------------------------------------------- /wrappers/python/src/pagefind/__main__.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | 4 | from .service import _must_get_executable 5 | 6 | bin = str(_must_get_executable().resolve().absolute()) 7 | argv = [bin, *sys.argv[1:]] 8 | if os.name == "posix": 9 | os.execv(bin, argv) 10 | else: 11 | import subprocess 12 | 13 | sys.exit(subprocess.call(argv)) 14 | -------------------------------------------------------------------------------- /wrappers/python/src/pagefind/py.typed: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudCannon/pagefind/d7d0b3a0f0eb12661cd2eb894ad02f10687a4ca0/wrappers/python/src/pagefind/py.typed -------------------------------------------------------------------------------- /wrappers/python/src/pagefind_python_bin/README.md: -------------------------------------------------------------------------------- 1 | 4 | # `pagefind_bin` 5 | A python wrapper for the `pagefind` executable. 6 | 7 | ## Usage 8 | 9 | ```py 10 | #!/usr/bin/env python3 11 | from pagefind_bin import get_executable 12 | print(get_executable()) # yields absolute path to the executable 13 | ``` 14 | 15 | ```sh 16 | #!/usr/bin/env bash 17 | python3 -m pagefind_bin --help 18 | ``` 19 | -------------------------------------------------------------------------------- /wrappers/python/src/pagefind_python_bin/__main__.py: -------------------------------------------------------------------------------- 1 | from . import cli 2 | 3 | cli() 4 | -------------------------------------------------------------------------------- /wrappers/python/src/tests/README.md: -------------------------------------------------------------------------------- 1 | Script to run tests from the repo root on an M* macOS: 2 | 3 | ```py 4 | bin="$PWD/target/release/pagefind" 5 | ext="$PWD/target/release/pagefind_extended" 6 | 7 | cd wrappers/python 8 | 9 | # set up the python virtual environment 10 | poetry install --no-root # for dev dependencies 11 | export VIRTUAL_ENV="${PWD}/.venv" 12 | export PATH="$VIRTUAL_ENV/bin:$PATH" 13 | 14 | # build and install the binary-only wheels 15 | 16 | python3 -m scripts.build.binary_only_wheel \ 17 | --llvm-triple="aarch64-apple-darwin" \ 18 | --bin-path=$bin \ 19 | --version=1.1.0 20 | 21 | python3 -m scripts.build.binary_only_wheel \ 22 | --llvm-triple="aarch64-apple-darwin" \ 23 | --bin-path=$ext \ 24 | --version=1.1.0 25 | 26 | python3 -m scripts.build.api_package 27 | 28 | poetry build # build the source-only distribution for the python API 29 | # install all the wheels 30 | pip install ./dist/*.whl --force-reinstall 31 | pip show --verbose pagefind 32 | pip show --verbose pagefind_bin 33 | pip show --verbose pagefind_bin_extended 34 | python3 --version 35 | 36 | LOG_LEVEL="DEBUG" python3 ./src/tests/integration.py 2>&1 | tee /tmp/integration_test.log 37 | ``` 38 | -------------------------------------------------------------------------------- /wrappers/tester/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tester", 3 | "type": "module", 4 | "version": "1.0.0", 5 | "description": "", 6 | "main": "tester.js", 7 | "scripts": { 8 | "test": "echo \"Error: no test specified\" && exit 1" 9 | }, 10 | "keywords": [], 11 | "author": "", 12 | "license": "ISC", 13 | "dependencies": { 14 | "pagefind": "file:../node" 15 | } 16 | } -------------------------------------------------------------------------------- /wrappers/tester/tester.js: -------------------------------------------------------------------------------- 1 | import * as pagefind from "pagefind"; 2 | 3 | const run = async () => { 4 | console.log(`Creating an index`); 5 | const result = await pagefind.createIndex(); 6 | console.log(result); 7 | 8 | if (!result.index) return; 9 | let index = result.index; 10 | 11 | console.log(`\nAdding an HTML file to the index`); 12 | const page = await index.addHTMLFile({path: "dogs/index.html", content: "

Testing, testing

"}); 13 | console.log(page); 14 | 15 | console.log(`\nAdding a custom file to the index`); 16 | const newfile = await index.addCustomRecord({ 17 | url: "/elephants/", 18 | content: "Some testing content regarding elephants", 19 | language: "en", 20 | meta: { 21 | "title": "Elephants" 22 | } 23 | }); 24 | console.log(newfile); 25 | 26 | console.log(`\nWriting files to memory`); 27 | const memfiles = await index.getFiles(); 28 | console.log("Got files", memfiles); 29 | 30 | console.log(`\nWriting files to disk`); 31 | const files = await index.writeFiles(); 32 | console.log("Wrote files", files); 33 | } 34 | 35 | run(); --------------------------------------------------------------------------------