Filtering for CSS Classes?

Just out of general curiousity, would it be possible to filter for html elements that have been given specific css classes, as if they were tiddlers being filtered by tags?

For example, lets say I have written a tiddler about computers, and chosen to highlight a specific section of that text using @@.highlight hello there@@ and once the filter is created, it generates a list of each instance with that CSS class?

I think this could be really useful for several usecases, such as transcluding specific classed sections of text within a tiddler ah-la [tag[Groceries]css:class[food]] would result in things like “broccoli garlic poptarts” etc. from a grocery list tiddler, and then wrapped to render as bulletpoints or even to link to the tiddlers they were from, which could be useful for quoting some text if it was recording dialogue within the tiddler, i.e. “Jim said (‘Not with my hammer’)[Tiddler About Jim’s Tools]” etc. etc.

You could just filter by text field contents, yes?

https://tiddlywiki.com/static/contains%20Operator.html

Hmm, I’ll have to give that a try to see if it works for something like .task.

Though, it looks like that only produces the tiddler is it in, but I may be wrong.

Interesting question. I have no idea how to do this in wikitext, although we could certainly do it in JS, perhaps with a TreeWalker. But my question is what would you expect back from this? A list of DOM nodes is not going to work with other TW tools, and a list of arbitrary strings, such as the text content of each node, doesn’t seem all that useful.

Edit, on rereading, perhaps a list of strings would be what you want. Hmmm. The technique I’m imagining would only work on ones active in the StoryList. Is that acceptable? Or are you trying to get all of them?

Well, my orginal idea would probably be all instances in TW’s DOM. it would be like searching the whole .html file in VSCode or another text editor using the find & replace (on windows, ctrl + F, in case I am referring to the wrong thing by name).

I believe Logseq does something similar…? I barely know anything about it unfortunately, I’ve been trying to look into how Obsidian and Logseq and other apps work in similar ways to TW.

Anyways, I digressed; Treewalker? hm. time for reading on my part then, I’m not familiar with them (yet!)

Note, though, that there is no real DOM for most tiddlers not currently rendered (except in the trivial sense that the JSON string representing all the tiddlers is stored inside a <script> tag.) While I mentioned the story river, it’s really the entire rendered HTML that we could search. But non-rendered tiddlers would not be covered by this technique.

With enough parsing work, we might be able to do this by using search over all the tiddlers. But it would be tricky, and trying to perfect it for all use-cases is doomed to failure.

Hm… well if it is really that impractical to implement then I see no reason to try to make something work that isn’t going to function to the full concept. But it is still a fun idea to think about.

Using the search function in TW is an interesting point though. I am curious if it would be possible to piggy back off it’s ability to search for text. I’m going to look into how it works :mag::thinking:

1 Like

@Justin_H See if you can follow me here…

I can transclude a specific element from a specific tiddler…

<<txx tiddler tagname>>

I can produce “quotes” using the same technique to produce a listing of each tagname across the wiki:

<<quotable tagname>>

Less useful I think, I can search my entire wiki for phrases whereby a listing of

 100chars + <phrase> + 100chars

is produced from every match found (I call it seek in context).

I’m not quite sure I understand your suggestion, would you be able to expand upon it?

Yes, that’s where we could make real progress. And my “doomed to failure” is overstated (although I love that StackOverflow answer!) We can’t parse general HTML with plain regexes, but we could still write a parser with more sophisticated tools than plain regex.

The thing is, DOM methods would give us a straightforward method of finding elements with a given class, but unless we call the rendering tools first, we don’t have a DOM to traverse. Plain text methods would be much, much harder.

Yes, I don’t think that’s very useful:

title: Silly Example

One of those stupid summer camp rhymes about food comes back to haunt me far too often:

> "I like <span class="yellow food">bananas</span>, <span class="food">coconuts</span>, and 
> <span class="delicious food">grapes</span>. 
> "I like <span class="yellow food">bananas</span>, <span class="food">coconuts</span>, and 
> <span class="delicious food">grapes</span>. 
> "I like <span class="yellow food">bananas</span>, <span class="food">coconuts</span>, and 
> <span class="delicious food">grapes</span>.
> That's why they call me Tarzan of the Apes!

It's not really about food, of course.  It's just using various different types of food 
stereotypically associated with...

And then for this tiddler:

findContext(25)('food')(input)

would yield:

[
    'summer camp rhymes about food comes back to haunt me f',
    'like <span class="yellow food">bananas</span>, <span c',
    'nas</span>, <span class="food">coconuts</span>, and\n>',
    '> <span class="delicious food">grapes</span>. \n> "I li',
    'like <span class="yellow food">bananas</span>, <span c',
    'nas</span>, <span class="food">coconuts</span>, and \n>',
    '> <span class="delicious food">grapes</span>. \n> "I li',
    'like <span class="yellow food">bananas</span>, <span c',
    'nas</span>, <span class="food">coconuts</span>, and \n>',
    '> <span class="delicious food">grapes</span>. \n> That's',
    '!\n\nIt\'s not really about food, of course.  It\'s just u',
    'rious different types of food \nstereotypically associa'
]

The first result and the last two don’t belong, as they are not tags, and the others are not really capturing the tags, just the whole HTML text. That’s why I think rendering: all the way to the DOM – or perhaps only as far as TW’s syntax tree – is necessary.

But I am intrigued by your first two snippets. Could you expand on them a bit?

Sure, this one is closest to what you’re asking for:

<<quotable tagname>>

While it doesn’t support specifying a class, it does allow fishing out every occurrence of elements called “tagname”. For example, let’s say you have…

<about-mars>
Stuff about Mars.
</about-mars>

<p>Stuff about something else...</p>

<about-mars>
More stuff about Mars.
</about-mars>

And in another tiddler…

<about-mars>
Even more stuff about Mars.
</about-mars>

So, no matter which tiddler they are in, the quotable macro will pull out and render…

Stuff about Mars.
More stuff about Mars.
Even more stuff about Mars.

I am not really sure what you try to achieve. – You describe a solution, that should achieve something.

This paragraph describes a goal: “It generates a list of each instance for that CSS class”. … But it assumes that assigning a class to text can be found by TW.

It can for exactly that usecase. Search for @@.higlight in the search input and you will get every tiddler, that contains this TW markup. – But that’s probably not what you want to achieve.

So again. Can you describe what you really want? – Not how you think it can be implemented.

Sure, happy to expand upon it.

So what I had in mind was a way to build a filter that looks through your tiddlywiki and finds any HTML elements that have a specific class. whatever is in that element or that element itself if it is a button or something, is then listed.

so for instance, it wouldn’t function like, [css:class[banana]] showing any tiddlers with an element that has .banana, but only that element, and whatever is inside it.

or in other words:

<p>
<details>
<summary>Hello There</summary>

<p>This is not a fruit,</p>
<p class="banana"> This is a fruit!</p>
<p>This is a paragraph.</p>

</details>
</p>
{{{ [css:class[banana]] }}}

Which shows:

<p class="banana"> This is a fruit!</p>

Does this help? I will think of other ways of elaborating in the mean time. It would be like transcluding snippets of text, rather than whole tiddlers.

Which is exactly what quotable does, but not with classes (not about to write a parser just to do that).

As Scott pointed out. There only is HTML on the page that you see at any time. If you close a tiddler in the story river it’s HTML is gone. Converting wikitext into HTML is very heavy weight in terms of CPU cycles.

So the fastest way is, to search the wikitext. That’s probably what CodaCoder uses for the “quotable” macro.

The reason why we can list backlinks fast is, that we keep tiddlers parse-tree in an internal cache and create a backlinks-index. The index only needs to be created once when it is used the very first time or a tiddler is modified. Processing time for backlinks grows linear with the number of tiddlers in the wiki.

The links-operator is relatively fast, because most of the time it only needs to evaluate a small list of tiddlers. As far as I know, the links list needs to be recreated every time the operator is requested.

Long story short. At the moment TiddlyWiki has no low level utilities to achieve what you suggest with the “class” indicator.

Searching for classes in the HTML DOM with JavaScript is easy, but only if all the tiddlers would be visible at the same time.

1 Like

Ah alright. That does make sense. Well I’m still glad I asked about it none the less!

I may look into something similar to codacoders proposed macro, I have an idea or two about what I could do in the meantime :thinking: