GordonS
GordonS

Reputation: 275

Search HTML for words and mark by wrapping with a span

I have HTML content (content edited via a CMS, not an entire website page) and when a search is performed, I need to highlight the searched for words by wrapping the words with a span.

So, consider the HTML content, when the search term is "commissioner":

> <p>
> In this section, we set out how the Commissioner regulates those
> who provide advice. For details, see 
> <a href="/the-commissioner/" title="The Commissioner">The Commissioner</a>
> </p>

I need to add a span around the work "Commissioner" in the text part of the link but NOT the URL or Title part of the link. Of course, also, I would need to add a span around "Commissioner" in the content too.

I tried using Regex but I couldn't see how to not change the link Url or Title.

I have looked at HtmlAgilityPack but it looks like you can't change the value of "InnerText" (of a node) so I don't understand how I can update the HTML and add the required spans.

Would I need to build a new HTML document instead of amending the one I'm reading through?

Upvotes: 0

Views: 81

Answers (2)

GordonS
GordonS

Reputation: 275

I solved this by using the Javascript library mark.js to do the highlighting on the clients browser.

On the HTML pages, the content goes inside an article tag.

<article class="article"> ... </article>

I used this Javascript. The search words are passed as a Querystring property ("q"). I also pass a property called "exact".

import Mark from 'mark.js'

// Create an instance of mark.js and pass an argument containing
// the DOM object of the context (where to search for matches)
var markInstance = new Mark(document.querySelector(".article"));

function performMark() {

    // Read the keywords
    const params = new URLSearchParams(window.location.search)
    var keyword = params.get("q")
    var separateWords = true;
    if (params.get("ExactMatch").toLowerCase() == 'true') {
        separateWords = false;
    }

    // Determine selected options
    var options = {
        "separateWordSearch": separateWords,
        "accuracy": {
            "value": "exactly",
            "limiters": [",", "."]
        }
    };
    // Remove previous marked elements and mark
    // the new keyword inside the context
    markInstance.unmark({
        done: function () {
            markInstance.mark(keyword, options);
        }
    });
};

performMark();

So, if a page has a querystring like "?q=student+advice&exact=true", the exact phrase of "student advice" will be highlighted by surrounding it with the "mark" tag.

Upvotes: -3

camilo_chart
camilo_chart

Reputation: 317

This program tries to solve the problem by taking the searched text that is not surrounded by characters used in html tags or url syntax.

Solution

using System.Text.RegularExpressions;

namespace StackOverflowAnswers
{
    public class ProgramStack78911999
    {
        static void Main(string[] args)
        {
            string input = "Commissioner";
            Console.WriteLine("Input:  " + input);
            SearchTextInHTML(input);
        }

        static void SearchTextInHTML(string search_text)
        {
            string content = "" +
                "<p>In this section, we set out how the Commissioner regulates those" +
                "who provide advice. For details, see " +
                "<a href=\"/the-commissioner/\" title=\"The Commissioner\">The Commissioner</a>" +
                "</p>";
            Console.WriteLine("Content");
            Console.WriteLine(content);
            Console.WriteLine("Matches");
            string pattern_group = @"([^\-""\/<>]{1})\b(" + search_text + @")\b([^\-""\/<>]{1})";
            string replace_group = "$1<span>$2</span>$3";
            string new_content = content;
            foreach (Match mtc in Regex.Matches(content, pattern_group))
            {
                Console.WriteLine(mtc);
                new_content = Regex.Replace(new_content, pattern_group, replace_group);

            }
            Console.WriteLine("New Content");
            Console.WriteLine(new_content);
        }
    }
}

Output

<p>In this section, we set out how the <span>Commissioner</span> regulates thosewho provide advice. For details, see <a href="/the-commissioner/" title="The Commissioner">The Commissioner</a></p>

Upvotes: -1

Related Questions