Filter input text to paragraphs containing a link to a particular tiddler?

I currently have a filter that returns the text of the input tiddler, split into individual paragraphs:

[<inputTiddler>get[text]splitregexp[\n]]

I would now like to filter down the list further to output only those paragraphs that contain a link to <<currentTiddler>>.

Now I kind of got half way there by messing around with the search[] operator, but it’s not ideal because a link to a tiddler can appear in so many different ways (e.g. HelloThere, [[HelloThere]], [[random text|HelloThere]]).

I’m wondering if anyone could suggest a cleaner approach?

Have you thought of using nested list widgets? The first finds all paragraphs, the second tests each;

  • I have noticed a trend to try and cram everything into one filter, when it is not only unnecessary but makes it harder to make use of values and variables found in each filter.
  • Nested lists can in some cases be more efficient, give more control and produce better layouts.

Thanks @TW_Tones, but I don’t see how this solves the problem? I would still need to filter the list of paragraphs into just those that contain a particular link, and I don’t know how to do this.

It is frustrating that the link operator only works with titles, not text input. I’ve run into similar issues with link extraction before… IIRC I ended up using split to split the input text at [[ and ]] (and then discard anything before a |).

It might be easier if you’re only interested in links to <<currentTiddler>>… I might try making use of variables defined in macros, which would let you use text substitution to capture the square brackets.

\define link() [[$(..currentTiddler)$]]
\define prettylink() |$(..currentTiddler)$]]

<$list filter="[<inputTiddler>get[text]splitregexp[\n]] :filter[search<link>else<currentTiddler>search<prettylink>]">

</$list>

(Note that the .. in $(..currentTiddler)$ is only necessary because I used the :filter prefix, which redefines <<currentTiddler>> to refer to each input string.)

This wouldn’t help you with CamelCase links, of course, so if you use them a lot, you might need to resort to regexp.

Let me know how it goes!

Here’s one “cleaner approach” that may or may not work, depending on your reason for dealing with longer tiddlers.

The cleaner approach I’d consider, if I wanted my searches to focus in on paragraph-level results, is “refactoring” the wiki so that each substantive paragraph is a tiddler, and any longer stretches of text are accomplished through transclusions.

You could even use a paragraph-tiddler template that gestures clearly and decisively toward the encompassing text. (I imagine a neat little “fading in” transclusion from prior paragraph and “fading forward” into next paragraph, at the paragraph-tiddler level, and an obvious “read this paragraph in context” button. I’d consider a two-column design – one main column scrolling through the source text (actually a “container” tiddler), and a second column for putting the magnifying glass on this or that chosen paragraph.)

Perhaps you’ve already considered this, and you’re locked into working with keeping the primary text in long tiddlers for reasons beyond your control. But just for the sake of the archive, future wiki design, etc…

Let us know what you do!

1 Like

It was more an approach to solving the problem. But know I see the main issue is using parsing functions Normaly done on the body text once that text is in a variable.

  • I am confident this is a feature gap

Some speculation

  • There may be a way to find a workaround but it seems something like @Springer’s approach may be nessasary.
  • if you are happy to have a button as trigger you could put each paragraph in a temp tiddler then introgate each paragraph tiddler.
  • I note in your example simply searching for "HelloThere will find it in all the different cases.
  • Once seperating each paragraph you can use the wikify widget on it, but not to parse/query it.
  • This is reminisent of @Mohammad’s section editor plugin which divides the content by headings.

I am curiouse why the target of your search is <<currentTiddler>>?

I have an idea, a more general solution, kind of reverse the logic, at most it may have a false positive.

  • Scan the text for links and save the titles in a variable (link operator etc…)
  • Now process each paragraph and check for those titles (all of them) in each paragraph, you will be searching for the “title of the link” only.
    • List (wikify?) only those paragraphs where the link “text” is found in the current paragraph, or that matches your <<currentTiddler>>.

Other approaches may be

  • to wikify the whole tiddler and do your search and paragraph splits against the html generated.
  • Look at how the Free links plugin works

Thanks everyone. I’m actually just trying to add context to backlinks. I know there exist plugins for this, I’m just messing around with a wikitext solution.

I think it is the case that for now I will need to use regex if I want to reliably match links, but as tones pointed out a plain search for the title will work OK in most cases. Separate tiddlers for each paragraph is a valid option but just isn’t something I want to do.

Thanks again :slight_smile:

@Sii just for completeness tiddlywiki already uses its parsing to identify links, that is how they are rendered in the first place. There are opportunities in TW 5.3.0 currently pre-release to Exploring default tiddler links hackability in V5.3.0.

  • I think there may be some simpler solutions for you but though I should bring it to your attention.

As I understand it, the gap @Sii was encountering—certainly the gap that I’ve encountered before—was that while TW does identify links in the text field, the links[] operator only accepts titles of tiddlers to be checked. There’s no way to use it to check for links in an arbitrary chunk of text. You can try these two examples at tiddlywiki.com to see the difference:

{{{ [[HelloThere]links[]] }}}

{{{ [[HelloThere]get[text]splitregexp[\n]first[]links[]] }}}

Ideally, there’d be a way to filter for links in only the first paragraph of “HelloThere”, but there isn’t, at present.

5.3.0 should let us create custom functions that condense all the complicated regex and/or splitting needed to do this currently, but it does still seem like a missing feature in the standard filter operators. (Of course, if I’m missing some existing alternative, I’d love to be proven wrong!)

Agreed, this is a gap to fill, in this case we want to run a filter against the text in a variable, in your case each paragraph.

I do still feel there is a work around, convoluted yes, but still a work around;

I have a hunch this will be easier, perhaps even possible in TW 5.3.0 because transclusions can be given parameters including fill/slots, and driven by $variable, thus you would “transclude” each paragraph.

As you said, this is convoluted but doable—when the text to be scanned is in the ‘‘text’’ field. I really wish we had, at minimum, an extensible links operator that would permit something like links:my-field[]… though of course this wouldn’t be necessary if we had, say, a textlinks[] operator that simply parsed its input string.

I don’t see an easy way to return paragraph neatly with this, but the ContextPlugin by @danielo515 does show search results within surrounding context, specifiable as a number of characters this way and that.

I wonder whether someone with greater skill could tinker with its details so as to show each result with as much “before” context as it takes to arrive at some kind of paragraph break (or field start), and as much “after” context as would be needed to get to something like the end of the paragraph.

Even if that solution can’t be hacked, I imagine that among folks curious about paragraph-specific search results, some such folks might be happy with search results that are highlighted within their context…