silverbulletmd / silverbullet

The knowledge tinkerer's notebook
https://silverbullet.md
MIT License
2.49k stars 180 forks source link

Add consistent tag inheritance #923

Open gorootde opened 3 months ago

gorootde commented 3 months ago

When selecting data from tables and items, SB is lacking a mechanism to conveniently select a subset of these objects.

Example: I use a daily journal that looks like this:

# Nodes
- Some random thoughs
- Other thoughts

# Time Recording
- 08:00-09:00 Thinking about random thoughts #TimeRecord
- 10:00-12:00 Working on project XYZ #TimeRecord

The only way I can query for all time records is to manually add the TimeRecord tag to each. This clutters up the time records with information that is not adding any value, except being able to select them.

Proposed solution It would be much more convenient to be able to add the tag only a single time (on paragraph level). The paragraph level tag would then be inherited by the items and included in itags property:

# Nodes
- Some random thoughs
- Other thoughts

# Time Recording
Global tags for items below: #TimeRecord
- 08:00-09:00 Thinking about random thoughts
- 10:00-12:00 Working on project XYZ

Similar problem for table rows. "Get all rows but only from a specific table" ends up in the same problem: Tagging all rows of a table with the same tag. Maybe there are even other objects where the same principle would make sense.

zefhemel commented 3 months ago

So the general pattern would be: “if a list is preceeded by some string ending with a colon and then a tag, then apply the tag to all the items in the list”?

I think that can make sense.

An alternative solution you can consider is a custom attribute extractor in space script: https://silverbullet.md/Space%20Script

You can create one that parses a list item, checks for the /\d\d:\d\d-\d\d:\d\d/ time pattern, and add a custom attribute (I think this can also be a tags, but not 100% sure, otherwise you can do something like a timeRecord: true attribute). Then you don’t have to put tags in at all and can still filter on the attribute. I hope that makes sense.

gorootde commented 3 months ago

I consider this to be a more generic problem (while describing one specific example only). Thus the attribute extractor approach would only work if there is some "common format" in all list items.

I'd propose a general inheritance of tags on a higher level to the levels below. Let me try to sketch that in a more extensive example:

---
tags:
   - journal
---
# This is a headline that is tagged #h1
Some paragraph that is  tagged as well #p1

## A Level 2 Headline #h2
This paragraph contains a list with some #groceries. Please add your items to the shopping list.
- Apple
- Banana

## Table example
These are my #contacts:

| Name | Phone Number |
| ---- | --------------- |
| Mike | 012345 |
| Alfred #business | 012345 |

# A tasklist

- [ ] do this #important
- [ ] do that

The objects return by a query would then be tagged (itags, not listing the already existing ones) as following:

gorootde commented 2 weeks ago

I've been digging in SB's code with the aim to create a PR for this feature.

I am assuming the following hierarchy of markdown elements in a page:

Whereas each node in the hierarchy would inherit the itags of its parent. We'd need to extend the updateITags function as follows: export function updateITags<T>( obj: ObjectValue<T>, frontmatter: FrontMatter, ...parents: ObjectValue<T>[] )

However, I cannot figure out how to get the corresponding parents in the places where this function is called (e.g. in plugs/tasks/task.ts:135. Any hint on this?