How to Display List of Transcluded Tiddlers in the Current Tiddler

Node Explorer in Shiraz and Mehregan shows list of tiddlers transcluded in current tiddler.

One easy and understandable solution for transclusion references is the below macro. I am sure others can give better solution.

\define ref-transclusion-in-thisTiddler(tiddler)
<$let tidText={{{ [<__tiddler__>get[text]] }}}
	leftcb="{{"  
	rightcb="}}"
	fieldop="!!"
	templateop="||">
<$list filter='
	[<tidText>split<leftcb>butfirst[]]
	:filter[<currentTiddler>trim[]!prefix[{]]
	:map[split<rightcb>first[]]
	:map[split<fieldop>first[]trim[]]
	:map[split<templateop>first[]trim[]]
'>
	<$link/><br>
</$list>
</$let>
\end
  • To give a try
  • Open: https://tiddlywiki.com/
  • Create a new tiddler
  • Tag it with $:/tags/Macro
  • Put the above macro inside it and save
  • As an example, in a new tiddler enter
<<ref-transclusion-in-thisTiddler "HelloThere">>

It will display:

$:/core/images/help
$:/core/images/video
$:/core/images/twitter
$:/core/images/github
$:/core/images/gitter
Product Hunt Link

Note all cases of transclusion is covered by above macro e.g. for transclusion through template we have:

{{thisTiddler||myTemplate}}

{{thisTiddler||myTemplate    }}
{{      thisTiddler||myTemplate}}
{{    thisTiddler||myTemplate   }}
{{   thisTiddler  ||   myTemplate   }}

{{thisTiddler
||
myTemplate}}

EDIT 1: A :filter is added to exclude cases like {{{ [[myTiddler]get[caption]] }}}. This is a filter transclusion and shall be excluded.

References

1 Like

I have a feeling that regexp would be ideal to deal with such things. Playing around a bit on https://regex101.com/, this one might do the trick (except maybe edge cases?):

{{\s*(.*?)\s*(?:}}|\|\||!!)

Since TW cannot extract text snippets according to a regexp, I’d put in start and end tokens before and after the capturing group using search-replace and then split the text apart at these points like so (untested):

\define subsplit() [all[current]split[###end###]first[]]

[all[current]get[text]search-replace:gm:regexp[{{\s*(.*?)\s*(?:}}|\|\||!!)],[###start###$1###end###]split[###start###]subfilter[subsplit]]

What you should be left with is a list of transcluded tiddler titles.

Have a nice day
Yaisog

1 Like

Just to extend the great work done so far

  • I modified the original macro
    • to use the current tiddler if none was provided
    • To display an emptyMessage
  • I then Created an Info tiddler so now there is an additional tab behind the Info button that displays the found transclusions;
\define transcluding(tiddler emptyMessage:"not transcluding other tiddlers")
\whitespace trim
<$set name=tiddler value="""$tiddler$""" emptyValue=<<currentTiddler>> >
<$let tidText={{{ [<tiddler>get[text]] }}}
        leftcb="{{"
	    rightcb="}}"
		fieldop="!!"
		templateop="||">
<$list filter="""
    [<tidText>split<leftcb>butfirst[]] 
	:filter[<currentTiddler>trim[]!prefix[{]]
    :map[split<rightcb>first[]] 
    :map[split<fieldop>first[]trim[]] 
    :map[split<templateop>first[]trim[]]""" 
    emptyMessage={{{ [[$emptyMessage$]!match[none]!is[blank]] }}}>
   <$link/><br>
</$list>
</$let>
\end

[Edited] To include @Mohammad’s revised filter above and package below

tiddlerInfo-Transcluding-tab.json (1.3 KB)

I am still working on how to use the transcluding macro as a test in a filter.

1 Like

Hi @Yaisog
A small issue is the above pattern also captures {{{ so it returns the argument of filter transclusion as a match.

1 Like

@Mohammad: You are exactly right.
Instead of tweaking my regexp, possibly introducing more non-working edge cases, I’ll just climb onto the shoulders of giants and copy from $:/core/modules/parsers/wikiparser/rules/transcludeinline.js. There the following regexp is used to parse the syntax:

\{\{([^\{\}\|]*)(?:\|\|([^\|\{\}]+))?\}\}

This should cover everything that TW thinks is an inline transclusion.
However, this regexp does not remove whitespace at the beginning or end of found strings. This is done separately in the core, but can also be done with a trim filter. The resulting filter would then be:

\define core-transclude-regexp() \{\{([^\{\}\|]*)(?:\|\|([^\|\{\}]+))?\}\}

[all[current]get[text]search-replace:gm:regexp<core-transclude-regexp>,[###start###$1###end###]split[###start###]] :map[split[###end###]first[]trim[]]

I also took inspiration from you and used map instead of subfilter. :slight_smile:

Have a nice day
Yaisog

2 Likes

Nice response! I dunno if all those escapes ("\") are really needed?
I’m thinking on it. But kudos you got a workable.

Just a comment
TT

I don’t think curly braces need to be escaped in regexp. But if it ain’t broken…

Have a nice day
Yaisog