Mark the words of a raw text that match a search query.
Matching goes through the same SearchCore.Pipeline as indexing and querying, so a
word is highlighted exactly when it would have matched in Postgres: both sides are
stemmed and accent-folded before comparing. "tomate" highlights "tomates",
"idee" highlights "idées".
The result is a list of {:text, part} / {:match, part} segments in document
order — renderer-agnostic, so a LiveView can map :match to <mark>, a terminal
to ANSI, etc. Joining every part reproduces the input text byte for byte. The fragments
carved out of the text — the matched words and the spans around them — are each copied
into a standalone binary rather than left as sub-binaries, so stashing the segments (or
just the :match words) in long-lived state never pins the whole source in memory
through a word-sized fragment. (A query that matches nothing returns your text itself
as the one segment, unchanged.)
iex> SearchCore.Highlight.highlight("Livraison de tomates anciennes", "tomate", :fr)
[{:text, "Livraison de "}, {:match, "tomates"}, {:text, " anciennes"}]
Summary
Functions
Split text into {:text, _} / {:match, _} segments for query in lang.
Types
Functions
@spec highlight(String.t(), String.t(), SearchCore.Language.t(), keyword()) :: [ segment() ]
Split text into {:text, _} / {:match, _} segments for query in lang.
Options (all forwarded to SearchCore.Pipeline):
:prefix— whentrue, a word matches if its stem starts with a query stem, mirroring atsquerybuilt withprefix: true(defaultfalse, mirroringSearchCore.tsquery/3). Highlighting should use the same:prefixas the query that ran.:min_length,:stopwords,:fold_accents— as inSearchCore.Pipeline.process/3.
A query with no usable tokens (blank, all stopwords) highlights nothing:
iex> SearchCore.Highlight.highlight("Un texte", "de", :fr)
[{:text, "Un texte"}]
iex> SearchCore.Highlight.highlight("Les idées vertes", "idee", :fr)
[{:text, "Les "}, {:match, "idées"}, {:text, " vertes"}]
iex> SearchCore.Highlight.highlight("BL-2024-0012", "bl", :fr, prefix: true)
[{:match, "BL"}, {:text, "-2024-0012"}]