adsfolio.pdf.search

Match library search text against catalog records.

The catalog SQL filter and the GUI’s in-memory search use these functions, so both return the same records.

A record’s search text holds its relative path, the decoded values of its metadata (keys excluded), and its content digest. Decoding matters: stored JSON can hold escapes such as \u00e9, and these must match é.

class adsfolio.pdf.search.SearchTerm(field, text)[source]

Bases: object

One part of a search query.

field is a key of SEARCH_FIELDS, or None for a plain term. A plain term searches the default fields.

Parameters:
  • field (str | None)

  • text (str)

field: str | None
text: str
adsfolio.pdf.search.document_matches(document, query, *, exact=False, wildcards=False, default_fields=())[source]

Return whether a search document matches every term of query.

Parameters:
  • document (Mapping[str, str]) – Output of record_search_document. When exact is false, pass the output of fold_document instead.

  • query (str) – Search query. See parse_query.

  • exact (bool, optional) – Search options. See search_matcher.

  • wildcards (bool, optional) – Search options. See search_matcher.

  • default_fields (Collection[str], optional) – Fields that plain terms search. Empty means all search text.

Return type:

bool

adsfolio.pdf.search.fold_document(document)[source]

Return document with fold_text applied to every field.

Parameters:

document (collections.abc.Mapping[str, str])

Return type:

dict[str, str]

adsfolio.pdf.search.fold_text(text)[source]

Remove accents and letter case, so Dorémont becomes doremont.

The text is decomposed (NFKD), combining marks are removed, and the result is case-folded.

Parameters:

text (str)

Return type:

str

adsfolio.pdf.search.parse_query(query)[source]

Split a query into terms that must all match.

Spaces separate terms. Double quotes keep a phrase together, also after a field name: author:"Doe, J.". A missing closing quote ends the phrase at the end of the query. A prefix that is not a known field name, as in https://, stays part of the text.

Parameters:

query (str)

Return type:

tuple[adsfolio.pdf.search.SearchTerm, …]

adsfolio.pdf.search.record_search_document(relative_path, metadata_json, sha256)[source]

Return the exact search text of each field of one catalog location.

The ALL_FIELDS entry equals record_search_text. Each other entry holds the values of that field, joined by FIELD_SEPARATOR.

Parameters:
  • relative_path (str | None)

  • metadata_json (str | None)

  • sha256 (str | None)

Return type:

dict[str, str]

adsfolio.pdf.search.record_search_text(relative_path, metadata_json, sha256)[source]

Return the exact search text of one catalog location.

Parameters:
  • relative_path (str or None) – Path of the PDF relative to its library root.

  • metadata_json (str or None) – Stored metadata JSON. Invalid JSON is searched as plain text.

  • sha256 (str or None) – Current content digest.

Returns:

The fields and metadata values, joined by FIELD_SEPARATOR.

Return type:

str

adsfolio.pdf.search.resolve_field(name)[source]

Return the field key for a field name or alias, ignoring letter case.

Parameters:

name (str)

Return type:

str | None

adsfolio.pdf.search.search_matcher(query, *, exact=False, wildcards=False)[source]

Return a test for one search query.

Apply the test to record_search_text output when exact is true, and to fold_text of that output when exact is false.

Parameters:
  • query (str) – Search text. Leading and trailing spaces are ignored. An empty query matches every record.

  • exact (bool, optional) – Match accents and letter case exactly. By default both are ignored.

  • wildcards (bool, optional) – Read % as any text and _ as any one character. By default they match only themselves. A wildcard does not cross fields.

Returns:

Function that returns True when a search text contains the query.

Return type:

Callable[[str], bool]

adsfolio.pdf.search.search_spans(text, query, *, exact=False, wildcards=False)[source]

Return the parts of text that the query matches, for highlighting.

The rules are the same as for search_matcher. Each span is a (start, end) index pair into text, not into its folded form. Spans do not overlap. A wildcard match of no characters is skipped.

Parameters:
  • text (str) – Displayed text, for example a title or a filename.

  • query (str) – Search text.

  • exact (bool, optional) – Search options. See search_matcher.

  • wildcards (bool, optional) – Search options. See search_matcher.

Return type:

tuple[tuple[int, int], …]

adsfolio.pdf.search.sql_search_match(relative_path, metadata_json, sha256, query, exact, wildcards, default_fields)[source]

Apply document_matches to one SQL row. SQLite calls this function.

default_fields is a comma-separated list of field keys.

Parameters:
  • relative_path (str | None)

  • metadata_json (str | None)

  • sha256 (str | None)

  • query (str)

  • exact (int)

  • wildcards (int)

  • default_fields (str)

Return type:

int