Skip to content

Instantly share code, notes, and snippets.

@Ahrengot
Created March 25, 2017 20:50
Show Gist options
  • Save Ahrengot/76bac2c471ef94fb3996fc5f4ba38532 to your computer and use it in GitHub Desktop.
Save Ahrengot/76bac2c471ef94fb3996fc5f4ba38532 to your computer and use it in GitHub Desktop.
{-
highlightMatches
Wraps matches in `<strong>` elements and returns a list of Html
If no matches are found then return a list with a single child
containing the original string wrapped in a `<span>`
-}
highlightMatches : String -> String -> List (Html Never)
highlightMatches needle haystack =
let
needleLen =
String.length needle
haystackLen =
String.length haystack
lcNeedle =
String.toLower needle
lcHaystack =
String.toLower haystack
matches : List Regex.Match
matches =
Regex.find Regex.All (regex lcNeedle) lcHaystack
matchByNumber : Int -> Maybe Regex.Match
matchByNumber num =
List.head <| List.filter (\match -> match.number == num) matches
highlightMatch : Regex.Match -> Html Never
highlightMatch match =
let
before =
if match.index == 0 then
""
else
case matchByNumber (match.number - 1) of
Nothing ->
String.slice 0 match.index haystack
Just prevMatch ->
String.slice (prevMatch.index + 1) match.index haystack
after =
case (List.head <| List.reverse matches) of
Nothing ->
""
Just lastMatch ->
-- Check if this match is the last match we found
if lastMatch.number == match.number then
-- Check if last match is also last char in string. If not
-- then add the remaining characters
if (lastMatch.index + needleLen) == haystackLen then
""
else
String.slice (lastMatch.index + needleLen) haystackLen haystack
else
""
in
span []
[ text before
, strong [] [ text <| String.slice match.index (match.index + needleLen) haystack ]
, text after
]
in
if List.isEmpty matches then
[ span [] [ text haystack ] ]
else
List.map highlightMatch matches
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment