[Solved] Struggling with dynamic filter string

Let’s say I have the following list:

1.

CH1 CH2 CH3 ... CHn

Let’s say ideally I want to produce this:

2.

[prefix[CH1]] [prefix[CH2]] [prefix[CH3]] ...

Further, let’s say I need to add the latter to a filter (for use in @pmario’s bundler plugin, if it matters)

3.

"stuff things this that the-other [prefix[CH1]] [prefix[CH2]] [prefix[CH3]] ..."

#1 is stored in a tiddler. Production of #2 should be easy but… :exploding_head: :grimacing:

Even with #2 prebuilt and strored in a tiddler, it confounds me as to how to produce #3. :sweat:

I can live with #2 if I need to, but can anyone think of a way, in one filter expression, to go from #1 to #3? Failing that, #2 to #3?

:pray:

I’m not sure I follow exactly, but this works for me at TiddlyWiki.com:

<$let filter="[prefix[a]] [prefix[b]] [prefix[c]]">

<$list filter={{{ [<filter>addprefix[ "this" "that" "the other"]] }}} />

</$let>

If “New Tiddler” contains “CH1 CH2 CH3”, then

\function foo(pfx,tid) [<tid>get[text]split[ ]encodeuricomponent[]addprefix[%5Bprefix%5B]addsuffix[%5D%5D]] +[decodeuricomponent[]join[ ]addprefix[ ]addprefix<pfx>]

<<foo "stuff things this that the-other" "New Tiddler">>

Might be what you want?

Thanks but…

I need a string (see title). IOW, it’s not for use in <$list ...>.

Ah… now that might have some legs. Thank you!

Maybe I don’t understand what’s at stake in “string”… You can use this any way you like:

<$text text={{{ [<filter>addprefix[ this that the other ]] }}}/>

Say more about what you need and why?

Previous reply edited…

It’s a bit like storing a filter’s text in a tiddler, perhaps tagged with filter, like the advanced search works. In the production of the string, I need to store not just the “knowns” (static stuff) but calculate/append the dynamic part (essentially the “unknowns”).

Looking at the output, what I have right now seems to work, except for the fact that when the filter is executed, “[prefix[CH1]] [prefix[CH2]] …” are being treated like text, i.e. as full on titles.

It’s an odd problem, but a problem nonetheless.

@andrewg_oz’s idea seems worth a shot. A function[] call will hopefully provide the “inner evaluation” I seem to need. IOW, it might prevent the “treating as titles” problem mentioned above.

In order to get the prefix[] surround, what about using a substitution string? Like in:

<$let surround="[prefix[$(currentTiddler)$]]">
<$text text={{{ [[CH1]] [[CH2]] [[CH3]] :map[<surround>substitute[]] :and[join[ ]] }}}/>
</$let>
1 Like

I feel as if I may be missing some complexity, but here’s what I’d try:

\function prefixed.with(input) [enlist<input>] :map:flat[all[tiddlers]prefix{!!title}]

{{{ stuff things this that the-other [prefixed.with{!!prefixes}] }}}

{!!prefixes} was just what I used for ease of testing on TW-com, and could of course point to any externally stored list.

Or “subtlety”.

Can you see that working here?

That’s the nub, I think: Store a string (with tag:filter) that evaluates the above and produces the desired output. @pmario’s bundler works identically. If I have to store a separate global function, that’s fine too. But I’m having trouble making it work.

Solution derived from @andrewg_oz 's idea…

\function .foo(tid) 
[<tid>get[text]split[ ]encodeuricomponent[]addprefix[%5Bprefix%5B]addsuffix[%5D%5D]] +[decodeuricomponent[]join[ ]]

I made that a $:/tags/Global function.

(@andrewg_oz you’ll notice the rejig I did. The pfx stuff doesn’t need to be passed in.)

A temp copy of #1 in the OP:

title: temp
text: CH1 CH2 CH3

Result:

image

Bingo.

Big thanks for your time, everyone.

No, no, no… that’s NOT a solution. Once again, the filter is treating each mention of [prefix[...]] as a title.

Back where I started…

Revisited. :wink:

Yes, okay, complexity. Hopefully the following will nail it.

Look back to my previous post. While it looks as though the “solution” is correct, what it’s not doing is, evaluating the last three elements in the result. Those prefix operators you’re seeing are simply text being produced from the (let’s call it) outer filter.

So the question is now extended: how to evaluate a filter’s output string, as a filter.

With the function stored in a global tiddler and the list of prefixes stored in a separate tiddler, as you said:


(I omitted the leading “stuff” tiddlers as I wasn’t sure whether they were meant to be constant; you can add them back in if so, of course.)

2 Likes

One way is to define a function the filter and use a function[functionname] in the subsequent filter.

@CodaCoder

Unfortunately I don’t understand the question, or why it’s being asked and feel perhaps the question is less than perfect.

  • But I a deep down feeling this can be done in a much simpler way.

That’s okay. It was difficult to get across the nature of the problem, too.

What!? Seriously?

So, taking what @etardiff did, but without a global function:

[[MyPrefixes]get[text]split[ ]] :map:flat[all[tiddlers]prefix{!!title}]

That {!!title} trick might be useful for some things I’m working on…

1 Like

The reason I suggested a global function (aside from reusability and brevity when used as part of a longer filter) is that, once you introduce a :map filter run, it will act on all preceding input. This isn’t necessarily a major issue, but it does mean that any additional titles/filter runs, like @CodaCoder’s stuff things this that the-other, will have to follow the map step:

[[MyPrefixes]get[text]split[ ]] :map:flat[all[tiddlers]prefix{!!title}] stuff things this that the-other

By isolating the :map step in a function with its own selection constructor [enlist{MyPrefixes}] (equivalent, in this case, to [[MyPrefixes]get[text]split[ ]]—though it also allows you to store multi-word prefixes in list format in MyPrefixes) you gain some flexibility in the sequence of filter runs.

You could also define several variants on the same structure and mix and match them within a filter:

\function has.prefix(input) [enlist<input>] :map:flat[all[tiddlers]prefix{!!title}]
\function has.suffix(input) [enlist<input>] :map:flat[all[tiddlers]suffix{!!title}]
\function has.tag(input) [enlist<input>] :map:flat[all[tiddlers]tag{!!title}]
\function has.tag.commas(input) [<input>split[,]trim[ ]] :map:flat[all[tiddlers]tag{!!title}]

[has.prefix{MyPrefixes}] [has.suffix[readme license]] -[has.tag.commas[exclude, a multi-word tag]]

Personally, I’ve been using @CodaCoder’s dynamic filter approach to eliminate long strings like [tag[A]] [tag[B]] [tag[C]] -[tag[D]] -[tag[E]] from my own wikis. [has.tag[A B C]] -[has.tag[D E]] feels much neater!

1 Like

That’s perceptive in the extreme. :clap:

And you did! :laughing:

That production is the key step, such that the output is evaluated (not just appended as text, which was the issue I was having all along).

Thanks again.