Formatting hashtags in markdown preview

I would like to make hashtags in my markdown documents stand out similar to Marked2 app:

Screenshot 2023-03-30 at 11.42.28

From reading help, I believe this is possible by using javascript to process the rendered HTML and surround each tag with something like <span id="hashtag">#myhashtag</span> and then add an entry to the CSS to style id=“hashtag”.

Unfortunately my javascript coding abilities are minimal. Is there a way to do this by adding something in the preferences>files>makrdwon>javascript box? Thanks for any help.

You might want to search the forum for an example handling check boxes with JavaScript. I posted it about 12 to 18 months ago.
Using an id is probably not a good idea here, I’d go for a class.
Doing it in the JS via the preferences is possible. But be aware that this requires special consideration if you want it to be usable also in a browser, ie after covering your MD to HTML.

Thanks for your rapid reply. I will search. I only need it for DTP’s preview as I tend to use Marked to generate output from markdown files.

Same problem: marked will have to have access to the JS code at rendering time. Which excludes DT item links in the global preferences.

@saltlane - I had the same need but found there was an easier way to make the hashtags stand out, although differently than in Marked2, by using underscores, viz.:
#pepper

#courgette

#pasta

along with your preferred changes to your Style Sheet (Settings->Files->Style Sheet ) in the /* strong / / emphasis / and / underline */ sections.

Unless I’m misunderstanding your idea, this would only work if you weren’t using those types of formatting elsewhere in the document. Those are so common, I’d suspect you’d end up with unusual results, e.g.,…

That’s a nice solution but I notice that the #tag entry didn’t appear in the tag bar. And, yes it is true that you’d have to reserve an emphasis type for a tag but if you have a template with a section for tags and you are diligent about the use of the reserved emphasis type the tags will stand out in the markdown view. On the other hand, if your Markdown engine could accept the kind of styling changes you showed and have the #tag appear in the tag bar, that would be excellent.

As I noted, what I thought you were describing leafs to unusual results. It’s just a bit of a visual hack and one that’s pretty likely to cause confusion.

Also, since it is just such a hack, I’d wager there’d be no support for it in tag detection. But development has to weigh in on that.

OK. I have been playing and getting closer. When it works, I can replace <mark> with a span and class to style it in CSS (like bullfrog’s above). The following test HTML highlights the tags in a browser;

<!DOCTYPE html>
<html dir="auto">
<head>
<title>Test tag highlight</title>
<meta name="generator" content="DEVONthink 3.9"/>

<script type="text/javascript"> 
document.addEventListener('DOMContentLoaded', (event) => {
const term = "(\#[a-zA-Z0-9_]*)";  
const RE = new RegExp(term, "g"); 
const html = document.body.innerHTML;  
document.body.innerHTML = html.replaceAll(RE, "<mark>$1</mark>");  
});
</script>

<meta charset="utf-8"/>
</head>
<body>
<h1>Test tag format</h1>

<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. In nisl nisi scelerisque eu. Dictum sit amet justo donec. Quis auctor elit sed vulputate mi sit amet mauris commodo. Proin sed .</p>

<p>#test #testx #23test</p>
</body>
</html>

You get the tags highlighted. If I put the script part into my markdown document in DTP and click preview it also works.

<script>
document.addEventListener('DOMContentLoaded', (event) => {
const term = "(\#[a-zA-Z0-9_]*)";  
const RE = new RegExp(term, "g"); 
const html = document.body.innerHTML;  
document.body.innerHTML = html.replaceAll(RE, "<mark>$1</mark>");  
});
</script>

# Test tag format

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. In nisl nisi scelerisque eu. Dictum sit amet justo donec. Quis auctor elit sed vulputate mi sit amet mauris commodo. Proin sed.

#test #testx #23test

However if I put the code in a text document linked to the preferences>files>markdown>javascript it doesn’t work.

What am I doing wrong? Any help gratefully received.

FYI text document:

document.addEventListener('DOMContentLoaded', (event) => {
const term = "(\#[a-zA-Z0-9_]*)";  
const RE = new RegExp(term, "g"); 
const html = document.body.innerHTML;  
document.body.innerHTML = html.replaceAll(RE, "<mark>$1</mark>");  
});

Cracked it. I created js file outside of DPT and imported then linked at it woks now.

1 Like

I’m not sure if that’s an issue, but your regular expression does not work with tags that contain a space. Nor with any characters outside the ASCII range.

From a semantic standpoint, using a span with an appropriate class might be better than mark. And there’s no need to escape the # sign.

Hashtags don’t support spaces.

1 Like

I See. I was thinking of DT tags, my bad.

No worries! :slight_smile:

Here is a full write-up and results for anyone interested and wants to highlight hashtags in markdown preview (hashtags within the markdown document NOT DTP hashtags)

  1. Create a javascript file (e.g. highlight_hashtags.js)
  2. Add the following code:
document.addEventListener('DOMContentLoaded', (event) => {
const term = "(#[-a-zA-Z0-9_]\/+)";  
const RE = new RegExp(term, "g"); 
const html = document.body.innerHTML;  
document.body.innerHTML = html.replaceAll(RE, "<span class=tag>$1</span>");  
});
  1. Import document into DTP
  2. Copy the link to the document (ctrl click > copy item link)
  3. Paste this into preferences>files>markdown>javascript
  4. Add the following css to your css file (there a lots of css files within the forum to try. I use a github one from Brett Terpstra):
.tag {
padding: .1em .3em;
background-color: lightgrey;
border-radius: 12px;
}
  1. Copy the link to your css file as above or select it in preferences>files>markdown>style sheet.

In markdown preview you get this:

I am sure this solution regex etc. could be improved. But it works for me.

1 Like

Well done, but I would modify the RegEx to…

const term = "(\#[-a-zA-Z0-9_]+)"; 

Otherwise, it will match a lone # and it won’t match a tag like user-defined.`

image

Thanks. I have corrected the write-up. Also included Obsidian style tag hierarchy #parent/child.

Also included Obsidian style tag hierarchy

?
DEVONthink has long supported this :wink:

:+1:
Me, being pedantic:

const term = "(#[-_/\p{L}\p{Nl}\p{Nd}]+)";
const RE = new RegExp(term, "gu");

should make it work for non-ASCII tags, too. The weird p{...} things seem to be the Unicode RE equivalent to the somewhat shorter POSIX [:alnum:] which JS unfortunately doesn’t know about. These shorthands only work when the u flag is also given to new RegExp.
And I don’t see a reason why / shouldn’t be part of the character class, so I moved it into the brackets.

I’d vote for a relative border-radius here, something like 0.8em or whatever looks ok. Makes it more flexible if someone uses a larger or smaller font.

I welcome all your knowledge and expertise. Thanks