'XX Replacement Text' '#zz#' => 'ZZ Replacement Text' Then wherever the symbols #xx# and #yy# appeared in the markup they would be replaced with given replacement texts. Much more sophisticated processing is also possible, and examples with explanations are given at: http://www.pmwiki.org/wiki/Cookbook/QuickReplace This page explains how to: 1) Set up replacements that take place when a page is saved, 2) Use regular expressions for the search and replace values, 3) Generate HTML output from the replacements, and 4) Define replacements in the config file instead of a wiki page. [Change Log] Oct 13, 2006 - First version started. Oct 26, 2006 - First version released. Oct 27, 2006 - Security update. The defaults were changed when flags contain 'e', to make it harder for a wiki-page to contain arbitrary code that gets executed. Also added the 'html' and 'convfunc' parameters. */ // Standard Recipe Information for PmWiki $RecipeInfo['QuickReplace'] = array ( 'Version' => '20061027' , 'Author' => 'Stirling Westrup' , 'Email' => 'sti@pooq.com' ); // Default function to apply the patterns so they are used during // ROS (Replace On Save). function QuickReplace_ApplyROS($pats,$conf) { global $ROSPatterns; foreach((array)$pats as $pat => $rep) $ROSPatterns[$pat] = $rep; } // Default function Apply the patterns so they are active // during standard markup processing. function QuickReplace_ApplyMarkup($pats,$conf) { $base = $conf['tag']; $ord = $conf['ordered']; $last = $conf['when']; $i = 0; foreach((array)$pats as $pat => $rep ) { $name = $base.$i++; Markup($name,$last,$pat,$rep); if($ord) $last = ">$name"; } } // Increment all pattern capture references by 1 in the replacement, // modulo 100. Thus $0 -> $1, $1 -> $2,...$99 -> $0. This compensates // for the extra capture being added in QuickReplace_PatternList function QuickReplace_refinc($n) { return "\${".(($n+1)%100)."}"; } // Generates a list of patterns and replacements from the list of // replacement keys and values, based on configured parameters. function QuickReplace_PatternList($list,$conf) { // Regex to match \1, $1 or ${1} markup, and replacement func. static $refpat = '/(?:[\\\\$](\d\d?))|(?:\${(\d\d?)})/e'; static $refrep = 'QuickReplace_refinc($1$2)'; $match = preg_quote($conf['match']); $beg = $conf['ends'][0]; $end = $conf['ends'][1].$conf['flags']; $output= $conf['output']; // Convert each key into a regex that matches occurances of that // key surrounded by the $match marker. Convert each value into a // replacement string that has adjusted capture references and is // imbedded in the $output string. foreach((array)$list as $k => $v) { $pat = $beg.str_replace('\$1',"($k)",$match).$end; $val = preg_replace($refpat,$refrep,$v); $rep = str_replace('$2',$val,$output); $pats[$pat] = $rep; } return $pats; } // Perform value quoting and any necessary string conversions. function QuickReplace_Convert($list,$conf) { $regex = $conf['regex']; $html = $conf['html']; $ends = $conf['ends']; foreach((array)$list as $k=>$v) { if( !$regex ) $k = preg_quote($k,implode("",$ends)); if( !$html ) $v = preg_replace( array('//'), array('<','>'), $v ); $ret[$k] = $v; } return $ret; } // This is the default function for retrieving the list of search keys // and replacement patterns. It loads them the configured wiki pages // and combines them with the entries in the replace array. function QuickReplace_GetReplaceList($conf) { global $XL,$XLLangs,$pagename; $lang = $conf['tag']; $larr = $XLLangs; // Load replacement list for given pages. // In reverse order so last named page has precedence foreach(array_reverse((array)$conf['page']) as $v) XLPage($lang, FmtPageName($v,$pagename)); // Add in any given replacements from replace array if( count($conf['replace']) ) XLSDV( $lang, $conf['replace']); // grab the list we've created $list = $XL[$lang]; // erase our fake 'lang' from the list $XLLangs = $larr; return $list; } // Defaults for ROS operation $QuickReplaceMode['ROS'] = array ( 'action' => 'edit' , 'applyfunc' => 'QuickReplace_ApplyROS' ); // Defaults for Markup operation $QuickReplaceMode['markup'] = array ( 'applyfunc' => 'QuickReplace_ApplyMarkup' , 'when' => 'inline' ); // This is the main routine. It runs through the list of defined // QuickReplace entries, applies defaults for all missing values, // loads the list of search keys and replacement values and applies // them so they are executed at the right time. // First we ensure there is at least one entry if(!count($QuickReplace)) $QuickReplace['QuickReplace'] = array(); // Then we process the entries. foreach( $QuickReplace as $key => $conf ) { $name = PageVar(MakePageName($pagename, $key), '$Name'); $conf = (array)$conf; // Set our simple defaults. SDVA ( $conf , array ( 'name' => $name , 'tag' => "QuickReplace:$name:" , 'mode' => 'markup' , 'match' => '$1' , 'flags' => '' , 'regex' => false , 'html' => false , 'ordered' => false , 'ends' => array( '/', '/') , 'sortfunc' => '' , 'listfunc' => 'QuickReplace_GetReplaceList' , 'pattfunc' => 'QuickReplace_PatternList' , 'convfunc' => 'QuickReplace_Convert' ) ); // Some defaults depend on previous ones. $eval = strpos($conf['flags'],'e') !== false; $html = $conf['html']; SDVA ( $conf , array ( 'output' => ($eval ? 'Keep(PSS(\'$2\'))' : '$2') , 'page' => (($eval || $html) ? '' : "{\$SiteGroup}.$name") ) ); // Merge in all mode-specific defaults SDVA($conf, $QuickReplaceMode[$conf['mode']]); // 'key' isn't defaultable. $conf['key'] = $key; // Find out what actions trigger this list. (blank = ALL) $when = (array)$conf['action']; // If we meet the criteria, apply the list. if( !count($when) || in_array( $action, $when) ) { // Load list of search/replace pairs. $list = (array)$conf['listfunc']($conf); // Save the raw list, just in case. $conf['list'] = $list; // Sort the list if necessary. if( $conf['sortfunc'] ) { $conf['sortfunc']($list); $conf['ordered'] = true; } // perform character conversion, if necessary if( $conf['convfunc'] ) $list = (array)$conf['convfunc']($list,$conf); // Generate search/replace patterns from the list. $pats = $conf['pattfunc']($list,$conf); // Save the patterns, if needed later. $conf['pats'] = $pats; // Apply the patterns, so they get executed later. $conf['applyfunc']($pats,$conf); // Cache our updated conf in a global variable in case some // replace function wants access to this data some day. $QuickReplaceCache[$key] = $conf; } } ?>