Example: Search and Replace links with _canonical_uris

Hello,

I wanted a template to switch all my links to _canonical_url tiddlers to point to the external link. This was in preparation to exporting dynamically generated reports to an HTML file and importing to Word and having the links point to the right external resources rather than internal links in a TiddlyWiki.

The solution was the following template tiddlers:

convert_to_canonical

\define lb() [[
\define rb() ]]
\define pipe() |
\define recurse_search-replace()
<$list filter="[enlist<link_list>first[]]" variable="currentLink" emptyMessage="""{{{ [<tidtext>] || delink}}}""">
<$let link_name={{{[<currentLink>split<pipe>first[]]}}} link_dest={{{[<currentLink>split<pipe>last[]]}}} to={{{ [<link_dest>get[_canonical_uri]addprefix<pipe>addprefix<link_name>else<currentLink>]}}} tidtext={{{ [<tidtext>search-replace:gm:<currentLink>,<to>] }}}>
<$set name=link_list filter="[enlist<link_list>] -[<currentLink>]">
<<recurse_search-replace>>
</$set>
</$let>
</$list>
\end

<$let tidtext={{{ [<currentTiddler>get[text]] }}}>
<$set name="link_list" filter="[<currentTiddler>get[text]split<lb>search<rb>splitbefore<rb>removesuffix<rb>]">
<<recurse_search-replace>>
</$set>
</$let>

and the formatting template

delink

<$wikify name="stuff" text=<<currentTiddler>> output=html >
<<stuff>>
</$wikify>

Transclude the tiddler with mixed links in it via:

{{TiddlerWithCanonicalLinksOrNot||convert_to_canonical}}

Where
TiddlerWithCanonicalLinksOrNot is something like this:

This is an example tiddler with a [[Normal link]] and

:a [[renamed|Other link]] normal link and
:a [[renamed link|Canonical (link)]] and to a [[Canonical (link)]]
:a link to a [[renamed something else tiddler|Canonical (link)]] and to duplicate [[Canonical (link)]]

I just wanted to share something that I got working using a convoluted recursive strategy and was wondering if there was a better way to do this using clever regexp expressions (which confound me at times) or :reduce filter runs (which didn’t seem to let me use the accumulator like I wanted to).

It took me way too long to figure out a way to do this. There seems like there should be a more elegant way to do this kind of search and replace.

Thanks,
/Mike

Edit: Removed “regexp” to made it more robust to allow Canonical link names containing parentheses.
Edit 2: Replaced link[] operator with splits to allow preservation of name of link while switching destination link to _canonical_uri .
Edit 3: There was an issue in that the previous version would not show anything if no links existed in the tiddler text. This use of emptyMessage in the first list is better and got rid of the hacky check for the last search and replace run.

2 Likes