General Form for a Macro Repeating Macro?

96 views
Skip to first unread message

Tiddly Novice

unread,
Jan 18, 2019, 4:06:53 PM1/18/19
to TiddlyWiki
Been having a lot of fun learning TiddlyWiki and relearning Java, but I've hit another wall. I need a way to repeat macros a number of times. I don't know ahead of time what those macros will be, how many times they'll need to be repeated, how many parameters the repeated macro will have, and what those parameters will be called. So far, I think I've managed to handle the first two unknowns (which macro and how many repeats) but I'm stumped on how to deal with the other two parts (how many parameters and what they're called).

Here's the code for the Tiddler I've written so far:

\define buttonmacro(countUp)
<$button style="background-color:White; width:100%; height:100%" >"""
Button Caption $countUp$
"""
</$button>
\end


<$macrocall $name=repeatmacroxv3 targetMacro=buttonmacro x=3 /
>


And here's the javascript macro I've written so far:

/*\
title: $:/_my/macros/repeatmacroxv3.js
type: application/javascript
module-type: macro

Macro to return a macro multiple times
\*/

(function(){

/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";

/*
Information about this macro
*/


exports
.name = "repeatmacroxv3";

exports
.params = [
 
{name: "targetMacro"},
 
{name: "x"}
];

/*
Run the macro
*/

exports
.run = function(targetMacro,x) {
 
var i;
 
var result;
 
for (i = 0; i < x; i++) {
   
if (i == 0) {
      result
= "<<" + targetMacro + " " + String(i + 1) + ">>";
   
} else {
      result
+= "<<" + targetMacro + " " + String(i + 1) + ">>";
   
}
 
}
 
return result;
};

})();


My instincts are telling me to try using lists somehow to pass the parameters to the javascript and maybe seeing if the javascript can check what the macro to be repeated wants for parameters. But I'm not sure that's the best way. In fact, I feel like this is something that would have been so commonly needed that someone would have already made a plug-in or macro for this situation already. But I can't seem to find it, probably because I haven't found the right search terms.

So my questions are:
1. Has someone made a generalized macro repeater already, and if so, where can I get it from?
2. If a generalized macro repeater doesn't already exist, how what is the best way to create 

Tiddly Novice

unread,
Jan 18, 2019, 4:33:17 PM1/18/19
to tiddl...@googlegroups.com
Mere moments after I posted, I realized I was overthinking the problem. I just needed to use spaces.

The code for a demonstration tiddler:

\define buttonmacro(countUp caption1 caption2)

<$button style="background-color:White; width:100%; height:100%" >
"""
Button $caption1$ $caption2$ $countUp$
"""
</$button>
\end


\define buttonmacro2(countUp caption1 caption2)

<$button style="background-color:White; width:100%; height:100%" >"""
Button $caption1$ $caption2$ $countUp$
"""</
$button>
\end


\define interimmacro(countUp caption1 caption2)
<$macrocall $name=repeatmacroxv4 targetMacro=buttonmacro2 x=$countUp$ parameterPassing="$caption1$ $caption2$"/>
\end


<$macrocall $name=repeatmacroxv4 targetMacro=buttonmacro2 x=3 parameterPassing="Buttons Words"/>


<<interimmacro 4 Dog Cat>>


The code for the demonstration javascript:

/*\
title: $:/_my/macros/repeatmacroxv4.js

type: application/javascript
module-type: macro


Macro to return a macro multiple times
\*/

(function(){


/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";


/*
Information about this macro
*/



exports
.name = "repeatmacroxv4";



exports
.params = [
 
{name: "targetMacro"},

 
{name: "x"},
   
{name: "parameterPassing"}

];


/*
Run the macro
*/

exports
.run = function(targetMacro,x,parameterPassing) {

 
var i;
 
var result;
 
for (i = 0; i < x; i++) {
   
if (i == 0) {

 result
= "<<" + targetMacro + " " + String(i + 1) + " " + parameterPassing + ">>";
 
} else {
 result
+= "<<" + targetMacro + " " + String(i + 1) + " " + parameterPassing + ">>";
 
}
 
}
 
return result;
};


})();

I'm pretty sure this works, but I'm still so new at this that I might be making some unobvious mistake that will become a problem later. So critiques are welcome if needed.

Edit: just realized this doesn't include how to deal with named parameters. Still figuring that out, also still don't know if this is the best way to do this.

Tiddly Novice

unread,
Jan 18, 2019, 5:15:16 PM1/18/19
to TiddlyWiki
Okay, I'm pretty sure I've gotten a $macrocall with named parameters version working.

Here is the demo tiddler:

\define buttonmacro3(countUp param1 param2)

<$button style="background-color:White; width:100%; height:100%" >
"""
$param1$ $param2$ $countUp$
"""
</$button>
\end


\define interimmacro2(countUp caption1 caption2)
<$macrocall $name=repeatmacroxv5 targetMacro=buttonmacro3 x=$countUp$ parameterPassing="param1=$caption1$ param2=$caption2$"/
>
\end


<$macrocall $name=repeatmacroxv5 targetMacro=buttonmacro3 x=3 parameterPassing="param1=Buttons param2=Words"/>


<<interimmacro2 4 Dog Cat>>


<<interimmacro2 2 Moose Squirrel>>



And here is the javascript:

/*\
title: $:/_my/macros/repeatmacroxv5.js

type: application/javascript
module-type: macro


Macro to return a macro multiple times
\*/

(function(){


/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";


/*
Information about this macro
*/



exports
.name = "repeatmacroxv5";



exports
.params = [
 
{name: "targetMacro"},
 
{name: "x"},
   
{name: "parameterPassing"}
];


/*
Run the macro
*/

exports
.run = function(targetMacro,x,parameterPassing) {
 
var i;
 
var result;
 
for (i = 0; i < x; i++) {
   
if (i == 0) {

 result
= "<$macrocall $name=" + targetMacro + " countUp=" + String(i + 1) + " " + parameterPassing + " />";
 
} else {
 result
+= "<$macrocall $name=" + targetMacro + " countUp=" + String(i + 1) + " " + parameterPassing + " />";
 
}
 
}
 
return result;
};


})();


It's not the most elegant design, but it is still a working way to do this. I'm still interested if somebody knows a better way though.

TonyM

unread,
Jan 19, 2019, 2:46:30 AM1/19/19
to TiddlyWiki
Tiddly Novice,

Thanks for sharing with the community. I am a Super User rather than a Java script writer. So it is not as meaningful to me as it would to others. However If a knew better what you wanted to do from the get go, I could more than likely do it in WikiText/Macros. 

If you want to post your desired solution, I would be happy to have a go to illustrate the possibilities, or even a way to simplify your javascript and make it more versatile.

Regards
Tony

Thomas Elmiger

unread,
Jan 19, 2019, 6:42:51 AM1/19/19
to TiddlyWiki
Hi,

My favorite repeater is the list widget:


\define buttonmacro(countUp, caption)

<$button style="background-color:White; width:100%; height:100%" >
"""

Button $caption$ $countUp$
"""</$button>
\end

<$list filter="[enlist[1 2 3]]" variable="nr">

<$macrocall $name="buttonmacro" countUp=<<nr>> caption="c" />

</$list>

Does that work for you?

Cheers,
Thomas

TonyM

unread,
Jan 19, 2019, 8:14:26 AM1/19/19
to TiddlyWiki
Thomas et al

We now have the range operator as well.

List is to me the key to tiddlywiki because through it and filters its all about sets, sets of tiddlers, tags, fields or any other list.

It is for all or for each we use list to repeat anything macro or otherwise.

Regards
Tony

Tiddly Novice

unread,
Jan 19, 2019, 4:43:33 PM1/19/19
to TiddlyWiki
Mostly what I was trying for was just a general purpose repeater. Sort of like a For Loop from Java or Basic, except for Wikitext instead. Of course, since TiddlyWiki can just use a javascript to loop things as needed, I guess the best option for me right now is to just use javascript when I need stuff like that. Anyway, I've figured out what I needed to do for this part of my self-imposed training assignment so I can get to the next part. Thanks.

TonyM

unread,
Jan 19, 2019, 6:53:04 PM1/19/19
to TiddlyWiki
Tiddly Novice,

May I respectfully suggest no need to resort to java script in most cases, because tiddlywiki does this nativity in Widgets and filters. If you do build things in javascrip that do things tiddlywiki does not currently do, please share with the community.

Regards
Tony
Reply all
Reply to author
Forward
0 new messages