* @created: Sat, 09 Dec 2023 14:59 -0300
*
* This is my first plugin, and I don't even know PHP well, that's why it's full
* of comments, but I'll leave it that way so I can consult it in the future.
*
*/
use dokuwiki\Extension\SyntaxPlugin;
use dokuwiki\Utf8\PhpString;
class syntax_plugin_parserfunctions extends SyntaxPlugin
{
/** @inheritDoc */
public function getType()
{
/* READ: https://www.dokuwiki.org/devel:syntax_plugins#syntax_types
* substition — modes where the token is simply replaced – they can not
* contain any other modes
*/
return 'substition';
}
/** @inheritDoc */
public function getPType()
{
/* READ: https://www.dokuwiki.org/devel:syntax_plugins
* normal — (default value, will be used if the method is not overridden)
* The plugin output will be inside a paragraph (or another block
* element), no paragraphs will be inside.
*/
return 'normal';
}
/** @inheritDoc */
public function getSort()
{
/* READ: https://www.dokuwiki.org/devel:parser:getsort_list
* Don't understand exactly what it does, need more study.
*
* Should go after Templater (302) and WST (319) plugin, to be able to
* render @parameter@ and {{{parameter}}}.
*/
return 320;
}
/** @inheritDoc */
public function connectTo($mode)
{
/* READ: https://www.dokuwiki.org/devel:syntax_plugins#patterns
* Regex accepts any alphabetical function name
* but not nested functions
*/
$this->Lexer->addSpecialPattern('\{\{#[[:alpha:]]+:[^(\{\{#)(#\}\})]+#\}\}', $mode, 'plugin_parserfunctions');
// $this->Lexer->addEntryPattern(''. $func_name . '
: ' .
$this->getLang('no_such_function') . ' ';
break;
}
// The instructions provided to the render() method:
return $func_result;
}
/** @inheritDoc */
public function render($mode, Doku_Renderer $renderer, $data)
{
/* READ: https://www.dokuwiki.org/devel:syntax_plugins#render_method
* The part of the plugin that provides the output for the final web page.
*
* Parameters:
*
* $mode — Name for the format mode of the final output produced by the
* renderer.
*
* $renderer — Give access to the object Doku_Renderer, which contains useful
* functions and values.
*
* $data — An array containing the instructions previously prepared
* and returned by the plugin's own handle() method. The render()
* must interpret the instruction and generate the appropriate
* output.
*/
if ($mode !== 'xhtml') {
return false;
}
if (!$data) {
return false;
}
// escape sequences
$data = $this->_escape($data);
// Do not use
'. $func_name . '
: ' . $this->getLang('not_enough_params') .
' ';
} else {
if ( !empty($params[0]) ) {
$result = $params[1];
} else {
if ( !empty($params[2]) ) {
$result = $params[2];
} else {
/**
* The last parameter (false) must have been intentionally omitted:
* user wants the result to be null if the test string is empty.
*/
$result = null;
}
}
}
return $result;
}
/**
* ========== #IFEQ
* {{#ifeq: 1st parameter | 2nd parameter | 3rd parameter | 4th parameter #}}
* {{#ifeq: string 1 | string 2 | value if identical | value if different #}}
*/
function _IFEQ($params, $func_name)
{
if ( count($params) < 4 ) {
$result = ' ' . $this->getLang('error') .
' '. $func_name . '
: ' . $this->getLang('not_enough_params') .
' ';
} else {
if ( $params[0] == $params[1] ) {
$result = $params[2];
} else {
$result = $params[3];
}
}
return $result;
}
/**
* ========== #SWITCH
* {{#switch: comparison string
* | case = result
* | case = result
* | ...
* | case = result
* | default result
* #}}
*/
function _SWITCH($params)
{
/**
* Then:
*
* "$params":
* (
* [0] => test string
* [1] => case 1 = value 1
* [2] => case 2 = value 2
* [3] => case 3 = value 3
* [4] => default value
* )
*/
$cases_kv = [];
$test_and_default_string = [];
foreach ( $params as $value ){
$value = preg_split('/=/', $value);
if ( isset($value[1]) ) {
$cases_kv[trim($value[0])] = trim($value[1]);
} else {
$test_and_default_string[] = trim($value[0]);
}
}
/**
* And now:
*
* "$cases_kv":
* (
* [case 1] => value 1
* [case 2] => value 2
* [case 3] => value 3
* )
*
* "$test_and_default_string":
* (
* [0] => test string
* [1] => default value
* )
*/
if ( array_key_exists($test_and_default_string[0], $cases_kv) ) {
$result = $cases_kv[$test_and_default_string[0]];
} else {
$result = $test_and_default_string[1] ?? '';
}
return $result;
}
/**
* Escape sequence handling
*/
function _escape($data){
/**
* To add more escapes, please refer to:
* https://www.freeformatter.com/html-entities.html
*
* Always use "&#__number__;" instead of "__number__;"
*
* Number sign "#" can be escaped with "#" and don't need to be
* added to the array below.
*/
$escapes = array(
"&#61;" => "=",
"&#123;" => "{",
"&#124;" => "|",
"&#125;" => "}"
);
foreach ( $escapes as $key => $value ) {
$data = preg_replace("/$key/s", $value, $data);
}
return $data;
}
}
// vim:ts=4:sw=4:et:enc=utf-8: