How to build a Search Result Highlighter in PureScript

by||2 min read
PureScript Search Highlighter
PureScript Search Highlighter

In this article we will explore the technique to build a Search Highlighter in PureScript. A common use case is a search component in a web project, i.e. Shops or Blogs.

In JavaScript this task is rather simple, since we can use the match function to search for an occurrence or multiple occurrences of a string, then replacing it with an HTML tag. In PureScript, at least the last step, is a bit more difficult (or let's say more strict).

Using Regular expressions for Search

Regular Expressions modules can be found in the purescript-strings library. We can define regular expressions by providing the string of your regular expression and the following tags:

import Data.String.Regex          (regex)
import Data.String.Regex.Flags    (noFlags, global)

sampleRegexWithoutFlags :: String -> Either String Regex
sampleRegexWithoutFlags str =
  regex str noFlags


sampleRegexWithG :: String -> Either String Regex
sampleRegexWithG str =
  regex str global

We can use the Data.String.Regex and Data.String.Regex.Flags modules to construct regular expressions. If we use those functions, we will see, that PureScript is very explicitly telling us where things can go wrong. Hence,k we will only get a valid Regex construct if the string and flag combination is valid. Let's see how the result looks like:

main :: Effect Unit
main = do
  traceM $  sampleRegexWithoutFlags "est"
  -- will output Right { value0: /est/ }

  traceM $ sampleRegexWithG "est"
  -- will output Right { value0: /est/g }

Great, we now know how to create Regular Expressions in PureScript! Those regular expressions can now be used to work on text. One possible option is the match function from the Data.String.Regex module. This function will give you the matches found in a string, as the following example illustrate:

module Sample where

import Prelude

import Data.Foldable (for_)
import Debug (traceM)

import Data.String.Regex          (match, regex)
import Data.String.Regex.Flags    (noFlags, global)

main :: Effect Unit
main = do
  for_ (sampleRegexWithG "est") \regex -> do
    traceM $  match regex sampleText
    -- will output Just { value0: [ Just { value0: 'est' }, Just { value0: 'est' } ] }

  where
    sampleText = "Lorem ipsum est sit amet, consetetur est elitr"

Since we matched some occurrences in the text, we receive a Just with a list of matched strings.

Highlighting search Results in a Text

We could now work with the shown match function to manually construct a highlighter which would locate the matches in the text and replace the according strings with a highlighted part (for instance a HTML tag). But, we don't need to! There is another function in the Data.String.Regex module which is called split. This function allows us to split the text by the matched Regular Expression strings. In this manner, we can take the result and "glue" the list of strings back together. As a glue we can use a HTML tag:

module Sample2 where

import Prelude

import Data.Foldable (for_)
import Debug (traceM)

import Data.String.Regex          (split, regex)
import Data.String.Regex.Flags    (global)

main :: Effect Unit
main = do
  for_ (sampleRegexWithG "est") \regex -> do
    traceM $  split regex sampleText
    -- will output [ "Lorem ipsum ", " sit amet, consetetur ", " elitr" ]

  where
    sampleText = "Lorem ipsum est sit amet, consetetur est elitr"

Thank you for reading this far! Let’s connect. You can @ me on Twitter (@debilofant) with comments, or feel free to follow. Please like/share this article so that it reaches others as well.

© Copyright 2022 - Ersocon - All rights reservedVer. 2.3.6.9