directives',
'/(?:^\\(|(\\()):input(.*?):\\)/ei',
'InputMakeHtml(PSS(\'$1\'), PSS(\'$2\'))'
);
function InputWarning($msg) {
return
'[PmWiki Warning: '
. htmlentities($msg, ENT_QUOTES)
. '] ';
}
# Helper functions for constructing entries in $InputFmt.
function InputOptionBoolean($option) {
return " $option=\"$option\"";
}
function InputOptionString($option) {
return '/^.*$/e/\' ' . $option . '="\' . htmlentities(\'$0\') . \'"\'';
}
SDVA($InputMethods, array(
'get'
=> ' method="get" enctype="application/x-www-form-urlencoded"',
'post/urlencoded'
=> ' method="post" enctype="application/x-www-form-urlencoded"',
'post/binary'
=> ' method="post" enctype="multipart/form-data"',
'post/text'
=> ' method="post" enctype="text/plain"'
));
SDV($InputMethods['post'], $InputMethods['post/binary']);
SDVA($InputFmt, array(
# All (:input...:) markup is of the form:
# (:input :)
# For each , this array has the following entries:
# .fmt
# The HTML to emit, with $xxx placeholders
# (xxx is the name of the placeheld position).
# .required
# A space-separated list of parameter names.
# These will be filled from the required (positional)
# parameters of the markup.
# ..default
# What to generate for $ if the markup doesn't have
# =value.
# ..present
# What to generate if just (without =)
# is supplied by the markup.
# ..match
# A pattern-plus-replacement string that's used to generate
# the text for $ if the markup supplies an
# = pair.
# The string is expected to have the form
# ///
# where
# is a PCRE pattern that's supposed to
# match the markup-supplied ,
# are PCRE modifiers,
# is a replacement string that will
# be substituted into the HTML output.
# // and are sumitted to PHP's
# preg_replace function (see http://www.php.net/preg_replace).
# You can use an alternate delimiter instead of /, but Perl-style
# (), {}, [], or <> delimiters won't work. All other features
# of preg_replace (in particular subpattern matching,
# backreferences, and the /e modifier) work as described.
'start.fmt' => '',
'button.fmt' => ' ',
'button.required' => 'name label',
'button.name.match' => InputOptionString('name'),
'button.label.match' => InputOptionString('value'),
'button.disabled.present' => InputOptionBoolean ('disabled'),
'hidden.fmt' => ' ',
'hidden.required' => 'name value',
'hidden.name.match' => InputOptionString('name'),
'hidden.value.match' => InputOptionString('value'),
'line.fmt' => ' ',
'line.required' => 'name',
'line.name.match' => InputOptionString('name'),
'line.password.default' => ' type="text"',
'line.password.present' => ' type="password"',
'line.columns.match' => InputOptionString ('size'),
'line.disabled.present' => ' disabled="disabled"',
'line.maxcolumns.match' => InputOptionString('maxlength'),
'line.readonly.present' => InputOptionBoolean('readonly'),
'line.text.match' => InputOptionString('value'),
'text.fmt' => '',
'text.required' => 'name',
'text.name.match' => InputOptionString('name'),
'text.columns.match' => InputOptionString('cols'),
'text.columns.default' => ' cols="65"',
'text.disabled.present' => InputOptionBoolean('disabled'),
'text.readonly.present' => InputOptionBoolean('readonly'),
'text.rows.match' => InputOptionString('rows'),
'text.rows.default' => ' rows="5"',
'text.text.match' => '/^.*$/e/htmlentities(PSS(\'$0\'))',
'checkbox.fmt' => ' ',
'checkbox.required' => 'name',
'checkbox.name.match' => InputOptionString('name'),
'checkbox.disabled.present' => InputOptionBoolean('disabled'),
'checkbox.checked.present' => InputOptionBoolean('checked'),
'checkbox.value.match' => InputOptionString('value'),
'radiobutton.fmt' => ' ',
'radiobutton.required' => 'name',
'radiobutton.name.match' => InputOptionString('name'),
'radiobutton.disabled.present' => InputOptionBoolean('disabled'),
'radiobutton.checked.present' => InputOptionBoolean('checked'),
'radiobutton.value.match' => InputOptionString('value'),
'menu.fmt' => '',
'menu.required' => 'name',
'menu.name.match' => '/^.*$/e/\' name="\' . htmlentities(\'$0\')',
'menu.multiple.present' => '[]"' . InputOptionBoolean('multiple'),
'menu.multiple.default' => '"',
'menu.disabled.present' => InputOptionBoolean('disabled'),
'menu.lines.match' => InputOptionString('size'),
'menu.lines.default' => ' size="1"',
'menuentry.fmt' => '$value ',
'menuentry.required' => 'value',
'menuentry.value.match' => '/^.*$/e/htmlentities(PSS(\'$0\'))',
'menuentry.checked.present' => InputOptionBoolean('selected'),
'menuentry.disabled.present' => InputOptionBoolean('disabled'),
'menugroup.fmt' => '',
'menugroup.required' => 'label',
'menugroup.label.match' => InputOptionString('label'),
'menugroup.disabled.present' => InputOptionBoolean('disabled'),
'menugroupend.fmt' => ' ',
'menuend.fmt' => ' '
));
function InputFindDefault($verb, $option) {
global $InputFmt;
return IsEnabled($InputFmt["$verb.$option.default"], '');
}
function InputMakeControl($verb, $args) {
global $InputFmt, $InputMethods;
$fmt = $InputFmt["$verb.fmt"];
if (!isset($fmt)) {
return InputWarning ("'$verb' unknown in (:input $verb ...:).");
}
$required_str = $InputFmt["$verb.required"];
if (isset($required_str)) {
$required = explode(' ', $required_str);
} else {
$required = array();
}
$args = array_slice($args ['#'], 2);
while (count($args) > 0) {
$param = array_shift($args);
$arg = array_shift($args);
$positional_name = array_shift($required);
if (isset($positional_name)) {
if (strlen($param) > 0 && $param != $positional_name) {
return InputWarning("(:input $verb:) needs positional parameters '$required_str', but those starting from '$positional_name' are missing.");
} else {
$param = $positional_name;
}
} else {
if (strlen($param) == 0) {
$param = $arg;
$arg = 1;
}
}
$text = $InputFmt["$verb.$param.present"];
if (!isset($text)) {
$text = $InputFmt["$verb.$param.match"];
if (isset($text)) {
preg_match('/^((.).*?\\2.*?)\\2(.*)$/', $text, $matches);
$pat = $matches['1'];
$rep = $matches['3'];
if (preg_match($pat, $arg) > 0) {
$text = preg_replace($pat, $rep, $arg, -1);
} else {
return InputWarning("Unrecognised value '$arg' for option '$param' in (:input $verb...:) markup.");
}
} else {
return InputWarning("Unknown option '$param' in (:input $verb...:) markup.");
}
}
$fmt = str_replace("\$$param", $text, $fmt);
}
# $args is processed, now fill in defaults
$fmt =
preg_replace(
'/\\$([a-z]+)/ei',
'InputFindDefault(\'' . $verb . '\', \'$1\')',
$fmt);
if (count($required) > 0) {
return InputWarning("(:input $verb:) needs positional parameters '$required_str', but those starting from '$required[0]' are missing.");
}
return $fmt;
}
$InputActive = 0;
function InputMakeHtml($flag, $argstring) {
global $InputActive;
$o = array();
$at_line_start = $flag == '';
$args = ParseArgs($argstring);
$verb = $args[''][0];
if ($verb == 'start' || $verb == 'end') {
if ($at_line_start) {
$o[] = '<:block>';
} else {
return Keep(InputWarning ("(:input $verb...:) must be at the start of a line."));
}
}
if (!isset($verb)) {
$o[] = Keep(InputWarning('(:input:) needs at least one parameter.'));
} else {
if ($verb == 'start') {
if ($InputActive) {
$o[] = '';
} else {
$InputActive = 1;
}
} else {
if (!$InputActive) {
$o[] = Keep(InputWarning('There should have been an (:input start...:) before this (:input...:) markup.'));
}
if ($verb == 'end') {
$InputActive = 0;
}
}
$o[] = Keep(InputMakeControl($verb, $args));
}
return implode("\n", $o);
}