slugbucket / crossword-hints

Python Flask web application to aid decipherment of cryptic crossword clues for known setters
GNU General Public License v3.0
1 stars 0 forks source link

List the cue word meanings on the cue word search results - feat0027 #29

Closed slugbucket closed 4 years ago

slugbucket commented 5 years ago

Because a cue word can be used in different contexts it will be good to show those contexts on the hints search results page and perhaps highlight the cue word in the list of results.

slugbucket commented 5 years ago

Perhaps also include a link on the solutions form so that the already entered cue word (and meaning) matching what is being entered to avoid repeating the meaning of a cue.

slugbucket commented 4 years ago

Be very aware that the submitted cue word must be sanitized before being displayed in the list of matching clues.

slugbucket commented 4 years ago

The easiest way to highlight the cue word is by using the replace filter in the Jinja2 template but this has a limitation in that it cannot be applied case-insensitively so that when the cue word is in a different case in the clue it won't be highlighted on the results page. The alternative is to lower-case the clue before the replace filter.

slugbucket commented 4 years ago

The real problem occurs when the clue starts with the cue word. We can't use the capitalize filter on the clue because it starts with HTML markup. Perhaps there is a better way to achieve the text replacement using JavaScript.

slugbucket commented 4 years ago

If not in JavaScript, then another alternative would be in SQL, but SQLite3 doesn't support select a regex substring from a column so this can't be used. The next approach would be a custom filter

slugbucket commented 4 years ago

There are three parts to adding a custom filter:

The filter function, say, highlight_text, can be added to the view support function python file, crossword_hints/views/crossword_hints.py,

def highlight_text(text, word, cls):
    p = re.compile(word, re.IGNORECASE)
    m = p.search(text)
    if m:
        hstr = ("<span class='%s'>%s</span>" % (cls, m.group()))
        return(p.sub(hstr, text))
    else:
        return(text)

The filter is registered with the Jinja2 environment thus in the top-level init.py:

application.jinja_env.filters['highlight_text'] = highlight_text

The filter is used in a template in the same way as any other:

{{ clue.clue|highlight_text(cue_word, 'highlight-cue')|safe }}

This should be worthy of a blog post.

slugbucket commented 4 years ago

feature merged and committed.