Tuesday, April 22, 2025

Highlighting text in the blog manager program


In September 2024, I described1 how I added search capability to the BMP. Some time ago, I thought it would be a 'righteous hack' if when a 'show blog entry' window were opened, the sought-for text would be highlighted. For example, there are eight blogs (so far) from the beginning of this year that contain the word 'guitar'; I want that if the contents of one of those blogs are displayed, the word 'guitar' will appear with a yellow background (as shown on the left; this is entry #1908)2.

I tried to achieve this about a month ago in a very ad hoc manner and unsurprisingly I did not succeed. I decided yesterday to resurrect this idea, and although I wasn't feeling very focused, I managed to implement this idea. There are two separate goals that have to be attained:
  1. Passing the search string to a 'show blog entry' window
  2. Highlighting the sought-for text
My original idea for goal #2 was to somehow fake a ctrl-F keypress in the browser window; this brings up a 'find' dialog. Then somehow I would have to enter the search string into this dialog and execute it. I found some code that purported to do this but I couldn't get it to work, which is probably the primary reason why I abandoned my original attempts.

This time around, however, I came across some code that allowed Delphi/TWebBrowser to execute arbitrary JavaScript code. OK: what would the JS code be to find a string and highlight it? I found some complicated (to me) code that ultimately surrounded the search string with <mark> and </mark> tags. I took a blog entry, went to its source, added those tags ... and nothing happened. But this gave me an idea, a realisation, an epiphany. The code for the 'show blog entry' windows receives the number of a blog then retrieves the raw text (including all HTML tags) from the database; this text is then turned into a stream and passed to the web browser. The epiphany was that during the loading stage, I could search for the search string, and if found, surround it with span/style tags that would highlight the text. An inner loop is used as the search string may appear more than once on any given line. As follows (sl is a TStringList):
sl.Text:= HTMLCode; if searchstring <> '' then for i:= 1 to sl.Count do begin aline:= sl[i - 1]; flag:= false; j:= pos (searchstring, aline); while j > 0 do begin flag:= true; s:= copy (aline, 1, j-1); aline:= copy (aline, j + length (searchstring), 200); s:= s + '<span style="background-color: yellow;"> ' + searchstring + '</span>'; j:= pos (searchstring, aline); end; if flag then sl[i - 1]:= s + aline; end; sl.SaveToStream (ms);

In the first line of the above code, the variable HTMLCode contains the raw text of the blog entry, including the various tags. I should change the line 'i:= 1 to sl.count' so that the loop starts with the second or possibly third line of the text; the opening line(s) contain the title and other text that is not displayed so there's no reason to consider them candidates for HTML insertion (it looks like the first seven lines can be skipped - this should also be applied to the code that searches for the string in the first place).

But how to pass the search string? This is complicated because of the recursive manner in which the list of blogs containing the search string is displayed; the TShowEntries window gets called by several different functions and it also calls itself. I found an elegant way of solving this problem: which ever way this window is invoked, it always receives an instance number that points to the data stored in the temp table (see here3 for an explanation). If I store the search string in these tuples, then it can be retrieved when the TShowEntries window is executed, and the search string can be passed to each 'show blog entry' window when opened.

All this took about half an hour to program and it worked first time. I admit that it could be polished but what exists is substantially correct.

Internal links
[1] 1828
[2] 1908
[3] 1548



This day in history:

Blog #Date TitleTags
12722/04/2008Holiday weekProgramming, Delphi, Cold feet
70222/04/2014More researchDBA
102422/04/2017Jerry Lee Lewis rides againGrandfather
160722/04/2023SongbirdSong writing
174722/04/2024Wishing you a happy and kosher Pesach!Personal

No comments:

Post a Comment