[pmwiki-devel] Markup -> ParseArg

Petko Yotov 5ko at 5ko.fr
Tue Feb 8 04:34:54 PST 2022


On 07/02/2022 03:01, Simon wrote:
> Here is one idea
> $opt       = \ParseArgs(implode (' ', array_slice ($m, 1)));
> 
> but I'm hoping there is some helper function built in?


ParseArgs() is the built-in helper function! :-)


My life would be much, much easier, and I would be much happier, if I 
have just one, not 17, captured matches in my regular expression, and I 
parse that one single match:

   Markup('myfunc', 'directives', '/\(:myfunc(.*?):\)/i', 
'FmtMyFunction');

   function FmtMyFunction($m) {
     $args = ParseArgs($m[1]);
     # first do something with $args['width']
     # then, do something with $args['height']
     # then, do something with $args['zoom']
     # then, do something with $args['label']
   }


See/test it on this page:

   https://www.pmwiki.org/wiki/Test/ParseArgs


On the top, there is a form where you can type the arguments (as one 
string, like in a wiki directive), and it will parse them and show what 
ParseArgs returns. This was added by Pm ~17 years ago.

After the form, I added a directive (:testpa:) to print the results of 
the ParseArgs() function.

Feel free to experiment on that page.

The goal is directives to allow people to type any arguments, in any 
order.

After parsing, your function can check for the arguments it expects, 
eventually sanitize them, cast them to integers or floats if needed.

Your function can ignore any arguments that it doesn't expect, or maybe 
do something with them. Many recipes like (:thumblist:) and (:worse:) 
ignore unexpected arguments, and so do some core directives like 
(:markup:) and (:if:).

In some cases the core will consider unexpected arguments as either html 
attributes, e.g. in (:div:), or as {$$variables}, e.g. in (:include:) or 
(:pagelist:), but ultimately if it is a typo, it will be ignored without 
breaking and without warning.


And a confession: I would now only use named arguments like 
$args['group'], and when possible avoid positional ones like 
$args[''][0]. Every time I used positional ones, I later regretted it 
when I wanted to add more arguments. Having both types makes everything 
more complex, both for the recipe and for the users.

Note that the argument names, or the keys of the $args array, are case 
sensitive.


At the bottom of that page, see my PHP function, and the Markup() call 
as well. Note how the regular expression in Markup(...) is very simple, 
and it can be as simple even for very complex recipes. Want to add a new 
argument in the future? No need to change the regexp, just test for 
$args['new_argument'].


See also, in case you haven't:

   https://www.pmwiki.org/wiki/Cookbook/ParseArgs


Petko
-- 
PmWeekly Blog  :  http://www.pmwiki.org/News
If you upgrade :  http://www.pmwiki.org/Upgrades



> On Mon, 7 Feb 2022 at 14:56, Simon <nzskiwi at gmail.com> wrote:
> 
>> I'm looking for something like this
>>  $opt       = \ParseArgs($m);
>> (which doesn't return what I want)
>> as parseargs() expects a string
>> 
>> where $m is returned from the markup()  function,
>> and $opt is an array of the parameter names and values passed to a
>> directive.



More information about the pmwiki-devel mailing list