Summary: Description of ParseArgs function for parsing argument lists
Prerequisites: pmwiki-2.0.0
Status: Stable
Maintainer: Petko (original author: Pm)
Discussion: ParseArgs-Talk

Questions answered by this recipe

  • Is there a function to make it easier to parse directive arguments when writing Cookbook recipes?
  • How do I make use of the ParseArgs function?


Since 2.0.beta25, PmWiki has a built-in function called ParseArgs that simplifies the parsing of argument strings, e.g. for (:directives:). This recipe describes how ParseArgs works and how it can be used.

For example, here's a directive for a list of all "normal" pages in the Cookbook:

    (:pagelist group=Cookbook list=normal fmt=simple:)

Or, for a search of all pages in Main containing "apple" and "cherry" but not "apple pie":

    (:searchresults group=Main apple -"apple pie" cherry:)

The potential for items to be quoted is what makes parsing such arguments a challenge. This is where ParseArgs is useful -- it will accept a string containing name=value and other (possibly quoted) arguments, and return an array with the arguments all in place. For example, given

    $args = ParseArgs('group=Cookbook list=normal fmt=simple');

the $args variable would then be set with:

    $args['group']     'Cookbook'
    $args['list']      'normal'
    $args['fmt']       'simple'

This makes it simple to grab options from a string:

    $args = ParseArgs($x);      // $x is the string to be parsed
    $group = $args['group'];
    $list = $args['list'];
    $fmt = $args['fmt'];

Default values for options can also be easily handled:

    $defaults = array('fmt'=>'bygroup', 'list'=>'all');
    $args = array_merge($defaults, ParseArgs($x));
    $group = $args['group'];   
    $list = $args['list'];     
    $fmt = $args['fmt'];

Arguments that dont have a name= in front are placed into an '' array entry:

    $args = ParseArgs('group=Main apple cherry');

resulting in

    $args['group']     'Main'
    $args['']          array('apple', 'cherry');

Arguments preceded by '+' or '-' get their own array entries:

    $args = ParseArgs('group=Main apple -"apple pie" cherry');

    $args['group']     'Main'
    $args['']          array('apple', 'cherry')
    $args['-']         array('apple pie')

Finally, if the order of all of the arguments needs to be known, a special '#' entry provides the complete ordering:

    $args = ParseArgs('group=Main apple -"apple pie" cherry');

    $args['#']         array('group', 'Main', 
                         '', 'apple', 
                         '-', 'apple pie',
                         '', 'cherry')


Note that the function uses both "=" and ":" as an assignment operator. Thus, if you want to have a string like an URL that starts with "http:" in a numbered array $args[""], you need to pass a second argument to ParseArgs:

  $args = ParseArgs("", '(?>(\\w+)=)');

This will return $args[""][0] = "". Otherwise, you would obtain $args['http'] = "//".


As an example, you can enter an argument string to be parsed in the box below and see the values that would result from calling ParseArgs with that string.

Key                 Value(s)
---------           --------
$arg['#']           (array) 'group' 'Main' '' 'apple' '-' 'apple pie' '' 'cherry' 
$arg['group']       'Main' 
$arg['']            (array) 'apple' 'cherry' 
$arg['-']           (array) 'apple pie' 


You can't have a parameter that has both a single and a double quote in it. (You can write "This ' is a single quote" and 'This " is a double quote', but you can't write "These '" are a single and a double quote"). In this, ParseArgs follows HTML conventions.


In this section we give more examples of calling ParseArgs to process arguments.

(Feel free to add questions or examples here.)


There's a problem when the text field contains single or double quote to be displayed:

   (:gma-point lat=yyy lon=xxx text="Vincent's home":)

Here is the hack (for version 2.1.2). In the file cookbook/GoogleMapAPI/gma-2.1.2.php

 line 181 in the if structure add the following lines:
   $m = preg_replace("/'/","\'", $m);
   $m = preg_replace('/"/','\"', $m);
 line 304 before the call to the function parseArgs add the following lines:
   //Hack for quotes
   //end hack

See Also


  • Pm, 2005-03-02