Hiding @Context in tasks

What I’m Trying to do:

I already have a CSS snippet that hides “tags”. This CSS is toggled via an entry hide-tags in cssclasses in the YAML frontmatter.

Now I’m trying to achieve the same thing for hiding contexts in tasks. My tasks look like this, sometimes with an appended @Context (which I would like to be able to hide):

- [ ] Task @Context

I’ve spent the entire weekend trying to get this working with the help of ChatGPT (and other AI systems). What I have so far works to some extent, but I would like the @Context to be hidden by default when opening a note, which I haven’t been able to achieve yet.

With my current setup (see below), this does not work properly. Although the YAML entry hideTaskContexts is already set to true when the note is opened, the setting only takes effect after pressing the button twice (first “Show Context”, then “Hide Context” again).

What I Would Like to Achieve:

  • A reasonably simple solution (what I currently have feels rather complicated)
  • Ideally, toggling should be controlled via an entry in cssclasses that enables or disables a CSS snippet
  • @Context should be hidden by default when a note is opened
  • Solution should work for all contexts beginning with @, not just @Context

What I Currently Have:

CSS

.hide-task-contexts .task-context.obsidian-context {
display: none !important;
}

meta-bind-js-view

{hideTaskContexts} as hide

const contexts = document.querySelectorAll(
".task-context"
);

contexts.forEach(context => {
context.classList.toggle(
"obsidian-context",
context.textContent.trim() === "
"
);
});

const preview = document.querySelector(
".markdown-preview-view"
);

if (preview) {
preview.classList.toggle(
"hide-task-contexts",
context.bound.hide === true
);
}

return "";

meta-bind-button to toggle

style: default
label: "Contexts ausblenden"
class: "task-context-toggle"
actions:

type: inlineJS
code: |
const file = app.workspace.getActiveFile();
if (!file) return;

const current = app.metadataCache.getFileCache(file)?.frontmatter?.hideTaskContexts ?? false;
const newValue = !current;

await app.fileManager.processFrontMatter(file, frontmatter => {
frontmatter.hideTaskContexts = newValue;
});

const button = document.querySelector(".task-context-toggle button");

if (button) {
button.textContent = newValue
? "Contexts anzeigen"
: "Contexts ausblenden";
}

document.body.classList.toggle(
"hide-task-contexts",
newValue
);

// Tasks neu verarbeiten
document.querySelectorAll(
".markdown-preview-view .task-list-item"
).forEach(task => {
task.querySelectorAll(".task-context").forEach(el => {
el.replaceWith(
document.createTextNode(el.textContent)
);
});
});

document.querySelectorAll(
".markdown-preview-view .task-list-item"
).forEach(task => {
const walker = document.createTreeWalker(
task,
NodeFilter.SHOW_TEXT
);

  const nodes = [];
  let node;

  while (node = walker.nextNode()) {
      if (
          !node.parentElement?.classList.contains(
              "task-context"
          ) &&
          /@[A-Za-zÄÖÜäöüß0-9_-]+/.test(node.nodeValue)
      ) {
          nodes.push(node);
      }
  }

  nodes.forEach(textNode => {
      const parts = textNode.nodeValue.split(
          /(\s+@[A-Za-zÄÖÜäöüß0-9_-]+)/g
      );

      if (parts.length <= 1) return;

      const fragment =
          document.createDocumentFragment();

      parts.forEach(part => {
          if (
              /^\s+@[A-Za-zÄÖÜäöüß0-9_-]+$/.test(part)
          ) {
              const span =
                  document.createElement("span");

              span.className = "task-context";
              span.textContent = part;

              fragment.appendChild(span);
          } else {
              fragment.appendChild(
                  document.createTextNode(part)
              );
          }
      });

      textNode.parentNode.replaceChild(
          fragment,
          textNode
      );
  });

});

Any help, ideas, or suggestions would be very welcome. Thanks in advance!

Don’t know if it will work for your use case, but there’s an example here of using Regex Mark (a community plugin) to catch and color anything starting with an @.

The css can be easily changed to display: none, and probably to only target checkbox/task entries.

I’ve installed and activated the plugin, and I’ve tried both (?@\w+) and @\w+ in the first text box (as shown in your screenshot), but I can’t get it to work.

Clicking “Verify and Apply” reports “Regexes applied successfully,” but nothing happens.

There’s also an activation button on the right-hand side of my regex definition, but I can’t seem to enable it as it appears to be disabled.

What am I doing wrong?

Did you reload the vault after setting the regex?

Yes, … have closed and re-opened my vault

  • Have installed Regex Mark and activated
  • Have defined one line (see screenshot)
  • Have added a css called “hide-context” and have activated the same

But no visible change in my note containing the tasks.

Anything else I may have forgotten?

As already said … I’ve been wondering about the button on the right side (should be the switch to activate, but cannot change).