<?php if (!defined('PmWiki')) exit();

/*
	autoLink.php, a recipe for PmWiki
	based on code provided by Patrick R. Michaud, Eemeli Aro, and Peter Bowers
	compiled by Adam Overton, August 2009
	
	. . .
	
	This program is free software; you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation; either version 2 of the License, or
	(at your option) any later version.
	http://www.gnu.org/copyleft/gpl.html
	
	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.
	
	. . .

	Using autoLink.php:
	This recipe displays any specified word, phrase or name as a link, throughout the entire site. To enable this recipe, create SiteAdmin.AutoLink and add your names and urls one-per-line, in the format:

		john doe|http://johndoe.com
	
	Note that: 
	- all names as declared here must be completely lowercase in order for this to work - all subsequent conversions of these names-to-links on the actual wikipages will be case-insensitive...
	- adding spaces around the pipe "|" may result in an error - correct: name|url, not: name | url
	- you can comment out individual lines by adding # or // to the beginning of a line
	
	Then in your config.php, include the recipe via:

		# enable autolink recipe:
		include_once('cookbook/autoLink.php');
		
	If you'd prefer to declare any names in your config.php instead of (or in addition to) posting them on SiteAdmin.AutoLink, simply declare them via $AutoLinkArray['name'] = 'url', before including the recipe, i.e.: 

		# reminder: all keys must be completely lowercase in order for this to work!
		$AutoLinkArray['john doe'] = 'http://johndoe.com';
		# enable autolink recipe:
		include_once('cookbook/autoLink.php');

	Note that AutoLink replacement can be prevented on your wiki pages by preceding any word or phrase with the backtick (`) character. If you'd prefer a different escape character, you can supply it via $AutoLinkEscapeChars.
	
	Finally, AutoLink by default causes each instance of a defined name or phrase to be linked. However, if you set $AutoLinkOnce = true; in config.php, then autolinking will be limited to only the first instance of each name or phrase.
	
	Versions:
	* 2009-10-06 - added $AutoLinkOnce capability (suggestion of Gustav)
	* 2009-09-01c - added $AutoLinkEscapeChars to recipe, which permits custom declaration of escape characters (the default being backtick (`)
	* 2009-09-01b - added 'addslashes' and 'stripslashes' to recipe, to fix a problem where apostrophes were preventing autolinking
	* 2009-09-01 - 1) added ability to define autolinks on SiteAdmin.AutoLink; 2) simplified markup to a single line; (special thanks to PeterBowers for help with both 1. & 2.!!) 3) renamed $NameToLinkArray to $AutoLinkArray.
	* 2009-08-26 - initial release

*/

$RecipeInfo['autoLink']['Version'] = '2009-10-06';


##### SITEADMIN.AUTOLINK SETUP
## much of what follows was majorly tweaked by Peter Bowers, with additional minor changes by Adam Overton

SDV($AutoLinkPage, "SiteAdmin.AutoLink");  # Define the location on the wikipage where names are stored
SDV($AutoLinkEscapeChars, "`");  # Define the character or characters you want to use to prevent AutoLinkage
SDV($AutoLinkOnce, false);  # if set to true, autolink will only iterate upon the first instance of a name

$page = ReadPage($AutoLinkPage);
if ($page) {
	# declare the array if it hasn't been declared already in config.php
	if (!is_array($AutoLinkArray)) $AutoLinkArray = array();
	# grab each line
	foreach (explode("\n", $page['text']) as $line) {
		# don't count lines that are commented out with either // or #
		if ( strpos($line, '#')===0 | strpos($line, '//')===0 | strpos($line, '/*')===0 ) continue;
		# make sure each line has the correct markup: name|url
		if (!strpos($line, '|')) continue;
		$lineArray = explode("|",$line); # break into name-[0] and url-[1] components
		if (count($lineArray) == 2) { # add to lineArray
			# addslashes used in case of apostrophes or other special characters
			$AutoLinkArray[strtolower(addslashes($lineArray[0]))] = $lineArray[1];
		}
	}
}


##### AUTOLINK MARKUP
if ($AutoLinkArray)
	Markup('names', 'inline',
	'/([' . $AutoLinkEscapeChars . ']?)\b(' . join('|', array_keys($AutoLinkArray)) . ')\b/ei',
	'AutoLink_func("$1","$2")'
	);


function AutoLink_func($escape='', $autoNameRaw) {
	global $AutoLinkArray, $AutoLinkOnce, $AutoLinkOnceFlag;
	
	# if escape character is present, just return the original text, with no autolink'ing
	if ($escape) return $autoNameRaw;
	else {
		# autolink'ing
		$autoNameKey = strtolower("$autoNameRaw");
		# if AutoLinkOnce is enabled, then only autolink the first time a name is encountered
		if (!$AutoLinkOnce || ( $AutoLinkOnce && !$AutoLinkOnceFlag[$autoNameKey] ) ) {
			$autoLinkOut = "%newwin%[[".$AutoLinkArray[$autoNameKey]."|".Keep(stripslashes("$autoNameRaw"))."]]";
			if($AutoLinkOnce) $AutoLinkOnceFlag[$autoNameKey] = true;
			return $autoLinkOut;
		} else {
			return $autoNameRaw;
		}
	}
}