Using $params as a rest-style parameters

(I almost filed this under tips-and-tricks, as I have something working, but I would like feedback about whether there are simpler ways to do this.)

I found a technique to combine many parameters into one. The idea is that I don’t want my wiki editors to have to add quotes around the final, optional, argument to my procedure. The first two parameters are required, but the third one will be created out of the others if it’s not supplied. I’m generating a link, and the url it creates is essential, and my proc will build the display text for you, but if you want to override that, you can supply it yourself.

These generate URLs such as https://www.law.cornell.edu/uscode/text/41/8101 and create links, using those URLs for the links’ hrefs.

That last case overrides the default text of the link. It works fine, but I want to make it as easy as possible for (non-TW-savvy) editors of my wiki to add such links. I would like to remove the quotation marks:

This is what in JS is called rest parameters1. I achieved this with the <$parameters> widget and its $params property. Basically, I skip the first two JSON indexes, and then gather the values of the others, joining them back together with spaces.

The code looks like this:

\procedure usc()
<$parameters title section $params="params" >
<$let 
  url=`https://www.law.cornell.edu/uscode/text/$(title)$/$(section)$`
  text={{{ [<params>jsonindexes[]butfirst[2]] :map[<params>jsonget<currentTiddler>] +[join[ ]] }}}
<!--       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^'            -->
  display={{{ =[<title>] U.S.C. § [<section>] +[join[ ]] }}}
  content={{{ [<text>match[]then<display>else<text>] }}}
>
<a class="usc" target="_blank" href=<<url>> ><<content>></a>
</$let>
</$parameters>
\end

You can see this in $____rham_procedures_usc_simplified.json (951 Bytes), which is a bit simplified from my actual implementation that handles deeply nested subsections as well, $____rham_procedures_usc.json (1.2 KB).

This is not horrible, but I’m wondering if there are simpler ways to do it. Does anyone have another technique?


1 In JS

const myFunc = (param1, param2, ...others) => {
  // Here `others` is an array of all the remaining parameters supplied after param1 and param2
}

// if called like this:
myFunc('abc', true, 8, 6, 7, 5, 3, 0, 9);

// then `others` will be [8, 6, 7, 5, 3, 0, 9]
1 Like