Inject at position N?

How would I split an arbitrary text at the n’th character?

Actually, my goal is a macro that, as input, takes a target tiddler, a source tiddler and a position N, and then injects the text from the source tiddler into position N in the target tiddlers text.

I’m thinking I should copy the target text and split it at position N, append the source text, and append the rest of the original target text after N. But I don’t know how to split the text at position N - ? (And, obviously, I must not loose e.g space characters or formatting in the process…)

Ideas?

Quickly slapped together “old school” approach:

<$let s="abcdefghijklmnopqrstuvwxyz"
          n=10
          i="*"
          s1={{{ [<s>split[]first<n>butlast[]join[]] }}}
          s2={{{ [<s>removeprefix<s1>] }}}
          sm={{{ [<s1>] [<i>] [<s2>] +[join[]] }}}>

* s = <<s>>
* n = <<n>>
* i = <<i>>
* s1 = <<s1>>
* s2 = <<s2>>
* sm = <<sm>>

</$let>

image

2 Likes

Wunderbar - thank you @Charlie_Veniot !

What is the “new school” approach then?

All of my TW instances, including any new ones I create, are version 5.2.3

Whatever new goodies added after version 5.2.3 are of no interest to me, so if there are any “new school” ways of doing things, I would have no idea what they are.

Even if there are other filters in version 5.2.3 that might make for less work than what I’ve coded, I also wouldn’t know what they are.

You could also search-replace the first N characters of the original string with that string + your insertion text.
The regex for the search (with e.g. 5 characters) is ^(.{5}), the replacement is $1‹yourtext›. You’d build the search and replacement term variables dynamically, e.g. <$let replacement={{{ [<sourcetiddler>get[text]addprefix[$1]] }}} />.
I’m not sure if it’s overall shorter, more elegant or new school, though.

3 Likes

Hi @twMat
Based on @Yaisog solution, I implemented an injection as shown below, but I’m not sure how readable and semantic it is compared to the more understandable and followable solution by @Charlie_Veniot.

\procedure insertAtPos(input, insert, n)
<$let
  pattern=`^(.{$(n)$})`
  replacement= `$1$(insert)$`
  result={{{ [<input>search-replace:g:regexp<pattern>,<replacement>] }}}
>

* ''Input:'' <$text text=<<input>> />
* ''Insert:'' <$text text=<<insert>> />
* ''n:'' <$text text=<<n>> />
* ''Result:'' <$text text=<<result>> />
</$let>

\end

<<insertAtPos "Hello TiddlyWiki. You are the best note-taking tool." "I love you! " 18>>

Returns:

  • Input: Hello TiddlyWiki. You are the best note-taking tool.
  • Insert: I love you!
  • n: 18
  • Result: Hello TiddlyWiki. I love you! You are the best note-taking tool.

To be honest I dont like syntax like below :wink:

replacement= `$1$(insert)$`

You can use the older “filtered transclusion with join” syntax, like this;

<$let
  pattern={{{ [[^(.{]] [<n>] [[})]] +[join[]] }}}
  replacement= {{{ [[$1]] [<insert>] +[join[]] }}}
  result={{{ [<input>search-replace:g:regexp<pattern>,<replacement>] }}}
>

-e

1 Like

I made this: https://inject.tiddlyhost.com/

I’m not sure it is worth bothering to publish officially because it is so very niched for (as you see there) plugin makers. At least that’s the intended user group - and that’s another aspect; the ability to inject arbitrary content via a macro call may be a bit sensitive so maybe it shouldn’t be generally broadcasted about? Anyway, I’m announcing it here since you guys have implied your interest in the matter and to show what I did with your kind help.