` blocks.
+ #
+ $text = preg_replace_callback('{
+ (?:\n\n|\A\n?)
+ ( # $1 = the code block -- one or more lines, starting with a space/tab
+ (?>
+ [ ]{'.$this->tab_width.'} # Lines must start with a tab or a tab-width of spaces
+ .*\n+
+ )+
+ )
+ ((?=^[ ]{0,'.$this->tab_width.'}\S)|\Z) # Lookahead for non-space at line-start, or end of doc
+ }xm',
+ array(&$this, '_doCodeBlocks_callback'), $text);
+
+ return $text;
+ }
+ function _doCodeBlocks_callback($matches) {
+ $codeblock = $matches[1];
+
+ $codeblock = $this->outdent($codeblock);
+ $codeblock = htmlspecialchars($codeblock, ENT_NOQUOTES);
+
+ # trim leading newlines and trailing newlines
+ $codeblock = preg_replace('/\A\n+|\n+\z/', '', $codeblock);
+
+ $codeblock = "$codeblock\n ";
+ return "\n\n".$this->hashBlock($codeblock)."\n\n";
+ }
+
+
+ function makeCodeSpan($code) {
+ #
+ # Create a code span markup for $code. Called from handleSpanToken.
+ #
+ $code = htmlspecialchars(trim($code), ENT_NOQUOTES);
+ return $this->hashPart("$code");
+ }
+
+
+ var $em_relist = array(
+ '' => '(?:(? '(?<=\S|^)(? '(?<=\S|^)(? '(?:(? '(?<=\S|^)(? '(?<=\S|^)(? '(?:(? '(?<=\S|^)(? '(?<=\S|^)(?em_relist as $em => $em_re) {
+ foreach ($this->strong_relist as $strong => $strong_re) {
+ # Construct list of allowed token expressions.
+ $token_relist = array();
+ if (isset($this->em_strong_relist["$em$strong"])) {
+ $token_relist[] = $this->em_strong_relist["$em$strong"];
+ }
+ $token_relist[] = $em_re;
+ $token_relist[] = $strong_re;
+
+ # Construct master expression from list.
+ $token_re = '{('. implode('|', $token_relist) .')}';
+ $this->em_strong_prepared_relist["$em$strong"] = $token_re;
+ }
+ }
+ }
+
+ function doItalicsAndBold($text) {
+ $token_stack = array('');
+ $text_stack = array('');
+ $em = '';
+ $strong = '';
+ $tree_char_em = false;
+
+ while (1) {
+ #
+ # Get prepared regular expression for seraching emphasis tokens
+ # in current context.
+ #
+ $token_re = $this->em_strong_prepared_relist["$em$strong"];
+
+ #
+ # Each loop iteration search for the next emphasis token.
+ # Each token is then passed to handleSpanToken.
+ #
+ $parts = preg_split($token_re, $text, 2, PREG_SPLIT_DELIM_CAPTURE);
+ $text_stack[0] .= $parts[0];
+ $token =& $parts[1];
+ $text =& $parts[2];
+
+ if (empty($token)) {
+ # Reached end of text span: empty stack without emitting.
+ # any more emphasis.
+ while ($token_stack[0]) {
+ $text_stack[1] .= array_shift($token_stack);
+ $text_stack[0] .= array_shift($text_stack);
+ }
+ break;
+ }
+
+ $token_len = strlen($token);
+ if ($tree_char_em) {
+ # Reached closing marker while inside a three-char emphasis.
+ if ($token_len == 3) {
+ # Three-char closing marker, close em and strong.
+ array_shift($token_stack);
+ $span = array_shift($text_stack);
+ $span = $this->runSpanGamut($span);
+ $span = "$span ";
+ $text_stack[0] .= $this->hashPart($span);
+ $em = '';
+ $strong = '';
+ } else {
+ # Other closing marker: close one em or strong and
+ # change current token state to match the other
+ $token_stack[0] = str_repeat($token{0}, 3-$token_len);
+ $tag = $token_len == 2 ? "strong" : "em";
+ $span = $text_stack[0];
+ $span = $this->runSpanGamut($span);
+ $span = "<$tag>$span$tag>";
+ $text_stack[0] = $this->hashPart($span);
+ $$tag = ''; # $$tag stands for $em or $strong
+ }
+ $tree_char_em = false;
+ } else if ($token_len == 3) {
+ if ($em) {
+ # Reached closing marker for both em and strong.
+ # Closing strong marker:
+ for ($i = 0; $i < 2; ++$i) {
+ $shifted_token = array_shift($token_stack);
+ $tag = strlen($shifted_token) == 2 ? "strong" : "em";
+ $span = array_shift($text_stack);
+ $span = $this->runSpanGamut($span);
+ $span = "<$tag>$span$tag>";
+ $text_stack[0] .= $this->hashPart($span);
+ $$tag = ''; # $$tag stands for $em or $strong
+ }
+ } else {
+ # Reached opening three-char emphasis marker. Push on token
+ # stack; will be handled by the special condition above.
+ $em = $token{0};
+ $strong = "$em$em";
+ array_unshift($token_stack, $token);
+ array_unshift($text_stack, '');
+ $tree_char_em = true;
+ }
+ } else if ($token_len == 2) {
+ if ($strong) {
+ # Unwind any dangling emphasis marker:
+ if (strlen($token_stack[0]) == 1) {
+ $text_stack[1] .= array_shift($token_stack);
+ $text_stack[0] .= array_shift($text_stack);
+ }
+ # Closing strong marker:
+ array_shift($token_stack);
+ $span = array_shift($text_stack);
+ $span = $this->runSpanGamut($span);
+ $span = "$span ";
+ $text_stack[0] .= $this->hashPart($span);
+ $strong = '';
+ } else {
+ array_unshift($token_stack, $token);
+ array_unshift($text_stack, '');
+ $strong = $token;
+ }
+ } else {
+ # Here $token_len == 1
+ if ($em) {
+ if (strlen($token_stack[0]) == 1) {
+ # Closing emphasis marker:
+ array_shift($token_stack);
+ $span = array_shift($text_stack);
+ $span = $this->runSpanGamut($span);
+ $span = "$span ";
+ $text_stack[0] .= $this->hashPart($span);
+ $em = '';
+ } else {
+ $text_stack[0] .= $token;
+ }
+ } else {
+ array_unshift($token_stack, $token);
+ array_unshift($text_stack, '');
+ $em = $token;
+ }
+ }
+ }
+ return $text_stack[0];
+ }
+
+
+ function doBlockQuotes($text) {
+ $text = preg_replace_callback('/
+ ( # Wrap whole match in $1
+ (?>
+ ^[ ]*>[ ]? # ">" at the start of a line
+ .+\n # rest of the first line
+ (.+\n)* # subsequent consecutive lines
+ \n* # blanks
+ )+
+ )
+ /xm',
+ array(&$this, '_doBlockQuotes_callback'), $text);
+
+ return $text;
+ }
+ function _doBlockQuotes_callback($matches) {
+ $bq = $matches[1];
+ # trim one level of quoting - trim whitespace-only lines
+ $bq = preg_replace('/^[ ]*>[ ]?|^[ ]+$/m', '', $bq);
+ $bq = $this->runBlockGamut($bq); # recurse
+
+ $bq = preg_replace('/^/m', " ", $bq);
+ # These leading spaces cause problem with content,
+ # so we need to fix that:
+ $bq = preg_replace_callback('{(\s*.+? )}sx',
+ array(&$this, '_doBlockQuotes_callback2'), $bq);
+
+ return "\n". $this->hashBlock("\n$bq\n ")."\n\n";
+ }
+ function _doBlockQuotes_callback2($matches) {
+ $pre = $matches[1];
+ $pre = preg_replace('/^ /m', '', $pre);
+ return $pre;
+ }
+
+
+ function formParagraphs($text) {
+ #
+ # Params:
+ # $text - string to process with html tags
+ #
+ # Strip leading and trailing lines:
+ $text = preg_replace('/\A\n+|\n+\z/', '', $text);
+
+ $grafs = preg_split('/\n{2,}/', $text, -1, PREG_SPLIT_NO_EMPTY);
+
+ #
+ # Wrap
tags and unhashify HTML blocks
+ #
+ foreach ($grafs as $key => $value) {
+ if (!preg_match('/^B\x1A[0-9]+B$/', $value)) {
+ # Is a paragraph.
+ $value = $this->runSpanGamut($value);
+ $value = preg_replace('/^([ ]*)/', "
", $value);
+ $value .= "
";
+ $grafs[$key] = $this->unhash($value);
+ }
+ else {
+ # Is a block.
+ # Modify elements of @grafs in-place...
+ $graf = $value;
+ $block = $this->html_hashes[$graf];
+ $graf = $block;
+// if (preg_match('{
+// \A
+// ( # $1 = tag
+//
]*
+// \b
+// markdown\s*=\s* ([\'"]) # $2 = attr quote char
+// 1
+// \2
+// [^>]*
+// >
+// )
+// ( # $3 = contents
+// .*
+// )
+// (
) # $4 = closing tag
+// \z
+// }xs', $block, $matches))
+// {
+// list(, $div_open, , $div_content, $div_close) = $matches;
+//
+// # We can't call Markdown(), because that resets the hash;
+// # that initialization code should be pulled into its own sub, though.
+// $div_content = $this->hashHTMLBlocks($div_content);
+//
+// # Run document gamut methods on the content.
+// foreach ($this->document_gamut as $method => $priority) {
+// $div_content = $this->$method($div_content);
+// }
+//
+// $div_open = preg_replace(
+// '{\smarkdown\s*=\s*([\'"]).+?\1}', '', $div_open);
+//
+// $graf = $div_open . "\n" . $div_content . "\n" . $div_close;
+// }
+ $grafs[$key] = $graf;
+ }
+ }
+
+ return implode("\n\n", $grafs);
+ }
+
+
+ function encodeAttribute($text) {
+ #
+ # Encode text for a double-quoted HTML attribute. This function
+ # is *not* suitable for attributes enclosed in single quotes.
+ #
+ $text = $this->encodeAmpsAndAngles($text);
+ $text = str_replace('"', '"', $text);
+ return $text;
+ }
+
+
+ function encodeAmpsAndAngles($text) {
+ #
+ # Smart processing for ampersands and angle brackets that need to
+ # be encoded. Valid character entities are left alone unless the
+ # no-entities mode is set.
+ #
+ if ($this->no_entities) {
+ $text = str_replace('&', '&', $text);
+ } else {
+ # Ampersand-encoding based entirely on Nat Irons's Amputator
+ # MT plugin:
+ $text = preg_replace('/&(?!#?[xX]?(?:[0-9a-fA-F]+|\w+);)/',
+ '&', $text);;
+ }
+ # Encode remaining <'s
+ $text = str_replace('<', '<', $text);
+
+ return $text;
+ }
+
+
+ function doAutoLinks($text) {
+ $text = preg_replace_callback('{<((https?|ftp|dict):[^\'">\s]+)>}i',
+ array(&$this, '_doAutoLinks_url_callback'), $text);
+
+ # Email addresses:
+ $text = preg_replace_callback('{
+ <
+ (?:mailto:)?
+ (
+ (?:
+ [-!#$%&\'*+/=?^_`.{|}~\w\x80-\xFF]+
+ |
+ ".*?"
+ )
+ \@
+ (?:
+ [-a-z0-9\x80-\xFF]+(\.[-a-z0-9\x80-\xFF]+)*\.[a-z]+
+ |
+ \[[\d.a-fA-F:]+\] # IPv4 & IPv6
+ )
+ )
+ >
+ }xi',
+ array(&$this, '_doAutoLinks_email_callback'), $text);
+
+ return $text;
+ }
+ function _doAutoLinks_url_callback($matches) {
+ $url = $this->encodeAttribute($matches[1]);
+ $link = "$url ";
+ return $this->hashPart($link);
+ }
+ function _doAutoLinks_email_callback($matches) {
+ $address = $matches[1];
+ $link = $this->encodeEmailAddress($address);
+ return $this->hashPart($link);
+ }
+
+
+ function encodeEmailAddress($addr) {
+ #
+ # Input: an email address, e.g. "foo@example.com"
+ #
+ # Output: the email address as a mailto link, with each character
+ # of the address encoded as either a decimal or hex entity, in
+ # the hopes of foiling most address harvesting spam bots. E.g.:
+ #
+ # foo@exampl
+ # e.com
+ #
+ # Based by a filter by Matthew Wickline, posted to BBEdit-Talk.
+ # With some optimizations by Milian Wolff.
+ #
+ $addr = "mailto:" . $addr;
+ $chars = preg_split('/(? $char) {
+ $ord = ord($char);
+ # Ignore non-ascii chars.
+ if ($ord < 128) {
+ $r = ($seed * (1 + $key)) % 100; # Pseudo-random function.
+ # roughly 10% raw, 45% hex, 45% dec
+ # '@' *must* be encoded. I insist.
+ if ($r > 90 && $char != '@') /* do nothing */;
+ else if ($r < 45) $chars[$key] = ''.dechex($ord).';';
+ else $chars[$key] = ''.$ord.';';
+ }
+ }
+
+ $addr = implode('', $chars);
+ $text = implode('', array_slice($chars, 7)); # text without `mailto:`
+ $addr = "$text ";
+
+ return $addr;
+ }
+
+
+ function parseSpan($str) {
+ #
+ # Take the string $str and parse it into tokens, hashing embeded HTML,
+ # escaped characters and handling code spans.
+ #
+ $output = '';
+
+ $span_re = '{
+ (
+ \\\\'.$this->escape_chars_re.'
+ |
+ (?no_markup ? '' : '
+ |
+ # comment
+ |
+ <\?.*?\?> | <%.*?%> # processing instruction
+ |
+ <[/!$]?[-a-zA-Z0-9:_]+ # regular tags
+ (?>
+ \s
+ (?>[^"\'>]+|"[^"]*"|\'[^\']*\')*
+ )?
+ >
+ ').'
+ )
+ }xs';
+
+ while (1) {
+ #
+ # Each loop iteration seach for either the next tag, the next
+ # openning code span marker, or the next escaped character.
+ # Each token is then passed to handleSpanToken.
+ #
+ $parts = preg_split($span_re, $str, 2, PREG_SPLIT_DELIM_CAPTURE);
+
+ # Create token from text preceding tag.
+ if ($parts[0] != "") {
+ $output .= $parts[0];
+ }
+
+ # Check if we reach the end.
+ if (isset($parts[1])) {
+ $output .= $this->handleSpanToken($parts[1], $parts[2]);
+ $str = $parts[2];
+ }
+ else {
+ break;
+ }
+ }
+
+ return $output;
+ }
+
+
+ function handleSpanToken($token, &$str) {
+ #
+ # Handle $token provided by parseSpan by determining its nature and
+ # returning the corresponding value that should replace it.
+ #
+ switch ($token{0}) {
+ case "\\":
+ return $this->hashPart("". ord($token{1}). ";");
+ case "`":
+ # Search for end marker in remaining text.
+ if (preg_match('/^(.*?[^`])'.preg_quote($token).'(?!`)(.*)$/sm',
+ $str, $matches))
+ {
+ $str = $matches[2];
+ $codespan = $this->makeCodeSpan($matches[1]);
+ return $this->hashPart($codespan);
+ }
+ return $token; // return as text since no ending marker found.
+ default:
+ return $this->hashPart($token);
+ }
+ }
+
+
+ function outdent($text) {
+ #
+ # Remove one level of line-leading tabs or spaces
+ #
+ return preg_replace('/^(\t|[ ]{1,'.$this->tab_width.'})/m', '', $text);
+ }
+
+
+ # String length function for detab. `_initDetab` will create a function to
+ # hanlde UTF-8 if the default function does not exist.
+ var $utf8_strlen = 'mb_strlen';
+
+ function detab($text) {
+ #
+ # Replace tabs with the appropriate amount of space.
+ #
+ # For each line we separate the line in blocks delemited by
+ # tab characters. Then we reconstruct every line by adding the
+ # appropriate number of space between each blocks.
+
+ $text = preg_replace_callback('/^.*\t.*$/m',
+ array(&$this, '_detab_callback'), $text);
+
+ return $text;
+ }
+ function _detab_callback($matches) {
+ $line = $matches[0];
+ $strlen = $this->utf8_strlen; # strlen function for UTF-8.
+
+ # Split in blocks.
+ $blocks = explode("\t", $line);
+ # Add each blocks to the line.
+ $line = $blocks[0];
+ unset($blocks[0]); # Do not add first block twice.
+ foreach ($blocks as $block) {
+ # Calculate amount of space, insert spaces, insert block.
+ $amount = $this->tab_width -
+ $strlen($line, 'UTF-8') % $this->tab_width;
+ $line .= str_repeat(" ", $amount) . $block;
+ }
+ return $line;
+ }
+ function _initDetab() {
+ #
+ # Check for the availability of the function in the `utf8_strlen` property
+ # (initially `mb_strlen`). If the function is not available, create a
+ # function that will loosely count the number of UTF-8 characters with a
+ # regular expression.
+ #
+ if (function_exists($this->utf8_strlen)) return;
+ $this->utf8_strlen = create_function('$text', 'return preg_match_all(
+ "/[\\\\x00-\\\\xBF]|[\\\\xC0-\\\\xFF][\\\\x80-\\\\xBF]*/",
+ $text, $m);');
+ }
+
+
+ function unhash($text) {
+ #
+ # Swap back in all the tags hashed by _HashHTMLBlocks.
+ #
+ return preg_replace_callback('/(.)\x1A[0-9]+\1/',
+ array(&$this, '_unhash_callback'), $text);
+ }
+ function _unhash_callback($matches) {
+ return $this->html_hashes[$matches[0]];
+ }
+
+}
+
+
+#
+# Markdown Extra Parser Class
+#
+
+class MarkdownExtra_Parser extends Markdown_Parser {
+
+ # Prefix for footnote ids.
+ var $fn_id_prefix = "";
+
+ # Optional title attribute for footnote links and backlinks.
+ var $fn_link_title = MARKDOWN_FN_LINK_TITLE;
+ var $fn_backlink_title = MARKDOWN_FN_BACKLINK_TITLE;
+
+ # Optional class attribute for footnote links and backlinks.
+ var $fn_link_class = MARKDOWN_FN_LINK_CLASS;
+ var $fn_backlink_class = MARKDOWN_FN_BACKLINK_CLASS;
+
+ # Predefined abbreviations.
+ var $predef_abbr = array();
+
+
+ function MarkdownExtra_Parser() {
+ #
+ # Constructor function. Initialize the parser object.
+ #
+ # Add extra escapable characters before parent constructor
+ # initialize the table.
+ $this->escape_chars .= ':|';
+
+ # Insert extra document, block, and span transformations.
+ # Parent constructor will do the sorting.
+ $this->document_gamut += array(
+ "doFencedCodeBlocks" => 5,
+ "stripFootnotes" => 15,
+ "stripAbbreviations" => 25,
+ "appendFootnotes" => 50,
+ );
+ $this->block_gamut += array(
+ "doFencedCodeBlocks" => 5,
+ "doTables" => 15,
+ "doDefLists" => 45,
+ );
+ $this->span_gamut += array(
+ "doFootnotes" => 5,
+ "doAbbreviations" => 70,
+ );
+
+ parent::Markdown_Parser();
+ }
+
+
+ # Extra variables used during extra transformations.
+ var $footnotes = array();
+ var $footnotes_ordered = array();
+ var $abbr_desciptions = array();
+ var $abbr_word_re = '';
+
+ # Give the current footnote number.
+ var $footnote_counter = 1;
+
+
+ function setup() {
+ #
+ # Setting up Extra-specific variables.
+ #
+ parent::setup();
+
+ $this->footnotes = array();
+ $this->footnotes_ordered = array();
+ $this->abbr_desciptions = array();
+ $this->abbr_word_re = '';
+ $this->footnote_counter = 1;
+
+ foreach ($this->predef_abbr as $abbr_word => $abbr_desc) {
+ if ($this->abbr_word_re)
+ $this->abbr_word_re .= '|';
+ $this->abbr_word_re .= preg_quote($abbr_word);
+ $this->abbr_desciptions[$abbr_word] = trim($abbr_desc);
+ }
+ }
+
+ function teardown() {
+ #
+ # Clearing Extra-specific variables.
+ #
+ $this->footnotes = array();
+ $this->footnotes_ordered = array();
+ $this->abbr_desciptions = array();
+ $this->abbr_word_re = '';
+
+ parent::teardown();
+ }
+
+
+ ### HTML Block Parser ###
+
+ # Tags that are always treated as block tags:
+ var $block_tags_re = 'p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|address|form|fieldset|iframe|hr|legend';
+
+ # Tags treated as block tags only if the opening tag is alone on it's line:
+ var $context_block_tags_re = 'script|noscript|math|ins|del';
+
+ # Tags where markdown="1" default to span mode:
+ var $contain_span_tags_re = 'p|h[1-6]|li|dd|dt|td|th|legend|address';
+
+ # Tags which must not have their contents modified, no matter where
+ # they appear:
+ var $clean_tags_re = 'script|math';
+
+ # Tags that do not need to be closed.
+ var $auto_close_tags_re = 'hr|img';
+
+
+ function hashHTMLBlocks($text) {
+ #
+ # Hashify HTML Blocks and "clean tags".
+ #
+ # We only want to do this for block-level HTML tags, such as headers,
+ # lists, and tables. That's because we still want to wrap s around
+ # "paragraphs" that are wrapped in non-block-level tags, such as anchors,
+ # phrase emphasis, and spans. The list of tags we're looking for is
+ # hard-coded.
+ #
+ # This works by calling _HashHTMLBlocks_InMarkdown, which then calls
+ # _HashHTMLBlocks_InHTML when it encounter block tags. When the markdown="1"
+ # attribute is found whitin a tag, _HashHTMLBlocks_InHTML calls back
+ # _HashHTMLBlocks_InMarkdown to handle the Markdown syntax within the tag.
+ # These two functions are calling each other. It's recursive!
+ #
+ #
+ # Call the HTML-in-Markdown hasher.
+ #
+ list($text, ) = $this->_hashHTMLBlocks_inMarkdown($text);
+
+ return $text;
+ }
+ function _hashHTMLBlocks_inMarkdown($text, $indent = 0,
+ $enclosing_tag_re = '', $span = false)
+ {
+ #
+ # Parse markdown text, calling _HashHTMLBlocks_InHTML for block tags.
+ #
+ # * $indent is the number of space to be ignored when checking for code
+ # blocks. This is important because if we don't take the indent into
+ # account, something like this (which looks right) won't work as expected:
+ #
+ #
+ #
+ # Hello World. <-- Is this a Markdown code block or text?
+ #
<-- Is this a Markdown code block or a real tag?
+ #
+ #
+ # If you don't like this, just don't indent the tag on which
+ # you apply the markdown="1" attribute.
+ #
+ # * If $enclosing_tag_re is not empty, stops at the first unmatched closing
+ # tag with that name. Nested tags supported.
+ #
+ # * If $span is true, text inside must treated as span. So any double
+ # newline will be replaced by a single newline so that it does not create
+ # paragraphs.
+ #
+ # Returns an array of that form: ( processed text , remaining text )
+ #
+ if ($text === '') return array('', '');
+
+ # Regex to check for the presense of newlines around a block tag.
+ $newline_before_re = '/(?:^\n?|\n\n)*$/';
+ $newline_after_re =
+ '{
+ ^ # Start of text following the tag.
+ (?>[ ]*)? # Optional comment.
+ [ ]*\n # Must be followed by newline.
+ }xs';
+
+ # Regex to match any tag.
+ $block_tag_re =
+ '{
+ ( # $2: Capture hole tag.
+ ? # Any opening or closing tag.
+ (?> # Tag name.
+ '.$this->block_tags_re.' |
+ '.$this->context_block_tags_re.' |
+ '.$this->clean_tags_re.' |
+ (?!\s)'.$enclosing_tag_re.'
+ )
+ (?:
+ (?=[\s"\'/a-zA-Z0-9]) # Allowed characters after tag name.
+ (?>
+ ".*?" | # Double quotes (can contain `>`)
+ \'.*?\' | # Single quotes (can contain `>`)
+ .+? # Anything but quotes and `>`.
+ )*?
+ )?
+ > # End of tag.
+ |
+ # HTML Comment
+ |
+ <\?.*?\?> | <%.*?%> # Processing instruction
+ |
+ # CData Block
+ |
+ # Code span marker
+ `+
+ '. ( !$span ? ' # If not in span.
+ |
+ # Indented code block
+ (?: ^[ ]*\n | ^ | \n[ ]*\n )
+ [ ]{'.($indent+4).'}[^\n]* \n
+ (?>
+ (?: [ ]{'.($indent+4).'}[^\n]* | [ ]* ) \n
+ )*
+ |
+ # Fenced code block marker
+ (?> ^ | \n )
+ [ ]{'.($indent).'}~~~+[ ]*\n
+ ' : '' ). ' # End (if not is span).
+ )
+ }xs';
+
+
+ $depth = 0; # Current depth inside the tag tree.
+ $parsed = ""; # Parsed text that will be returned.
+
+ #
+ # Loop through every tag until we find the closing tag of the parent
+ # or loop until reaching the end of text if no parent tag specified.
+ #
+ do {
+ #
+ # Split the text using the first $tag_match pattern found.
+ # Text before pattern will be first in the array, text after
+ # pattern will be at the end, and between will be any catches made
+ # by the pattern.
+ #
+ $parts = preg_split($block_tag_re, $text, 2,
+ PREG_SPLIT_DELIM_CAPTURE);
+
+ # If in Markdown span mode, add a empty-string span-level hash
+ # after each newline to prevent triggering any block element.
+ if ($span) {
+ $void = $this->hashPart("", ':');
+ $newline = "$void\n";
+ $parts[0] = $void . str_replace("\n", $newline, $parts[0]) . $void;
+ }
+
+ $parsed .= $parts[0]; # Text before current tag.
+
+ # If end of $text has been reached. Stop loop.
+ if (count($parts) < 3) {
+ $text = "";
+ break;
+ }
+
+ $tag = $parts[1]; # Tag to handle.
+ $text = $parts[2]; # Remaining text after current tag.
+ $tag_re = preg_quote($tag); # For use in a regular expression.
+
+ #
+ # Check for: Code span marker
+ #
+ if ($tag{0} == "`") {
+ # Find corresponding end marker.
+ $tag_re = preg_quote($tag);
+ if (preg_match('{^(?>.+?|\n(?!\n))*?(?.*\n)+?'.$tag_re.' *\n}', $text,
+ $matches))
+ {
+ # End marker found: pass text unchanged until marker.
+ $parsed .= $tag . $matches[0];
+ $text = substr($text, strlen($matches[0]));
+ }
+ else {
+ # No end marker: just skip it.
+ $parsed .= $tag;
+ }
+ }
+ #
+ # Check for: Opening Block level tag or
+ # Opening Context Block tag (like ins and del)
+ # used as a block tag (tag is alone on it's line).
+ #
+ else if (preg_match('{^<(?:'.$this->block_tags_re.')\b}', $tag) ||
+ ( preg_match('{^<(?:'.$this->context_block_tags_re.')\b}', $tag) &&
+ preg_match($newline_before_re, $parsed) &&
+ preg_match($newline_after_re, $text) )
+ )
+ {
+ # Need to parse tag and following text using the HTML parser.
+ list($block_text, $text) =
+ $this->_hashHTMLBlocks_inHTML($tag . $text, "hashBlock", true);
+
+ # Make sure it stays outside of any paragraph by adding newlines.
+ $parsed .= "\n\n$block_text\n\n";
+ }
+ #
+ # Check for: Clean tag (like script, math)
+ # HTML Comments, processing instructions.
+ #
+ else if (preg_match('{^<(?:'.$this->clean_tags_re.')\b}', $tag) ||
+ $tag{1} == '!' || $tag{1} == '?')
+ {
+ # Need to parse tag and following text using the HTML parser.
+ # (don't check for markdown attribute)
+ list($block_text, $text) =
+ $this->_hashHTMLBlocks_inHTML($tag . $text, "hashClean", false);
+
+ $parsed .= $block_text;
+ }
+ #
+ # Check for: Tag with same name as enclosing tag.
+ #
+ else if ($enclosing_tag_re !== '' &&
+ # Same name as enclosing tag.
+ preg_match('{^?(?:'.$enclosing_tag_re.')\b}', $tag))
+ {
+ #
+ # Increase/decrease nested tag count.
+ #
+ if ($tag{1} == '/') $depth--;
+ else if ($tag{strlen($tag)-2} != '/') $depth++;
+
+ if ($depth < 0) {
+ #
+ # Going out of parent element. Clean up and break so we
+ # return to the calling function.
+ #
+ $text = $tag . $text;
+ break;
+ }
+
+ $parsed .= $tag;
+ }
+ else {
+ $parsed .= $tag;
+ }
+ } while ($depth >= 0);
+
+ return array($parsed, $text);
+ }
+ function _hashHTMLBlocks_inHTML($text, $hash_method, $md_attr) {
+ #
+ # Parse HTML, calling _HashHTMLBlocks_InMarkdown for block tags.
+ #
+ # * Calls $hash_method to convert any blocks.
+ # * Stops when the first opening tag closes.
+ # * $md_attr indicate if the use of the `markdown="1"` attribute is allowed.
+ # (it is not inside clean tags)
+ #
+ # Returns an array of that form: ( processed text , remaining text )
+ #
+ if ($text === '') return array('', '');
+
+ # Regex to match `markdown` attribute inside of a tag.
+ $markdown_attr_re = '
+ {
+ \s* # Eat whitespace before the `markdown` attribute
+ markdown
+ \s*=\s*
+ (?>
+ (["\']) # $1: quote delimiter
+ (.*?) # $2: attribute value
+ \1 # matching delimiter
+ |
+ ([^\s>]*) # $3: unquoted attribute value
+ )
+ () # $4: make $3 always defined (avoid warnings)
+ }xs';
+
+ # Regex to match any tag.
+ $tag_re = '{
+ ( # $2: Capture hole tag.
+ ? # Any opening or closing tag.
+ [\w:$]+ # Tag name.
+ (?:
+ (?=[\s"\'/a-zA-Z0-9]) # Allowed characters after tag name.
+ (?>
+ ".*?" | # Double quotes (can contain `>`)
+ \'.*?\' | # Single quotes (can contain `>`)
+ .+? # Anything but quotes and `>`.
+ )*?
+ )?
+ > # End of tag.
+ |
+ # HTML Comment
+ |
+ <\?.*?\?> | <%.*?%> # Processing instruction
+ |
+ # CData Block
+ )
+ }xs';
+
+ $original_text = $text; # Save original text in case of faliure.
+
+ $depth = 0; # Current depth inside the tag tree.
+ $block_text = ""; # Temporary text holder for current text.
+ $parsed = ""; # Parsed text that will be returned.
+
+ #
+ # Get the name of the starting tag.
+ # (This pattern makes $base_tag_name_re safe without quoting.)
+ #
+ if (preg_match('/^<([\w:$]*)\b/', $text, $matches))
+ $base_tag_name_re = $matches[1];
+
+ #
+ # Loop through every tag until we find the corresponding closing tag.
+ #
+ do {
+ #
+ # Split the text using the first $tag_match pattern found.
+ # Text before pattern will be first in the array, text after
+ # pattern will be at the end, and between will be any catches made
+ # by the pattern.
+ #
+ $parts = preg_split($tag_re, $text, 2, PREG_SPLIT_DELIM_CAPTURE);
+
+ if (count($parts) < 3) {
+ #
+ # End of $text reached with unbalenced tag(s).
+ # In that case, we return original text unchanged and pass the
+ # first character as filtered to prevent an infinite loop in the
+ # parent function.
+ #
+ return array($original_text{0}, substr($original_text, 1));
+ }
+
+ $block_text .= $parts[0]; # Text before current tag.
+ $tag = $parts[1]; # Tag to handle.
+ $text = $parts[2]; # Remaining text after current tag.
+
+ #
+ # Check for: Auto-close tag (like
)
+ # Comments and Processing Instructions.
+ #
+ if (preg_match('{^?(?:'.$this->auto_close_tags_re.')\b}', $tag) ||
+ $tag{1} == '!' || $tag{1} == '?')
+ {
+ # Just add the tag to the block as if it was text.
+ $block_text .= $tag;
+ }
+ else {
+ #
+ # Increase/decrease nested tag count. Only do so if
+ # the tag's name match base tag's.
+ #
+ if (preg_match('{^?'.$base_tag_name_re.'\b}', $tag)) {
+ if ($tag{1} == '/') $depth--;
+ else if ($tag{strlen($tag)-2} != '/') $depth++;
+ }
+
+ #
+ # Check for `markdown="1"` attribute and handle it.
+ #
+ if ($md_attr &&
+ preg_match($markdown_attr_re, $tag, $attr_m) &&
+ preg_match('/^1|block|span$/', $attr_m[2] . $attr_m[3]))
+ {
+ # Remove `markdown` attribute from opening tag.
+ $tag = preg_replace($markdown_attr_re, '', $tag);
+
+ # Check if text inside this tag must be parsed in span mode.
+ $this->mode = $attr_m[2] . $attr_m[3];
+ $span_mode = $this->mode == 'span' || $this->mode != 'block' &&
+ preg_match('{^<(?:'.$this->contain_span_tags_re.')\b}', $tag);
+
+ # Calculate indent before tag.
+ if (preg_match('/(?:^|\n)( *?)(?! ).*?$/', $block_text, $matches)) {
+ $strlen = $this->utf8_strlen;
+ $indent = $strlen($matches[1], 'UTF-8');
+ } else {
+ $indent = 0;
+ }
+
+ # End preceding block with this tag.
+ $block_text .= $tag;
+ $parsed .= $this->$hash_method($block_text);
+
+ # Get enclosing tag name for the ParseMarkdown function.
+ # (This pattern makes $tag_name_re safe without quoting.)
+ preg_match('/^<([\w:$]*)\b/', $tag, $matches);
+ $tag_name_re = $matches[1];
+
+ # Parse the content using the HTML-in-Markdown parser.
+ list ($block_text, $text)
+ = $this->_hashHTMLBlocks_inMarkdown($text, $indent,
+ $tag_name_re, $span_mode);
+
+ # Outdent markdown text.
+ if ($indent > 0) {
+ $block_text = preg_replace("/^[ ]{1,$indent}/m", "",
+ $block_text);
+ }
+
+ # Append tag content to parsed text.
+ if (!$span_mode) $parsed .= "\n\n$block_text\n\n";
+ else $parsed .= "$block_text";
+
+ # Start over a new block.
+ $block_text = "";
+ }
+ else $block_text .= $tag;
+ }
+
+ } while ($depth > 0);
+
+ #
+ # Hash last block text that wasn't processed inside the loop.
+ #
+ $parsed .= $this->$hash_method($block_text);
+
+ return array($parsed, $text);
+ }
+
+
+ function hashClean($text) {
+ #
+ # Called whenever a tag must be hashed when a function insert a "clean" tag
+ # in $text, it pass through this function and is automaticaly escaped,
+ # blocking invalid nested overlap.
+ #
+ return $this->hashPart($text, 'C');
+ }
+
+
+ function doHeaders($text) {
+ #
+ # Redefined to add id attribute support.
+ #
+ # Setext-style headers:
+ # Header 1 {#header1}
+ # ========
+ #
+ # Header 2 {#header2}
+ # --------
+ #
+ $text = preg_replace_callback(
+ '{
+ (^.+?) # $1: Header text
+ (?:[ ]+\{\#([-_:a-zA-Z0-9]+)\})? # $2: Id attribute
+ [ ]*\n(=+|-+)[ ]*\n+ # $3: Header footer
+ }mx',
+ array(&$this, '_doHeaders_callback_setext'), $text);
+
+ # atx-style headers:
+ # # Header 1 {#header1}
+ # ## Header 2 {#header2}
+ # ## Header 2 with closing hashes ## {#header3}
+ # ...
+ # ###### Header 6 {#header2}
+ #
+ $text = preg_replace_callback('{
+ ^(\#{1,6}) # $1 = string of #\'s
+ [ ]*
+ (.+?) # $2 = Header text
+ [ ]*
+ \#* # optional closing #\'s (not counted)
+ (?:[ ]+\{\#([-_:a-zA-Z0-9]+)\})? # id attribute
+ [ ]*
+ \n+
+ }xm',
+ array(&$this, '_doHeaders_callback_atx'), $text);
+
+ return $text;
+ }
+ function _doHeaders_attr($attr) {
+ if (empty($attr)) return "";
+ return " id=\"$attr\"";
+ }
+ function _doHeaders_callback_setext($matches) {
+ if ($matches[3] == '-' && preg_match('{^- }', $matches[1]))
+ return $matches[0];
+ $level = $matches[3]{0} == '=' ? 1 : 2;
+ $attr = $this->_doHeaders_attr($id =& $matches[2]);
+ $block = "
".$this->runSpanGamut($matches[1])." ";
+ return "\n" . $this->hashBlock($block) . "\n\n";
+ }
+ function _doHeaders_callback_atx($matches) {
+ $level = strlen($matches[1]);
+ $attr = $this->_doHeaders_attr($id =& $matches[3]);
+ $block = "
".$this->runSpanGamut($matches[2])." ";
+ return "\n" . $this->hashBlock($block) . "\n\n";
+ }
+
+
+ function doTables($text) {
+ #
+ # Form HTML tables.
+ #
+ $less_than_tab = $this->tab_width - 1;
+ #
+ # Find tables with leading pipe.
+ #
+ # | Header 1 | Header 2
+ # | -------- | --------
+ # | Cell 1 | Cell 2
+ # | Cell 3 | Cell 4
+ #
+ $text = preg_replace_callback('
+ {
+ ^ # Start of a line
+ [ ]{0,'.$less_than_tab.'} # Allowed whitespace.
+ [|] # Optional leading pipe (present)
+ (.+) \n # $1: Header row (at least one pipe)
+
+ [ ]{0,'.$less_than_tab.'} # Allowed whitespace.
+ [|] ([ ]*[-:]+[-| :]*) \n # $2: Header underline
+
+ ( # $3: Cells
+ (?>
+ [ ]* # Allowed whitespace.
+ [|] .* \n # Row content.
+ )*
+ )
+ (?=\n|\Z) # Stop at final double newline.
+ }xm',
+ array(&$this, '_doTable_leadingPipe_callback'), $text);
+
+ #
+ # Find tables without leading pipe.
+ #
+ # Header 1 | Header 2
+ # -------- | --------
+ # Cell 1 | Cell 2
+ # Cell 3 | Cell 4
+ #
+ $text = preg_replace_callback('
+ {
+ ^ # Start of a line
+ [ ]{0,'.$less_than_tab.'} # Allowed whitespace.
+ (\S.*[|].*) \n # $1: Header row (at least one pipe)
+
+ [ ]{0,'.$less_than_tab.'} # Allowed whitespace.
+ ([-:]+[ ]*[|][-| :]*) \n # $2: Header underline
+
+ ( # $3: Cells
+ (?>
+ .* [|] .* \n # Row content
+ )*
+ )
+ (?=\n|\Z) # Stop at final double newline.
+ }xm',
+ array(&$this, '_DoTable_callback'), $text);
+
+ return $text;
+ }
+ function _doTable_leadingPipe_callback($matches) {
+ $head = $matches[1];
+ $underline = $matches[2];
+ $content = $matches[3];
+
+ # Remove leading pipe for each row.
+ $content = preg_replace('/^ *[|]/m', '', $content);
+
+ return $this->_doTable_callback(array($matches[0], $head, $underline, $content));
+ }
+ function _doTable_callback($matches) {
+ $head = $matches[1];
+ $underline = $matches[2];
+ $content = $matches[3];
+
+ # Remove any tailing pipes for each line.
+ $head = preg_replace('/[|] *$/m', '', $head);
+ $underline = preg_replace('/[|] *$/m', '', $underline);
+ $content = preg_replace('/[|] *$/m', '', $content);
+
+ # Reading alignement from header underline.
+ $separators = preg_split('/ *[|] */', $underline);
+ foreach ($separators as $n => $s) {
+ if (preg_match('/^ *-+: *$/', $s)) $attr[$n] = ' align="right"';
+ else if (preg_match('/^ *:-+: *$/', $s))$attr[$n] = ' align="center"';
+ else if (preg_match('/^ *:-+ *$/', $s)) $attr[$n] = ' align="left"';
+ else $attr[$n] = '';
+ }
+
+ # Parsing span elements, including code spans, character escapes,
+ # and inline HTML tags, so that pipes inside those gets ignored.
+ $head = $this->parseSpan($head);
+ $headers = preg_split('/ *[|] */', $head);
+ $col_count = count($headers);
+
+ # Write column headers.
+ $text = "
\n";
+ $text .= "\n";
+ $text .= "\n";
+ foreach ($headers as $n => $header)
+ $text .= " ".$this->runSpanGamut(trim($header))." \n";
+ $text .= " \n";
+ $text .= " \n";
+
+ # Split content by row.
+ $rows = explode("\n", trim($content, "\n"));
+
+ $text .= "\n";
+ foreach ($rows as $row) {
+ # Parsing span elements, including code spans, character escapes,
+ # and inline HTML tags, so that pipes inside those gets ignored.
+ $row = $this->parseSpan($row);
+
+ # Split row by cell.
+ $row_cells = preg_split('/ *[|] */', $row, $col_count);
+ $row_cells = array_pad($row_cells, $col_count, '');
+
+ $text .= "\n";
+ foreach ($row_cells as $n => $cell)
+ $text .= " ".$this->runSpanGamut(trim($cell))." \n";
+ $text .= " \n";
+ }
+ $text .= " \n";
+ $text .= "
";
+
+ return $this->hashBlock($text) . "\n";
+ }
+
+
+ function doDefLists($text) {
+ #
+ # Form HTML definition lists.
+ #
+ $less_than_tab = $this->tab_width - 1;
+
+ # Re-usable pattern to match any entire dl list:
+ $whole_list_re = '(?>
+ ( # $1 = whole list
+ ( # $2
+ [ ]{0,'.$less_than_tab.'}
+ ((?>.*\S.*\n)+) # $3 = defined term
+ \n?
+ [ ]{0,'.$less_than_tab.'}:[ ]+ # colon starting definition
+ )
+ (?s:.+?)
+ ( # $4
+ \z
+ |
+ \n{2,}
+ (?=\S)
+ (?! # Negative lookahead for another term
+ [ ]{0,'.$less_than_tab.'}
+ (?: \S.*\n )+? # defined term
+ \n?
+ [ ]{0,'.$less_than_tab.'}:[ ]+ # colon starting definition
+ )
+ (?! # Negative lookahead for another definition
+ [ ]{0,'.$less_than_tab.'}:[ ]+ # colon starting definition
+ )
+ )
+ )
+ )'; // mx
+
+ $text = preg_replace_callback('{
+ (?>\A\n?|(?<=\n\n))
+ '.$whole_list_re.'
+ }mx',
+ array(&$this, '_doDefLists_callback'), $text);
+
+ return $text;
+ }
+ function _doDefLists_callback($matches) {
+ # Re-usable patterns to match list item bullets and number markers:
+ $list = $matches[1];
+
+ # Turn double returns into triple returns, so that we can make a
+ # paragraph for the last item in a list, if necessary:
+ $result = trim($this->processDefListItems($list));
+ $result = "
\n" . $result . "\n ";
+ return $this->hashBlock($result) . "\n\n";
+ }
+
+
+ function processDefListItems($list_str) {
+ #
+ # Process the contents of a single definition list, splitting it
+ # into individual term and definition list items.
+ #
+ $less_than_tab = $this->tab_width - 1;
+
+ # trim trailing blank lines:
+ $list_str = preg_replace("/\n{2,}\\z/", "\n", $list_str);
+
+ # Process definition terms.
+ $list_str = preg_replace_callback('{
+ (?>\A\n?|\n\n+) # leading line
+ ( # definition terms = $1
+ [ ]{0,'.$less_than_tab.'} # leading whitespace
+ (?![:][ ]|[ ]) # negative lookahead for a definition
+ # mark (colon) or more whitespace.
+ (?> \S.* \n)+? # actual term (not whitespace).
+ )
+ (?=\n?[ ]{0,3}:[ ]) # lookahead for following line feed
+ # with a definition mark.
+ }xm',
+ array(&$this, '_processDefListItems_callback_dt'), $list_str);
+
+ # Process actual definitions.
+ $list_str = preg_replace_callback('{
+ \n(\n+)? # leading line = $1
+ ( # marker space = $2
+ [ ]{0,'.$less_than_tab.'} # whitespace before colon
+ [:][ ]+ # definition mark (colon)
+ )
+ ((?s:.+?)) # definition text = $3
+ (?= \n+ # stop at next definition mark,
+ (?: # next term or end of text
+ [ ]{0,'.$less_than_tab.'} [:][ ] |
+
| \z
+ )
+ )
+ }xm',
+ array(&$this, '_processDefListItems_callback_dd'), $list_str);
+
+ return $list_str;
+ }
+ function _processDefListItems_callback_dt($matches) {
+ $terms = explode("\n", trim($matches[1]));
+ $text = '';
+ foreach ($terms as $term) {
+ $term = $this->runSpanGamut(trim($term));
+ $text .= "\n" . $term . " ";
+ }
+ return $text . "\n";
+ }
+ function _processDefListItems_callback_dd($matches) {
+ $leading_line = $matches[1];
+ $marker_space = $matches[2];
+ $def = $matches[3];
+
+ if ($leading_line || preg_match('/\n{2,}/', $def)) {
+ # Replace marker with the appropriate whitespace indentation
+ $def = str_repeat(' ', strlen($marker_space)) . $def;
+ $def = $this->runBlockGamut($this->outdent($def . "\n\n"));
+ $def = "\n". $def ."\n";
+ }
+ else {
+ $def = rtrim($def);
+ $def = $this->runSpanGamut($this->outdent($def));
+ }
+
+ return "\n " . $def . " \n";
+ }
+
+
+ function doFencedCodeBlocks($text) {
+ #
+ # Adding the fenced code block syntax to regular Markdown:
+ #
+ # ~~~
+ # Code block
+ # ~~~
+ #
+ $less_than_tab = $this->tab_width;
+
+ $text = preg_replace_callback('{
+ (?:\n|\A)
+ # 1: Opening marker
+ (
+ ~{3,} # Marker: three tilde or more.
+ )
+ [ ]* \n # Whitespace and newline following marker.
+
+ # 2: Content
+ (
+ (?>
+ (?!\1 [ ]* \n) # Not a closing marker.
+ .*\n+
+ )+
+ )
+
+ # Closing marker.
+ \1 [ ]* \n
+ }xm',
+ array(&$this, '_doFencedCodeBlocks_callback'), $text);
+
+ return $text;
+ }
+ function _doFencedCodeBlocks_callback($matches) {
+ $codeblock = $matches[2];
+ $codeblock = htmlspecialchars($codeblock, ENT_NOQUOTES);
+ $codeblock = preg_replace_callback('/^\n+/',
+ array(&$this, '_doFencedCodeBlocks_newlines'), $codeblock);
+ $codeblock = "
$codeblock";
+ return "\n\n".$this->hashBlock($codeblock)."\n\n";
+ }
+ function _doFencedCodeBlocks_newlines($matches) {
+ return str_repeat("
empty_element_suffix",
+ strlen($matches[0]));
+ }
+
+
+ #
+ # Redefining emphasis markers so that emphasis by underscore does not
+ # work in the middle of a word.
+ #
+ var $em_relist = array(
+ '' => '(?:(? '(?<=\S|^)(? '(?<=\S|^)(? '(?:(? '(?<=\S|^)(? '(?<=\S|^)(? '(?:(? '(?<=\S|^)(? '(?<=\S|^)(? tags
+ #
+ # Strip leading and trailing lines:
+ $text = preg_replace('/\A\n+|\n+\z/', '', $text);
+
+ $grafs = preg_split('/\n{2,}/', $text, -1, PREG_SPLIT_NO_EMPTY);
+
+ #
+ # Wrap
tags and unhashify HTML blocks
+ #
+ foreach ($grafs as $key => $value) {
+ $value = trim($this->runSpanGamut($value));
+
+ # Check if this should be enclosed in a paragraph.
+ # Clean tag hashes & block tag hashes are left alone.
+ $is_p = !preg_match('/^B\x1A[0-9]+B|^C\x1A[0-9]+C$/', $value);
+
+ if ($is_p) {
+ $value = "
$value
";
+ }
+ $grafs[$key] = $value;
+ }
+
+ # Join grafs in one text, then unhash HTML tags.
+ $text = implode("\n\n", $grafs);
+
+ # Finish by removing any tag hashes still present in $text.
+ $text = $this->unhash($text);
+
+ return $text;
+ }
+
+
+ ### Footnotes
+
+ function stripFootnotes($text) {
+ #
+ # Strips link definitions from text, stores the URLs and titles in
+ # hash references.
+ #
+ $less_than_tab = $this->tab_width - 1;
+
+ # Link defs are in the form: [^id]: url "optional title"
+ $text = preg_replace_callback('{
+ ^[ ]{0,'.$less_than_tab.'}\[\^(.+?)\][ ]?: # note_id = $1
+ [ ]*
+ \n? # maybe *one* newline
+ ( # text = $2 (no blank lines allowed)
+ (?:
+ .+ # actual text
+ |
+ \n # newlines but
+ (?!\[\^.+?\]:\s)# negative lookahead for footnote marker.
+ (?!\n+[ ]{0,3}\S)# ensure line is not blank and followed
+ # by non-indented content
+ )*
+ )
+ }xm',
+ array(&$this, '_stripFootnotes_callback'),
+ $text);
+ return $text;
+ }
+ function _stripFootnotes_callback($matches) {
+ $note_id = $this->fn_id_prefix . $matches[1];
+ $this->footnotes[$note_id] = $this->outdent($matches[2]);
+ return ''; # String that will replace the block
+ }
+
+
+ function doFootnotes($text) {
+ #
+ # Replace footnote references in $text [^id] with a special text-token
+ # which will be replaced by the actual footnote marker in appendFootnotes.
+ #
+ if (!$this->in_anchor) {
+ $text = preg_replace('{\[\^(.+?)\]}', "F\x1Afn:\\1\x1A:", $text);
+ }
+ return $text;
+ }
+
+
+ function appendFootnotes($text) {
+ #
+ # Append footnote list to text.
+ #
+ $text = preg_replace_callback('{F\x1Afn:(.*?)\x1A:}',
+ array(&$this, '_appendFootnotes_callback'), $text);
+
+ if (!empty($this->footnotes_ordered)) {
+ $text .= "\n\n";
+ $text .= "";
+ }
+ return $text;
+ }
+ function _appendFootnotes_callback($matches) {
+ $node_id = $this->fn_id_prefix . $matches[1];
+
+ # Create footnote marker only if it has a corresponding footnote *and*
+ # the footnote hasn't been used by another marker.
+ if (isset($this->footnotes[$node_id])) {
+ # Transfert footnote content to the ordered list.
+ $this->footnotes_ordered[$node_id] = $this->footnotes[$node_id];
+ unset($this->footnotes[$node_id]);
+
+ $num = $this->footnote_counter++;
+ $attr = " rel=\"footnote\"";
+ if ($this->fn_link_class != "") {
+ $class = $this->fn_link_class;
+ $class = $this->encodeAttribute($class);
+ $attr .= " class=\"$class\"";
+ }
+ if ($this->fn_link_title != "") {
+ $title = $this->fn_link_title;
+ $title = $this->encodeAttribute($title);
+ $attr .= " title=\"$title\"";
+ }
+
+ $attr = str_replace("%%", $num, $attr);
+ $node_id = $this->encodeAttribute($node_id);
+
+ return
+ "
".
+ "$num ".
+ " ";
+ }
+
+ return "[^".$matches[1]."]";
+ }
+
+
+ ### Abbreviations ###
+
+ function stripAbbreviations($text) {
+ #
+ # Strips abbreviations from text, stores titles in hash references.
+ #
+ $less_than_tab = $this->tab_width - 1;
+
+ # Link defs are in the form: [id]*: url "optional title"
+ $text = preg_replace_callback('{
+ ^[ ]{0,'.$less_than_tab.'}\*\[(.+?)\][ ]?: # abbr_id = $1
+ (.*) # text = $2 (no blank lines allowed)
+ }xm',
+ array(&$this, '_stripAbbreviations_callback'),
+ $text);
+ return $text;
+ }
+ function _stripAbbreviations_callback($matches) {
+ $abbr_word = $matches[1];
+ $abbr_desc = $matches[2];
+ if ($this->abbr_word_re)
+ $this->abbr_word_re .= '|';
+ $this->abbr_word_re .= preg_quote($abbr_word);
+ $this->abbr_desciptions[$abbr_word] = trim($abbr_desc);
+ return ''; # String that will replace the block
+ }
+
+
+ function doAbbreviations($text) {
+ #
+ # Find defined abbreviations in text and wrap them in
elements.
+ #
+ if ($this->abbr_word_re) {
+ // cannot use the /x modifier because abbr_word_re may
+ // contain significant spaces:
+ $text = preg_replace_callback('{'.
+ '(?abbr_word_re.')'.
+ '(?![\w\x1A])'.
+ '}',
+ array(&$this, '_doAbbreviations_callback'), $text);
+ }
+ return $text;
+ }
+ function _doAbbreviations_callback($matches) {
+ $abbr = $matches[0];
+ if (isset($this->abbr_desciptions[$abbr])) {
+ $desc = $this->abbr_desciptions[$abbr];
+ if (empty($desc)) {
+ return $this->hashPart("$abbr ");
+ } else {
+ $desc = $this->encodeAttribute($desc);
+ return $this->hashPart("$abbr ");
+ }
+ } else {
+ return $matches[0];
+ }
+ }
+
+}
+
+
+/*
+
+PHP Markdown Extra
+==================
+
+Description
+-----------
+
+This is a PHP port of the original Markdown formatter written in Perl
+by John Gruber. This special "Extra" version of PHP Markdown features
+further enhancements to the syntax for making additional constructs
+such as tables and definition list.
+
+Markdown is a text-to-HTML filter; it translates an easy-to-read /
+easy-to-write structured text format into HTML. Markdown's text format
+is most similar to that of plain text email, and supports features such
+as headers, *emphasis*, code blocks, blockquotes, and links.
+
+Markdown's syntax is designed not as a generic markup language, but
+specifically to serve as a front-end to (X)HTML. You can use span-level
+HTML tags anywhere in a Markdown document, and you can use block level
+HTML tags (like and
as well).
+
+For more information about Markdown's syntax, see:
+
+
+
+
+Bugs
+----
+
+To file bug reports please send email to:
+
+
+
+Please include with your report: (1) the example input; (2) the output you
+expected; (3) the output Markdown actually produced.
+
+
+Version History
+---------------
+
+See the readme file for detailed release notes for this version.
+
+
+Copyright and License
+---------------------
+
+PHP Markdown & Extra
+Copyright (c) 2004-2009 Michel Fortin
+
+All rights reserved.
+
+Based on Markdown
+Copyright (c) 2003-2006 John Gruber
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+* Neither the name "Markdown" nor the names of its contributors may
+ be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+This software is provided by the copyright holders and contributors "as
+is" and any express or implied warranties, including, but not limited
+to, the implied warranties of merchantability and fitness for a
+particular purpose are disclaimed. In no event shall the copyright owner
+or contributors be liable for any direct, indirect, incidental, special,
+exemplary, or consequential damages (including, but not limited to,
+procurement of substitute goods or services; loss of use, data, or
+profits; or business interruption) however caused and on any theory of
+liability, whether in contract, strict liability, or tort (including
+negligence or otherwise) arising in any way out of the use of this
+software, even if advised of the possibility of such damage.
+
+*/
+?>
\ No newline at end of file
diff --git a/cookbook/markdownpmw.php b/cookbook/markdownpmw.php
new file mode 100644
index 0000000..2ab7b78
--- /dev/null
+++ b/cookbook/markdownpmw.php
@@ -0,0 +1,43 @@
+
+ * @version 0.1
+ * @link http://www.pmwiki.org/wiki/Cookbook/MarkdownMarkupExtension http://www.pmwiki.org/wiki/Cookbook/MarkdownMarkupExtension
+ * @copyright by the respective authors 2006
+ * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License
+ * @package markdownpmw
+ */
+
+define(MARKDOWNPMW, "0.1");
+
+SDVA($PmWikiAutoUpdate['MarkdownPmW'], array(
+ 'version' => MARKDOWNPMW,
+ 'updateurl' => 'http://www.pmwiki.org/wiki/Cookbook/MarkdownMarkupExtension',
+));
+
+include_once("markdown.php");
+
+Markup("markdown", '" => "\n\n",
+ "(:nl:)" => "\n",
+ );
+ $pstr = array(
+ "//" => "
",
+ "/&(.*?);/" => "&\\1;",
+ );
+
+ $text = str_replace(array_keys($astr), $astr, $text);
+ $text = Markdown($text);
+ $text = preg_replace(array_keys($pstr), $pstr, $text);
+
+ return $text;
+ }
+
+?>
\ No newline at end of file
diff --git a/docs/COPYING.txt b/docs/COPYING.txt
new file mode 100644
index 0000000..5b6e7c6
--- /dev/null
+++ b/docs/COPYING.txt
@@ -0,0 +1,340 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ 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.
+
+ 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.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ , 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/docs/DOCUMENTATION.txt b/docs/DOCUMENTATION.txt
new file mode 100644
index 0000000..b2cff0c
--- /dev/null
+++ b/docs/DOCUMENTATION.txt
@@ -0,0 +1,10 @@
+Where is the documentation?
+
+PmWiki maintains its documentation as wiki pages.
+If you already have PmWiki installed, then a local copy of
+the documentation is available through PmWiki itself --
+see the "PmWiki.DocumentationIndex" page on your site.
+
+The documentation is also available online at
+http://www.pmwiki.org/wiki/PmWiki/DocumentationIndex .
+
diff --git a/docs/INSTALL.txt b/docs/INSTALL.txt
new file mode 100644
index 0000000..fb63ca8
--- /dev/null
+++ b/docs/INSTALL.txt
@@ -0,0 +1,39 @@
+This is the INSTALL.txt file for PmWiki. This document provides
+convenient steps so an administrator can have a PmWiki site up and
+running quickly. More extensive information about installing PmWiki
+is available at http://www.pmwiki.org/wiki/PmWiki/Installation .
+
+Once your site is up and running you will be able to read the bundled
+documentation pages.
+
+Here are some quick steps to start you on your path toward a complete,
+customized installation:
+
+1a) Put the software in a location accessible by your webserver.
+
+1b) PmWiki can also be run if no webserver is installed. See
+ http://pmwiki.org/wiki/Cookbook/Standalone
+
+2) Point your browser to pmwiki.php.
+
+3) You may see an error message saying that PmWiki needs to have
+ a writable wiki.d/ directory. If so, follow the directions to
+ establish one. This directory will hold your wiki page files.
+
+4) If you want a directory index file, create a file called index.php
+ in the main directory that contains the following single line of
+ text, purposefully without a closing "?>":
+
+ with your question(s) and I'll
+ provide explanations (and add comments) that answer them.
+*/
+error_reporting(E_ALL ^ E_NOTICE);
+StopWatch('PmWiki');
+@ini_set('magic_quotes_runtime', 0);
+@ini_set('magic_quotes_sybase', 0);
+if (@ini_get('pcre.backtrack_limit') < 1000000)
+ @ini_set('pcre.backtrack_limit', 1000000);
+if (ini_get('register_globals'))
+ foreach($_REQUEST as $k=>$v) {
+ if (preg_match('/^(GLOBALS|_SERVER|_GET|_POST|_COOKIE|_FILES|_ENV|_REQUEST|_SESSION|FarmD|WikiDir)$/i', $k)) exit();
+ ${$k}=''; unset(${$k});
+ }
+$UnsafeGlobals = array_keys($GLOBALS); $GCount=0; $FmtV=array();
+SDV($FarmD,dirname(__FILE__));
+SDV($WorkDir,'wiki.d');
+define('PmWiki',1);
+if (preg_match('/\\w\\w:/', $FarmD)) exit();
+@include_once("$FarmD/scripts/version.php");
+$GroupPattern = '[[:upper:]][\\w]*(?:-\\w+)*';
+$NamePattern = '[[:upper:]\\d][\\w]*(?:-\\w+)*';
+$BlockPattern = 'form|div|table|t[rdh]|p|[uo]l|d[ltd]|h[1-6r]|pre|blockquote';
+$WikiWordPattern = '[[:upper:]][[:alnum:]]*(?:[[:upper:]][[:lower:]0-9]|[[:lower:]0-9][[:upper:]])[[:alnum:]]*';
+$WikiDir = new PageStore('wiki.d/{$FullName}');
+$WikiLibDirs = array(&$WikiDir,new PageStore('$FarmD/wikilib.d/{$FullName}'));
+$LocalDir = 'local';
+$InterMapFiles = array("$FarmD/scripts/intermap.txt",
+ "$FarmD/local/farmmap.txt", '$SiteGroup.InterMap', 'local/localmap.txt');
+$Newline = "\263"; # deprecated, 2.0.0
+$KeepToken = "\235\235";
+$Now=time();
+define('READPAGE_CURRENT', $Now+604800);
+$TimeFmt = '%B %d, %Y, at %I:%M %p';
+$TimeISOFmt = '%Y-%m-%dT%H:%M:%S';
+$TimeISOZFmt = '%Y-%m-%dT%H:%M:%SZ';
+$MessagesFmt = array();
+$BlockMessageFmt = "$[This post has been blocked by the administrator] ";
+$EditFields = array('text');
+$EditFunctions = array('EditTemplate', 'RestorePage', 'ReplaceOnSave',
+ 'SaveAttributes', 'PostPage', 'PostRecentChanges', 'AutoCreateTargets',
+ 'PreviewPage');
+$EnablePost = 1;
+$ChangeSummary = substr(preg_replace('/[\\x00-\\x1f]|=\\]/', '',
+ stripmagic(@$_REQUEST['csum'])), 0, 100);
+$AsSpacedFunction = 'AsSpaced';
+$SpaceWikiWords = 0;
+$RCDelimPattern = ' ';
+$RecentChangesFmt = array(
+ '$SiteGroup.AllRecentChanges' =>
+ '* [[{$Group}.{$Name}]] . . . $CurrentTime $[by] $AuthorLink: [=$ChangeSummary=]',
+ '$Group.RecentChanges' =>
+ '* [[{$Group}/{$Name}]] . . . $CurrentTime $[by] $AuthorLink: [=$ChangeSummary=]');
+$UrlScheme = (@$_SERVER['HTTPS']=='on' || @$_SERVER['SERVER_PORT']==443)
+ ? 'https' : 'http';
+$ScriptUrl = $UrlScheme.'://'.$_SERVER['HTTP_HOST'].$_SERVER['SCRIPT_NAME'];
+$PubDirUrl = preg_replace('#/[^/]*$#', '/pub', $ScriptUrl, 1);
+$HTMLVSpace = "";
+$HTMLPNewline = '';
+$MarkupFrame = array();
+$MarkupFrameBase = array('cs' => array(), 'vs' => '', 'ref' => 0,
+ 'closeall' => array(), 'is' => array(),
+ 'escape' => 1);
+$WikiWordCountMax = 1000000;
+$WikiWordCount['PmWiki'] = 1;
+$TableRowIndexMax = 1;
+$UrlExcludeChars = '<>"{}|\\\\^`()[\\]\'';
+$QueryFragPattern = "[?#][^\\s$UrlExcludeChars]*";
+$SuffixPattern = '(?:-?[[:alnum:]]+)*';
+$LinkPageSelfFmt = "\$LinkText ";
+$LinkPageExistsFmt = "\$LinkText ";
+$LinkPageCreateFmt =
+ "\$LinkText ? ";
+$UrlLinkFmt =
+ "\$LinkText ";
+umask(002);
+$CookiePrefix = '';
+$SiteGroup = 'Site';
+$SiteAdminGroup = 'SiteAdmin';
+$DefaultGroup = 'Main';
+$DefaultName = 'HomePage';
+$GroupHeaderFmt = '(:include {$Group}.GroupHeader self=0 basepage={*$FullName}:)(:nl:)';
+$GroupFooterFmt = '(:nl:)(:include {$Group}.GroupFooter self=0 basepage={*$FullName}:)';
+$PagePathFmt = array('{$Group}.$1','$1.$1','$1.{$DefaultName}');
+$PageAttributes = array(
+ 'passwdread' => '$[Set new read password:]',
+ 'passwdedit' => '$[Set new edit password:]',
+ 'passwdattr' => '$[Set new attribute password:]');
+$XLLangs = array('en');
+if (preg_match('/^C$|\.UTF-?8/i',setlocale(LC_ALL,0)))
+ setlocale(LC_ALL,'en_US');
+$FmtP = array();
+$FmtPV = array(
+ # '$ScriptUrl' => 'PUE($ScriptUrl)', ## $ScriptUrl is special
+ '$PageUrl' =>
+ 'PUE(($EnablePathInfo)
+ ? "$ScriptUrl/$group/$name"
+ : "$ScriptUrl?n=$group.$name")',
+ '$FullName' => '"$group.$name"',
+ '$Groupspaced' => '$AsSpacedFunction($group)',
+ '$Namespaced' => '$AsSpacedFunction($name)',
+ '$Group' => '$group',
+ '$Name' => '$name',
+ '$Titlespaced' => '@$page["title"] ?
+ str_replace("$", "$", $page["title"]) : $AsSpacedFunction($name)',
+ '$Title' => '@$page["title"] ?
+ str_replace("$", "$", $page["title"]) :
+ ($GLOBALS["SpaceWikiWords"] ? $AsSpacedFunction($name) : $name)',
+ '$LastModifiedBy' => '@$page["author"]',
+ '$LastModifiedHost' => '@$page["host"]',
+ '$LastModified' => 'strftime($GLOBALS["TimeFmt"], $page["time"])',
+ '$LastModifiedSummary' => '@$page["csum"]',
+ '$LastModifiedTime' => '$page["time"]',
+ '$Description' => '@$page["description"]',
+ '$SiteGroup' => '$GLOBALS["SiteGroup"]',
+ '$VersionNum' => '$GLOBALS["VersionNum"]',
+ '$Version' => '$GLOBALS["Version"]',
+ '$Author' => 'NoCache($GLOBALS["Author"])',
+ '$AuthId' => 'NoCache($GLOBALS["AuthId"])',
+ '$DefaultGroup' => '$GLOBALS["DefaultGroup"]',
+ '$DefaultName' => '$GLOBALS["DefaultName"]',
+ '$BaseName' => 'MakeBaseName($pn)',
+ '$Action' => '$GLOBALS["action"]',
+ '$PasswdRead' => 'PasswdVar($pn, "read")',
+ '$PasswdEdit' => 'PasswdVar($pn, "edit")',
+ '$PasswdAttr' => 'PasswdVar($pn, "attr")',
+ );
+$SaveProperties = array('title', 'description', 'keywords');
+$PageTextVarPatterns = array(
+ 'var:' => '/^(:*\\s*(\\w[-\\w]*)\\s*:[ \\t]?)(.*)($)/m',
+ '(:var:...:)' => '/(\\(: *(\\w[-\\w]*) *:(?!\\))\\s?)(.*?)(:\\))/s'
+ );
+
+
+$WikiTitle = 'PmWiki';
+$Charset = 'ISO-8859-1';
+$HTTPHeaders = array(
+ "Expires: Tue, 01 Jan 2002 00:00:00 GMT",
+ "Cache-Control: no-store, no-cache, must-revalidate",
+ "Content-type: text/html; charset=ISO-8859-1;");
+$CacheActions = array('browse','diff','print');
+$EnableHTMLCache = 0;
+$NoHTMLCache = 0;
+$HTMLDoctypeFmt =
+ "
+ \n";
+$HTMLStylesFmt['pmwiki'] = "
+ ul, ol, pre, dl, p { margin-top:0px; margin-bottom:0px; }
+ code.escaped { white-space: nowrap; }
+ .vspace { margin-top:1.33em; }
+ .indent { margin-left:40px; }
+ .outdent { margin-left:40px; text-indent:-40px; }
+ a.createlinktext { text-decoration:none; border-bottom:1px dotted gray; }
+ a.createlink { text-decoration:none; position:relative; top:-0.5em;
+ font-weight:bold; font-size:smaller; border-bottom:none; }
+ img { border:0px; }
+ ";
+$HTMLHeaderFmt['styles'] = array(
+ "");
+$HTMLBodyFmt = "\n";
+$HTMLStartFmt = array('headers:',&$HTMLDoctypeFmt,&$HTMLHeaderFmt,
+ &$HTMLBodyFmt);
+$HTMLEndFmt = "\n\n";
+$PageStartFmt = array(&$HTMLStartFmt,"\n\n");
+$PageEndFmt = array('
',&$HTMLEndFmt);
+
+$HandleActions = array(
+ 'browse' => 'HandleBrowse', 'print' => 'HandleBrowse',
+ 'edit' => 'HandleEdit', 'source' => 'HandleSource',
+ 'attr' => 'HandleAttr', 'postattr' => 'HandlePostAttr',
+ 'logout' => 'HandleLogoutA', 'login' => 'HandleLoginA');
+$HandleAuth = array(
+ 'browse' => 'read', 'source' => 'read', 'print' => 'read',
+ 'edit' => 'edit', 'attr' => 'attr', 'postattr' => 'attr',
+ 'logout' => 'read', 'login' => 'login');
+$ActionTitleFmt = array(
+ 'edit' => '| $[Edit]',
+ 'attr' => '| $[Attributes]',
+ 'login' => '| $[Login]');
+$DefaultPasswords = array('admin'=>'*','read'=>'','edit'=>'','attr'=>'');
+$AuthCascade = array('edit'=>'read', 'attr'=>'edit');
+$AuthList = array('' => 1, 'nopass:' => 1, '@nopass' => 1);
+$SessionEncode = 'base64_encode';
+$SessionDecode = 'base64_decode';
+
+$Conditions['enabled'] = '(boolean)@$GLOBALS[$condparm]';
+$Conditions['false'] = 'false';
+$Conditions['true'] = 'true';
+$Conditions['group'] =
+ "(boolean)MatchPageNames(\$pagename, FixGlob(\$condparm, '$1$2.*'))";
+$Conditions['name'] =
+ "(boolean)MatchPageNames(\$pagename, FixGlob(\$condparm, '$1*.$2'))";
+$Conditions['match'] = 'preg_match("!$condparm!",$pagename)';
+$Conditions['authid'] = 'NoCache(@$GLOBALS["AuthId"] > "")';
+$Conditions['exists'] = 'PageExists(MakePageName($pagename, $condparm))';
+$Conditions['equal'] = 'CompareArgs($condparm) == 0';
+function CompareArgs($arg)
+ { $arg = ParseArgs($arg); return strcmp(@$arg[''][0], @$arg[''][1]); }
+
+$Conditions['auth'] = 'NoCache(CondAuth($pagename, $condparm))';
+function CondAuth($pagename, $condparm) {
+ @list($level, $pn) = explode(' ', $condparm, 2);
+ $pn = ($pn > '') ? MakePageName($pagename, $pn) : $pagename;
+ return (boolean)RetrieveAuthPage($pn, $level, false, READPAGE_CURRENT);
+}
+
+## CondExpr handles complex conditions (expressions)
+## Portions Copyright 2005 by D. Faure (dfaure@cpan.org)
+function CondExpr($pagename, $condname, $condparm) {
+ global $CondExprOps;
+ SDV($CondExprOps, 'and|x?or|&&|\\|\\||[!()]');
+ if ($condname == '(' || $condname == '[')
+ $condparm = preg_replace('/[\\]\\)]\\s*$/', '', $condparm);
+ $condparm = str_replace('&&', '&&', $condparm);
+ $terms = preg_split("/(? $t) {
+ $t = trim($t);
+ if (preg_match("/^($CondExprOps)$/i", $t)) continue;
+ if ($t) $terms[$i] = CondText($pagename, "if $t", 'TRUE') ? '1' : '0';
+ }
+ return @eval('return(' . implode(' ', $terms) . ');');
+}
+$Conditions['expr'] = 'CondExpr($pagename, $condname, $condparm)';
+$Conditions['('] = 'CondExpr($pagename, $condname, $condparm)';
+$Conditions['['] = 'CondExpr($pagename, $condname, $condparm)';
+
+$MarkupTable['_begin']['seq'] = 'B';
+$MarkupTable['_end']['seq'] = 'E';
+Markup('fulltext','>_begin');
+Markup('split','>fulltext',"\n",
+ '$RedoMarkupLine=1; return explode("\n",$x);');
+Markup('directives','>split');
+Markup('inline','>directives');
+Markup('links','>inline');
+Markup('block','>links');
+Markup('style','>block');
+Markup('closeall', '_begin',
+ '/^\\(:closeall:\\)$/e',
+ "'<:block>' . MarkupClose()");
+
+$ImgExtPattern="\\.(?:gif|jpg|jpeg|png|GIF|JPG|JPEG|PNG)";
+$ImgTagFmt=" ";
+
+$BlockMarkups = array(
+ 'block' => array('','','',0),
+ 'ul' => array('',1),
+ 'dl' => array('','',' ',1),
+ 'ol' => array('',' ',' ',1),
+ 'p' => array('','','
',0),
+ 'indent' =>
+ array("","
",'
',1),
+ 'outdent' =>
+ array("","
",'
',1),
+ 'pre' => array('','',' ',0),
+ 'table' => array("',0));
+
+foreach(array('http:','https:','mailto:','ftp:','news:','gopher:','nap:',
+ 'file:') as $m)
+ { $LinkFunctions[$m] = 'LinkIMap'; $IMap[$m]="$m$1"; }
+$LinkFunctions['<:page>'] = 'LinkPage';
+
+$q = preg_replace('/(\\?|%3f)([-\\w]+=)/', '&$2', @$_SERVER['QUERY_STRING']);
+if ($q != @$_SERVER['QUERY_STRING']) {
+ unset($_GET);
+ parse_str($q, $_GET);
+ $_REQUEST = array_merge($_REQUEST, $_GET, $_POST);
+}
+
+if (isset($_GET['action'])) $action = $_GET['action'];
+elseif (isset($_POST['action'])) $action = $_POST['action'];
+else $action = 'browse';
+
+$pagename = @$_REQUEST['n'];
+if (!$pagename) $pagename = @$_REQUEST['pagename'];
+if (!$pagename &&
+ preg_match('!^'.preg_quote($_SERVER['SCRIPT_NAME'],'!').'/?([^?]*)!',
+ $_SERVER['REQUEST_URI'],$match))
+ $pagename = urldecode($match[1]);
+if (preg_match('/[\\x80-\\xbf]/',$pagename))
+ $pagename=utf8_decode($pagename);
+$pagename = preg_replace('![^[:alnum:]\\x80-\\xff]+$!','',$pagename);
+$FmtPV['$RequestedPage'] = "'".htmlspecialchars($pagename, ENT_QUOTES)."'";
+$Cursor['*'] = &$pagename;
+if (function_exists("date_default_timezone_get") ) { # fix PHP5.3 warnings
+ @date_default_timezone_set(@date_default_timezone_get());
+}
+
+if (file_exists("$FarmD/local/farmconfig.php"))
+ include_once("$FarmD/local/farmconfig.php");
+if (IsEnabled($EnableLocalConfig,1)) {
+ if (file_exists("$LocalDir/config.php"))
+ include_once("$LocalDir/config.php");
+ elseif (file_exists('config.php'))
+ include_once('config.php');
+}
+
+// if (file_exists("$FarmD/cookbook/markdown.php")
+ // include_once(".cookbook/markdown.php");
+
+SDV($CurrentTime, strftime($TimeFmt, $Now));
+SDV($CurrentTimeISO, strftime($TimeISOFmt, $Now));
+
+if (IsEnabled($EnableStdConfig,1))
+ include_once("$FarmD/scripts/stdconfig.php");
+
+foreach((array)$InterMapFiles as $f) {
+ $f = FmtPageName($f, $pagename);
+ if (($v = @file($f)))
+ $v = preg_replace('/^\\s*(?>\\w[-\\w]*)(?!:)/m', '$0:', implode('', $v));
+ else if (PageExists($f)) {
+ $p = ReadPage($f, READPAGE_CURRENT);
+ $v = $p['text'];
+ } else continue;
+ if (!preg_match_all("/^\\s*(\\w[-\\w]*:)[^\\S\n]+(\\S*)/m", $v,
+ $match, PREG_SET_ORDER)) continue;
+ foreach($match as $m) {
+ if (strpos($m[2], '$1') === false) $m[2] .= '$1';
+ $LinkFunctions[$m[1]] = 'LinkIMap';
+ $IMap[$m[1]] = FmtPageName($m[2], $pagename);
+ }
+}
+
+$LinkPattern = implode('|',array_keys($LinkFunctions));
+SDV($LinkPageCreateSpaceFmt,$LinkPageCreateFmt);
+
+$keys = array_keys($AuthCascade);
+while ($keys) {
+ $k = array_shift($keys); $t = $AuthCascade[$k];
+ if (in_array($t, $keys))
+ { unset($AuthCascade[$k]); $AuthCascade[$k] = $t; array_push($keys, $k); }
+}
+
+$ActionTitle = FmtPageName(@$ActionTitleFmt[$action], $pagename);
+if (!@$HandleActions[$action] || !function_exists($HandleActions[$action]))
+ $action='browse';
+if (IsEnabled($EnableActions, 1)) HandleDispatch($pagename, $action);
+Lock(0);
+return;
+
+## HandleDispatch() is used to dispatch control to the appropriate
+## action handler with the appropriate permissions.
+## If a message is supplied, it is added to $MessagesFmt.
+function HandleDispatch($pagename, $action, $msg=NULL) {
+ global $MessagesFmt, $HandleActions, $HandleAuth;
+ if ($msg) $MessagesFmt[] = "$msg
";
+ $fn = $HandleActions[$action];
+ $auth = $HandleAuth[$action];
+ if (!$auth) $auth = 'read';
+ return $fn($pagename, $auth);
+}
+
+## helper functions
+function stripmagic($x)
+ { return get_magic_quotes_gpc() ? stripslashes($x) : $x; }
+function pre_r(&$x)
+ { return ''.htmlspecialchars(print_r($x, true)).' '; }
+function PSS($x)
+ { return str_replace('\\"','"',$x); }
+function PVS($x)
+ { return preg_replace("/\n[^\\S\n]*(?=\n)/", "\n<:vspace>", $x); }
+function PVSE($x) { return PVS(htmlspecialchars($x, ENT_NOQUOTES)); }
+function PZZ($x,$y='') { return ''; }
+function PRR($x=NULL)
+ { if ($x || is_null($x)) $GLOBALS['RedoMarkupLine']++; return $x; }
+function PUE($x)
+ { return preg_replace('/[\\x80-\\xff \'"<>]/e', "'%'.dechex(ord('$0'))", $x); }
+function PQA($x) {
+ $out = '';
+ if (preg_match_all('/([a-zA-Z]+)\\s*=\\s*("[^"]*"|\'[^\']*\'|\\S*)/',
+ $x, $attr, PREG_SET_ORDER)) {
+ foreach($attr as $a) {
+ if (preg_match('/^on/i', $a[1])) continue;
+ $out .= $a[1] . '='
+ . preg_replace( '/^(?![\'"]).*$/e',
+ "\"'\".str_replace(\"'\", ''', PSS('$0')).\"'\"", $a[2])
+ . ' ';
+ }
+ }
+ return $out;
+}
+function SDV(&$v,$x) { if (!isset($v)) $v=$x; }
+function SDVA(&$var,$val)
+ { foreach($val as $k=>$v) if (!isset($var[$k])) $var[$k]=$v; }
+function IsEnabled(&$var,$f=0)
+ { return (isset($var)) ? $var : $f; }
+function SetTmplDisplay($var, $val)
+ { NoCache(); $GLOBALS['TmplDisplay'][$var] = $val; }
+function NoCache($x = '') { $GLOBALS['NoHTMLCache'] |= 1; return $x; }
+function ParseArgs($x, $optpat = '(?>(\\w+)[:=])') {
+ $z = array();
+ preg_match_all("/($optpat|[-+])?(\"[^\"]*\"|'[^']*'|\\S+)/",
+ $x, $terms, PREG_SET_ORDER);
+ foreach($terms as $t) {
+ $v = preg_replace('/^([\'"])?(.*)\\1$/', '$2', $t[3]);
+ if ($t[2]) { $z['#'][] = $t[2]; $z[$t[2]] = $v; }
+ else { $z['#'][] = $t[1]; $z[$t[1]][] = $v; }
+ $z['#'][] = $v;
+ }
+ return $z;
+}
+function StopWatch($x) {
+ global $StopWatch, $EnableStopWatch;
+ if (!$EnableStopWatch) return;
+ static $wstart = 0, $ustart = 0;
+ list($usec,$sec) = explode(' ',microtime());
+ $wtime = ($sec+$usec);
+ if (!$wstart) $wstart = $wtime;
+ if ($EnableStopWatch != 2)
+ { $StopWatch[] = sprintf("%05.2f %s", $wtime-$wstart, $x); return; }
+ $dat = getrusage();
+ $utime = ($dat['ru_utime.tv_sec']+$dat['ru_utime.tv_usec']/1000000);
+ if (!$ustart) $ustart=$utime;
+ $StopWatch[] =
+ sprintf("%05.2f %05.2f %s", $wtime-$wstart, $utime-$ustart, $x);
+}
+
+
+## DRange converts a variety of string formats into date (ranges).
+## It returns the start and end timestamps (+1 second) of the specified date.
+function DRange($when) {
+ global $Now;
+ ## unix/posix @timestamp dates
+ if (preg_match('/^\\s*@(\\d+)\\s*(.*)$/', $when, $m)) {
+ $t0 = $m[2] ? strtotime($m[2], $m[1]) : $m[1];
+ return array($t0, $t0+1);
+ }
+ ## ISO-8601 dates
+ $dpat = '/
+ (?'' && @$m[5] == '') { @$n[4]++; }
+ ## if no day given, assume 1st of month and full month range
+ if (@$m[4] == '') { $m[4] = 1; $n[4] = 1; $n[3]++; }
+ ## if no seconds given, assume range of 1 minute (except when full day)
+ if (@$m[7]>'' && @$m[8] == '') { @$n[7]++; }
+ $t0 = @mktime($m[5], $m[7], $m[8], $m[3], $m[4], $m[1]);
+ $t1 = @mktime($n[5], $n[7], $n[8], $n[3], $n[4], $n[1]);
+ return array($t0, $t1);
+ }
+ ## now, today, tomorrow, yesterday
+ NoCache();
+ if ($when == 'now') return array($Now, $Now+1);
+ $m = localtime(time());
+ if ($when == 'tomorrow') { $m[3]++; $when = 'today'; }
+ if ($when == 'yesterday') { $m[3]--; $when = 'today'; }
+ if ($when == 'today')
+ return array(mktime(0, 0, 0, $m[4]+1, $m[3] , $m[5]+1900),
+ mktime(0, 0, 0, $m[4]+1, $m[3]+1, $m[5]+1900));
+ if (preg_match('/^\\s*$/', $when)) return array(-1, -1);
+ $t0 = strtotime($when);
+ $t1 = strtotime("+1 day", $t0);
+ return array($t0, $t1);
+}
+
+## AsSpaced converts a string with WikiWords into a spaced version
+## of that string. (It can be overridden via $AsSpacedFunction.)
+function AsSpaced($text) {
+ $text = preg_replace("/([[:lower:]\\d])([[:upper:]])/", '$1 $2', $text);
+ $text = preg_replace('/([^-\\d])(\\d[-\\d]*( |$))/','$1 $2',$text);
+ return preg_replace("/([[:upper:]])([[:upper:]][[:lower:]\\d])/",
+ '$1 $2', $text);
+}
+
+## Lock is used to make sure only one instance of PmWiki is running when
+## files are being written. It does not "lock pages" for editing.
+function Lock($op) {
+ global $WorkDir, $LockFile, $EnableReadOnly;
+ if ($op > 0 && IsEnabled($EnableReadOnly, 0))
+ Abort('Cannot modify site -- $EnableReadOnly is set', 'readonly');
+ SDV($LockFile, "$WorkDir/.flock");
+ mkdirp(dirname($LockFile));
+ static $lockfp,$curop;
+ if (!$lockfp) $lockfp = @fopen($LockFile, "w");
+ if (!$lockfp) {
+ if ($op <= 0) return;
+ @unlink($LockFile);
+ $lockfp = fopen($LockFile,"w") or
+ Abort('Cannot acquire lockfile', 'flock');
+ fixperms($LockFile);
+ }
+ if ($op<0) { flock($lockfp,LOCK_UN); fclose($lockfp); $lockfp=0; $curop=0; }
+ elseif ($op==0) { flock($lockfp,LOCK_UN); $curop=0; }
+ elseif ($op==1 && $curop<1)
+ { session_write_close(); flock($lockfp,LOCK_SH); $curop=1; }
+ elseif ($op==2 && $curop<2)
+ { session_write_close(); flock($lockfp,LOCK_EX); $curop=2; }
+}
+
+## mkdirp creates a directory and its parents as needed, and sets
+## permissions accordingly.
+function mkdirp($dir) {
+ global $ScriptUrl;
+ if (file_exists($dir)) return;
+ if (!file_exists(dirname($dir))) mkdirp(dirname($dir));
+ if (mkdir($dir, 0777)) {
+ fixperms($dir);
+ if (@touch("$dir/xxx")) { unlink("$dir/xxx"); return; }
+ rmdir($dir);
+ }
+ $parent = realpath(dirname($dir));
+ $bdir = basename($dir);
+ $perms = decoct(fileperms($parent) & 03777);
+ $msg = "PmWiki needs to have a writable $dir/ directory
+ before it can continue. You can create the directory manually
+ by executing the following commands on your server:
+ mkdir $parent/$bdir\n chmod 777 $parent/$bdir
+ Then, reload this page .";
+ $safemode = ini_get('safe_mode');
+ if (!$safemode) $msg .= " Or, for a slightly more
+ secure installation, try executing chmod 2777 $parent
+ on your server and following
+ this link . Afterwards you can restore the permissions to
+ their current setting by executing chmod $perms $parent .";
+ Abort($msg);
+}
+
+## fixperms attempts to correct permissions on a file or directory
+## so that both PmWiki and the account (current dir) owner can manipulate it
+function fixperms($fname, $add = 0) {
+ clearstatcache();
+ if (!file_exists($fname)) Abort('?no such file');
+ $bp = 0;
+ if (fileowner($fname)!=@fileowner('.')) $bp = (is_dir($fname)) ? 007 : 006;
+ if (filegroup($fname)==@filegroup('.')) $bp <<= 3;
+ $bp |= $add;
+ if ($bp && (fileperms($fname) & $bp) != $bp)
+ @chmod($fname,fileperms($fname)|$bp);
+}
+
+## GlobToPCRE converts wildcard patterns into pcre patterns for
+## inclusion and exclusion. Wildcards beginning with '-' or '!'
+## are treated as things to be excluded.
+function GlobToPCRE($pat) {
+ $pat = preg_quote($pat, '/');
+ $pat = str_replace(array('\\*', '\\?', '\\[', '\\]', '\\^', '\\-', '\\!'),
+ array('.*', '.', '[', ']', '^', '-', '!'), $pat);
+ $excl = array(); $incl = array();
+ foreach(preg_split('/,+\s?/', $pat, -1, PREG_SPLIT_NO_EMPTY) as $p) {
+ if ($p{0} == '-' || $p{0} == '!') $excl[] = '^'.substr($p, 1).'$';
+ else $incl[] = "^$p$";
+ }
+ return array(implode('|', $incl), implode('|', $excl));
+}
+
+## FixGlob changes wildcard patterns without '.' to things like
+## '*.foo' (name matches) or 'foo.*' (group matches).
+function FixGlob($x, $rep = '$1*.$2') {
+ return preg_replace('/([\\s,][-!]?)([^\\/.\\s,]+)(?=[\\s,])/', $rep, ",$x,");
+}
+
+## MatchPageNames reduces $pagelist to those pages with names
+## matching the pattern(s) in $pat. Patterns can be either
+## regexes to include ('/'), regexes to exclude ('!'), or
+## wildcard patterns (all others).
+function MatchPageNames($pagelist, $pat) {
+ global $Charset;
+ $pcre8 = ($Charset == 'UTF-8')? 'u' : ''; # allow range matches in utf8
+ $pagelist = (array)$pagelist;
+ foreach((array)$pat as $p) {
+ if (count($pagelist) < 1) break;
+ if (!$p) continue;
+ switch ($p{0}) {
+ case '/':
+ $pagelist = preg_grep($p, $pagelist);
+ continue;
+ case '!':
+ $pagelist = array_diff($pagelist, preg_grep($p, $pagelist));
+ continue;
+ default:
+ list($inclp, $exclp) = GlobToPCRE(str_replace('/', '.', $p));
+ if ($exclp)
+ $pagelist = array_diff($pagelist, preg_grep("/$exclp/i$pcre8", $pagelist));
+ if ($inclp)
+ $pagelist = preg_grep("/$inclp/i$pcre8", $pagelist);
+ }
+ }
+ return $pagelist;
+}
+
+## ResolvePageName "normalizes" a pagename based on the current
+## settings of $DefaultPage and $PagePathFmt. It's normally used
+## during initialization to fix up any missing or partial pagenames.
+function ResolvePageName($pagename) {
+ global $DefaultPage, $DefaultGroup, $DefaultName,
+ $GroupPattern, $NamePattern, $EnableFixedUrlRedirect;
+ SDV($DefaultPage, "$DefaultGroup.$DefaultName");
+ $pagename = preg_replace('!([./][^./]+)\\.html$!', '$1', $pagename);
+ if ($pagename == '') return $DefaultPage;
+ $p = MakePageName($DefaultPage, $pagename);
+ if (!preg_match("/^($GroupPattern)[.\\/]($NamePattern)$/i", $p)) {
+ header('HTTP/1.1 404 Not Found');
+ Abort('$[?invalid page name]');
+ }
+ if (preg_match("/^($GroupPattern)[.\\/]($NamePattern)$/i", $pagename))
+ return $p;
+ if (IsEnabled($EnableFixedUrlRedirect, 1)
+ && $p && (PageExists($p) || preg_match('/[\\/.]/', $pagename)))
+ { Redirect($p); exit(); }
+ return MakePageName($DefaultPage, "$pagename.$pagename");
+}
+
+## MakePageName is used to convert a string $str into a fully-qualified
+## pagename. If $str doesn't contain a group qualifier, then
+## MakePageName uses $basepage and $PagePathFmt to determine the
+## group of the returned pagename.
+function MakePageName($basepage, $str) {
+ global $MakePageNameFunction, $PageNameChars, $PagePathFmt,
+ $MakePageNamePatterns;
+ if (@$MakePageNameFunction) return $MakePageNameFunction($basepage, $str);
+ SDV($PageNameChars,'-[:alnum:]');
+ SDV($MakePageNamePatterns, array(
+ "/'/" => '', # strip single-quotes
+ "/[^$PageNameChars]+/" => ' ', # convert everything else to space
+ '/((^|[^-\\w])\\w)/e' => "strtoupper('$1')",
+ '/ /' => ''));
+ $str = preg_replace('/[#?].*$/', '', $str);
+ $m = preg_split('/[.\\/]/', $str);
+ if (count($m)<1 || count($m)>2 || $m[0]=='') return '';
+ ## handle "Group.Name" conversions
+ if (@$m[1] > '') {
+ $group = preg_replace(array_keys($MakePageNamePatterns),
+ array_values($MakePageNamePatterns), $m[0]);
+ $name = preg_replace(array_keys($MakePageNamePatterns),
+ array_values($MakePageNamePatterns), $m[1]);
+ return "$group.$name";
+ }
+ $name = preg_replace(array_keys($MakePageNamePatterns),
+ array_values($MakePageNamePatterns), $m[0]);
+ $isgrouphome = count($m) > 1;
+ foreach((array)$PagePathFmt as $pg) {
+ if ($isgrouphome && strncmp($pg, '$1.', 3) !== 0) continue;
+ $pn = FmtPageName(str_replace('$1', $name, $pg), $basepage);
+ if (PageExists($pn)) return $pn;
+ }
+ if ($isgrouphome) {
+ foreach((array)$PagePathFmt as $pg)
+ if (strncmp($pg, '$1.', 3) == 0)
+ return FmtPageName(str_replace('$1', $name, $pg), $basepage);
+ return "$name.$name";
+ }
+ return preg_replace('/[^\\/.]+$/', $name, $basepage);
+}
+
+
+## MakeBaseName uses $BaseNamePatterns to return the "base" form
+## of a given pagename -- i.e., stripping any recipe-defined
+## prefixes or suffixes from the page.
+function MakeBaseName($pagename, $patlist = NULL) {
+ global $BaseNamePatterns;
+ if (is_null($patlist)) $patlist = (array)@$BaseNamePatterns;
+ foreach($patlist as $pat => $rep)
+ $pagename = preg_replace($pat, $rep, $pagename);
+ return $pagename;
+}
+
+
+## PCache caches basic information about a page and its attributes--
+## usually everything except page text and page history. This makes
+## for quicker access to certain values in PageVar below.
+function PCache($pagename, $page) {
+ global $PCache;
+ foreach($page as $k=>$v)
+ if ($k!='text' && strpos($k,':')===false) $PCache[$pagename][$k]=$v;
+}
+
+## SetProperty saves a page property into $PCache. For convenience
+## it returns the $value of the property just set. If $sep is supplied,
+## then $value is appended to the current property (with $sep as
+## as separator) instead of replacing it. If $keep is suplied and the
+## property already exists, then $value will be ignored.
+function SetProperty($pagename, $prop, $value, $sep=NULL, $keep=NULL) {
+ global $PCache, $KeepToken;
+ NoCache();
+ $prop = "=p_$prop";
+ $value = preg_replace("/$KeepToken(\\d.*?)$KeepToken/e",
+ "\$GLOBALS['KPV']['$1']", $value);
+ if (!is_null($sep) && isset($PCache[$pagename][$prop]))
+ $value = $PCache[$pagename][$prop] . $sep . $value;
+ if (is_null($keep) || !isset($PCache[$pagename][$prop]))
+ $PCache[$pagename][$prop] = $value;
+ return $PCache[$pagename][$prop];
+}
+
+
+## PageTextVar loads a page's text variables (defined by
+## $PageTextVarPatterns) into a page's $PCache entry, and returns
+## the property associated with $var.
+function PageTextVar($pagename, $var) {
+ global $PCache, $PageTextVarPatterns, $MaxPageTextVars;
+ SDV($MaxPageTextVars, 500);
+ static $status;
+ if(@$status["$pagename:$var"]++ > $MaxPageTextVars) return '';
+ if (!@$PCache[$pagename]['=pagetextvars']) {
+ $pc = &$PCache[$pagename];
+ $pc['=pagetextvars'] = 1;
+ $page = RetrieveAuthPage($pagename, 'read', false, READPAGE_CURRENT);
+ if ($page) {
+ foreach((array)$PageTextVarPatterns as $pat)
+ if (preg_match_all($pat, IsEnabled($PCache[$pagename]['=preview'],@$page['text']),
+ $match, PREG_SET_ORDER))
+ foreach($match as $m) {
+ $t = preg_replace("/\\{\\$:{$m[2]}\\}/", '', $m[3]);
+ $pc["=p_{$m[2]}"] = Qualify($pagename, $t);
+ }
+ }
+ }
+ return @$PCache[$pagename]["=p_$var"];
+}
+
+
+function PageVar($pagename, $var, $pn = '') {
+ global $Cursor, $PCache, $FmtPV, $AsSpacedFunction, $ScriptUrl,
+ $EnablePathInfo;
+ if ($var == '$ScriptUrl') return PUE($ScriptUrl);
+ if ($pn) {
+ $pn = isset($Cursor[$pn]) ? $Cursor[$pn] : MakePageName($pagename, $pn);
+ } else $pn = $pagename;
+ if ($pn) {
+ if (preg_match('/^(.+)[.\\/]([^.\\/]+)$/', $pn, $match)
+ && !isset($PCache[$pn]['time'])
+ && (!@$FmtPV[$var] || strpos($FmtPV[$var], '$page') !== false))
+ { $page = ReadPage($pn, READPAGE_CURRENT); PCache($pn, $page); }
+ @list($d, $group, $name) = $match;
+ $page = &$PCache[$pn];
+ } else { $group = ''; $name = ''; }
+ if (@$FmtPV[$var]) return eval("return ({$FmtPV[$var]});");
+ if (strncmp($var, '$:', 2)==0) return PageTextVar($pn, substr($var, 2));
+ return '';
+}
+
+
+## FmtPageName handles $[internationalization] and $Variable
+## substitutions in strings based on the $pagename argument.
+function FmtPageName($fmt, $pagename) {
+ # Perform $-substitutions on $fmt relative to page given by $pagename
+ global $GroupPattern, $NamePattern, $EnablePathInfo, $ScriptUrl,
+ $GCount, $UnsafeGlobals, $FmtV, $FmtP, $FmtPV, $PCache, $AsSpacedFunction;
+ if (strpos($fmt,'$')===false) return $fmt;
+ $fmt = preg_replace('/\\$([A-Z]\\w*Fmt)\\b/e','$GLOBALS[\'$1\']',$fmt);
+ $fmt = preg_replace('/\\$\\[(?>([^\\]]+))\\]/e',"XL(PSS('$1'))",$fmt);
+ $fmt = str_replace('{$ScriptUrl}', '$ScriptUrl', $fmt);
+ $fmt =
+ preg_replace('/\\{(\\$[A-Z]\\w+)\\}/e', "PageVar(\$pagename, '$1')", $fmt);
+ if (strpos($fmt,'$')===false) return $fmt;
+ if ($FmtP) $fmt = preg_replace(array_keys($FmtP), array_values($FmtP), $fmt);
+ static $pv, $pvpat;
+ if ($pv != count($FmtPV)) {
+ $pvpat = str_replace('$', '\\$', implode('|', array_keys($FmtPV)));
+ $pv = count($FmtPV);
+ }
+ $fmt = preg_replace("/(?:$pvpat)\\b/e", "PageVar(\$pagename, '$0')", $fmt);
+ $fmt = preg_replace('!\\$ScriptUrl/([^?#\'"\\s<>]+)!e',
+ (@$EnablePathInfo) ? "'$ScriptUrl/'.PUE('$1')" :
+ "'$ScriptUrl?n='.str_replace('/','.',PUE('$1'))",
+ $fmt);
+ if (strpos($fmt,'$')===false) return $fmt;
+ static $g;
+ if ($GCount != count($GLOBALS)+count($FmtV)) {
+ $g = array();
+ foreach($GLOBALS as $n=>$v) {
+ if (is_array($v) || is_object($v) ||
+ isset($FmtV["\$$n"]) || in_array($n,$UnsafeGlobals)) continue;
+ $g["\$$n"] = $v;
+ }
+ $GCount = count($GLOBALS)+count($FmtV);
+ krsort($g); reset($g);
+ }
+ $fmt = str_replace(array_keys($g),array_values($g),$fmt);
+ $fmt = preg_replace('/(?>(\\$[[:alpha:]]\\w+))/e',
+ "isset(\$FmtV['$1']) ? \$FmtV['$1'] : '$1'", $fmt);
+ return $fmt;
+}
+
+## FmtTemplateVars uses $vars to replace all occurrences of
+## {$$key} in $text with $vars['key'].
+function FmtTemplateVars($text, $vars, $pagename = NULL) {
+ global $FmtPV;
+ if ($pagename) {
+ $pat = implode('|', array_map('preg_quote', array_keys($FmtPV)));
+ $text = preg_replace("/\\{\\$($pat)\\}/e",
+ "PageVar('$pagename', '$1')", $text);
+ }
+ foreach(preg_grep('/^[\\w$]/', array_keys($vars)) as $k)
+ if (!is_array($vars[$k]))
+ $text = str_replace("{\$\$$k}", $vars[$k], $text);
+ return $text;
+}
+
+## The XL functions provide translation tables for $[i18n] strings
+## in FmtPageName().
+function XL($key) {
+ global $XL,$XLLangs;
+ foreach($XLLangs as $l) if (isset($XL[$l][$key])) return $XL[$l][$key];
+ return $key;
+}
+function XLSDV($lang,$a) {
+ global $XL;
+ foreach($a as $k=>$v) { if (!isset($XL[$lang][$k])) $XL[$lang][$k]=$v; }
+}
+function XLPage($lang,$p) {
+ global $TimeFmt,$XLLangs,$FarmD;
+ $page = ReadPage($p, READPAGE_CURRENT);
+ if (!$page) return;
+ $text = preg_replace("/=>\\s*\n/",'=> ',@$page['text']);
+ foreach(explode("\n",$text) as $l)
+ if (preg_match('/^\\s*[\'"](.+?)[\'"]\\s*=>\\s*[\'"](.+)[\'"]/',$l,$match))
+ $xl[stripslashes($match[1])] = stripslashes($match[2]);
+ if (isset($xl)) {
+ if (@$xl['xlpage-i18n']) {
+ $i18n = preg_replace('/[^-\\w]/','',$xl['xlpage-i18n']);
+ include_once("$FarmD/scripts/xlpage-$i18n.php");
+ }
+ if (@$xl['Locale']) setlocale(LC_ALL,$xl['Locale']);
+ if (@$xl['TimeFmt']) $TimeFmt=$xl['TimeFmt'];
+ if (!in_array($lang, $XLLangs)) array_unshift($XLLangs, $lang);
+ XLSDV($lang,$xl);
+ }
+}
+
+## CmpPageAttr is used with uksort to order a page's elements with
+## the latest items first. This can make some operations more efficient.
+function CmpPageAttr($a, $b) {
+ @list($x, $agmt) = explode(':', $a);
+ @list($x, $bgmt) = explode(':', $b);
+ if ($agmt != $bgmt)
+ return ($agmt==0 || $bgmt==0) ? $agmt - $bgmt : $bgmt - $agmt;
+ return strcmp($a, $b);
+}
+
+## class PageStore holds objects that store pages via the native
+## filesystem.
+class PageStore {
+ var $dirfmt;
+ var $iswrite;
+ var $attr;
+ function PageStore($d='$WorkDir/$FullName', $w=0, $a=NULL) {
+ $this->dirfmt = $d; $this->iswrite = $w; $this->attr = (array)$a;
+ $GLOBALS['PageExistsCache'] = array();
+ }
+ function pagefile($pagename) {
+ global $FarmD;
+ $dfmt = $this->dirfmt;
+ if ($pagename > '') {
+ $pagename = str_replace('/', '.', $pagename);
+ if ($dfmt == 'wiki.d/{$FullName}') # optimizations for
+ return "wiki.d/$pagename"; # standard locations
+ if ($dfmt == '$FarmD/wikilib.d/{$FullName}') #
+ return "$FarmD/wikilib.d/$pagename"; #
+ if ($dfmt == 'wiki.d/{$Group}/{$FullName}')
+ return preg_replace('/([^.]+).*/', 'wiki.d/$1/$0', $pagename);
+ }
+ return FmtPageName($dfmt, $pagename);
+ }
+ function read($pagename, $since=0) {
+ $newline = '';
+ $urlencoded = false;
+ $pagefile = $this->pagefile($pagename);
+ if ($pagefile && ($fp=@fopen($pagefile, "r"))) {
+ $page = $this->attr;
+ while (!feof($fp)) {
+ $line = fgets($fp, 4096);
+ while (substr($line, -1, 1) != "\n" && !feof($fp))
+ { $line .= fgets($fp, 4096); }
+ $line = rtrim($line);
+ if ($urlencoded) $line = urldecode(str_replace('+', '%2b', $line));
+ @list($k,$v) = explode('=', $line, 2);
+ if (!$k) continue;
+ if ($k == 'version') {
+ $ordered = (strpos($v, 'ordered=1') !== false);
+ $urlencoded = (strpos($v, 'urlencoded=1') !== false);
+ if (strpos($v, 'pmwiki-0.')!==false) $newline="\262";
+ }
+ if ($k == 'newline') { $newline = $v; continue; }
+ if ($since > 0 && preg_match('/:(\\d+)/', $k, $m) && $m[1] < $since) {
+ if ($ordered) break;
+ continue;
+ }
+ if ($newline) $v = str_replace($newline, "\n", $v);
+ $page[$k] = $v;
+ }
+ fclose($fp);
+ }
+ return @$page;
+ }
+ function write($pagename,$page) {
+ global $Now, $Version;
+ $page['name'] = $pagename;
+ $page['time'] = $Now;
+ $page['host'] = $_SERVER['REMOTE_ADDR'];
+ $page['agent'] = @$_SERVER['HTTP_USER_AGENT'];
+ $page['rev'] = @$page['rev']+1;
+ unset($page['version']); unset($page['newline']);
+ uksort($page, 'CmpPageAttr');
+ $s = false;
+ $pagefile = $this->pagefile($pagename);
+ $dir = dirname($pagefile); mkdirp($dir);
+ if (!file_exists("$dir/.htaccess") && $fp = @fopen("$dir/.htaccess", "w"))
+ { fwrite($fp, "Order Deny,Allow\nDeny from all\n"); fclose($fp); }
+ if ($pagefile && ($fp=fopen("$pagefile,new","w"))) {
+ $r0 = array('%', "\n", '<');
+ $r1 = array('%25', '%0a', '%3c');
+ $x = "version=$Version ordered=1 urlencoded=1\n";
+ $s = true && fputs($fp, $x); $sz = strlen($x);
+ foreach($page as $k=>$v)
+ if ($k > '' && $k{0} != '=') {
+ $x = str_replace($r0, $r1, "$k=$v") . "\n";
+ $s = $s && fputs($fp, $x); $sz += strlen($x);
+ }
+ $s = fclose($fp) && $s;
+ $s = $s && (filesize("$pagefile,new") > $sz * 0.95);
+ if (file_exists($pagefile)) $s = $s && unlink($pagefile);
+ $s = $s && rename("$pagefile,new", $pagefile);
+ }
+ $s && fixperms($pagefile);
+ if (!$s)
+ Abort("Cannot write page to $pagename ($pagefile)...changes not saved");
+ PCache($pagename, $page);
+ }
+ function exists($pagename) {
+ if (!$pagename) return false;
+ $pagefile = $this->pagefile($pagename);
+ return ($pagefile && file_exists($pagefile));
+ }
+ function delete($pagename) {
+ global $Now;
+ $pagefile = $this->pagefile($pagename);
+ @rename($pagefile,"$pagefile,del-$Now");
+ }
+ function ls($pats=NULL) {
+ global $GroupPattern, $NamePattern;
+ StopWatch("PageStore::ls begin {$this->dirfmt}");
+ $pats=(array)$pats;
+ array_push($pats, "/^$GroupPattern\.$NamePattern$/");
+ $dir = $this->pagefile('$Group.$Name');
+ $maxslash = substr_count($dir, '/');
+ $dirlist = array(preg_replace('!/*[^/]*\\$.*$!','',$dir));
+ $out = array();
+ while (count($dirlist)>0) {
+ $dir = array_shift($dirlist);
+ $dfp = @opendir($dir); if (!$dfp) { continue; }
+ $dirslash = substr_count($dir, '/') + 1;
+ $o = array();
+ while ( ($pagefile = readdir($dfp)) !== false) {
+ if ($pagefile{0} == '.') continue;
+ if ($dirslash < $maxslash && is_dir("$dir/$pagefile"))
+ { array_push($dirlist,"$dir/$pagefile"); continue; }
+ if ($dirslash == $maxslash) $o[] = $pagefile;
+ }
+ closedir($dfp);
+ StopWatch("PageStore::ls merge {$this->dirfmt}");
+ $out = array_merge($out, MatchPageNames($o, $pats));
+ }
+ StopWatch("PageStore::ls end {$this->dirfmt}");
+ return $out;
+ }
+}
+
+function ReadPage($pagename, $since=0) {
+ # read a page from the appropriate directories given by $WikiReadDirsFmt.
+ global $WikiLibDirs,$Now;
+ foreach ($WikiLibDirs as $dir) {
+ $page = $dir->read($pagename, $since);
+ if ($page) break;
+ }
+ if (@!$page) $page['ctime'] = $Now;
+ if (@!$page['time']) $page['time'] = $Now;
+ return $page;
+}
+
+function WritePage($pagename,$page) {
+ global $WikiLibDirs,$WikiDir,$LastModFile;
+ $WikiDir->iswrite = 1;
+ for($i=0; $iiswrite && $wd->exists($pagename)) break;
+ }
+ if ($i >= count($WikiLibDirs)) $wd = &$WikiDir;
+ $wd->write($pagename,$page);
+ if ($LastModFile && !@touch($LastModFile))
+ { unlink($LastModFile); touch($LastModFile); fixperms($LastModFile); }
+}
+
+function PageExists($pagename) {
+ ## note: $PageExistsCache might change or disappear someday
+ global $WikiLibDirs, $PageExistsCache;
+ if (!isset($PageExistsCache[$pagename])) {
+ foreach((array)$WikiLibDirs as $dir)
+ if ($PageExistsCache[$pagename] = $dir->exists($pagename)) break;
+ }
+ return $PageExistsCache[$pagename];
+}
+
+function ListPages($pat=NULL) {
+ global $WikiLibDirs;
+ foreach((array)$WikiLibDirs as $dir)
+ $out = array_unique(array_merge($dir->ls($pat),(array)@$out));
+ return $out;
+}
+
+function RetrieveAuthPage($pagename, $level, $authprompt=true, $since=0) {
+ global $AuthFunction;
+ SDV($AuthFunction,'PmWikiAuth');
+ if (!function_exists($AuthFunction)) return ReadPage($pagename, $since);
+ return $AuthFunction($pagename, $level, $authprompt, $since);
+}
+
+function Abort($msg, $info='') {
+ # exit pmwiki with an abort message
+ global $ScriptUrl, $Charset;
+ if ($info)
+ $info = "$[More information]
";
+ $msg = "$[PmWiki can't process your request]
+ $msg
+ $[We are sorry for any inconvenience].
+ $info
+ $[Return to] $ScriptUrl
";
+ @header("Content-type: text/html; charset=$Charset");
+ echo preg_replace('/\\$\\[([^\\]]+)\\]/e', "XL(PSS('$1'))", $msg);
+ exit;
+}
+
+function Redirect($pagename, $urlfmt='$PageUrl') {
+ # redirect the browser to $pagename
+ global $EnableRedirect, $RedirectDelay, $EnableStopWatch;
+ SDV($RedirectDelay, 0);
+ clearstatcache();
+ $pageurl = FmtPageName($urlfmt,$pagename);
+ if (IsEnabled($EnableRedirect,1) &&
+ (!isset($_REQUEST['redirect']) || $_REQUEST['redirect'])) {
+ header("Location: $pageurl");
+ header("Content-type: text/html");
+ echo "
+
+ Redirect ";
+ exit;
+ }
+ echo "Redirect to $pageurl ";
+ if (@$EnableStopWatch && function_exists('StopWatchHTML'))
+ StopWatchHTML($pagename, 1);
+ exit;
+}
+
+function PrintFmt($pagename,$fmt) {
+ global $HTTPHeaders,$FmtV;
+ if (is_array($fmt))
+ { foreach($fmt as $f) PrintFmt($pagename,$f); return; }
+ if ($fmt == 'headers:') {
+ foreach($HTTPHeaders as $h) (@$sent++) ? @header($h) : header($h);
+ return;
+ }
+ $x = FmtPageName($fmt,$pagename);
+ if (strncmp($fmt, 'function:', 9) == 0 &&
+ preg_match('/^function:(\S+)\s*(.*)$/s', $x, $match) &&
+ function_exists($match[1]))
+ { $match[1]($pagename,$match[2]); return; }
+ if (strncmp($fmt, 'file:', 5) == 0 && preg_match("/^file:(.+)/s",$x,$match)) {
+ $filelist = preg_split('/[\\s]+/',$match[1],-1,PREG_SPLIT_NO_EMPTY);
+ foreach($filelist as $f) {
+ if (file_exists($f)) { include($f); return; }
+ }
+ return;
+ }
+ if (substr($x, 0, 7) == 'markup:')
+ { print MarkupToHTML($pagename, substr($x, 7)); return; }
+ if (substr($x, 0, 5) == 'wiki:')
+ { PrintWikiPage($pagename, substr($x, 5), 'read'); return; }
+ if (substr($x, 0, 5) == 'page:')
+ { PrintWikiPage($pagename, substr($x, 5), ''); return; }
+ echo $x;
+}
+
+function PrintWikiPage($pagename, $wikilist=NULL, $auth='read') {
+ if (is_null($wikilist)) $wikilist=$pagename;
+ $pagelist = preg_split('/\s+/',$wikilist,-1,PREG_SPLIT_NO_EMPTY);
+ foreach($pagelist as $p) {
+ if (PageExists($p)) {
+ $page = ($auth) ? RetrieveAuthPage($p, $auth, false, READPAGE_CURRENT)
+ : ReadPage($p, READPAGE_CURRENT);
+ if ($page['text'])
+ echo MarkupToHTML($pagename,Qualify($p, $page['text']));
+ return;
+ }
+ }
+}
+
+function Keep($x, $pool=NULL) {
+ # Keep preserves a string from being processed by wiki markups
+ global $BlockPattern, $KeepToken, $KPV, $KPCount;
+ $x = preg_replace("/$KeepToken(\\d.*?)$KeepToken/e", "\$KPV['\$1']", $x);
+ if (is_null($pool) && preg_match("!?($BlockPattern)\\b!", $x)) $pool = 'B';
+ $KPCount++; $KPV[$KPCount.$pool]=$x;
+ return $KeepToken.$KPCount.$pool.$KeepToken;
+}
+
+
+## MarkupEscape examines markup source and escapes any [@...@]
+## and [=...=] sequences using Keep(). MarkupRestore undoes the
+## effect of any MarkupEscape().
+function MarkupEscape($text) {
+ global $EscapePattern;
+ SDV($EscapePattern, '\\[([=@]).*?\\1\\]');
+ return preg_replace("/$EscapePattern/es", "Keep(PSS('$0'))", $text);
+}
+function MarkupRestore($text) {
+ global $KeepToken, $KPV;
+ return preg_replace("/$KeepToken(\\d.*?)$KeepToken/e", "\$KPV['$1']", $text);
+}
+
+
+## Qualify() applies $QualifyPatterns to convert relative links
+## and references into absolute equivalents.
+function Qualify($pagename, $text) {
+ global $QualifyPatterns, $KeepToken, $KPV;
+ if (!@$QualifyPatterns) return $text;
+ $text = MarkupEscape($text);
+ $group = PageVar($pagename, '$Group');
+ $name = PageVar($pagename, '$Name');
+ foreach((array)$QualifyPatterns as $pat => $rep)
+ $text = preg_replace($pat, $rep, $text);
+ return MarkupRestore($text);
+}
+
+
+function CondText($pagename,$condspec,$condtext) {
+ global $Conditions;
+ if (!preg_match("/^(\\S+)\\s*(!?)\\s*(\\S+)?\\s*(.*?)\\s*$/",
+ $condspec,$match)) return '';
+ @list($condstr,$condtype,$not,$condname,$condparm) = $match;
+ if (isset($Conditions[$condname])) {
+ $tf = @eval("return (".$Conditions[$condname].");");
+ if (!$tf xor $not) $condtext='';
+ }
+ return $condtext;
+}
+
+
+## TextSection extracts a section of text delimited by page anchors.
+## The $sections parameter can have the form
+## #abc - [[#abc]] to next anchor
+## #abc#def - [[#abc]] up to [[#def]]
+## #abc#, #abc.. - [[#abc]] to end of text
+## ##abc, #..#abc - beginning of text to [[#abc]]
+## Returns the text unchanged if no sections are requested,
+## or false if a requested beginning anchor isn't in the text.
+function TextSection($text, $sections, $args = NULL) {
+ $args = (array)$args;
+ $npat = '[[:alpha:]][-\\w*]*';
+ if (!preg_match("/#($npat)?(\\.\\.)?(#($npat)?)?/", $sections, $match))
+ return $text;
+ @list($x, $aa, $dots, $b, $bb) = $match;
+ if (!$dots && !$b) $bb = $npat;
+ if ($aa) {
+ $pos = strpos($text, "[[#$aa]]"); if ($pos === false) return false;
+ if (@$args['anchors'])
+ while ($pos > 0 && $text[$pos-1] != "\n") $pos--;
+ else $pos += strlen("[[#$aa]]");
+ $text = substr($text, $pos);
+ }
+ if ($bb)
+ $text = preg_replace("/(\n)[^\n]*\\[\\[#$bb\\]\\].*$/s", '$1', $text, 1);
+ return $text;
+}
+
+
+## RetrieveAuthSection extracts a section of text from a page.
+## If $pagesection starts with anything other than '#', it identifies
+## the page to extract text from. Otherwise RetrieveAuthSection looks
+## in the pages given by $list, or in $pagename if $list is not specified.
+## The selected page is placed in the global $RASPageName variable.
+## The caller is responsible for calling Qualify() as needed.
+function RetrieveAuthSection($pagename, $pagesection, $list=NULL, $auth='read') {
+ global $RASPageName, $PCache;
+ if ($pagesection{0} != '#')
+ $list = array(MakePageName($pagename, $pagesection));
+ else if (is_null($list)) $list = array($pagename);
+ foreach((array)$list as $t) {
+ $t = FmtPageName($t, $pagename);
+ if (!PageExists($t)) continue;
+ $tpage = RetrieveAuthPage($t, $auth, false, READPAGE_CURRENT);
+ if (!$tpage) continue;
+ $text = TextSection(IsEnabled($PCache[$t]['=preview'],$tpage['text']),$pagesection);
+ if ($text !== false) { $RASPageName = $t; return $text; }
+ }
+ $RASPageName = '';
+ return false;
+}
+
+function IncludeText($pagename, $inclspec) {
+ global $MaxIncludes, $IncludeOpt, $InclCount, $PCache;
+ SDV($MaxIncludes,50);
+ SDVA($IncludeOpt, array('self'=>1));
+ $npat = '[[:alpha:]][-\\w]*';
+ if ($InclCount++>=$MaxIncludes) return Keep($inclspec);
+ $args = array_merge($IncludeOpt, ParseArgs($inclspec));
+ while (count($args['#'])>0) {
+ $k = array_shift($args['#']); $v = array_shift($args['#']);
+ if ($k=='') {
+ if ($v{0} != '#') {
+ if (isset($itext)) continue;
+ $iname = MakePageName($pagename, $v);
+ if (!$args['self'] && $iname == $pagename) continue;
+ $ipage = RetrieveAuthPage($iname, 'read', false, READPAGE_CURRENT);
+ $itext = IsEnabled($PCache[$iname]['=preview'], @$ipage['text']);
+ }
+ $itext = TextSection($itext, $v, array('anchors' => 1));
+ continue;
+ }
+ if (preg_match('/^(?:line|para)s?$/', $k)) {
+ preg_match('/^(\\d*)(\\.\\.(\\d*))?$/', $v, $match);
+ @list($x, $a, $dots, $b) = $match;
+ $upat = ($k{0} == 'p') ? ".*?(\n\\s*\n|$)" : "[^\n]*(?:\n|$)";
+ if (!$dots) { $b=$a; $a=0; }
+ if ($a>0) $a--;
+ $itext=preg_replace("/^(($upat){0,$b}).*$/s",'$1',$itext,1);
+ $itext=preg_replace("/^($upat){0,$a}/s",'',$itext,1);
+ continue;
+ }
+ }
+ $basepage = isset($args['basepage'])
+ ? MakePageName($pagename, $args['basepage'])
+ : $iname;
+ if ($basepage) $itext = Qualify(@$basepage, @$itext);
+ return FmtTemplateVars(PVSE($itext), $args);
+}
+
+
+function RedirectMarkup($pagename, $opt) {
+ $k = Keep("(:redirect $opt:)");
+ global $MarkupFrame, $EnableRedirectQuiet;
+ if (!@$MarkupFrame[0]['redirect']) return $k;
+ $opt = ParseArgs($opt);
+ $to = @$opt['to']; if (!$to) $to = @$opt[''][0];
+ if (!$to) return $k;
+ if (preg_match('/^([^#]+)(#[A-Za-z][-\\w]*)$/', $to, $match))
+ { $to = $match[1]; $anchor = @$match[2]; }
+ $to = MakePageName($pagename, $to);
+ if (!PageExists($to)) return $k;
+ if ($to == $pagename) return '';
+ if (@$opt['from']
+ && !MatchPageNames($pagename, FixGlob($opt['from'], '$1*.$2')))
+ return '';
+ if (preg_match('/^30[1237]$/', @$opt['status']))
+ header("HTTP/1.1 {$opt['status']}");
+ Redirect($to, "{\$PageUrl}"
+ . (IsEnabled($EnableRedirectQuiet, 0) && IsEnabled($opt['quiet'], 0)
+ ? '' : "?from=$pagename")
+ . $anchor);
+ exit();
+}
+
+
+function Block($b) {
+ global $BlockMarkups,$HTMLVSpace,$HTMLPNewline,$MarkupFrame;
+ $mf = &$MarkupFrame[0]; $cs = &$mf['cs']; $vspaces = &$mf['vs'];
+ $out = '';
+ if ($b == 'vspace') {
+ $vspaces .= "\n";
+ while (count($cs)>0 && @end($cs)!='pre' && @$BlockMarkups[@end($cs)][3]==0)
+ { $c = array_pop($cs); $out .= $BlockMarkups[$c][2]; }
+ return $out;
+ }
+ @list($code, $depth, $icol) = explode(',', $b);
+ if (!$code) $depth = 1;
+ if ($depth == 0) $depth = strlen($depth);
+ if ($icol == 0) $icol = strlen($icol);
+ if ($depth > 0) $depth += @$mf['idep'];
+ if ($icol > 0) $mf['is'][$depth] = $icol + @$mf['icol'];
+ @$mf['idep'] = @$mf['icol'] = 0;
+ while (count($cs)>$depth)
+ { $c = array_pop($cs); $out .= $BlockMarkups[$c][2]; }
+ if (!$code) {
+ if (@end($cs) == 'p') { $out .= $HTMLPNewline; $code = 'p'; }
+ else if ($depth < 2) { $code = 'p'; $mf['is'][$depth] = 0; }
+ else { $out .= $HTMLPNewline; $code = 'block'; }
+ }
+ if ($depth>0 && $depth==count($cs) && $cs[$depth-1]!=$code)
+ { $c = array_pop($cs); $out .= $BlockMarkups[$c][2]; }
+ while (count($cs)>0 && @end($cs)!=$code &&
+ @$BlockMarkups[@end($cs)][3]==0)
+ { $c = array_pop($cs); $out .= $BlockMarkups[$c][2]; }
+ if ($vspaces) {
+ $out .= (@end($cs) == 'pre') ? $vspaces : $HTMLVSpace;
+ $vspaces='';
+ }
+ if ($depth==0) { return $out; }
+ if ($depth==count($cs)) { return $out.$BlockMarkups[$code][1]; }
+ while (count($cs)<$depth-1) {
+ array_push($cs, 'dl'); $mf['is'][count($cs)] = 0;
+ $out .= $BlockMarkups['dl'][0].'';
+ }
+ if (count($cs)<$depth) {
+ array_push($cs,$code);
+ $out .= $BlockMarkups[$code][0];
+ }
+ return $out;
+}
+
+
+function MarkupClose($key = '') {
+ global $MarkupFrame;
+ $cf = & $MarkupFrame[0]['closeall'];
+ $out = '';
+ if ($key == '' || isset($cf[$key])) {
+ $k = array_keys((array)$cf);
+ while ($k) {
+ $x = array_pop($k); $out .= $cf[$x]; unset($cf[$x]);
+ if ($x == $key) break;
+ }
+ }
+ return $out;
+}
+
+
+function FormatTableRow($x, $sep = '\\|\\|') {
+ global $Block, $TableCellAttrFmt, $MarkupFrame, $TableRowAttrFmt,
+ $TableRowIndexMax, $FmtV;
+ static $rowcount;
+ $x = preg_replace("/$sep\\s*$/",'',$x);
+ $td = preg_split("/$sep/", $x); $y = '';
+ for($i=0;$i1) { $attr .= " colspan='$colspan'"; }
+ $y .= "<$t $attr>".trim($td[$i])."$t>";
+ }
+ if ($t=='caption') return "<:table,1>$y";
+ if (@$MarkupFrame[0]['cs'][0] != 'table') $rowcount = 0; else $rowcount++;
+ $FmtV['$TableRowCount'] = $rowcount + 1;
+ $FmtV['$TableRowIndex'] = ($rowcount % $TableRowIndexMax) + 1;
+ $trattr = FmtPageName(@$TableRowAttrFmt, '');
+ return "<:table,1>$y ";
+}
+
+function LinkIMap($pagename,$imap,$path,$alt,$txt,$fmt=NULL) {
+ global $FmtV, $IMap, $IMapLinkFmt, $UrlLinkFmt;
+ $FmtV['$LinkUrl'] = PUE(str_replace('$1',$path,$IMap[$imap]));
+ $FmtV['$LinkText'] = $txt;
+ $FmtV['$LinkAlt'] = str_replace(array('"',"'"),array('"','''),$alt);
+ if (!$fmt)
+ $fmt = (isset($IMapLinkFmt[$imap])) ? $IMapLinkFmt[$imap] : $UrlLinkFmt;
+ return str_replace(array_keys($FmtV),array_values($FmtV),$fmt);
+}
+
+function LinkPage($pagename,$imap,$path,$alt,$txt,$fmt=NULL) {
+ global $QueryFragPattern, $LinkPageExistsFmt, $LinkPageSelfFmt,
+ $LinkPageCreateSpaceFmt, $LinkPageCreateFmt, $LinkTargets,
+ $EnableLinkPageRelative;
+ if (!$fmt && $path{0} == '#') {
+ $path = preg_replace("/[^-.:\\w]/", '', $path);
+ return ($path) ? "$txt " : '';
+ }
+ if (!preg_match("/^\\s*([^#?]+)($QueryFragPattern)?$/",$path,$match))
+ return '';
+ $tgtname = MakePageName($pagename, $match[1]);
+ if (!$tgtname) return '';
+ $qf = @$match[2];
+ @$LinkTargets[$tgtname]++;
+ if (!$fmt) {
+ if (!PageExists($tgtname) && !preg_match('/[&?]action=/', $qf))
+ $fmt = preg_match('/\\s/', $txt)
+ ? $LinkPageCreateSpaceFmt : $LinkPageCreateFmt;
+ else
+ $fmt = ($tgtname == $pagename && $qf == '')
+ ? $LinkPageSelfFmt : $LinkPageExistsFmt;
+ }
+ $url = PageVar($tgtname, '$PageUrl');
+ $txt = str_replace("$", "$", $txt);
+ if (@$EnableLinkPageRelative)
+ $url = preg_replace('!^[a-z]+://[^/]*!i', '', $url);
+ $fmt = str_replace(array('$LinkUrl', '$LinkText'),
+ array($url.PUE($qf), $txt), $fmt);
+ return FmtPageName($fmt,$tgtname);
+}
+
+function MakeLink($pagename,$tgt,$txt=NULL,$suffix=NULL,$fmt=NULL) {
+ global $LinkPattern,$LinkFunctions,$UrlExcludeChars,$ImgExtPattern,$ImgTagFmt;
+ $t = preg_replace('/[()]/','',trim($tgt));
+ $t = preg_replace('/<[^>]*>/','',$t);
+ preg_match("/^($LinkPattern)?(.+?)(\"(.*)\")?$/",$t,$m);
+ if (!$m[1]) $m[1]='<:page>';
+ if (preg_match("/(($LinkPattern)([^$UrlExcludeChars]+$ImgExtPattern))(\"(.*)\")?$/",$txt,$tm))
+ $txt = $LinkFunctions[$tm[2]]($pagename,$tm[2],$tm[3],@$tm[5],
+ $tm[1],$ImgTagFmt);
+ else {
+ if (is_null($txt)) {
+ $txt = preg_replace('/\\([^)]*\\)/','',$tgt);
+ if ($m[1]=='<:page>') {
+ $txt = preg_replace('!/\\s*$!', '', $txt);
+ $txt = preg_replace('!^.*[^<]/!', '', $txt);
+ }
+ }
+ $txt .= $suffix;
+ }
+ $out = $LinkFunctions[$m[1]]($pagename,$m[1],$m[2],@$m[4],$txt,$fmt);
+ return $out;
+}
+
+function Markup($id, $when, $pat=NULL, $rep=NULL) {
+ global $MarkupTable;
+ unset($GLOBALS['MarkupRules']);
+ if (preg_match('/^([<>])?(.+)$/', $when, $m)) {
+ $MarkupTable[$id]['cmd'] = $when;
+ $MarkupTable[$m[2]]['dep'][$id] = $m[1];
+ if (!$m[1]) $m[1] = '=';
+ if (@$MarkupTable[$m[2]]['seq']) {
+ $MarkupTable[$id]['seq'] = $MarkupTable[$m[2]]['seq'].$m[1];
+ foreach((array)@$MarkupTable[$id]['dep'] as $i=>$m)
+ Markup($i,"$m$id");
+ unset($GLOBALS['MarkupTable'][$id]['dep']);
+ }
+ }
+ if ($pat && !isset($MarkupTable[$id]['pat'])) {
+ $MarkupTable[$id]['pat'] = $pat;
+ $MarkupTable[$id]['rep'] = $rep;
+ }
+}
+
+function DisableMarkup() {
+ global $MarkupTable;
+ $idlist = func_get_args();
+ unset($GLOBALS['MarkupRules']);
+ while (count($idlist)>0) {
+ $id = array_shift($idlist);
+ if (is_array($id)) { $idlist = array_merge($idlist, $id); continue; }
+ $MarkupTable[$id] = array('cmd' => 'none', 'pat'=>'');
+ }
+}
+
+function mpcmp($a,$b) { return @strcmp($a['seq'].'=',$b['seq'].'='); }
+function BuildMarkupRules() {
+ global $MarkupTable,$MarkupRules,$LinkPattern;
+ if (!$MarkupRules) {
+ uasort($MarkupTable,'mpcmp');
+ foreach($MarkupTable as $id=>$m)
+ if (@$m['pat'] && @$m['seq'])
+ $MarkupRules[str_replace('\\L',$LinkPattern,$m['pat'])]=$m['rep'];
+ }
+ return $MarkupRules;
+}
+
+
+function MarkupToHTML($pagename, $text, $opt = NULL) {
+ # convert wiki markup text to HTML output
+ global $MarkupRules, $MarkupFrame, $MarkupFrameBase, $WikiWordCount,
+ $K0, $K1, $RedoMarkupLine;
+
+ StopWatch('MarkupToHTML begin');
+ array_unshift($MarkupFrame, array_merge($MarkupFrameBase, (array)$opt));
+ $MarkupFrame[0]['wwcount'] = $WikiWordCount;
+ foreach((array)$text as $l)
+ $lines[] = $MarkupFrame[0]['escape'] ? PVSE($l) : $l;
+ $lines[] = '(:closeall:)';
+ $out = '';
+ while (count($lines)>0) {
+ $x = array_shift($lines);
+ $RedoMarkupLine=0;
+ $markrules = BuildMarkupRules();
+ foreach($markrules as $p=>$r) {
+ if ($p{0} == '/') $x=preg_replace($p,$r,$x);
+ elseif (strstr($x,$p)!==false) $x=eval($r);
+ if (isset($php_errormsg))
+ { echo "ERROR: pat=$p $php_errormsg"; unset($php_errormsg); }
+ if ($RedoMarkupLine) { $lines=array_merge((array)$x,$lines); continue 2; }
+ }
+ if ($x>'') $out .= "$x\n";
+ }
+ foreach((array)(@$MarkupFrame[0]['posteval']) as $v) eval($v);
+ array_shift($MarkupFrame);
+ StopWatch('MarkupToHTML end');
+ return $out;
+}
+
+function HandleBrowse($pagename, $auth = 'read') {
+ # handle display of a page
+ global $DefaultPageTextFmt, $PageNotFoundHeaderFmt, $HTTPHeaders,
+ $EnableHTMLCache, $NoHTMLCache, $PageCacheFile, $LastModTime, $IsHTMLCached,
+ $FmtV, $HandleBrowseFmt, $PageStartFmt, $PageEndFmt, $PageRedirectFmt;
+ $page = RetrieveAuthPage($pagename, $auth, true, READPAGE_CURRENT);
+ if (!$page) Abort("?cannot read $pagename");
+ PCache($pagename,$page);
+ if (PageExists($pagename)) $text = @$page['text'];
+ else {
+ SDV($DefaultPageTextFmt,'(:include $[{$SiteGroup}.PageNotFound]:)');
+ $text = FmtPageName($DefaultPageTextFmt, $pagename);
+ SDV($PageNotFoundHeaderFmt, 'HTTP/1.1 404 Not Found');
+ SDV($HTTPHeaders['status'], $PageNotFoundHeaderFmt);
+ }
+ $opt = array();
+ SDV($PageRedirectFmt,"($[redirected from] {\$FullName} )
\$HTMLVSpace\n");
+ if (@!$_GET['from']) { $opt['redirect'] = 1; $PageRedirectFmt = ''; }
+ else $PageRedirectFmt = FmtPageName($PageRedirectFmt, $_GET['from']);
+ if (@$EnableHTMLCache && !$NoHTMLCache && $PageCacheFile &&
+ @filemtime($PageCacheFile) > $LastModTime) {
+ list($ctext) = unserialize(file_get_contents($PageCacheFile));
+ $FmtV['$PageText'] = "$ctext";
+ $IsHTMLCached = 1;
+ StopWatch("HandleBrowse: using cached copy");
+ } else {
+ $IsHTMLCached = 0;
+ $text = '(:groupheader:)'.@$text.'(:groupfooter:)';
+ $t1 = time();
+ $FmtV['$PageText'] = MarkupToHTML($pagename, $text, $opt);
+ if (@$EnableHTMLCache > 0 && !$NoHTMLCache && $PageCacheFile
+ && (time() - $t1 + 1) >= $EnableHTMLCache) {
+ $fp = @fopen("$PageCacheFile,new", "x");
+ if ($fp) {
+ StopWatch("HandleBrowse: caching page");
+ fwrite($fp, serialize(array($FmtV['$PageText']))); fclose($fp);
+ rename("$PageCacheFile,new", $PageCacheFile);
+ }
+ }
+ }
+ SDV($HandleBrowseFmt,array(&$PageStartFmt, &$PageRedirectFmt, '$PageText',
+ &$PageEndFmt));
+ PrintFmt($pagename,$HandleBrowseFmt);
+}
+
+
+## UpdatePage goes through all of the steps needed to update a page,
+## preserving page history, computing link targets, page titles,
+## and other page attributes. It does this by calling each entry
+## in $EditFunctions. $pagename is the name of the page to be updated,
+## $page is the old version of the page (used for page history),
+## $new is the new version of the page to be saved, and $fnlist is
+## an optional list of functions to use instead of $EditFunctions.
+function UpdatePage(&$pagename, &$page, &$new, $fnlist = NULL) {
+ global $EditFunctions, $IsPagePosted;
+ StopWatch("UpdatePage: begin $pagename");
+ if (is_null($fnlist)) $fnlist = $EditFunctions;
+ $IsPagePosted = false;
+ foreach((array)$fnlist as $fn) {
+ StopWatch("UpdatePage: $fn ($pagename)");
+ $fn($pagename, $page, $new);
+ }
+ StopWatch("UpdatePage: end $pagename");
+ return $IsPagePosted;
+}
+
+
+# EditTemplate allows a site administrator to pre-populate new pages
+# with the contents of another page.
+function EditTemplate($pagename, &$page, &$new) {
+ global $EditTemplatesFmt;
+ if (@$new['text'] > '') return;
+ if (@$_REQUEST['template'] && PageExists($_REQUEST['template'])) {
+ $p = RetrieveAuthPage($_REQUEST['template'], 'read', false,
+ READPAGE_CURRENT);
+ if ($p['text'] > '') $new['text'] = $p['text'];
+ return;
+ }
+ foreach((array)$EditTemplatesFmt as $t) {
+ $p = RetrieveAuthPage(FmtPageName($t,$pagename), 'read', false,
+ READPAGE_CURRENT);
+ if (@$p['text'] > '') { $new['text'] = $p['text']; return; }
+ }
+}
+
+# RestorePage handles returning to the version of text as of
+# the version given by $restore or $_REQUEST['restore'].
+function RestorePage($pagename,&$page,&$new,$restore=NULL) {
+ if (is_null($restore)) $restore=@$_REQUEST['restore'];
+ if (!$restore) return;
+ $t = $page['text'];
+ $nl = (substr($t,-1)=="\n");
+ $t = explode("\n",$t);
+ if ($nl) array_pop($t);
+ krsort($page); reset($page);
+ foreach($page as $k=>$v) {
+ if ($k<$restore) break;
+ if (strncmp($k, 'diff:', 5) != 0) continue;
+ foreach(explode("\n",$v) as $x) {
+ if (preg_match('/^(\\d+)(,(\\d+))?([adc])(\\d+)/',$x,$match)) {
+ $a1 = $a2 = $match[1];
+ if ($match[3]) $a2=$match[3];
+ $b1 = $match[5];
+ if ($match[4]=='d') array_splice($t,$b1,$a2-$a1+1);
+ if ($match[4]=='c') array_splice($t,$b1-1,$a2-$a1+1);
+ continue;
+ }
+ if (strncmp($x,'< ',2) == 0) { $nlflag=true; continue; }
+ if (preg_match('/^> (.*)$/',$x,$match)) {
+ $nlflag=false;
+ array_splice($t,$b1-1,0,$match[1]); $b1++;
+ }
+ if ($x=='\\ No newline at end of file') $nl=$nlflag;
+ }
+ }
+ if ($nl) $t[]='';
+ $new['text']=implode("\n",$t);
+ $new['=preview'] = $new['text'];
+ PCache($pagename, $new);
+ return $new['text'];
+}
+
+## ReplaceOnSave performs text replacements on the text being posted.
+## Patterns held in $ROEPatterns are replaced on every edit request,
+## patterns held in $ROSPatterns are replaced only when the page
+## is being posted (as signaled by $EnablePost).
+function ReplaceOnSave($pagename,&$page,&$new) {
+ global $EnablePost, $ROSPatterns, $ROEPatterns;
+ foreach ((array)@$ROEPatterns as $pat => $rep)
+ $new['text'] = preg_replace($pat, $rep, $new['text']);
+ if ($EnablePost) {
+ foreach((array)@$ROSPatterns as $pat=>$rep)
+ $new['text'] = preg_replace($pat, $rep, $new['text']);
+ }
+ $new['=preview'] = $new['text'];
+ PCache($pagename, $new);
+}
+
+function SaveAttributes($pagename,&$page,&$new) {
+ global $EnablePost, $LinkTargets, $SaveAttrPatterns, $PCache,
+ $SaveProperties;
+ if (!$EnablePost) return;
+ $text = preg_replace(array_keys($SaveAttrPatterns),
+ array_values($SaveAttrPatterns), $new['text']);
+ $LinkTargets = array();
+ $html = MarkupToHTML($pagename,$text);
+ $new['targets'] = implode(',',array_keys((array)$LinkTargets));
+ $p = & $PCache[$pagename];
+ foreach((array)$SaveProperties as $k) {
+ if (@$p["=p_$k"]) $new[$k] = $p["=p_$k"];
+ else unset($new[$k]);
+ }
+ unset($new['excerpt']);
+}
+
+function PostPage($pagename, &$page, &$new) {
+ global $DiffKeepDays, $DiffFunction, $DeleteKeyPattern, $EnablePost,
+ $Now, $Charset, $Author, $WikiDir, $IsPagePosted, $DiffKeepNum;
+ SDV($DiffKeepDays,3650);
+ SDV($DiffKeepNum,20);
+ SDV($DeleteKeyPattern,"^\\s*delete\\s*$");
+ $IsPagePosted = false;
+ if ($EnablePost) {
+ $new['charset'] = $Charset;
+ $new['author'] = @$Author;
+ $new["author:$Now"] = @$Author;
+ $new["host:$Now"] = $_SERVER['REMOTE_ADDR'];
+ $diffclass = preg_replace('/\\W/','',@$_POST['diffclass']);
+ if ($page['time']>0 && function_exists(@$DiffFunction))
+ $new["diff:$Now:{$page['time']}:$diffclass"] =
+ $DiffFunction($new['text'],@$page['text']);
+ $keepgmt = $Now-$DiffKeepDays * 86400;
+ $keepnum = array();
+ $keys = array_keys($new);
+ foreach($keys as $k)
+ if (preg_match("/^\\w+:(\\d+)/",$k,$match)) {
+ $keepnum[$match[1]] = 1;
+ if(count($keepnum)>$DiffKeepNum && $match[1]<$keepgmt)
+ unset($new[$k]);
+ }
+ if (preg_match("/$DeleteKeyPattern/",$new['text'])){
+ if(@$new['passwdattr']>'' && !CondAuth($pagename, 'attr'))
+ Abort('$[The page has an "attr" attribute and cannot be deleted.]');
+ else $WikiDir->delete($pagename);
+ }
+ else WritePage($pagename,$new);
+ $IsPagePosted = true;
+ }
+}
+
+function PostRecentChanges($pagename,$page,$new,$Fmt=null) {
+ global $IsPagePosted, $RecentChangesFmt, $RCDelimPattern, $RCLinesMax;
+ if (!$IsPagePosted && $Fmt==null) return;
+ if ($Fmt==null) $Fmt = $RecentChangesFmt;
+ foreach($Fmt as $rcfmt=>$pgfmt) {
+ $rcname = FmtPageName($rcfmt,$pagename); if (!$rcname) continue;
+ $pgtext = FmtPageName($pgfmt,$pagename); if (!$pgtext) continue;
+ if (@$seen[$rcname]++) continue;
+ $rcpage = ReadPage($rcname);
+ $rcelim = preg_quote(preg_replace("/$RCDelimPattern.*$/",' ',$pgtext),'/');
+ $rcpage['text'] = preg_replace("/^.*$rcelim.*\n/m", '', @$rcpage['text']);
+ if (!preg_match("/$RCDelimPattern/",$rcpage['text']))
+ $rcpage['text'] .= "$pgtext\n";
+ else
+ $rcpage['text'] = preg_replace("/([^\n]*$RCDelimPattern.*\n)/",
+ "$pgtext\n$1", $rcpage['text'], 1);
+ if (@$RCLinesMax > 0)
+ $rcpage['text'] = implode("\n", array_slice(
+ explode("\n", $rcpage['text'], $RCLinesMax + 1), 0, $RCLinesMax));
+ WritePage($rcname, $rcpage);
+ }
+}
+
+function AutoCreateTargets($pagename, &$page, &$new) {
+ global $IsPagePosted, $AutoCreate, $LinkTargets;
+ if (!$IsPagePosted) return;
+ foreach((array)@$AutoCreate as $pat => $init) {
+ if (is_null($init)) continue;
+ foreach(preg_grep($pat, array_keys((array)@$LinkTargets)) as $aname) {
+ if (PageExists($aname)) continue;
+ $x = RetrieveAuthPage($aname, 'edit', false, READPAGE_CURRENT);
+ if (!$x) continue;
+ WritePage($aname, $init);
+ }
+ }
+}
+
+function PreviewPage($pagename,&$page,&$new) {
+ global $IsPageSaved, $FmtV;
+ if (@$_REQUEST['preview']) {
+ $text = '(:groupheader:)'.$new['text'].'(:groupfooter:)';
+ $FmtV['$PreviewText'] = MarkupToHTML($pagename,$text);
+ }
+}
+
+function HandleEdit($pagename, $auth = 'edit') {
+ global $IsPagePosted, $EditFields, $ChangeSummary, $EditFunctions,
+ $EnablePost, $FmtV, $Now, $EditRedirectFmt,
+ $PageEditForm, $HandleEditFmt, $PageStartFmt, $PageEditFmt, $PageEndFmt;
+ SDV($EditRedirectFmt, '$FullName');
+ if (@$_POST['cancel'])
+ { Redirect(FmtPageName($EditRedirectFmt, $pagename)); return; }
+ Lock(2);
+ $page = RetrieveAuthPage($pagename, $auth, true);
+ if (!$page) Abort("?cannot edit $pagename");
+ $new = $page;
+ foreach((array)$EditFields as $k)
+ if (isset($_POST[$k])) $new[$k]=str_replace("\r",'',stripmagic($_POST[$k]));
+ $new['csum'] = $ChangeSummary;
+ if ($ChangeSummary) $new["csum:$Now"] = $ChangeSummary;
+ $EnablePost &= preg_grep('/^post/', array_keys(@$_POST));
+ $new['=preview'] = $new['text'];
+ PCache($pagename, $new);
+ UpdatePage($pagename, $page, $new);
+ Lock(0);
+ if ($IsPagePosted && !@$_POST['postedit'])
+ { Redirect(FmtPageName($EditRedirectFmt, $pagename)); return; }
+ $FmtV['$DiffClassMinor'] =
+ (@$_POST['diffclass']=='minor') ? "checked='checked'" : '';
+ $FmtV['$EditText'] =
+ str_replace('$','$',htmlspecialchars(@$new['text'],ENT_NOQUOTES));
+ $FmtV['$EditBaseTime'] = $Now;
+ if (@$PageEditForm) {
+ $efpage = FmtPageName($PageEditForm, $pagename);
+ $form = RetrieveAuthPage($efpage, 'read', false, READPAGE_CURRENT);
+ if (!$form || !@$form['text'])
+ Abort("?unable to retrieve edit form $efpage", 'editform');
+ $FmtV['$EditForm'] = MarkupToHTML($pagename, $form['text']);
+ }
+ SDV($PageEditFmt, "
+
$[Editing {\$FullName}]
+
+ $[Password]:
+ \$PostVars
+ ", &$PageEndFmt));
+ PrintFmt($pagename,$AuthPromptFmt);
+ exit;
+}
+
+function IsAuthorized($chal, $source, &$from) {
+ global $AuthList, $AuthPw, $AllowPassword;
+ if (!$chal) return $from;
+ $auth = 0;
+ $passwd = array();
+ foreach((array)$chal as $c) {
+ $x = '';
+ $pwchal = preg_split('/([, ]|\\w+:)/', $c, -1, PREG_SPLIT_DELIM_CAPTURE);
+ foreach($pwchal as $pw) {
+ if ($pw == ',' || $pw == '') continue;
+ else if ($pw == ' ') { $x = ''; continue; }
+ else if (substr($pw, -1, 1) == ':') { $x = $pw; continue; }
+ else if ($pw{0} != '@' && $x > '') $pw = $x . $pw;
+ if (!$pw) continue;
+ $passwd[] = $pw;
+ if ($auth < 0) continue;
+ if ($x || $pw{0} == '@') {
+ if (@$AuthList[$pw]) $auth = $AuthList[$pw];
+ continue;
+ }
+ if (crypt($AllowPassword, $pw) == $pw) # nopass
+ { $auth=1; continue; }
+ foreach((array)$AuthPw as $pwresp) # password
+ if (crypt($pwresp, $pw) == $pw) { $auth=1; continue; }
+ }
+ }
+ if (!$passwd) return $from;
+ if ($auth < 0) $auth = 0;
+ return array($auth, $passwd, $source);
+}
+
+
+## SessionAuth works with PmWikiAuth to manage authorizations
+## as stored in sessions. First, it can be used to set session
+## variables by calling it with an $auth argument. It then
+## uses the authid, authpw, and authlist session variables
+## to set the corresponding values of $AuthId, $AuthPw, and $AuthList
+## as needed.
+function SessionAuth($pagename, $auth = NULL) {
+ global $AuthId, $AuthList, $AuthPw, $SessionEncode, $SessionDecode,
+ $EnableSessionPasswords;
+ static $called;
+
+ @$called++;
+ $sn = session_name(); # in PHP5.3, $_REQUEST doesn't contain $_COOKIE
+ if (!$auth && ($called > 1 || (!@$_REQUEST[$sn] && !@$_COOKIE[$sn]))) return;
+
+ $sid = session_id();
+ @session_start();
+ foreach((array)$auth as $k => $v) {
+ if ($k == 'authpw') {
+ foreach((array)$v as $pw => $pv) {
+ if ($SessionEncode) $pw = $SessionEncode($pw);
+ $_SESSION[$k][$pw] = $pv;
+ }
+ }
+ else if ($k) $_SESSION[$k] = (array)$v + (array)@$_SESSION[$k];
+ }
+
+ if (!isset($AuthId)) $AuthId = @end($_SESSION['authid']);
+ $AuthPw = array_map($SessionDecode, array_keys((array)@$_SESSION['authpw']));
+ if (!IsEnabled($EnableSessionPasswords, 1)) $_SESSION['authpw'] = array();
+ $AuthList = array_merge($AuthList, (array)@$_SESSION['authlist']);
+
+ if (!$sid) session_write_close();
+}
+
+
+function PasswdVar($pagename, $level) {
+ global $PCache, $PasswdVarAuth, $FmtV;
+ $page = $PCache[$pagename];
+ if (!isset($page['=passwd'][$level])) {
+ $page = RetrieveAuthPage($pagename, 'ALWAYS', false, READPAGE_CURRENT);
+ if ($page) PCache($pagename, $page);
+ }
+ SDV($PasswdVarAuth, 'attr');
+ if ($PasswdVarAuth && !@$page['=auth'][$PasswdVarAuth]) return XL('(protected)');
+ $pwsource = $page['=pwsource'][$level];
+ if (strncmp($pwsource, 'cascade:', 8) == 0) {
+ $FmtV['$PWCascade'] = substr($pwsource, 8);
+ return FmtPageName('$[(using $PWCascade password)]', $pagename);
+ }
+ $setting = htmlspecialchars(implode(' ', preg_replace('/^(?!@|\\w+:).+$/', '****',
+ (array)$page['=passwd'][$level])));
+ if ($pwsource == 'group' || $pwsource == 'site') {
+ $FmtV['$PWSource'] = $pwsource;
+ $setting = FmtPageName('$[(set by $PWSource)] ', $pagename)
+ . htmlspecialchars($setting);
+ }
+ return $setting;
+}
+
+
+function PrintAttrForm($pagename) {
+ global $PageAttributes, $PCache, $FmtV;
+ echo FmtPageName("
+
+
+ ",
+ $pagename);
+}
+
+function HandleAttr($pagename, $auth = 'attr') {
+ global $HandleAttrFmt,$PageAttrFmt,$PageStartFmt,$PageEndFmt;
+ $page = RetrieveAuthPage($pagename, $auth, true, READPAGE_CURRENT);
+ if (!$page) { Abort("?unable to read $pagename"); }
+ PCache($pagename,$page);
+ XLSDV('en', array('EnterAttributes' =>
+ "Enter new attributes for this page below. Leaving a field blank
+ will leave the attribute unchanged. To clear an attribute, enter
+ 'clear'."));
+ SDV($PageAttrFmt,"
+
$[{\$FullName} Attributes]
+
$[EnterAttributes]
");
+ SDV($HandleAttrFmt,array(&$PageStartFmt,&$PageAttrFmt,
+ 'function:PrintAttrForm',&$PageEndFmt));
+ PrintFmt($pagename,$HandleAttrFmt);
+}
+
+function HandlePostAttr($pagename, $auth = 'attr') {
+ global $PageAttributes, $EnablePostAttrClearSession;
+ Lock(2);
+ $page = RetrieveAuthPage($pagename, $auth, true);
+ if (!$page) { Abort("?unable to read $pagename"); }
+ foreach($PageAttributes as $attr=>$p) {
+ $v = stripmagic(@$_POST[$attr]);
+ if ($v == '') continue;
+ if ($v=='clear') unset($page[$attr]);
+ else if (strncmp($attr, 'passwd', 6) != 0) $page[$attr] = $v;
+ else {
+ $a = array();
+ preg_match_all('/"[^"]*"|\'[^\']*\'|\\S+/', $v, $match);
+ foreach($match[0] as $pw)
+ $a[] = preg_match('/^(@|\\w+:)/', $pw) ? $pw
+ : crypt(preg_replace('/^([\'"])(.*)\\1$/', '$2', $pw));
+ if ($a) $page[$attr] = implode(' ',$a);
+ }
+ }
+ WritePage($pagename,$page);
+ Lock(0);
+ if (IsEnabled($EnablePostAttrClearSession, 1)) {
+ @session_start();
+ unset($_SESSION['authid']);
+ unset($_SESSION['authlist']);
+ $_SESSION['authpw'] = array();
+ }
+ Redirect($pagename);
+ exit;
+}
+
+
+function HandleLogoutA($pagename, $auth = 'read') {
+ global $LogoutRedirectFmt, $LogoutCookies;
+ SDV($LogoutRedirectFmt, '$FullName');
+ SDV($LogoutCookies, array());
+ @session_start();
+ $_SESSION = array();
+ if ( session_id() != '' || isset($_COOKIE[session_name()]) )
+ setcookie(session_name(), '', time()-43200, '/');
+ foreach ($LogoutCookies as $c)
+ if (isset($_COOKIE[$c])) setcookie($c, '', time()-43200, '/');
+ session_destroy();
+ Redirect(FmtPageName($LogoutRedirectFmt, $pagename));
+}
+
+
+function HandleLoginA($pagename, $auth = 'login') {
+ global $AuthId, $DefaultPasswords;
+ unset($DefaultPasswords['admin']);
+ $prompt = @(!$_POST['authpw'] || ($AuthId != $_POST['authid']));
+ $page = RetrieveAuthPage($pagename, $auth, $prompt, READPAGE_CURRENT);
+ Redirect($pagename);
+}
+
diff --git a/local/config.php b/local/config.php
new file mode 100644
index 0000000..5aecd36
--- /dev/null
+++ b/local/config.php
@@ -0,0 +1,172 @@
+ $Now);
+
+## PmWiki allows a great deal of flexibility for creating custom markup.
+## To add support for '*bold*' and '~italic~' markup (the single quotes
+## are part of the markup), uncomment the following lines.
+## (See PmWiki.CustomMarkup and the Cookbook for details and examples.)
+# Markup("'~", "inline", "/'~(.*?)~'/", "
$1 "); # '~italic~'
+# Markup("'*", "inline", "/'\\*(.*?)\\*'/", "
$1 "); # '*bold*'
+
+## If you want to have to approve links to external sites before they
+## are turned into links, uncomment the line below. See PmWiki.UrlApprovals.
+## Also, setting $UnapprovedLinkCountMax limits the number of unapproved
+## links that are allowed in a page (useful to control wikispam).
+# $UnapprovedLinkCountMax = 10;
+# include_once("scripts/urlapprove.php");
+
+## The following lines make additional editing buttons appear in the
+## edit page for subheadings, lists, tables, etc.
+# $GUIButtons['h2'] = array(400, '\\n!! ', '\\n', '$[Heading]',
+# '$GUIButtonDirUrlFmt/h2.gif"$[Heading]"');
+# $GUIButtons['h3'] = array(402, '\\n!!! ', '\\n', '$[Subheading]',
+# '$GUIButtonDirUrlFmt/h3.gif"$[Subheading]"');
+# $GUIButtons['indent'] = array(500, '\\n->', '\\n', '$[Indented text]',
+# '$GUIButtonDirUrlFmt/indent.gif"$[Indented text]"');
+# $GUIButtons['outdent'] = array(510, '\\n-<', '\\n', '$[Hanging indent]',
+# '$GUIButtonDirUrlFmt/outdent.gif"$[Hanging indent]"');
+# $GUIButtons['ol'] = array(520, '\\n# ', '\\n', '$[Ordered list]',
+# '$GUIButtonDirUrlFmt/ol.gif"$[Ordered (numbered) list]"');
+# $GUIButtons['ul'] = array(530, '\\n* ', '\\n', '$[Unordered list]',
+# '$GUIButtonDirUrlFmt/ul.gif"$[Unordered (bullet) list]"');
+# $GUIButtons['hr'] = array(540, '\\n----\\n', '', '',
+# '$GUIButtonDirUrlFmt/hr.gif"$[Horizontal rule]"');
+# $GUIButtons['table'] = array(600,
+# '||border=1 width=80%\\n||!Hdr ||!Hdr ||!Hdr ||\\n|| || || ||\\n|| || || ||\\n', '', '',
+# '$GUIButtonDirUrlFmt/table.gif"$[Table]"');
+// error_reporting(E_ALL);
+// ini_set('display_errors','ON');
+
+include_once("$FarmD/cookbook/markdownpmw.php");
+
+// $GroupHeaderFmt =
+// '(:include $SiteGroup.AllGroupHeader:)(:nl:)'
+// .'(:include $Group.GroupHeader:)(:nl:)';
+$GroupHeaderFmt = '(:markdown:)';
+$GroupFooterFmt = '(:markdownend:)';
diff --git a/pub/guiedit/README b/pub/guiedit/README
new file mode 100644
index 0000000..dbadaf2
--- /dev/null
+++ b/pub/guiedit/README
@@ -0,0 +1,6 @@
+The images in this directory are part of the GUIEdit module
+for PmWiki, Copyright 2005-2006 Patrick R. Michaud (pmichaud@pobox.com)
+These images are part of PmWiki; you can redistribute it and/or modify
+them 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. See pmwiki.php for full details.
diff --git a/pub/guiedit/attach.gif b/pub/guiedit/attach.gif
new file mode 100644
index 0000000..720d0b6
Binary files /dev/null and b/pub/guiedit/attach.gif differ
diff --git a/pub/guiedit/big.gif b/pub/guiedit/big.gif
new file mode 100644
index 0000000..d0d3d0d
Binary files /dev/null and b/pub/guiedit/big.gif differ
diff --git a/pub/guiedit/blank.gif b/pub/guiedit/blank.gif
new file mode 100644
index 0000000..a3b8d18
Binary files /dev/null and b/pub/guiedit/blank.gif differ
diff --git a/pub/guiedit/center.gif b/pub/guiedit/center.gif
new file mode 100644
index 0000000..64e354b
Binary files /dev/null and b/pub/guiedit/center.gif differ
diff --git a/pub/guiedit/em.gif b/pub/guiedit/em.gif
new file mode 100644
index 0000000..58e65b0
Binary files /dev/null and b/pub/guiedit/em.gif differ
diff --git a/pub/guiedit/extlink.gif b/pub/guiedit/extlink.gif
new file mode 100644
index 0000000..1eacc92
Binary files /dev/null and b/pub/guiedit/extlink.gif differ
diff --git a/pub/guiedit/guiedit.js b/pub/guiedit/guiedit.js
new file mode 100644
index 0000000..eca474e
--- /dev/null
+++ b/pub/guiedit/guiedit.js
@@ -0,0 +1,62 @@
+/* Copyright 2004 Patrick R. Michaud (pmichaud@pobox.com)
+ This file is part of PmWiki; 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. See pmwiki.php for full details.
+
+ This file provides Javascript functions to support WYSIWYG-style
+ editing. The concepts are borrowed from the editor used in Wikipedia,
+ but the code has been rewritten from scratch to integrate better with
+ PHP and PmWiki's codebase.
+*/
+
+function insButton(mopen, mclose, mtext, mlabel, mkey) {
+ if (mkey > '') { mkey = 'accesskey="' + mkey + '" ' }
+ document.write("
"
+ + mlabel + " ");
+}
+
+function insMarkup(mopen, mclose, mtext) {
+ var tarea = document.getElementById('text');
+ if (tarea.setSelectionRange > '') {
+ var p0 = tarea.selectionStart;
+ var p1 = tarea.selectionEnd;
+ var top = tarea.scrollTop;
+ var str = mtext;
+ var cur0 = p0 + mopen.length;
+ var cur1 = p0 + mopen.length + str.length;
+ while (p1 > p0 && tarea.value.substring(p1-1, p1) == ' ') p1--;
+ if (p1 > p0) {
+ str = tarea.value.substring(p0, p1);
+ cur0 = p0 + mopen.length + str.length + mclose.length;
+ cur1 = cur0;
+ }
+ tarea.value = tarea.value.substring(0,p0)
+ + mopen + str + mclose
+ + tarea.value.substring(p1);
+ tarea.focus();
+ tarea.selectionStart = cur0;
+ tarea.selectionEnd = cur1;
+ tarea.scrollTop = top;
+ } else if (document.selection) {
+ var str = document.selection.createRange().text;
+ tarea.focus();
+ range = document.selection.createRange()
+ if (str == '') {
+ range.text = mopen + mtext + mclose;
+ range.moveStart('character', -mclose.length - mtext.length );
+ range.moveEnd('character', -mclose.length );
+ } else {
+ if (str.charAt(str.length - 1) == " ") {
+ mclose = mclose + " ";
+ str = str.substr(0, str.length - 1);
+ }
+ range.text = mopen + str + mclose;
+ }
+ range.select();
+ } else { tarea.value += mopen + mtext + mclose; }
+ return;
+}
diff --git a/pub/guiedit/h.gif b/pub/guiedit/h.gif
new file mode 100644
index 0000000..76e062b
Binary files /dev/null and b/pub/guiedit/h.gif differ
diff --git a/pub/guiedit/h1.gif b/pub/guiedit/h1.gif
new file mode 100644
index 0000000..4a358da
Binary files /dev/null and b/pub/guiedit/h1.gif differ
diff --git a/pub/guiedit/h2.gif b/pub/guiedit/h2.gif
new file mode 100644
index 0000000..a6aca2c
Binary files /dev/null and b/pub/guiedit/h2.gif differ
diff --git a/pub/guiedit/h3.gif b/pub/guiedit/h3.gif
new file mode 100644
index 0000000..0459f89
Binary files /dev/null and b/pub/guiedit/h3.gif differ
diff --git a/pub/guiedit/hr.gif b/pub/guiedit/hr.gif
new file mode 100644
index 0000000..486d47c
Binary files /dev/null and b/pub/guiedit/hr.gif differ
diff --git a/pub/guiedit/indent.gif b/pub/guiedit/indent.gif
new file mode 100644
index 0000000..e158e40
Binary files /dev/null and b/pub/guiedit/indent.gif differ
diff --git a/pub/guiedit/left.gif b/pub/guiedit/left.gif
new file mode 100644
index 0000000..d78986d
Binary files /dev/null and b/pub/guiedit/left.gif differ
diff --git a/pub/guiedit/math.gif b/pub/guiedit/math.gif
new file mode 100644
index 0000000..33fb51a
Binary files /dev/null and b/pub/guiedit/math.gif differ
diff --git a/pub/guiedit/ol.gif b/pub/guiedit/ol.gif
new file mode 100644
index 0000000..0368a46
Binary files /dev/null and b/pub/guiedit/ol.gif differ
diff --git a/pub/guiedit/outdent.gif b/pub/guiedit/outdent.gif
new file mode 100644
index 0000000..68aace1
Binary files /dev/null and b/pub/guiedit/outdent.gif differ
diff --git a/pub/guiedit/pagelink.gif b/pub/guiedit/pagelink.gif
new file mode 100644
index 0000000..21039ff
Binary files /dev/null and b/pub/guiedit/pagelink.gif differ
diff --git a/pub/guiedit/preview.gif b/pub/guiedit/preview.gif
new file mode 100644
index 0000000..baefe3f
Binary files /dev/null and b/pub/guiedit/preview.gif differ
diff --git a/pub/guiedit/right.gif b/pub/guiedit/right.gif
new file mode 100644
index 0000000..689a22a
Binary files /dev/null and b/pub/guiedit/right.gif differ
diff --git a/pub/guiedit/save.gif b/pub/guiedit/save.gif
new file mode 100644
index 0000000..1e734b6
Binary files /dev/null and b/pub/guiedit/save.gif differ
diff --git a/pub/guiedit/small.gif b/pub/guiedit/small.gif
new file mode 100644
index 0000000..add9870
Binary files /dev/null and b/pub/guiedit/small.gif differ
diff --git a/pub/guiedit/spellcheck.gif b/pub/guiedit/spellcheck.gif
new file mode 100644
index 0000000..b1ab46a
Binary files /dev/null and b/pub/guiedit/spellcheck.gif differ
diff --git a/pub/guiedit/strong.gif b/pub/guiedit/strong.gif
new file mode 100644
index 0000000..47fd9a2
Binary files /dev/null and b/pub/guiedit/strong.gif differ
diff --git a/pub/guiedit/sub.gif b/pub/guiedit/sub.gif
new file mode 100644
index 0000000..c5acc18
Binary files /dev/null and b/pub/guiedit/sub.gif differ
diff --git a/pub/guiedit/sup.gif b/pub/guiedit/sup.gif
new file mode 100644
index 0000000..a14c766
Binary files /dev/null and b/pub/guiedit/sup.gif differ
diff --git a/pub/guiedit/table.gif b/pub/guiedit/table.gif
new file mode 100644
index 0000000..d0bad0f
Binary files /dev/null and b/pub/guiedit/table.gif differ
diff --git a/pub/guiedit/ul.gif b/pub/guiedit/ul.gif
new file mode 100644
index 0000000..6c31b5c
Binary files /dev/null and b/pub/guiedit/ul.gif differ
diff --git a/pub/guiedit/underline.gif b/pub/guiedit/underline.gif
new file mode 100644
index 0000000..1399a41
Binary files /dev/null and b/pub/guiedit/underline.gif differ
diff --git a/pub/skins/equilibrium/ie7.css b/pub/skins/equilibrium/ie7.css
new file mode 100644
index 0000000..e2c7198
--- /dev/null
+++ b/pub/skins/equilibrium/ie7.css
@@ -0,0 +1,8 @@
+.pageactions {top:-10px}
+#s{height:15px; width:180px}
+#searchform{margin-bottom:0}
+#searchsubmit{height:2.3em}
+.post-category{margin-bottom:0}
+.postMeta-post{padding-bottom:0}
+#sidebar li a{display:inline-block}
+#wikitext pre {padding-top:5px; padding-bottom: 20px}
diff --git a/pub/skins/equilibrium/images/comment.gif b/pub/skins/equilibrium/images/comment.gif
new file mode 100644
index 0000000..34ad7cc
Binary files /dev/null and b/pub/skins/equilibrium/images/comment.gif differ
diff --git a/pub/skins/equilibrium/skin.php b/pub/skins/equilibrium/skin.php
new file mode 100644
index 0000000..c259b0d
--- /dev/null
+++ b/pub/skins/equilibrium/skin.php
@@ -0,0 +1,129 @@
+'#000','entry-title-text'=>'#0B96D0','text-highlight'=>'#0B96D0','block-highlight-text'=>'#fff','title-text'=>'#000');
+$ValidSkinColors['red'] = array('block-highlight-back'=>'#CC0000','entry-title-text'=>'#000','text-highlight'=>'#0B96D0','block-highlight-text'=>'#fff','title-text'=>'#000');
+$ValidSkinColors['orange'] = array('block-highlight-back'=>'#FF7400','entry-title-text'=>'#000','text-highlight'=>'#0B96D0','block-highlight-text'=>'#fff','title-text'=>'#000');
+$ValidSkinColors['dark-orange'] = array('block-highlight-back'=>'#D64B00','entry-title-text'=>'#000','text-highlight'=>'#0B96D0','block-highlight-text'=>'#fff','title-text'=>'#000');
+$ValidSkinColors['light-blue'] = array('block-highlight-back'=>'#4096EE','entry-title-text'=>'#000','text-highlight'=>'#0B96D0','block-highlight-text'=>'#fff','title-text'=>'#000');
+$ValidSkinColors['pink'] = array('block-highlight-back'=>'#FF0084','entry-title-text'=>'#000','text-highlight'=>'#0B96D0','block-highlight-text'=>'#fff','title-text'=>'#000');
+$ValidSkinColors['purple'] = array('block-highlight-back'=>'#80185B','entry-title-text'=>'#000','text-highlight'=>'#0B96D0','block-highlight-text'=>'#fff','title-text'=>'#000');
+$ValidSkinColors['gold'] = array('block-highlight-back'=>'#C79810','entry-title-text'=>'#000','text-highlight'=>'#0B96D0','block-highlight-text'=>'#fff','title-text'=>'#000');
+$ValidSkinColors['green'] = array('block-highlight-back'=>'#008C00','entry-title-text'=>'#000','text-highlight'=>'#0B96D0','block-highlight-text'=>'#fff','title-text'=>'#000');
+$ValidSkinColors['blue'] = array('block-highlight-back'=>'#356AA0','entry-title-text'=>'#000','text-highlight'=>'#0B96D0','block-highlight-text'=>'#fff','title-text'=>'#000');
+$ValidSkinColors['mint'] = array('block-highlight-back'=>'#CDEB8B','entry-title-text'=>'#000','text-highlight'=>'#0B96D0','block-highlight-text'=>'#fff','title-text'=>'#000');
+$ValidSkinColors['dark-blue'] = array('block-highlight-back'=>'#3F4C6B','entry-title-text'=>'#000','text-highlight'=>'#0B96D0','block-highlight-text'=>'#fff','title-text'=>'#000');
+$ValidSkinColors = array_merge($ValidSkinColors, $UserSkinColors);
+
+if ( isset($_GET['color']) && isset($ValidSkinColors[$_GET['color']]) ) $SkinColor = $_GET['color'];
+elseif ( !isset($ValidSkinColors[$SkinColor]) ) $SkinColor = 'black';
+
+$UserStyle = $HTMLStylesFmt['equilibrium'];
+$HTMLStylesFmt['equilibrium'] =
+ '.featured .title,.latest .title,.featured .title h2 a,.latest .title h2 a'.
+ '{color:'. $ValidSkinColors[$SkinColor]['entry-title-text']. '} '.
+ '.featured-title h2 a:hover,.featured .title h2 a:hover{color:'. $ValidSkinColors[$SkinColor]['block-highlight-text'].'} '.
+ '.featured .title,.latest .title{background:'. $ValidSkinColors[$SkinColor]['block-highlight-back'].'} '.
+ 'p a,p a:visited,.postMeta-post a,.postMeta-post a:visited,.featured .post-content h2 a,'.
+ '.blogit-page-topigation a,.blogit-page-topigation a:visited,'.
+ '.latest .post-content h2,#footer div a:hover,'.
+ '#comments .commentmetadata li a'.
+ '{color:'. $ValidSkinColors[$SkinColor]['text-highlight']. '} '.
+ '#sidebar a:hover,#top a:hover,#siteheader ul a:hover,ul#top li.current_page_item a:link,'.
+ 'ul#top li.current_page_item a:visited,ul#top li.current_page_item a:hover,ul#top li.current_page_item a:active,'.
+ '#siteheader ul li.current_page_item a:link,#siteheader ul li.current_page_item a:visited,#siteheader ul li.current_page_item a:hover,'.
+ '#siteheader ul li.current_page_item a:active'.
+ '{color:'. $ValidSkinColors[$SkinColor]['block-highlight-text'].
+ ' !important;background:'. $ValidSkinColors[$SkinColor]['block-highlight-back'].'} '.
+ '#siteheader .sitetitle.logo a, #siteheader .sitetitle a'.
+ '{color:'. $ValidSkinColors[$SkinColor]['title-text']. '} ';
+
+global $PageLogoUrl, $PageLogoUrlHeight, $PageLogoUrlWidth,$HTMLStylesFmt;
+if (!empty($PageLogoUrl)) {
+ dg_SetLogoHeightWidth(15);
+ $HTMLStylesFmt['equilibrium'] .=
+ '#siteheader .sitetitle a{height:' .$PageLogoUrlHeight .'; background: url(' .$PageLogoUrl .') left top no-repeat} '.
+ '#siteheader .sitetitle a, #siteheader .sitetag{padding-left: ' .$PageLogoUrlWidth .'} '.
+ '#siteheader .sitetag{margin-top: ' .(45-substr($PageLogoUrlHeight,0,-2)) .'px}';
+}
+$HTMLStylesFmt['equilibrium'] .= $UserStyle;
+
+# Allows classes on anchors
+global $WikiStyleApply;
+$WikiStyleApply['a'] = 'a';
+
+# ----------------------------------------
+# - Standard Skin Setup
+# ----------------------------------------
+$FmtPV['$WikiTitle'] = '$GLOBALS["WikiTitle"]';
+$FmtPV['$WikiTag'] = '$GLOBALS["WikiTag"]';
+
+# Move any (:noleft:) or SetTmplDisplay('PageLeftFmt', 0); directives to variables for access in jScript.
+$FmtPV['$LeftColumn'] = "\$GLOBALS['TmplDisplay']['PageLeftFmt']";
+Markup('noleft', 'directives', '/\\(:noleft:\\)/ei', "SetTmplDisplay('PageLeftFmt',0)");
+$FmtPV['$RightColumn'] = "\$GLOBALS['TmplDisplay']['PageRightFmt']";
+Markup('noright', 'directives', '/\\(:noright:\\)/ei', "SetTmplDisplay('PageRightFmt',0)");
+$FmtPV['$ActionBar'] = "\$GLOBALS['TmplDisplay']['PageActionFmt']";
+Markup('noaction', 'directives', '/\\(:noaction:\\)/ei', "SetTmplDisplay('PageActionFmt',0)");
+$FmtPV['$TabsBar'] = "\$GLOBALS['TmplDisplay']['PageTabsFmt']";
+Markup('notabs', 'directives', '/\\(:notabs:\\)/ei', "SetTmplDisplay('PageTabsFmt',0)");
+$FmtPV['$SearchBar'] = "\$GLOBALS['TmplDisplay']['PageSearchFmt']";
+Markup('nosearch', 'directives', '/\\(:nosearch:\\)/ei', "SetTmplDisplay('PageSearchFmt',0)");
+$FmtPV['$TitleGroup'] = "\$GLOBALS['TmplDisplay']['PageTitleGroupFmt']";
+Markup('notitlegroup', 'directives', '/\\(:notitlegroup:\\)/ei', "SetTmplDisplay('PageTitleGroupFmt',0)");
+Markup('notitle', 'directives', '/\\(:notitle:\\)/ei', "SetTmplDisplay('PageTitleFmt',0); SetTmplDisplay('PageTitleGroupFmt',0)");
+Markup('fieldset', 'inline', '/\\(:fieldset:\\)/i', "
");
+Markup('fieldsetend', 'inline', '/\\(:fieldsetend:\\)/i', " ");
+
+# Override pmwiki styles otherwise they will override styles declared in css
+global $HTMLStylesFmt;
+$HTMLStylesFmt['pmwiki'] = '';
+
+# Add a custom page storage location
+global $WikiLibDirs;
+$PageStorePath = dirname(__FILE__)."/wikilib.d/{\$FullName}";
+$where = count($WikiLibDirs);
+if ($where>1) $where--;
+array_splice($WikiLibDirs, $where, 0, array(new PageStore($PageStorePath)));
+
+# ----------------------------------------
+# - Standard Skin Functions
+# ----------------------------------------
+function dg_SetSkinColor($default, $valid_colors){
+global $SkinColor, $ValidSkinColors, $_GET;
+ if ( !is_array($ValidSkinColors) ) $ValidSkinColors = array();
+ $ValidSkinColors = array_merge($ValidSkinColors, $valid_colors);
+ if ( isset($_GET['color']) && in_array($_GET['color'], $ValidSkinColors) )
+ $SkinColor = $_GET['color'];
+ elseif ( !in_array($SkinColor, $ValidSkinColors) )
+ $SkinColor = $default;
+ return $SkinColor;
+}
+function dg_PoweredBy(){
+ print ('
BlogIt':'">PmWiki').' ');
+}
+# Determine logo height and width
+function dg_SetLogoHeightWidth ($wPad, $hPad=0){
+global $PageLogoUrl, $PageLogoUrlHeight, $PageLogoUrlWidth;
+ if (!isset($PageLogoUrlWidth) || !isset($PageLogoUrlHeight)){
+ $size = @getimagesize($PageLogoUrl);
+ if (!isset($PageLogoUrlWidth)) SDV($PageLogoUrlWidth, ($size ?$size[0]+$wPad :0) .'px');
+ if (!isset($PageLogoUrlHeight)) SDV($PageLogoUrlHeight, ($size ?$size[1]+$hPad :0) .'px');
+ }
+}
diff --git a/pub/skins/equilibrium/skin.tmpl b/pub/skins/equilibrium/skin.tmpl
new file mode 100644
index 0000000..1bdeb70
--- /dev/null
+++ b/pub/skins/equilibrium/skin.tmpl
@@ -0,0 +1,74 @@
+
+
+
+
$WikiTitle {$Group}/{$Titlespaced}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pub/skins/equilibrium/style.css b/pub/skins/equilibrium/style.css
new file mode 100644
index 0000000..707bbd5
--- /dev/null
+++ b/pub/skins/equilibrium/style.css
@@ -0,0 +1,366 @@
+/*
+-----------------------------------------
+RESET
+-----------------------------------------
+*/
+html, body, div, dl, dt, dd, ul, ol, li, h1, h2, h3, h4, h5, h6, pre, form, label, fieldset, input, p, blockquote, th, td{margin:0; padding:0}
+table{border-collapse:collapse; border-spacing:0}
+fieldset, img{border:0}
+address, caption, cite, code, dfn, em, strong, th, var{font-style:normal; font-weight:normal}
+caption, th{text-align:left}
+h1, h2, h3, h4, h5, h6{font-size:100%; font-weight:normal}
+q:before, q:after{content:''}
+
+strong{font-weight:bold}
+em{font-style:italic}
+a img{border:none}
+
+h1, h2, h3, h5, h5, h6{font-weight:bold}
+
+/*
+-----------------------------------------
+LAYOUT
+-----------------------------------------
+*/
+.aligncenter{display:block; margin:0 auto}
+.alignleft{float:left}
+.alignright{float:right}
+.floatLeft{float:left}
+.floatRight{float:right}
+.clear{clear:both}
+
+/*
+-----------------------------------------
+STRUCTURE
+-----------------------------------------
+*/
+html, body{height:100%}
+body{font-size:62.5%; font-family:Arial,Helvetica,sans-serif; color:#222; margin:0 auto -80px; text-align:center}
+#page-wrap{position:relative; width:960px; margin:0 auto; padding-left:10px; padding-right:10px; text-align:left}
+.content{width:680px; float:left}
+
+/*
+-----------------------------------------
+TYPOGRAPHY
+-----------------------------------------
+*/
+p, address, caption, cite, pre, code, dfn, em, strong, th, var, dt, dd
+{color:#222; font-size:1.2em; line-height:1.5; margin-top:1.5em; margin-bottom:1.5em; text-align:justify}
+pre {font-size: 1.5em}
+p a, p a:visited,
+.blogit-page-navigation a, .blogit-page-navigation a:visited,
+.postMeta-post a, .postMeta-post a:visited{border-bottom:1px solid #c9c9c9; text-decoration:none}
+p a:hover,
+.blogit-page-navigation a:hover,
+.postMeta-post a:hover{border-bottom:1px solid #c9c9c9; color:#000; text-decoration:none}
+h1, strong{font-size:1.4em; font-weight:bold}
+h4, h2, #sidebar .sidehead, #wikitext h2.section-head{font-size:1.8em; color:#222; text-transform:uppercase; padding-bottom:4px; border-bottom:4px solid #c9c9c9; margin-top:28px; margin-bottom:28px; font-weight:bold}
+h3.page-head{border-bottom:4px solid #c9c9c9; color:#222; font-size:2.2em; font-weight:bold; padding-bottom:4px}
+h3 a{text-decoration:none; color:#222}
+
+.post h2,
+#wikitext h2, #wikitext h3, #wikitext h4{text-transform:none; padding-bottom:0; border-bottom:0; margin-bottom:0; margin-top:1.5em}
+#wikitext h3 {font-size: 1.5em}
+#wikitext h4 {font-size: 1.2em}
+.post ul li,
+.post ol li,
+#wikitext ul li,
+#wikitext ol li{font-size:1.2em; margin:5px 0 5px 15px}
+
+#reply{border-bottom:4px solid #C9C9C9; color:#222; font-size:1.8em; margin-top:28px; margin-bottom:16px; padding-bottom:4px}
+
+/*
+-----------------------------------------
+TOP
+-----------------------------------------
+*/
+#top{margin-top:55px; padding-bottom:70px}
+
+#siteheader {float: left; position: relative;}
+
+h1.logo a,
+#siteheader .sitetitle {float:left}
+#siteheader .sitetitle a{display: block}
+#siteheader .sitetag {float: left; clear: left}
+
+#siteheader .sitetitle a{font-size:2.6em; font-weight:bold; color:#000; text-transform:uppercase; text-decoration:none}
+#siteheader .sitetag {color: #8A8A8A}
+
+#nav, #top ul{float:right; margin-top:1.2em}
+
+#nav ul, #top ul{list-style-type:none;}
+
+#nav li, #top li{display:block; display:inline}
+
+#nav a:link,
+#nav a:visited,
+#top ul a:link,
+#top ul a:visited{padding:5px; display:block; color:#353434; margin-left:10px; float:left; text-decoration:none; font-size:1.4em; font-weight:bold; text-transform:uppercase}
+
+ul#nav li.current_page_item a:link,
+ul#nav li.current_page_item a:visited,
+ul#nav li.current_page_item a:hover,
+ul#nav li.current_page_item a:active,
+#top ul li.current_page_item a:link,
+#top ul li.current_page_item a:visited,
+#top ul li.current_page_item a:hover,
+#top ul li.current_page_item a:active
+{text-decoration:none}
+
+/*
+-----------------------------------------
+FEATURED
+-----------------------------------------
+*/
+.front-post,
+.featured .post-wrap{width:327px; margin-bottom:3.5em; margin-right:25px; float:left}
+
+.front-post-last{width:100%; float:left}
+
+.featured-content,
+.featured .post-content{position:relative; width:100%} /*margin-bottom:3.5em*/
+
+.featured-content p,
+.featured .post-content p{margin-top:1em}
+
+.featured-post,
+.featured .post-head{overflow:hidden; width:100%; margin-bottom:1.2em} /*height:231px; */
+
+.featured-title h2,
+#wikitext .featured .title h2{margin:8px 10px 7px; line-height:1.4em; font-size:1.1em; text-transform:none; padding-bottom:0; border-bottom:0}
+
+.featured-title h2 a,
+.featured .title h2 a{font-size:1.1em; display:block; text-decoration:none; border-bottom:0}
+
+.featured-title,
+.featured .title{display:block; z-index:101; width:100%; top:0; filter:alpha(opacity=80); -moz-opacity:.80; opacity:.80; float:left; z-index:2}
+
+.featured-image,
+.featured .post-head img{position:relative; width:100%; z-index:1; margin:0 !important} /*height:231px; */
+.featured .content-wrap img {display:none}
+
+.featured-content h2,
+.featured .post-content h2{margin-top:15px}
+.featured-content h2 a,
+.featured .post-content h2 a{text-decoration:none}
+.featured-content h2 a:hover,
+.featured .post-content h2 a{color:#000}
+
+/*
+-----------------------------------------
+SIDEBAR
+-----------------------------------------
+*/
+#sidebar{float:right; width:260px; padding-left:20px; overflow:hidden}
+#sidebar li {list-style-type: none}
+#sidebar li a{display:block; width:260px; margin:0; padding:8px 2px; list-style:none; border-bottom:1px solid #c9c9c9; font-size:1.4em; list-style-type:none; text-decoration:none; color:#222}
+#sidebar a{color:#222; text-decoration:none}
+#sidebar h2, #sidebar .sidehead{font-size:1.8em; color:#222; text-align:right; text-transform:uppercase; border-bottom:4px solid #c9c9c9; margin-top:28px; margin-bottom:0}
+
+/*
+-----------------------------------------
+LATEST
+-----------------------------------------
+*/
+#front-bottom{margin-top:36px}
+
+#latest-wrap,
+.latest{float:left; width:680px}
+
+.latest-post-wrap,
+.latest .post-wrap{float:left; width:162px; margin-right:8px}
+
+.latest-post,
+.latest .post-head{overflow:hidden; width:162px}
+
+.latest-image,
+.latest .post-head img{position:relative; width:100%; z-index:1; margin:0 !important}
+.latest .content-wrap img {display:none}
+
+.latest-title h2,
+#wikitext .latest .title h2{margin:8px 10px 7px; line-height:1.4em; font-size:1em; text-transform:none; padding-bottom:0; border-bottom:0}
+
+.latest-title h2 a,
+.latest .title h2 a{display:block; text-decoration:none}
+
+.latest-title h2 a:hover,
+.latest .title h2 a:hover{color:#fff}
+
+.latest-title,
+.latest .title{display:block; z-index:101; width:100%; bottom:0; filter:alpha(opacity=80); -moz-opacity:.80; opacity:.80; float:left; z-index:2}
+
+.latest-content,
+.latest .post-content{position:relative; width:162px; margin-bottom:20px} /*height:200px; */
+
+.latest-content h2,
+.latest .post-content h2{margin-top:15px}
+.latest-content h2 a,
+.latest .post-content h2{text-decoration:none}
+.latest-content h2 a:hover,
+.latest .post-content h2:hover{color:#000}
+
+.latest-content p,
+.latest .post-content p{color:#222; font-size:1.2em; line-height:1.5; margin-top:8px; margin-bottom:1.5em; text-align:left}
+
+.row-wrap{float: left}
+.no-right-margin{margin-right:0 !important}
+
+/*
+-----------------------------------------
+FOOTER
+-----------------------------------------
+*/
+#push{height:80px}
+
+#footer{clear: both; padding-top:10px; border-top:1px solid #C9C9C9; width:960px; margin:60px auto 0; height:80px; color:#4d4d4d}
+
+#footer div, #footer p{text-align: center; font-size:1em; color:#4d4d4d; line-height:1.5em; margin-bottom:0; margin-top:0}
+
+#footer div a, #footer p a{border-bottom:1px solid #c9c9c9; color:#4d4d4d; text-decoration:none}
+
+#footer div a:hover, #footer a:hover{border-bottom:1px solid #c9c9c9; text-decoration:none}
+
+/*
+-----------------------------------------
+POSTMETA
+-----------------------------------------
+*/
+.postMeta{font-size:1.2em; margin-bottom:18px; margin-top:8px; padding-bottom:24px; border-bottom:1px solid #c9c9c9}
+
+.postMeta-featured,
+.featured .postMeta,
+.latest .postMeta{margin-top:8px; font-size:1.2em; width:100%; margin-bottom:0; padding-bottom:0; border-bottom:none}
+
+.postMeta-front{margin-top:8px; font-size:1.2em}
+
+.postMeta-post{font-size:1.2em; margin-bottom:18px; margin-top:8px; border-bottom:1px solid #c9c9c9; padding-bottom:10px}
+
+.postMeta span.date,
+.postMeta-post span.date,
+.postMeta-featured span.date,
+.postMeta-front span.date{color:#8a8a8a; float:left}
+
+.postMeta-post span.date,
+.postMeta-post span.comments{clear:both;}
+
+.postMeta span.comments a,
+.postMeta-post span.comments a,
+.postMeta-featured span.comments a,
+.postMeta-featured span.date a,
+.postMeta-front span.comments a,
+.postMeta-front span.date a{float:left; color:#8a8a8a; text-decoration:none}
+
+.postMeta-post span.date a,
+.postMeta span.date a{color:#8a8a8a; text-decoration:none}
+
+.postMeta span.comments,
+.postMeta-featured span.comments,
+.postMeta-post span.comments,
+.postMeta-front span.comments{color:#8a8a8a;float:right; background:#FFF url(images/comment.gif) no-repeat left center; padding-left:15px; margin-left:2px}
+
+/*
+-----------------------------------------
+POSTS
+-----------------------------------------
+*/
+.post-category{color:#8a8a8a; float:right; margin-bottom:8px}
+.post-tags{color:#8a8a8a; float:left; margin-bottom:8px}
+
+.post-category p,
+.post-tags p{color:#8A8A8A; font-size:1em; line-height:1.5em; margin-bottom:0em; margin-top:0em; text-align:none}
+.post img,
+#wikitext img{margin:0.5em 1em;}
+.post blockquote p {margin:0 2.6em; font-style:italic}
+
+/*
+-----------------------------------------
+COMMENTS
+-----------------------------------------
+*/
+#comments {clear:both; overflow:hidden}
+#comments .comment-heading{margin-top: 40px; margin-bottom:26px; text-transform:none; border:none}
+#comments .commentwrap, #wikitext .commentwrap{border-top:1px solid #C9C9C9; padding-bottom:25px; padding-top:15px}
+
+#comments .commentpost, #wikitext .commentpost{float:right; width:510px; padding:0.3em}
+#comments .commentpost p, #wikitext .commentpost p{margin-top:0}
+
+#comments .commentmetadata, #wikitext .commentmetadata{float:left; width:20%; color:#2F2B23; line-height:1.5em; padding-right:20px; color:#999; font-size:1.1em}
+#comments .commentmetadata li, #wikitext .commentmetadata li{list-style-type:none; padding:.3em; margin:0 .5em 0 0; font-size:1em;}
+#comments .commentmetadata li a, #wikitext .commentmetadata li a{border-bottom:1px solid #c9c9c9; text-decoration:none}
+
+#comments .warning{padding:10px; background:#282828; border:1px solid #323232; ; margin-bottom:10px}
+
+#comments label input {width:160px}
+
+#comments label input,
+#wikitext input{border:1px solid #E5E5E5; padding:5px 4px; margin-bottom:10px}
+
+#comments label span,
+#comments span.label{line-height:27px}
+
+#comments label,
+#comments .label,
+#wikitext input{font-family:"Lucida Sans Unicode"; font-size:1.1em}
+
+#comment_author{margin:20px 20px 20px 0px; padding:0px; width:150px; float:left}
+#comments-content{display:block; border-bottom:1px solid #C9C9C9; margin:10px 0px 10px 0px; padding:0px}
+#comments textarea,
+#wikitext textarea{padding:4px 0px; width:100%; border:1px solid #E5E5E5}
+
+.button{border:1px solid #E5E5E5; font-size:1.1em; font-weight:bold; height:25px; margin-top:10px; margin-bottom:10px; padding:0 8px; text-transform:uppercase}
+
+.children {margin-left: 50px}
+.children div {border:none}
+.children .commentwrap {border-top: 1px solid #C9C9C9;}
+.children .commentmetadata {padding-right:0px}
+.children .commentpost {text-align:left; float:right; width:78%}
+
+/*
+-----------------------------------------
+SEARCH
+-----------------------------------------
+*/
+#searchform{float:left; margin-top:1em; height:2.3em}
+#searchsubmit{border:1px solid #E5E5E5; font-size:1.1em; font-weight:bold; height:2.1em; padding:2px 8px; text-transform:uppercase; float:right; background-color:#F0F0F0}
+#s{float:left; width:204px; margin-right:6px; padding-top:4px; padding-bottom:4px; padding-left:2px; padding-right:2px; border:1px solid #E5E5E5; font-size:1.1em}
+
+/*
+-----------------------------------------
+PMWIKI
+-----------------------------------------
+*/
+#footer .credits {clear: left; margin-top: 2.5em; font-size:1em; color: #8A8A8A;}
+#footer .credits a {color: #8A8A8A}
+#top .createlink, #top ul .createlink { display: none !important}
+.pageactions {position:absolute;right:5px;top:-70px}
+.pageactions li a {font-size:9px !important; color: #C9C9C9 !important; text-transform: lowercase !important}
+.pagegroup {display:block; margin-top: 9.3px;color: #8A8A8A; font-size:1.1em; text-transform: lowercase;text-decoration: none}
+ a.createlinktext { text-decoration:none; border-bottom:none; }
+a.createlink { text-decoration:none; position:relative; top:-0.5em; font-weight:bold; font-size:smaller; border-bottom:none; }
+.blogit-page-navigation{clear:both; padding:20px 0}
+.blogit-older-entries a, .blogit-newer-entries a {font-size:130%; font-weight: bold;}
+.blogit-older-entries a {float:right;}
+.blogit-newer-entries a {float:left;}
+.blogit-listmore {text-align:right;}
+.blogit-readmore {display: block; margin-top: 10px; padding-bottom: 10px; font-weight: bold;}
+.wikimessage {color: red; font-weight: bold; font-size: 110%; }
+#captcha { display: inline; font-weight: bold;}
+#captcha input { width: 50px; }
+#wikitext dd, #wikitext .indent { margin-left:40px; }
+#wikitext .outdent {margin: 1em 40px .5em 40px; text-indent:-40px; }
+#wikitext .quickref {background-color: #fff; font-size: 100% !important; margin-top: 4em}
+#wikitext .quickref p, #wikitext .quickref .outdent, #wikitext .quickref div, #wikitext .quickref strong {font-size:1em; margin:0; text-align:left; text-indent:0; line-height: 2em}
+#wikitext .quickref br {display:none}
+#wikitext code.escaped,
+#wikitext pre {font-size:140%; background-color: #f6f6f6; overflow: auto; height: auto; width: 90%; margin: 1.5em auto; padding: .15em; color: #666}
+#wikitext hr {border:1px solid #C9C9C9; margin:3em 0}
+#wikiedit img {margin:0}
+#wikiedit a {border:0}
+#wikiedit #text {width:99%}
+.difftime, .difftype {font-size: 1em !important}
+.postMeta-post .blogit-edit {float:right; margin-right:5px; padding-right:5px; border-bottom: none !important }
+.force_contain:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; }
+.force_contain { display: inline-block; _height: 1%; }
+/* Hides from IE-mac \*/
+.force_contain { display: block; }
+/* End hide from IE-mac */
diff --git a/pub/skins/equilibrium/wikilib.d/Site.BlogIt-SkinTemplate-equilibrium b/pub/skins/equilibrium/wikilib.d/Site.BlogIt-SkinTemplate-equilibrium
new file mode 100644
index 0000000..f7c8106
--- /dev/null
+++ b/pub/skins/equilibrium/wikilib.d/Site.BlogIt-SkinTemplate-equilibrium
@@ -0,0 +1,12 @@
+version=pmwiki-2.2.1 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3 (.NET CLR 3.5.30729)
+author=daveg
+charset=ISO-8859-1
+csum=
+ctime=1238968598
+host=127.0.0.1
+name=Site.BlogIt-SkinTemplate-equilibrium
+rev=160
+targets=
+text=!!! #multi-entry-view%0aParameters: pagenav, perpage, cols%0a%0a[@%0a(:if false:)[[#multi-entry-view]](:if:)%0a(:template defaults order=-$:entrydate:)%0a(:template each:)%0a(:if equal 1 {(mod {$$PageCount} {$$cols})}:)(:div9989 class="row-wrap":)(:if:)%0a(:div9990 class="post-wrap (:if equal 0 {(mod {$$PageCount} {$$cols})}:)no-right-margin(:if:)":)%0a(:div9991 class="post-head":)%0a(:div9992 class="title":)%0a!! [[{=$FullName}|{=$Title}]]%0a(:div9992end:)(:if !bi_isnull {=$:featured_image}:)[[{=$FullName} | {=$:featured_image}]](:if:)%0a(:div9991end:)%0a(:div9991 class="content-wrap":)%0a(:div9993 class="postMeta":)%25date%25(:blogit-skin date fmt='short':){=$:entrydate}(:blogit-skinend:)%25%25 \%0a%25comments%25(:blogit-skin commentcount status='{=$:entrycomments}' group='{=$Group}' name='{=$Name}':)(:blogit-skinend:)%25%25%0a(:div9993end:)%0a>>clear%3c%3c%0a>>%3c%3c%0a(:blogit-skin intro class="post-content force_contain" page={=$FullName}:)%0a{=$:entrybody}(:blogit-skinend:)%0a>>clear%3c%3c%0a>>%3c%3c%0a(:div9991end:)%0a(:div9990end:)%0a(:if equal 0 {(mod {$$PageCount} {$$cols})}:)(:div9989end:)(:if:)%0a(:template last:)%0a(:includesection "#page-navigation itemsonpage={$$PageCount} pagenav={$$pagenav} perpage={$$perpage}":)%0a[[#multi-entry-viewend]]%0a@]%0a%0a!!! #single-entry-view%0a[@%0a(:if false:)[[#single-entry-view]](:if:)%0a(:div9991 class="postMeta-post":)%25date%25\%0a(:blogit-skin author pre_text='$[by] ' post_text=' $[on] ':){*$:entryauthor}(:blogit-skinend:)\%0a(:blogit-skin date fmt='long':)*$:entrydate}(:blogit-skinend:)%25%25\%0a(:blogit-skin tags pre_text='%25post-category%25' post_text='%25%25':){*$:entrytags}(:blogit-skinend:)\%0a%25comments%25(:blogit-skin commentcount status='{*$:entrycomments}' group='{*$Group}' name='{*$Name}':)(:blogit-skinend:)%25%25\%0a(:blogit-skin edit pre_text='%25blogit-edit accesskey="$[ak_edit]"%25' post_text='%25%25' page='{*$Group}.{*$Name}':)$[edit](:blogit-skinend:)%0a>>clear%3c%3c%0a>>%3c%3c%0a(:div9991end:)%0a{*$:entrybody}%0a%0a(:includesection "#comments-pagelist pagename={*$Name} group={*$Group} entrycomments={*$:entrycomments} divid=comments":)%0a[[#single-entry-viewend]]%0a@]%0a%0a!!! #comment-view-all%0a[@%0a(:if false:)[[#comment-view-all]](:if:)%0a(:template first:)%0a!!%25block comment-heading%25$[Comments]%0a%0a(:template each:)%0a(:div9990 class="commentwrap":)%0a* [[#T{=$:commentdate}]]%25list commentmetadata%25(:blogit-skin commentauthor website='{=$:website}' author='{=$:commentauthor}':)(:blogit-skinend:)%0a* {(ftime fmt="$[%25b %25d, %25Y, %25H:%25M]" when=@{=$:commentdate})}%0a* %0a* (:includesection "#admin-links commentstatus='{=$:commentapproved}' commentpage='{=$FullName}'":)%0a(:div9991 class="commentpost":)%0a%25commenttext%25(:blogit-skin commenttext page='{=$FullName}':){=$:commenttext}(:blogit-skinend:)%25%25%0a(:div9991end:)%0a>>clear%3c%3c%0a>>%3c%3c%0a(:div9990end:)%0a[[#comment-viewend]]%0a@]%0a%0a!!! #comment-form%0a[@%0a(:if false:)[[#comment-form]](:if:)%0a!!! %25block id=reply%25$[Leave a Comment]%0a(:messages:)\\%0a%25label%25$[Name] $[(required)]%25%25\\%0a(:input text $:commentauthor id="comment-author":)\\%0a%25label%25$[E-mail] $[(required, will not be published)]%25%25\\%0a(:input text $:email id="comment-email":)\\%0a%25label%25$[Website (optional)]%25%25\\%0a(:input text $:website id="comment-website":)\\%0a%25label%25$[Comment]%25%25\%0a(:input textarea $:commenttext rows=10 cols=50 id="comment-text":)\\%0a(:if equal {$EnablePostCaptchaRequired} 1:)$[Enter value:] {$Captcha} (:input captcha:) (:if:)\\%0a(:input submit class="button" name=post value="$[Post]" id="comment-post":)\%0a[[#comment-formend]]%0a@]
+
diff --git a/pub/skins/equilibrium/wikilib.d/Site.SiteFooter b/pub/skins/equilibrium/wikilib.d/Site.SiteFooter
new file mode 100644
index 0000000..80df693
--- /dev/null
+++ b/pub/skins/equilibrium/wikilib.d/Site.SiteFooter
@@ -0,0 +1,12 @@
+(:markdownend:)
+version=pmwiki-2.2.1 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1) Gecko/20090624 Firefox/3.5 (.NET CLR 3.5.30729)
+author=
+charset=ISO-8859-1
+csum=
+ctime=1246582656
+host=127.0.0.1
+name=Site.SiteFooter
+rev=6
+targets=
+text=$[Page last modified on {*$LastModified}]
\ No newline at end of file
diff --git a/pub/skins/equilibrium/wikilib.d/Site.SiteHeader b/pub/skins/equilibrium/wikilib.d/Site.SiteHeader
new file mode 100644
index 0000000..243b187
--- /dev/null
+++ b/pub/skins/equilibrium/wikilib.d/Site.SiteHeader
@@ -0,0 +1,12 @@
+version=pmwiki-2.2.1 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1) Gecko/20090624 Firefox/3.5 (.NET CLR 3.5.30729)
+author=
+charset=ISO-8859-1
+csum=
+ctime=1194389975
+host=127.0.0.1
+name=Site.SiteHeader
+rev=37
+targets=
+text=! %25block sitetitle%25[[{$ScriptUrl} | {$WikiTitle}]]%0a(:div class="sitetag":){$WikiTag}%0a(:divend:)
+(:markdown:)
\ No newline at end of file
diff --git a/pub/skins/equilibrium/wikilib.d/Site.SiteNav b/pub/skins/equilibrium/wikilib.d/Site.SiteNav
new file mode 100644
index 0000000..cf3ed74
--- /dev/null
+++ b/pub/skins/equilibrium/wikilib.d/Site.SiteNav
@@ -0,0 +1,13 @@
+version=pmwiki-2.2.0 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.8) Gecko/2009032609 Firefox/3.0.8 (.NET CLR 3.5.30729)
+author=
+charset=ISO-8859-1
+csum=
+ctime=1238793180
+host=127.0.0.1
+name=Site.SiteNav
+rev=2
+targets=
+text=* [[PmWiki/PmWiki]]%0a* [[tab2]]%0a* [[tab3]]%0a
+time=1238894638
+
diff --git a/pub/skins/equilibrium/wikilib.d/Site.XLPage-equilibrium b/pub/skins/equilibrium/wikilib.d/Site.XLPage-equilibrium
new file mode 100644
index 0000000..bc50ea2
--- /dev/null
+++ b/pub/skins/equilibrium/wikilib.d/Site.XLPage-equilibrium
@@ -0,0 +1,12 @@
+version=pmwiki-2.2.1 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3 (.NET CLR 3.5.30729)
+
+charset=ISO-8859-1
+csum=
+ctime=1254105809
+host=127.0.0.1
+name=Site.XLPage-equilibrium
+rev=3
+targets=
+text=### Equilibrium Template%0a 'Search' => '',%0a 'theme originally by' => '',%0a 'adapted by' => '',%0a 'powered by' => '',%0a%0a### Site.Blogit-SkinTemplate-equilibrium%0a%0a ## #single-entry-view%0a 'by' => '',%0a%0a ## #comment-form%0a '(required)' => '',%0a '(required, will not be published)' => '',%0a 'Website (optional)' => '',%0a 'Page last modified on {*$LastModified}' => '',%0a '%25b %25d, %25Y, %25H:%25M' => ''%0a
+
diff --git a/pub/skins/pmwiki/README b/pub/skins/pmwiki/README
new file mode 100644
index 0000000..2374d41
--- /dev/null
+++ b/pub/skins/pmwiki/README
@@ -0,0 +1,22 @@
+This directory contains the files to display pages in PmWiki according
+to the default layout.
+
+==>Don't edit these files directly, as you may lose your edits the
+next time you upgrade PmWiki!
+
+Instead, copy the files to another directory in pub/skins/ and edit
+them there. You can then configure PmWiki to use your modified layout
+files by setting the $Skin variable in your local/config.php. For
+example, if you copy your custom skin to pub/skins/custom, then you
+would set
+ $Skin = 'custom';
+in local/config.php.
+
+The files in this directory:
+ pmwiki.tmpl -- the default template for page layouts
+ pmwiki.css -- PmWiki's default css
+ pmwiki-32.gif -- the PmWiki logo
+
+If you just want to change the logo, you can do it by setting $PageLogoUrl
+to the url location of your logo.
+
diff --git a/pub/skins/pmwiki/pmwiki-32.gif b/pub/skins/pmwiki/pmwiki-32.gif
new file mode 100644
index 0000000..6f74964
Binary files /dev/null and b/pub/skins/pmwiki/pmwiki-32.gif differ
diff --git a/pub/skins/pmwiki/pmwiki.css b/pub/skins/pmwiki/pmwiki.css
new file mode 100644
index 0000000..eb3e3fb
--- /dev/null
+++ b/pub/skins/pmwiki/pmwiki.css
@@ -0,0 +1,102 @@
+/***********************************************************************
+** pmwiki.css
+** Copyright 2004-2006 Patrick R. Michaud (pmichaud@pobox.com)
+** Copyright 2006 Hagan Fox
+** This file is part of PmWiki; 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. See pmwiki.php for full details.
+***********************************************************************/
+
+/* This sets the overall frame for the site */
+body {
+ margin:0px; background-color:#f7f7f7;
+ font-family:Arial,Helvetica,sans-serif; font-size:11pt;
+}
+
+/* These control the fixed-width text elements of the page */
+textarea, pre, code { font-size:0.9em; }
+pre, code { font-family:'Lucida Console','Andale Mono','Courier New',Courier,monospace; }
+pre { line-height:1.2em; }
+pre code, code code, pre pre { font-size:100%; }
+
+/* These primarily adjust the size and spacing of heading elements,
+** most browsers have atrocious defaults for these. */
+h1, h2, h3, h4, h5, h6 { margin-top:1.0em; margin-bottom:0.6em; }
+h1, h2, h3, h6 { font-weight:normal; }
+h4, h5 { font-weight:bold; }
+h1 code, h2 code, h3 code, h4 code { font-size:1em; }
+h1 { font-size:1.8em; }
+h2 { font-size:1.44em; }
+h3 { font-size:1.22em; }
+h4 { font-size:1.07em; }
+h5 { font-size:1.0em; }
+h6 { font-size:1.0em; }
+
+/* The #wikilogo element is the logo from $PageLogoFmt */
+#wikilogo { margin-top:4px; padding:6px; border-bottom:1px #cccccc solid; }
+
+/* This controls the rest of the heading (primarily the search box) */
+#wikihead {
+ position:absolute; right:10px; top:10px;
+ font-family:Verdana,sans-serif; font-size:85%;
+}
+#wikihead input { font-size:85%; }
+
+/* These are for the left-sidebar. */
+#wikileft {
+ width:155px;
+ padding:6px; border-right:1px #cccccc solid;
+ line-height:1.33em;
+ font-size:9.4pt; font-family:Verdana,sans-serif;
+}
+#wikileft .vspace { margin-top:1.125em; }
+#wikileft a { text-decoration:none; color:black; }
+#wikileft a:hover { text-decoration:underline; color:blue; }
+#wikileft ul { list-style:none; padding:0px; margin:0px; }
+#wikileft li { margin:0px; padding-left: 6px; }
+.sidehead {
+ margin:0px; padding:4px 2px 2px 2px;
+ font-size:11pt; font-weight:bold; font-style:normal;
+}
+.sidehead a
+ { color:#505050; font-weight:bold; font-style:normal; }
+
+/* These affect the main content area. */
+#wikibody {
+ padding:0px 10px 10px 10px; background-color:white;
+ font-size:11pt;
+}
+#wikicmds {
+ float:right; white-space:nowrap;
+ font-family:Verdana,sans-serif; font-size:80%;
+}
+#wikicmds ul { list-style:none; margin:0px; padding:0px; }
+#wikicmds li { display:inline; margin:0px 5px; }
+#wikicmds li a { text-decoration:none; color:black; border:none; }
+#wikicmds li a.createlink { display:none; }
+#wikicmds li a:hover { text-decoration:underline; color:blue; }
+.pagegroup { margin-top:8px; margin-bottom:2px; }
+.pagetitle { line-height:1em; margin:0px; font-size:1.6em; font-weight:normal; }
+.wikiaction { margin-top:4px; margin-bottom:4px; }
+#wikitext { margin-top:12px; line-height:1.33em; }
+#wikitext table { font-size:100%; line-height:1.33em; } /* For MSIE 5.5 */
+
+/* These are for the edit form. */
+#wikiedit form { margin:0px; width:100%; }
+#wikiedit textarea { width:100%; }
+.wikimessage { margin-top:4px; margin-bottom:4px; font-style:italic; }
+
+/* These affect the lines at the very bottom. */
+#wikifoot {
+ padding-left:178px; padding-bottom:4px; border-top:1px #cccccc solid;
+ font-family:Verdana,sans-serif; font-size:80%;
+}
+
+/* These affect the printed appearance of the web view (not the separate
+** print view) of pages. The sidebar and action links aren't printed. */
+@media print {
+ body { width:auto; margin:0px; padding:0.5em; }
+ #wikihead, #wikileft, #wikicmds, .footnav { display:none; }
+ #wikifoot { padding:2px; }
+}
diff --git a/pub/skins/pmwiki/pmwiki.tmpl b/pub/skins/pmwiki/pmwiki.tmpl
new file mode 100644
index 0000000..7b66be0
--- /dev/null
+++ b/pub/skins/pmwiki/pmwiki.tmpl
@@ -0,0 +1,52 @@
+
+
+
+
$WikiTitle | {$Group} / {$Title} $ActionTitle
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pub/skins/print/README b/pub/skins/print/README
new file mode 100644
index 0000000..7dadea1
--- /dev/null
+++ b/pub/skins/print/README
@@ -0,0 +1,20 @@
+This directory contains the files to print pages in PmWiki for ?action=print.
+This is a template just like any other layout skin, except that for
+?action=print PmWiki looks for print.tmpl instead of screen.tmpl.
+
+==>Don't edit these files directly, as you may lose your edits the
+next time you upgrade PmWiki!
+
+Instead, copy the files to another directory in pub/skins/ and edit
+them there. You can then configure PmWiki to use your modified layout
+files by setting $ActionSkin['print'] to the name of your new skin.
+For example, if you copy your custom print skin to pub/skins/custom,
+then you would set
+ $ActionSkin['print'] = 'custom';
+in local/config.php.
+
+The files in this directory:
+ print.tmpl -- the default template for ?action=print
+ print.css -- the print template's css
+ print.php -- loaded when the skin is loaded, it redefines the link
+ formats to a form better suited for printing
diff --git a/pub/skins/print/print.css b/pub/skins/print/print.css
new file mode 100644
index 0000000..5244ff5
--- /dev/null
+++ b/pub/skins/print/print.css
@@ -0,0 +1,50 @@
+/***********************************************************************
+** print.css
+** Copyright 2004 Patrick R. Michaud (pmichaud@pobox.com)
+** This file is part of PmWiki; 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. See pmwiki.php for full details.
+***********************************************************************/
+
+/***********************************************************************
+** These settings are part of the ?action=print skin. If you want
+** to change these settings, create a new print template and set
+** $PrintTemplateFmt in the config.php file to point to your new
+** printing skin.
+***********************************************************************/
+
+body {
+ width:auto;
+ background-color:white;
+ color:black;
+ font-family:serif;
+}
+
+#printhead {
+ font-family:sans-serif;
+ border-top:3px solid #a0a0a0;
+ border-bottom:5px solid #a0a0a0;
+ margin-bottom:1em;
+}
+#printhead h3 { margin-top:0px; }
+#printhead h1 { margin-bottom:0px; }
+
+#printtitle {
+}
+
+#printfoot {
+ clear:both;
+ margin-top:1em;
+ border-top:5px solid #a0a0a0;
+ font-size:smaller;
+}
+
+
+a:link { color:#444444; font-weight:bold; text-decoration:none; }
+a:visited { color:#444444; font-weight:bold; text-decoration:none; }
+a.wikilink:hover { color: #444444; text-decoration:underline; }
+a.createlink { color:#444444; }
+a.createlink:visited { color:#444444; }
+a.createlink:hover { color:#ff2222; }
+
diff --git a/pub/skins/print/print.php b/pub/skins/print/print.php
new file mode 100644
index 0000000..4d30dd0
--- /dev/null
+++ b/pub/skins/print/print.php
@@ -0,0 +1,29 @@
+\$LinkText";
+SDV($GroupPrintHeaderFmt,'(:include $Group.GroupPrintHeader basepage={*$FullName}:)(:nl:)');
+SDV($GroupPrintFooterFmt,'(:nl:)(:include $Group.GroupPrintFooter basepage={*$FullName}:)');
+$GroupHeaderFmt = $GroupPrintHeaderFmt;
+$GroupFooterFmt = $GroupPrintFooterFmt;
+
diff --git a/pub/skins/print/print.tmpl b/pub/skins/print/print.tmpl
new file mode 100644
index 0000000..1dd1157
--- /dev/null
+++ b/pub/skins/print/print.tmpl
@@ -0,0 +1,20 @@
+
+
+
$WikiTitle | {$Group} / {$Title}
+
+
+
+
+
+
+
+
+
+
diff --git a/scripts/author.php b/scripts/author.php
new file mode 100644
index 0000000..5e68270
--- /dev/null
+++ b/scripts/author.php
@@ -0,0 +1,55 @@
+$[An author name is required.]");
+Markup('[[~','
"FmtPageName('[[~\$Author]] \$CurrentTime', \$pagename)",
+ '/(? "FmtPageName('[[~\$Author]]', \$pagename)"));
+ Markup('~~~~','<[[~','/(?~~~~','/(?.
+
+ This script enables simple authentication based on username and
+ password combinations. At present this script can authenticate
+ from passwords held in arrays or in .htpasswd-formatted files,
+ but eventually it will support authentication via sources such
+ as LDAP and Active Directory.
+
+ To configure a .htpasswd-formatted file for authentication, do
+ $AuthUser['htpasswd'] = '/path/to/.htpasswd';
+ prior to including this script.
+
+ Individual username/password combinations can also be placed
+ directly in the $AuthUser array, such as:
+ $AuthUser['pmichaud'] = crypt('secret');
+
+ To authenticate against an LDAP server, put the url for
+ the server in $AuthUser['ldap'], as in:
+ $AuthUser['ldap'] = 'ldap://ldap.example.com/ou=People,o=example?uid';
+*/
+
+# let Site.AuthForm know that we're doing user-based authorization
+$EnableAuthUser = 1;
+
+if (@$_POST['authid'])
+ AuthUserId($pagename, stripmagic(@$_POST['authid']),
+ stripmagic(@$_POST['authpw']));
+else SessionAuth($pagename);
+
+function AuthUserId($pagename, $id, $pw=NULL) {
+ global $AuthUser, $AuthUserPageFmt, $AuthUserFunctions,
+ $AuthId, $MessagesFmt;
+
+ $auth = array();
+ foreach((array)$AuthUser as $k=>$v) $auth[$k] = (array)$v;
+ $authid = '';
+
+ # load information from SiteAdmin.AuthUser (or page in $AuthUserPageFmt)
+ SDV($AuthUserPageFmt, '$SiteAdminGroup.AuthUser');
+ SDVA($AuthUserFunctions, array(
+ 'htpasswd' => 'AuthUserHtPasswd',
+ 'ldap' => 'AuthUserLDAP',
+# 'mysql' => 'AuthUserMySQL',
+ $id => 'AuthUserConfig'));
+
+ $pn = FmtPageName($AuthUserPageFmt, $pagename);
+ $apage = ReadPage($pn, READPAGE_CURRENT);
+ if ($apage && preg_match_all("/^\\s*([@\\w][^\\s:]*):(.*)/m",
+ $apage['text'], $matches, PREG_SET_ORDER)) {
+ foreach($matches as $m) {
+ if (!preg_match_all('/\\bldaps?:\\S+|[^\\s,]+/', $m[2], $v))
+ continue;
+ if ($m[1]{0} == '@')
+ foreach($v[0] as $g) $auth[$g][] = $m[1];
+ else $auth[$m[1]] = array_merge((array)@$auth[$m[1]], $v[0]);
+ }
+ }
+
+ if (func_num_args()==2) $authid = $id;
+ else
+ foreach($AuthUserFunctions as $k => $fn)
+ if (@$auth[$k] && $fn($pagename, $id, $pw, $auth[$k]))
+ { $authid = $id; break; }
+
+ if (!$authid) { $GLOBALS['InvalidLogin'] = 1; return; }
+ if (!isset($AuthId)) $AuthId = $authid;
+ $authlist["id:$authid"] = 1;
+ $authlist["id:-$authid"] = -1;
+ foreach(preg_grep('/^@/', (array)@$auth[$authid]) as $g)
+ $authlist[$g] = 1;
+ foreach(preg_grep('/^@/', (array)@$auth['*']) as $g)
+ $authlist[$g] = 1;
+ foreach(preg_grep('/^@/', array_keys($auth)) as $g)
+ if (in_array($authid, $auth[$g])) $authlist[$g] = 1;
+ if ($auth['htgroup']) {
+ foreach(AuthUserHtGroup($pagename, $id, $pw, $auth['htgroup']) as $g)
+ $authlist["@$g"] = 1;
+ }
+ SessionAuth($pagename, array('authid' => $authid, 'authlist' => $authlist));
+}
+
+
+function AuthUserConfig($pagename, $id, $pw, $pwlist) {
+ foreach ((array)$pwlist as $chal)
+ if (_crypt($pw, $chal) == $chal) return true;
+ return false;
+}
+
+
+function AuthUserHtPasswd($pagename, $id, $pw, $pwlist) {
+ foreach ((array)$pwlist as $f) {
+ $fp = fopen($f, "r"); if (!$fp) continue;
+ while ($x = fgets($fp, 1024)) {
+ $x = rtrim($x);
+ @list($i, $c, $r) = explode(':', $x, 3);
+ if ($i == $id && _crypt($pw, $c) == $c) { fclose($fp); return true; }
+ }
+ fclose($fp);
+ }
+ return false;
+}
+
+
+function AuthUserHtGroup($pagename, $id, $pw, $pwlist) {
+ $groups = array();
+ foreach ((array)$pwlist as $f) {
+ $fp = fopen($f, 'r'); if (!$fp) continue;
+ while ($x = fgets($fp, 4096)) {
+ if (preg_match('/^(\\w[^\\s:]+)\\s*:(.*)$/', trim($x), $match)) {
+ $glist = preg_split('/[\\s,]+/', $match[2], -1, PREG_SPLIT_NO_EMPTY);
+ if (in_array($id, $glist)) $groups[$match[1]] = 1;
+ }
+ }
+ fclose($fp);
+ }
+ return array_keys($groups);
+}
+
+
+function AuthUserLDAP($pagename, $id, $pw, $pwlist) {
+ global $AuthLDAPBindDN, $AuthLDAPBindPassword;
+ if (!$pw) return false;
+ if (!function_exists('ldap_connect'))
+ Abort('authuser: LDAP authentication requires PHP ldap functions','ldapfn');
+ foreach ((array)$pwlist as $ldap) {
+ if (!preg_match('!(ldaps?://[^/]+)/(.*)$!', $ldap, $match))
+ continue;
+ ## connect to the LDAP server
+ list($z, $url, $path) = $match;
+ $ds = ldap_connect($url);
+ ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3);
+ ## For Active Directory, don't specify a path and we simply
+ ## attempt to bind with the username and password directly
+ if (!$path && @ldap_bind($ds, $id, $pw)) { ldap_close($ds); return true; }
+ ## Otherwise, we use Apache-style urls for LDAP authentication
+ ## Split the path into its search components
+ list($basedn, $attr, $sub, $filter) = explode('?', $path);
+ if (!$attr) $attr = 'uid';
+ if (!$sub) $sub = 'one';
+ if (!$filter) $filter = '(objectClass=*)';
+ $binddn = @$AuthLDAPBindDN;
+ $bindpw = @$AuthLDAPBindPassword;
+ if (ldap_bind($ds, $binddn, $bindpw)) {
+ ## Search for the appropriate uid
+ $fn = ($sub == 'sub') ? 'ldap_search' : 'ldap_list';
+ $sr = $fn($ds, $basedn, "(&$filter($attr=$id))", array($attr));
+ $x = ldap_get_entries($ds, $sr);
+ ## If we find a unique id, bind to it for success
+ if ($x['count'] == 1) {
+ $dn = $x[0]['dn'];
+ if (@ldap_bind($ds, $dn, $pw)) { ldap_close($ds); return true; }
+ }
+ }
+ ldap_close($ds);
+ }
+ return false;
+}
+
+
+# The _crypt function provides support for SHA1 encrypted passwords
+# (keyed by '{SHA}') and Apache MD5 encrypted passwords (keyed by
+# '$apr1$'); otherwise it just calls PHP's crypt() for the rest.
+# The APR MD5 encryption code was contributed by D. Faure.
+
+function _crypt($plain, $salt=null) {
+ if (strncmp($salt, '{SHA}', 5) == 0)
+ return '{SHA}'.base64_encode(pack('H*', sha1($plain)));
+ if (strncmp($salt, '$apr1$', 6) == 0) {
+ preg_match('/^\\$apr1\\$([^$]+)/', $salt, $match);
+ $salt = $match[1];
+ $length = strlen($plain);
+ $context = $plain . '$apr1$' . $salt;
+ $binary = pack('H32', md5($plain . $salt . $plain));
+ for($i = $length; $i > 0; $i -= 16)
+ $context .= substr($binary, 0, min(16, $i));
+ for($i = $length; $i > 0; $i >>= 1)
+ $context .= ($i & 1) ? chr(0) : $plain{0};
+ $binary = pack('H32', md5($context));
+ for($i = 0; $i < 1000; $i++) {
+ $new = ($i & 1) ? $plain : $binary;
+ if ($i % 3) $new .= $salt;
+ if ($i % 7) $new .= $plain;
+ $new .= ($i & 1) ? $binary : $plain;
+ $binary = pack('H32', md5($new));
+ }
+ $q = '';
+ for ($i = 0; $i < 5; $i++) {
+ $k = $i + 6;
+ $j = $i + 12;
+ if ($j == 16) $j = 5;
+ $q = $binary{$i}.$binary{$k}.$binary{$j} . $q;
+ }
+ $q = chr(0).chr(0).$binary{11} . $q;
+ $q = strtr(strrev(substr(base64_encode($q), 2)),
+ 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/',
+ './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz');
+ return "\$apr1\$$salt\$$q";
+ }
+ if (md5($plain) == $salt) return $salt;
+ return crypt($plain, $salt);
+}
diff --git a/scripts/blocklist.php b/scripts/blocklist.php
new file mode 100644
index 0000000..62285d9
--- /dev/null
+++ b/scripts/blocklist.php
@@ -0,0 +1,239 @@
+ 1));
+ if (isset($_POST['text']) && @$BlocklistActions[$action]) {
+ Blocklist($pagename, $_POST['text']);
+ if (!$EnablePost) {
+ unset($_POST['post']);
+ unset($_POST['postattr']);
+ unset($_POST['postedit']);
+ }
+ }
+}
+
+
+## If $EnableBlocklist is set to 10 or higher, then arrange to
+## periodically download the "chongqed" and "moinmaster" blacklists.
+if ($EnableBlocklist >= 10) {
+ SDVA($BlocklistDownload['SiteAdmin.Blocklist-Chongqed'], array(
+ 'url' => 'http://blacklist.chongqed.org/',
+ 'format' => 'regex'));
+ SDVA($BlocklistDownload['SiteAdmin.Blocklist-MoinMaster'], array(
+ 'url' => 'http://moinmaster.wikiwikiweb.de/BadContent?action=raw',
+ 'format' => 'regex'));
+}
+
+
+## CheckBlocklist is inserted into $EditFunctions, to automatically
+## check for blocks on anything being posted through the normal
+## "update a page cycle"
+array_unshift($EditFunctions, 'CheckBlocklist');
+function CheckBlocklist($pagename, &$page, &$new) {
+ StopWatch("CheckBlocklist: begin $pagename");
+ $ptext = implode('', @$_POST);
+ if (@$ptext) Blocklist($pagename, $ptext);
+ StopWatch("CheckBlocklist: end $pagename");
+}
+
+
+## Blocklist is the function that does all of the work of
+## checking for reasons to block a posting. It reads
+## the available blocklist pages ($BlocklistPages) and
+## builds an array of strings and regular expressiongs to
+## be checked against the page; if any are found, then
+## posting is blocked (via $EnablePost=0). The function
+## also checks the REMOTE_ADDR against any blocked IP addresses.
+function Blocklist($pagename, $text) {
+ global $BlocklistPages, $BlockedMessagesFmt, $BlocklistDownload,
+ $BlocklistDownloadRefresh, $Now, $EnablePost, $WhyBlockedFmt,
+ $MessagesFmt, $BlocklistMessageFmt, $EnableWhyBlocked, $IsBlocked;
+
+ StopWatch("Blocklist: begin $pagename");
+
+ $BlocklistDownload = (array)@$BlocklistDownload;
+ SDV($BlocklistPages,
+ array_merge(array('$SiteAdminGroup.Blocklist',
+ '$SiteAdminGroup.Blocklist-Farm'),
+ array_keys($BlocklistDownload)));
+ SDV($BlocklistMessageFmt, "$[This post has been blocked by the administrator] ");
+ SDVA($BlockedMessagesFmt, array(
+ 'ip' => '$[Address blocked from posting]: ',
+ 'text' => '$[Text blocked from posting]: '));
+ SDV($BlocklistDownloadRefresh, 86400);
+
+ ## Loop over all blocklist pages
+ foreach((array)$BlocklistPages as $b) {
+
+ ## load the current blocklist page
+ $pn = FmtPageName($b, $pagename);
+ $page = ReadPage($pn, READPAGE_CURRENT);
+ if (!$page) continue;
+
+ ## if the page being checked is a blocklist page, stop blocking
+ if ($pagename == $pn) return;
+
+ ## If the blocklist page is managed by automatic download,
+ ## schedule any new downloads here
+ if (@$BlocklistDownload[$pn]) {
+ $bd = &$BlocklistDownload[$pn];
+ SDVA($bd, array(
+ 'refresh' => $BlocklistDownloadRefresh,
+ 'url' => "http://www.pmwiki.org/blocklists/$pn" ));
+ if (!@$page['text'] || $page['time'] < $Now - $bd['refresh'])
+ register_shutdown_function('BlocklistDownload', $pn, getcwd());
+ }
+
+ ## If the blocklist is simply a list of regexes to be matched, load
+ ## them into $terms['block'] and continue to the next blocklist page.
+ ## Some regexes from remote sites aren't well-formed, so we have
+ ## to escape any slashes that aren't already escaped.
+ if (strpos(@$page['text'], 'blocklist-format: regex') !==false) {
+ if (preg_match_all('/^([^\\s#].+)/m', $page['text'], $match))
+ foreach($match[0] as $m) {
+ $m = preg_replace('#(?$why\n";
+ }
+ StopWatch("Blocklist: end $pagename");
+}
+
+
+## BlocklistDownload() handles retrieving blocklists from
+## external sources into PmWiki pages. If it's able to
+## download an updated list, it uses that; otherwise it leaves
+## any existing list alone.
+function BlocklistDownload($pagename, $dir = '') {
+ global $BlocklistDownloadFmt, $BlocklistDownload, $FmtV;
+
+ if ($dir) { flush(); chdir($dir); }
+ SDV($BlocklistDownloadFmt, "
+ [@
+## blocklist-note: NOTE: This page is automatically generated by blocklist.php
+## blocklist-note: NOTE: Any edits to this page may be lost!
+## blocklist-url: \$BlocklistDownloadUrl
+## blocklist-when: \$CurrentTimeISO
+# blocklist-format: \$BlocklistFormat
+\$BlocklistData
+ @]
+");
+
+ ## get the existing blocklist page
+ $bd = &$BlocklistDownload[$pagename];
+ $page = ReadPage($pagename, READPAGE_CURRENT);
+
+ ## try to retrieve the remote data
+ $blocklistdata = @file($bd['url']);
+
+ ## if we didn't get it, and we don't already have text, save a
+ ## note in the page so we know what happened
+ if (!$blocklistdata && !@$page['text']) {
+ $auf = ini_get('allow_url_fopen');
+ $blocklistdata = "#### Unable to download blocklist (allow_url_fopen=$auf)";
+ }
+
+ ## if we have some new text to save, let's format it and save it
+ if ($blocklistdata) {
+ $blocklistdata = implode('', (array)$blocklistdata);
+ $blocklistdata = preg_replace('/^##blocklist.*/m', '', $blocklistdata);
+ $FmtV['$BlocklistData'] = $blocklistdata;
+ $FmtV['$BlocklistDownloadUrl'] = $bd['url'];
+ $FmtV['$BlocklistFormat'] = $bd['format'];
+ $page['text'] = FmtPageName($BlocklistDownloadFmt, $pagename);
+ SDV($page['passwdread'], '@lock');
+ }
+
+ ## save our updated(?) blocklist page
+ WritePage($pagename, $page);
+}
diff --git a/scripts/caches.php b/scripts/caches.php
new file mode 100644
index 0000000..b4593bb
--- /dev/null
+++ b/scripts/caches.php
@@ -0,0 +1,63 @@
+ $LastModTime) $LastModTime = $v; }
+
+if (@$EnableIMSCaching) {
+ SDV($IMSCookie, $CookiePrefix.'imstime');
+ SDV($IMSCookieExpires, $Now + 60*60*24*30);
+ SDV($IMSInvalidators, array('authpw', 'author'));
+ $LogoutCookies[] = $IMSCookie;
+
+ if ($IMSCookie) {
+ $IMSTime = @$_COOKIE[$IMSCookie];
+ if ($IMSTime < $LastModTime
+ || array_intersect($IMSInvalidators, array_keys($_POST))) {
+ $IMSTime = $Now;
+ setcookie($IMSCookie, $IMSTime, $IMSCookieExpires, '/');
+ }
+ } else $IMSTime = $LastModTime;
+
+ if (in_array($action, (array)$CacheActions)) {
+ $HTTPLastMod = gmdate('D, d M Y H:i:s \G\M\T',$IMSTime);
+ $HTTPHeaders[] = "Cache-Control: no-cache";
+ $HTTPHeaders[] = "Last-Modified: $HTTPLastMod";
+ if (@$_SERVER['HTTP_IF_MODIFIED_SINCE']==$HTTPLastMod) {
+ header("HTTP/1.0 304 Not Modified");
+ header("Cache-Control: no-cache");
+ header("Expires: ");
+ header("Last-Modified: $HTTPLastMod");
+ exit();
+ }
+ }
+}
+
+if ($NoHTMLCache
+ || !@$PageCacheDir
+ || count($_POST) > 0
+ || count($_GET) > 2
+ || (count($_GET) == 1 && !@$_GET['n'])) { $NoHTMLCache |= 1; return; }
+
+mkdirp($PageCacheDir);
+if (!file_exists("$PageCacheDir/.htaccess")
+ && $fp = @fopen("$PageCacheDir/.htaccess", "w"))
+ { fwrite($fp, "Order Deny,Allow\nDeny from all\n"); fclose($fp); }
+$PageCacheFile = "$PageCacheDir/$pagename,cache";
+if (file_exists($PageCacheFile) && @filemtime($PageCacheFile) < $LastModTime)
+ @unlink($PageCacheFile);
+
diff --git a/scripts/creole.php b/scripts/creole.php
new file mode 100644
index 0000000..1470fca
--- /dev/null
+++ b/scripts/creole.php
@@ -0,0 +1,66 @@
+(.+?)\\*\\*)(?!\\S)|(?$1$2');
+
+## //emphasized//
+Markup('//', 'inline',
+ '/(?$1');
+
+## == Headings ==
+Markup('^=', 'block',
+ '/^(={1,6})\\s?(.*?)(\\s*=*\\s*)$/e',
+ "'<:block,1>$2 '");
+
+## Line breaks
+Markup('\\\\', 'inline', '/\\\\\\\\/', ' ');
+
+## Preformatted
+Markup('^{{{', '[=',
+ "/^\\{\\{\\{\n(.*?\n)\\}\\}\\}[^\\S\n]*\n/sme",
+ "Keep(PSS('$1 '))");
+Markup('{{{', '>{{{',
+ '/\\{\\{\\{(.*?)\\}\\}\\}/se',
+ "Keep(PSS('$1'))");
+
+## Tables
+Markup('|-table', '>^||',
+ '/^\\|(.*)$/e',
+ "FormatTableRow(PSS('$0'), '\\|')");
+
+## Images
+Markup('{{', 'inline',
+ '/\\{\\{(?>(\\L))([^|\\]]*)(?:\\|\\s*(.*?)\\s*)?\\}\\}/e',
+ "Keep(\$GLOBALS['LinkFunctions']['$1'](\$pagename, '$1', '$2', '$3',
+ '$1$2', \$GLOBALS['ImgTagFmt']),'L')");
+
+
+## GUIButtons
+SDVA($GUIButtons, array(
+ 'em' => array(100, "//", "//", '$[Emphasized]',
+ '$GUIButtonDirUrlFmt/em.gif"$[Emphasized (italic)]"',
+ '$[ak_em]'),
+ 'strong' => array(110, "**", "**", '$[Strong]',
+ '$GUIButtonDirUrlFmt/strong.gif"$[Strong (bold)]"',
+ '$[ak_strong]'),
+ 'h2' => array(400, '\\n== ', ' ==\\n', '$[Heading]',
+ '$GUIButtonDirUrlFmt/h.gif"$[Heading]"'),
+
+ ));
+
diff --git a/scripts/crypt.php b/scripts/crypt.php
new file mode 100644
index 0000000..f4a040e
--- /dev/null
+++ b/scripts/crypt.php
@@ -0,0 +1,41 @@
+
+ Enter password to encrypt:
+
+
+
+
",
+ $pagename);
+ if ($passwd) {
+ $crypt = crypt($passwd);
+ echo "Encrypted password = $crypt
";
+ echo "To set a site-wide password, insert the line below
+ in your config.php file, replacing 'type' with
+ one of 'admin' , 'read' , 'edit' ,
+ or 'attr' . See PasswordsAdmin for more
+ details.
+ \$DefaultPasswords['type']='$crypt'; ";
+ }
+ PrintFmt($pagename,$HTMLEndFmt);
+}
+
diff --git a/scripts/diag.php b/scripts/diag.php
new file mode 100644
index 0000000..6aee036
--- /dev/null
+++ b/scripts/diag.php
@@ -0,0 +1,53 @@
+$m)
+ $out .= sprintf("%-16s %-16s %-16s\n",$id,@$m['cmd'],@$m['seq']);
+ return $out;
+}
+
+$HandleActions['ruleset'] = 'HandleRuleset';
+
+function HandleRuleset($pagename) {
+ header("Content-type: text/plain");
+ print Ruleset();
+}
+
+function StopWatchHTML($pagename, $print = 0) {
+ global $StopWatch;
+ StopWatch('now');
+ $l = strlen(count($StopWatch));
+ $out = '';
+ foreach((array)$StopWatch as $i => $x)
+ $out .= sprintf("%{$l}d: %s\n", $i, $x);
+ $out .= ' ';
+ if (is_array($StopWatch)) array_pop($StopWatch);
+ if ($print) print $out;
+ return $out;
+}
+
diff --git a/scripts/draft.php b/scripts/draft.php
new file mode 100644
index 0000000..07c3879
--- /dev/null
+++ b/scripts/draft.php
@@ -0,0 +1,63 @@
+ ' '.XL('Publish').' '));
+SDVA($InputTags['e_saveeditbutton'], array('value' => ' '.XL('Save draft and edit').' '));
+SDVA($InputTags['e_savedraftbutton'], array(
+ ':html' => " ",
+ 'name' => 'postdraft', 'value' => ' '.XL('Save draft').' ',
+ 'accesskey' => XL('ak_savedraft')));
+
+## disable the 'publish' button if not authorized to publish
+if (!CondAuth($basename, 'publish'))
+ SDVA($InputTags['e_savebutton'], array('disabled' => 'disabled'));
+
+## add the draft handler into $EditFunctions
+if ($action == 'edit') array_unshift($EditFunctions, 'EditDraft');
+function EditDraft(&$pagename, &$page, &$new) {
+ global $WikiDir, $DraftSuffix, $DeleteKeyPattern,
+ $DraftRecentChangesFmt, $RecentChangesFmt;
+ SDV($DeleteKeyPattern, "^\\s*delete\\s*$");
+ $basename = preg_replace("/$DraftSuffix\$/", '', $pagename);
+ $draftname = $basename . $DraftSuffix;
+ if ($_POST['postdraft'] || $_POST['postedit']) $pagename = $draftname;
+ else if ($_POST['post'] && !preg_match("/$DeleteKeyPattern/", $new['text'])) {
+ $pagename = $basename;
+ $page = ReadPage($basename);
+ $WikiDir->delete($draftname);
+ }
+ else if (PageExists($draftname) && $pagename != $draftname)
+ { Redirect($draftname, '$PageUrl?action=edit'); exit(); }
+ if ($pagename == $draftname && isset($DraftRecentChangesFmt))
+ $RecentChangesFmt = $DraftRecentChangesFmt;
+}
+
+
diff --git a/scripts/feeds.php b/scripts/feeds.php
new file mode 100644
index 0000000..892895d
--- /dev/null
+++ b/scripts/feeds.php
@@ -0,0 +1,544 @@
+All Rights Reserved" in the feed for
+ ?action=atom. If the value of an entry begins with a '<',
+ then feeds.php doesn't automatically add the tag around it.
+ Elements can also be callable functions which are called to
+ generate the appropriate output.
+
+ For example, to set the RSS 2.0 element to the
+ value of the last author to modify a page, one can set
+ (in local/config.php):
+
+ $FeedFmt['rss']['item']['author'] = '$LastModifiedBy';
+
+ To use the RSS 2.0 element to contain the
+ change summary of the most recent edit, set
+
+ $FeedFmt['rss']['item']['description'] = '$LastModifiedSummary';
+
+ Feeds.php can also be combined with attachments to support
+ podcasting via ?action=rss. Any page such as "PageName"
+ that has an mp3 attachment with the same name as the page
+ ("PageName.mp3") will have an appropriate element
+ in the feed output. The set of allowed attachments can be
+ extended using the $RSSEnclosureFmt array:
+
+ $RSSEnclosureFmt = array('{$Name}.mp3', '{$Name}.mp4');
+
+ References:
+ http://www.atomenabled.org/developers/syndication/
+ http://dublincore.org/documents/dcmes-xml/
+ http://en.wikipedia.org/wiki/Podcasting
+*/
+
+## Settings for ?action=atom
+SDVA($FeedFmt['atom']['feed'], array(
+ '_header' => 'Content-type: text/xml; charset="$Charset"',
+ '_start' => '
+'."\n",
+ '_end' => " \n",
+ 'title' => '$WikiTitle',
+ 'link' => ' ',
+ 'id' => '{$PageUrl}?action=atom',
+ 'updated' => '$FeedISOTime',
+ 'author' => "$WikiTitle \n",
+ 'generator' => '$Version',
+ 'logo' => '$PageLogoUrl'));
+SDVA($FeedFmt['atom']['item'], array(
+ '_start' => "\n",
+ 'id' => '{$PageUrl}',
+ 'title' => '{$Title}',
+ 'updated' => '$ItemISOTime',
+ 'link' => " \n",
+ 'author' => "{\$LastModifiedBy} \n",
+ 'summary' => '{$Description}',
+ 'category' => " \n",
+ '_end' => " \n"));
+
+## Settings for ?action=dc
+SDVA($FeedFmt['dc']['feed'], array(
+ '_header' => 'Content-type: text/xml; charset="$Charset"',
+ '_start' => '
+
+'."\n",
+ '_end' => " \n"));
+SDVA($FeedFmt['dc']['item'], array(
+ '_start' => "\n",
+ 'dc:title' => '{$Title}',
+ 'dc:identifier' => '{$PageUrl}',
+ 'dc:date' => '$ItemISOTime',
+ 'dc:type' => 'Text',
+ 'dc:format' => 'text/html',
+ 'dc:description' => '{$Description}',
+ 'dc:subject' => "\$Category \n",
+ 'dc:publisher' => '$WikiTitle',
+ 'dc:author' => '{$LastModifiedBy}',
+ '_end' => " \n"));
+
+## RSS 2.0 settings for ?action=rss
+SDVA($FeedFmt['rss']['feed'], array(
+ '_header' => 'Content-type: text/xml; charset="$Charset"',
+ '_start' => '
+
+'."\n",
+ '_end' => " \n \n",
+ 'title' => '$WikiTitle | {$Group} / {$Title}',
+ 'link' => '{$PageUrl}?action=rss',
+ 'description' => '{$Group}.{$Title}',
+ 'lastBuildDate' => '$FeedRSSTime'));
+SDVA($FeedFmt['rss']['item'], array(
+ '_start' => "- \n",
+ '_end' => "
\n",
+ 'title' => '{$Group} / {$Title}',
+ 'link' => '{$PageUrl}',
+ 'description' => '{$Description}',
+ 'dc:contributor' => '{$LastModifiedBy}',
+ 'dc:date' => '$ItemISOTime',
+ 'pubDate' => '$ItemRSSTime',
+ 'enclosure' => 'RSSEnclosure'));
+
+## RDF 1.0, for ?action=rdf
+SDVA($FeedFmt['rdf']['feed'], array(
+ '_header' => 'Content-type: text/xml; charset="$Charset"',
+ '_start' => '
+
+ '."\n",
+ 'title' => '$WikiTitle | {$Group} / {$Title}',
+ 'link' => '{$PageUrl}?action=rdf',
+ 'description' => '{$Group}.{$Title}',
+ 'dc:date' => '$FeedISOTime',
+ 'items' => "\n\n\$FeedRDFSeq \n \n",
+ '_items' => " \n",
+ '_end' => " \n"));
+SDVA($FeedFmt['rdf']['item'], array(
+ '_start' => "- \n",
+ '_end' => "
\n",
+ 'title' => '$WikiTitle | {$Group} / {$Title}',
+ 'link' => '{$PageUrl}',
+ 'description' => '{$Description}',
+ 'dc:date' => '$ItemISOTime'));
+
+foreach(array_keys($FeedFmt) as $k) {
+ SDV($HandleActions[$k], 'HandleFeed');
+ SDV($HandleAuth[$k], 'read');
+}
+
+function HandleFeed($pagename, $auth = 'read') {
+ global $FeedFmt, $action, $PCache, $FmtV, $TimeISOZFmt, $RSSTimeFmt,
+ $FeedPageListOpt, $FeedCategoryOpt, $FeedTrailOpt,
+ $FeedDescPatterns, $CategoryGroup, $EntitiesTable;
+ SDV($RSSTimeFmt, 'D, d M Y H:i:s \G\M\T');
+ SDV($FeedDescPatterns,
+ array('/<[^>]*$/' => ' ', '/\\w+$/' => '', '/<[^>]+>/' => ''));
+ $FeedPageListOpt = (array)@$FeedPageListOpt;
+ SDVA($FeedCategoryOpt, array('link' => $pagename));
+ SDVA($FeedTrailOpt, array('trail' => $pagename, 'count' => 10));
+
+ $f = $FeedFmt[$action];
+ $page = RetrieveAuthPage($pagename, $auth, true, READPAGE_CURRENT);
+ if (!$page) Abort("?cannot generate feed");
+ $feedtime = $page['time'];
+
+ # determine list of pages to display
+ if (@($_REQUEST['trail'] || $_REQUEST['group'] || $_REQUEST['link']
+ || $_REQUEST['name']))
+ $opt = $FeedPageListOpt;
+ else if (preg_match("/^$CategoryGroup\\./", $pagename))
+ $opt = $FeedCategoryOpt;
+ else if ($action != 'dc') $opt = $FeedTrailOpt;
+ else {
+ PCache($pagename, $page);
+ $pagelist = array($pagename);
+ }
+ if (!@$pagelist) {
+ $opt = array_merge($opt, @$_REQUEST);
+ $pagelist = MakePageList($pagename, $opt, 0);
+ }
+
+ # process list of pages in feed
+ $rdfseq = '';
+ $pl = array();
+ foreach($pagelist as $pn) {
+ if (!PageExists($pn)) continue;
+ if (!isset($PCache[$pn]['time']))
+ { $page = ReadPage($pn, READPAGE_CURRENT); PCache($pn, $page); }
+ $pc = & $PCache[$pn];
+ $pl[] = $pn;
+ if (@$opt['count'] && count($pl) >= $opt['count']) break;
+ $rdfseq .= FmtPageName(" \n", $pn);
+ if ($pc['time'] > $feedtime) $feedtime = $pc['time'];
+ }
+ $pagelist = $pl;
+
+ $FmtV['$FeedRDFSeq'] = $rdfseq;
+ $FmtV['$FeedISOTime'] = gmstrftime($TimeISOZFmt, $feedtime);
+ $FmtV['$FeedRSSTime'] = gmdate($RSSTimeFmt, $feedtime);
+ # format start of feed
+ $out = FmtPageName($f['feed']['_start'], $pagename);
+
+ # format feed elements
+ foreach($f['feed'] as $k => $v) {
+ if ($k{0} == '_' || !$v) continue;
+ $x = FmtPageName($v, $pagename);
+ if (!$x) continue;
+ $out .= ($v{0} == '<') ? $x : "<$k>$x$k>\n";
+ }
+
+ # format items in feed
+ if (@$f['feed']['_items'])
+ $out .= FmtPageName($f['feed']['_items'], $pagename);
+ foreach($pagelist as $pn) {
+ $page = &$PCache[$pn];
+ $FmtV['$ItemDesc'] = @$page['description'];
+ $FmtV['$ItemISOTime'] = gmstrftime($TimeISOZFmt, $page['time']);
+ $FmtV['$ItemRSSTime'] = gmdate($RSSTimeFmt, $page['time']);
+
+ $out .= FmtPageName($f['item']['_start'], $pn);
+ foreach((array)@$f['item'] as $k => $v) {
+ if ($k{0} == '_' || !$v) continue;
+ if (is_callable($v)) { $out .= $v($pn, $page, $k); continue; }
+ if (strpos($v, '$LastModifiedBy') !== false && !@$page['author'])
+ continue;
+ if (strpos($v, '$Category') !== false) {
+ if (preg_match_all("/(?<=^|,)$CategoryGroup\\.([^,]+)/",
+ @$page['targets'], $match)) {
+ foreach($match[1] as $c) {
+ $FmtV['$Category'] = $c;
+ $out .= FmtPageName($v, $pn);
+ }
+ }
+ continue;
+ }
+ $x = FmtPageName($v, $pn);
+ if (!$x) continue;
+ $out .= ($v{0} == '<') ? $x : "<$k>$x$k>\n";
+ }
+ $out .= FmtPageName($f['item']['_end'], $pn);
+ }
+ $out .= FmtPageName($f['feed']['_end'], $pagename);
+ foreach((array)@$f['feed']['_header'] as $fmt)
+ header(FmtPageName($fmt, $pagename));
+ print str_replace(array_keys($EntitiesTable),
+ array_values($EntitiesTable), $out);
+}
+
+## RSSEnclosure is called in ?action=rss to generate
+## tags for any pages that have an attached "PageName.mp3" file.
+## The set of attachments to enclose is given by $RSSEnclosureFmt.
+function RSSEnclosure($pagename, &$page, $k) {
+ global $RSSEnclosureFmt, $UploadFileFmt, $UploadExts;
+ if (!function_exists('MakeUploadName')) return '';
+ SDV($RSSEnclosureFmt, array('{$Name}.mp3'));
+ $encl = '';
+ foreach((array)$RSSEnclosureFmt as $fmt) {
+ $path = FmtPageName($fmt, $pagename);
+ $upname = MakeUploadName($pagename, $path);
+ $filepath = FmtPageName("$UploadFileFmt/$upname", $pagename);
+ if (file_exists($filepath)) {
+ $length = filesize($filepath);
+ $type = @$UploadExts[preg_replace('/.*\\./', '', $filepath)];
+ $url = LinkUpload($pagename, 'Attach:', $path, '', '', '$LinkUrl');
+ $encl .= "<$k url='$url' length='$length' type='$type' />";
+ }
+ }
+ return $encl;
+}
+
+## Since most feeds don't understand html character entities, we
+## convert the common ones to their numeric form here.
+SDVA($EntitiesTable, array(
+ # entities defined in "http://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent"
+ ' ' => ' ',
+ '¡' => '¡',
+ '¢' => '¢',
+ '£' => '£',
+ '¤' => '¤',
+ '¥' => '¥',
+ '¦' => '¦',
+ '§' => '§',
+ '¨' => '¨',
+ '©' => '©',
+ 'ª' => 'ª',
+ '«' => '«',
+ '¬' => '¬',
+ '' => '',
+ '®' => '®',
+ '¯' => '¯',
+ '°' => '°',
+ '±' => '±',
+ '²' => '²',
+ '³' => '³',
+ '´' => '´',
+ 'µ' => 'µ',
+ '¶' => '¶',
+ '·' => '·',
+ '¸' => '¸',
+ '¹' => '¹',
+ 'º' => 'º',
+ '»' => '»',
+ '¼' => '¼',
+ '½' => '½',
+ '¾' => '¾',
+ '¿' => '¿',
+ 'À' => 'À',
+ 'Á' => 'Á',
+ 'Â' => 'Â',
+ 'Ã' => 'Ã',
+ 'Ä' => 'Ä',
+ 'Å' => 'Å',
+ 'Æ' => 'Æ',
+ 'Ç' => 'Ç',
+ 'È' => 'È',
+ 'É' => 'É',
+ 'Ê' => 'Ê',
+ 'Ë' => 'Ë',
+ 'Ì' => 'Ì',
+ 'Í' => 'Í',
+ 'Î' => 'Î',
+ 'Ï' => 'Ï',
+ 'Ð' => 'Ð',
+ 'Ñ' => 'Ñ',
+ 'Ò' => 'Ò',
+ 'Ó' => 'Ó',
+ 'Ô' => 'Ô',
+ 'Õ' => 'Õ',
+ 'Ö' => 'Ö',
+ '×' => '×',
+ 'Ø' => 'Ø',
+ 'Ù' => 'Ù',
+ 'Ú' => 'Ú',
+ 'Û' => 'Û',
+ 'Ü' => 'Ü',
+ 'Ý' => 'Ý',
+ 'Þ' => 'Þ',
+ 'ß' => 'ß',
+ 'à' => 'à',
+ 'á' => 'á',
+ 'â' => 'â',
+ 'ã' => 'ã',
+ 'ä' => 'ä',
+ 'å' => 'å',
+ 'æ' => 'æ',
+ 'ç' => 'ç',
+ 'è' => 'è',
+ 'é' => 'é',
+ 'ê' => 'ê',
+ 'ë' => 'ë',
+ 'ì' => 'ì',
+ 'í' => 'í',
+ 'î' => 'î',
+ 'ï' => 'ï',
+ 'ð' => 'ð',
+ 'ñ' => 'ñ',
+ 'ò' => 'ò',
+ 'ó' => 'ó',
+ 'ô' => 'ô',
+ 'õ' => 'õ',
+ 'ö' => 'ö',
+ '÷' => '÷',
+ 'ø' => 'ø',
+ 'ù' => 'ù',
+ 'ú' => 'ú',
+ 'û' => 'û',
+ 'ü' => 'ü',
+ 'ý' => 'ý',
+ 'þ' => 'þ',
+ 'ÿ' => 'ÿ',
+ # entities defined in "http://www.w3.org/TR/xhtml1/DTD/xhtml-special.ent"
+ '"' => '"',
+ #'&' => '&',
+ #'<' => '<',
+ #'>' => '>',
+ ''' => ''',
+ 'Œ' => 'Œ',
+ 'œ' => 'œ',
+ 'Š' => 'Š',
+ 'š' => 'š',
+ 'Ÿ' => 'Ÿ',
+ 'ˆ' => 'ˆ',
+ '˜' => '˜',
+ ' ' => ' ',
+ ' ' => ' ',
+ ' ' => ' ',
+ '' => '',
+ '' => '',
+ '' => '',
+ '' => '',
+ '–' => '–',
+ '—' => '—',
+ '‘' => '‘',
+ '’' => '’',
+ '‚' => '‚',
+ '“' => '“',
+ '”' => '”',
+ '„' => '„',
+ '†' => '†',
+ '‡' => '‡',
+ '‰' => '‰',
+ '‹' => '‹',
+ '›' => '›',
+ '€' => '€',
+ # entities defined in "http://www.w3.org/TR/xhtml1/DTD/xhtml-symbol.ent"
+ 'ƒ' => 'ƒ',
+ 'Α' => 'Α',
+ 'Β' => 'Β',
+ 'Γ' => 'Γ',
+ 'Δ' => 'Δ',
+ 'Ε' => 'Ε',
+ 'Ζ' => 'Ζ',
+ 'Η' => 'Η',
+ 'Θ' => 'Θ',
+ 'Ι' => 'Ι',
+ 'Κ' => 'Κ',
+ 'Λ' => 'Λ',
+ 'Μ' => 'Μ',
+ 'Ν' => 'Ν',
+ 'Ξ' => 'Ξ',
+ 'Ο' => 'Ο',
+ 'Π' => 'Π',
+ 'Ρ' => 'Ρ',
+ 'Σ' => 'Σ',
+ 'Τ' => 'Τ',
+ 'Υ' => 'Υ',
+ 'Φ' => 'Φ',
+ 'Χ' => 'Χ',
+ 'Ψ' => 'Ψ',
+ 'Ω' => 'Ω',
+ 'α' => 'α',
+ 'β' => 'β',
+ 'γ' => 'γ',
+ 'δ' => 'δ',
+ 'ε' => 'ε',
+ 'ζ' => 'ζ',
+ 'η' => 'η',
+ 'θ' => 'θ',
+ 'ι' => 'ι',
+ 'κ' => 'κ',
+ 'λ' => 'λ',
+ 'μ' => 'μ',
+ 'ν' => 'ν',
+ 'ξ' => 'ξ',
+ 'ο' => 'ο',
+ 'π' => 'π',
+ 'ρ' => 'ρ',
+ 'ς' => 'ς',
+ 'σ' => 'σ',
+ 'τ' => 'τ',
+ 'υ' => 'υ',
+ 'φ' => 'φ',
+ 'χ' => 'χ',
+ 'ψ' => 'ψ',
+ 'ω' => 'ω',
+ 'ϑ' => 'ϑ',
+ 'ϒ' => 'ϒ',
+ 'ϖ' => 'ϖ',
+ '•' => '•',
+ '…' => '…',
+ '′' => '′',
+ '″' => '″',
+ '‾' => '‾',
+ '⁄' => '⁄',
+ '℘' => '℘',
+ 'ℑ' => 'ℑ',
+ 'ℜ' => 'ℜ',
+ '™' => '™',
+ 'ℵ' => 'ℵ',
+ '←' => '←',
+ '↑' => '↑',
+ '→' => '→',
+ '↓' => '↓',
+ '↔' => '↔',
+ '↵' => '↵',
+ '⇐' => '⇐',
+ '⇑' => '⇑',
+ '⇒' => '⇒',
+ '⇓' => '⇓',
+ '⇔' => '⇔',
+ '∀' => '∀',
+ '∂' => '∂',
+ '∃' => '∃',
+ '∅' => '∅',
+ '∇' => '∇',
+ '∈' => '∈',
+ '∉' => '∉',
+ '∋' => '∋',
+ '∏' => '∏',
+ '∑' => '∑',
+ '−' => '−',
+ '∗' => '∗',
+ '√' => '√',
+ '∝' => '∝',
+ '∞' => '∞',
+ '∠' => '∠',
+ '∧' => '∧',
+ '∨' => '∨',
+ '∩' => '∩',
+ '∪' => '∪',
+ '∫' => '∫',
+ '∴' => '∴',
+ '∼' => '∼',
+ '≅' => '≅',
+ '≈' => '≈',
+ '≠' => '≠',
+ '≡' => '≡',
+ '≤' => '≤',
+ '≥' => '≥',
+ '⊂' => '⊂',
+ '⊃' => '⊃',
+ '⊄' => '⊄',
+ '⊆' => '⊆',
+ '⊇' => '⊇',
+ '⊕' => '⊕',
+ '⊗' => '⊗',
+ '⊥' => '⊥',
+ '⋅' => '⋅',
+ '⌈' => '⌈',
+ '⌉' => '⌉',
+ '⌊' => '⌊',
+ '⌋' => '⌋',
+ '〈' => '〈',
+ '〉' => '〉',
+ '◊' => '◊',
+ '♠' => '♠',
+ '♣' => '♣',
+ '♥' => '♥',
+ '♦' => '♦'));
+
diff --git a/scripts/forms.php b/scripts/forms.php
new file mode 100644
index 0000000..ecf5c11
--- /dev/null
+++ b/scripts/forms.php
@@ -0,0 +1,332 @@
+");
+SDV($InputTags['text']['class'], 'inputbox');
+SDV($InputTags['password']['class'], 'inputbox');
+SDV($InputTags['submit']['class'], 'inputbutton');
+SDV($InputTags['reset']['class'], 'inputbutton');
+SDV($InputTags['radio'][':checked'], 'checked');
+SDV($InputTags['checkbox'][':checked'], 'checked');
+
+# (:input form:)
+SDVA($InputTags['form'], array(
+ ':args' => array('action', 'method'),
+ ':html' => "",
+ 'method' => 'post'));
+
+# (:input end:)
+SDV($InputTags['end'][':html'], ' ');
+
+# (:input textarea:)
+SDVA($InputTags['textarea'], array(
+ ':content' => array('value'),
+ ':attr' => array_diff($InputAttrs, array('value')),
+ ':html' => "\$InputFormContent "));
+
+# (:input image:)
+SDV($InputTags['image'][':args'], array('name', 'src', 'alt'));
+
+# (:input select:)
+SDVA($InputTags['select-option'], array(
+ ':args' => array('name', 'value', 'label'),
+ ':content' => array('label', 'value', 'name'),
+ ':attr' => array('value', 'selected'),
+ ':checked' => 'selected',
+ ':html' => "\$InputFormContent "));
+SDVA($InputTags['select'], array(
+ 'class' => 'inputbox',
+ ':html' => "\$InputSelectOptions "));
+
+# (:input defaults?:)
+SDVA($InputTags['default'], array(':fn' => 'InputDefault'));
+SDVA($InputTags['defaults'], array(':fn' => 'InputDefault'));
+
+## (:input ...:) directives
+Markup('input', 'directives',
+ '/\\(:input\\s+(\\w+)(.*?):\\)/ei',
+ "InputMarkup(\$pagename, '$1', PSS('$2'))");
+
+## (:input select:) has its own markup processing
+Markup('input-select', ' .*?:\\)))\\s+(?=\\(:input\\s)/', '$1');
+
+SDV($InputFocusFmt,
+ "");
+
+## InputToHTML performs standard processing on (:input ...:) arguments,
+## and returns the formatted HTML string.
+function InputToHTML($pagename, $type, $args, &$opt) {
+ global $InputTags, $InputAttrs, $InputValues, $FmtV, $KeepToken,
+ $InputFocusLevel, $InputFocusId, $InputFocusFmt, $HTMLFooterFmt;
+ if (!@$InputTags[$type]) return "(:input $type $args:)";
+ ## get input arguments
+ if (!is_array($args)) $args = ParseArgs($args);
+ ## convert any positional arguments to named arguments
+ $posnames = @$InputTags[$type][':args'];
+ if (!$posnames) $posnames = array('name', 'value');
+ while (count($posnames) > 0 && count(@$args['']) > 0) {
+ $n = array_shift($posnames);
+ if (!isset($args[$n])) $args[$n] = array_shift($args['']);
+ }
+ ## merge defaults for input type with arguments
+ $opt = array_merge($InputTags[$type], $args);
+ ## www.w3.org/TR/html4/types
+ if(isset($opt['id'])) $opt['id'] = preg_replace('/[^-A-Za-z0-9:_.]+/', '_', $opt['id']);
+ ## convert any remaining positional args to flags
+ foreach ((array)@$opt[''] as $a)
+ { $a = strtolower($a); if (!isset($opt[$a])) $opt[$a] = $a; }
+ if (isset($opt['name'])) {
+ $opt['name'] = preg_replace('/^\\$:/', 'ptv_', @$opt['name']);
+ $opt['name'] = preg_replace('/[^-A-Za-z0-9:_.\\[\\]]+/', '_', $opt['name']);
+ $name = $opt['name'];
+ ## set control values from $InputValues array
+ ## radio, checkbox, select, etc. require a flag of some sort,
+ ## others just set 'value'
+ if (isset($InputValues[$name])) {
+ $checked = @$opt[':checked'];
+ if ($checked) {
+ $opt[$checked] = in_array(@$opt['value'], (array)$InputValues[$name])
+ ? $checked : false;
+ } else if (!isset($opt['value'])) $opt['value'] = $InputValues[$name];
+ }
+ }
+ ## build $InputFormContent
+ $FmtV['$InputFormContent'] = '';
+ foreach((array)@$opt[':content'] as $a)
+ if (isset($opt[$a])) { $FmtV['$InputFormContent'] = $opt[$a]; break; }
+ ## hash and store any "secure" values
+ if (@$opt['secure'] == '#') $opt['secure'] = rand();
+ if (@$opt['secure'] > '') {
+ $md5 = md5($opt['secure'] . $opt['value']);
+ @session_start();
+ $_SESSION['forms'][$md5] = $opt['value'];
+ $opt['value'] = $md5;
+ }
+ ## handle focus=# option
+ $focus = @$opt['focus'];
+ if (isset($focus)
+ && (!isset($InputFocusLevel) || $focus < $InputFocusLevel)) {
+ if (!isset($opt['id'])) $opt['id'] = "wikifocus$focus";
+ $InputFocusLevel = $focus;
+ $InputFocusId = $opt['id'];
+ $HTMLFooterFmt['inputfocus'] = $InputFocusFmt;
+ }
+ ## build $InputFormArgs from $opt
+ $attrlist = (isset($opt[':attr'])) ? $opt[':attr'] : $InputAttrs;
+ $attr = array();
+ foreach ($attrlist as $a) {
+ if (!isset($opt[$a]) || $opt[$a]===false) continue;
+ if(strpos($opt[$a], $KeepToken)!== false) # multiline textarea/hidden fields
+ $opt[$a] = Keep(str_replace("'", ''', MarkupRestore($opt[$a]) ));
+ $attr[] = "$a='".str_replace("'", ''', $opt[$a])."'";
+ }
+ $FmtV['$InputFormArgs'] = implode(' ', $attr);
+ return FmtPageName($opt[':html'], $pagename);
+}
+
+
+## InputMarkup handles the (:input ...:) directive. It either
+## calls any function given by the :fn element of the corresponding
+## tag, or else just returns the result of InputToHTML().
+function InputMarkup($pagename, $type, $args) {
+ global $InputTags;
+ $fn = @$InputTags[$type][':fn'];
+ if ($fn) return $fn($pagename, $type, $args);
+ return Keep(InputToHTML($pagename, $type, $args, $opt));
+}
+
+
+## (:input default:) directive.
+function InputDefault($pagename, $type, $args) {
+ global $InputValues, $PageTextVarPatterns, $PCache;
+ $args = ParseArgs($args);
+ $args[''] = (array)@$args[''];
+ $name = (isset($args['name'])) ? $args['name'] : array_shift($args['']);
+ $name = preg_replace('/^\\$:/', 'ptv_', $name);
+ $value = (isset($args['value'])) ? $args['value'] : array_shift($args['']);
+ if (!isset($InputValues[$name])) $InputValues[$name] = $value;
+ if (@$args['request']) {
+ $req = array_merge($_GET, $_POST);
+ foreach($req as $k => $v)
+ if (!isset($InputValues[$k]))
+ $InputValues[$k] = htmlspecialchars(stripmagic($v), ENT_NOQUOTES);
+ }
+ $source = @$args['source'];
+ if ($source) {
+ $source = MakePageName($pagename, $source);
+ $page = RetrieveAuthPage($source, 'read', false, READPAGE_CURRENT);
+ if ($page) {
+ foreach((array)$PageTextVarPatterns as $pat)
+ if (preg_match_all($pat, IsEnabled($PCache[$source]['=preview'], $page['text']),
+ $match, PREG_SET_ORDER))
+ foreach($match as $m)
+ if (!isset($InputValues['ptv_'.$m[2]]))
+ $InputValues['ptv_'.$m[2]] =
+ htmlspecialchars(Qualify($source, $m[3]), ENT_NOQUOTES);
+ }
+ }
+ return '';
+}
+
+
+## (:input select ...:) is special, because we need to process a bunch of
+## them as a single unit.
+function InputSelect($pagename, $type, $markup) {
+ global $InputTags, $InputAttrs, $FmtV;
+ preg_match_all('/\\(:input\\s+\\S+\\s+(.*?):\\)/', $markup, $match);
+ $selectopt = (array)$InputTags[$type];
+ $opt = $selectopt;
+ $optionshtml = '';
+ $optiontype = isset($InputTags["$type-option"])
+ ? "$type-option" : "select-option";
+ foreach($match[1] as $args) {
+ $optionshtml .= InputToHTML($pagename, $optiontype, $args, $oo);
+ $opt = array_merge($opt, $oo);
+ }
+ $attrlist = array_diff($InputAttrs, array('value'));
+ $attr = array();
+ foreach($attrlist as $a) {
+ if (!isset($opt[$a]) || $opt[$a]===false) continue;
+ $attr[] = "$a='".str_replace("'", ''', $opt[$a])."'";
+ }
+ $FmtV['$InputSelectArgs'] = implode(' ', $attr);
+ $FmtV['$InputSelectOptions'] = $optionshtml;
+ return Keep(FmtPageName($selectopt[':html'], $pagename));
+}
+
+
+function InputActionForm($pagename, $type, $args) {
+ global $InputAttrs;
+ $args = ParseArgs($args);
+ if (@$args['pagename']) $pagename = $args['pagename'];
+ $opt = NULL;
+ $html = InputToHTML($pagename, $type, $args, $opt);
+ foreach(preg_grep('/^[\\w$]/', array_keys($args)) as $k) {
+ if (is_array($args[$k]) || in_array($k, $InputAttrs)) continue;
+ if ($k == 'n' || $k == 'pagename') continue;
+ $html .= " ";
+ }
+ return Keep($html);
+}
+
+
+## RequestArgs is used to extract values from controls (typically
+## in $_GET and $_POST).
+function RequestArgs($req = NULL) {
+ if (is_null($req)) $req = array_merge($_GET, $_POST);
+ foreach ($req as $k => $v) $req[$k] = stripmagic($req[$k]);
+ return $req;
+}
+
+
+## Form-based authorization prompts (for use with PmWikiAuth)
+
+$r = str_replace("'", '%37', stripmagic($_SERVER['REQUEST_URI']));
+SDVA($InputTags['auth_form'], array(
+ ':html' => "\$PostVars"));
+SDV($AuthPromptFmt, array(&$PageStartFmt, 'page:$SiteGroup.AuthForm',
+ "",
+ &$PageEndFmt));
+
+## The section below handles specialized EditForm pages.
+## We don't bother to load it if we're not editing.
+
+if ($action != 'edit') return;
+
+SDV($PageEditForm, '$SiteGroup.EditForm');
+SDV($PageEditFmt, '$EditForm');
+if (@$_REQUEST['editform']) {
+ $PageEditForm=$_REQUEST['editform'];
+ $PageEditFmt='$EditForm';
+}
+$Conditions['e_preview'] = '(boolean)$_REQUEST["preview"]';
+
+XLSDV('en', array(
+ 'ak_save' => 's',
+ 'ak_saveedit' => 'u',
+ 'ak_preview' => 'p',
+ 'ak_textedit' => ',',
+ 'e_rows' => '23',
+ 'e_cols' => '60'));
+
+# (:e_preview:) displays the preview of formatted text.
+Markup('e_preview', 'directives',
+ '/^\\(:e_preview:\\)/e',
+ "Keep(\$GLOBALS['FmtV']['\$PreviewText'])");
+
+# If we didn't load guiedit.php, then set (:e_guibuttons:) to
+# simply be empty.
+Markup('e_guibuttons', 'directives', '/\\(:e_guibuttons:\\)/', '');
+
+# Prevent (:e_preview:) and (:e_guibuttons:) from
+# participating in text rendering step.
+SDV($SaveAttrPatterns['/\\(:e_(preview|guibuttons):\\)/'], ' ');
+
+SDVA($InputTags['e_form'], array(
+ ':html' => " "));
+SDVA($InputTags['e_textarea'], array(
+ ':html' => "\$EditText ",
+ 'name' => 'text', 'id' => 'text', 'accesskey' => XL('ak_textedit'),
+ 'rows' => XL('e_rows'), 'cols' => XL('e_cols')));
+SDVA($InputTags['e_author'], array(
+ ':html' => " ",
+ 'name' => 'author', 'value' => $Author));
+SDVA($InputTags['e_changesummary'], array(
+ ':html' => " ",
+ 'name' => 'csum', 'size' => '60', 'maxlength' => '100',
+ 'value' => htmlspecialchars(stripmagic(@$_POST['csum']), ENT_QUOTES)));
+SDVA($InputTags['e_minorcheckbox'], array(
+ ':html' => " ",
+ 'name' => 'diffclass', 'value' => 'minor'));
+if (@$_POST['diffclass']=='minor')
+ SDV($InputTags['e_minorcheckbox']['checked'], 'checked');
+SDVA($InputTags['e_savebutton'], array(
+ ':html' => " ",
+ 'name' => 'post', 'value' => ' '.XL('Save').' ',
+ 'accesskey' => XL('ak_save')));
+SDVA($InputTags['e_saveeditbutton'], array(
+ ':html' => " ",
+ 'name' => 'postedit', 'value' => ' '.XL('Save and edit').' ',
+ 'accesskey' => XL('ak_saveedit')));
+SDVA($InputTags['e_savedraftbutton'], array(':html' => ''));
+SDVA($InputTags['e_previewbutton'], array(
+ ':html' => " ",
+ 'name' => 'preview', 'value' => ' '.XL('Preview').' ',
+ 'accesskey' => XL('ak_preview')));
+SDVA($InputTags['e_cancelbutton'], array(
+ ':html' => " ",
+ 'name' => 'cancel', 'value' => ' '.XL('Cancel').' ' ));
+SDVA($InputTags['e_resetbutton'], array(
+ ':html' => " ",
+ 'value' => ' '.XL('Reset').' '));
+
diff --git a/scripts/guiedit.php b/scripts/guiedit.php
new file mode 100644
index 0000000..fe3e876
--- /dev/null
+++ b/scripts/guiedit.php
@@ -0,0 +1,82 @@
+ "\n"));
+
+SDV($GUIButtonDirUrlFmt,'$FarmPubDirUrl/guiedit');
+
+SDVA($GUIButtons, array(
+ 'em' => array(100, "''", "''", '$[Emphasized]',
+ '$GUIButtonDirUrlFmt/em.gif"$[Emphasized (italic)]"',
+ '$[ak_em]'),
+ 'strong' => array(110, "'''", "'''", '$[Strong]',
+ '$GUIButtonDirUrlFmt/strong.gif"$[Strong (bold)]"',
+ '$[ak_strong]'),
+ 'pagelink' => array(200, '[[', ']]', '$[Page link]',
+ '$GUIButtonDirUrlFmt/pagelink.gif"$[Link to internal page]"'),
+ 'extlink' => array(210, '[[', ']]', 'http:// | $[link text]',
+ '$GUIButtonDirUrlFmt/extlink.gif"$[Link to external page]"'),
+ 'big' => array(300, "'+", "+'", '$[Big text]',
+ '$GUIButtonDirUrlFmt/big.gif"$[Big text]"'),
+ 'small' => array(310, "'-", "-'", '$[Small text]',
+ '$GUIButtonDirUrlFmt/small.gif"$[Small text]"'),
+ 'sup' => array(320, "'^", "^'", '$[Superscript]',
+ '$GUIButtonDirUrlFmt/sup.gif"$[Superscript]"'),
+ 'sub' => array(330, "'_", "_'", '$[Subscript]',
+ '$GUIButtonDirUrlFmt/sub.gif"$[Subscript]"'),
+ 'h2' => array(400, '\\n!! ', '\\n', '$[Heading]',
+ '$GUIButtonDirUrlFmt/h.gif"$[Heading]"'),
+ 'center' => array(410, '%25center%25', '', '',
+ '$GUIButtonDirUrlFmt/center.gif"$[Center]"')));
+
+Markup('e_guibuttons', 'directives',
+ '/\\(:e_guibuttons:\\)/e',
+ "Keep(FmtPageName(GUIButtonCode(\$pagename), \$pagename))");
+
+function GUIButtonCode($pagename) {
+ global $GUIButtons;
+ $cmpfn = create_function('$a,$b', 'return $a[0]-$b[0];');
+ usort($GUIButtons, $cmpfn);
+ $out = "';
+ return $out;
+}
+
diff --git a/scripts/httpauth.php b/scripts/httpauth.php
new file mode 100644
index 0000000..73c2d3a
--- /dev/null
+++ b/scripts/httpauth.php
@@ -0,0 +1,46 @@
+array($_SERVER['PHP_AUTH_PW'] => 1)));
+
+
+## $EnableHTTPBasicAuth tells PmWikiAuth to use the browser's
+## HTTP Basic protocol prompt instead of a form-based prompt.
+if (IsEnabled($EnableHTTPBasicAuth, 1))
+ SDV($AuthPromptFmt, 'function:HTTPBasicAuthPrompt');
+
+## HTTPBasicAuthPrompt replaces PmWikiAuth's form-based password
+## prompt with the browser-based HTTP Basic prompt.
+function HTTPBasicAuthPrompt($pagename) {
+ global $AuthRealmFmt, $AuthDeniedFmt;
+ SDV($AuthRealmFmt,$GLOBALS['WikiTitle']);
+ SDV($AuthDeniedFmt,'A valid password is required to access this feature.');
+ $realm=FmtPageName($AuthRealmFmt,$pagename);
+ header("WWW-Authenticate: Basic realm=\"$realm\"");
+ header("Status: 401 Unauthorized");
+ header("HTTP-Status: 401 Unauthorized");
+ PrintFmt($pagename,$AuthDeniedFmt);
+ exit;
+}
+
diff --git a/scripts/intermap.txt b/scripts/intermap.txt
new file mode 100644
index 0000000..c7ec2eb
--- /dev/null
+++ b/scripts/intermap.txt
@@ -0,0 +1,8 @@
+PmWiki: http://www.pmwiki.org/wiki/PmWiki/
+Cookbook: http://www.pmwiki.org/wiki/Cookbook/
+Wiki: http://www.c2.com/cgi/wiki?
+UseMod: http://www.usemod.com/cgi-bin/wiki.pl?
+Meatball: http://www.usemod.com/cgi-bin/mb.pl?
+Wikipedia: http://www.wikipedia.com/wiki/
+PITS: http://www.pmwiki.org/PITS/
+Path:
diff --git a/scripts/markupexpr.php b/scripts/markupexpr.php
new file mode 100644
index 0000000..f1f9d2f
--- /dev/null
+++ b/scripts/markupexpr.php
@@ -0,0 +1,123 @@
+{$var}',
+ '/\\{(\\(\\w+\\b.*?\\))\\}/e',
+ "MarkupExpression(\$pagename, PSS('$1'))");
+
+SDVA($MarkupExpr, array(
+ 'substr' => 'call_user_func_array("substr", $args)',
+ 'strlen' => 'strlen($args[0])',
+ 'ftime' => 'ME_ftime(@$args[0], @$args[1], $argp)',
+ 'rand' => '($args) ? rand($args[0], $args[1]) : rand()',
+ 'ucfirst' => 'ucfirst($args[0])',
+ 'ucwords' => 'ucwords($args[0])',
+ 'tolower' => 'strtolower($args[0])',
+ 'toupper' => 'strtoupper($args[0])',
+ 'asspaced' => '$GLOBALS["AsSpacedFunction"]($args[0])',
+ 'pagename' => 'MakePageName($pagename, preg_replace($rpat, $rrep, $params))',
+));
+
+function MarkupExpression($pagename, $expr) {
+ global $KeepToken, $KPV, $MarkupExpr;
+ $rpat = "/$KeepToken(\\d+P)$KeepToken/e";
+ $rrep = '$KPV[\'$1\']';
+ $expr = preg_replace('/([\'"])(.*?)\\1/e', "Keep(PSS('$2'),'P')", $expr);
+ $expr = preg_replace('/\\(\\W/e', "Keep(PSS('$2'),'P')", $expr);
+ while (preg_match('/\\((\\w+)(\\s[^()]*)?\\)/', $expr, $match)) {
+ list($repl, $func, $params) = $match;
+ $code = @$MarkupExpr[$func];
+ ## if not a valid function, save this string as-is and exit
+ if (!$code) break;
+ ## if the code uses '$params', we just evaluate directly
+ if (strpos($code, '$params') !== false) {
+ $out = eval("return ({$code});");
+ if ($expr == $repl) { $expr = $out; break; }
+ $expr = str_replace($repl, $out, $expr);
+ continue;
+ }
+ ## otherwise, we parse arguments into $args before evaluating
+ $argp = ParseArgs($params);
+ $x = $argp['#']; $args = array();
+ while ($x) {
+ list($k, $v) = array_splice($x, 0, 2);
+ if ($k == '' || $k == '+' || $k == '-')
+ $args[] = $k.preg_replace($rpat, $rrep, $v);
+ }
+ ## fix any quoted arguments
+ foreach ($argp as $k => $v)
+ if (!is_array($v)) $argp[$k] = preg_replace($rpat, $rrep, $v);
+ $out = eval("return ({$code});");
+ if ($expr == $repl) { $expr = $out; break; }
+ $expr = str_replace($repl, Keep($out, 'P'), $expr);
+ }
+ return preg_replace($rpat, $rrep, $expr);
+}
+
+## ME_ftime handles {(ftime ...)} expressions.
+##
+function ME_ftime($arg0 = '', $arg1 = '', $argp = NULL) {
+ global $TimeFmt, $Now, $FTimeFmt;
+ if (@$argp['fmt']) $fmt = $argp['fmt'];
+ else if (strpos($arg0, '%') !== false) { $fmt = $arg0; $arg0 = $arg1; }
+ else if (strpos($arg1, '%') !== false) $fmt = $arg1;
+ ## determine the timestamp
+ if (isset($argp['when'])) list($time, $x) = DRange($argp['when']);
+ else if ($arg0 > '') list($time, $x) = DRange($arg0);
+ else $time = $Now;
+ if (@$fmt == '') { SDV($FTimeFmt, $TimeFmt); $fmt = $FTimeFmt; }
+ ## make sure we have %F available for ISO dates
+ $fmt = str_replace(array('%F', '%s'), array('%Y-%m-%d', $time), $fmt);
+ return strftime($fmt, $time);
+}
+
diff --git a/scripts/notify.php b/scripts/notify.php
new file mode 100644
index 0000000..a9e53d5
--- /dev/null
+++ b/scripts/notify.php
@@ -0,0 +1,197 @@
+]*(notify[:=].*)/m', $npage['text'], $nlist);
+ $nlist = array_merge((array)@$NotifyList, (array)@$nlist[1]);
+ if (!$nlist) return;
+
+ ## make sure other processes are locked out
+ Lock(2);
+
+ ## let's load the current .notifylist table
+ $nfile = FmtPageName($NotifyFile, $pagename);
+ $nfp = @fopen($nfile, 'r');
+ if ($nfp) {
+ ## get our current squelch and delay timestamps
+ clearstatcache();
+ $sz = filesize($nfile);
+ list($nextevent, $firstpost) = explode(' ', rtrim(fgets($nfp, $sz)));
+ ## restore our notify array
+ $notify = unserialize(fgets($nfp, $sz));
+ fclose($nfp);
+ }
+ if (!is_array($notify)) $notify = array();
+
+ ## if this is for a newly posted page, get its information
+ if ($IsPagePosted) {
+ $page = ReadPage($pagename, READPAGE_CURRENT);
+ $FmtV['$PostTime'] = strftime($NotifyTimeFmt, $Now);
+ $item = urlencode(FmtPageName($NotifyItemFmt, $pagename));
+ if ($firstpost < 1) $firstpost = $Now;
+ }
+
+ foreach($nlist as $n) {
+ $opt = ParseArgs($n);
+ $mailto = preg_split('/[\s,]+/', $opt['notify']);
+ if (!$mailto) continue;
+ if ($opt['squelch'])
+ foreach($mailto as $m) $squelch[$m] = $opt['squelch'];
+ if (!$IsPagePosted) continue;
+ if ($opt['link']) {
+ $link = MakePageName($pagename, $opt['link']);
+ if (!preg_match("/(^|,)$link(,|$)/i", $page['targets'])) continue;
+ }
+ $pats = @(array)$SearchPatterns[$opt['list']];
+ if ($opt['group']) $pats[] = FixGlob($opt['group'], '$1$2.*');
+ if ($opt['name']) $pats[] = FixGlob($opt['name'], '$1*.$2');
+ if ($pats && !MatchPageNames($pagename, $pats)) continue;
+ if ($opt['trail']) {
+ $trail = ReadTrail($pagename, $opt['trail']);
+ for ($i=0; $i= count($trail)) continue;
+ }
+ foreach($mailto as $m) { $notify[$m][] = $item; }
+ }
+
+ $nnow = time();
+ if ($nnow < $firstpost + $NotifyDelay)
+ $nextevent = $firstpost + $NotifyDelay;
+ else {
+ $firstpost = 0;
+ $nextevent = $nnow + 86400;
+ $mailto = array_keys($notify);
+ $subject = FmtPageName($NotifySubjectFmt, $pagename);
+ if(IsEnabled($EnableNotifySubjectEncode, 0)
+ && preg_match("/[^\x20-\x7E]/", $subject))
+ $subject = strtoupper("=?$Charset?B?"). base64_encode($subject)."?=";
+ $body = FmtPageName($NotifyBodyFmt, $pagename);
+ foreach ($mailto as $m) {
+ $msquelch = @$notify[$m]['lastmail'] +
+ ((@$squelch[$m]) ? $squelch[$m] : $NotifySquelch);
+ if ($nnow < $msquelch) {
+ if ($msquelch < $nextevent && count($notify[$m])>1)
+ $nextevent = $msquelch;
+ continue;
+ }
+ unset($notify[$m]['lastmail']);
+ if (!$notify[$m]) { unset($notify[$m]); continue; }
+ $mbody = str_replace('$NotifyItems',
+ urldecode(implode("\n", $notify[$m])), $body);
+ if ($NotifyParameters && !@ini_get('safe_mode'))
+ mail($m, $subject, $mbody, $NotifyHeaders, $NotifyParameters);
+ else
+ mail($m, $subject, $mbody, $NotifyHeaders);
+ $notify[$m] = array('lastmail' => $nnow);
+ }
+ }
+
+ ## save the updated notify status
+ $nfp = @fopen($nfile, "w");
+ if ($nfp) {
+ fputs($nfp, "$nextevent $firstpost\n");
+ fputs($nfp, serialize($notify) . "\n");
+ fclose($nfp);
+ }
+ Lock(0);
+ return true;
+}
+
diff --git a/scripts/pagelist.php b/scripts/pagelist.php
new file mode 100644
index 0000000..68b6cc6
--- /dev/null
+++ b/scripts/pagelist.php
@@ -0,0 +1,844 @@
+ '!\.(All)?Recent(Changes|Uploads)$!',
+ 'group' => '!\.Group(Print)?(Header|Footer|Attributes)$!',
+ 'self' => str_replace('.', '\\.', "!^$pagename$!")));
+
+## $FPLFormatOpt is a list of options associated with fmt=
+## values. 'default' is used for any undefined values of fmt=.
+SDVA($FPLFormatOpt, array(
+ 'default' => array('fn' => 'FPLTemplate', 'fmt' => '#default'),
+ 'bygroup' => array('fn' => 'FPLTemplate', 'template' => '#bygroup',
+ 'class' => 'fplbygroup'),
+ 'simple' => array('fn' => 'FPLTemplate', 'template' => '#simple',
+ 'class' => 'fplsimple'),
+ 'group' => array('fn' => 'FPLTemplate', 'template' => '#group',
+ 'class' => 'fplgroup'),
+ 'title' => array('fn' => 'FPLTemplate', 'template' => '#title',
+ 'class' => 'fpltitle', 'order' => 'title'),
+ 'count' => array('fn' => 'FPLCountA'),
+ ));
+
+SDV($SearchResultsFmt, "\$[SearchFor]
+
\$MatchList
+
\$[SearchFound]
");
+SDV($SearchQuery, str_replace('$', '$',
+ htmlspecialchars(stripmagic(@$_REQUEST['q']), ENT_NOQUOTES)));
+XLSDV('en', array(
+ 'SearchFor' => 'Results of search for $Needle :',
+ 'SearchFound' =>
+ '$MatchCount pages found out of $MatchSearched pages searched.'));
+
+SDV($PageListArgPattern, '((?:\\$:?)?\\w+)[:=]');
+
+Markup('pagelist', 'directives',
+ '/\\(:pagelist(\\s+.*?)?:\\)/ei',
+ "FmtPageList('\$MatchList', \$pagename, array('o' => PSS('$1 ')))");
+Markup('searchbox', 'directives',
+ '/\\(:searchbox(\\s.*?)?:\\)/e',
+ "SearchBox(\$pagename, ParseArgs(PSS('$1'), '$PageListArgPattern'))");
+Markup('searchresults', 'directives',
+ '/\\(:searchresults(\\s+.*?)?:\\)/ei',
+ "FmtPageList(\$GLOBALS['SearchResultsFmt'], \$pagename,
+ array('req' => 1, 'request'=>1, 'o' => PSS('$1')))");
+
+SDV($SaveAttrPatterns['/\\(:(searchresults|pagelist)(\\s+.*?)?:\\)/i'], ' ');
+
+SDV($HandleActions['search'], 'HandleSearchA');
+SDV($HandleAuth['search'], 'read');
+SDV($ActionTitleFmt['search'], '| $[Search Results]');
+
+SDVA($PageListFilters, array(
+ 'PageListCache' => 80,
+ 'PageListProtect' => 90,
+ 'PageListSources' => 100,
+ 'PageListPasswords' => 120,
+ 'PageListIf' => 140,
+ 'PageListTermsTargets' => 160,
+ 'PageListVariables' => 180,
+ 'PageListSort' => 900,
+));
+
+foreach(array('random', 'size', 'time', 'ctime') as $o)
+ SDV($PageListSortCmp[$o], "@(\$PCache[\$x]['$o']-\$PCache[\$y]['$o'])");
+SDV($PageListSortCmp['title'],
+ '@strcasecmp($PCache[$x][\'=title\'], $PCache[$y][\'=title\'])');
+
+define('PAGELIST_PRE' , 1);
+define('PAGELIST_ITEM', 2);
+define('PAGELIST_POST', 4);
+
+## SearchBox generates the output of the (:searchbox:) markup.
+## If $SearchBoxFmt is defined, that is used, otherwise a searchbox
+## is generated. Options include group=, size=, label=.
+function SearchBox($pagename, $opt) {
+ global $SearchBoxFmt, $SearchBoxOpt, $SearchQuery, $EnablePathInfo;
+ if (isset($SearchBoxFmt)) return Keep(FmtPageName($SearchBoxFmt, $pagename));
+ SDVA($SearchBoxOpt, array('size' => '40',
+ 'label' => FmtPageName('$[Search]', $pagename),
+ 'value' => str_replace("'", "'", $SearchQuery)));
+ $opt = array_merge((array)$SearchBoxOpt, @$_GET, (array)$opt);
+ $opt['action'] = 'search';
+ $target = (@$opt['target'])
+ ? MakePageName($pagename, $opt['target']) : $pagename;
+ $opt['n'] = IsEnabled($EnablePathInfo, 0) ? '' : $target;
+ $out = FmtPageName(" class='wikisearch' action='\$PageUrl' method='get'>",
+ $target);
+ foreach($opt as $k => $v) {
+ if ($v == '' || is_array($v)) continue;
+ $v = str_replace("'", "'", $v);
+ $opt[$k] = $v;
+ if ($k == 'q' || $k == 'label' || $k == 'value' || $k == 'size') continue;
+ $k = str_replace("'", "'", $k);
+ $out .= " ";
+ }
+ $out .= " ";
+ return '';
+}
+
+
+## FmtPageList combines options from markup, request form, and url,
+## calls the appropriate formatting function, and returns the string.
+function FmtPageList($outfmt, $pagename, $opt) {
+ global $GroupPattern, $FmtV, $PageListArgPattern,
+ $FPLFormatOpt, $FPLFunctions;
+ # get any form or url-submitted request
+ $rq = htmlspecialchars(stripmagic(@$_REQUEST['q']), ENT_NOQUOTES);
+ # build the search string
+ $FmtV['$Needle'] = $opt['o'] . ' ' . $rq;
+ # Handle "group/" at the beginning of the form-submitted request
+ if (preg_match("!^($GroupPattern(\\|$GroupPattern)*)?/!i", $rq, $match)) {
+ $opt['group'] = @$match[1];
+ $rq = substr($rq, strlen(@$match[1])+1);
+ }
+ $opt = array_merge($opt, ParseArgs($opt['o'], $PageListArgPattern));
+ # merge markup options with form and url
+ if (@$opt['request'])
+ $opt = array_merge($opt, ParseArgs($rq, $PageListArgPattern), @$_REQUEST);
+ # non-posted blank search requests return nothing
+ if (@($opt['req'] && !$opt['-'] && !$opt[''] && !$opt['+'] && !$opt['q']))
+ return '';
+ # terms and group to be included and excluded
+ $GLOBALS['SearchIncl'] = array_merge((array)@$opt[''], (array)@$opt['+']);
+ $GLOBALS['SearchExcl'] = (array)@$opt['-'];
+ $GLOBALS['SearchGroup'] = @$opt['group'];
+ $fmt = @$opt['fmt']; if (!$fmt) $fmt = 'default';
+ $fmtopt = @$FPLFormatOpt[$fmt];
+ if (!is_array($fmtopt)) {
+ if ($fmtopt) $fmtopt = array('fn' => $fmtopt);
+ elseif (@$FPLFunctions[$fmt])
+ $fmtopt = array('fn' => $FPLFunctions[$fmt]);
+ else $fmtopt = $FPLFormatOpt['default'];
+ }
+ $fmtfn = @$fmtopt['fn'];
+ if (!is_callable($fmtfn)) $fmtfn = $FPLFormatOpt['default']['fn'];
+ $matches = array();
+ $opt = array_merge($fmtopt, $opt);
+ $out = $fmtfn($pagename, $matches, $opt);
+ $FmtV['$MatchCount'] = count($matches);
+ if ($outfmt != '$MatchList')
+ { $FmtV['$MatchList'] = $out; $out = FmtPageName($outfmt, $pagename); }
+ if ($out[0] == '<') $out = Keep($out);
+ return PRR($out);
+}
+
+
+## MakePageList generates a list of pages using the specifications given
+## by $opt.
+function MakePageList($pagename, $opt, $retpages = 1) {
+ global $MakePageListOpt, $PageListFilters, $PCache;
+
+ StopWatch('MakePageList pre');
+ SDVA($MakePageListOpt, array('list' => 'default'));
+ $opt = array_merge((array)$MakePageListOpt, (array)$opt);
+ if (!@$opt['order'] && !@$opt['trail']) $opt['order'] = 'name';
+
+ ksort($opt); $opt['=key'] = md5(serialize($opt));
+
+ $itemfilters = array(); $postfilters = array();
+ asort($PageListFilters);
+ $opt['=phase'] = PAGELIST_PRE; $list=array(); $pn=NULL; $page=NULL;
+ foreach($PageListFilters as $fn => $v) {
+ if ($v<0) continue;
+ $ret = $fn($list, $opt, $pagename, $page);
+ if ($ret & PAGELIST_ITEM) $itemfilters[] = $fn;
+ if ($ret & PAGELIST_POST) $postfilters[] = $fn;
+ }
+
+ StopWatch("MakePageList items count=".count($list).", filters=".implode(',',$itemfilters));
+ $opt['=phase'] = PAGELIST_ITEM;
+ $matches = array(); $opt['=readc'] = 0;
+ foreach((array)$list as $pn) {
+ $page = array();
+ foreach((array)$itemfilters as $fn)
+ if (!$fn($list, $opt, $pn, $page)) continue 2;
+ $page['pagename'] = $page['name'] = $pn;
+ PCache($pn, $page);
+ $matches[] = $pn;
+ }
+ $list = $matches;
+ StopWatch("MakePageList post count=".count($list).", readc={$opt['=readc']}");
+
+ $opt['=phase'] = PAGELIST_POST; $pn=NULL; $page=NULL;
+ foreach((array)$postfilters as $fn)
+ $fn($list, $opt, $pagename, $page);
+
+ if ($retpages)
+ for($i=0; $i '') ? PAGELIST_ITEM : 0;
+
+ $condspec = $opt['if'];
+ $Cursor['='] = $pn;
+ $varpat = '\\{([=*]|!?[-\\w.\\/\\x80-\\xff]*)(\\$:?\\w+)\\}';
+ while (preg_match("/$varpat/", $condspec, $match)) {
+ $condspec = preg_replace("/$varpat/e",
+ "PVSE(PageVar(\$pn, '$2', '$1'))", $condspec);
+ }
+ if (!preg_match("/^\\s*(!?)\\s*(\\S*)\\s*(.*?)\\s*$/", $condspec, $match))
+ return 0;
+ list($x, $not, $condname, $condparm) = $match;
+ if (!isset($Conditions[$condname])) return 1;
+ $tf = (int)@eval("return ({$Conditions[$condname]});");
+ return (boolean)($tf xor $not);
+}
+
+
+function PageListTermsTargets(&$list, &$opt, $pn, &$page) {
+ global $FmtV;
+ static $reindex = array();
+ $fold = $GLOBALS['StrFoldFunction'];
+
+ switch ($opt['=phase']) {
+ case PAGELIST_PRE:
+ $FmtV['$MatchSearched'] = count($list);
+ $incl = array(); $excl = array();
+ foreach((array)@$opt[''] as $i) { $incl[] = $fold($i); }
+ foreach((array)@$opt['+'] as $i) { $incl[] = $fold($i); }
+ foreach((array)@$opt['-'] as $i) { $excl[] = $fold($i); }
+
+ $indexterms = PageIndexTerms($incl);
+ foreach($incl as $i) {
+ $delim = (!preg_match('/[^\\w\\x80-\\xff]/', $i)) ? '$' : '/';
+ $opt['=inclp'][] = $delim . preg_quote($i,$delim) . $delim . 'i';
+ }
+ if ($excl)
+ $opt['=exclp'][] = '$'.implode('|', array_map('preg_quote',$excl)).'$i';
+
+ if (@$opt['link']) {
+ $link = MakePageName($pn, $opt['link']);
+ $opt['=linkp'] = "/(^|,)$link(,|$)/i";
+ $indexterms[] = " $link ";
+ }
+
+ if (@$opt['=cached']) return 0;
+ if ($indexterms) {
+ StopWatch("PageListTermsTargets begin count=".count($list));
+ $xlist = PageIndexGrep($indexterms, true);
+ $list = array_diff($list, $xlist);
+ StopWatch("PageListTermsTargets end count=".count($list));
+ }
+
+ if (@$opt['=inclp'] || @$opt['=exclp'] || @$opt['=linkp'])
+ return PAGELIST_ITEM|PAGELIST_POST;
+ return 0;
+
+ case PAGELIST_ITEM:
+ if (!$page) { $page = ReadPage($pn, READPAGE_CURRENT); $opt['=readc']++; }
+ if (!$page) return 0;
+ if (@$opt['=linkp'] && !preg_match($opt['=linkp'], @$page['targets']))
+ { $reindex[] = $pn; return 0; }
+ if (@$opt['=inclp'] || @$opt['=exclp']) {
+ $text = $fold($pn."\n".@$page['targets']."\n".@$page['text']);
+ foreach((array)@$opt['=exclp'] as $i)
+ if (preg_match($i, $text)) return 0;
+ foreach((array)@$opt['=inclp'] as $i)
+ if (!preg_match($i, $text)) {
+ if ($i{0} == '$') $reindex[] = $pn;
+ return 0;
+ }
+ }
+ return 1;
+
+ case PAGELIST_POST:
+ if ($reindex) PageIndexQueueUpdate($reindex);
+ $reindex = array();
+ return 0;
+ }
+}
+
+
+function PageListVariables(&$list, &$opt, $pn, &$page) {
+ switch ($opt['=phase']) {
+ case PAGELIST_PRE:
+ $varlist = preg_grep('/^\\$/', array_keys($opt));
+ if (!$varlist) return 0;
+ foreach($varlist as $v) {
+ list($inclp, $exclp) = GlobToPCRE($opt[$v]);
+ if ($inclp) $opt['=varinclp'][$v] = "/$inclp/i";
+ if ($exclp) $opt['=varexclp'][$v] = "/$exclp/i";
+ }
+ return PAGELIST_ITEM;
+
+ case PAGELIST_ITEM:
+ if (@$opt['=varinclp'])
+ foreach($opt['=varinclp'] as $v => $pat)
+ if (!preg_match($pat, PageVar($pn, $v))) return 0;
+ if (@$opt['=varexclp'])
+ foreach($opt['=varexclp'] as $v => $pat)
+ if (preg_match($pat, PageVar($pn, $v))) return 0;
+ return 1;
+ }
+}
+
+
+function PageListSort(&$list, &$opt, $pn, &$page) {
+ global $PageListSortCmp, $PCache, $PageListSortRead;
+ SDVA($PageListSortRead, array('name' => 0, 'group' => 0, 'random' => 0,
+ 'title' => 0));
+
+ switch ($opt['=phase']) {
+ case PAGELIST_PRE:
+ $ret = 0;
+ foreach(preg_split('/[\\s,|]+/', @$opt['order'], -1, PREG_SPLIT_NO_EMPTY)
+ as $o) {
+ $ret |= PAGELIST_POST;
+ $r = '+';
+ if ($o{0} == '-') { $r = '-'; $o = substr($o, 1); }
+ $opt['=order'][$o] = $r;
+ if ($o{0} != '$' &&
+ (!isset($PageListSortRead[$o]) || $PageListSortRead[$o]))
+ $ret |= PAGELIST_ITEM;
+ }
+ StopWatch(@"PageListSort pre ret=$ret order={$opt['order']}");
+ return $ret;
+
+ case PAGELIST_ITEM:
+ if (!$page) { $page = ReadPage($pn, READPAGE_CURRENT); $opt['=readc']++; }
+ return 1;
+ }
+
+ ## case PAGELIST_POST
+ StopWatch('PageListSort begin');
+ $order = $opt['=order'];
+ if (@$order['title'])
+ foreach($list as $pn) $PCache[$pn]['=title'] = PageVar($pn, '$Title');
+ if (@$order['group'])
+ foreach($list as $pn) $PCache[$pn]['group'] = PageVar($pn, '$Group');
+ if (@$order['random'])
+ { NoCache(); foreach($list as $pn) $PCache[$pn]['random'] = rand(); }
+ foreach(preg_grep('/^\\$/', array_keys($order)) as $o)
+ foreach($list as $pn)
+ $PCache[$pn][$o] = PageVar($pn, $o);
+ $code = '';
+ foreach($opt['=order'] as $o => $r) {
+ if (@$PageListSortCmp[$o])
+ $code .= "\$c = {$PageListSortCmp[$o]}; ";
+ else
+ $code .= "\$c = @strcasecmp(\$PCache[\$x]['$o'],\$PCache[\$y]['$o']); ";
+ $code .= "if (\$c) return $r\$c;\n";
+ }
+ StopWatch('PageListSort sort');
+ if ($code)
+ uasort($list,
+ create_function('$x,$y', "global \$PCache; $code return 0;"));
+ StopWatch('PageListSort end');
+}
+
+
+function PageListCache(&$list, &$opt, $pn, &$page) {
+ global $PageListCacheDir, $LastModTime, $PageIndexFile;
+
+ if (@!$PageListCacheDir) return 0;
+ if (isset($opt['cache']) && !$opt['cache']) return 0;
+
+ $key = $opt['=key'];
+ $cache = "$PageListCacheDir/$key,cache";
+ switch ($opt['=phase']) {
+ case PAGELIST_PRE:
+ if (!file_exists($cache) || filemtime($cache) <= $LastModTime)
+ return PAGELIST_POST;
+ StopWatch("PageListCache begin load key=$key");
+ list($list, $opt['=protectsafe']) =
+ unserialize(file_get_contents($cache));
+ $opt['=cached'] = 1;
+ StopWatch("PageListCache end load");
+ return 0;
+
+ case PAGELIST_POST:
+ StopWatch("PageListCache begin save key=$key");
+ $fp = @fopen($cache, "w");
+ if ($fp) {
+ fputs($fp, serialize(array($list, $opt['=protectsafe'])));
+ fclose($fp);
+ }
+ StopWatch("PageListCache end save");
+ return 0;
+ }
+ return 0;
+}
+
+
+## HandleSearchA performs ?action=search. It's basically the same
+## as ?action=browse, except it takes its contents from Site.Search.
+function HandleSearchA($pagename, $level = 'read') {
+ global $PageSearchForm, $FmtV, $HandleSearchFmt,
+ $PageStartFmt, $PageEndFmt;
+ SDV($HandleSearchFmt,array(&$PageStartFmt, '$PageText', &$PageEndFmt));
+ SDV($PageSearchForm, '$[{$SiteGroup}/Search]');
+ $form = RetrieveAuthPage($pagename, $level, true, READPAGE_CURRENT);
+ if (!$form) Abort("?unable to read $pagename");
+ PCache($pagename, $form);
+ $text = preg_replace('/\\[([=@])(.*?)\\1\\]/s', ' ', @$form['text']);
+ if (!preg_match('/\\(:searchresults(\\s.*?)?:\\)/', $text))
+ foreach((array)$PageSearchForm as $formfmt) {
+ $form = ReadPage(FmtPageName($formfmt, $pagename), READPAGE_CURRENT);
+ if ($form['text']) break;
+ }
+ $text = @$form['text'];
+ if (!$text) $text = '(:searchresults:)';
+ $FmtV['$PageText'] = MarkupToHTML($pagename,$text);
+ PrintFmt($pagename, $HandleSearchFmt);
+}
+
+
+########################################################################
+## The functions below provide different formatting options for
+## the output list, controlled by the fmt= parameter and the
+## $FPLFormatOpt hash.
+########################################################################
+
+## This helper function handles the count= parameter for extracting
+## a range of pagelist in the list.
+function CalcRange($range, $n) {
+ if ($n < 1) return array(0, 0);
+ if (strpos($range, '..') === false) {
+ if ($range > 0) return array(1, min($range, $n));
+ if ($range < 0) return array(max($n + $range + 1, 1), $n);
+ return array(1, $n);
+ }
+ list($r0, $r1) = explode('..', $range);
+ if ($r0 < 0) $r0 += $n + 1;
+ if ($r1 < 0) $r1 += $n + 1;
+ else if ($r1 == 0) $r1 = $n;
+ if ($r0 < 1 && $r1 < 1) return array($n+1, $n+1);
+ return array(max($r0, 1), max($r1, 1));
+}
+
+
+## FPLCountA handles fmt=count
+function FPLCountA($pagename, &$matches, $opt) {
+ $matches = array_values(MakePageList($pagename, $opt, 0));
+ return count($matches);
+}
+
+SDVA($FPLTemplateFunctions, array(
+ 'FPLTemplateLoad' => 100,
+ 'FPLTemplateDefaults' => 200,
+ 'FPLTemplatePageList' => 300,
+ 'FPLTemplateSliceList' => 400,
+ 'FPLTemplateFormat' => 500
+ ));
+
+function FPLTemplate($pagename, &$matches, $opt) {
+ global $FPLTemplateFunctions;
+ StopWatch("FPLTemplate: Chain begin");
+ asort($FPLTemplateFunctions, SORT_NUMERIC);
+ $fnlist = $FPLTemplateFunctions;
+ $output = '';
+ foreach($FPLTemplateFunctions as $fn=>$i) {
+ if ($i<0) continue;
+ StopWatch("FPLTemplate: $fn");
+ $fn($pagename, $matches, $opt, $tparts, $output);
+ }
+ StopWatch("FPLTemplate: Chain end");
+ return $output;
+}
+
+## Loads a template section
+function FPLTemplateLoad($pagename, $matches, $opt, &$tparts){
+ global $Cursor, $FPLTemplatePageFmt, $RASPageName, $PageListArgPattern;
+ SDV($FPLTemplatePageFmt, array('{$FullName}',
+ '{$SiteGroup}.LocalTemplates', '{$SiteGroup}.PageListTemplates'));
+
+ $template = @$opt['template'];
+ if (!$template) $template = @$opt['fmt'];
+ $ttext = RetrieveAuthSection($pagename, $template, $FPLTemplatePageFmt);
+ $ttext = PVSE(Qualify($RASPageName, $ttext));
+
+ ## save any escapes
+ $ttext = MarkupEscape($ttext);
+ ## remove any anchor markups to avoid duplications
+ $ttext = preg_replace('/\\[\\[#[A-Za-z][-.:\\w]*\\]\\]/', '', $ttext);
+
+ ## extract portions of template
+ $tparts = preg_split('/\\(:(template)\\s+(\\w+)\\s*(.*?):\\)/i', $ttext, -1,
+ PREG_SPLIT_DELIM_CAPTURE);
+}
+
+## Merge parameters from (:template default :) with those in the (:pagelist:)
+function FPLTemplateDefaults($pagename, $matches, &$opt, &$tparts){
+ global $PageListArgPattern;
+ $i = 0;
+ while ($i < count($tparts)) {
+ if ($tparts[$i] != 'template') { $i++; continue; }
+ if ($tparts[$i+1] != 'defaults' && $tparts[$i+1] != 'default') { $i+=4; continue; }
+ $opt = array_merge(ParseArgs($tparts[$i+2], $PageListArgPattern), $opt);
+ array_splice($tparts, $i, 3);
+ }
+ SDVA($opt, array('class' => 'fpltemplate', 'wrap' => 'div'));
+}
+
+## get the list of pages
+function FPLTemplatePageList($pagename, &$matches, &$opt){
+ $matches = array_unique(array_merge((array)$matches, MakePageList($pagename, $opt, 0)));
+ ## count matches before any slicing and save value as template var {$$PageListCount}
+ $opt['PageListCount'] = count($matches);
+}
+
+## extract page subset according to 'count=' parameter
+function FPLTemplateSliceList($pagename, &$matches, $opt){
+ if (@$opt['count']) {
+ list($r0, $r1) = CalcRange($opt['count'], count($matches));
+ if ($r1 < $r0)
+ $matches = array_reverse(array_slice($matches, $r1-1, $r0-$r1+1));
+ else
+ $matches = array_slice($matches, $r0-1, $r1-$r0+1);
+ }
+}
+
+
+function FPLTemplateFormat($pagename, $matches, $opt, $tparts, &$output){
+ global $Cursor, $FPLTemplateMarkupFunction;
+ SDV($FPLTemplateMarkupFunction, 'MarkupToHTML');
+ $savecursor = $Cursor;
+ $pagecount = 0; $groupcount = 0; $grouppagecount = 0;
+ $pseudovars = array('{$$PageCount}' => &$pagecount,
+ '{$$GroupCount}' => &$groupcount,
+ '{$$GroupPageCount}' => &$grouppagecount);
+
+ foreach(preg_grep('/^[\\w$]/', array_keys($opt)) as $k)
+ if (!is_array($opt[$k]))
+ $pseudovars["{\$\$$k}"] = htmlspecialchars($opt[$k], ENT_NOQUOTES);
+
+ $vk = array_keys($pseudovars);
+ $vv = array_values($pseudovars);
+
+ $lgroup = ''; $out = '';
+ if(count($matches)==0 )
+ {
+ $t = 0;
+ while($t < count($tparts))
+ {
+ if($tparts[$t]=='template' && $tparts[$t+1]=='none')
+ {
+ $out .= MarkupRestore($tparts[$t+3]);
+ $t+=3;
+ }
+ $t++;
+ }
+ } # else:
+ foreach($matches as $i => $pn) {
+ $group = PageVar($pn, '$Group');
+ if ($group != $lgroup) { $groupcount++; $grouppagecount = 0; $lgroup = $group; }
+ $grouppagecount++; $pagecount++;
+
+ $t = 0;
+ while ($t < count($tparts)) {
+ if ($tparts[$t] != 'template') { $item = $tparts[$t]; $t++; }
+ else {
+ list($when, $control, $item) = array_slice($tparts, $t+1, 3); $t+=4;
+ if($when=='none') continue;
+ if (!$control) {
+ if ($when == 'first' && $i != 0) continue;
+ if ($when == 'last' && $i != count($matches) - 1) continue;
+ } else {
+ if ($when == 'first' || !isset($last[$t])) {
+ $Cursor['<'] = $Cursor['<'] = (string)@$matches[$i-1];
+ $Cursor['='] = $pn;
+ $Cursor['>'] = $Cursor['>'] = (string)@$matches[$i+1];
+ $curr = str_replace($vk, $vv, $control);
+ $curr = preg_replace('/\\{(=|&[lg]t;)(\\$:?\\w+)\\}/e',
+ "PageVar(\$pn, '$2', '$1')", $curr);
+ if ($when == 'first' && $i > 0 && $last[$t] == $curr) continue;
+ $last[$t] = $curr;
+ }
+ if ($when == 'last') {
+ $Cursor['<'] = $Cursor['<'] = $pn;
+ $Cursor['='] = (string)@$matches[$i+1];
+ $Cursor['>'] = $Cursor['>'] = (string)@$matches[$i+2];
+ $next = str_replace($vk, $vv, $control);
+ $next = preg_replace('/\\{(=|&[lg]t;)(\\$:?\\w+)\\}/e',
+ "PageVar(\$pn, '$2', '$1')", $next);
+ if ($next == $last[$t] && $i != count($matches) - 1) continue;
+ $last[$t] = $next;
+ }
+ }
+ }
+ $Cursor['<'] = $Cursor['<'] = (string)@$matches[$i-1];
+ $Cursor['='] = $pn;
+ $Cursor['>'] = $Cursor['>'] = (string)@$matches[$i+1];
+ $item = str_replace($vk, $vv, $item);
+ $item = preg_replace('/\\{(=|&[lg]t;)(\\$:?\\w+)\\}/e',
+ "PVSE(PageVar(\$pn, '$2', '$1'))", $item);
+ $out .= MarkupRestore($item);
+ }
+ }
+
+ $class = preg_replace('/[^-a-zA-Z0-9\\x80-\\xff]/', ' ', @$opt['class']);
+ if ($class) $class = " class='$class'";
+ $wrap = @$opt['wrap'];
+ if ($wrap != 'inline') {
+ $out = $FPLTemplateMarkupFunction($pagename, $out, array('escape' => 0, 'redirect'=>1));
+ if ($wrap != 'none') $out = "$out
";
+ }
+ $Cursor = $savecursor;
+ $output .= $out;
+}
+
+########################################################################
+## The functions below optimize searches by maintaining a file of
+## words and link cross references (the "page index").
+########################################################################
+
+## PageIndexTerms($terms) takes an array of strings and returns a
+## normalized list of associated search terms. This reduces the
+## size of the index and speeds up searches.
+function PageIndexTerms($terms) {
+ global $StrFoldFunction;
+ $w = array();
+ foreach((array)$terms as $t) {
+ $w = array_merge($w, preg_split('/[^\\w\\x80-\\xff]+/',
+ $StrFoldFunction($t), -1, PREG_SPLIT_NO_EMPTY));
+ }
+ return $w;
+}
+
+## The PageIndexUpdate($pagelist) function updates the page index
+## file with terms and target links for the pages in $pagelist.
+## The optional $dir parameter allows this function to be called
+## via register_shutdown_function (which sometimes changes directories
+## on us).
+function PageIndexUpdate($pagelist = NULL, $dir = '') {
+ global $EnableReadOnly, $PageIndexUpdateList, $PageIndexFile,
+ $PageIndexTime, $Now;
+ if (IsEnabled($EnableReadOnly, 0)) return;
+ $abort = ignore_user_abort(true);
+ if ($dir) { flush(); chdir($dir); }
+ if (is_null($pagelist))
+ { $pagelist = (array)$PageIndexUpdateList; $PageIndexUpdateList = array(); }
+ if (!$pagelist || !$PageIndexFile) return;
+ SDV($PageIndexTime, 10);
+ $c = count($pagelist); $updatecount = 0;
+ StopWatch("PageIndexUpdate begin ($c pages to update)");
+ $pagelist = (array)$pagelist;
+ $timeout = time() + $PageIndexTime;
+ $cmpfn = create_function('$a,$b', 'return strlen($b)-strlen($a);');
+ Lock(2);
+ $ofp = fopen("$PageIndexFile,new", 'w');
+ foreach($pagelist as $pn) {
+ if (@$updated[$pn]) continue;
+ @$updated[$pn]++;
+ if (time() > $timeout) continue;
+ $page = ReadPage($pn, READPAGE_CURRENT);
+ if ($page) {
+ $targets = str_replace(',', ' ', @$page['targets']);
+ $terms = PageIndexTerms(array(@$page['text'], $targets, $pn));
+ usort($terms, $cmpfn);
+ $x = '';
+ foreach($terms as $t) { if (strpos($x, $t) === false) $x .= " $t"; }
+ fputs($ofp, "$pn:$Now: $targets :$x\n");
+ }
+ $updatecount++;
+ }
+ $ifp = @fopen($PageIndexFile, 'r');
+ if ($ifp) {
+ while (!feof($ifp)) {
+ $line = fgets($ifp, 4096);
+ while (substr($line, -1, 1) != "\n" && !feof($ifp))
+ $line .= fgets($ifp, 4096);
+ $i = strpos($line, ':');
+ if ($i === false) continue;
+ $n = substr($line, 0, $i);
+ if (@$updated[$n]) continue;
+ fputs($ofp, $line);
+ }
+ fclose($ifp);
+ }
+ fclose($ofp);
+ if (file_exists($PageIndexFile)) unlink($PageIndexFile);
+ rename("$PageIndexFile,new", $PageIndexFile);
+ fixperms($PageIndexFile);
+ StopWatch("PageIndexUpdate end ($updatecount updated)");
+ ignore_user_abort($abort);
+}
+
+## PageIndexQueueUpdate specifies pages to be updated in
+## the index upon shutdown (via register_shutdown function).
+function PageIndexQueueUpdate($pagelist) {
+ global $PageIndexUpdateList;
+ if (!@$PageIndexUpdateList)
+ register_shutdown_function('PageIndexUpdate', NULL, getcwd());
+ $PageIndexUpdateList = array_merge((array)@$PageIndexUpdateList,
+ (array)$pagelist);
+ $c1 = count($pagelist); $c2 = count($PageIndexUpdateList);
+ StopWatch("PageIndexQueueUpdate: queued $c1 pages ($c2 total)");
+}
+
+## PageIndexGrep returns a list of pages that match the strings
+## provided. Note that some search terms may need to be normalized
+## in order to get the desired results (see PageIndexTerms above).
+## Also note that this just works for the index; if the index is
+## incomplete, then so are the results returned by this list.
+## (MakePageList above already knows how to deal with this.)
+function PageIndexGrep($terms, $invert = false) {
+ global $PageIndexFile;
+ if (!$PageIndexFile) return array();
+ StopWatch('PageIndexGrep begin');
+ $pagelist = array();
+ $fp = @fopen($PageIndexFile, 'r');
+ if ($fp) {
+ $terms = (array)$terms;
+ while (!feof($fp)) {
+ $line = fgets($fp, 4096);
+ while (substr($line, -1, 1) != "\n" && !feof($fp))
+ $line .= fgets($fp, 4096);
+ $i = strpos($line, ':');
+ if (!$i) continue;
+ $add = true;
+ foreach($terms as $t)
+ if (strpos($line, $t) === false) { $add = false; break; }
+ if ($add xor $invert) $pagelist[] = substr($line, 0, $i);
+ }
+ fclose($fp);
+ }
+ StopWatch('PageIndexGrep end');
+ return $pagelist;
+}
+
+## PostPageIndex is inserted into $EditFunctions to update
+## the linkindex whenever a page is saved.
+function PostPageIndex($pagename, &$page, &$new) {
+ global $IsPagePosted;
+ if ($IsPagePosted) PageIndexQueueUpdate($pagename);
+}
diff --git a/scripts/pagerev.php b/scripts/pagerev.php
new file mode 100644
index 0000000..c39ab5d
--- /dev/null
+++ b/scripts/pagerev.php
@@ -0,0 +1,214 @@
+$[Hide minor edits]" :
+ "$[Show minor edits] " );
+SDV($DiffSourceFmt, ($DiffShow['source']=='y') ?
+ "$[Show changes to output] " :
+ "$[Show changes to markup] ");
+SDV($PageDiffFmt,"$[{\$FullName} History]
+ $DiffMinorFmt - $DiffSourceFmt
+ ");
+SDV($DiffStartFmt,"
+ \$DiffTime
+ \$[by]
\$DiffAuthor - \$DiffChangeSum
");
+SDV($DiffDelFmt['a'],"
+
\$[Deleted line \$DiffLines:]
+
");
+SDV($DiffDelFmt['c'],"
+
\$[Changed line \$DiffLines from:]
+
");
+SDV($DiffAddFmt['d'],"
+
\$[Added line \$DiffLines:]
+
");
+SDV($DiffAddFmt['c'],"
+
$[to:]
+
");
+SDV($DiffEndDelAddFmt,"
");
+SDV($DiffEndFmt,"
");
+SDV($DiffRestoreFmt,"
+
");
+
+SDV($HandleActions['diff'], 'HandleDiff');
+SDV($HandleAuth['diff'], 'read');
+SDV($ActionTitleFmt['diff'], '| $[History]');
+SDV($HTMLStylesFmt['diff'], "
+ .diffbox { width:570px; border-left:1px #999999 solid; margin-top:1.33em; }
+ .diffauthor { font-weight:bold; }
+ .diffchangesum { font-weight:bold; }
+ .difftime { font-family:verdana,sans-serif; font-size:66%;
+ background-color:#dddddd; }
+ .difftype { clear:both; font-family:verdana,sans-serif;
+ font-size:66%; font-weight:bold; }
+ .diffadd { border-left:5px #99ff99 solid; padding-left:5px; }
+ .diffdel { border-left:5px #ffff99 solid; padding-left:5px; }
+ .diffrestore { clear:both; font-family:verdana,sans-serif;
+ font-size:66%; margin:1.5em 0px; }
+ .diffmarkup { font-family:monospace; }
+ .diffmarkup del { background:#ffff99; text-decoration: none; }
+ .diffmarkup ins { background:#99ff99; text-decoration: none; }");
+
+function PrintDiff($pagename) {
+ global $DiffHTMLFunction,$DiffShow,$DiffStartFmt,$TimeFmt,
+ $DiffEndFmt,$DiffRestoreFmt,$FmtV, $LinkFunctions;
+ $page = ReadPage($pagename);
+ if (!$page) return;
+ krsort($page); reset($page);
+ $lf = $LinkFunctions;
+ $LinkFunctions['http:'] = 'LinkSuppress';
+ $LinkFunctions['https:'] = 'LinkSuppress';
+ SDV($DiffHTMLFunction, 'DiffHTML');
+ foreach($page as $k=>$v) {
+ if (!preg_match("/^diff:(\d+):(\d+):?([^:]*)/",$k,$match)) continue;
+ $diffclass = $match[3];
+ if ($diffclass=='minor' && $DiffShow['minor']!='y') continue;
+ $diffgmt = $FmtV['$DiffGMT'] = $match[1];
+ $FmtV['$DiffTime'] = strftime($TimeFmt,$diffgmt);
+ $diffauthor = @$page["author:$diffgmt"];
+ if (!$diffauthor) @$diffauthor=$page["host:$diffgmt"];
+ if (!$diffauthor) $diffauthor="unknown";
+ $FmtV['$DiffChangeSum'] = htmlspecialchars(@$page["csum:$diffgmt"]);
+ $FmtV['$DiffHost'] = @$page["host:$diffgmt"];
+ $FmtV['$DiffAuthor'] = $diffauthor;
+ $FmtV['$DiffId'] = $k;
+ $html = $DiffHTMLFunction($pagename, $v);
+ if ($html===false) continue;
+ echo FmtPageName($DiffStartFmt,$pagename);
+ echo $html;
+ echo FmtPageName($DiffEndFmt,$pagename);
+ echo FmtPageName($DiffRestoreFmt,$pagename);
+ }
+ $LinkFunctions = $lf;
+}
+
+# This function converts a single diff entry from the wikipage file
+# into HTML, ready for display.
+function DiffHTML($pagename, $diff) {
+ global $FmtV, $DiffShow, $DiffAddFmt, $DiffDelFmt, $DiffEndDelAddFmt,
+ $DiffRenderSourceFunction;
+ SDV($DiffRenderSourceFunction, 'DiffRenderSource');
+ $difflines = explode("\n",$diff."\n");
+ $in=array(); $out=array(); $dtype=''; $html = '';
+ foreach($difflines as $d) {
+ if ($d>'') {
+ if ($d[0]=='-' || $d[0]=='\\') continue;
+ if ($d[0]=='<') { $out[]=substr($d,2); continue; }
+ if ($d[0]=='>') { $in[]=substr($d,2); continue; }
+ }
+ if (preg_match("/^(\\d+)(,(\\d+))?([adc])(\\d+)(,(\\d+))?/",
+ $dtype,$match)) {
+ if (@$match[7]>'') {
+ $lines='lines';
+ $count=$match[1].'-'.($match[1]+$match[7]-$match[5]);
+ } elseif ($match[3]>'') {
+ $lines='lines'; $count=$match[1].'-'.$match[3];
+ } else { $lines='line'; $count=$match[1]; }
+ if ($match[4]=='a' || $match[4]=='c') {
+ $txt = str_replace('line',$lines,$DiffDelFmt[$match[4]]);
+ $FmtV['$DiffLines'] = $count;
+ $html .= FmtPageName($txt,$pagename);
+ if ($DiffShow['source']=='y')
+ $html .= "
"
+ .$DiffRenderSourceFunction($in, $out, 0)
+ ."
";
+ else $html .= MarkupToHTML($pagename,
+ preg_replace('/\\(:.*?:\\)/e',"Keep(htmlspecialchars(PSS('$0')))", join("\n",$in)));
+ }
+ if ($match[4]=='d' || $match[4]=='c') {
+ $txt = str_replace('line',$lines,$DiffAddFmt[$match[4]]);
+ $FmtV['$DiffLines'] = $count;
+ $html .= FmtPageName($txt,$pagename);
+ if ($DiffShow['source']=='y')
+ $html .= "
"
+ .$DiffRenderSourceFunction($in, $out, 1)
+ ."
";
+ else $html .= MarkupToHTML($pagename,
+ preg_replace('/\\(:.*?:\\)/e',"Keep(htmlspecialchars(PSS('$0')))",join("\n",$out)));
+ }
+ $html .= FmtPageName($DiffEndDelAddFmt,$pagename);
+ }
+ $in=array(); $out=array(); $dtype=$d;
+ }
+ return $html;
+}
+function HandleDiff($pagename, $auth='read') {
+ global $HandleDiffFmt, $PageStartFmt, $PageDiffFmt, $PageEndFmt;
+ $page = RetrieveAuthPage($pagename, $auth, true, READPAGE_CURRENT);
+ if (!$page) { Abort("?cannot diff $pagename"); }
+ PCache($pagename, $page);
+ SDV($HandleDiffFmt,array(&$PageStartFmt,
+ &$PageDiffFmt,"
", 'function:PrintDiff', '
',
+ &$PageEndFmt));
+ PrintFmt($pagename,$HandleDiffFmt);
+}
+## Functions for simple word-diff (written by Petko Yotov)
+function DiffRenderSource($in, $out, $which) {
+ global $WordDiffFunction, $EnableDiffInline;
+ if (!IsEnabled($EnableDiffInline, 1)) {
+ $a = $which? $out : $in;
+ return str_replace("\n","
",htmlspecialchars(join("\n",$a)));
+ }
+ $lines = $cnt = $x2 = $y2 = array();
+ foreach($in as $line) {
+ $tmp = DiffPrepareInline($line);
+ if(!$which) $cnt[] = array(count($x2), count($tmp));
+ $x2 = array_merge($x2, $tmp);
+ }
+ foreach($out as $line) {
+ $tmp = DiffPrepareInline($line);
+ if($which) $cnt[] = array(count($y2), count($tmp));
+ $y2 = array_merge($y2, $tmp);
+ }
+ $z = $WordDiffFunction(implode("\n", $x2), implode("\n", $y2));
+
+ $z2 = array_map('htmlspecialchars', ($which? $y2 : $x2));
+ array_unshift($z2, '');
+ foreach (explode("\n", $z) as $zz) {
+ if (preg_match('/^(\\d+)(,(\\d+))?([adc])(\\d+)(,(\\d+))?/',$zz,$m)) {
+ $a1 = $a2 = $m[1];
+ if ($m[3]) $a2=$m[3];
+ $b1 = $b2 = $m[5];
+ if ($m[7]) $b2=$m[7];
+
+ if (!$which && ($m[4]=='c'||$m[4]=='d')) {
+ $z2[$a1] = '
'. $z2[$a1];
+ $z2[$a2] .= '';
+ }
+ if ($which && ($m[4]=='c'||$m[4]=='a')) {
+ $z2[$b1] = '
'.$z2[$b1];
+ $z2[$b2] .= ' ';
+ }
+ }
+ }
+ $line = array_shift($z2);
+ $z2[0] = $line.$z2[0];
+ foreach ($cnt as $a) $lines[] = implode('', array_slice($z2, $a[0], $a[1]));
+ $ret = trim(implode("\n", $lines));
+ return str_replace("\n","
",$ret);
+}
+## Split a line into pieces before passing it through `diff`
+function DiffPrepareInline($x) {
+ global $DiffSplitInlineDelims;
+ SDV($DiffSplitInlineDelims, "-@!?#$%^&*()=+[]{}.'\"\\:|,<>_/;~");
+ return preg_split("/([".preg_quote($DiffSplitInlineDelims, '/')."\\s])/",
+ $x, -1, PREG_SPLIT_DELIM_CAPTURE);
+}
+
+SDV($WordDiffFunction, 'PHPDiff'); # faster than sysdiff for many calls
+if (IsEnabled($EnableDiffInline, 1) && $DiffShow['source'] == 'y'
+ && $WordDiffFunction == 'PHPDiff' && !function_exists('PHPDiff'))
+ include_once("$FarmD/scripts/phpdiff.php");
diff --git a/scripts/pagetoc.php b/scripts/pagetoc.php
new file mode 100644
index 0000000..d09b1cc
--- /dev/null
+++ b/scripts/pagetoc.php
@@ -0,0 +1,286 @@
+
+function toggle(obj) {
+ var elstyle = document.getElementById(obj).style;
+ var text = document.getElementById(obj + \"tog\");
+ if (elstyle.display == 'none') {
+ elstyle.display = 'block';
+ text.innerHTML = \"{$ToggleText[0]}\";
+ } else {
+ elstyle.display = 'none';
+ text.innerHTML = \"{$ToggleText[1]}\";
+ }
+}
+";
+
+## in-page cross-references
+Markup('[[#|#','>nl1','/\[\[#([A-Za-z][-.:\w]*)\s*\|\s*#\]\]/e',
+ "'[[#$1 | '.CrossReference(\$pagename,\$x,'$1').']]'");
+Markup('[[#|*','<[[|','/\[\[#([A-Za-z][-.:\w]*)\s*\|\s*\*\]\]/',
+ '[[#$1 | $1]]');
+Markup('[[#|+','<[[|','/\[\[#([A-Za-z][-.:\w]*)\s*\|\s*\+\]\]/',
+ '[[#$1 | Back to $1]]');
+Markup("[^#",'<[[#|#','/\[\^#([A-Za-z][-.:\w]*)\^\]/e',"Shortcut(\$x,'$1')");
+SDVA($LinkCleanser, array(
+ '/`\..*?$/' => '...',
+ "/\\[\\[([^|\\]]+)\\|\\s*(.*?)\\]\\]($SuffixPattern)/e" =>
+ "MakeLink(\$pagename,PSS('$1'),PSS('$2'),'$3','\$LinkText')",
+ "/\\[\\[([^\\]]+?)\\s*-+>\\s*(.*?)\\]\\]($SuffixPattern)/e" =>
+ "MakeLink(\$pagename,PSS('$2'),PSS('$1'),'$3','\$LinkText')",
+ '/\\[\\[#([A-Za-z][-.:\\w]*)\\]\\]/' => "",
+ "/\\[\\[(.*?)\\]\\]($SuffixPattern)/e" =>
+ "MakeLink(\$pagename,PSS('$1'),NULL,'$2','\$LinkText')",
+ '/[\\[\\{](.*?)\\|(.*?)[\\]\\}]/' => '$1',
+ "/`(($GroupPattern([\\/.]))?($WikiWordPattern))/" => '$1',
+ "/$GroupPattern\\/($WikiWordPattern)/" => '$1'
+ ));
+
+function CrossReference($pagename,$text,$anchor) {
+ global $LinkCleanser;
+ $r = Shortcut($text,$anchor);
+ foreach ($LinkCleanser as $p => $c) $r = preg_replace($p,$c,$r);
+ return $r;
+}
+
+function Shortcut($text,$anchor) {
+ if (preg_match("/\\[\\[#+$anchor\\]\\]\\n?([^\n]+)/",$text,$match)) {
+ return preg_replace("/^[#*!:]+\s*/","",
+ preg_replace("/([^!]+)!.+/","$1",$match[1]));
+ } else {
+ return "
$anchor not found";
+ }
+}
+
+## [[##visibleanchor]]
+SDV($VisibleAnchor,'§');
+SDV($VisibleAnchorLinks,false);
+SDV($DefaultTocAnchor,'toc');
+$RefOrTitle = ($VisibleAnchorLinks) ? 'href' : 'title';
+
+## autonumber anchors
+Markup('^!#','
" .
+ Keep("" .
+ wordwrap($texta, 70) . " ") .
+ "\n$textb\n(:divend:)
\n";
+}
+
+Markup('`markup','links',"/`\./",''); ## included in extendmarkup.php
+
+## page table of contents
+$IdPattern = "[A-Za-z][-.:\w]*";
+if ($format=='pdf') {
+ SDV($DefaultTocTitle,'Contents');
+ SDV($TocHeaderFmt,
+ '[[#toc]]$TocTitle ');
+ SDV($RemoteTocFmt,
+ 'Contents of [[$Toc(#toc)]] ');
+} else {
+ SDV($DefaultTocTitle,'On this page...');
+ SDV($TocHeaderFmt,'[[#toc]]$TocTitle ');
+ SDV($RemoteTocFmt,'On page [[$Toc(#toc)]]... ');
+}
+SDV($NumberToc,true);
+SDV($L1TocChar, '.');
+SDV($OmitQMarkup,false);
+
+if ($action=="print" || $action=="publish") {
+ Markup('[[##','<[[#','/\[\[##([A-Za-z][-.:\w]*)\]\]/','[[#$1]]');
+ if ($action=='publish') Markup('toc','>include',
+ '/\(:([#\*])?toc(?:-(float|hide))?(?:\s+anchors=(v)isible)?(?:\s+(.*?))?:\)/', '');
+ Markup('tocback','directives','/\(:toc-back(?:\s+(.*?))?:\)/','');
+} else {
+ Markup('[[##','<[[#','/\[\[##([A-Za-z][-.:\w]*)\]\]/e',
+ "Keep(\"$VisibleAnchor \",
+ 'L')");
+}
+Markup('toc','>nl1',
+ '/\(:([#\*])?toc(?:-(float|hide))?(?:\s+anchors=(v)isible)?(?:\s+(.*?))?(?:\s+(Q))?:\)(.*)$/se',
+ "TableOfContents(\$pagename,'$1','$2',PSS('$4'),'$5',PSS('$6')).
+ TocEntryAnchors('$3',PSS('$6'))");
+SDV($TocBackFmt,'↑ Contents');
+Markup('tocback','directives','/\(:toc-back(?:\s+(.*?))?:\)/e',
+ "'[[#toc | '.TocLinkText(PSS('$1')).']]'");
+Markup('tocpage','directives','/\(:toc-page\s+(.*?)(?:\s+self=([01]))?:\)/e',
+ "RemoteTableOfContents(\$pagename,'$1','$2')");
+
+function RemoteTableOfContents($pagename,$ref,$self=0) {
+ global $TocHeaderFmt,$RemoteTocFmt;
+ $oTocHeader = $TocHeaderFmt;
+ $TocHeaderFmt = str_replace('$Toc',$ref,$RemoteTocFmt);
+ $tocname = MakePageName($pagename,$ref);
+ if ($tocname==$pagename && $self==0) return '';
+ $tocpage=RetrieveAuthPage($tocname,'read',false);
+ $toctext=@$tocpage['text'];
+ if (preg_match('/\(:([#\*])?toc(?:-(float|hide))?(?:\s+anchors=(v)isible)?(?:\s+(.*?))?(?:\s+(Q))?:\)(.*)$/se',$toctext,$m))
+ $toc = str_replace('[[#',"[[$ref#",
+ TableOfContents($tocname,$m[1],'page','',$m[5],PSS($m[6])));
+ $TocHeaderFmt = $oTocHeader;
+ return $toc;
+}
+
+function TocLinkText($text) {
+ global $TocBackFmt;
+ if ($text) $TocBackFmt = $text;
+ return $TocBackFmt;
+}
+
+function TocEntryAnchors($visible,$text) {
+ global $IdPattern;
+ return preg_replace("/\n(!+|Q:)((\[\[#+$IdPattern\]\])|##?)?/e",
+ '"\n$1".InsertAnchor($visible,"$1","$2")',$text);
+}
+
+function InsertAnchor($visible,$h,$mark) {
+ global $OmitQMarkup, $NumberToc, $L1TocChar;
+ static $l1,$l2,$toc1,$toc2;
+ if ($h=='Q:' && $OmitQMarkup) return $mark;
+ if ($mark=='') $visibility = ($visible=='') ? '#' : '##';
+ else $visibility = $mark;
+ if ($h=='Q:') return $visibility;
+ $r = '';
+ $len = strlen($h);
+ if ($l1==0) { $l1 = $len; }
+ else if ($len!=$l1 && $l2==0) { $l2 = $len; }
+# if ($l1==$len || $l2==$len) $r = $visibility;
+ if ($l1==$len) {
+ $toc1++; $toc2 = 0; $r = $visibility;
+ if ($NumberToc) $r .= "$toc1$L1TocChar ";
+ } elseif ($l2==$len) {
+ $toc2++; $r = $visibility;
+ if ($NumberToc) $r .= "$toc1.$toc2 ";
+ }
+ return $r;
+}
+
+function TableOfContents($pagename,$number,$float,$title,$includeq,$text) {
+ global $DefaultTocTitle,$TocHeaderFmt,$IdPattern,$NumberToc,$OmitQMarkup,
+ $format,$L1TocChar,$DefaultTocAnchor,$TocFloat,$HTMLHeaderFmt,
+ $ToggleText;
+ if ($includeq) $OmitQMarkup = (!$OmitQMarkup);
+ if ($float=='float') $TocFloat = (!$TocFloat);
+ $l1 = 0; $l2 = 0; $l3 = 0;
+ $q = 0; $prelen = 1; $counter = 0;
+ $r = ''; $toc1 = 0;
+ if (!$title) $title = $DefaultTocTitle;
+ $toc = str_replace('$TocTitle',$title,$TocHeaderFmt);
+ if ($number=='*') $NumberToc = false;
+ elseif ($number=='#') $NumberToc = true;
+ $closel = 0;
+ if ($format=='pdf') {
+ $l = 'tbook:item';
+ $s = ($NumberToc) ? 'tbook:enumerate' : 'tbook:itemize'; $sc = $s;
+ $toc = "$toc ".
+ "<$sc><$l>\$List$l>$s> ";
+ } elseif ($float=='hide') { return '';
+ } else {
+ $tocid = ($float=='page') ? 'ptocid' : 'tocid'; // remote toc?
+ $toggle = " ({$ToggleText[0]} )";
+ $l = 'li'; $s = ($NumberToc) ? 'ol' : 'ul';
+ $sc = "$s class='toc'";
+ $f = ($TocFloat) ? 'float' : '';
+ $toc = "$toc$toggle
" .
+ "<$sc id='$tocid'><$l>\$List$l>$s>
";
+ }
+ preg_match_all("/\n(!+|Q?:)\s*(\[\[#+$IdPattern\]\]|#*)([^\n]*)/",$text, $match);
+ for ($i=0;$i
diff --git a/scripts/pgcust.php b/scripts/pgcust.php
new file mode 100644
index 0000000..4b1c42e
--- /dev/null
+++ b/scripts/pgcust.php
@@ -0,0 +1,39 @@
+ '') $t1[] = "$x\n\\ No newline at end of file";
+ $t2 = explode("\n", $new);
+ $x = array_pop($t2);
+ if ($x > '') $t2[] = "$x\n\\ No newline at end of file";
+
+ $t1_start = 0; $t1_end = count($t1);
+ $t2_start = 0; $t2_end = count($t2);
+
+ # stop with a common ending
+ while ($t1_start < $t1_end && $t2_start < $t2_end
+ && $t1[$t1_end-1] == $t2[$t2_end-1]) { $t1_end--; $t2_end--; }
+
+ # skip over any common beginning
+ while ($t1_start < $t1_end && $t2_start < $t2_end
+ && $t1[$t1_start] == $t2[$t2_start]) { $t1_start++; $t2_start++; }
+
+ # build a reverse-index array using the line as key and line number as value
+ # don't store blank lines, so they won't be targets of the shortest distance
+ # search
+ for($i = $t1_start; $i < $t1_end; $i++) if ($t1[$i]>'') $r1[$t1[$i]][] = $i;
+ for($i = $t2_start; $i < $t2_end; $i++) if ($t2[$i]>'') $r2[$t2[$i]][] = $i;
+
+ $a1 = $t1_start; $a2 = $t2_start; # start at beginning of each list
+ $actions = array();
+
+ # walk this loop until we reach the end of one of the lists
+ while ($a1 < $t1_end && $a2 < $t2_end) {
+ # if we have a common element, save it and go to the next
+ if ($t1[$a1] == $t2[$a2]) { $actions[] = 4; $a1++; $a2++; continue; }
+
+ # otherwise, find the shortest move (Manhattan-distance) from the
+ # current location
+ $best1 = $t1_end; $best2 = $t2_end;
+ $s1 = $a1; $s2 = $a2;
+ while(($s1 + $s2 - $a1 - $a2) < ($best1 + $best2 - $a1 - $a2)) {
+ $d = -1;
+ foreach((array)@$r1[$t2[$s2]] as $n)
+ if ($n >= $s1) { $d = $n; break; }
+ if ($d >= $s1 && ($d + $s2 - $a1 - $a2) < ($best1 + $best2 - $a1 - $a2))
+ { $best1 = $d; $best2 = $s2; }
+ $d = -1;
+ foreach((array)@$r2[$t1[$s1]] as $n)
+ if ($n >= $s2) { $d = $n; break; }
+ if ($d >= $s2 && ($s1 + $d - $a1 - $a2) < ($best1 + $best2 - $a1 - $a2))
+ { $best1 = $s1; $best2 = $d; }
+ $s1++; $s2++;
+ }
+ while ($a1 < $best1) { $actions[] = 1; $a1++; } # deleted elements
+ while ($a2 < $best2) { $actions[] = 2; $a2++; } # added elements
+ }
+
+ # we've reached the end of one list, now walk to the end of the other
+ while($a1 < $t1_end) { $actions[] = 1; $a1++; } # deleted elements
+ while($a2 < $t2_end) { $actions[] = 2; $a2++; } # added elements
+
+ # and this marks our ending point
+ $actions[] = 8;
+
+ # now, let's follow the path we just took and report the added/deleted
+ # elements into $out.
+ $op = 0;
+ $x0 = $x1 = $t1_start; $y0 = $y1 = $t2_start;
+ $out = array();
+ foreach($actions as $act) {
+ if ($act == 1) { $op |= $act; $x1++; continue; }
+ if ($act == 2) { $op |= $act; $y1++; continue; }
+ if ($op > 0) {
+ $xstr = ($x1 == ($x0+1)) ? $x1 : ($x0+1) . ",$x1";
+ $ystr = ($y1 == ($y0+1)) ? $y1 : ($y0+1) . ",$y1";
+ if ($op == 1) $out[] = "{$xstr}d{$y1}";
+ elseif ($op == 3) $out[] = "{$xstr}c{$ystr}";
+ while ($x0 < $x1) { $out[] = '< ' . $t1[$x0]; $x0++; } # deleted elems
+ if ($op == 2) $out[] = "{$x1}a{$ystr}";
+ elseif ($op == 3) $out[] = '---';
+ while ($y0 < $y1) { $out[] = '> '.$t2[$y0]; $y0++; } # added elems
+ }
+ $x1++; $x0 = $x1;
+ $y1++; $y0 = $y1;
+ $op = 0;
+ }
+ $out[] = '';
+ StopWatch("PHPDiff: end");
+ return join("\n",$out);
+}
+
+if (!function_exists(@$DiffFunction))
+ $DiffFunction = 'PHPDiff';
+
diff --git a/scripts/prefs.php b/scripts/prefs.php
new file mode 100644
index 0000000..f4aa870
--- /dev/null
+++ b/scripts/prefs.php
@@ -0,0 +1,47 @@
+ '',
+ 'ak_edit' => 'e',
+ 'ak_history' => 'h',
+ 'ak_print' => '',
+ 'ak_recentchanges' => 'c',
+ 'ak_save' => 's',
+ 'ak_saveedit' => 'u',
+ 'ak_savedraft' => 'd',
+ 'ak_preview' => 'p',
+ 'ak_em' => '',
+ 'ak_strong' => '',
+ ));
+
diff --git a/scripts/refcount.php b/scripts/refcount.php
new file mode 100644
index 0000000..0064cca
--- /dev/null
+++ b/scripts/refcount.php
@@ -0,0 +1,121 @@
+Reference Count Results");
+SDV($RefCountTimeFmt," %Y-%b-%d %H:%M ");
+SDV($HandleActions['refcount'], 'HandleRefCount');
+
+function PrintRefCount($pagename) {
+ global $GroupPattern,$NamePattern,$PageRefCountFmt,$RefCountTimeFmt;
+ $pagelist = ListPages();
+ $grouplist = array();
+ foreach($pagelist as $pname) {
+ if (!preg_match("/^($GroupPattern)[\\/.]($NamePattern)$/",$pname,$m))
+ continue;
+ $grouplist[$m[1]]=$m[1];
+ }
+ asort($grouplist);
+ $grouplist = array_merge(array('all' => 'all groups'),$grouplist);
+
+ $wlist = array('all','missing','existing','orphaned');
+ $tlist = isset($_REQUEST['tlist']) ? $_REQUEST['tlist'] : array('all');
+ $flist = isset($_REQUEST['flist']) ? $_REQUEST['flist'] : array('all');
+ $whichrefs = @$_REQUEST['whichrefs'];
+ $showrefs = @$_REQUEST['showrefs'];
+ $submit = @$_REQUEST['submit'];
+
+ echo FmtPageName($PageRefCountFmt,$pagename);
+ echo "
+ Show
+ ";
+ foreach($wlist as $w)
+ echo "$w\n";
+ echo " page names in group
+ ";
+ foreach($grouplist as $g=>$t)
+ echo "$t\n";
+ echo " referenced from pages in
+ ";
+ foreach($grouplist as $g=>$t)
+ echo "$t\n";
+ echo "
+
+ Display referencing pages
+
";
+
+ if ($submit) {
+ foreach($pagelist as $pname) {
+ $ref = array();
+ $page = ReadPage($pname, READPAGE_CURRENT);
+ if (!$page) continue;
+ $tref[$pname]['time'] = $page['time'];
+ if (!in_array('all',$flist) &&
+ !in_array(FmtPageName('$Group',$pname),$flist)) continue;
+ $rc = preg_match('/RecentChanges$/',$pname);
+ foreach(explode(',',@$page['targets']) as $r) {
+ if ($r=='') continue;
+ if ($rc) @$tref[$r]['rc']++;
+ else { @$tref[$r]['page']++; @$pref[$r][$pname]++; }
+ }
+ }
+ uasort($tref,'RefCountCmp');
+ echo "
+ Referring pages
+ Name / Time All R.C. ";
+ reset($tref);
+ foreach($tref as $p=>$c) {
+ if (!in_array('all',$tlist) &&
+ !in_array(FmtPageName('$Group',$p),$tlist)) continue;
+ if ($whichrefs=='missing' && PageExists($p)) continue;
+ elseif ($whichrefs=='existing' && !PageExists($p)) continue;
+ elseif ($whichrefs=='orphaned' &&
+ (@$tref[$p]['page']>0 || !PageExists($p))) continue;
+ echo "",LinkPage($pagename, '', $p, '', $p);
+ if (@$tref[$p]['time']) echo strftime($RefCountTimeFmt,$tref[$p]['time']);
+ if ($showrefs && is_array(@$pref[$p])) {
+ foreach($pref[$p] as $pr=>$pc)
+ echo "", LinkPage($pagename, '', $pr, '', $pr);
+ }
+ echo " ";
+ echo "",@$tref[$p]['page']+0," ";
+ echo "",@$tref[$p]['rc']+0," ";
+ echo " ";
+ }
+ echo "
";
+ }
+}
+
+
+function RefCountCmp($ua,$ub) {
+ if (@($ua['page']!=$ub['page'])) return @($ub['page']-$ua['page']);
+ if (@($ua['rc']!=$ub['rc'])) return @($ub['rc']-$ua['rc']);
+ return @($ub['time']-$ua['time']);
+}
+
+
+
+function HandleRefCount($pagename, $auth='read') {
+ global $HandleRefCountFmt,$PageStartFmt,$PageEndFmt;
+ $page = RetrieveAuthPage($pagename, $auth, true, READPAGE_CURRENT);
+ if (!$page) Abort('?unauthorized');
+ PCache($pagename, $page);
+ SDV($HandleRefCountFmt,array(&$PageStartFmt,
+ 'function:PrintRefCount',&$PageEndFmt));
+ PrintFmt($pagename,$HandleRefCountFmt);
+}
+
diff --git a/scripts/robots.php b/scripts/robots.php
new file mode 100644
index 0000000..20400dc
--- /dev/null
+++ b/scripts/robots.php
@@ -0,0 +1,76 @@
+ tag in the head of the HTML document.
+ By default $MetaRobots is set so that robots do not index pages in
+ the Site, SiteAdmin, and PmWiki groups.
+
+ The $RobotPattern variable is used to determine if the user agent
+ accessing the site is a robot, and $IsRobotAgent is set accordingly.
+ By default this pattern identifies Googlebot, Yahoo! Slurp, msnbot,
+ BecomeBot, and HTTrack as robots.
+
+ If the agent is deemed a robot, then the $RobotActions array is
+ checked to see if robots are allowed to perform the given action,
+ and if not the robot is immediately sent an HTTP 403 Forbidden
+ response.
+
+ If $EnableRobotCloakActions is set, then a pattern is added to
+ $FmtP to hide any "?action=" url parameters in page urls
+ generated by PmWiki for actions that robots aren't allowed to
+ access. This can greatly reduce the load on the server by
+ not providing the robot with links to pages that it will be
+ forbidden to index anyway.
+*/
+
+## $MetaRobots provides the value for the tag.
+SDV($MetaRobots,
+ ($action!='browse' || !PageExists($pagename)
+ || preg_match('#^PmWiki[./](?!PmWiki$)|^Site(Admin)?[./]#', $pagename))
+ ? 'noindex,nofollow' : 'index,follow');
+if ($MetaRobots)
+ $HTMLHeaderFmt['robots'] =
+ " \n";
+
+## $RobotPattern is used to identify robots.
+SDV($RobotPattern,'Googlebot|Slurp|msnbot|Teoma|ia_archiver|BecomeBot|HTTrack|MJ12bot|XML Sitemaps|Yandex');
+SDV($IsRobotAgent,
+ $RobotPattern && preg_match("!$RobotPattern!", @$_SERVER['HTTP_USER_AGENT']));
+if (!$IsRobotAgent) return;
+
+## $RobotActions indicates which actions a robot is allowed to perform.
+SDVA($RobotActions, array('browse' => 1, 'rss' => 1, 'dc' => 1));
+if (!@$RobotActions[$action]) {
+ $pagename = ResolvePageName($pagename);
+ if (!PageExists($pagename)) {
+ header("HTTP/1.1 404 Not Found");
+ print("Not Found ");
+ exit();
+ }
+ header("HTTP/1.1 403 Forbidden");
+ print("Forbidden ");
+ exit();
+}
+
+## The following removes any ?action= parameters that robots aren't
+## allowed to access.
+if (IsEnabled($EnableRobotCloakActions, 0)) {
+ $p = create_function('$a', 'return (boolean)$a;');
+ $p = join('|', array_keys(array_filter($RobotActions, $p)));
+ $FmtPV['$PageUrl'] =
+ 'PUE(($EnablePathInfo)
+ ? "\\$ScriptUrl/$group/$name"
+ : "\\$ScriptUrl?n=$group.$name")';
+ $FmtP["/(\\\$ScriptUrl[^#\"'\\s<>]+)\\?action=(?!$p)\\w+/"] = '$1';
+}
diff --git a/scripts/simuledit.php b/scripts/simuledit.php
new file mode 100644
index 0000000..e198224
--- /dev/null
+++ b/scripts/simuledit.php
@@ -0,0 +1,67 @@
+= $Now
+ || $_POST['basetime']>=$page['time']
+ || $page['text'] == $new['text']) return;
+ $EnablePost = 0;
+ $old = array();
+ RestorePage($pagename,$page,$old,"diff:{$_POST['basetime']}");
+ $text = Merge($new['text'],$old['text'],$page['text']);
+ if ($text > '') { $new['text'] = $text; $ec = '$[EditConflict]'; }
+ else $ec = '$[EditWarning]';
+ XLSDV('en', array(
+ 'EditConflict' => "The page you are
+ editing has been modified since you started editing it.
+ The modifications have been merged into the text below,
+ you may want to verify the results of the merge before
+ pressing save. Conflicts the system couldn't resolve are
+ bracketed by <<<<<<< and
+ >>>>>>>.",
+ 'EditWarning' => "The page you are editing has been modified
+ since you started editing it. If you continue, your
+ changes will overwrite any changes that others have made."));
+ $MessagesFmt[] = "$ec
+ ($[View changes] )
+
\n";
+}
+
diff --git a/scripts/skins.php b/scripts/skins.php
new file mode 100644
index 0000000..a6fbd07
--- /dev/null
+++ b/scripts/skins.php
@@ -0,0 +1,147 @@
+ 0));
+
+# $PageTemplateFmt is deprecated
+if (isset($PageTemplateFmt)) LoadPageTemplate($pagename,$PageTemplateFmt);
+else {
+ $x = array_merge((array)@$ActionSkin[$action], (array)$Skin);
+ SetSkin($pagename, $x);
+}
+
+SDV($PageCSSListFmt,array(
+ 'pub/css/local.css' => '$PubDirUrl/css/local.css',
+ 'pub/css/{$Group}.css' => '$PubDirUrl/css/{$Group}.css',
+ 'pub/css/{$FullName}.css' => '$PubDirUrl/css/{$FullName}.css'));
+
+foreach((array)$PageCSSListFmt as $k=>$v)
+ if (file_exists(FmtPageName($k,$pagename)))
+ $HTMLHeaderFmt[] = " \n";
+
+# SetSkin changes the current skin to the first available skin from
+# the $skin array.
+function SetSkin($pagename, $skin) {
+ global $Skin, $SkinLibDirs, $SkinDir, $SkinDirUrl,
+ $IsTemplateLoaded, $PubDirUrl, $FarmPubDirUrl, $FarmD, $GCount;
+ SDV($SkinLibDirs, array(
+ "./pub/skins/\$Skin" => "$PubDirUrl/skins/\$Skin",
+ "$FarmD/pub/skins/\$Skin" => "$FarmPubDirUrl/skins/\$Skin"));
+ foreach((array)$skin as $sfmt) {
+ $Skin = FmtPageName($sfmt, $pagename); $GCount = 0;
+ foreach($SkinLibDirs as $dirfmt => $urlfmt) {
+ $SkinDir = FmtPageName($dirfmt, $pagename);
+ if (is_dir($SkinDir))
+ { $SkinDirUrl = FmtPageName($urlfmt, $pagename); break 2; }
+ }
+ }
+ if (!is_dir($SkinDir)) {
+ unset($Skin);
+ Abort("?unable to find skin from list ".implode(' ',(array)$skin));
+ }
+ $IsTemplateLoaded = 0;
+ if (file_exists("$SkinDir/$Skin.php"))
+ include_once("$SkinDir/$Skin.php");
+ else if (file_exists("$SkinDir/skin.php"))
+ include_once("$SkinDir/skin.php");
+ if ($IsTemplateLoaded) return;
+ if (file_exists("$SkinDir/$Skin.tmpl"))
+ LoadPageTemplate($pagename, "$SkinDir/$Skin.tmpl");
+ else if (file_exists("$SkinDir/skin.tmpl"))
+ LoadPageTemplate($pagename, "$SkinDir/skin.tmpl");
+ else if (($dh = opendir($SkinDir))) {
+ while (($fname = readdir($dh)) !== false) {
+ if ($fname[0] == '.') continue;
+ if (substr($fname, -5) != '.tmpl') continue;
+ if ($IsTemplateLoaded)
+ Abort("?unable to find unique template in $SkinDir");
+ LoadPageTemplate($pagename, "$SkinDir/$fname");
+ }
+ closedir($dh);
+ }
+ if (!$IsTemplateLoaded) Abort("Unable to load $Skin template", 'skin');
+}
+
+
+# LoadPageTemplate loads a template into $TmplFmt
+function LoadPageTemplate($pagename,$tfilefmt) {
+ global $PageStartFmt, $PageEndFmt,
+ $EnableSkinDiag, $HTMLHeaderFmt, $HTMLFooterFmt,
+ $IsTemplateLoaded, $TmplFmt, $TmplDisplay,
+ $PageTextStartFmt, $PageTextEndFmt, $SkinDirectivesPattern;
+
+ SDV($PageTextStartFmt, "\n\n");
+ SDV($PageTextEndFmt, "
\n");
+ SDV($SkinDirectivesPattern,
+ "[[<]!--((?:wiki|file|function|markup):.*?)--[]>]");
+
+ $sddef = array('PageEditFmt' => 0);
+ $k = implode('', file(FmtPageName($tfilefmt, $pagename)));
+
+ if (IsEnabled($EnableSkinDiag, 0)) {
+ if (!preg_match('//i', $k))
+ Abort("Skin template missing <!--HTMLHeader-->", 'htmlheader');
+ if (!preg_match('//i', $k))
+ Abort("Skin template missing <!--HTMLFooter-->", 'htmlheader');
+ }
+
+ $sect = preg_split(
+ '#[[<]!--(/?(?:Page[A-Za-z]+Fmt|(?:HT|X)ML(?:Head|Foot)er|HeaderText|PageText).*?)--[]>]#',
+ $k, 0, PREG_SPLIT_DELIM_CAPTURE);
+ $TmplFmt['Start'] = array_merge(array('headers:'),
+ preg_split("/$SkinDirectivesPattern/s",
+ array_shift($sect),0,PREG_SPLIT_DELIM_CAPTURE));
+ $TmplFmt['End'] = array($PageTextEndFmt);
+ $ps = 'Start';
+ while (count($sect)>0) {
+ $k = array_shift($sect);
+ $v = preg_split("/$SkinDirectivesPattern/s",
+ array_shift($sect),0,PREG_SPLIT_DELIM_CAPTURE);
+ $TmplFmt[$ps][] = "";
+ if ($k{0} == '/')
+ { $TmplFmt[$ps][] = (count($v) > 1) ? $v : $v[0]; continue; }
+ @list($var, $sd) = explode(' ', $k, 2);
+ $GLOBALS[$var] = (count($v) > 1) ? $v : $v[0];
+ if ($sd > '') $sddef[$var] = $sd;
+ if ($var == 'PageText') { $ps = 'End'; }
+ if ($var == 'HTMLHeader' || $var == 'XMLHeader')
+ $TmplFmt[$ps][] = &$HTMLHeaderFmt;
+ if ($var == 'HTMLFooter' || $var == 'XMLFooter')
+ $TmplFmt[$ps][] = &$HTMLFooterFmt;
+ ## deprecated, 2.1.16
+ if ($var == 'HeaderText') { $TmplFmt[$ps][] = &$HTMLHeaderFmt; }
+ $TmplFmt[$ps][$var] =& $GLOBALS[$var];
+ }
+ array_push($TmplFmt['Start'], $PageTextStartFmt);
+ $PageStartFmt = 'function:PrintSkin Start';
+ $PageEndFmt = 'function:PrintSkin End';
+ $IsTemplateLoaded = 1;
+ SDVA($TmplDisplay, $sddef);
+}
+
+# This function is called to print a portion of the skin template
+# according to the settings in $TmplDisplay.
+function PrintSkin($pagename, $arg) {
+ global $TmplFmt, $TmplDisplay;
+ foreach ($TmplFmt[$arg] as $k => $v)
+ if (!isset($TmplDisplay[$k]) || $TmplDisplay[$k])
+ PrintFmt($pagename, $v);
+}
+
diff --git a/scripts/stdconfig.php b/scripts/stdconfig.php
new file mode 100644
index 0000000..8fceeb7
--- /dev/null
+++ b/scripts/stdconfig.php
@@ -0,0 +1,89 @@
+".Keep($text)."";
+ $text = preg_replace("/\n[^\\S\n]+$/", "\n", $text);
+ if ($lead == "" || $lead == "\n")
+ return "$lead".Keep($text)." ";
+ return "$lead<:pre,1>".Keep($text);
+}
+
+Markup('[=','_begin',"/(\n[^\\S\n]*)?\\[([=@])(.*?)\\2\\]/se",
+ "PreserveText('$2', PSS('$3'), '$1')");
+Markup('restore','<_end',"/$KeepToken(\\d.*?)$KeepToken/e",
+ '$GLOBALS[\'KPV\'][\'$1\']');
+Markup('<:', '>restore',
+ '/<:[^>]*>/', '');
+Markup('', '/',
+ "
");
+Markup('', '<',
+ "/]*)(\\s)class=(['\"])([^>]*?)\\4)?/",
+ "
[=',
+ '/\\$\\[(?>([^\\]]+))\\]/e', "NoCache(XL(PSS('$1')))");
+
+# {$var} substitutions
+Markup('{$var}', '>$[phrase]',
+ '/\\{(\\*|!?[-\\w.\\/\\x80-\\xff]*)(\\$:?\\w+)\\}/e',
+ "PRR(PVSE(PageVar(\$pagename, '$2', '$1')))");
+
+# invisible (:textvar:...:) definition
+Markup('textvar:', '([A-Za-z0-9]+|#\\d+|#[xX][A-Fa-f0-9]+));/',
+ '&$1;');
+Markup('&', '<&', '/&/', Keep('&'));
+
+
+## (:if:)/(:elseif:)/(:else:)
+SDV($CondTextPattern,
+ "/ \\(:if (\d*) (?:end)? \\b[^\n]*?:\\)
+ .*?
+ (?: \\(: (?:if\\1|if\\1end) \\s* :\\)
+ | (?=\\(:(?:if\\1|if\\1end)\\b[^\n]*?:\\) | $)
+ )
+ /seix");
+SDV($CondTextReplacement, "CondText2(\$pagename, PSS('$0'), '$1')");
+Markup('if', 'fulltext', $CondTextPattern, $CondTextReplacement);
+
+function CondText2($pagename, $text, $code = '') {
+ global $Conditions, $CondTextPattern, $CondTextReplacement;
+ $if = "if$code";
+
+ $parts = preg_split("/\\(:(?:{$if}end|$if|else *$if|else$code)\\b\\s*(.*?)\\s*:\\)/",
+ $text, -1, PREG_SPLIT_DELIM_CAPTURE);
+ $x = array_shift($parts);
+ while ($parts) {
+ list($condspec, $condtext) = array_splice($parts, 0, 2);
+ if (!preg_match("/^\\s*(!?)\\s*(\\S*)\\s*(.*?)\\s*$/", $condspec, $match)) continue;
+ list($x, $not, $condname, $condparm) = $match;
+ if (!isset($Conditions[$condname]))
+ return preg_replace($CondTextPattern, $CondTextReplacement, $condtext);
+ $tf = @eval("return ({$Conditions[$condname]});");
+ if ($tf xor $not)
+ return preg_replace($CondTextPattern, $CondTextReplacement, $condtext);
+ }
+ return '';
+}
+
+
+## (:include:)
+Markup('include', '>if',
+ '/\\(:include\\s+(\\S.*?):\\)/ei',
+ "PRR(IncludeText(\$pagename, PSS('$1')))");
+
+## (:redirect:)
+Markup('redirect', 'include',
+ '/\\(:nogroupheader:\\)/ei',
+ "PZZ(\$GLOBALS['GroupHeaderFmt']='')");
+Markup('nogroupfooter', '>include',
+ '/\\(:nogroupfooter:\\)/ei',
+ "PZZ(\$GLOBALS['GroupFooterFmt']='')");
+Markup('groupheader', '>nogroupheader',
+ '/\\(:groupheader:\\)/ei',
+ "PRR(FmtPageName(\$GLOBALS['GroupHeaderFmt'],\$pagename))");
+Markup('groupfooter','>nogroupfooter',
+ '/\\(:groupfooter:\\)/ei',
+ "PRR(FmtPageName(\$GLOBALS['GroupFooterFmt'],\$pagename))");
+
+## (:nl:)
+Markup('nl0','(?:\\(:nl:\\))+)([^\n])/i","$1\n$2");
+Markup('nl1','>nl0',"/\\(:nl:\\)/i",'');
+
+## \\$ (end of line joins)
+Markup('\\$','>nl1',"/\\\\(?>(\\\\*))\n/e",
+ "str_repeat(' ',strlen('$1'))");
+
+## Remove one <:vspace> after !headings
+Markup('!vspace', '>\\$', "/^(!(?>[^\n]+)\n)<:vspace>/m", '$1');
+
+## (:noheader:),(:nofooter:),(:notitle:)...
+Markup('noheader', 'directives',
+ '/\\(:noheader:\\)/ei',
+ "SetTmplDisplay('PageHeaderFmt',0)");
+Markup('nofooter', 'directives',
+ '/\\(:nofooter:\\)/ei',
+ "SetTmplDisplay('PageFooterFmt',0)");
+Markup('notitle', 'directives',
+ '/\\(:notitle:\\)/ei',
+ "SetTmplDisplay('PageTitleFmt',0)");
+Markup('noleft', 'directives',
+ '/\\(:noleft:\\)/ei',
+ "SetTmplDisplay('PageLeftFmt',0)");
+Markup('noright', 'directives',
+ '/\\(:noright:\\)/ei',
+ "SetTmplDisplay('PageRightFmt',0)");
+Markup('noaction', 'directives',
+ '/\\(:noaction:\\)/ei',
+ "SetTmplDisplay('PageActionFmt',0)");
+
+## (:spacewikiwords:)
+Markup('spacewikiwords', 'directives',
+ '/\\(:(no)?spacewikiwords:\\)/ei',
+ "PZZ(\$GLOBALS['SpaceWikiWords']=('$1'!='no'))");
+
+## (:linkwikiwords:)
+Markup('linkwikiwords', 'directives',
+ '/\\(:(no)?linkwikiwords:\\)/ei',
+ "PZZ(\$GLOBALS['LinkWikiWords']=('$1'!='no'))");
+
+## (:linebreaks:)
+Markup('linebreaks', 'directives',
+ '/\\(:(no)?linebreaks:\\)/ei',
+ "PZZ(\$GLOBALS['HTMLPNewline'] = ('$1'!='no') ? ' ' : '')");
+
+## (:messages:)
+Markup('messages', 'directives',
+ '/^\\(:messages:\\)/ei',
+ "'<:block>'.Keep(
+ FmtPageName(implode('',(array)\$GLOBALS['MessagesFmt']), \$pagename))");
+
+## (:comment:)
+Markup('comment', 'directives', '/\\(:comment .*?:\\)/i', '');
+
+## (:title:) +fix for PITS:00266, 00779
+$tmpwhen = IsEnabled($EnablePageTitlePriority, 0) ? ' SetProperty(\$pagename, 'title', PSS('$1'), NULL, $tmpkeep))))");
+unset($tmpwhen, $tmpkeep);
+
+## (:keywords:), (:description:)
+Markup('keywords', 'directives',
+ "/\\(:keywords?\\s+(.+?):\\)/ei",
+ "PZZ(SetProperty(\$pagename, 'keywords', PSS('$1'), ', '))");
+Markup('description', 'directives',
+ "/\\(:description\\s+(.+?):\\)/ei",
+ "PZZ(SetProperty(\$pagename, 'description', PSS('$1'), '\n'))");
+$HTMLHeaderFmt['meta'] = 'function:PrintMetaTags';
+function PrintMetaTags($pagename, $args) {
+ global $PCache;
+ foreach(array('keywords', 'description') as $n) {
+ foreach((array)@$PCache[$pagename]["=p_$n"] as $v) {
+ $v = str_replace("'", ''', $v);
+ print " \n";
+ }
+ }
+}
+
+#### inline markups ####
+## ''emphasis''
+Markup("''",'inline',"/''(.*?)''/",'$1 ');
+
+## '''strong'''
+Markup("'''","<''","/'''(.*?)'''/",'$1 ');
+
+## '''''strong emphasis'''''
+Markup("'''''","<'''","/'''''(.*?)'''''/",'$1 ');
+
+## @@code@@
+Markup('@@','inline','/@@(.*?)@@/','$1');
+
+## '+big+', '-small-'
+Markup("'+","<'''''","/'\\+(.*?)\\+'/",'$1 ');
+Markup("'-","<'''''","/'\\-(.*?)\\-'/",'$1 ');
+
+## '^superscript^', '_subscript_'
+Markup("'^","<'''''","/'\\^(.*?)\\^'/",'$1 ');
+Markup("'_","<'''''","/'_(.*?)_'/",'$1 ');
+
+## [+big+], [-small-]
+Markup('[+','inline','/\\[(([-+])+)(.*?)\\1\\]/e',
+ "''.
+ PSS('$3 ')");
+
+## {+ins+}, {-del-}
+Markup('{+','inline','/\\{\\+(.*?)\\+\\}/','$1 ');
+Markup('{-','inline','/\\{-(.*?)-\\}/','$1');
+
+## [[<<]] (break)
+Markup('[[<<]]','inline','/\\[\\[<<\\]\\]/'," ");
+
+###### Links ######
+## [[free links]]
+Markup('[[','links',"/(?>\\[\\[\\s*(.*?)\\]\\])($SuffixPattern)/e",
+ "Keep(MakeLink(\$pagename,PSS('$1'),NULL,'$2'),'L')");
+
+## [[!Category]]
+SDV($CategoryGroup,'Category');
+SDV($LinkCategoryFmt,"\$LinkText ");
+Markup('[[!','<[[','/\\[\\[!(.*?)\\]\\]/e',
+ "Keep(MakeLink(\$pagename,PSS('$CategoryGroup/$1'),NULL,'',\$GLOBALS['LinkCategoryFmt']),'L')");
+# This is a temporary workaround for blank category pages.
+# It may be removed in a future release (Pm, 2006-01-24)
+if (preg_match("/^$CategoryGroup\\./", $pagename)) {
+ SDV($DefaultPageTextFmt, '');
+ SDV($PageNotFoundHeaderFmt, 'HTTP/1.1 200 Ok');
+}
+
+## [[target | text]]
+Markup('[[|','<[[',
+ "/(?>\\[\\[([^|\\]]*)\\|\\s*)(.*?)\\s*\\]\\]($SuffixPattern)/e",
+ "Keep(MakeLink(\$pagename,PSS('$1'),PSS('$2'),'$3'),'L')");
+
+## [[text -> target ]]
+Markup('[[->','>[[|',
+ "/(?>\\[\\[([^\\]]+?)\\s*-+>\\s*)(.*?)\\]\\]($SuffixPattern)/e",
+ "Keep(MakeLink(\$pagename,PSS('$2'),PSS('$1'),'$3'),'L')");
+
+if (IsEnabled($EnableRelativePageLinks, 1))
+ SDV($QualifyPatterns['/(\\[\\[(?>[^\\]]+?->)?\\s*)([-\\w\\x80-\\xfe\\s\'()]+([|#?].*?)?\\]\\])/e'], "PSS('$1').\$group.PSS('/$2')");
+
+## [[#anchor]]
+Markup('[[#','<[[','/(?>\\[\\[#([A-Za-z][-.:\\w]*))\\]\\]/e',
+ "Keep(TrackAnchors('$1') ? '' : \" \", 'L')");
+function TrackAnchors($x) { global $SeenAnchor; return @$SeenAnchor[$x]++; }
+
+## [[target |#]] reference links
+Markup('[[|#', '<[[|',
+ "/(?>\\[\\[([^|\\]]+))\\|\\s*#\\s*\\]\\]/e",
+ "Keep(MakeLink(\$pagename,PSS('$1'),'['.++\$MarkupFrame[0]['ref'].']'),'L')");
+
+## [[target |+]] title links
+Markup('[[|+', '<[[|',
+ "/(?>\\[\\[([^|\\]]+))\\|\\s*\\+\\s*]]/e",
+ "Keep(MakeLink(\$pagename, PSS('$1'),
+ PageVar(MakePageName(\$pagename,PSS('$1')), '\$Title')
+ ),'L')");
+
+## bare urllinks
+Markup('urllink','>[[',
+ "/\\b(?>(\\L))[^\\s$UrlExcludeChars]*[^\\s.,?!$UrlExcludeChars]/e",
+ "Keep(MakeLink(\$pagename,'$0','$0'),'L')");
+
+## mailto: links
+Markup('mailto','(\\L))([^\\s$UrlExcludeChars]+$ImgExtPattern)(\"([^\"]*)\")?/e",
+ "Keep(\$GLOBALS['LinkFunctions']['$1'](\$pagename,'$1','$2','$4','$1$2',
+ \$GLOBALS['ImgTagFmt']),'L')");
+
+## bare wikilinks
+## v2.2: markup rule moved to scripts/wikiwords.php)
+Markup('wikilink', '>urllink');
+
+## escaped `WikiWords
+## v2.2: rule kept here for markup compatibility with 2.1 and earlier
+Markup('`wikiword', ' markup (after all other block markups)
+Markup('^<:','>block','/^(?=\\s*\\S)(<:([^>]+)>)?/e',"Block('$2')");
+
+## unblocked lines w/block markup become anonymous <:block>
+Markup('^!<:', '<^<:',
+ "/^(?!<:)(?=.*(<\\/?($BlockPattern)\\b)|$KeepToken\\d+B$KeepToken)/",
+ '<:block>');
+
+## Lines that begin with displayed images receive their own block. A
+## pipe following the image indicates a "caption" (generates a linebreak).
+Markup('^img', 'block',
+ "/^((?>(\\s+|%%|%[A-Za-z][-,=:#\\w\\s'\".]*%)*)$KeepToken(\\d+L)$KeepToken)(\\s*\\|\\s?)?(.*)$/e",
+ "PSS((strpos(\$GLOBALS['KPV']['$3'],'$1' . ('$4' ? ' ' : '') .'$5
')");
+
+## Whitespace at the beginning of lines can be used to maintain the
+## indent level of a previous list item, or a preformatted text block.
+Markup('^ws', '<^img', '/^\\s+ #1/ex', "WSIndent('$0')");
+function WSIndent($i) {
+ global $MarkupFrame;
+ $icol = strlen($i);
+ for($depth = count(@$MarkupFrame[0]['cs']); $depth > 0; $depth--)
+ if (@$MarkupFrame[0]['is'][$depth] == $icol) {
+ $MarkupFrame[0]['idep'] = $depth;
+ $MarkupFrame[0]['icol'] = $icol;
+ return '';
+ }
+ return $i;
+}
+
+## The $EnableWSPre setting uses leading spaces on markup lines to indicate
+## blocks of preformatted text.
+SDV($EnableWSPre, 1);
+Markup('^ ', 'block',
+ '/^\\s+ #2/ex',
+ "(\$GLOBALS['EnableWSPre'] > 0 && strlen('$0') >= \$GLOBALS['EnableWSPre'])
+ ? '<:pre,1>$0' : '$0'");
+
+## bullet lists
+Markup('^*','block','/^(\\*+)\\s?(\\s*)/','<:ul,$1,$0>$2');
+
+## numbered lists
+Markup('^#','block','/^(#+)\\s?(\\s*)/','<:ol,$1,$0>$2');
+
+## indented (->) /hanging indent (-<) text
+Markup('^->','block','/^(?>(-+))>\\s?(\\s*)/','<:indent,$1,$1 $2>$2');
+Markup('^-<','block','/^(?>(-+))<\\s?(\\s*)/','<:outdent,$1,$1 $2>$2');
+
+## definition lists
+Markup('^::','block','/^(:+)(\s*)([^:]+):/','<:dl,$1,$1$2>$2$3 ');
+
+## Q: and A:
+Markup('^Q:', 'block', '/^Q:(.*)$/', "<:block,1>$1
");
+Markup('^A:', 'block', '/^A:/', Keep(''));
+
+## tables
+## ||cell||, ||!header cell||, ||!caption!||
+Markup('^||||', 'block',
+ '/^\\|\\|.*\\|\\|.*$/e',
+ "FormatTableRow(PSS('$0'))");
+## ||table attributes
+Markup('^||','>^||||','/^\\|\\|(.*)$/e',
+ "PZZ(\$GLOBALS['BlockMarkups']['table'][0] = '')
+ .'<:block,1>'");
+
+## headings
+Markup('^!', 'block',
+ '/^(!{1,6})\\s?(.*)$/e',
+ "'<:block,1>$2 '");
+
+## horiz rule
+Markup('^----','>^->','/^----+/','<:block,1> ');
+
+#### (:table:) markup (AdvancedTables)
+function Cells($name,$attr) {
+ global $MarkupFrame;
+ $attr = PQA($attr);
+ $tattr = @$MarkupFrame[0]['tattr'];
+ $name = strtolower($name);
+ $key = preg_replace('/end$/', '', $name);
+ if (preg_match("/^(?:head|cell)/", $name)) $key = 'cell';
+ $out = '<:block>'.MarkupClose($key);
+ if (substr($name, -3) == 'end') return $out;
+ $cf = & $MarkupFrame[0]['closeall'];
+ if ($name == 'table') $MarkupFrame[0]['tattr'] = $attr;
+ else if ($key == 'cell') {
+ if (strpos($attr, "valign=")===false) $attr .= " valign='top'";
+ $t = (strpos($name, 'head')===0 ) ? 'th' : 'td';
+ if (!@$cf['table']) {
+ $tattr = @$MarkupFrame[0]['tattr'];
+ $out .= "<$t $attr>";
+ $cf['table'] = '
';
+ } else if ( preg_match("/nr$/", $name)) $out .= "<$t $attr>";
+ else $out .= "<$t $attr>";
+ $cf['cell'] = "$t>";
+ } else {
+ $out .= "";
+ $cf[$key] = '
';
+ }
+ return $out;
+}
+
+Markup('table', '>', '><<', '<^>>',
+ '/^>><</',
+ '(:divend:)');
+
+#### special stuff ####
+## (:markup:) for displaying markup examples
+function MarkupMarkup($pagename, $text, $opt = '') {
+ global $MarkupWordwrapFunction;
+ SDV($MarkupWordwrapFunction, 'wordwrap');
+ $MarkupMarkupOpt = array('class' => 'vert');
+ $opt = array_merge($MarkupMarkupOpt, ParseArgs($opt));
+ $html = MarkupToHTML($pagename, $text, array('escape' => 0));
+ if (@$opt['caption'])
+ $caption = str_replace("'", ''',
+ "{$opt['caption']} ");
+ $class = preg_replace('/[^-\\s\\w]+/', ' ', @$opt['class']);
+ if (strpos($class, 'horiz') !== false)
+ { $sep = ''; $pretext = $MarkupWordwrapFunction($text, 40); }
+ else
+ { $sep = ''; $pretext = $MarkupWordwrapFunction($text, 75); }
+ return Keep(@"$caption
+ $pretext $sep$html
");
+}
+
+Markup('markup', '<[=',
+ "/\\(:markup(\\s+([^\n]*?))?:\\)[^\\S\n]*\\[([=@])(.*?)\\3\\]/sei",
+ "MarkupMarkup(\$pagename, PSS('$4'), PSS('$2'))");
+Markup('markupend', '>markup',
+ "/\\(:markup(\\s+([^\n]*?))?:\\)[^\\S\n]*\n(.*?)\\(:markupend:\\)/sei",
+ "MarkupMarkup(\$pagename, PSS('$3'), PSS('$1'))");
+
+SDV($HTMLStylesFmt['markup'], "
+ table.markup { border:2px dotted #ccf; width:90%; }
+ td.markup1, td.markup2 { padding-left:10px; padding-right:10px; }
+ table.vert td.markup1 { border-bottom:1px solid #ccf; }
+ table.horiz td.markup1 { width:23em; border-right:1px solid #ccf; }
+ table.markup caption { text-align:left; }
+ div.faq p, div.faq pre { margin-left:2em; }
+ div.faq p.question { margin:1em 0 0.75em 0; font-weight:bold; }
+ div.faqtoc div.faq * { display:none; }
+ div.faqtoc div.faq p.question
+ { display:block; font-weight:normal; margin:0.5em 0 0.5em 20px; line-height:normal; }
+ div.faqtoc div.faq p.question * { display:inline; }
+ ");
+
+#### Special conditions ####
+## The code below adds (:if date:) conditions to the markup.
+$Conditions['date'] = "CondDate(\$condparm)";
+
+function CondDate($condparm) {
+ global $Now;
+ if (!preg_match('/^(\\S*?)(\\.\\.(\\S*))?(\\s+\\S.*)?$/',
+ trim($condparm), $match))
+ return false;
+ if ($match[4] == '') { $x0 = $Now; NoCache(); }
+ else { list($x0, $x1) = DRange($match[4]); }
+ if ($match[1] > '') {
+ list($t0, $t1) = DRange($match[1]);
+ if ($x0 < $t0) return false;
+ if ($match[2] == '' && $x0 >= $t1) return false;
+ }
+ if ($match[3] > '') {
+ list($t0, $t1) = DRange($match[3]);
+ if ($x0 >= $t1) return false;
+ }
+ return true;
+}
+
+# This pattern enables the (:encrypt :) markup/replace-on-save
+# pattern.
+SDV($ROSPatterns['/\\(:encrypt\\s+([^\\s:=]+).*?:\\)/e'], "crypt(PSS('$1'))");
+
diff --git a/scripts/trails.php b/scripts/trails.php
new file mode 100644
index 0000000..ace0d7d
--- /dev/null
+++ b/scripts/trails.php
@@ -0,0 +1,127 @@
+> to be
+ used to build "trails" through wiki documents.
+
+ This feature is automatically included from stdconfig.php unless
+ disabled by $EnableWikiTrails = 0; . To explicitly include this feature,
+ execute
+ include_once("scripts/trails.php");
+ from config.php somewhere.
+
+ Once enabled, the <<|TrailPage|>> markup is replaced with
+ << PrevPage | TrailPage | NextPage >> on output. TrailPage should
+ contain either a bullet or number list defining the sequence of pages
+ in the "trail".
+
+ The ^|TrailPage|^ markup uses the depth of the bullets to display
+ the ancestry of the TrailPage to the current one. The <|TrailPage|>
+ markup is like <<|TrailPage|>> except that "< PrevPage |" and
+ "| NextPage >" are omitted if at the beginning or end of the
+ trail respectively. Thanks to John Rankin for contributing these
+ markups and the original suggestion for WikiTrails.
+*/
+
+Markup('<<|','<<|','/<\\|([^|]+|\\[\\[(.+?)\\]\\])\\|>/e',
+ "MakeTrailStopB(\$pagename,'$1')");
+Markup('^|','>/' => '$1',
+ '/<\\|([^|]+|\\[\\[(.+?)\\]\\])\\|>/' => '$1',
+ '/\\^\\|([^|]+|\\[\\[(.+?)\\]\\])\\|\\^/' => '$1'));
+
+$Conditions['ontrail'] = 'CondOnTrail($pagename, $condparm)';
+
+function CondOnTrail($pagename, $condparm) {
+ @list($trailname, $pn) = preg_split('/\\s+/', $condparm, 2);
+ $trail = ReadTrail($pagename, $trailname);
+ if (!$trail) return false;
+ $pn = ($pn > '') ? MakePageName($pagename, $pn) : $pagename;
+ foreach($trail as $t)
+ if ($t['pagename'] == $pn) return true;
+ return false;
+}
+
+function ReadTrail($pagename, $trailname) {
+ global $RASPageName, $SuffixPattern, $GroupPattern, $WikiWordPattern,
+ $LinkWikiWords;
+ if (preg_match('/^\\[\\[(.+?)(->|\\|)(.+?)\\]\\]$/', $trailname, $m))
+ $trailname = ($m[2] == '|') ? $m[1] : $m[3];
+ $trailtext = RetrieveAuthSection($pagename, $trailname);
+ $trailname = $RASPageName;
+ $trailtext = Qualify($trailname, $trailtext);
+ $t = array();
+ $n = 0;
+ foreach(explode("\n", htmlspecialchars(@$trailtext, ENT_NOQUOTES))
+ as $x) {
+ $x = preg_replace("/\\[\\[([^\\]]*)->([^\\]]*)\\]\\]/",'[[$2|$1]]',$x);
+ if (!preg_match("/^([#*:]+) \\s*
+ (\\[\\[([^:#!|][^|:]*?)(\\|.*?)?\\]\\]($SuffixPattern)
+ | (($GroupPattern([\\/.]))?$WikiWordPattern)) (.*)/x",$x,$match))
+ continue;
+ if (@$match[6]) {
+ if (!$LinkWikiWords) continue;
+ $tgt = MakePageName($trailname, $match[6]);
+ } else $tgt = MakePageName($trailname,
+ preg_replace('/[#?].+/', '', $match[3]));
+ $t[$n]['depth'] = $depth = strlen($match[1]);
+ $t[$n]['pagename'] = $tgt;
+ $t[$n]['markup'] = $match[2];
+ $t[$n]['detail'] = $match[9];
+ for($i=$depth;$i<10;$i++) $d[$i]=$n;
+ if ($depth>1) $t[$n]['parent']=@$d[$depth-1];
+ $n++;
+ }
+ return $t;
+}
+
+function MakeTrailStop($pagename,$trailname) {
+ $t = ReadTrail($pagename,$trailname);
+ $prev=''; $next='';
+ for($i=0;$i0) $prev = $t[$i-1]['markup'];
+ if ($i+1<< $prev | $trailname | $next >>";
+}
+
+function MakeTrailStopB($pagename,$trailname) {
+ $t = ReadTrail($pagename,$trailname);
+ $prev = ''; $next = '';
+ for($i=0;$i0) $prev = '< '.$t[$i-1]['markup'].' | ';
+ if ($i+1$prev$trailname$next";
+}
+
+function MakeTrailPath($pagename,$trailname) {
+ global $TrailPathSep;
+ SDV($TrailPathSep,' | ');
+ $t = ReadTrail($pagename,$trailname);
+ $crumbs = '';
+ for($i=0;$i0) {
+ $crumbs = $TrailPathSep.$t[$i]['markup'].$crumbs;
+ $i = @$t[$i]['parent'];
+ }
+ return "$trailname$crumbs ";
+ }
+ }
+ return "$trailname ";
+}
+
diff --git a/scripts/transition.php b/scripts/transition.php
new file mode 100644
index 0000000..b159cc9
--- /dev/null
+++ b/scripts/transition.php
@@ -0,0 +1,277 @@
+
+
+ $Transition['version'] < 2001006 - all transitions listed above
+
+ $Transition['fplbygroup'] - restore FPLByGroup function
+
+ $Transition['version'] < 2000915 - all transitions listed above
+
+ $Transition['mainrc'] - keep using Main.AllRecentChanges
+ $Transition['mainapprovedurls'] - keep using Main.ApprovedUrls
+ $Transition['pageeditfmt'] - default $PageEditFmt value
+ $Transition['mainpages'] - other default pages in Main
+
+ $Transition['version'] < 1999944 - all transitions listed above
+
+ To get all of the transitions for compatibility with a previous
+ version of PmWiki, simply set $Transition['version'] in a local
+ configuration file to the version number you want compatibility
+ with. All of the transitions associated with that version will
+ then be enabled. Example:
+
+ # Keep compatibility with PmWiki version 2.0.13
+ $Transition['version'] = 2000013;
+
+ To explicitly enable or disable specific transitions, set
+ the corresponding $Transition[] element to 1 or 0. This will
+ override the $Transition['version'] item listed above. For
+ example, to enable just the 'pageeditfmt' transition, use
+
+ $Transition['pageeditfmt'] = 1;
+
+*/
+
+## if ?trans=0 is specified, then we don't do any fixups.
+if (@$_REQUEST['trans']==='0') return;
+
+## set a default Transition version if we don't have one
+SDV($Transition['version'], $VersionNum);
+
+## Transitions from 2.2.0-beta67
+if (@$Transition['version'] < 2001967)
+ SDVA($Transition, array('nosessionencode' => 1));
+
+if (@$Transition['nosessionencode']) {
+ $SessionEncode = NULL;
+ $SessionDecode = NULL;
+}
+
+## Transitions from 2.2.0-beta41
+if (@$Transition['version'] < 2001941)
+ SDVA($Transition, array('wspre' => 1));
+
+if (@$Transition['wspre']) SDV($EnableWSPre, 1);
+
+## Transitions from 2.2.0-beta24
+if (@$Transition['version'] < 2001924)
+ SDVA($Transition, array('wikiwords' => 1));
+
+## wikiwords:
+## This restores the PmWiki 2.1 behavior for WikiWord processing.
+## WikiWords aren't linked by default, but appear with
+## ... tags around them.
+if (@$Transition['wikiwords']) {
+ SDV($EnableWikiWords, 1);
+ SDV($LinkWikiWords, 0);
+}
+
+## Transitions from 2.2.0-beta1
+if (@$Transition['version'] < 2001901)
+ SDVA($Transition, array('abslinks' => 1));
+
+## abslinks:
+## This restores settings so that PmWiki treats all links
+## as absolute (following the 2.1.x and earlier interpretation).
+if (@$Transition['abslinks']) {
+ SDV($EnableRelativePageLinks, 0);
+ SDV($EnableRelativePageVars, 0);
+}
+
+## Transitions from 2.1.12
+
+if (@$Transition['version'] < 2001012)
+ SDVA($Transition, array('nodivnest' => 1));
+
+## nodivnest:
+## This restores the PmWiki 2.1.11 behavior that doesn't
+## allow nesting of divs and tables.
+if (@$Transition['nodivnest']) {
+ function TCells($name,$attr) {
+ global $MarkupFrame;
+ $attr = preg_replace('/([a-zA-Z]=)([^\'"]\\S*)/',"\$1'\$2'",$attr);
+ $tattr = @$MarkupFrame[0]['tattr'];
+ $name = strtolower($name);
+ $out = '<:block>';
+ if (strncmp($name, 'cell', 4) != 0 || @$MarkupFrame[0]['closeall']['div']) {
+ $out .= @$MarkupFrame[0]['closeall']['div'];
+ unset($MarkupFrame[0]['closeall']['div']);
+ $out .= @$MarkupFrame[0]['closeall']['table'];
+ unset($MarkupFrame[0]['closeall']['table']);
+ }
+ if ($name == 'div') {
+ $MarkupFrame[0]['closeall']['div'] = "";
+ $out .= "";
+ }
+ if ($name == 'table') $MarkupFrame[0]['tattr'] = $attr;
+ if (strncmp($name, 'cell', 4) == 0) {
+ if (strpos($attr, "valign=")===false) $attr .= " valign='top'";
+ if (!@$MarkupFrame[0]['closeall']['table']) {
+ $MarkupFrame[0]['closeall']['table'] = "
";
+ $out .= "";
+ } else if ($name == 'cellnr') $out .= " ";
+ else $out .= " ";
+ }
+ return $out;
+ }
+
+ Markup('table', ' 1));
+
+## vspace:
+## This restores PmWiki's use of
to mark
+## vertical space in the output.
+if (@$Transition['vspace']) $HTMLVSpace = "
";
+
+
+## Transitions from 2.1.beta15
+
+if (@$Transition['version'] < 2000915)
+ SDVA($Transition, array('fplbygroup' => 1));
+
+## fplbygroup:
+## The FPLByGroup function was removed in 2.1.beta15, this restores it.
+if (@$Transition['fplbygroup'] && !function_exists('FPLByGroup')) {
+ SDV($FPLFormatOpt['bygroup'], array('fn' => 'FPLByGroup'));
+ function FPLByGroup($pagename, &$matches, $opt) {
+ global $FPLByGroupStartFmt, $FPLByGroupEndFmt, $FPLByGroupGFmt,
+ $FPLByGroupIFmt, $FPLByGroupOpt;
+ SDV($FPLByGroupStartFmt,"");
+ SDV($FPLByGroupEndFmt,' ');
+ SDV($FPLByGroupGFmt,"\$Group / \n");
+ SDV($FPLByGroupIFmt,"\$Name \n");
+ SDVA($FPLByGroupOpt, array('readf' => 0, 'order' => 'name'));
+ $matches = MakePageList($pagename,
+ array_merge((array)$FPLByGroupOpt, $opt), 0);
+ if (@$opt['count']) array_splice($matches, $opt['count']);
+ if (count($matches)<1) return '';
+ $out = '';
+ foreach($matches as $pn) {
+ $pgroup = FmtPageName($FPLByGroupGFmt, $pn);
+ if ($pgroup != @$lgroup) { $out .= $pgroup; $lgroup = $pgroup; }
+ $out .= FmtPageName($FPLByGroupIFmt, $pn);
+ }
+ return FmtPageName($FPLByGroupStartFmt, $pagename) . $out .
+ FmtPageName($FPLByGroupEndFmt, $pagename);
+ }
+}
+
+## Transitions from 2.0.beta44
+
+if (@$Transition['version'] < 1999944)
+ SDVA($Transition, array('mainrc' => 1, 'mainapprovedurls' => 1,
+ 'pageeditfmt' => 1, 'mainpages' => 1));
+
+## mainrc:
+## 2.0.beta44 switched Main.AllRecentChanges to be
+## $SiteGroup.AllRecentChanges. This setting keeps Main.AllRecentChanges
+## if it exists.
+if (@$Transition['mainrc'] && PageExists('Main.AllRecentChanges')) {
+ SDV($RecentChangesFmt['Main.AllRecentChanges'],
+ '* [[$Group.$Name]] . . . $CurrentTime $[by] $AuthorLink');
+}
+
+## siteapprovedurls:
+## 2.0.beta44 switched Main.ApprovedUrls to be $SiteGroup.ApprovedUrls .
+## This setting keeps using Main.ApprovedUrls if it exists.
+if (@$Transition['mainapprovedurls'] && PageExists('Main.ApprovedUrls')) {
+ $ApprovedUrlPagesFmt = (array)$ApprovedUrlPagesFmt;
+ if (PageExists(FmtPageName($ApprovedUrlPagesFmt[0], $pagename)))
+ $ApprovedUrlPagesFmt[] = 'Main.ApprovedUrls';
+ else array_unshift($ApprovedUrlPagesFmt, 'Main.ApprovedUrls');
+}
+
+## pageeditfmt:
+## 2.0.beta44 switched to using wiki markup forms for page editing.
+## However, some sites and skins have customized values of $PageEdit.
+## This setting restores the default values.
+if (@$Transition['pageeditfmt']) {
+ SDV($PageEditFmt, "");
+ if (@$_POST['preview'])
+ SDV($PagePreviewFmt, "
+
$[Preview \$FullName]
+
$[Page is unsaved]
+ \$PreviewText
+
$[End of preview -- remember to save]
+ $[Top]
");
+ SDV($HandleEditFmt, array(&$PageStartFmt,
+ &$PageEditFmt, 'wiki:$[PmWiki.EditQuickReference]', &$PagePreviewFmt,
+ &$PageEndFmt));
+ $EditMessageFmt = implode('', $MessagesFmt) . $EditMessageFmt;
+ if ($action=='edit' && IsEnabled($EnableGUIButtons, 0))
+ array_push($EditFunctions, 'GUIEdit');
+} else $MessagesFmt[] = @$EditMessageFmt;
+
+
+function GUIEdit($pagename, &$page, &$new) {
+ global $EditMessageFmt;
+ $EditMessageFmt .= GUIButtonCode($pagename);
+}
+
+## mainpages:
+## In 2.0.beta44 several utility pages change location to the new Site
+## group. These settings cause some skins (that use translations)
+## to know to link to the new locations.
+if (@$Transition['mainpages']) {
+ XLSDV('en', array(
+ 'Main/SearchWiki' => XL('Site/Search'),
+ 'PmWiki.EditQuickReference' => XL('Site/EditQuickReference'),
+ 'PmWiki.UploadQuickReference' => XL('Site/UploadQuickReference'),
+ ));
+}
+
diff --git a/scripts/upgrades.php b/scripts/upgrades.php
new file mode 100644
index 0000000..65d26f6
--- /dev/null
+++ b/scripts/upgrades.php
@@ -0,0 +1,98 @@
+ SiteAdmin.*
+ foreach(array('AuthUser', 'NotifyList', 'Blocklist', 'ApprovedUrls') as $n) {
+ $n0 = "$SiteGroup.$n"; $n1 = "$SiteAdminGroup.$n";
+ StopWatch("HandleUpgrade: checking $n0 -> $n1");
+ ## checking AuthUser is special, because Site.AuthUser comes with the
+ ## distribution.
+ if ($n == 'AuthUser') {
+ ## if we already have a user-modified SiteAdmin.AuthUser, we can skip
+ SDV($AuthUserPageFmt, '$SiteAdminGroup.AuthUser');
+ $n1 = FmtPageName($AuthUserPageFmt, $pagename);
+ $page = ReadPage($n1, READPAGE_CURRENT);
+ if (@$page['time'] > 1000000000) continue;
+ ## if there's not a user-modified Site.AuthUser, we can skip
+ $page = ReadPage($n0, READPAGE_CURRENT);
+ if (@$page['time'] == 1000000000) continue;
+ } else if (!PageExists($n0) || PageExists($n1)) continue;
+
+ if (@$_REQUEST['migrate'] == 'yes') {
+ ## if the admin wants PmWiki to migrate, do it.
+ $page = RetrieveAuthPage($n0, 'admin', true);
+ StopWatch("HandleUpgrade: copying $n0 -> $n1");
+ if ($page) {
+ WritePage($n1, $page);
+ $done .= "Copied $n0 to $n1 ";
+ continue;
+ }
+ }
+ $message .= "$n0 -> $n1 ";
+ }
+
+ if ($message) {
+ $migrateurl = "$ScriptUrl?action=upgrade&migrate=yes";
+ $infourl = 'http://www.pmwiki.org/wiki/PmWiki/UpgradeToSiteAdmin';
+ $message =
+ "Upgrade notice -- SiteAdmin group
+ This version of PmWiki expects several administrative pages
+ from the Site group to be found in a new SiteAdmin group.
+ On this site, the following pages appear to need to be relocated:
+
+
+ For more information about this change, including the various
+ options for proceeding, see
+ $infourl
+
+
+ If you would like PmWiki to attempt to automatically copy
+ these pages into their new locations for you, try
+
+
+
+ (admin password required)
+
+
+ If you want to configure PmWiki so that it continues to
+ look for the above pages in $SiteGroup , add the
+ following line near the top of local/config.php :
+
+ \$SiteAdminGroup = \$SiteGroup;
+
+ $Version
+ ";
+ print $message;
+ exit;
+ }
+
+ StopWatch("UpgradeCheck: writing $StatusPageName");
+ Lock(2);
+ SDV($StatusPageName, "$SiteAdminGroup.Status");
+ $page = ReadPage($StatusPageName);
+ $page['updatedto'] = $VersionNum;
+ WritePage($StatusPageName, $page);
+
+ if ($done) {
+ $done .= "Updated $StatusPageName ";
+ echo "Upgrade to $Version ... ok ";
+ $GLOBALS['EnableRedirect'] = 0;
+ }
+ Redirect($pagename);
+}
diff --git a/scripts/upload.php b/scripts/upload.php
new file mode 100644
index 0000000..19a629f
--- /dev/null
+++ b/scripts/upload.php
@@ -0,0 +1,327 @@
+ 'image/gif', 'jpg' => 'image/jpeg', 'jpeg' => 'image/jpeg',
+ 'png' => 'image/png', 'bmp' => 'image/bmp', 'ico' => 'image/x-icon',
+ 'wbmp' => 'image/vnd.wap.wbmp',
+ 'mp3' => 'audio/mpeg', 'au' => 'audio/basic', 'wav' => 'audio/x-wav',
+ 'mpg' => 'video/mpeg', 'mpeg' => 'video/mpeg',
+ 'mov' => 'video/quicktime', 'qt' => 'video/quicktime',
+ 'wmf' => 'text/plain', 'avi' => 'video/x-msvideo',
+ 'zip' => 'application/zip', '7z' => 'application/x-7z-compressed',
+ 'gz' => 'application/x-gzip', 'tgz' => 'application/x-gzip',
+ 'rpm' => 'application/x-rpm',
+ 'hqx' => 'application/mac-binhex40', 'sit' => 'application/x-stuffit',
+ 'doc' => 'application/msword', 'ppt' => 'application/vnd.ms-powerpoint',
+ 'xls' => 'application/vnd.ms-excel', 'mdb' => 'text/plain',
+ 'exe' => 'application/octet-stream',
+ 'pdf' => 'application/pdf', 'psd' => 'text/plain',
+ 'ps' => 'application/postscript', 'ai' => 'application/postscript',
+ 'eps' => 'application/postscript',
+ 'htm' => 'text/html', 'html' => 'text/html', 'css' => 'text/css',
+ 'fla' => 'application/x-shockwave-flash',
+ 'swf' => 'application/x-shockwave-flash',
+ 'txt' => 'text/plain', 'rtf' => 'application/rtf',
+ 'tex' => 'application/x-tex', 'dvi' => 'application/x-dvi',
+ 'odt' => 'application/vnd.oasis.opendocument.text',
+ 'ods' => 'application/vnd.oasis.opendocument.spreadsheet',
+ 'odp' => 'application/vnd.oasis.opendocument.presentation',
+ 'kml' => 'application/vnd.google-earth.kml+xml',
+ 'kmz' => 'application/vnd.google-earth.kmz',
+ '' => 'text/plain'));
+
+SDV($UploadMaxSize,50000);
+SDV($UploadPrefixQuota,0);
+SDV($UploadDirQuota,0);
+foreach($UploadExts as $k=>$v)
+ if (!isset($UploadExtSize[$k])) $UploadExtSize[$k]=$UploadMaxSize;
+
+SDV($UploadDir,'uploads');
+SDV($UploadPrefixFmt,'/$Group');
+SDV($UploadFileFmt,"$UploadDir$UploadPrefixFmt");
+$v = preg_replace('#^/(.*/)#', '', $UploadDir);
+SDV($UploadUrlFmt,preg_replace('#/[^/]*$#', "/$v", $PubDirUrl, 1));
+SDV($LinkUploadCreateFmt, "\$LinkText Δ ");
+SDVA($ActionTitleFmt, array('upload' => '| $[Attach]'));
+
+SDV($PageUploadFmt,array("
+
+
$[Attachments for] {\$FullName}
+
\$UploadResult
+
+
+
+ ",
+ 'wiki:$[{$SiteGroup}/UploadQuickReference]'));
+XLSDV('en',array(
+ 'ULsuccess' => 'successfully uploaded',
+ 'ULbadname' => 'invalid attachment name',
+ 'ULbadtype' => '\'$upext\' is not an allowed file extension',
+ 'ULtoobig' => 'file is larger than maximum allowed by webserver',
+ 'ULtoobigext' => 'file is larger than allowed maximum of $upmax
+ bytes for \'$upext\' files',
+ 'ULpartial' => 'incomplete file received',
+ 'ULnofile' => 'no file uploaded',
+ 'ULexists' => 'file with that name already exists',
+ 'ULpquota' => 'group quota exceeded',
+ 'ULtquota' => 'upload quota exceeded'));
+SDV($PageAttributes['passwdupload'],'$[Set new upload password:]');
+SDV($DefaultPasswords['upload'],'*');
+SDV($AuthCascade['upload'], 'read');
+SDV($FmtPV['$PasswdUpload'], 'PasswdVar($pn, "upload")');
+
+Markup('attachlist', 'directives',
+ '/\\(:attachlist\\s*(.*?):\\)/ei',
+ "Keep(''.FmtUploadList('$pagename',PSS('$1')).' ')");
+SDV($GUIButtons['attach'], array(220, 'Attach:', '', '$[file.ext]',
+ '$GUIButtonDirUrlFmt/attach.gif"$[Attach file]"'));
+SDV($LinkFunctions['Attach:'], 'LinkUpload');
+SDV($IMap['Attach:'], '$1');
+SDVA($HandleActions, array('upload' => 'HandleUpload',
+ 'postupload' => 'HandlePostUpload',
+ 'download' => 'HandleDownload'));
+SDVA($HandleAuth, array('upload' => 'upload',
+ 'download' => 'read'));
+SDV($HandleAuth['postupload'], $HandleAuth['upload']);
+SDV($UploadVerifyFunction, 'UploadVerifyBasic');
+
+function MakeUploadName($pagename,$x) {
+ global $UploadNameChars, $MakeUploadNamePatterns;
+ SDV($UploadNameChars, "-\\w. ");
+ SDV($MakeUploadNamePatterns, array(
+ "/[^$UploadNameChars]/" => '',
+ '/\\.[^.]*$/e' => 'strtolower("$0")',
+ '/^[^[:alnum:]_]+/' => '',
+ '/[^[:alnum:]_]+$/' => ''));
+ return preg_replace(array_keys($MakeUploadNamePatterns),
+ array_values($MakeUploadNamePatterns), $x);
+}
+
+function LinkUpload($pagename, $imap, $path, $alt, $txt, $fmt=NULL) {
+ global $FmtV, $UploadFileFmt, $LinkUploadCreateFmt, $UploadUrlFmt,
+ $UploadPrefixFmt, $EnableDirectDownload;
+ if (preg_match('!^(.*)/([^/]+)$!', $path, $match)) {
+ $pagename = MakePageName($pagename, $match[1]);
+ $path = $match[2];
+ }
+ $upname = MakeUploadName($pagename, $path);
+ $filepath = FmtPageName("$UploadFileFmt/$upname", $pagename);
+ $FmtV['$LinkUpload'] =
+ FmtPageName("\$PageUrl?action=upload&upname=$upname", $pagename);
+ $FmtV['$LinkText'] = $txt;
+ if (!file_exists($filepath))
+ return FmtPageName($LinkUploadCreateFmt, $pagename);
+ $path = PUE(FmtPageName(IsEnabled($EnableDirectDownload, 1)
+ ? "$UploadUrlFmt$UploadPrefixFmt/$upname"
+ : "{\$PageUrl}?action=download&upname=$upname",
+ $pagename));
+ return LinkIMap($pagename, $imap, $path, $alt, $txt, $fmt);
+}
+
+# Authenticate group downloads with the group password
+function UploadAuth($pagename, $auth, $cache=0){
+ global $GroupAttributesFmt, $EnableUploadGroupAuth;
+ if (IsEnabled($EnableUploadGroupAuth,0)){
+ SDV($GroupAttributesFmt,'$Group/GroupAttributes');
+ $pn_upload = FmtPageName($GroupAttributesFmt, $pagename);
+ } else $pn_upload = $pagename;
+ $page = RetrieveAuthPage($pn_upload, $auth, true, READPAGE_CURRENT);
+ if(!$page) Abort("?No '$auth' permissions for $pagename");
+ if($cache) PCache($pn_upload,$page);
+ return true;
+}
+
+function HandleUpload($pagename, $auth = 'upload') {
+ global $FmtV,$UploadExtMax,
+ $HandleUploadFmt,$PageStartFmt,$PageEndFmt,$PageUploadFmt;
+ UploadAuth($pagename, $auth, 1);
+ $FmtV['$UploadName'] = MakeUploadName($pagename,@$_REQUEST['upname']);
+ $upresult = htmlspecialchars(@$_REQUEST['upresult']);
+ $uprname = htmlspecialchars(@$_REQUEST['uprname']);
+ $FmtV['$upext'] = htmlspecialchars(@$_REQUEST['upext']);
+ $FmtV['$upmax'] = htmlspecialchars(@$_REQUEST['upmax']);
+ $FmtV['$UploadResult'] = ($upresult) ?
+ FmtPageName("$uprname : $[UL$upresult]",$pagename) : '';
+ SDV($HandleUploadFmt,array(&$PageStartFmt,&$PageUploadFmt,&$PageEndFmt));
+ PrintFmt($pagename,$HandleUploadFmt);
+}
+
+function HandleDownload($pagename, $auth = 'read') {
+ global $UploadFileFmt, $UploadExts, $DownloadDisposition;
+ SDV($DownloadDisposition, "inline");
+ UploadAuth($pagename, $auth);
+ $upname = MakeUploadName($pagename, @$_REQUEST['upname']);
+ $filepath = FmtPageName("$UploadFileFmt/$upname", $pagename);
+ if (!$upname || !file_exists($filepath)) {
+ header("HTTP/1.0 404 Not Found");
+ Abort("?requested file not found");
+ exit();
+ }
+ preg_match('/\\.([^.]+)$/',$filepath,$match);
+ if ($UploadExts[@$match[1]])
+ header("Content-Type: {$UploadExts[@$match[1]]}");
+ header("Content-Length: ".filesize($filepath));
+ header("Content-disposition: $DownloadDisposition; filename=\"$upname\"");
+ $fp = fopen($filepath, "r");
+ if ($fp) {
+ while (!feof($fp)) echo fread($fp, 4096);
+ fclose($fp);
+ }
+ exit();
+}
+
+function HandlePostUpload($pagename, $auth = 'upload') {
+ global $UploadVerifyFunction, $UploadFileFmt, $LastModFile,
+ $EnableUploadVersions, $Now, $RecentUploadsFmt, $FmtV;
+ UploadAuth($pagename, $auth);
+ $uploadfile = $_FILES['uploadfile'];
+ $upname = $_REQUEST['upname'];
+ if ($upname=='') $upname=$uploadfile['name'];
+ $upname = MakeUploadName($pagename,$upname);
+ if (!function_exists($UploadVerifyFunction))
+ Abort('?no UploadVerifyFunction available');
+ $filepath = FmtPageName("$UploadFileFmt/$upname",$pagename);
+ $result = $UploadVerifyFunction($pagename,$uploadfile,$filepath);
+ if ($result=='') {
+ $filedir = preg_replace('#/[^/]*$#','',$filepath);
+ mkdirp($filedir);
+ if (IsEnabled($EnableUploadVersions, 0))
+ @rename($filepath, "$filepath,$Now");
+ if (!move_uploaded_file($uploadfile['tmp_name'],$filepath))
+ { Abort("?cannot move uploaded file to $filepath"); return; }
+ fixperms($filepath,0444);
+ if ($LastModFile) { touch($LastModFile); fixperms($LastModFile); }
+ $result = "upresult=success";
+ if (IsEnabled($RecentUploadsFmt, 0)) {
+ $FmtV['$upname'] = $upname;
+ $FmtV['$upsize'] = $uploadfile['size'];
+ PostRecentChanges($pagename, '', '', $RecentUploadsFmt);
+ }
+ }
+ Redirect($pagename,"{\$PageUrl}?action=upload&uprname=$upname&$result");
+}
+
+function UploadVerifyBasic($pagename,$uploadfile,$filepath) {
+ global $EnableUploadOverwrite,$UploadExtSize,$UploadPrefixQuota,
+ $UploadDirQuota,$UploadDir;
+ if (!$EnableUploadOverwrite && file_exists($filepath))
+ return 'upresult=exists';
+ preg_match('/\\.([^.\\/]+)$/',$filepath,$match); $ext=@$match[1];
+ $maxsize = $UploadExtSize[$ext];
+ if ($maxsize<=0) return "upresult=badtype&upext=$ext";
+ if ($uploadfile['size']>$maxsize)
+ return "upresult=toobigext&upext=$ext&upmax=$maxsize";
+ switch (@$uploadfile['error']) {
+ case 1: return 'upresult=toobig';
+ case 2: return 'upresult=toobig';
+ case 3: return 'upresult=partial';
+ case 4: return 'upresult=nofile';
+ }
+ if (!is_uploaded_file($uploadfile['tmp_name'])) return 'upresult=nofile';
+ $filedir = preg_replace('#/[^/]*$#','',$filepath);
+ if ($UploadPrefixQuota &&
+ (dirsize($filedir)-@filesize($filepath)+$uploadfile['size']) >
+ $UploadPrefixQuota) return 'upresult=pquota';
+ if ($UploadDirQuota &&
+ (dirsize($UploadDir)-@filesize($filepath)+$uploadfile['size']) >
+ $UploadDirQuota) return 'upresult=tquota';
+ return '';
+}
+
+function dirsize($dir) {
+ $size = 0;
+ $dirp = @opendir($dir);
+ if (!$dirp) return 0;
+ while (($file=readdir($dirp)) !== false) {
+ if ($file[0]=='.') continue;
+ if (is_dir("$dir/$file")) $size+=dirsize("$dir/$file");
+ else $size+=filesize("$dir/$file");
+ }
+ closedir($dirp);
+ return $size;
+}
+
+function FmtUploadList($pagename, $args) {
+ global $UploadDir, $UploadPrefixFmt, $UploadUrlFmt, $EnableUploadOverwrite,
+ $TimeFmt, $EnableDirectDownload;
+
+ $opt = ParseArgs($args);
+ if (@$opt[''][0]) $pagename = MakePageName($pagename, $opt[''][0]);
+ if (@$opt['ext'])
+ $matchext = '/\\.('
+ . implode('|', preg_split('/\\W+/', $opt['ext'], -1, PREG_SPLIT_NO_EMPTY))
+ . ')$/i';
+
+ $uploaddir = FmtPageName("$UploadDir$UploadPrefixFmt", $pagename);
+ $uploadurl = FmtPageName(IsEnabled($EnableDirectDownload, 1)
+ ? "$UploadUrlFmt$UploadPrefixFmt/"
+ : "\$PageUrl?action=download&upname=",
+ $pagename);
+
+ $dirp = @opendir($uploaddir);
+ if (!$dirp) return '';
+ $filelist = array();
+ while (($file=readdir($dirp)) !== false) {
+ if ($file{0} == '.') continue;
+ if (@$matchext && !preg_match(@$matchext, $file)) continue;
+ $filelist[$file] = $file;
+ }
+ closedir($dirp);
+ $out = array();
+ natcasesort($filelist);
+ $overwrite = '';
+ foreach($filelist as $file=>$x) {
+ $name = PUE("$uploadurl$file");
+ $stat = stat("$uploaddir/$file");
+ if ($EnableUploadOverwrite)
+ $overwrite = FmtPageName(" Δ ",
+ $pagename);
+ $out[] = " $file $overwrite ... ".
+ number_format($stat['size']) . " bytes ... " .
+ strftime($TimeFmt, $stat['mtime']) . " ";
+ }
+ return implode("\n",$out);
+}
+
+# this adds (:if [!]attachments:) to the markup
+$Conditions['attachments'] = "AttachExist(\$pagename)";
+function AttachExist($pagename) {
+ global $UploadDir, $UploadPrefixFmt;
+ $uploaddir = FmtPageName("$UploadDir$UploadPrefixFmt", $pagename);
+ $count = 0;
+ $dirp = @opendir($uploaddir);
+ if ($dirp) {
+ while (($file = readdir($dirp)) !== false)
+ if ($file{0} != '.') $count++;
+ closedir($dirp);
+ }
+ return $count;
+}
diff --git a/scripts/urlapprove.php b/scripts/urlapprove.php
new file mode 100644
index 0000000..4400bd6
--- /dev/null
+++ b/scripts/urlapprove.php
@@ -0,0 +1,125 @@
+$[(approve sites)]");
+$HTMLStylesFmt['urlapprove'] = '.apprlink { font-size:smaller; }';
+SDV($ApproveUrlPattern,
+ "\\bhttps?:[^\\s$UrlExcludeChars]*[^\\s.,?!$UrlExcludeChars]");
+$WhiteUrlPatterns = (array)$WhiteUrlPatterns;
+SDV($HandleActions['approveurls'], 'HandleApprove');
+SDV($HandleAuth['approveurls'], 'edit');
+SDV($HandleActions['approvesites'], 'HandleApprove');
+SDV($HandleAuth['approvesites'], 'edit');
+SDV($UnapprovedLinkCountMax, 1000000);
+array_splice($EditFunctions, array_search('PostPage', $EditFunctions),
+ 0, 'BlockUnapprovedPosts');
+
+function LinkHTTP($pagename,$imap,$path,$alt,$txt,$fmt=NULL) {
+ global $EnableUrlApprovalRequired, $IMap, $WhiteUrlPatterns, $FmtV,
+ $UnapprovedLink, $UnapprovedLinkCount, $UnapprovedLinkFmt;
+ if (!IsEnabled($EnableUrlApprovalRequired,1))
+ return LinkIMap($pagename,$imap,$path,$alt,$txt,$fmt);
+ static $havereadpages;
+ if (!$havereadpages) { ReadApprovedUrls($pagename); $havereadpages=true; }
+ $p = str_replace(' ','%20',$path);
+ $url = str_replace('$1',$p,$IMap[$imap]);
+ if (!isset($UnapprovedLink)) $UnapprovedLink = array();
+ foreach((array)$WhiteUrlPatterns as $pat) {
+ if (preg_match("!^$pat(/|$)!i",$url))
+ return LinkIMap($pagename,$imap,$path,$alt,$txt,$fmt);
+ }
+ $FmtV['$LinkUrl'] = PUE(str_replace('$1',$path,$IMap[$imap]));
+ $FmtV['$LinkText'] = $txt;
+ $FmtV['$LinkAlt'] = str_replace(array('"',"'"),array('"','''),$alt);
+ $UnapprovedLink[] = $url;
+ @$UnapprovedLinkCount++;
+ return FmtPageName($UnapprovedLinkFmt,$pagename);
+}
+
+function ReadApprovedUrls($pagename) {
+ global $ApprovedUrlPagesFmt,$ApproveUrlPattern,$WhiteUrlPatterns;
+ foreach((array)$ApprovedUrlPagesFmt as $p) {
+ $pn = FmtPageName($p, $pagename);
+ StopWatch("ReadApprovedUrls $pn begin");
+ $apage = ReadPage($pn, READPAGE_CURRENT);
+ preg_match_all("/$ApproveUrlPattern/",@$apage['text'],$match);
+ foreach($match[0] as $a)
+ $WhiteUrlPatterns[] = preg_quote($a,'!');
+ StopWatch("ReadApprovedUrls $pn end");
+ }
+}
+
+function HandleApprove($pagename, $auth='edit') {
+ global $ApproveUrlPattern,$WhiteUrlPatterns,$ApprovedUrlPagesFmt,$action;
+ Lock(2);
+ $page = ReadPage($pagename);
+ $text = preg_replace('/[()]/','',$page['text']);
+ preg_match_all("/$ApproveUrlPattern/",$text,$match);
+ ReadApprovedUrls($pagename);
+ $addpat = array();
+ foreach($match[0] as $a) {
+ if ($action=='approvesites')
+ $a=preg_replace("!^([^:]+://[^/]+).*$!",'$1',$a);
+ $addpat[] = $a;
+ }
+ if (count($addpat)>0) {
+ $aname = FmtPageName($ApprovedUrlPagesFmt[0],$pagename);
+ $apage = RetrieveAuthPage($aname, $auth);
+ if (!$apage) Abort("?cannot edit $aname");
+ $new = $apage;
+ if (substr($new['text'],-1,1)!="\n") $new['text'].="\n";
+ foreach($addpat as $a) {
+ foreach((array)$WhiteUrlPatterns as $pat)
+ if (preg_match("!^$pat(/|$)!i",$a)) continue 2;
+ $urlp = preg_quote($a,'!');
+ $WhiteUrlPatterns[] = $urlp;
+ $new['text'].=" $a\n";
+ }
+ $_POST['post'] = 'y';
+ PostPage($aname,$apage,$new);
+ }
+ Redirect($pagename);
+}
+
+function BlockUnapprovedPosts($pagename, &$page, &$new) {
+ global $EnableUrlApprovalRequired, $UnapprovedLinkCount,
+ $UnapprovedLinkCountMax, $EnablePost, $MessagesFmt, $BlockMessageFmt;
+ if (!IsEnabled($EnableUrlApprovalRequired, 1)) return;
+ if ($UnapprovedLinkCount <= $UnapprovedLinkCountMax) return;
+ if ($page['=auth']['admin']) return;
+ $EnablePost = 0;
+ $MessagesFmt[] = $BlockMessageFmt;
+}
+
diff --git a/scripts/vardoc.php b/scripts/vardoc.php
new file mode 100644
index 0000000..a6bd777
--- /dev/null
+++ b/scripts/vardoc.php
@@ -0,0 +1,78 @@
+\$LinkText");
+ VarIndexLoad($pagename);
+ $FmtV['$LinkText'] = str_replace('$', '$', $txt);
+ $FmtV['$LinkUrl'] = @$VarIndex[$tgt]['url'];
+ if (@!$VarIndex[$tgt]['url'])
+ return FmtPageName($VarLinkMissingFmt,$pagename);
+ return FmtPageName($VarLinkExistsFmt,$pagename);
+}
+
+function VarIndexLoad($pagename) {
+ global $VarPagesFmt,$VarIndex,$WikiWordPattern;
+ static $loaded;
+ $VarIndex = (array)@$VarIndex;
+ if ($loaded) return;
+ foreach($VarPagesFmt as $vf) {
+ $v = FmtPageName($vf, $pagename);
+ if (@$loaded[$v]) continue;
+ $vlist = array($v);
+ $t = ReadTrail($pagename,$v);
+ if ($t)
+ for($i=0;$iVariable Documented in \n";
+ foreach($VarIndex as $v=>$a)
+ $out .= FmtPageName("$$v{\$Name} \n",$a['pagename']);
+ $out .= "
";
+ return $out;
+}
+
diff --git a/scripts/version.php b/scripts/version.php
new file mode 100644
index 0000000..0059537
--- /dev/null
+++ b/scripts/version.php
@@ -0,0 +1 @@
+split',
+ "/^(?=%define=)((?:$WikiStylePattern)\\s*)+$/e",
+ "PZZ(ApplyStyles(PSS('$0')))");
+
+## restore links before applying styles
+Markup('restorelinks','<%%',"/$KeepToken(\\d+L)$KeepToken/e",
+ '$GLOBALS[\'KPV\'][\'$1\']');
+
+# define PmWiki's standard/default wikistyles
+if (IsEnabled($EnableStdWikiStyles,1)) {
+ ## standard colors
+ foreach(array('black','white','red','yellow','blue','gray',
+ 'silver','maroon','green','navy','purple') as $c)
+ SDV($WikiStyle[$c]['color'],$c);
+ ## %newwin% style opens links in a new window
+ SDV($WikiStyle['newwin']['target'],'_blank');
+ ## %comment% style turns markup into a comment via display:none css
+ SDV($WikiStyle['comment']['display'],'none');
+ ## display, margin, padding, and border css properties
+ $WikiStyleCSS[] =
+ 'float|display|(margin|padding|border)(-(left|right|top|bottom))?';
+ $WikiStyleCSS[] = 'white-space';
+ ## list-styles
+ $WikiStyleCSS[] = 'list-style';
+ $WikiStyleCSS[] = 'width|height';
+ foreach(array('decimal'=>'decimal', 'roman'=>'lower-roman',
+ 'ROMAN'=>'upper-roman', 'alpha'=>'lower-alpha', 'ALPHA'=>'upper-alpha')
+ as $k=>$v)
+ SDV($WikiStyle[$k],array('apply'=>'list','list-style'=>$v));
+ ## apply ranges
+ SDVA($WikiStyleApply,array(
+ 'item' => 'li|dt',
+ 'list' => 'ul|ol|dl',
+ 'div' => 'div',
+ 'pre' => 'pre',
+ 'img' => 'img',
+ 'block' => 'p(?!\\sclass=)|div|ul|ol|dl|li|dt|pre|h[1-6]',
+ 'p' => 'p(?!\\sclass=)'));
+ foreach(array('item', 'list', 'block', 'p', 'div') as $c)
+ SDV($WikiStyle[$c],array('apply'=>$c));
+ ## block justifications
+ foreach(array('left','right','center') as $c)
+ SDV($WikiStyle[$c],array('apply'=>'block','text-align'=>$c));
+ ## frames, floating frames, and floats
+ SDV($HTMLStylesFmt['wikistyles'], "
+ .frame
+ { border:1px solid #cccccc; padding:4px; background-color:#f9f9f9; }
+ .lfloat { float:left; margin-right:0.5em; }
+ .rfloat { float:right; margin-left:0.5em; }\n");
+ SDV($WikiStyle['thumb'], array('width' => '100px'));
+ SDV($WikiStyle['frame'], array('class' => 'frame'));
+ SDV($WikiStyle['lframe'], array('class' => 'frame lfloat'));
+ SDV($WikiStyle['rframe'], array('class' => 'frame rfloat'));
+ SDV($WikiStyle['cframe'], array(
+ 'class' => 'frame', 'margin-left' => 'auto', 'margin-right' => 'auto',
+ 'width' => '200px', 'apply' => 'block', 'text-align' => 'center'));
+ ## preformatted text sections
+ SDV($WikiStyle['pre'], array('apply' => 'block', 'white-space' => 'pre'));
+ SDV($WikiStyle['sidehead'], array('apply' => 'block', 'class' => 'sidehead'));
+}
+
+SDVA($WikiStyleAttr,array(
+ 'vspace' => 'img',
+ 'hspace' => 'img',
+ 'align' => 'img',
+ 'value' => 'li',
+ 'target' => 'a',
+ 'accesskey' => 'a',
+ 'rel' => 'a'));
+
+SDVA($WikiStyleRepl,array(
+ '/^%(.*)%$/' => '$1',
+ '/\\bbgcolor([:=])/' => 'background-color$1',
+ '/\\b(\d+)pct\\b/' => '$1%',
+ ));
+
+$WikiStyleCSS[] = 'color|background-color';
+$WikiStyleCSS[] = 'text-align|text-decoration';
+$WikiStyleCSS[] = 'font-size|font-family|font-weight|font-style';
+
+SDV($imgTag, '(?:img|object|embed)'); SDV($aTag, 'a'); SDV($spanTag, 'span');
+
+function ApplyStyles($x) {
+ global $UrlExcludeChars, $WikiStylePattern, $WikiStyleRepl, $WikiStyle,
+ $WikiStyleAttr, $WikiStyleCSS, $WikiStyleApply, $BlockPattern,
+ $WikiStyleTag, $imgTag, $aTag, $spanTag, $WikiStyleAttrPrefix;
+ $wt = @$WikiStyleTag; $ns = $WikiStyleAttrPrefix; $ws = '';
+ $x = preg_replace("/\\b(href|src)=(['\"]?)[^$UrlExcludeChars]+\\2/e",
+ "Keep(PSS('$0'))", $x);
+ $x = preg_replace("/\\bhttps?:[^$UrlExcludeChars]+/e", "Keep('$0')", $x);
+ $parts = preg_split("/($WikiStylePattern)/",$x,-1,PREG_SPLIT_DELIM_CAPTURE);
+ $parts[] = NULL;
+ $out = '';
+ $style = array();
+ $wikicsspat = '/^('.implode('|',(array)$WikiStyleCSS).')$/';
+ while ($parts) {
+ $p = array_shift($parts);
+ if (preg_match("/^$WikiStylePattern\$/",$p)) {
+ $WikiStyle['curr']=$style; $style=array();
+ foreach((array)$WikiStyleRepl as $pat=>$rep)
+ $p=preg_replace($pat,$rep,$p);
+ preg_match_all(
+ '/\\b([a-zA-Z][-\\w]*)([:=]([-#,\\w.()%]+|([\'"]).*?\\4))?/',
+ $p, $match, PREG_SET_ORDER);
+ while ($match) {
+ $m = array_shift($match);
+ if (@$m[2]) $style[$m[1]]=preg_replace('/^([\'"])(.*)\\1$/','$2',$m[3]);
+ else if (!isset($WikiStyle[$m[1]])) @$style['class'] .= ' ' . $m[1];
+ else {
+ $c = @$style['class'];
+ $style=array_merge($style,(array)$WikiStyle[$m[1]]);
+ if ($c && !preg_match("/(^| )$c( |$)/", $style['class']) )
+ $style['class'] = $c . ' ' . $style['class'];
+ }
+ }
+ if (@$style['define']) {
+ $d = $style['define']; unset($style['define']);
+ $WikiStyle[$d] = $style;
+ }
+ if (@$WikiStyleApply[$style['apply']]) {
+ $apply[$style['apply']] =
+ array_merge((array)@$apply[$style['apply']],$style);
+ $style=array();
+ }
+ continue;
+ }
+ if (is_null($p))
+ { $alist=@$apply; unset($alist['']); $p=$out; $out=''; }
+ elseif ($p=='') continue;
+ else { $alist=array(''=>$style); }
+ foreach((array)$alist as $a=>$s) {
+ $spanattr = ''; $stylev = array(); $id = '';
+ foreach((array)$s as $k=>$v) {
+ $v = trim($v);
+ if ($wt) $ws = str_replace('$1', "$ns$k='$v'", $wt);
+ if ($k == 'class' && $v) $spanattr = "{$ns}class='$v'";
+ elseif ($k=='id') $id = preg_replace('/[^-A-Za-z0-9:_.]+/', '_', $v);
+ elseif (($k=='width' || $k=='height') && !@$WikiStyleApply[$a]
+ && preg_match("/\\s*<$imgTag\\b/", $p))
+ $p = preg_replace("/<($imgTag)\\b(?![^>]*\\s$k=)/",
+ "$ws<$1 $ns$k='$v'", $p);
+ elseif (@$WikiStyleAttr[$k])
+ $p = preg_replace(
+ "/<({$WikiStyleAttr[$k]}(?![^>]*\\s(?:$ns)?$k=))([^>]*)>/s",
+ "$ws<$1 $ns$k='$v' $2>", $p);
+ elseif (preg_match($wikicsspat,$k)) $stylev[]="$k: $v;";
+ }
+ if ($stylev) $spanattr .= " {$ns}style='".implode(' ',$stylev)."'";
+ if ($id) $spanattr .= " {$ns}id='$id'";
+ if ($spanattr) {
+ if ($wt) $ws = str_replace('$1', $spanattr, $wt);
+ if (!@$WikiStyleApply[$a]) {
+ $p = preg_replace("!^(.*?)($|?($BlockPattern))!s",
+ "$ws<$spanTag $spanattr>$1$spanTag>$2", $p, 1);
+}
+ elseif (!preg_match('/^(\\s*<[^>]+>)*$/s',$p) ||
+ preg_match("/<$imgTag\\b/", $p)) {
+ $p = preg_replace("/<({$WikiStyleApply[$a]})\\b/",
+ "$ws<$1 $spanattr", $p);
+ }
+ }
+ if (@$s['color']) {
+ $colorattr = "{$ns}style='color: {$s['color']}'";
+ if ($wt) $ws = str_replace('$1', $colorattr, $wt);
+ $p = preg_replace("/<$aTag\\b/", "$ws<$aTag $colorattr", $p);
+ }
+ }
+ $out .= $p;
+ }
+ return $out;
+}
+
diff --git a/scripts/wikiwords.php b/scripts/wikiwords.php
new file mode 100644
index 0000000..cac4e1b
--- /dev/null
+++ b/scripts/wikiwords.php
@@ -0,0 +1,69 @@
+urllink',
+ "/\\b(?'.WikiLink(\$pagename,'$0').'',
+ 'L')");
+
+function WikiLink($pagename, $word) {
+ global $LinkWikiWords, $WikiWordCount, $SpaceWikiWords, $AsSpacedFunction,
+ $MarkupFrame, $WikiWordCountMax;
+ if (!$LinkWikiWords || ($WikiWordCount[$word] < 0)) return $word;
+ $text = ($SpaceWikiWords) ? $AsSpacedFunction($word) : $word;
+ $text = preg_replace('!.*/!', '', $text);
+ if (!isset($MarkupFrame[0]['wwcount'][$word]))
+ $MarkupFrame[0]['wwcount'][$word] = $WikiWordCountMax;
+ if ($MarkupFrame[0]['wwcount'][$word]-- < 1) return $text;
+ return MakeLink($pagename, $word, $text);
+}
+
+
diff --git a/scripts/xlpage-iso-8859-13.php b/scripts/xlpage-iso-8859-13.php
new file mode 100644
index 0000000..30c64a1
--- /dev/null
+++ b/scripts/xlpage-iso-8859-13.php
@@ -0,0 +1,12 @@
+' ', 'Ä„'=>'¡', '˘'=>'¢', 'Å'=>'£',
+ '¤'=>'¤', 'Ľ'=>'¥', 'Åš'=>'¦', '§'=>'§',
+ '¨'=>'¨', 'Å '=>'©', 'Åž'=>'ª', 'Ť'=>'«',
+ 'Ź'=>'¬', 'Â'=>'', 'Ž'=>'®', 'Å»'=>'¯',
+ '°'=>'°', 'Ä…'=>'±', 'Ë›'=>'²', 'Å‚'=>'³',
+ '´'=>'´', 'ľ'=>'µ', 'Å›'=>'¶', 'ˇ'=>'·',
+ '¸'=>'¸', 'Å¡'=>'¹', 'ÅŸ'=>'º', 'Å¥'=>'»',
+ 'ź'=>'¼', 'Ë'=>'½', 'ž'=>'¾', 'ż'=>'¿',
+ 'Å”'=>'À', 'Ã'=>'Á', 'Â'=>'Â', 'Ä‚'=>'Ã',
+ 'Ä'=>'Ä', 'Ĺ'=>'Å', 'Ć'=>'Æ', 'Ç'=>'Ç',
+ 'ÄŒ'=>'È', 'É'=>'É', 'Ę'=>'Ê', 'Ë'=>'Ë',
+ 'Äš'=>'Ì', 'Ã'=>'Í', 'ÃŽ'=>'Î', 'ÄŽ'=>'Ï',
+ 'Ä'=>'Ð', 'Ń'=>'Ñ', 'Ň'=>'Ò', 'Ó'=>'Ó',
+ 'Ô'=>'Ô', 'Å'=>'Õ', 'Ö'=>'Ö', '×'=>'×',
+ 'Ř'=>'Ø', 'Å®'=>'Ù', 'Ú'=>'Ú', 'Ű'=>'Û',
+ 'Ü'=>'Ü', 'Ã'=>'Ý', 'Å¢'=>'Þ', 'ß'=>'ß',
+ 'Å•'=>'à', 'á'=>'á', 'â'=>'â', 'ă'=>'ã',
+ 'ä'=>'ä', 'ĺ'=>'å', 'ć'=>'æ', 'ç'=>'ç',
+ 'Ä'=>'è', 'é'=>'é', 'Ä™'=>'ê', 'ë'=>'ë',
+ 'Ä›'=>'ì', 'Ã'=>'í', 'î'=>'î', 'Ä'=>'ï',
+ 'Ä‘'=>'ð', 'Å„'=>'ñ', 'ň'=>'ò', 'ó'=>'ó',
+ 'ô'=>'ô', 'Å‘'=>'õ', 'ö'=>'ö', '÷'=>'÷',
+ 'Å™'=>'ø', 'ů'=>'ù', 'ú'=>'ú', 'ű'=>'û',
+ 'ü'=>'ü', 'ý'=>'ý', 'Å£'=>'þ', 'Ë™'=>'ÿ',
+ );
+ $pagename = str_replace(array_keys($conv),array_values($conv),$pagename);
+ }
+
diff --git a/scripts/xlpage-iso-8859-9.php b/scripts/xlpage-iso-8859-9.php
new file mode 100644
index 0000000..a97354a
--- /dev/null
+++ b/scripts/xlpage-iso-8859-9.php
@@ -0,0 +1,12 @@
+";
+$pagename = @$_REQUEST['n'];
+if (!$pagename) $pagename = @$_REQUEST['pagename'];
+if (!$pagename &&
+ preg_match('!^'.preg_quote($_SERVER['SCRIPT_NAME'],'!').'/?([^?]*)!',
+ $_SERVER['REQUEST_URI'],$match))
+ $pagename = urldecode($match[1]);
+$pagename = preg_replace('!/+$!','',$pagename);
+$FmtPV['$RequestedPage'] = "'".htmlspecialchars($pagename, ENT_QUOTES)."'";
+
+$GroupPattern = '[\\w\\x80-\\xfe]+(?:-[\\w\\x80-\\xfe]+)*';
+$NamePattern = '[\\w\\x80-\\xfe]+(?:-[\\w\\x80-\\xfe]+)*';
+$WikiWordPattern =
+ '[A-Z][A-Za-z0-9]*(?:[A-Z][a-z0-9]|[a-z0-9][A-Z])[A-Za-z0-9]*';
+$SuffixPattern = '(?:-?[A-Za-z0-9\\x80-\\xd6]+)*';
+
+SDV($PageNameChars, '-[:alnum:]\\x80-\\xfe');
+SDV($MakePageNamePatterns, array(
+ '/[?#].*$/' => '', # strip everything after ? or #
+ "/'/" => '', # strip single-quotes
+ "/[^$PageNameChars]+/" => ' ', # convert everything else to space
+ '/(?<=^| )([a-z])/e' => "strtoupper('$1')",
+ '/(?<=^| )([\\xc0-\\xdf].)/e' => "utf8toupper('$1')",
+ '/ /' => ''));
+SDV($StrFoldFunction, 'utf8fold');
+
+$AsSpacedFunction = 'AsSpacedUTF8';
+
+function utf8toupper($x) {
+ global $CaseConversions;
+ if (strlen($x) <= 2 && @$CaseConversions[$x])
+ return $CaseConversions[$x];
+ static $lower, $upper;
+ if (!@$lower) {
+ $lower = array_keys($CaseConversions);
+ $upper = array_values($CaseConversions);
+ }
+ return str_replace($lower, $upper, $x);
+}
+
+
+function utf8fold($x) {
+ global $StringFolding;
+ static $source, $target;
+ if (!@$source) {
+ $source = array_keys($StringFolding);
+ $target = array_values($StringFolding);
+ }
+ return str_replace($source, $target, $x);
+}
+
+
+function AsSpacedUTF8($text) {
+ global $CaseConversions;
+ static $lower, $upper;
+ if (!@$CaseConversions) return AsSpaced($text);
+ if (!@$lower) {
+ $lower = implode('|', array_keys($CaseConversions));
+ $upper = implode('|', array_values($CaseConversions));
+ }
+ $text = preg_replace("/($lower|\\d)($upper)/", '$1 $2', $text);
+ $text = preg_replace('/([^-\\d])(\\d[-\\d]*( |$))/', '$1 $2', $text);
+ return preg_replace("/($upper)(($upper)($lower|\\d))/", '$1 $2', $text);
+}
+
+
+## Conversion tables.
+## $CaseConversion maps lowercase utf8 sequences to
+## their uppercase equivalents. The table was derived from [1].
+## $StringFolding normalizes strings so that "equivalent"
+## forms will match using a binary comparison (derived from [2]).
+## [1] http://unicode.org/Public/UNIDATA/UnicodeData.txt
+## [2] http://unicode.org/Public/UNIDATA/CaseFolding.txt
+
+SDV($CaseConversions, array(
+ ## U+0060
+ "a" => "A", "b" => "B", "c" => "C", "d" => "D", "e" => "E", "f" => "F",
+ "g" => "G", "h" => "H", "i" => "I", "j" => "J", "k" => "K", "l" => "L",
+ "m" => "M", "n" => "N", "o" => "O", "p" => "P", "q" => "Q", "r" => "R",
+ "s" => "S", "t" => "T", "u" => "U", "v" => "V", "w" => "W", "x" => "X",
+ "y" => "Y", "z" => "Z",
+ ## U+00b5
+ "\xc2\xb5" => "\xce\x9c",
+ ## U+00E0 to U+00FF
+ "\xc3\xa0" => "\xc3\x80", "\xc3\xa1" => "\xc3\x81",
+ "\xc3\xa2" => "\xc3\x82", "\xc3\xa3" => "\xc3\x83",
+ "\xc3\xa4" => "\xc3\x84", "\xc3\xa5" => "\xc3\x85",
+ "\xc3\xa6" => "\xc3\x86", "\xc3\xa7" => "\xc3\x87",
+ "\xc3\xa8" => "\xc3\x88", "\xc3\xa9" => "\xc3\x89",
+ "\xc3\xaa" => "\xc3\x8a", "\xc3\xab" => "\xc3\x8b",
+ "\xc3\xac" => "\xc3\x8c", "\xc3\xad" => "\xc3\x8d",
+ "\xc3\xae" => "\xc3\x8e", "\xc3\xaf" => "\xc3\x8f",
+ "\xc3\xb0" => "\xc3\x90", "\xc3\xb1" => "\xc3\x91",
+ "\xc3\xb2" => "\xc3\x92", "\xc3\xb3" => "\xc3\x93",
+ "\xc3\xb4" => "\xc3\x94", "\xc3\xb5" => "\xc3\x95",
+ "\xc3\xb6" => "\xc3\x96", "\xc3\xb8" => "\xc3\x98",
+ "\xc3\xb9" => "\xc3\x99", "\xc3\xba" => "\xc3\x9a",
+ "\xc3\xbb" => "\xc3\x9b", "\xc3\xbc" => "\xc3\x9c",
+ "\xc3\xbd" => "\xc3\x9d", "\xc3\xbe" => "\xc3\x9e",
+ "\xc3\xbf" => "\xc5\xb8",
+ ## U+0100
+ "\xc4\x81" => "\xc4\x80", "\xc4\x83" => "\xc4\x82",
+ "\xc4\x85" => "\xc4\x84", "\xc4\x87" => "\xc4\x86",
+ "\xc4\x89" => "\xc4\x88", "\xc4\x8b" => "\xc4\x8a",
+ "\xc4\x8d" => "\xc4\x8c", "\xc4\x8f" => "\xc4\x8e",
+ "\xc4\x91" => "\xc4\x90", "\xc4\x93" => "\xc4\x92",
+ "\xc4\x95" => "\xc4\x94", "\xc4\x97" => "\xc4\x96",
+ "\xc4\x99" => "\xc4\x98", "\xc4\x9b" => "\xc4\x9a",
+ "\xc4\x9d" => "\xc4\x9c", "\xc4\x9f" => "\xc4\x9e",
+ "\xc4\xa1" => "\xc4\xa0", "\xc4\xa3" => "\xc4\xa2",
+ "\xc4\xa5" => "\xc4\xa4", "\xc4\xa7" => "\xc4\xa6",
+ "\xc4\xa9" => "\xc4\xa8", "\xc4\xab" => "\xc4\xaa",
+ "\xc4\xad" => "\xc4\xac", "\xc4\xaf" => "\xc4\xae",
+ "\xc4\xb1" => "I", "\xc4\xb3" => "\xc4\xb2",
+ "\xc4\xb5" => "\xc4\xb4", "\xc4\xb7" => "\xc4\xb6",
+ "\xc4\xba" => "\xc4\xb9", "\xc4\xbc" => "\xc4\xbb",
+ "\xc4\xbe" => "\xc4\xbd",
+ ## U+0140
+ "\xc5\x80" => "\xc4\xbf", "\xc5\x82" => "\xc5\x81",
+ "\xc5\x84" => "\xc5\x83", "\xc5\x86" => "\xc5\x85",
+ "\xc5\x88" => "\xc5\x87", "\xc5\x8b" => "\xc5\x8a",
+ "\xc5\x8d" => "\xc5\x8c", "\xc5\x8f" => "\xc5\x8e",
+ "\xc5\x91" => "\xc5\x90", "\xc5\x93" => "\xc5\x92",
+ "\xc5\x95" => "\xc5\x94", "\xc5\x97" => "\xc5\x96",
+ "\xc5\x99" => "\xc5\x98", "\xc5\x9b" => "\xc5\x9a",
+ "\xc5\x9d" => "\xc5\x9c", "\xc5\x9f" => "\xc5\x9e",
+ "\xc5\xa1" => "\xc5\xa0", "\xc5\xa3" => "\xc5\xa2",
+ "\xc5\xa5" => "\xc5\xa4", "\xc5\xa7" => "\xc5\xa6",
+ "\xc5\xa9" => "\xc5\xa8", "\xc5\xab" => "\xc5\xaa",
+ "\xc5\xad" => "\xc5\xac", "\xc5\xaf" => "\xc5\xae",
+ "\xc5\xb1" => "\xc5\xb0", "\xc5\xb3" => "\xc5\xb2",
+ "\xc5\xb5" => "\xc5\xb4", "\xc5\xb7" => "\xc5\xb6",
+ "\xc5\xba" => "\xc5\xb9", "\xc5\xbc" => "\xc5\xbb",
+ "\xc5\xbe" => "\xc5\xbd", "\xc5\xbf" => "S",
+ ## U+0180
+ "\xc6\x80" => "\xc9\x83", "\xc6\x83" => "\xc6\x82",
+ "\xc6\x85" => "\xc6\x84", "\xc6\x88" => "\xc6\x87",
+ "\xc6\x8c" => "\xc6\x8b", "\xc6\x92" => "\xc6\x91",
+ "\xc6\x95" => "\xc7\xb6", "\xc6\x99" => "\xc6\x98",
+ "\xc6\x9a" => "\xc8\xbd", "\xc6\x9e" => "\xc8\xa0",
+ "\xc6\xa1" => "\xc6\xa0", "\xc6\xa3" => "\xc6\xa2",
+ "\xc6\xa5" => "\xc6\xa4", "\xc6\xa8" => "\xc6\xa7",
+ "\xc6\xad" => "\xc6\xac", "\xc6\xb0" => "\xc6\xaf",
+ "\xc6\xb4" => "\xc6\xb3", "\xc6\xb6" => "\xc6\xb5",
+ "\xc6\xb9" => "\xc6\xb8", "\xc6\xbd" => "\xc6\xbc",
+ "\xc6\xbf" => "\xc7\xb7",
+ ## U+01c0
+ "\xc7\x85" => "\xc7\x84", "\xc7\x86" => "\xc7\x84",
+ "\xc7\x88" => "\xc7\x87", "\xc7\x89" => "\xc7\x87",
+ "\xc7\x8b" => "\xc7\x8a", "\xc7\x8c" => "\xc7\x8a",
+ "\xc7\x8e" => "\xc7\x8d", "\xc7\x90" => "\xc7\x8f",
+ "\xc7\x92" => "\xc7\x91", "\xc7\x94" => "\xc7\x93",
+ "\xc7\x96" => "\xc7\x95", "\xc7\x98" => "\xc7\x97",
+ "\xc7\x9a" => "\xc7\x99", "\xc7\x9c" => "\xc7\x9b",
+ "\xc7\x9d" => "\xc6\x8e", "\xc7\x9f" => "\xc7\x9e",
+ "\xc7\xa1" => "\xc7\xa0", "\xc7\xa3" => "\xc7\xa2",
+ "\xc7\xa5" => "\xc7\xa4", "\xc7\xa7" => "\xc7\xa6",
+ "\xc7\xa9" => "\xc7\xa8", "\xc7\xab" => "\xc7\xaa",
+ "\xc7\xad" => "\xc7\xac", "\xc7\xaf" => "\xc7\xae",
+ "\xc7\xb2" => "\xc7\xb1", "\xc7\xb3" => "\xc7\xb1",
+ "\xc7\xb5" => "\xc7\xb4", "\xc7\xb9" => "\xc7\xb8",
+ "\xc7\xbb" => "\xc7\xba", "\xc7\xbd" => "\xc7\xbc",
+ "\xc7\xbf" => "\xc7\xbe",
+ ## U+0200
+ "\xc8\x81" => "\xc8\x80", "\xc8\x83" => "\xc8\x82",
+ "\xc8\x85" => "\xc8\x84", "\xc8\x87" => "\xc8\x86",
+ "\xc8\x89" => "\xc8\x88", "\xc8\x8b" => "\xc8\x8a",
+ "\xc8\x8d" => "\xc8\x8c", "\xc8\x8f" => "\xc8\x8e",
+ "\xc8\x91" => "\xc8\x90", "\xc8\x93" => "\xc8\x92",
+ "\xc8\x95" => "\xc8\x94", "\xc8\x97" => "\xc8\x96",
+ "\xc8\x99" => "\xc8\x98", "\xc8\x9b" => "\xc8\x9a",
+ "\xc8\x9d" => "\xc8\x9c", "\xc8\x9f" => "\xc8\x9e",
+ "\xc8\xa3" => "\xc8\xa2", "\xc8\xa5" => "\xc8\xa4",
+ "\xc8\xa7" => "\xc8\xa6", "\xc8\xa9" => "\xc8\xa8",
+ "\xc8\xab" => "\xc8\xaa", "\xc8\xad" => "\xc8\xac",
+ "\xc8\xaf" => "\xc8\xae", "\xc8\xb1" => "\xc8\xb0",
+ "\xc8\xb3" => "\xc8\xb2", "\xc8\xbc" => "\xc8\xbb",
+ ## U+0240
+ "\xc9\x82" => "\xc9\x81", "\xc9\x87" => "\xc9\x86",
+ "\xc9\x89" => "\xc9\x88", "\xc9\x8b" => "\xc9\x8a",
+ "\xc9\x8d" => "\xc9\x8c", "\xc9\x8f" => "\xc9\x8e",
+ "\xc9\x93" => "\xc6\x81", "\xc9\x94" => "\xc6\x86",
+ "\xc9\x96" => "\xc6\x89", "\xc9\x97" => "\xc6\x8a",
+ "\xc9\x99" => "\xc6\x8f", "\xc9\x9b" => "\xc6\x90",
+ "\xc9\xa0" => "\xc6\x93", "\xc9\xa3" => "\xc6\x94",
+ "\xc9\xa8" => "\xc6\x97", "\xc9\xa9" => "\xc6\x96",
+ "\xc9\xab" => "\xe2\xb1\xa2", "\xc9\xaf" => "\xc6\x9c",
+ "\xc9\xb2" => "\xc6\x9d", "\xc9\xb5" => "\xc6\x9f",
+ "\xc9\xbd" => "\xe2\xb1\xa4",
+ ## U+0280
+ "\xca\x80" => "\xc6\xa6", "\xca\x83" => "\xc6\xa9",
+ "\xca\x88" => "\xc6\xae", "\xca\x89" => "\xc9\x84",
+ "\xca\x8a" => "\xc6\xb1", "\xca\x8b" => "\xc6\xb2",
+ "\xca\x8c" => "\xc9\x85", "\xca\x92" => "\xc6\xb7",
+ ## U+0340
+ "\xcd\x85" => "\xce\x99", "\xcd\xbb" => "\xcf\xbd",
+ "\xcd\xbc" => "\xcf\xbe", "\xcd\xbd" => "\xcf\xbf",
+ ## U+0380
+ "\xce\xac" => "\xce\x86", "\xce\xad" => "\xce\x88",
+ "\xce\xae" => "\xce\x89", "\xce\xaf" => "\xce\x8a",
+ "\xce\xb1" => "\xce\x91", "\xce\xb2" => "\xce\x92",
+ "\xce\xb3" => "\xce\x93", "\xce\xb4" => "\xce\x94",
+ "\xce\xb5" => "\xce\x95", "\xce\xb6" => "\xce\x96",
+ "\xce\xb7" => "\xce\x97", "\xce\xb8" => "\xce\x98",
+ "\xce\xb9" => "\xce\x99", "\xce\xba" => "\xce\x9a",
+ "\xce\xbb" => "\xce\x9b", "\xce\xbc" => "\xce\x9c",
+ "\xce\xbd" => "\xce\x9d", "\xce\xbe" => "\xce\x9e",
+ "\xce\xbf" => "\xce\x9f",
+ ## U+03c0
+ "\xcf\x80" => "\xce\xa0", "\xcf\x81" => "\xce\xa1",
+ "\xcf\x82" => "\xce\xa3", "\xcf\x83" => "\xce\xa3",
+ "\xcf\x84" => "\xce\xa4", "\xcf\x85" => "\xce\xa5",
+ "\xcf\x86" => "\xce\xa6", "\xcf\x87" => "\xce\xa7",
+ "\xcf\x88" => "\xce\xa8", "\xcf\x89" => "\xce\xa9",
+ "\xcf\x8a" => "\xce\xaa", "\xcf\x8b" => "\xce\xab",
+ "\xcf\x8c" => "\xce\x8c", "\xcf\x8d" => "\xce\x8e",
+ "\xcf\x8e" => "\xce\x8f", "\xcf\x90" => "\xce\x92",
+ "\xcf\x91" => "\xce\x98", "\xcf\x95" => "\xce\xa6",
+ "\xcf\x96" => "\xce\xa0", "\xcf\x99" => "\xcf\x98",
+ "\xcf\x9b" => "\xcf\x9a", "\xcf\x9d" => "\xcf\x9c",
+ "\xcf\x9f" => "\xcf\x9e", "\xcf\xa1" => "\xcf\xa0",
+ "\xcf\xa3" => "\xcf\xa2", "\xcf\xa5" => "\xcf\xa4",
+ "\xcf\xa7" => "\xcf\xa6", "\xcf\xa9" => "\xcf\xa8",
+ "\xcf\xab" => "\xcf\xaa", "\xcf\xad" => "\xcf\xac",
+ "\xcf\xaf" => "\xcf\xae", "\xcf\xb0" => "\xce\x9a",
+ "\xcf\xb1" => "\xce\xa1", "\xcf\xb2" => "\xcf\xb9",
+ "\xcf\xb5" => "\xce\x95", "\xcf\xb8" => "\xcf\xb7",
+ "\xcf\xbb" => "\xcf\xba",
+ ## U+0400
+ "\xd0\xb0" => "\xd0\x90", "\xd0\xb1" => "\xd0\x91",
+ "\xd0\xb2" => "\xd0\x92", "\xd0\xb3" => "\xd0\x93",
+ "\xd0\xb4" => "\xd0\x94", "\xd0\xb5" => "\xd0\x95",
+ "\xd0\xb6" => "\xd0\x96", "\xd0\xb7" => "\xd0\x97",
+ "\xd0\xb8" => "\xd0\x98", "\xd0\xb9" => "\xd0\x99",
+ "\xd0\xba" => "\xd0\x9a", "\xd0\xbb" => "\xd0\x9b",
+ "\xd0\xbc" => "\xd0\x9c", "\xd0\xbd" => "\xd0\x9d",
+ "\xd0\xbe" => "\xd0\x9e", "\xd0\xbf" => "\xd0\x9f",
+ ## U+0440
+ "\xd1\x80" => "\xd0\xa0", "\xd1\x81" => "\xd0\xa1",
+ "\xd1\x82" => "\xd0\xa2", "\xd1\x83" => "\xd0\xa3",
+ "\xd1\x84" => "\xd0\xa4", "\xd1\x85" => "\xd0\xa5",
+ "\xd1\x86" => "\xd0\xa6", "\xd1\x87" => "\xd0\xa7",
+ "\xd1\x88" => "\xd0\xa8", "\xd1\x89" => "\xd0\xa9",
+ "\xd1\x8a" => "\xd0\xaa", "\xd1\x8b" => "\xd0\xab",
+ "\xd1\x8c" => "\xd0\xac", "\xd1\x8d" => "\xd0\xad",
+ "\xd1\x8e" => "\xd0\xae", "\xd1\x8f" => "\xd0\xaf",
+ "\xd1\x90" => "\xd0\x80", "\xd1\x91" => "\xd0\x81",
+ "\xd1\x92" => "\xd0\x82", "\xd1\x93" => "\xd0\x83",
+ "\xd1\x94" => "\xd0\x84", "\xd1\x95" => "\xd0\x85",
+ "\xd1\x96" => "\xd0\x86", "\xd1\x97" => "\xd0\x87",
+ "\xd1\x98" => "\xd0\x88", "\xd1\x99" => "\xd0\x89",
+ "\xd1\x9a" => "\xd0\x8a", "\xd1\x9b" => "\xd0\x8b",
+ "\xd1\x9c" => "\xd0\x8c", "\xd1\x9d" => "\xd0\x8d",
+ "\xd1\x9e" => "\xd0\x8e", "\xd1\x9f" => "\xd0\x8f",
+ "\xd1\xa1" => "\xd1\xa0", "\xd1\xa3" => "\xd1\xa2",
+ "\xd1\xa5" => "\xd1\xa4", "\xd1\xa7" => "\xd1\xa6",
+ "\xd1\xa9" => "\xd1\xa8", "\xd1\xab" => "\xd1\xaa",
+ "\xd1\xad" => "\xd1\xac", "\xd1\xaf" => "\xd1\xae",
+ "\xd1\xb1" => "\xd1\xb0", "\xd1\xb3" => "\xd1\xb2",
+ "\xd1\xb5" => "\xd1\xb4", "\xd1\xb7" => "\xd1\xb6",
+ "\xd1\xb9" => "\xd1\xb8", "\xd1\xbb" => "\xd1\xba",
+ "\xd1\xbd" => "\xd1\xbc", "\xd1\xbf" => "\xd1\xbe",
+ ## U+0480
+ "\xd2\x81" => "\xd2\x80", "\xd2\x8b" => "\xd2\x8a",
+ "\xd2\x8d" => "\xd2\x8c", "\xd2\x8f" => "\xd2\x8e",
+ "\xd2\x91" => "\xd2\x90", "\xd2\x93" => "\xd2\x92",
+ "\xd2\x95" => "\xd2\x94", "\xd2\x97" => "\xd2\x96",
+ "\xd2\x99" => "\xd2\x98", "\xd2\x9b" => "\xd2\x9a",
+ "\xd2\x9d" => "\xd2\x9c", "\xd2\x9f" => "\xd2\x9e",
+ "\xd2\xa1" => "\xd2\xa0", "\xd2\xa3" => "\xd2\xa2",
+ "\xd2\xa5" => "\xd2\xa4", "\xd2\xa7" => "\xd2\xa6",
+ "\xd2\xa9" => "\xd2\xa8", "\xd2\xab" => "\xd2\xaa",
+ "\xd2\xad" => "\xd2\xac", "\xd2\xaf" => "\xd2\xae",
+ "\xd2\xb1" => "\xd2\xb0", "\xd2\xb3" => "\xd2\xb2",
+ "\xd2\xb5" => "\xd2\xb4", "\xd2\xb7" => "\xd2\xb6",
+ "\xd2\xb9" => "\xd2\xb8", "\xd2\xbb" => "\xd2\xba",
+ "\xd2\xbd" => "\xd2\xbc", "\xd2\xbf" => "\xd2\xbe",
+ ## U+04c0
+ "\xd3\x82" => "\xd3\x81", "\xd3\x84" => "\xd3\x83",
+ "\xd3\x86" => "\xd3\x85", "\xd3\x88" => "\xd3\x87",
+ "\xd3\x8a" => "\xd3\x89", "\xd3\x8c" => "\xd3\x8b",
+ "\xd3\x8e" => "\xd3\x8d", "\xd3\x8f" => "\xd3\x80",
+ "\xd3\x91" => "\xd3\x90", "\xd3\x93" => "\xd3\x92",
+ "\xd3\x95" => "\xd3\x94", "\xd3\x97" => "\xd3\x96",
+ "\xd3\x99" => "\xd3\x98", "\xd3\x9b" => "\xd3\x9a",
+ "\xd3\x9d" => "\xd3\x9c", "\xd3\x9f" => "\xd3\x9e",
+ "\xd3\xa1" => "\xd3\xa0", "\xd3\xa3" => "\xd3\xa2",
+ "\xd3\xa5" => "\xd3\xa4", "\xd3\xa7" => "\xd3\xa6",
+ "\xd3\xa9" => "\xd3\xa8", "\xd3\xab" => "\xd3\xaa",
+ "\xd3\xad" => "\xd3\xac", "\xd3\xaf" => "\xd3\xae",
+ "\xd3\xb1" => "\xd3\xb0", "\xd3\xb3" => "\xd3\xb2",
+ "\xd3\xb5" => "\xd3\xb4", "\xd3\xb7" => "\xd3\xb6",
+ "\xd3\xb9" => "\xd3\xb8", "\xd3\xbb" => "\xd3\xba",
+ "\xd3\xbd" => "\xd3\xbc", "\xd3\xbf" => "\xd3\xbe",
+ ## U+0500
+ "\xd4\x81" => "\xd4\x80", "\xd4\x83" => "\xd4\x82",
+ "\xd4\x85" => "\xd4\x84", "\xd4\x87" => "\xd4\x86",
+ "\xd4\x89" => "\xd4\x88", "\xd4\x8b" => "\xd4\x8a",
+ "\xd4\x8d" => "\xd4\x8c", "\xd4\x8f" => "\xd4\x8e",
+ "\xd4\x91" => "\xd4\x90", "\xd4\x93" => "\xd4\x92",
+ ## U+0560
+ "\xd5\xa1" => "\xd4\xb1", "\xd5\xa2" => "\xd4\xb2",
+ "\xd5\xa3" => "\xd4\xb3", "\xd5\xa4" => "\xd4\xb4",
+ "\xd5\xa5" => "\xd4\xb5", "\xd5\xa6" => "\xd4\xb6",
+ "\xd5\xa7" => "\xd4\xb7", "\xd5\xa8" => "\xd4\xb8",
+ "\xd5\xa9" => "\xd4\xb9", "\xd5\xaa" => "\xd4\xba",
+ "\xd5\xab" => "\xd4\xbb", "\xd5\xac" => "\xd4\xbc",
+ "\xd5\xad" => "\xd4\xbd", "\xd5\xae" => "\xd4\xbe",
+ "\xd5\xaf" => "\xd4\xbf", "\xd5\xb0" => "\xd5\x80",
+ "\xd5\xb1" => "\xd5\x81", "\xd5\xb2" => "\xd5\x82",
+ "\xd5\xb3" => "\xd5\x83", "\xd5\xb4" => "\xd5\x84",
+ "\xd5\xb5" => "\xd5\x85", "\xd5\xb6" => "\xd5\x86",
+ "\xd5\xb7" => "\xd5\x87", "\xd5\xb8" => "\xd5\x88",
+ "\xd5\xb9" => "\xd5\x89", "\xd5\xba" => "\xd5\x8a",
+ "\xd5\xbb" => "\xd5\x8b", "\xd5\xbc" => "\xd5\x8c",
+ "\xd5\xbd" => "\xd5\x8d", "\xd5\xbe" => "\xd5\x8e",
+ "\xd5\xbf" => "\xd5\x8f",
+ ## U+0580
+ "\xd6\x80" => "\xd5\x90", "\xd6\x81" => "\xd5\x91",
+ "\xd6\x82" => "\xd5\x92", "\xd6\x83" => "\xd5\x93",
+ "\xd6\x84" => "\xd5\x94", "\xd6\x85" => "\xd5\x95",
+ "\xd6\x86" => "\xd5\x96"
+ ));
+
+SDV($StringFolding, array(
+ ## U+0040
+ "A" => "a", "B" => "b", "C" => "c", "D" => "d", "E" => "e", "F" => "f",
+ "G" => "g", "H" => "h", "I" => "i", "J" => "j", "K" => "k", "L" => "l",
+ "M" => "m", "N" => "n", "O" => "o", "P" => "p", "Q" => "q", "R" => "r",
+ "S" => "s", "T" => "t", "U" => "u", "V" => "v", "W" => "w", "X" => "x",
+ "Y" => "y", "Z" => "z",
+ ## U+00B5
+ "\xc2\xb5" => "\xce\xbc",
+ ## U+00C0
+ "\xc3\x80" => "\xc3\xa0", "\xc3\x81" => "\xc3\xa1",
+ "\xc3\x82" => "\xc3\xa2", "\xc3\x83" => "\xc3\xa3",
+ "\xc3\x84" => "\xc3\xa4", "\xc3\x85" => "\xc3\xa5",
+ "\xc3\x86" => "\xc3\xa6", "\xc3\x87" => "\xc3\xa7",
+ "\xc3\x88" => "\xc3\xa8", "\xc3\x89" => "\xc3\xa9",
+ "\xc3\x8a" => "\xc3\xaa", "\xc3\x8b" => "\xc3\xab",
+ "\xc3\x8c" => "\xc3\xac", "\xc3\x8d" => "\xc3\xad",
+ "\xc3\x8e" => "\xc3\xae", "\xc3\x8f" => "\xc3\xaf",
+ "\xc3\x90" => "\xc3\xb0", "\xc3\x91" => "\xc3\xb1",
+ "\xc3\x92" => "\xc3\xb2", "\xc3\x93" => "\xc3\xb3",
+ "\xc3\x94" => "\xc3\xb4", "\xc3\x95" => "\xc3\xb5",
+ "\xc3\x96" => "\xc3\xb6", "\xc3\x98" => "\xc3\xb8",
+ "\xc3\x99" => "\xc3\xb9", "\xc3\x9a" => "\xc3\xba",
+ "\xc3\x9b" => "\xc3\xbb", "\xc3\x9c" => "\xc3\xbc",
+ "\xc3\x9d" => "\xc3\xbd", "\xc3\x9e" => "\xc3\xbe",
+ "\xc3\x9f" => "ss",
+ ## U+0100
+ "\xc4\x80" => "\xc4\x81", "\xc4\x82" => "\xc4\x83",
+ "\xc4\x84" => "\xc4\x85", "\xc4\x86" => "\xc4\x87",
+ "\xc4\x88" => "\xc4\x89", "\xc4\x8a" => "\xc4\x8b",
+ "\xc4\x8c" => "\xc4\x8d", "\xc4\x8e" => "\xc4\x8f",
+ "\xc4\x90" => "\xc4\x91", "\xc4\x92" => "\xc4\x93",
+ "\xc4\x94" => "\xc4\x95", "\xc4\x96" => "\xc4\x97",
+ "\xc4\x98" => "\xc4\x99", "\xc4\x9a" => "\xc4\x9b",
+ "\xc4\x9c" => "\xc4\x9d", "\xc4\x9e" => "\xc4\x9f",
+ "\xc4\xa0" => "\xc4\xa1", "\xc4\xa2" => "\xc4\xa3",
+ "\xc4\xa4" => "\xc4\xa5", "\xc4\xa6" => "\xc4\xa7",
+ "\xc4\xa8" => "\xc4\xa9", "\xc4\xaa" => "\xc4\xab",
+ "\xc4\xac" => "\xc4\xad", "\xc4\xae" => "\xc4\xaf",
+ "\xc4\xb0" => "i\xcc\x87", "\xc4\xb2" => "\xc4\xb3",
+ "\xc4\xb4" => "\xc4\xb5", "\xc4\xb6" => "\xc4\xb7",
+ "\xc4\xb9" => "\xc4\xba", "\xc4\xbb" => "\xc4\xbc",
+ "\xc4\xbd" => "\xc4\xbe", "\xc4\xbf" => "\xc5\x80",
+ ## U+0140
+ "\xc5\x81" => "\xc5\x82", "\xc5\x83" => "\xc5\x84",
+ "\xc5\x85" => "\xc5\x86", "\xc5\x87" => "\xc5\x88",
+ "\xc5\x89" => "\xca\xbcn", "\xc5\x8a" => "\xc5\x8b",
+ "\xc5\x8c" => "\xc5\x8d", "\xc5\x8e" => "\xc5\x8f",
+ "\xc5\x90" => "\xc5\x91", "\xc5\x92" => "\xc5\x93",
+ "\xc5\x94" => "\xc5\x95", "\xc5\x96" => "\xc5\x97",
+ "\xc5\x98" => "\xc5\x99", "\xc5\x9a" => "\xc5\x9b",
+ "\xc5\x9c" => "\xc5\x9d", "\xc5\x9e" => "\xc5\x9f",
+ "\xc5\xa0" => "\xc5\xa1", "\xc5\xa2" => "\xc5\xa3",
+ "\xc5\xa4" => "\xc5\xa5", "\xc5\xa6" => "\xc5\xa7",
+ "\xc5\xa8" => "\xc5\xa9", "\xc5\xaa" => "\xc5\xab",
+ "\xc5\xac" => "\xc5\xad", "\xc5\xae" => "\xc5\xaf",
+ "\xc5\xb0" => "\xc5\xb1", "\xc5\xb2" => "\xc5\xb3",
+ "\xc5\xb4" => "\xc5\xb5", "\xc5\xb6" => "\xc5\xb7",
+ "\xc5\xb8" => "\xc3\xbf", "\xc5\xb9" => "\xc5\xba",
+ "\xc5\xbb" => "\xc5\xbc", "\xc5\xbd" => "\xc5\xbe",
+ "\xc5\xbf" => "s",
+ ## U+0180
+ "\xc6\x81" => "\xc9\x93", "\xc6\x82" => "\xc6\x83",
+ "\xc6\x84" => "\xc6\x85", "\xc6\x86" => "\xc9\x94",
+ "\xc6\x87" => "\xc6\x88", "\xc6\x89" => "\xc9\x96",
+ "\xc6\x8a" => "\xc9\x97", "\xc6\x8b" => "\xc6\x8c",
+ "\xc6\x8e" => "\xc7\x9d", "\xc6\x8f" => "\xc9\x99",
+ "\xc6\x90" => "\xc9\x9b", "\xc6\x91" => "\xc6\x92",
+ "\xc6\x93" => "\xc9\xa0", "\xc6\x94" => "\xc9\xa3",
+ "\xc6\x96" => "\xc9\xa9", "\xc6\x97" => "\xc9\xa8",
+ "\xc6\x98" => "\xc6\x99", "\xc6\x9c" => "\xc9\xaf",
+ "\xc6\x9d" => "\xc9\xb2", "\xc6\x9f" => "\xc9\xb5",
+ "\xc6\xa0" => "\xc6\xa1", "\xc6\xa2" => "\xc6\xa3",
+ "\xc6\xa4" => "\xc6\xa5", "\xc6\xa6" => "\xca\x80",
+ "\xc6\xa7" => "\xc6\xa8", "\xc6\xa9" => "\xca\x83",
+ "\xc6\xac" => "\xc6\xad", "\xc6\xae" => "\xca\x88",
+ "\xc6\xaf" => "\xc6\xb0", "\xc6\xb1" => "\xca\x8a",
+ "\xc6\xb2" => "\xca\x8b", "\xc6\xb3" => "\xc6\xb4",
+ "\xc6\xb5" => "\xc6\xb6", "\xc6\xb7" => "\xca\x92",
+ "\xc6\xb8" => "\xc6\xb9", "\xc6\xbc" => "\xc6\xbd",
+ ## U+01c0
+ "\xc7\x84" => "\xc7\x86", "\xc7\x85" => "\xc7\x86",
+ "\xc7\x87" => "\xc7\x89", "\xc7\x88" => "\xc7\x89",
+ "\xc7\x8a" => "\xc7\x8c", "\xc7\x8b" => "\xc7\x8c",
+ "\xc7\x8d" => "\xc7\x8e", "\xc7\x8f" => "\xc7\x90",
+ "\xc7\x91" => "\xc7\x92", "\xc7\x93" => "\xc7\x94",
+ "\xc7\x95" => "\xc7\x96", "\xc7\x97" => "\xc7\x98",
+ "\xc7\x99" => "\xc7\x9a", "\xc7\x9b" => "\xc7\x9c",
+ "\xc7\x9e" => "\xc7\x9f", "\xc7\xa0" => "\xc7\xa1",
+ "\xc7\xa2" => "\xc7\xa3", "\xc7\xa4" => "\xc7\xa5",
+ "\xc7\xa6" => "\xc7\xa7", "\xc7\xa8" => "\xc7\xa9",
+ "\xc7\xaa" => "\xc7\xab", "\xc7\xac" => "\xc7\xad",
+ "\xc7\xae" => "\xc7\xaf", "\xc7\xb0" => "j\xcc\x8c",
+ "\xc7\xb1" => "\xc7\xb3", "\xc7\xb2" => "\xc7\xb3",
+ "\xc7\xb4" => "\xc7\xb5", "\xc7\xb6" => "\xc6\x95",
+ "\xc7\xb7" => "\xc6\xbf", "\xc7\xb8" => "\xc7\xb9",
+ "\xc7\xba" => "\xc7\xbb", "\xc7\xbc" => "\xc7\xbd",
+ "\xc7\xbe" => "\xc7\xbf",
+ ## U+0200
+ "\xc8\x80" => "\xc8\x81", "\xc8\x82" => "\xc8\x83",
+ "\xc8\x84" => "\xc8\x85", "\xc8\x86" => "\xc8\x87",
+ "\xc8\x88" => "\xc8\x89", "\xc8\x8a" => "\xc8\x8b",
+ "\xc8\x8c" => "\xc8\x8d", "\xc8\x8e" => "\xc8\x8f",
+ "\xc8\x90" => "\xc8\x91", "\xc8\x92" => "\xc8\x93",
+ "\xc8\x94" => "\xc8\x95", "\xc8\x96" => "\xc8\x97",
+ "\xc8\x98" => "\xc8\x99", "\xc8\x9a" => "\xc8\x9b",
+ "\xc8\x9c" => "\xc8\x9d", "\xc8\x9e" => "\xc8\x9f",
+ "\xc8\xa0" => "\xc6\x9e", "\xc8\xa2" => "\xc8\xa3",
+ "\xc8\xa4" => "\xc8\xa5", "\xc8\xa6" => "\xc8\xa7",
+ "\xc8\xa8" => "\xc8\xa9", "\xc8\xaa" => "\xc8\xab",
+ "\xc8\xac" => "\xc8\xad", "\xc8\xae" => "\xc8\xaf",
+ "\xc8\xb0" => "\xc8\xb1", "\xc8\xb2" => "\xc8\xb3",
+ "\xc8\xba" => "\xe2\xb1\xa5", "\xc8\xbb" => "\xc8\xbc",
+ "\xc8\xbd" => "\xc6\x9a", "\xc8\xbe" => "\xe2\xb1\xa6",
+ ## U+0240
+ "\xc9\x81" => "\xc9\x82", "\xc9\x83" => "\xc6\x80",
+ "\xc9\x84" => "\xca\x89", "\xc9\x85" => "\xca\x8c",
+ "\xc9\x86" => "\xc9\x87", "\xc9\x88" => "\xc9\x89",
+ "\xc9\x8a" => "\xc9\x8b", "\xc9\x8c" => "\xc9\x8d",
+ "\xc9\x8e" => "\xc9\x8f",
+ ## U+0345
+ "\xcd\x85" => "\xce\xb9",
+ ## U+0380
+ "\xce\x86" => "\xce\xac", "\xce\x88" => "\xce\xad",
+ "\xce\x89" => "\xce\xae", "\xce\x8a" => "\xce\xaf",
+ "\xce\x8c" => "\xcf\x8c", "\xce\x8e" => "\xcf\x8d",
+ "\xce\x8f" => "\xcf\x8e", "\xce\x90" => "\xce\xb9\xcc\x88\xcc\x81",
+ "\xce\x91" => "\xce\xb1", "\xce\x92" => "\xce\xb2",
+ "\xce\x93" => "\xce\xb3", "\xce\x94" => "\xce\xb4",
+ "\xce\x95" => "\xce\xb5", "\xce\x96" => "\xce\xb6",
+ "\xce\x97" => "\xce\xb7", "\xce\x98" => "\xce\xb8",
+ "\xce\x99" => "\xce\xb9", "\xce\x9a" => "\xce\xba",
+ "\xce\x9b" => "\xce\xbb", "\xce\x9c" => "\xce\xbc",
+ "\xce\x9d" => "\xce\xbd", "\xce\x9e" => "\xce\xbe",
+ "\xce\x9f" => "\xce\xbf", "\xce\xa0" => "\xcf\x80",
+ "\xce\xa1" => "\xcf\x81", "\xce\xa3" => "\xcf\x83",
+ "\xce\xa4" => "\xcf\x84", "\xce\xa5" => "\xcf\x85",
+ "\xce\xa6" => "\xcf\x86", "\xce\xa7" => "\xcf\x87",
+ "\xce\xa8" => "\xcf\x88", "\xce\xa9" => "\xcf\x89",
+ "\xce\xaa" => "\xcf\x8a", "\xce\xab" => "\xcf\x8b",
+ "\xce\xb0" => "\xcf\x85\xcc\x88\xcc\x81",
+ ## U+03c0
+ "\xcf\x82" => "\xcf\x83", "\xcf\x90" => "\xce\xb2",
+ "\xcf\x91" => "\xce\xb8", "\xcf\x95" => "\xcf\x86",
+ "\xcf\x96" => "\xcf\x80", "\xcf\x98" => "\xcf\x99",
+ "\xcf\x9a" => "\xcf\x9b", "\xcf\x9c" => "\xcf\x9d",
+ "\xcf\x9e" => "\xcf\x9f", "\xcf\xa0" => "\xcf\xa1",
+ "\xcf\xa2" => "\xcf\xa3", "\xcf\xa4" => "\xcf\xa5",
+ "\xcf\xa6" => "\xcf\xa7", "\xcf\xa8" => "\xcf\xa9",
+ "\xcf\xaa" => "\xcf\xab", "\xcf\xac" => "\xcf\xad",
+ "\xcf\xae" => "\xcf\xaf", "\xcf\xb0" => "\xce\xba",
+ "\xcf\xb1" => "\xcf\x81", "\xcf\xb4" => "\xce\xb8",
+ "\xcf\xb5" => "\xce\xb5", "\xcf\xb7" => "\xcf\xb8",
+ "\xcf\xb9" => "\xcf\xb2", "\xcf\xba" => "\xcf\xbb",
+ "\xcf\xbd" => "\xcd\xbb", "\xcf\xbe" => "\xcd\xbc",
+ "\xcf\xbf" => "\xcd\xbd",
+ ## U+0400
+ "\xd0\x80" => "\xd1\x90", "\xd0\x81" => "\xd1\x91",
+ "\xd0\x82" => "\xd1\x92", "\xd0\x83" => "\xd1\x93",
+ "\xd0\x84" => "\xd1\x94", "\xd0\x85" => "\xd1\x95",
+ "\xd0\x86" => "\xd1\x96", "\xd0\x87" => "\xd1\x97",
+ "\xd0\x88" => "\xd1\x98", "\xd0\x89" => "\xd1\x99",
+ "\xd0\x8a" => "\xd1\x9a", "\xd0\x8b" => "\xd1\x9b",
+ "\xd0\x8c" => "\xd1\x9c", "\xd0\x8d" => "\xd1\x9d",
+ "\xd0\x8e" => "\xd1\x9e", "\xd0\x8f" => "\xd1\x9f",
+ "\xd0\x90" => "\xd0\xb0", "\xd0\x91" => "\xd0\xb1",
+ "\xd0\x92" => "\xd0\xb2", "\xd0\x93" => "\xd0\xb3",
+ "\xd0\x94" => "\xd0\xb4", "\xd0\x95" => "\xd0\xb5",
+ "\xd0\x96" => "\xd0\xb6", "\xd0\x97" => "\xd0\xb7",
+ "\xd0\x98" => "\xd0\xb8", "\xd0\x99" => "\xd0\xb9",
+ "\xd0\x9a" => "\xd0\xba", "\xd0\x9b" => "\xd0\xbb",
+ "\xd0\x9c" => "\xd0\xbc", "\xd0\x9d" => "\xd0\xbd",
+ "\xd0\x9e" => "\xd0\xbe", "\xd0\x9f" => "\xd0\xbf",
+ "\xd0\xa0" => "\xd1\x80", "\xd0\xa1" => "\xd1\x81",
+ "\xd0\xa2" => "\xd1\x82", "\xd0\xa3" => "\xd1\x83",
+ "\xd0\xa4" => "\xd1\x84", "\xd0\xa5" => "\xd1\x85",
+ "\xd0\xa6" => "\xd1\x86", "\xd0\xa7" => "\xd1\x87",
+ "\xd0\xa8" => "\xd1\x88", "\xd0\xa9" => "\xd1\x89",
+ "\xd0\xaa" => "\xd1\x8a", "\xd0\xab" => "\xd1\x8b",
+ "\xd0\xac" => "\xd1\x8c", "\xd0\xad" => "\xd1\x8d",
+ "\xd0\xae" => "\xd1\x8e", "\xd0\xaf" => "\xd1\x8f",
+ ## U+0460
+ "\xd1\xa0" => "\xd1\xa1", "\xd1\xa2" => "\xd1\xa3",
+ "\xd1\xa4" => "\xd1\xa5", "\xd1\xa6" => "\xd1\xa7",
+ "\xd1\xa8" => "\xd1\xa9", "\xd1\xaa" => "\xd1\xab",
+ "\xd1\xac" => "\xd1\xad", "\xd1\xae" => "\xd1\xaf",
+ "\xd1\xb0" => "\xd1\xb1", "\xd1\xb2" => "\xd1\xb3",
+ "\xd1\xb4" => "\xd1\xb5", "\xd1\xb6" => "\xd1\xb7",
+ "\xd1\xb8" => "\xd1\xb9", "\xd1\xba" => "\xd1\xbb",
+ "\xd1\xbc" => "\xd1\xbd", "\xd1\xbe" => "\xd1\xbf",
+ ## U+0480
+ "\xd2\x80" => "\xd2\x81", "\xd2\x8a" => "\xd2\x8b",
+ "\xd2\x8c" => "\xd2\x8d", "\xd2\x8e" => "\xd2\x8f",
+ "\xd2\x90" => "\xd2\x91", "\xd2\x92" => "\xd2\x93",
+ "\xd2\x94" => "\xd2\x95", "\xd2\x96" => "\xd2\x97",
+ "\xd2\x98" => "\xd2\x99", "\xd2\x9a" => "\xd2\x9b",
+ "\xd2\x9c" => "\xd2\x9d", "\xd2\x9e" => "\xd2\x9f",
+ "\xd2\xa0" => "\xd2\xa1", "\xd2\xa2" => "\xd2\xa3",
+ "\xd2\xa4" => "\xd2\xa5", "\xd2\xa6" => "\xd2\xa7",
+ "\xd2\xa8" => "\xd2\xa9", "\xd2\xaa" => "\xd2\xab",
+ "\xd2\xac" => "\xd2\xad", "\xd2\xae" => "\xd2\xaf",
+ "\xd2\xb0" => "\xd2\xb1", "\xd2\xb2" => "\xd2\xb3",
+ "\xd2\xb4" => "\xd2\xb5", "\xd2\xb6" => "\xd2\xb7",
+ "\xd2\xb8" => "\xd2\xb9", "\xd2\xba" => "\xd2\xbb",
+ "\xd2\xbc" => "\xd2\xbd", "\xd2\xbe" => "\xd2\xbf",
+ ## U+04c0
+ "\xd3\x80" => "\xd3\x8f", "\xd3\x81" => "\xd3\x82",
+ "\xd3\x83" => "\xd3\x84", "\xd3\x85" => "\xd3\x86",
+ "\xd3\x87" => "\xd3\x88", "\xd3\x89" => "\xd3\x8a",
+ "\xd3\x8b" => "\xd3\x8c", "\xd3\x8d" => "\xd3\x8e",
+ "\xd3\x90" => "\xd3\x91", "\xd3\x92" => "\xd3\x93",
+ "\xd3\x94" => "\xd3\x95", "\xd3\x96" => "\xd3\x97",
+ "\xd3\x98" => "\xd3\x99", "\xd3\x9a" => "\xd3\x9b",
+ "\xd3\x9c" => "\xd3\x9d", "\xd3\x9e" => "\xd3\x9f",
+ "\xd3\xa0" => "\xd3\xa1", "\xd3\xa2" => "\xd3\xa3",
+ "\xd3\xa4" => "\xd3\xa5", "\xd3\xa6" => "\xd3\xa7",
+ "\xd3\xa8" => "\xd3\xa9", "\xd3\xaa" => "\xd3\xab",
+ "\xd3\xac" => "\xd3\xad", "\xd3\xae" => "\xd3\xaf",
+ "\xd3\xb0" => "\xd3\xb1", "\xd3\xb2" => "\xd3\xb3",
+ "\xd3\xb4" => "\xd3\xb5", "\xd3\xb6" => "\xd3\xb7",
+ "\xd3\xb8" => "\xd3\xb9", "\xd3\xba" => "\xd3\xbb",
+ "\xd3\xbc" => "\xd3\xbd", "\xd3\xbe" => "\xd3\xbf",
+ ## U+0500
+ "\xd4\x80" => "\xd4\x81", "\xd4\x82" => "\xd4\x83",
+ "\xd4\x84" => "\xd4\x85", "\xd4\x86" => "\xd4\x87",
+ "\xd4\x88" => "\xd4\x89", "\xd4\x8a" => "\xd4\x8b",
+ "\xd4\x8c" => "\xd4\x8d", "\xd4\x8e" => "\xd4\x8f",
+ "\xd4\x90" => "\xd4\x91", "\xd4\x92" => "\xd4\x93",
+ "\xd4\xb1" => "\xd5\xa1", "\xd4\xb2" => "\xd5\xa2",
+ "\xd4\xb3" => "\xd5\xa3", "\xd4\xb4" => "\xd5\xa4",
+ "\xd4\xb5" => "\xd5\xa5", "\xd4\xb6" => "\xd5\xa6",
+ "\xd4\xb7" => "\xd5\xa7", "\xd4\xb8" => "\xd5\xa8",
+ "\xd4\xb9" => "\xd5\xa9", "\xd4\xba" => "\xd5\xaa",
+ "\xd4\xbb" => "\xd5\xab", "\xd4\xbc" => "\xd5\xac",
+ "\xd4\xbd" => "\xd5\xad", "\xd4\xbe" => "\xd5\xae",
+ "\xd4\xbf" => "\xd5\xaf",
+ ## U+0540
+ "\xd5\x80" => "\xd5\xb0", "\xd5\x81" => "\xd5\xb1",
+ "\xd5\x82" => "\xd5\xb2", "\xd5\x83" => "\xd5\xb3",
+ "\xd5\x84" => "\xd5\xb4", "\xd5\x85" => "\xd5\xb5",
+ "\xd5\x86" => "\xd5\xb6", "\xd5\x87" => "\xd5\xb7",
+ "\xd5\x88" => "\xd5\xb8", "\xd5\x89" => "\xd5\xb9",
+ "\xd5\x8a" => "\xd5\xba", "\xd5\x8b" => "\xd5\xbb",
+ "\xd5\x8c" => "\xd5\xbc", "\xd5\x8d" => "\xd5\xbd",
+ "\xd5\x8e" => "\xd5\xbe", "\xd5\x8f" => "\xd5\xbf",
+ "\xd5\x90" => "\xd6\x80", "\xd5\x91" => "\xd6\x81",
+ "\xd5\x92" => "\xd6\x82", "\xd5\x93" => "\xd6\x83",
+ "\xd5\x94" => "\xd6\x84", "\xd5\x95" => "\xd6\x85",
+ "\xd5\x96" => "\xd6\x86", "\xd6\x87" => "\xd5\xa5\xd6\x82"
+ ));
+
+
diff --git a/wiki.d/Main.HomePage b/wiki.d/Main.HomePage
new file mode 100644
index 0000000..048e36e
--- /dev/null
+++ b/wiki.d/Main.HomePage
@@ -0,0 +1,50 @@
+version=pmwiki-2.2.13 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_2; en-US) AppleWebKit/533.1 (KHTML, like Gecko) Chrome/5.0.335.0 Safari/533.1
+author=
+charset=ISO-8859-1
+csum=
+host=209.234.11.50
+name=Main.HomePage
+rev=213
+targets=
+text=**Test**%0a%0a* reason 1%0a* raeson 2%0a
+time=1267204614
+author:1267204614=
+diff:1267204614:1267203738:=0a1%0a> %0a4a6%0a> %0a
+host:1267204614=209.234.11.50
+author:1267203738=
+diff:1267203738:1267203602:=1c1%0a%3c %0a---%0a> (:markdown:)%0a6a7%0a> (:markdownend:)%0a\ No newline at end of file%0a
+host:1267203738=209.234.11.50
+author:1267203602=
+diff:1267203602:1267203481:=1d0%0a%3c (:markdown:)%0a7d5%0a%3c (:markdownend:)%0a\ No newline at end of file%0a
+host:1267203602=209.234.11.50
+author:1267203481=
+diff:1267203481:1267203471:=0a1%0a> %0a
+host:1267203481=209.234.11.50
+author:1267203471=
+diff:1267203471:1267203126:=1c1,2%0a%3c %0a---%0a> (:markdown:)%0a> %0a6a8,9%0a> %0a> (:markdownend:)%0a\ No newline at end of file%0a
+host:1267203471=209.234.11.50
+author:1267203126=
+diff:1267203126:1267203108:=4,7d3%0a%3c %0a%3c * reason 1%0a%3c * raeson 2%0a%3c %0a
+host:1267203126=209.234.11.50
+author:1267203108=
+diff:1267203108:1267203097:=3c3%0a%3c **Test**%0a---%0a> ** Test**%0a
+host:1267203108=209.234.11.50
+author:1267203097=
+diff:1267203097:1267203049:=1,5c1,5%0a%3c (:markdown:)%0a%3c %0a%3c ** Test**%0a%3c %0a%3c (:markdownend:)%0a\ No newline at end of file%0a---%0a> *testing*, **testing**, %0a> %0a> * 1%0a> * 2%0a> * 3%0a
+host:1267203097=209.234.11.50
+author:1267203049=
+diff:1267203049:1267202179:=1,5c1,6%0a%3c *testing*, **testing**, %0a%3c %0a%3c * 1%0a%3c * 2%0a%3c * 3%0a---%0a> (:markdown:)%0a> %0a> Test%0a> ====%0a> %0a> (:markdownend:)%0a\ No newline at end of file%0a
+host:1267203049=209.234.11.50
+author:1267202179=
+diff:1267202179:1267202109:=0a1%0a> Welcome to PmWiki for Züm!%0a2,6c3,13%0a%3c %0a%3c Test%0a%3c ====%0a%3c %0a%3c (:markdownend:)%0a\ No newline at end of file%0a---%0a> A local copy of *PmWiki*'s%0a> (:endmarkdown:)%0a> documentation has been installed along with the software,%0a> and is available via the [[PmWiki/documentation index]]. %0a> %0a> To continue setting up PmWiki, see [[PmWiki/initial setup tasks]].%0a> %0a> The [[PmWiki/basic editing]] page describes how to create pages%0a> in PmWiki. You can practice editing in the [[wiki sandbox]].%0a> %0a> More information about PmWiki is available from http://www.pmwiki.org .%0a
+host:1267202179=209.234.11.50
+author:1267202109=
+diff:1267202109:1267202065:=2c2%0a%3c (:markdown:)%0a---%0a> %0a4d3%0a%3c (:endmarkdown:)%0a
+host:1267202109=209.234.11.50
+author:1267202065=
+diff:1267202065:1267156086:=3c3%0a%3c A local copy of *PmWiki*'s%0a---%0a> A local copy of PmWiki's%0a
+host:1267202065=209.234.11.50
+author:1267156086=
+diff:1267156086:1142203034:=1c1%0a%3c Welcome to PmWiki for Züm!%0a---%0a> Welcome to PmWiki!%0a
+host:1267156086=67.163.124.137
diff --git a/wiki.d/Main.RecentChanges b/wiki.d/Main.RecentChanges
new file mode 100644
index 0000000..7ea7f63
--- /dev/null
+++ b/wiki.d/Main.RecentChanges
@@ -0,0 +1,8 @@
+version=pmwiki-2.2.13 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_2; en-US) AppleWebKit/533.1 (KHTML, like Gecko) Chrome/5.0.335.0 Safari/533.1
+ctime=1267156086
+host=209.234.11.50
+name=Main.RecentChanges
+rev=13
+text=* [[Main/HomePage]] . . . February 26, 2010, at 09:16 AM by ?: [==]%0a
+time=1267204614
diff --git a/wiki.d/Site.AllRecentChanges b/wiki.d/Site.AllRecentChanges
new file mode 100644
index 0000000..1a093c5
--- /dev/null
+++ b/wiki.d/Site.AllRecentChanges
@@ -0,0 +1,8 @@
+version=pmwiki-2.2.13 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_2; en-US) AppleWebKit/533.1 (KHTML, like Gecko) Chrome/5.0.335.0 Safari/533.1
+ctime=1267156086
+host=209.234.11.50
+name=Site.AllRecentChanges
+rev=16
+text=* [[Site.Footer]] . . . February 26, 2010, at 09:18 AM by ?: [==]%0a* [[Main.HomePage]] . . . February 26, 2010, at 09:16 AM by ?: [==]%0a* [[Site.Header]] . . . February 26, 2010, at 09:05 AM by ?: [==]%0a
+time=1267204707
diff --git a/wiki.d/Site.Footer b/wiki.d/Site.Footer
new file mode 100644
index 0000000..2c67d6d
--- /dev/null
+++ b/wiki.d/Site.Footer
@@ -0,0 +1,18 @@
+version=pmwiki-2.2.13 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_2; en-US) AppleWebKit/533.1 (KHTML, like Gecko) Chrome/5.0.335.0 Safari/533.1
+author=
+charset=ISO-8859-1
+csum=
+ctime=1267203946
+host=209.234.11.50
+name=Site.Footer
+rev=2
+targets=
+text=
+time=1267204707
+author:1267204707=
+diff:1267204707:1267203946:=0a1%0a> (:markdownend:)%0a\ No newline at end of file%0a
+host:1267204707=209.234.11.50
+author:1267203946=
+diff:1267203946:1267203946:=1d0%0a%3c (:markdownend:)%0a\ No newline at end of file%0a
+host:1267203946=209.234.11.50
diff --git a/wiki.d/Site.Header b/wiki.d/Site.Header
new file mode 100644
index 0000000..40f4810
--- /dev/null
+++ b/wiki.d/Site.Header
@@ -0,0 +1,15 @@
+version=pmwiki-2.2.13 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_2; en-US) AppleWebKit/533.1 (KHTML, like Gecko) Chrome/5.0.335.0 Safari/533.1
+author=
+charset=ISO-8859-1
+csum=
+ctime=1267203959
+host=209.234.11.50
+name=Site.Header
+rev=1
+targets=
+text=(:markdown:)
+time=1267203959
+author:1267203959=
+diff:1267203959:1267203959:=1d0%0a%3c (:markdown:)%0a\ No newline at end of file%0a
+host:1267203959=209.234.11.50
diff --git a/wiki.d/Site.RecentChanges b/wiki.d/Site.RecentChanges
new file mode 100644
index 0000000..4836ff1
--- /dev/null
+++ b/wiki.d/Site.RecentChanges
@@ -0,0 +1,8 @@
+version=pmwiki-2.2.13 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_2; en-US) AppleWebKit/533.1 (KHTML, like Gecko) Chrome/5.0.335.0 Safari/533.1
+ctime=1267203946
+host=209.234.11.50
+name=Site.RecentChanges
+rev=3
+text=* [[Site/Footer]] . . . February 26, 2010, at 09:18 AM by ?: [==]%0a* [[Site/Header]] . . . February 26, 2010, at 09:05 AM by ?: [==]%0a
+time=1267204707
diff --git a/wiki.d/SiteAdmin.Status b/wiki.d/SiteAdmin.Status
new file mode 100644
index 0000000..13bb1cb
--- /dev/null
+++ b/wiki.d/SiteAdmin.Status
@@ -0,0 +1,12 @@
+version=pmwiki-2.2.13 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_2; en-US) AppleWebKit/533.1 (KHTML, like Gecko) Chrome/5.0.335.0 Safari/533.1
+author=simon
+charset=ISO-8859-1
+csum=Add summary, see how long a summary lasts?!
+host=67.163.124.137
+name=SiteAdmin.Status
+rev=23
+targets=
+text=(:Summary: PmWiki version {$Version} (VersionNum={$VersionNum}):)%0a(:comment Any local edits to this page may be lost!:)%0a%0aThis site is running {$Version} (VersionNum={$VersionNum}).%0a
+time=1267156072
+updatedto=2002013
diff --git a/wikilib.d/Category.GroupFooter b/wikilib.d/Category.GroupFooter
new file mode 100644
index 0000000..1a0b24d
--- /dev/null
+++ b/wikilib.d/Category.GroupFooter
@@ -0,0 +1,11 @@
+version=pmwiki-2.2.1 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.19) Gecko/20081216 Ubuntu/8.04 (hardy) Firefox/2.0.0.19
+author=Petko
+charset=ISO-8859-1
+csum=$FullName
+host=81.65.14.164
+name=Category.GroupFooter
+rev=66
+targets=
+text=(:Summary:content generated for Category list pages:)%0a----%0a[--'''{*$:Summary}'''--]%0a(:pagelist link={*$FullName} list=normal:)%0a
+time=1238273681
diff --git a/wikilib.d/Main.HomePage b/wikilib.d/Main.HomePage
new file mode 100644
index 0000000..c1124bf
--- /dev/null
+++ b/wikilib.d/Main.HomePage
@@ -0,0 +1,10 @@
+version=pmwiki-2.1.0 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (Windows; U; Win98; en-US; rv:1.7.12) Gecko/20050915
+author=HaganFox
+csum=Bold "first time installers:" wasn't necessary.
+host=216.161.175.221
+name=Main.HomePage
+rev=200
+targets=PmWiki.DocumentationIndex,PmWiki.InitialSetupTasks,PmWiki.BasicEditing,Main.WikiSandbox
+text=Welcome to PmWiki!%0a%0aA local copy of PmWiki's%0adocumentation has been installed along with the software,%0aand is available via the [[PmWiki/documentation index]]. %0a%0aTo continue setting up PmWiki, see [[PmWiki/initial setup tasks]].%0a%0aThe [[PmWiki/basic editing]] page describes how to create pages%0ain PmWiki. You can practice editing in the [[wiki sandbox]].%0a%0aMore information about PmWiki is available from http://www.pmwiki.org .%0a
+time=1142203034
diff --git a/wikilib.d/Main.WikiSandbox b/wikilib.d/Main.WikiSandbox
new file mode 100644
index 0000000..55fe4c4
--- /dev/null
+++ b/wikilib.d/Main.WikiSandbox
@@ -0,0 +1,9 @@
+version=pmwiki-2.0.devel1
+newline=²
+version=pmwiki-2.0.devel1
+text=Feel free to use this page to experiment with the [[PmWiki/Text Formatting Rules]]. Just click the "Edit Page" link at the bottom of the page.²----²
+time=1093548433
+name=Main.WikiSandbox
+host=24.1.26.221
+agent=Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.7) Gecko/20040707 Firefox/0.8
+rev=3
diff --git a/wikilib.d/PmWiki.AccessKeys b/wikilib.d/PmWiki.AccessKeys
new file mode 100644
index 0000000..e9b728d
--- /dev/null
+++ b/wikilib.d/PmWiki.AccessKeys
@@ -0,0 +1,12 @@
+version=pmwiki-2.2.4 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.19) Gecko/20081216 Ubuntu/8.04 (hardy) Firefox/2.0.0.19
+author=Petko
+charset=ISO-8859-1
+csum=fixed doc, rm faq
+ctime=1137027716
+host=86.69.109.9
+name=PmWiki.AccessKeys
+rev=101
+targets=PmWiki.Internationalizations,PmWiki.SitePreferences,Site.Preferences,Site.PageActions
+text=(:Summary:Access keys are keyboard shortcuts for tasks that would otherwise require a mouse:)%0a(:Audience: visitors (intermediate) :)%0a%0aAccess keys (See also [[Wikipedia:access keys]]) are keyboard shortcuts for tasks that would otherwise require a mouse. %0aThey are part of markup that may exist on any webpage.%0aOn PmWiki steps have been taken to make it easier to use access keys throughout a site, and to make it possible to adjust key assignments to accommodate different languages and preferences.%0a%0a!! Using access keys in different operating systems and browsers%0aAccess keys require you to hold down two or more keys.%0a* On Windows with Internet Explorer, press ALT + the access key.%0a* With Firefox, press SHIFT + ALT + the access key.%0a* On a Macintosh with Firefox, Omniweb, Internet Explorer, press Ctrl + the access key.%0a** With Safari (Version 4.0.2) press Ctrl + Option + the access key.%0a* With [[http://opera.com/support/tutorials/nomouse/#access | Opera]] press Shift+Esc to enter (or exit) access-key mode.%0a* With Konqueror, press Ctrl to enter (or exit) access-key mode.%0a%0aExceptions exist for specific browsers, and specific versions. For example, %0a* Internet Explorer requires that the Enter key be pressed at the end of the sequence for versions 5 and up under Windows, but not under Macintosh (where access keys were not supported until after version 4.5). %0a* Firefox versions 1.5 and earlier simply use Alt, while Firefox version 2.0 uses Shift+Alt. %0a%0aNote, in cases of conflicts between the keyboard shortcuts assigned by browsers and access keys assigned by links and other markup on webpages, many browsers, including Mozilla, Netscape and Internet Explorer, allow access keys to override the browser defaults and require a different sequence to continue using overridden browser assignments (typically, by pressing and releasing the Alt key, instead of holding it down). %0a%0a!! Access key assignments in this PmWiki installation%0aThe following is a list of the currently defined access keys for built-in actions. Remember that the letters identified below must be used together with the combination listed above (depending on your operating system and browser). Note that some actions do not have a corresponding access key by default.%0a%0a||width=%0a||! Key ||!Function ||%0a|| $[ak_edit] ||edit||%0a|| $[ak_history] ||history||%0a|| $[ak_recentchanges] ||recent changes||%0a|| $[ak_save] ||save page||%0a|| $[ak_saveedit] ||save and keep editing||%0a|| $[ak_savedraft] ||save draft||%0a|| $[ak_preview] ||preview page||%0a|| $[ak_print] ||print||%0a|| $[ak_view] ||view||%0a|| $[ak_em] ||''emphasized'' text||%0a|| $[ak_strong] ||'''strong''' text||%0a|| $[ak_textedit] ||jump to edit textarea (when in edit modes)|| %0a%0a%0a%25audience%25 admins (intermediate)%0a!! [[#customkeys]] Customizing access keys%0aPmWiki uses the same "phrase translation" methods for access key mappings as it does for [[internationalization(s)]]. This makes it possible for administrators, skins, language translators, and visitors to all influence the way that specific keys are mapped to actions.%0a%0aSee [[SitePreferences]] and [[Site.Preferences]] for more information and a template.%0a%0aNote that some skins (e.g., [[Cookbook:LeanSkin | Lean]]) don't use the translation mechanism. In this case one must edit the template file itself in order to change the access keys.%0a%0aBy convention, the translation phrases for all of the access key actions start with the characters "ak_", so that the page variable "[@$[ak_edit]@]" is replaced by the access key for editing as defined by the current preferences, language, skin default, or site default.%0a%0a!! Implementation of access keys%0aAccess keys are implemented in html as optional parameters that can be added to links and many other types of markup.%0a%0a'''Example:''' [@%3ca href="http://example.com" accesskey="x">Example%3c/a>@] would create a link to example.com that could be triggered by clicking on the linked word "example" or using the access key Akey+x. That same action key link could be created in PmWiki markup by typing [@%25accesskey="x"%25[[http://example.com|Example]]%25%25@], like this: %25accesskey="x"%25[[http://example.com|Example]]%25%25. Try it and see if it works. Note that this AKey+x access key only works this way on this page, because it is simply a shortcut for accessing the link that exists only on this page.%0a%0aThe list of access key assignments in default PmWiki installations generally work throughout a site because links have been created in PmWiki skins and editing screens that incorporate access key parameters using the access key translation phrases. One location where those links can be viewed is [[Site.PageActions]]. That page contains the links that the default PmWiki skin, and many other skins, use to generate links such as "View" "Edit" and "History" that appear on most pages (other than editing screens). Each of the links in that page also has an [@%25accesskey=$[ak_xxx]%25@] declaration in front of it, which enables a specific access key for that link.%0a%0a>>faq%3c%3c [[#faq]]%0a%0aQ: How can I change the keyboard shortcuts for editing and saving a page?%0aA: See [[#customkeys | Customizing access keys]].%0a%0a
+time=1251071968
diff --git a/wikilib.d/PmWiki.Audiences b/wikilib.d/PmWiki.Audiences
new file mode 100644
index 0000000..427d42b
--- /dev/null
+++ b/wikilib.d/PmWiki.Audiences
@@ -0,0 +1,11 @@
+version=pmwiki-2.2.1 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/530.5 (KHTML, like Gecko) Chrome/2.0.172.30 Safari/530.5
+author=Simon
+charset=ISO-8859-1
+csum=layout
+host=202.37.32.2
+name=PmWiki.Audiences
+rev=27
+targets=PmWiki.WikiAdministrator,PmWiki.InitialSetupTasks,PmWiki.PmWikiPhilosophy,PmWiki.LocalCustomizations
+text=(:Summary:Patrick Michaud's comments regarding the "audiences" for which PmWiki was designed:)%0aThis page contains Patrick Michaud's comments regarding the "audiences" for which PmWiki was designed. As such, many people are reluctant to modify the page, because it is a statement of his opinions and describes some of the thought that went into creating PmWiki. (And we all thank him for that!) %0a%0a%0a!!Patrick's comments%0aI think of PmWiki in terms of two audiences: %0a* ''Authors'' are the people who generate web content using PmWiki, and %0a* ''[[wiki administrator]]s'' are the folks who install, configure, and maintain a PmWiki installation on a web server. %0aIn some senses it could be claimed that as the primary developer of PmWiki I should only have wiki administrators as my target audience, and that authors are the target audience for the administrators. But what really makes PmWiki useful to wiki administrators is that I've put a lot of consideration into creating a tool that is usable by authors, so I have to keep the needs of both audiences in mind as I'm designing and adding new features to PmWiki. %0a%0aWithin the authoring audience I see that there are "naive authors" and "experienced authors". %0a%0a"Naive authors" are the folks who use wiki to generate content but may know next-to-nothing about HTML, much less style sheets or PHP or the like. Naive authors are easily discouraged from generating web content if they have to wade through markup text that has lots of funny and cryptic symbols in them. So, if we want a site with lots of contributors, we have to be very careful not to do things that will cause this group to exclude themselves from participating.%0a%0a"Experienced authors" are the folks who know a lot about HTML and could write their content as HTML, but have chosen to use wiki because of its other useful features (ease of linking, collaboration, ease of updates, revision histories, etc.) or because they want to collaborate with naive authors. Experienced authors usually don't have any problem with documents with lots of ugly markup in them; after all, they already know HTML. Experienced authors are sometimes frustrated with wiki because it doesn't have markup that would let them do something they know they can do in HTML (e.g., tables, stylesheets, colored text, etc.). And, they sometimes have difficulty understanding why naive authors would turn away from documents that have lots of markup sequences in them. %0a%0aFor the wiki administrator audience--the folks who install and may want to [[PmWiki/InitialSetupTasks|customize]] PmWiki--their backgrounds and goals are often quite diverse. PmWiki is designed so that it can be installed and be useful with minimal HTML/PHP knowledge, but it doesn't restrict people who know HTML/PHP from doing some fairly complex things. For one, PmWiki allows a site administrator to build-in markup sequences and features customized to his/her needs (and the needs of his/her audiences). %0a%0aThe separate needs of these audiences are behind most of the [[PmWikiPhilosoph(y)]]ies. The people who develop PmWiki software must continually keep naive authors in mind as new features are requested and proposed by expert authors and Wiki Administrators. Sometimes it may seem to these latter groups that it's okay to implement the complex features because "naive authors don't have to use them", but the truth is that if complex/ugly markup sequences are available then they will eventually be used by someone, and once used they become a barrier to the naive authors. So, if I see that a feature could become a barrier to a naive author I don't include it in the base implementation of PmWiki, but instead find ways to let Wiki Administrators include it as a [[local customization(s)]]. %0a
+time=1244681371
diff --git a/wikilib.d/PmWiki.AuthUser b/wikilib.d/PmWiki.AuthUser
new file mode 100644
index 0000000..7f95850
--- /dev/null
+++ b/wikilib.d/PmWiki.AuthUser
@@ -0,0 +1,11 @@
+version=pmwiki-2.2.2 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.19) Gecko/20081216 Ubuntu/8.04 (hardy) Firefox/2.0.0.19
+author=Petko
+charset=ISO-8859-1
+csum=
+host=81.65.14.164
+name=PmWiki.AuthUser
+rev=168
+targets=PmWiki.Passwords,PmWiki.PasswordsAdmin,SiteAdmin.AuthUser,PmWiki.AuthUser
+text=(:Summary:Authorization system that uses usernames and passwords:)%0a(:Audience: administrators (intermediate) :)%0aAuthUser is PmWiki's identity-based authorization system that allows access to pages to be controlled through the use of usernames and passwords. AuthUser can be used in addition to the [[Passwords | password-based]] scheme that is PmWiki's default configuration.%0a%0aAuthUser is a very flexible system for managing access control on pages, but flexibility can also bring complexity and increased maintenance overhead to the wiki administrator. This is why PmWiki defaults to the simpler password-based system. For some thoughts about the relative merits of the two approaches, see [[PmWiki:ThoughtsOnAccessControl]].%0a%0aSee also: [[Cookbook:Quick Start for AuthUser]].%0a%0a!! Activating AuthUser%0aTo activate PmWiki's identity-based system, add the following line%0ato ''local/config.php'':%0a%0a include_once("$FarmD/scripts/authuser.php");%0a%0aEnsure that you have [[PasswordsAdmin | set a site wide admin password]], otherwise you will not be able to edit [[SiteAdmin.AuthUser]].%0a%0a->%25note%25 Note: Older versions of PmWiki (before 2.2.0-beta58) use ''Site.AuthUser''.%0a%0aPmWiki caches some group and page authorization levels when a page is accessed. For this reason, it is better to include @@authuser.php@@ quite early in config.php, notably%0a* after any recipe which inserts some custom writable PageStore class (MySQL, SQLite, Compressed PageStore or other)%0a* and after any internationalization (UTF-8 and XLPage).%0a%0a(If you don't use a custom PageStore class and i18n, include @@authuser.php@@ first thing in @@config.php@@.)%0a%0aAll other recipes should be included after these.%0a%0a!! Creating user accounts%0aMost of AuthUser's configuration is performed via the [[SiteAdmin.AuthUser]] page. To change the AuthUser configuration, simply edit this page like any other wiki page (you'll typically need to use the site's admin password for this).%0a%0aTo create a login account, simply add lines to SiteAdmin.AuthUser that look like:%0a%0a username: [=(:=]encrypt ''password'':)%0a%0aFor example, to create a login account for "alice" with a password of "wonderland", enter:%0a%0a alice: [=(:=]encrypt wonderland:)%0a%0aWhen the page is saved, the "@@[=(:=]encrypt wonderland:)@@" part of the text will be replaced by an encrypted form of the password "wonderland". This encryption is done so that someone looking at the SiteAdmin.AuthUser page cannot easily determine the passwords stored in the page. %0a%0aTo change or reset an account's password, simply replace the encrypted string with another @@[=(:=]encrypt:)@@ directive.%0a%0a!! Controlling access to pages by login%0a%0aPages and groups can be protected based on login account by using "passwords" of the form [@id:username@] in the password fields of [@?action=attr@] (see [[PmWiki.Passwords]]). For example, to restrict a page to being edited by Alice, one would set the password to "[@id:alice@]".%0a%0aIt's possible to use multiple "id:" declarations and passwords in the [@?action=attr@] form, thus the following setting would allow access to Alice, Carol, and anyone who knows the password "quick":%0a%0a quick id:alice,carol%0a%0aTo allow access to anyone who has successfully logged in, use "[@id:*@]".%0a%0aOne can also perform site-wide restrictions based on identity in the $DefaultPasswords array: e.g.%0a%0a # require valid login before viewing pages%0a $DefaultPasswords['read'] = 'id:*';%0a # Alice and carol may edit%0a $DefaultPasswords['edit'] = 'id:alice,carol';%0a # All admins and Fred may edit%0a $DefaultPasswords['edit'] = array('@admins', 'id:Fred');%0a%0aYou can change the $DefaultPasswords array in local customization files such as:%0a* local/config.php (for entire wiki)%0a* farmconfig.php (for entire wikifarm)%0a%0a!! [[#auth_groups]] Organizing accounts into groups%0a%0aAuthUser also makes it possible to group login accounts together into authorization groups, indicated by a leading "@" sign. As with login accounts, group memberships are maintained by editing the SiteAdmin.AuthUser page. Group memberships can be specified by either listing the groups for a login account (person belongs to groups) or the login accounts for a group (group includes people). You can repeat or mix-and-match the two kinds as desired:%0a%0a @writers: alice, bob%0a carol: @writers, @editors%0a @admins: alice, dave%0a %0aThen, to restrict page access to a particular group, simply use "[@@group@]" as the "password" in [@?action=attr@] or the $DefaultPasswords array, similar to the way that "[@id:username@]" is used to restrict access to specific login accounts.%0a%0a!!! Excluding individuals from password groups%0a%0aGroup password memberships are maintained by editing the SiteAdmin.AuthUser page. To specify a password group that allows access to anyone who is authenticated, you can specify:%0a%0a @wholeoffice: *%0a%0aIf you need to keep "Fred" out of this password group :%0a%0a @wholeoffice: *,-Fred%0a%0aTo allow all users except Fred to change page attributes, for example, you can add to config.php :%0a $DefaultPasswords['attr'] = array('id:*,-Fred');%0a%0a(:if authid:)%0a>>clip%3c%3c%0a!!!!!Wiki Debug%0a* %25newwin%25 [[Diagnostics -> {$Name}?action=diag]]%0a* %25newwin%25 [[PHPInfo -> {$Name}?action=phpinfo]]%0a(:ifend:)%0a%0a!! Getting account names and passwords from external sources%0a%0aThe AuthUser script has the capability of obtaining username/password pairs from places other than the SiteAdmin.AuthUser page, such as passwd-formatted files (usually called '.htpasswd' on Apache servers), [[#LDAP|LDAP]] servers, or even the ''local/config.php'' file.%0a%0a!!! Passwd-formatted files (.htpasswd/.htgroup)%0a%0aPasswd-formatted files, commonly called ''.htpasswd'' files in Apache, are text files where each line contains a username and an encrypted password separated by a colon. A typical ''.htpasswd'' file might look like:%0a%0a alice:vK99sgDV1an6I%0a carol:Q1kSeNcTfwqjs%0a%0aTo get AuthUser to obtain usernames and passwords from a ''.htaccess'' file, add the following line to SiteAdmin.AuthUser, replacing "/path/to/.htpasswd" with the filesystem path of the ''.htpasswd'' file:%0a%0a htpasswd: /path/to/.htpasswd%0a%0aCreation and maintenance of the ''.htpasswd'' file can be performed using a text editor, or any number of other third-party tools available for maintaining ''.htpasswd'' files. The Apache web server typically includes an ''htpasswd'' command for creating accounts in .htpasswd:%0a%0a $ htpasswd /path/to/.htpasswd alice%0a New password:%0a Re-type new password:%0a Adding password for user alice%0a $%0a%0aSimilarly, one can use ''.htgroup'' formatted files to specify group memberships. Each line has the name of a group (without the "@"), followed by a colon, followed by a space separated list of usernames in the group.%0a%0a writers: carol%0a editors: alice carol bob%0a admins: alice dave%0a%0aNote that the groups are still "@writers", "@editors", and "@admins" in PmWiki even though the file doesn't specify the @ signs. To get AuthUser to load these groups, use a line in SiteAdmin.AuthUser like:%0a%0a htgroup: /path/to/.htgroup%0a%0a!!! Configuration via ''local/config.php''%0a%0aAuthUser configuration settings can also be made from the ''local/config.php'' file in addition to the SiteAdmin.AuthUser page. Such settings are placed in the $AuthUser array, and ''must be set prior to including the ''authuser.php'' script''. Some examples:%0a%0a # set a password for alice%0a $AuthUser['alice'] = crypt('wonderland');%0a # set a password for carol%0a $AuthUser['carol'] = '$1$CknC8zAs$dC8z2vu3UvnIXMfOcGDON0';%0a # define the @editors group%0a $AuthUser['@editors'] = array('alice', 'carol', 'bob');%0a # Use local/.htpasswd for usernames/passwords%0a $AuthUser['htpasswd'] = 'local/.htpasswd';%0a # Use local/.htgroup for group memberships%0a $AuthUser['htgroup'] = 'local/.htgroup';%0a%0a[[#LDAP]]%0a!!! Configuration via LDAP%0a%0aAuthentication can be performed via an external LDAP server -- simply set an entry for "ldap" in either SiteAdmin.AuthUser or the ''local/config.php'' file.%0a%0a # use ldap.airius.com for authentication%0a $AuthUser['ldap'] = 'ldap://ldap.airius.com/ou=People,o=Airius?cn?sub';%0a%0aMake sure to include AuthUser below the entry for the ldap server:%0a%0a # Want to use AuthUser so we can use ldap for passwords%0a include_once("$FarmD/scripts/authuser.php");%0a%0aAnd remember to assign the Security Variables for edit and history (or whatever):%0a%0a #Security Variables set login for edit & history page%0a # to let anyone edit that has an ldap entry:%0a $HandleAuth['diff'] = 'edit';%0a $DefaultPasswords['edit'] = 'id:*';%0a $Author = $AuthId;%0a%0aLDAP authentication in AuthUser closely follows the model used by Apache 2.0's [[http://httpd.apache.org/docs/2.0/mod/mod_auth_ldap.html|mod_auth_ldap]] module; see especially the documentation for [[http://httpd.apache.org/docs/2.0/mod/mod_auth_ldap.html#authldapurl|AuthLDAPUrl]] for a description of the url format.%0a%0aFor servers that don't allow anonymous binds, AuthUser provides $AuthLDAPBindDN and $AuthLDAPBindPassword variables to specify the binding to be used for searching.%0a%0aSee also [[Cookbook:AuthUser via Microsoft LDAP]]%0a%0a!! Setting the Author Name%0aBy default, PmWiki will use a login name in the Author field of the edit form, but allows the author to change this value prior to saving. To force the login name to always be used as the author name, use the following sequence in config.php to activate AuthUser:%0a%0a include_once("$FarmD/scripts/authuser.php");%0a $Author = $AuthId; # after include_once()%0a%0aTo allow more flexibility, but still enable changes to be linked to the authorized user, one can give the author name a prefix of the $AuthId instead:%0a[@%0a include_once("$FarmD/scripts/author.php");%0a include_once("$FarmD/scripts/authuser.php");%0a if ($Author) {%0a if (strstr($Author, '-') != false) {%0a $Author = "$AuthId-" . preg_replace('/^[^-]*-/', '', $Author);%0a } else if ($Author != $AuthId) {%0a $Author = $AuthId . '-' . $Author;%0a } else {%0a $Author = $AuthId;%0a }%0a } else {%0a $Author = $AuthId;%0a }%0a $AuthorLink = "[[~$Author]]";%0a@]%0aThe above will allow the user to put in the author name of their choice, but that will always be replaced by that name prefixed with "$AuthId-".%0aThe reason why $AuthorLink needs to be set is that, if it isn't, the RecentChanges page will have the wrong link in it.%0a%0a!!! Removing the "Author" edit field%0aTo force users to edit with their AuthID instead of having a field they can place any name in. This enables administration to keep track of who is doing what better. This line also links the Author name to their Profile.\\%0aGo to Site.EditForm, remove the line\\%0a[@$[Author]: (:input e_author:)@]\\%0aor replace it with\\%0a[@$[Author]: [[Profiles/{$Author}]]@]\\%0a%0a!! Authorization, Sessions, and WikiFarms [[#sessions]]%0a%0aPmWiki uses PHP sessions to keep track of any user authorization information. By default PHP is configured so that all interactions with the same server (as identified by the server's domain name) are treated as part of the same session.%0a%0aWhat this means for PmWiki is that if there are multiple wikis running within the same domain name, PHP will treat a login to one wiki as being valid for all wikis in the same domain. The easiest fix is to tell each wiki to have use a different "session cookie". Near the top of a wiki's ''local/config.php'' file, before calling authuser or other recipes, add a line like:%0a%0a-->[@session_name('XYZSESSID');@]%0a%0aThe XYZSESSID can be any unique name (letters only is safest).%0a%0a!! See Also%0a%0a* [[PmWiki.Passwords]]%0a* [[PmWiki.PasswordsAdmin]]%0a* [[Cookbook:AuthUser]] for tips and tricks%0a* [[SiteAdmin.AuthUser]]%0a%0a%0a>>faq%3c%3c [[#faq]]%0aQ: I get http error 500 "Internal Server Error" when I try to log in. What's wrong?%0a%0aA: This can happen if the encrypted passwords are not created on the web server that hosts the PmWiki.%0aThe crypt function changed during the PHP development, e.g. a password encrypted with PHP 5.2 can not be decrypted in PHP 5.1, but PHP 5.2 can decrypt passwords created by PHP 5.1.%0aThis situation normally happens if you prepare everything on your local machine with the latest PHP version and you upload the passwords to a webserver which is running an older version.%0aThe same error occurs when you add encrypted passwords to local/config.php.%0a%0aSolution: Create the passwords on the system with the oldest PHP version and use them on all other systems.%0a%0aQ: Can I specify authorization group memberships from with ''local/config.php''?%0a%0aA: Yes -- put the group definition into the $AuthUser array (in config.php):%0a%0a $AuthUser['@editors'] = array('alice', 'carol', 'bob');%0a%0aQ: I'm running multiple wikis under the same domain name, and logins from one wiki are appearing on other wikis. Shouldn't they be independent?%0a%0aA: This is caused by the way that PHP treats sessions. See [[PmWiki.AuthUser#sessions]] for more details.%0a%0a%0aQ: Is there any way to record the time of the last login for each user when using AuthUser? I need a way to look for stale accounts.%0a%0aA: See [[Cookbook:UserLastAction]].%0a%0aQ: Though every settings seem correct, authentication against LDAP is not working, and there is nothing in ldap log. What's wrong ?%0a%0aA: Be sure ldap php module is installed ( on debian apt-get install php(4|5)-ldap ; apache(2)ctl graceful )%0a%0a%0aQ: The login form asks for username and password, but only password matters. %0a-> Username can be left blank and it still signs in under the account. Is this intentional and if so, can I change it so that the username and password must both be entered? - X 1/18/07 Never mind I think this has something to do with using the admin password. I created a test account and it's working ok.%0a%0aA: Make sure you are not entering the admin password when testing the account because, if the password is equal to the admin password, it will authenticate directly through the config.php file and skip any other system.%0a%0aA: Do note that even with AuthUser activated you can still log in with a blank username and only entering the password. In that case any password you enter will be "accepted" but only passwords which authenticate in the given context will actually give you any authorization rights. Using this capability AuthUser comfortably coexists with the default password-based system.%0a%0aIf you want to require both username and password, then you need to set an admin id '''before''' including authuser.php:%0a%0a[@%0a## Define usernames and passwords.%0a$AuthUser['carol'] = '$1$CknC8zAs$dC8z2vu3UvnIXMfOcGDON0';%0a%0a## Enable authentication based on username.%0ainclude_once('scripts/authuser.php');%0a%0a# $DefaultPasswords['admin'] = crypt('secret');%0a$DefaultPasswords['admin'] = 'id:carol';%0a@]%0a%0aA username and password will then be required before login is successful.%0a%0aQ: Is there any way to hide IP addresses once someone has logged in so that registered users can keep their IP addresses invisible to everyone except administrators? - X 1/18/07%0a%0aA: Not yet.%0a%0a%0aQ: Is there a way that people could self-register through AuthUser? %0a%0aA: You can see [[Cookbook:AuthUserSignup]] for a recipe about this problem. %0a%0aQ: I would like it that after I have AuthUser turned and a user is authenticated to get on my site, that if I have a password put on a particular page or group that they don't get the AuthUser form to show up (username and password), but only the typical field for password?%0a%0aA: See [[this thread of the mailing list -> http://article.gmane.org/gmane.comp.web.wiki.pmwiki.user/52420]].%0a
+time=1246997357
diff --git a/wikilib.d/PmWiki.AvailableActions b/wikilib.d/PmWiki.AvailableActions
new file mode 100644
index 0000000..1f73666
--- /dev/null
+++ b/wikilib.d/PmWiki.AvailableActions
@@ -0,0 +1,11 @@
+version=pmwiki-2.2.7 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/532.0 (KHTML, like Gecko) Chrome/3.0.195.32 Safari/532.0
+author=simon
+charset=ISO-8859-1
+csum=add link
+host=203.97.214.12
+name=PmWiki.AvailableActions
+rev=109
+targets=PmWiki.Security,PmWiki.Passwords,PmWiki.PageHistory,PmWiki.BasicEditing,Site.AuthForm,PmWiki.RefCount,PmWiki.Search,PmWiki.WebFeeds,PmWiki.SitePreferences,PmWiki.Uploads,PmWiki.CustomMarkup,PmWiki.UrlApprovals,PmWiki.WikiFarms
+text=(:Summary: All PmWiki page actions (?action=):)%0a(:div class="rfloat frame" style="font-size:smaller; clear:right;" :)%0a!!!! Table of contents%0a* [[#defaultactions| Default actions]]%0a* [[#enablediag| Enable diag actions]]%0a* [[#scriptactions | Script actions]]%0a* [[#cookbook | Cookbook actions]]%0a(:divend:)%0a%0aPage actions are applied to wiki pages, as a [[Wikipedia:Query_string|query string]] appended to the [[Wikipedia:Uniform_Resource_Locator|URL]].%0a[[Security]] can be applied to all [[#defaultactions|default actions]], and [[#scriptactions|script actions]] with one exception, but not [[#enablediag|diag actions]], through the use of [[passwords]].%0a%0a[[#defaultactions]]%0a!! Default Actions%0a%0a[[#attr]]%0a:?action='''attr''': displays dialog for setting/changing password of the specified page or group of pages, see [[PmWiki/passwords]], see also $EnablePostAttrClearSession if you do not want to have the session cleared after validating change [- {PmWiki/Passwords$:Summary} -]%0a%0a[[#browse]]%0a:?action='''browse''': display the specified page (default action if no [@?action=@] is present)%0a%0a[[#crypt]]%0a:?action='''crypt''': displays a form for generating hashed [[Passwords | passwords]] out of clear text for usage in your config.php%0a%0a[[#diff]]%0a:?action='''diff''': show a change history of the specified page, see [[PmWiki/page history]] [- {PmWiki/PageHistory$:Summary} -]%0a%0a[[#download]]%0a:?action='''download'''&upname=''file.ext'': retrieve the page's attachment named ''file.ext'', see $EnableDirectDownload%0a%0a[[#edit]]%0a:?action='''edit''': edit the specified page, see [[PmWiki/basic editing]] [- {PmWiki/BasicEditing$:Summary} -]%0a%0a[[#login]]%0a:?action='''login''': prompt visitor for username/password, by default using [[Site.AuthForm]]%0a%0a[[#logout]]%0a:?action='''logout''': remove author, password, and login information%0a%0a[[#print]]%0a:?action='''print''': display the specified page using the skin specified by $ActionSkin['print']%0a%0a[[#refcount]]%0a:?action='''refcount''': bring up the reference count form, which allows the user to generate a list of links (all, missing, existing or orphaned) in or from specified groups. See [[Ref Count]] [- {PmWiki/RefCount$:Summary} -]. Part of the core distribution but must be enabled by the administrator.%0a%0a[[#search]]%0a:?action='''search''': displays searchbox on current page, see [[PmWiki/search]] [- {PmWiki/Search$:Summary} -]%0a%0a:?action='''search'''&q=''searchterm'': performs search with ''searchterm'' and displays results on current page%0a%0a[[#source]]%0a:?action='''source''': show page source%0a%0a[[#feed]]%0a:?action='''atom''':%0a:?action='''rdf''':%0a:?action='''rss''':%0a:?action='''dc''': If [[web feeds]] are enabled, returns a syndication feed based on the contents of the page or other options provided by the url, see [[PmWiki/web feeds]] [- {PmWiki/WebFeeds$:Summary} -]%0a%0a[[#setprefs]]%0a:?'''setprefs'''=SomeGroup.CustomPreferences: sets cookie to custom preferences page. See [[PmWiki/site preferences]] [- {PmWiki/SitePreferences$:Summary} -]%0a%0a[[#upload]]%0a:?action='''upload''': display a form to upload an attachment for the current group, see [[PmWiki/uploads]] [- {Cookbook/Uploads$:Summary} -]%0a[[#defaultactionsend]]%0a----%0a[[#enablediag]]%0a!! Actions enabled by $EnableDiag%0a[[#BEGENABLEDIAG]]%0aThe following actions are available only if you set @@$EnableDiag = 1;@@ in your configuration file. They can be used for debugging and should not be set in a production environment.%0a%0a:?action='''ruleset''': displays a list of all markups in 3 columns:%0a** column 1 = markup-name (1. parameter of markup() )%0a** column 2 = when will rule apply (2. parameter of markup() )%0a** column 3 = PmWiki's internal sort key (derived from #2)%0a->(see [[Custom Markup]] [- {PmWiki/CustomMarkup$:Summary} -]).%0a->To see more than what [@?action=ruleset@] gives you, apply the [[Cookbook:MarkupRulesetDebugging]] recipe: it can also show the pattern and the replacement strings.%0a** doesn't make use of PmWiki's authorization mechanisms.%0a%0a[[#phpinfo]]%0a:?action='''phpinfo''': displays the output of phpinfo() and exits. no page will be processed%0a** doesn't make use of PmWiki's authorization mechanisms.%0a%0a[[#diag]]%0a:?action='''diag''': displays a dump of all global vars and exits. no page will be processed%0a** doesn't make use of PmWiki's authorization mechanisms.%0a%0a[[#ENDENABLEDIAG]]%0a----%0a[[#scriptactions]]%0a!! Actions enabled by PmWiki Scripts%0a%0a[[#analyse]]%0a:?action='''analyze''': see [[(PmWiki:)Site Analyzer]] and [[(PmWiki:)Analyze Results]]%0a%0a[[#approvesites]]%0a:?action='''approvesites''': see [[PmWiki/Url approvals]] [- {PmWiki/UrlApprovals$:Summary} -]%0a** doesn't make use of PmWiki's authorization mechanisms.%0a%0a[[#analyseend]]%0a----%0a[[#cookbook]]%0a!! Actions enabled by [[Cookbook(:.)]] recipes%0a(more information about [[(PmWiki:)Custom Actions]])%0a%0a:?action='''admin''': see [[Cookbook:UserAuth2]] [- {Cookbook/UserAuth2$:Summary} -]%0a%0a:?action='''backup''': see [[Cookbook:BackupPages]] [- {Cookbook/BackupPages$:Summary} -]%0a%0a:?action='''clearsky''': see [[Cookbook:SearchCloud]] [- {Cookbook/SearchCloud$:Summary} -]%0a%0a:?action='''comment''': see [[Cookbook:CommentBox]] [- {Cookbook/CommentBox$:Summary} -]%0a%0a:?action='''comments''': see [[Cookbook:Comments]] [- {Cookbook/Comments$:Summary} -]%0a%0a:?action='''comment-rss''': see [[Cookbook:CommentDb]] [- {Cookbook/CommentDb$:Summary} -]%0a%0a:?action='''convert''': see [[Cookbook:ROEPatterns]] [- {Cookbook/ROEPatterns$:Summary} -]%0a%0a:?action='''converttable''': [[Cookbook:ConvertTable]] [- {Cookbook/ConvertTable$:Summary} -]%0a%0a:?action='''copy''': see [[Cookbook:MovePage]] [- {Cookbook/MovePage$:Summary} -]%0a%0a:?action='''downloaddeleted''':%0a:?action='''delattach''':%0a:?action='''undelattach''': [[Cookbook:Attachtable]] [- {Cookbook/Attachtable$:Summary} -]%0a%0a:?action='''delete''': see [[Cookbook:DeleteAction]] [- {Cookbook/DeleteAction$:Summary} -]%0a%0a:?action='''discuss''': see [[Cookbook:DiscussionTab]] [- {Cookbook/DiscussionTab$:Summary} -]%0a%0a:?action='''downloadman''': see [[Cookbook:DownloadManager]] [- {Cookbook/DownloadManager$:Summary} -]%0a%0a:?action='''expirediff''': see [[Cookbook:ExpireDiff]] [- {Cookbook/ExpireDiff$:Summary} -]%0a%0a:?action='''import''': see [[Cookbook:ImportText]] [- {Cookbook/ImportText$:Summary} -]%0a%0a:?action='''move''': see [[Cookbook:MovePage]] [- {Cookbook/MovePage$:Summary} -]%0a%0a:?action='''PageUrl''': see [[Cookbook:CommentBoxPlus]] [- {Cookbook/CommentBoxPlus$:Summary} -]%0a%0a:?action='''pageindex''': see [[Cookbook:ListCategories]] [- {Cookbook/ListCategories$:Summary} -]%0a%0a:?action='''pdf''': see [[Cookbook:GeneratePDF]] [- {Cookbook/GeneratePDF$:Summary} -] or [[Cookbook:PmWiki2PDF]] [- {Cookbook/PmWiki2PDF$:Summary} -]%0a%0a:?action='''publish''': see [[Cookbook:PublishPDF]] [- {Cookbook/PublishPDF$:Summary} -]%0a%0a:?action='''purgeqns''': see [[Cookbook:ASCIIMath]] [- {Cookbook/ASCIIMath$:Summary} -]%0a%0a:?action='''pwchange''': see [[Cookbook:UserAuth2]] [- {Cookbook/UserAuth2$:Summary} -]%0a%0a:?action='''imgtpl''': (the ''imgtpl'' action is called automatically and should not be called by a link in a wiki page)%0a:?action='''createthumb''': (the ''createthumb'' action is called automatically and should not be called by a link in a wiki page)%0a:?action='''mini''': (this action is called automatically and should not be called by a link in a wiki page)%0a:?action='''purgethumbs''': see [[Cookbook:ThumbList]] [- {Cookbook/ThumbList$:Summary} -] \\%0a see [[Cookbook:Mini]] [- {Cookbook/Mini$:Summary} -]%0a%0a:?action='''recipecheck''': see [[Cookbook:RecipeCheck]] [- {Cookbook/RecipeCheck$:Summary} -]%0a%0a:?action='''regen''': see [[Cookbook:PageRegenerate]] [- {Cookbook/PageRegenerate$:Summary} -]%0a%0a:?action='''rename''':%0a:?action='''links''': see [[Cookbook:RenamePage]] [- {Cookbook/RenamePage$:Summary} -]%0a%0a:?action='''share''':%0a:?action='''unshare''': see [[Cookbook:SharedPages]] [- {Cookbook/SharedPages$:Summary} -]%0a%0a:?action='''sitemapaddgroups''':%0a:?action='''sitemapupdate''': see [[Cookbook:Sitemapper]] [- {Cookbook/Sitemapper$:Summary} -]%0a%0a:?action='''totalcounter''': see [[Cookbook:TotalCounter]] [- {Cookbook/TotalCounter$:Summary} -]%0a%0a:?action='''trash''':%0a:?action='''untrash''': see [[Cookbook:Trash]] [- {Cookbook/Trash$:Summary} -]%0a%0a:?action='''webadmin''': see [[Cookbook:WebAdmin]] [- {Cookbook/WebAdmin$:Summary} -]%0a%0a:?action='''zap''': see [[Cookbook:ZAP]] [- {Cookbook/ZAP$:Summary} -]%0a[[#cookbookend]]%0a%0a
+time=1258048543
diff --git a/wikilib.d/PmWiki.BackupAndRestore b/wikilib.d/PmWiki.BackupAndRestore
new file mode 100644
index 0000000..248035e
--- /dev/null
+++ b/wikilib.d/PmWiki.BackupAndRestore
@@ -0,0 +1,13 @@
+version=pmwiki-2.2.1 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.19) Gecko/20081216 Ubuntu/8.04 (hardy) Firefox/2.0.0.19
+author=Petko
+charset=ISO-8859-1
+csum=enabled links
+ctime=1134693395
+host=81.65.14.164
+name=PmWiki.BackupAndRestore
+rev=30
+targets=PmWiki.Uploads
+text=(:title Backup and Restore:)%0a(:Summary:background information and some basic backup and restore procedures:)%0a%0aThis page has some background information on making backups and explains some basic *nix backup and restore procedures.%0a%0a!! Introduction%0a%0aYour wiki installation contains some unique data in the following directories:%0a%0a local/ Local configuration scripts%0a cookbook/ Recipes obtained from the [[(Cookbook:)Cookbook]]%0a pub/ Publicly accessible files%0a wiki.d/ Wiki pages%0a uploads/ [[Uploads|Uploaded files]] (attachments)%0a%0aA good backup plan will include periodically archiving these directories — or at bare minimum [@local/@] and [@wiki.d/@]. Good practice dictates keeping your backup archives on a separate machine.%0a%0a!! Simple Backup and Restore (*nix)%0a%0aWhen it comes to backup, simpler is better. %0aSince the pmwiki distribution is very small (about 1/4 megabyte), it's simplest to just archive the distribution files along with the data.%0a%0a!!! Making a Backup Archive%0a%0aThe following *nix command, executed from the parent directory of your wiki's directory, will put a complete backup archive of your site in your home directory.%0a%0a-> [@%0atar -zcvf ~/wiki-backup-`date +%25Y%25m`.tar.gz wiki/%0a@]%0a%0a[[#restore]]%0a!!! Restoring the Backup Archive%0a%0a!!!! Simple Method%0a%0aYour site can be restored and running in under 30 seconds with%0a%0a-> [@%0atar -zxvf ~/wiki-backup-200512.tar.gz%0afind wiki/uploads/ -type d |xargs chmod 777%0afind wiki/wiki.d/ -type d |xargs chmod 777%0a@]%0a%0a!!!! A Slightly-More-Secure Method%0a%0aThe simple restore commands above will give you world-writable files and directories. You can avoid world-writable permissions by letting PmWiki create directories with the proper attributes (ownership and permissions) for you.%0a%0aStart with%0a%0a-> [@%0atar -zxvf ~/wiki-backup-200512.tar.gz%0arm -rf wiki/wiki.d%0arm -rf uploads%0achmod 2777 wiki/%0a@]%0a%0aNow upload a file in each group that had uploads. If your site doesn't have uploads, just visit your site once so the wiki.d/ directory will be created.%0a%0aFinish your installation with%0a%0a-> [@%0achmod 755 wiki/%0atar -zxvf ~/wiki-backup-200512.tar.gz%0a@]%0a%0a%0a!!! Details%0a%0aThe commands on this page assume your site is in a directory called "wiki/". The test backup was made in December, 2005 so it's named accordingly.%0a%0aYour site will only have an uploads/ directory if uploads are enabled.%0a%0aThe backup command uses a date stamp (YYYYMM) in the filename. If you automate the command via cron you'll wind up with monthly snapshots of your site. You can get a daily snapshot by appending %25d to the date command ([@`date +%25Y%25m%25d`@] will get you YYYYMMDD). Be wary of space limitations if you have a large uploads/ directory.%0a%0a%0a!! See Also%0a%0a* A [[http://thread.gmane.org/gmane.comp.web.wiki.pmwiki.user/20317| thread]] [gmane.org] on the pmwiki-users mailing list.%0a* A [[(Cookbook:)Backup Pages]] recipe in the cookbook.%0a%0a!! Miscellaneous%0a%0a%0a!! Backup via FTP%0aDownload and install a ftp client like [[http://filezilla-project.org/download.php?type=client|Filezilla]]%0a%0a# Using the ftp client connect to the server where you host pmWiki using%0a## the IP address (ex: 123.234.56.67) or the ftp name (ex: ftp.myhost.com)%0a## supply your account name (ex: mylogin) and password (ex: myp4ssw0rd)%0a# Move to your pmWiki directory (ex: @@/usr/mylogin/web/wiki/@@ or @@/tahi/public_html/pmwiki@@ )%0a# Select the folder you want to backup as explained before (probably either only the data or the whole wiki directory)%0a** for data you will want to backup both the directories%0a*** @@wiki.d@@ for user page data%0a*** @@pmwikiuploads@@ (or @@uploads@@) for your attachments (uploads)%0a** for system you will want, at a minimum, to backup both the directories%0a*** @@local@@ for configuration data %0a*** @@pub@@ for local CSS and skins customisations%0a# Download them to a local folder%0a# Use [[http://www.7-zip.org/ | 7zip]] or a similar software to build an archive of this backup%0a%0aYou can also very easily sync your FTP directories with your hard disc via this command line:%0a-> [@ wget -nv -np -m ftp://user:password@ftp.yourhost.net/ @]%0a'-Download [[http://gnuwin32.sourceforge.net/packages/wget.htm | Wget for Windows]] (other systems normally have it installed).-'%0a
+time=1241736520
+title=Backup and Restore
diff --git a/wikilib.d/PmWiki.BasicEditing b/wikilib.d/PmWiki.BasicEditing
new file mode 100644
index 0000000..6fe3fd5
--- /dev/null
+++ b/wikilib.d/PmWiki.BasicEditing
@@ -0,0 +1,13 @@
+version=pmwiki-2.2.7 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_2; en-us) AppleWebKit/531.21.8 (KHTML, like Gecko) Version/4.0.4 Safari/531.21.10
+author=Victor
+charset=ISO-8859-1
+csum=
+description=PmWiki's basic edit syntax
+host=74.72.193.67
+name=PmWiki.BasicEditing
+rev=432
+targets=PmWiki.WikiSandbox,Main.WikiSandbox,PmWiki.WikiWikiWeb,PmWiki.Passwords,PmWiki.TextFormattingRules,PmWiki.MarkupMasterIndex,PmWiki.WikiStyles,PmWiki.WikiGroup,PmWiki.InterMap,PmWiki.NonexistentPages,PmWiki.Links,PmWiki.Tables,PmWiki.TableDirectives,PmWiki.Images,PmWiki.PageLists,PmWiki.BasicEditing,PmWiki.WikiTrails,PmWiki.DocumentationIndex,PmWiki.SpecialCharacters,PmWiki.PmWikiPhilosophy,PmWiki.Audiences
+text=(:Summary: PmWiki's basic edit syntax:)(:Audience: authors (basic) :)%0aThe pages on this site are [[Wiki Wiki Web]] pages, which means that pages can be created and edited by multiple authors. To edit a page, click the '''Edit''' link that exists '''somewhere''' on the page, usually in the header or footer. Some pages may be [[password(s)]]-protected, depending on the system's security policies, but many systems allow open editing of pages.%0a%0aPmWiki is not [[(Wikipedia:)WYSIWYG]] - When editing a page, you see the ''markup text'' that describes the content of the page. The basic rules for page markup are simple:%0a# Use a blank line to start a new paragraph [-[[#Paragraphs|more]]-].%0a# To make a list, start each line with # for numbered (ordered) lists or * for bulleted (unordered) lists [-[[#lists|more]]-].%0a# To make a heading, start a line with two or more ! marks; !! is a subheading, and !!! is a sub-subheading [-[[#headings|more]]-].%0a# To emphasize text, enclose it in 2 or 3 ''single quotes''; [@''text''@] for italics or [@'''text'''@] for bold [-[[#emphasis|more]]-].%0a# To make a link to another page, enclose the page's name in double brackets; for example [@[[basic editing]]@] links to this page [-[[#links|more]]-].%0a# To make a link to another site, type its address, such as http://example.com/ [- [[#links|more]]-].%0a%0a'''If you want to experiment with editing a page, try it on the [[Main/Wiki Sandbox]].''' You can [[Main/WikiSandbox?action=edit | edit the Wiki Sandbox]] without affecting anything important on this site. On talk pages and discussions, it's courteous to '''sign''' your contribution; using [=~~=]~ effectively 'signs' the name that you provide in the Author field on the Page Edit form.%0a%0a!! Examples of common markups%0a%0aThe tables below demonstrate many of the common markups used to format pages. The left column shows what to write to achieve the effect, the right column shows the effect of the markup. More details are available from the [[text formatting rules]] and other documentation pages. An exhaustive list of default markup is available as the [[markup master index]].%0a%0a!!! [[#Paragraphs]]Paragraphs and line breaks%0a[[#markupheaders]]%0a(:table class='markup horiz' align='center':)%0a(:cellnr class='markup1':)%0a[-'''What to type'''-]%0a(:cell class='markup2':)%0a[-'''What it looks like'''-]%0a(:tableend:)%0a[[#markupheadersend]]%0a%0a(:markup class=horiz:)%0aConsecutive lines%0awill be merged together%0aas part of the same paragraph.%0a%0aOne or more empty lines will start a new paragraph.%0a(:markupend:)%0a%0a(:markup class=horiz:)%0aTwo backslashes at the end of a line \\%0aforce a line break.%0a%0aOr use this markup: [[%3c%3c]] to force a break.%0a(:markupend:)%0aFurther reading:%0a* [[text formatting rules]] for more information on linebreaks, indented or hanging paragraphs.%0a* [[wiki styles]] for centered or right justified paragraphs and "floating" text (boxes), borders and much more.%0a%0a!!![[#lists]]Lists%0aStart each line with # for numbered (ordered) lists or * for bulleted (unordered) lists:%0a(:markup class=horiz:)%0a* Bullet list%0a* Another item%0a** More asterisks produce sub-items%0a** etc.%0a(:markupend:)%0a%0a(:markup class=horiz:)%0a# Numbered lists%0a# Another item%0a## more hashes produce sub-items%0a(:markupend:)%0a%0a(:markup class=horiz:)%0a# List types%0a# can be mixed%0a** numbered list with unordered sub-list%0a(:markupend:)%0a%0a(:if false:)%0aif someone thinks definition lists are "basic":%0a(:markup class=horiz:)%0a: Definition list : list of definitions%0a: item : the item's definition%0a: another item : that item's definition%0a:: indentation : more leading colons produce deeper lists%0a(:markupend:)%0a(:ifend:)%0a%0aLearn more about [[Text Formatting Rules#BulletedLists|lists]] (including [[Text Formatting Rules#DefinitionLists|definition lists]]) and [[(PmWiki:)list styles]].%0a%0a!!![[#headings]] Headings%0aHeadings are useful for creating a "well-structured" page. They're not just for making big text.%0a%0a(:include {$FullName}#markupheaders#markupheadersend:)%0a%0a(:markup class=horiz:)%0a!! Major Subheading%0a!!! Minor Subheading%0a!!!! And More%0a!!!!! Subheadings%0a(:markupend:)%0a%0a!!![[#emphasis]] Text Emphasis%0aTo emphasize, enclose text in apostrophes (single-quote marks), not double-quotes.%0a%0a(:include {$FullName}#markupheaders#markupheadersend:)%0a%0a(:markup class=horiz:)%0a''Emphasize'' (italics),%0a'''strong''' (bold), %0a'''''very strong''''' (bold italics).%0a(:markupend:)%0a%0a!!![[#links]] Links%0aTo make a link to another page, enclose the page's name in double square brackets.%0a%0a(:include {$FullName}#markupheaders#markupheadersend:)%0a%0a(:markup class=horiz:)%0aPractice editing in the [[wiki sandbox]]%0a(:markupend:)%0aNote that words are automatically ''capitalized'' in page titles. The link above links to the page WikiSandbox.%0a%0aText after a pipe (|) is used as the link text:%0a(:markup class=horiz:)%0aPractice editing in the%0a[[WikiSandbox | practice area]].%0a(:markupend:)%0a%0a(:comment is this still "basic" or should it be removed? :)%0aEndings become part of the link text, parentheses hide parts of the link name:%0a(:markup class=horiz:)%0a[[wiki sandbox]]es.%0a%0a[[(wiki) sandbox]].%0a(:markupend:)%0a%0aWhen linking to a page in a different [[WikiGroup]], provide the group name, followed by a separator, and then the page name:%0a(:markup class=horiz:)%0a[[Main.Wiki Sandbox]] shows group + name%0a%0a[[Main/Wiki Sandbox]] shows only name%0a(:markupend:)%0a%0aLinks to external sites%0a(:markup class=horiz:)%0abare url: http://www.pmwiki.org%0a%0alink text: [[http://www.pmwiki.org | PmWiki home]]%0a(:markupend:)%0a%0a(:comment is this still "basic" or should it be removed? :)%0aColons make [[InterMap]] (also called InterWiki) links to other wikis:%0a(:markup class=horiz:)%0aWhat's an [[Wikipedia:aardvark]], anyway?%0a(:markupend:)%0a%0aLinks to [[nonexistent pages]] are displayed specially, to invite others to create the page.%0a%0aPmWiki supports more link types and a lot of display options, see [[Links]] to learn more.%0a%0a%0a!!!Preformatted text%0aPreformatted text is displayed using a monospace font and not generating linebreaks except where explicitly indicated in the markup.%0a%0aNote that very long lines of preformatted text can cause the whole page to be wide.%0a%0aFor preformatted text with markup (e.g. emphasis) being processed, start each line with a space:%0a(:markup class=horiz:)%0a Lines that begin with a space%0a are formatted exactly as typed%0a in a '''fixed-width''' font.%0a(:markupend:)%0a%0aIf you don't want Wiki markup to be processed, use [=[@ @]=]. Can also be used inline.%0a(:markup class=horiz:)%0a[@%0aText escaped this way has%0athe HTML ''code'' style%0a@]%0a(:markupend:)%0a%0a!!! Escape sequence%0aIf you don't want Wiki markup to be processed, but lines reformatted use [@[= =]@]. Can also be used inline.%0a(:markup class=horiz:)%0a[=%0amarkup is ''not'' processed%0abut lines are reformatted%0a=]%0a(:markupend:)%0a%0a%0a!!! Horizontal line%0a(:markup class=horiz:)%0aFour or more dashes at%0athe beginning of a line%0a----%0aproduce a "horizontal rule"%0a(:markupend:)%0a%0a!!! Tables%0aSimple tables use double pipe characters to separate cells:%0a(:markup class=horiz:)%0a|| border=1%0a||! head 1 ||! head 2 ||! head 3 ||%0a|| cell 1 || cell 2 || cell 3 ||%0a(:markupend:)%0aSee [[Tables|simple tables]] and [[Table Directives|advanced tables]] to learn more about the rich feature set of PmWiki tables.%0a%0a!!! Images%0aSee [[Images]]%0a%0a(:if false:)%0aIMO this is not "basic" and should be removed from this page --OliverBetz%0a!!!Indented and "hanging" paragraphs%0a(:markup class=horiz:)%0a-> An arrow (->) indents content.%0a%0a Line up text to continue the indent.%0a%0a-->Longer arrows (-->) indent further.%0a%0a-%3cA reverse arrow (-%3c) creates a hanging indent, the first line is outdented and remaining lines are indented.%0a(:markupend:)%0a(:ifend:)%0a%0a!!! Character formatting%0a%0a(:include {$FullName}#markupheaders#markupheadersend:)%0a%0a(:markup class=horiz:)%0a* @@Monospaced text@@%0a* Text with '^superscripts^'%0a* Text with '_subscripts_'%0a* deleted {-strikethrough-} text%0a* inserted {+underline+} text%0a* [+big+], [++bigger++] text%0a* [-small-], [--smaller--] text%0a(:markupend:)%0a%0aUse [[WikiStyles]] to change %25red%25 the %25blue%25 text %25green%25 %25color=#ff7f00%25 color %25%25.%0a%0a[[#pagetitles]]%0a!!! Page titles%0aThe [@(:title:)@] directive sets the page's title to something other than its page name.%0a(:markup class=horiz:)%0a(:Title Basic PmWiki editing rules:)%0aThe name of this page is "{$Name}", and its title is "{$Title}".%0a(:markupend:)%0a%0a[[#pagesummary]]%0a!!! Page Description%0a%0a* The [@(:Description Page summary here:)@] directive sets the page description. The description is used by search engines, and can displayed in search results and in [[page lists]].%0a(:markup class=horiz:)%0a(:Description PmWiki's basic edit syntax:)%0aThe summary description of this page is {$Description}.%0a(:markupend:)%0a%0a%0a%0a>>faq%3c%3c [[#faq]]%0a[[#beginning]]%0aQ: I'm new to PmWiki, where can I find some basic help for getting started?%0aA: The [[Basic Editing]] page is a good start. From there, you can just follow the navigational links at the top or the bottom of the page (they are called [[Wiki Trails]]) to the next pages, or to the [[Documentation Index]] page, which provides an outline style index of essential documentation pages, organized from basic to advanced.%0a%0aQ: How do I include special characters such as Copyright (©) and Trademark (® or ™) on my wiki pages?%0aA: See [[special characters]] on how to insert special characters that don't appear on your keyboard.%0a%0aQ: Why are separate lines of text in the markup combined into a single line on output?%0aA: PmWiki normally treats consecutive lines of text as being a paragraph, and merges and wraps lines together on output. This is consistent with most other wiki packages. An author can use the [@(:linebreaks:)@] directive to cause separate lines of markup text to be kept as separate lines in the output. Or a wiki administrator can set in ''config.php'' @@$HTMLPNewline = '%3cbr/>';@@ to force literal new lines for the whole site.%0a%0aQ: Can I just enter HTML directly?%0aA: By default (and by design), PmWiki does not support the use of HTML elements in the editable markup for wiki pages. There are a number of reasons for this described in the [[PmWiki Philosophy]] and [[Audiences]]. Enabling HTML markup within wiki pages in a collaborative environment may exclude some potential authors from being able to edit pages, and pose a number of display and security issues. However, a site administrator can use the [[Cookbook:Enable HTML]] recipe to enable the use of HTML markup directly in pages.%0a%0aQ: Where can I find more documentation?%0aA: See the [[Documentation Index | documentation index]] and the [[markup master index]] pages.%0a
+time=1260040652
+title=Basic PmWiki editing rules
diff --git a/wikilib.d/PmWiki.BasicVariables b/wikilib.d/PmWiki.BasicVariables
new file mode 100644
index 0000000..96fcdeb
--- /dev/null
+++ b/wikilib.d/PmWiki.BasicVariables
@@ -0,0 +1,11 @@
+version=pmwiki-2.2.10 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.7) Gecko/20100106 Ubuntu/9.10 (karmic) Firefox/3.5.7
+author=Petko
+charset=ISO-8859-1
+csum=Update documentation EnableRelativePageVars
+host=86.69.109.228
+name=PmWiki.BasicVariables
+rev=87
+targets=PmWiki.AuthoringPhilosophy,PmWiki.AuthUser,PmWiki.Categories,PmWiki.WikiFarms,PmWiki.WikiGroup,PmWiki.GroupCustomizations,PmWiki.LocalCustomizations,PmWiki.WikiWord,PmWiki.MarkupExpressions,Cookbook.LimitWikiGroups,Site.Search,Site.EditForm,Site.PageNotFound,SiteAdmin.AuthList,SiteAdmin.AuthUser,SiteAdmin.ApprovedUrls,PmWiki.PageVariables
+text=(:Summary: core variables:)%0a%0aWhere the variables are available as wiki markup they are shown as ''Variable value "[={$=]VariableName}"''.%0a%0a:$AsSpacedFunction:The name of the function used to convert WikiWords into normal, spaced strings. Defaults to 'AsSpaced'.%0a:{$AsSpacedFunction} :[@$AsSpacedFunction = 'MyAsSpaced';@]%0a%0a%25rfloat%25Variable value "{$Author}"%0a:$Author [==]: Set to the current reader, who is potentially an author ([[PmWiki:AuthoringPhilosophy|see discussion]]). See also $EnablePostAuthorRequired.%0a%0a(:if ! equal '{$AuthorGroup}' '':)%25rfloat%25Variable value "{$AuthorGroup}"(:ifend:)%0a:$AuthorGroup: The WikiGroup for user profiles. Defaults to 'Profiles'. This variable is implicit in the markup [@[[~AuthorName]]@]%0a: :[@$AuthorGroup = 'Users';@]%0a%0a(:if ! equal '{$AuthId}' '':)%25rfloat%25Variable value "{$AuthId}"(:ifend:)%0a:$AuthId: For sites using [[AuthUser | user-based authorization]], tracks the "reader" or login name.%0a: :[@SessionAuth($pagename);@]%0a: :[@if( isset($AuthId) ) { // this person has been authenticated@]%0a%0a(:if ! equal '{$AuthPw}' '':)%0a%25rfloat%25Variable value "{$AuthPw}"%0a(:ifend:)%0a:$AuthPw: Request for documentation, meanwhile see [[http://permalink.gmane.org/gmane.comp.web.wiki.pmwiki.user/30037|here]].%0a: :[@SessionAuth($pagename);@]%0a: :[@if( isset($AuthPw) ) { // this person has entered a password@] %0a%0a%25rfloat%25Variable value "{$BaseName}"%0a:$BaseName:%0a:$BaseNamePatterns:Allows population of the [@{$BaseName}@] PageVariable. The key to the hash is the pattern to be replaced and the value is the replacement string.%0a: :[@%0a# If {$FullName} is 'Group.Page-Draft' then {$BaseName} is 'Group.Page'%0a$BaseNamePatterns['/-Draft$/'] = '';%0a# If {$FullName} is 'Comments-Group.Page' then {$BaseName} is 'Group.Page'%0a$BaseNamePatterns['/^Comments-/'] = '';@]%0a%0a(:if ! equal '{$CategoryGroup}' '':)%0a%25rfloat%25Variable value "{$CategoryGroup}"%0a(:ifend:)%0a:$CategoryGroup: The WikiGroup used for categories. Defaults to 'Category'. (See [[Categories]]). This variable is implicit in the markup [@[[!CategoryName]]@]%0a%0a(:if ! equal '{$CookiePrefix}' '':)%0a%25rfloat%25Variable value "{$CookiePrefix}"%0a(:ifend:)%0a:$CookiePrefix: A string prefix to be prepended to cookies set from PmWiki scripts. It defaults to '', but can be set to a different value to avoid conflicts with similar-named cookies from other applications, or to allow multiple wikis from the same domain to store separate cookies.%0a: :[@$CookiePrefix = 'pmwiki_';@] # set cookie prefix to 'pmwiki_'%0a::If you have a [[WikiFarm(s)]], use the following in each field's ''config.php'' to get a unique prefix for each field in the farm, thus isolating each field's cookies.:%0a: :[@$CookiePrefix = substr($tmp = md5(__FILE__), 0, 5).'_';@]%0a%0a%25rfloat%25Variable value "{$DefaultGroup}"%0a:$DefaultGroup:[[WikiGroup]] used by default (on startup) when no group is specified in the URL. %0a%0a%25rfloat%25Variable value "{$DefaultName}"%0a:$DefaultName:Name of the default HomePage of each WikiGroup. Used when the group doesn't have a page with the same name as the group.%0a%0a(:if ! equal '{$DefaultPage}' '':)%0a%25rfloat%25Variable value "{$DefaultPage}"%0a(:ifend:)%0a:$DefaultPage:Startup page when PmWiki is called without a specified page, normally ''$DefaultGroup.$DefaultName''.%0a-> Note: for $DefaultGroup, $DefaultName and $DefaultPage variables to work, they should be defined in the beginning of (farm)config.php, before any call to the function ResolvePageName(). This means, before any script from PmWiki and before any recipe that might be using this function.%0a%0a(:if ! equal '{$EnableLocalConfig}' '':)%0a%25rfloat%25Variable value "{$EnableLocalConfig}"%0a(:ifend:)%0a:$EnableLocalConfig:Allows/disables local/config.php customizations (usually for a farm's wikis). Can be set to zero in local/farmconfig.php to prevent the farm's wikis' local/config.php from being loaded.%0a: :[@$EnableLocalConfig = 0; # disable PmWiki's local/config@]%0a%0a(:if ! equal '{$EnablePGCust}' '':)%0a%25rfloat%25Variable value "{$EnablePGCust}"%0a(:ifend:)%0a:$EnablePGCust:Allows/disables per-page and [[GroupCustomizations | per-group customizations]]. Can be set to zero in any [[local customization(s)]] file to prevent remaining page/group customizations from being loaded.%0a: :[@$EnablePGCust=0; # turn off per-page/group configs@]%0a%0a:$EnableRedirect:When enabled (default), causes page redirects to automatically be performed by the browser. Setting $EnableRedirect to zero causes PmWiki to pause and issue a "Redirect to ''link''" message instead. This is sometimes useful when debugging recipes to be able to see the results of actions before page redirections occur.%0a%0a(:if ! equal '{$EnableWikiWords}' '':)%0a%25rfloat%25Variable value "{$EnableWikiWords}"%0a(:ifend:)%0a:$EnableWikiWords:Enable [[WikiWord]] processing.%0a%0a:$EnableWSPre:Enables a markup rule that causes lines with leading spaces to be treated as sections of preformatted text. If set to a value greater than 1, indicates the minimum number of leading spaces required for this treatment.%0a: :[@$EnableWSPre = 1; # leading spaces are preformatted text@]%0a: :[@$EnableWSPre = 0; # leading spaces are normal lines of text@]%0a: :[@$EnableWSPre = 4; # 4+ spaces are preformatted text@]%0a%0a:$FTimeFmt:Can be used to override the default date format used by the "ftime" function. The default $FTimeFmt is $TimeFmt. (See [[Markup Expressions]])%0a%0a:$GroupPattern: The regular expression pattern used for valid [[WikiGroup]] name specifications. Defaults to allowing any group name beginning with an uppercase letter, but can be set to limit the valid group names (see Cookbook:LimitWikiGroups).%0a: :[@# limit groups to Site, SiteAdmin, PmWiki, and MyGroup@]%0a: :[@$GroupPattern = '(?:Site|SiteAdmin|PmWiki|MyGroup)';@]%0a: :[@#for case-sensitive group names, note the ?-i switch:@]%0a: :[@$GroupPattern = '(?-i:Site|SiteAdmin|PmWiki|MyGroup)';@]%0a%0a:$LinkWikiWords:If set, then bare WikiWords in a page are automatically linked to pages of the same name. Note that this value can also be affected by the [@(:linkwikiwords:)@] and [@(:nolinkwikiwords:)@] directives.%0a: :[@$LinkWikiWords = 1; # turn on WikiWord links@]%0a: :[@$LinkWikiWords = 0; # disable WikiWord links@]%0a%0a:$LogoutRedirectFmt: Identifies the page to which the visitor should be sent after an [@?action=logout@]. Defaults to the current page.%0a: :[@$LogoutRedirectFmt = 'Site.Logout'; # ?action=logout target@]%0a%0a:$LogoutCookies: An array of cookie names to be removed when [@?action=logout@] is invoked.%0a%0a(:if ! equal '{$NamePattern}' '':)%0a%25rfloat%25Variable value "{$NamePattern}"%0a(:ifend:)%0a:$NamePattern: The regular expression pattern used for valid page names. Defaults to allowing pages beginning with an uppercase letter or digit, followed by sequences of alphanumeric characters, hyphens, and underscores. %0a%0a%25rfloat%25Variable value "{$SiteGroup}"%0a:$SiteGroup:Default group for storing configuration and utility pages such as [[Site.Search]], [[Site.EditForm]], [[Site.PageNotFound]], etc.%0a%0a:$SiteAdminGroup:Default group for locked administrative pages such as [[SiteAdmin.AuthList]], [[SiteAdmin.AuthUser]], [[SiteAdmin.ApprovedUrls]], etc, defaults to 'SiteAdmin'.%0a%0a(:if ! equal '{$SpaceWikiWords}' '':)%0a%25rfloat%25Variable value "{$SpaceWikiWords}"%0a(:ifend:)%0a:$SpaceWikiWords:If set, then WikiWords in pages are automatically spaced according to $AsSpacedFunction. Note that this value can also be affected by the [@(:spacewikiwords:)@] and [@(:nospacewikiwords:)@] directives.%0a: :[@$SpaceWikiWords = 1; # turn on WikiWord spacing@]%0a: :[@$SpaceWikiWords = 0; # turn off WikiWord spacing@]%0a%0a(:if ! equal '{$TimeFmt}' '':)%0a%25rfloat%25Variable value "{$TimeFmt}"%0a(:ifend:)%0a:$TimeFmt: The format to use for dates and times, in [[http://php.net/strftime | strftime()]] format. The default value is [@'%25B %25d, %25Y at %25I:%25M %25p'@], which gives dates of the form "September 8, 2005 at 10:57 PM".%0a: :[@$TimeFmt = '%25B %25d, %25Y'; # dates as "September 8, 2005"@]%0a: :[@$TimeFmt = '%25Y-%25m-%25d'; # dates as "2005-09-08"@]%0a%0a%25rfloat%25Variable value "{$Version}"%0a:$Version: A string representing the release version of PmWiki.%0a%0a%25rfloat%25Variable value "{$VersionNum}"%0a:$VersionNum: A number representing the release version of PmWiki,%0a with the major and minor release components padded with zeroes to%0a produce three digits. Thus, release "pmwiki-2.1.40" will have $VersionNum set to 2001040.%0a%0a The first digit is a 2, the next three digits are the major%0a release number, and the last three digits are the minor release%0a number. Beta releases use 900-999 for the minor release number.%0a Thus:%0a--> [@%0a2.1.0 2001000%0a2.1.1 2001001%0a...%0a2.1.27 2001027%0a2.2.0-beta1 2001901%0a2.2.0-beta2 2001902%0a...%0a2.2.0-beta18 2001918%0a...%0a2.2.0 2002000%0a@]%0a%0a(:if ! equal '{$WikiWordPattern}' '':)%0a%25rfloat%25Variable value "{$WikiWordPattern}"%0a(:ifend:)%0a:$WikiWordPattern: The pattern that describes a WikiWord.%0a%0a:$EnableRelativePageVars:This setting controls how [[Page variables]] in included pages are understood by PmWiki.%0a: :@@$EnableRelativePageVars = 1; # PmWiki current default@@\\%0aIn this case @@[={$Name}=]@@ displays the name of the physical page where it written. If @@[={$Name}=]@@ is in an included page, it will display the name of the included page. (This is currently PmWiki's default.)%0a: :@@$EnableRelativePageVars = 0; # revert to previous default@@\\%0aIn this case @@[={$Name}=]@@ displays the name of the currently browsed page. Even if @@[={$Name}=]@@ is in an included page, it will display the name of the browsed page. This was PmWiki's default in versions 2.2.8 and earlier, and changed in 2.2.9, but you can revert it back with this line in config.php.%0a: : @@[={*$Name}=]@@ with an asterisk always displays the name of the currently browsed page, regardless of $EnableRelativePageVars.%0a
+time=1265886842
diff --git a/wikilib.d/PmWiki.Blocklist b/wikilib.d/PmWiki.Blocklist
new file mode 100644
index 0000000..9d3c148
--- /dev/null
+++ b/wikilib.d/PmWiki.Blocklist
@@ -0,0 +1,12 @@
+version=pmwiki-2.2.0 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.19) Gecko/20081216 Ubuntu/8.04 (hardy) Firefox/2.0.0.19
+author=Petko
+charset=ISO-8859-1
+csum=refactored, mv questions to talk page
+ctime=1159592216
+host=81.65.14.164
+name=PmWiki.Blocklist
+rev=54
+targets=PmWiki.Security,PmWiki.Passwords,PmWiki.PasswordsAdmin,SiteAdmin.Blocklist,PmWiki.PageHistory,PmWiki.WikiAdministrator,PmWiki.PageVariables
+text=(:Summary:Blocking IP addresses, phrases, and expressions to counteract spam and vandalism.:)%0a(:Audience: administrators (basic) :)%0a%0aThe block list is one of a number of [[security]] measures that can be taken to protect your wiki from unwelcome postings.%0a%0aUnfortunately, the open-editability of many wiki systems often makes them attractive targets for "link spam" or "wikispam", in which links are added to pages in an effort to increase search engine rankings or drive traffic to other sites. Also, many link spammers have developed automated systems to locate sites that accept visitor input and attempt to flood the site with unwanted links.%0aAlso, and harder to deal with, is just plain [[PmWiki/Security#wikivandalism|wiki vandalism]] where nonsense changes are made, often replacing entire pages.%0a%0aBy far the best countermeasure against wikispam is to restrict editing through the use of passwords (see [[Passwords]] and [[Passwords Admin]]). Experience has shown that passwords can be effective even if the password is widely known, and even if the password is publicly available on the site itself. However, there are many cases where passwording may be an impediment, so these will generally want to use some form of blocklist.%0a%0a!! Blocklist basics%0a%0aA ''blocklist'' is a list of IP addresses, phrases, and expressions which are prevented from being added into pages on the website. PmWiki is distributed with a built-in blocklisting capability; blocklists can be enabled by adding the following line to ''local/config.php'':%0a%0a-> $EnableBlocklist = 1;%0a%0aThis tells PmWiki to scan the [[SiteAdmin.Blocklist]] page and the "SiteAdmin.Blocklist-Farm" page (and possibly other pages -- see below) looking for phrases and IP addresses to be excluded from posting to the site.%0a%0a!!! Blocking by word or phrase%0aThe simplest form of block is simply a line containing "[@block:@]" followed by a word or phrase to be excluded from postings. For example, a line like %0a%0a-> [@block:spam.com @]%0a%0ain SiteAdmin.Blocklist will block any posts containing the string "spam.com" (case-insensitive) anywhere in the post.%0a%0a[[#blockbyipaddress]]%0a!!! Blocking by IP address%0aSometimes we wish to restrict posts coming from particular addresses or address ranges that are known as sources of wikispam. If a blocklist page contains IP addresses of the form "a.b.c.d" or "a.b.c.*", then any posts coming from that address or range will be blocked. %0a%0a-> %25note%25 To find an author's IP address, try hovering the mouse over the author name in the [[page history]] for a page.%0a%0a!!! Blocking by regular expression or pattern%0aBlocking on simple words can sometimes pose difficulties; for example, a simple "[@block:cial@]" entry will also block the word "specialist". For these cases it's often helpful to use a regular expression, as in:%0a%0a->[@block:/\bcial\b/@]%0a%0aThis says to block "cial" only if it doesn't occur in the middle of a larger word. The leading slash (/) after "block:" tells PmWiki to use a regular expression match instead of a simple string match. (Blocklist uses PCRE or "Perl Compatible Regular Expressions"; see http://php.net/manual/en/ref.pcre.php for more information.)%0a%0a!!!! Regular expression to block 'href'%0a%0aIf you want to block '@@href@@', you can use the following markup:%0a-> [@block:/[^\w\\]href\b/@]%0awhich blocks '@@href@@', but neither '@@\href@@' nor '@@toughref@@'.%0a%0aThe regular expression can be interpreted as follows: Match any character that is '''neither''' a word character%0a'''nor''' a '\', followed by @@href@@ which ends in a word boundary.%0a%0a!! Letting authors know why they've been blocked%0a%0aBy default, blocklist only tells an author that a particular edit has been blocked, but doesn't give a specific reason for the blocking (e.g., the offending phrase). Setting the following in a local customization file will also provide the reasons for the block:%0a%0a-> $EnableWhyBlocked = 1;%0a%0a%0a!! Managing multiple blocklists%0a%0aPmWiki allows blocklist entries to come from multiple pages by setting the $BlocklistPages variable. By default $BlocklistPages is set to "SiteAdmin.Blocklist", as well as any automatically downloaded blocklists as described below. PmWiki will use all entries in all the blocklists for filtering wikispam. Setting a value of $BlocklistPages changes the default:%0a%0a-> $BlocklistPages = array('Main.Blocklist', '{$Group}.Blocklist');%0a%0aThe order of blocklists really doesn't matter -- all of the blocklist%0apages ultimately get used, and the [@unblock:@] entries are processed %0aafter all of the blocklist pages have been loaded.%0a%0a[[#automaticblocklists]]%0a!! Automatically downloaded blocklists%0a%0aMaintaining blocklists is relatively easy to do, but can become tedious over time. Several groups have formed and maintain "shared blocklists", where a common blocklist is made available to all. PmWiki's blocklist capability has built-in features for automatically downloading and updating such shared blocklists.%0a%0aIf you're just in a hurry to make use of some standard blocklists, make the following setting in ''local/config.php'':%0a%0a-> $EnableBlocklist = 10;%0a%0aThis tells PmWiki to not only enable blocklists on the site, but to also configure itself to automatically retrieve and maintain local copies of well-known blocklists such as [[(http://)chongqed.org]] and [[http://moinmaster.wikiwikiweb.de/|MoinMaster]]. These local copies will be saved in SiteAdmin.Blocklist-Chongqed and SiteAdmin.Blocklist-MoinMaster and refreshed once per day (as determined by the value of $BlocklistDownloadRefresh).%0a%0aTo automatically retrieve the [[SiteAdmin.Blocklist]] page used at pmwiki.org, add the following setting in ''local/config.php'':%0a%0a-> [@ $BlocklistDownload["$SiteAdminGroup.Blocklist-PmWiki"] = array('format' => 'pmwiki'); @]%0a%0a!! Ignoring specific entries in a blocklist (unblock)%0a%0aWhen using a large master blocklist or blocklists automatically refreshed from external sites, it may be that some entries in the blocklists are inappropriate or overeager and block legitimate content. In this case a wikiadministrator can use "unblock" in a blocklist page to ignore an entry from the blocklist. For example, to allow "spam.com" even if another blocklist has a block entry for it:%0a%0a-> unblock:spam.com%0a%0aIn order for unblocking to work the phrase or pattern following "unblock:" must be ''exactly'' the same as the original.%0a%0a!! Permissions on blocklist pages%0a%0aIn general, an [[(wiki )administrator]] will want to edit-protect the SiteAdmin.Blocklist and any other blocklist pages to prevent arbitrary changes to the blocklist (see [[Passwords]]). Since most pages in the SiteAdmin.* group are edit-protected by default anyway, this usually isn't a problem.%0a%0aAdministrators may also wish to read-protect the various blocklist pages so that others do not know the exact phrases and/or IP addresses that are being blocked. (By their nature blocklists tend to contain phrases or terms that may be offensive or inappropriate to some.)%0a%0aAny pages created via automatic download (see above) are automatically locked against viewing except by administrators. %0a%0a%25audience%25 administrators (intermediate)%0a!! Detailed configuration of automatically downloaded blocklists%0a%0aAutomatic downloading of blocklist information is controlled by the $BlocklistDownload array. An entry for MoinMaster might look like:%0a%0a-> $BlocklistDownload["$SiteAdminGroup.Blocklist-MoinMaster"] = array(%0a--> 'url' => 'http://moinmaster.wikiwikiweb.de/BadContent?action=raw',%0a--> 'format' => 'regex',%0a--> 'refresh' => 86400);%0a%0aThis says to download the blocklist data from the given url into the SiteAdmin.Blocklist-MoinMaster page, that the entries in the blocklist are regular expressions, and to refresh the information every 86,400 seconds (one day).%0a%0aIf 'refresh' is omitted, then the page will be refreshed at the time interval given by $BlocklistDownloadRefresh (default one day). If 'format' is omitted, the page is assumed to have PmWiki-formatted entries as described above. If 'url' is omitted, then the blocklist information is downloaded from a standard location on the pmwiki.org site.%0a%0aTo force a refresh of an automatically downloaded blocklist, simply delete the existing page -- a new version will be installed upon the next blocklist scan. Blocklist pages are checked for download in response to any ?action=edit request.%0a%0aIf you are specifying your Blocklist-Pages in the config.php you have to specify the automatically updated pages too, else they won't be updated or created even if you use $EnableBlocklist = 10; .%0a%0a!! Farm-wide blocklist%0a%0aA blocklist can be applied farm-wide (see [[(Cookbook:)SharedPages]]). %0aAfter these pages are created they can be moved into the farm ''shared.d/'' directory:%0a%0a!! [[#variables]] Blocklist Variables%0a%0aThe following variables help control the configuration and operation of blocklists:%0a%0a:$EnableBlocklist:If set to a non-zero value, then blocklists are enabled on the site. If set to a value of ten or higher, then add entries for automatic downloads of standard blocklists.%0a: : $EnableBlocklist = 1; # enable blocklists%0a: : $EnableBlocklist = 10; # auto-configure standard blocklists%0a%0a:$EnableWhyBlocked:By default, authors are not told which particular phrases or IP addresses are causing a particular post to be blocked; setting $EnableWhyBlocked to 1 provides this information.%0a: : $EnableWhyBlocked = 1; # give reasons for blocking%0a%0a:$BlocklistPages:An array of pages to be checked for blocklist entries. The elements of the array may contain [[page variables]]. Defaults to "Site.Blocklist", plus any other automatically downloaded blocklist pages.%0a%0a:$BlocklistMessageFmt:The message to provide the author whenever a post has been blocked.%0a%0a:$BlockedMessagesFmt:If $EnableWhyBlocked is set, defines the text to use for each type of block being performed. Currently only 'ip' and 'text' are recognized.%0a: : BlockedMessagesFmt['ip'] = "$[IP address blocked from posting]: ";%0a: : $BlockedMessagesFmt['text'] = "$[Text blocked from posting]: ";%0a%0a:$BlocklistDownload:An array of automatically-downloaded blocklists. The keys of the array are the pages in which the blocklists should be stored, the values contain the url, format, and refresh interval for the downloaded blocklist.%0a->[@ # Download the MoinMaster blocklist every twelve hours%0a $BlocklistDownload["$SiteAdminGroup.Blocklist-MoinMaster"] = array(%0a 'url' => 'http://moinmaster.wikiwikiweb.de/BadContent?action=raw',%0a 'format' => 'regex',%0a 'refresh' => 43200);%0a # Download a shared blocklist from pmwiki.org every day%0a $BlocklistDownload["$SiteAdminGroup.Blocklist-Shared"] = array(%0a 'format' => 'pmwiki');%0a@]%0a%0a:$BlocklistDownloadRefresh:The default refresh interval for any $BlocklistDownload entries that don't explicitly specify a 'refresh' value.%0a: : # perform automatic downloads once per week by default%0a: : $BlocklistDownloadRefresh = 86400 * 7;%0a%0a:$BlocklistDownloadFmt:The format to use when saving automatically downloaded blocklists.%0a%0a%0a:$EnableBlocklistImmediate:Some cookbook recipes update pages with author input but don't use the built-in data posting routines. If $EnableBlocklistImmediate is set (default) and the current action is listed in $BlocklistActions (below), then an immediate blocklist scan is performed on the incoming text.%0a%0a:$BlocklistActions:A list of actions for which immediate blocklist checks should be performed (see $EnableBlocklistImmediate above).%0a: : # perform immediate checks for ?action=comment%0a: : $BlocklistActions['comment'] = 1;%0a: : # perform immediate checks for ?action=postdata%0a: : $BlocklistActions['postdata'] = 1;%0a
+time=1234620238
diff --git a/wikilib.d/PmWiki.Categories b/wikilib.d/PmWiki.Categories
new file mode 100644
index 0000000..88f1046
--- /dev/null
+++ b/wikilib.d/PmWiki.Categories
@@ -0,0 +1,12 @@
+version=pmwiki-2.2.4 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (Macintosh; U; PPC Mac OS X 10_4_11; en) AppleWebKit/530.19.2 (KHTML, like Gecko) Version/4.0.2 Safari/530.19
+author=Scott Connard
+charset=ISO-8859-1
+csum=Category.GroupFooter is now part of the PmWiki release
+host=68.38.68.7
+keywords=categories, tags
+name=PmWiki.Categories
+rev=67
+targets=Category.GroupFooter,Category.Category,PmWiki.EditVariables
+text=(:Summary:Categories are a way to organize and find related pages:)%0a(:keywords categories, tags:)%0a(:Audience: authors (intermediate) :)%0a%0a!!Purpose of categories%0aCategories (also known as "tags") are a way to organize and find related pages. Categories are implemented by default in PmWiki 2, and in most wikis they don't require any special code or markup, they're just a useful convention. The idea is that every page that falls into a particular subject area should have a link to a shared page containing links to other pages on that subject. These pages are created in the ''Category'' group, and thus these subject areas are called "categories".%0a%0a!!Using categories%0aGetting categories to work requires a single step: adding links to each category. A category named Subject is created by adding a link to [=Category.Subject=] on any page. When you add the link to a page, the page can be described as being ''in'' the category "Subject". %0a%0aThere is a special markup for creating these links which makes categories work more smoothly: [=[[!Subject]]=] will create a link to Category.Subject. So [=[[!Subject]]=] is a kind of shortcut to the page Subject in the category group.%0a%0aA [[Category.GroupFooter]] file is included in the PmWiki release that contains the line [@(:pagelist link={*$FullName} list=normal:)@] so that whenever a category page is displayed, it will show a list of links to pages that reference that page in the category group. Like any other page in [@wikilib.d@] you can modify this page and it will not get overwritten by another release.%0a%0aIt is worth noting that rather than using Category.GroupFooter, the pagelist directive can be added to Category.GroupHeader to similar effect; it just depends on whether you'd prefer to have the list of pages appear before or after any text that you add to the individual category pages (which can be edited just like normal pages).%0a%0aBecause we use the normal [[Cookbook:PagelistExplained|PageList]] @@link=@@ markup, you can use it not only in the category group. If you want to show all pages belonging to the category Subject you can use on any wiki page [@(:pagelist link=Category.Subject list=normal:)@].%0a%0aSimilarly, there's no requirement that a "category page" has to be in the ''Category'' group -- any page can define a "category" of pages that link to it.%0a%0aAn administrator can override the default category group name of "Category" by setting the $CategoryGroup variable in ''config.php'' to another group name.%0a%0aA page author can also link to a category list without adding the linking page to the category by using [=[[ {Category.Subject$PageUrl} | Subject ]]=]. This will create a link that looks like [=[[!Subject]]=] without adding the linking page to the category listing.%0a%0a!!!Recap%0aSo, by adding the link [=[[!Subject]]=] to a page, a link to that page will automatically appear on the page ''Category.Subject'', as long as ''Category.GroupFooter'' has been tweaked appropriately. Thus, you can create a page that automatically creates an alphabetized list of all movies discussed on your wiki by creating links to [=[[!Movies]]=] on each film's page; the resulting automatic list would be on the page ''Category.Movies'' . %0a%0a%25audience%25 authors (advanced)%0a[[#CategoryNesting]]%0a!!Category nesting%0aCategories have the potential for even greater usefulness because [@Category.*@] pages can themselves be placed into categories! To follow an excellent example from John Rankin, let's suppose we have the following film pages in the categories listed to the right:%0a%0a-> [@%0aFilm.ShaunOfTheDead [[!Horror]] [[!Comedy]] [[!2003]]%0aFilm.InMyFathersDen [[!Drama]] [[!2004]]%0aFilm.TheCorporation [[!Documentary]] [[!2003]]%0a@]%0a%0aNow then, we can create [@Category.Horror@], [@Category.Comedy@], [@Category.Drama@], and [@Category.Documentary@], and in each one of those pages we put [@[[!Genre]]@]. In [@Category.2003@] and [@Category.2004@], we put [@[[!Year]]@].%0a%0aSo, what happens when we display [@Category.Genre@] ? We see links to "Comedy", "Drama", "Documentary", and "Horror", because they're in the Genre category. When we click on one of those links, we see all of the films listed in one of those categories. Similarly, if we click on [@Category.Year@], we see links to "2003" and "2004", each of which in turn displays the list of films for that year.%0a%0aFinally, in [@Category.Genre@] and [@Category.Year@] we can put [@[[!Category]]@], which makes them "top-level" categories reachable from the [@Category.Category@] page. Voila, we now have an instant "hierarchy":%0a%0a-> [@%0aCategory.Category%0a Category.Genre%0a Category.Comedy%0a Film.ShaunOfTheDead%0a Category.Drama%0a Film.InMyFathersDen%0a Category.Documentary%0a Film.TheCorporation%0a Category.Horror%0a Film.ShaunOfTheDead%0a Category.Year%0a Category.2003%0a Film.ShaunOfTheDead%0a Film.TheCorporation%0a Category.2004%0a Film.InMyFathersDen%0a@]%0a%0aNote however that this isn't a "strict" hierarchy--i.e., any page or category can appear simultaneously in multiple categories. For example, [@Category.Documentary@] could be a member of both the Genre and top-level category listings.%0a%0aEach category page can have content text before the generated list, e.g., to give a generic description of things in the category. (Or it can be empty, which works fine.) It can also contain associations to related categories ("see also" references). For example, in a tourism wiki, the ''bed and breakfast" category might contain a see-also reference to the "self-catering" category.%0a%0a%25audience%25 administrators (intermediate)%0a!!The guts of the category markup%0aAs mentioned, all of the necessary markup features for Categories are enabled by default in current releases of PmWiki 2.0, but here's how they work for those who are interested. The use of the Category group as the repository for all categories is determined by setting the $CategoryGroup variable, and the special [=[[!Subject]]=] markup is activated by a call to the Markup() function:%0a %0a-> [@SDV($CategoryGroup,'Category');%0aMarkup('[[!','%3clinks','/\[\[!([^\|\]] ?)\]\]/',%0a "%3cspan class='category'>[[$CategoryGroup/$1]]%3c/span>");%0a@]%0a%0a%0a!!Coming up with good category schemes%0aThe hard part about using categories is choosing a good vocabulary. Site content managers may wish to follow the Guidelines for the establishment and development of monolingual thesauri (ISO 2788-1986) and the Guidelines for the establishment and development of multilingual thesauri (ISO 5964-1985). Questions to think about include:%0a* whether a scheme already exists and can be reused%0a* number of levels in a multilevel scheme (not too shallow, not too deep -- e.g. 3)%0a* number of categories per page (not too many, not too few -- e.g. 3)%0a* consistent use of singular ([@[[Mercury]] is a [[!planet]]@]) or plural ([@[[Mercury]] is in the [[!planets]] category@])%0a* disambiguation and use of phrases ([@[[!musical instruments]]@] and [@[[!medical instruments]]@]) or [[Cookbook:Subpage Markup]] ([@[[!Instruments*Musical]]@] and [@[[!Instruments*Medical]]@])%0a%0aOr you can just let people use whatever category terms they find meaningful. A vocabulary (or "folksonomy") will emerge over time.%0a%0a!!Showing a list of categories%0a%0aTo show a list of categories we can use a pagelist for the pages in the category group. %0aFor instance the following will list pages in the Category group, put it on page [[Category.Category]] for convenience, or on any other page:%0a%0a->[@(:pagelist group=Category list=normal fmt=#title:)@]%0a%0aBut there is a problem: Just adding a category markup to a page will not create a corresponding category page, even though following the link will show the page with a list of pages linking to it!\\%0aTo have category pages automatically created in group 'Category' add the following to config.php:%0a%0a->[@$AutoCreate['/^Category\./'] = array('ctime' => $Now, 'text' => $page['text']);@]%0a%0aChange 'Category' to the name of your category group. You can also add more definitions for more category groups, useful if you use a recipe like Cookbook:Tagger which allows multiple category groups.%0a%0aSee also [[PmWiki/EditVariables#AutoCreate]]%0a
+time=1248048308
diff --git a/wikilib.d/PmWiki.ChangeLog b/wikilib.d/PmWiki.ChangeLog
new file mode 100644
index 0000000..59a7f72
--- /dev/null
+++ b/wikilib.d/PmWiki.ChangeLog
@@ -0,0 +1,11 @@
+version=pmwiki-2.2.12 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.7) Gecko/20100106 Ubuntu/9.10 (karmic) Firefox/3.5.7
+author=Petko
+charset=ISO-8859-1
+csum=* Update documentation.
+host=81.65.12.233
+name=PmWiki.ChangeLog
+rev=982
+targets=Cookbook.RecentChanges,PmWiki.MailingLists,PITS.00571,PITS.01106,PITS.00796,PITS.00535,PITS.01145,PITS.01098,PITS.00266,PITS.00779,PITS.01155,PITS.01156,PITS.01149,PITS.01150,PITS.01141,PmWiki.CustomMarkup,PITS.01125,PITS.00703,PITS.00088,PITS.00976,PITS.01146,PITS.00813,PITS.01126,PITS.01131,PITS.01071,PITS.00802,PITS.01102,PITS.00238,PITS.01114,PITS.01062,PITS.01103,PITS.01104,PITS.00915,PITS.01099,PITS.00396,PITS.01037,PITS.00836,PITS.00998,PITS.01073,PITS.00980,Cookbook.UTF-8,PmWiki.ReleaseNotes,PITS.00407,PITS.00919,PITS.01081,PITS.01066,PITS.00984,PITS.01030,PITS.00989,PITS.00988,PITS.00987,PmWiki.WikiFarms,SiteAdmin.SiteAdmin,Cookbook.LimitWikiGroups,PmWiki.Version,SiteAdmin.Status,SiteAdmin.AuthList,PmWiki.PageTextVariables,PmWiki.Links,PITS.00387,PmWiki.WikiStyles,PmWiki.PageLists,PmWiki.Forms,PmWiki.PageListTemplates,PmWiki.FAQ,PITS.00935,PmWiki.Passwords,PmWiki.Skins,PmWiki.PageVariables,PITS.00755,PmWiki.MarkupExpressions,PITS.00906,Site.PageListTemplates,PmWiki.PageDirectives,PITS.00558,PmWiki.ConditionalMarkup,PITS.00878,PITS.00787,PmWiki.AuthUser,PmWiki.PagelistVariables,PITS.00875,PITS.00881,PITS.00850,PITS.00846,PITS.00853,PITS.00854,PmWiki.Robots,PmWiki.Uploads,PITS.00801,PITS.00410,PITS.00527,PITS.00595,PITS.00567,PITS.00327,PITS.00573,PITS.00708,PITS.00767,PITS.00753,PITS.00750,PITS.00749,PITS.00751,PITS.00530,PITS.00611,PITS.00671,PITS.00739,PITS.00723,PITS.00736,PITS.00709,PITS.00696,PITS.00713,PITS.00620,PITS.00702,PITS.00699,PmWiki.ChangeLogArchive
+text=(:Summary: Log of changes made to PmWiki by [[Release(Notes)]]:)%0aSee [[Cookbook:RecentChanges | the cookbook recent changes page]] for additional updates and activity by other developers, or join the [[PmWiki/MailingLists | pmwiki mailing lists]] to discuss feature development with us.%0a%0a(:comment Changes made to the [[PmWiki:Subversion | subversion pre-release ]] of PmWiki.:)%0a!!! [[#v2212]] Version 2.2.13 (2010-02-21)%0a* Replace deprecated in PHP 5.3 function split() with explode().%0a* Add $WordDiffFunction default to PHPDiff().%0a* Use existing border colors as highlighting background.%0a* Refactor/optimize DiffRenderSource(), merge with DiffRenderInline().%0a* Change default history to show word-level highlighting.%0a* Fix bug with $DiffKeepNum which kept less revisions than it should.%0a* Fix RetrieveAuthPage() call from HandleAuth().%0a* Update documentation.%0a%0a!!! [[#v2212]] Version 2.2.12 (2010-02-17)%0a* Allow a custom $DiffHTMLFunction to skip the line rendering if it returns false.%0a* Add $EnableDiffInline, simple word-level diffs (PITS:00571).%0a* Update documentation.%0a%0a!!! [[#v2211]] Version 2.2.11 (2010-02-14)%0a* Break PrintDiff() into customizable functions (PITS:01106).%0a* Add anchors to individual diffs (PITS:00796).%0a* Remove unused $RecipeInfo definition in markupexpr.php (reported by P.Bowers).%0a* Add [=(:head:) and (:headnr:)=] table directives (PITS:00535).%0a* Fix $GroupPattern and $NamePattern in xlpage-utf-8.php.%0a* Update documentation.%0a%0a!!! [[#v229]] [[#v2210]] Version 2.2.9, 2.2.10 (2010-01-17)%0a* Fix i18n string in PasswdVar(), reported by SteP.%0a* Fix sample-config.php with correct information about $EnableWSPre (PITS:01145).%0a* Fix range searches for wikis in UTF-8 (reported by Maxim).%0a* Fix global variable $StringFolding in scripts/xlpage-utf-8.php.%0a* Fix markup for italics in creole.php.%0a* Fix previews for PTVs, Pagelist templates and included sections (PITS:01098).%0a* Add $DiffKeepNum - number of revisions kept, even if older than $DiffKeepDays.%0a* Add Yandex to robots.php.%0a* Change default $EnableRelativePageVars to 1 (PITS:01145).%0a* Add fifth parameter to SetProperty() : keep existing property.%0a* Add $EnablePageTitlePriority (PITS:00266, PITS:00779).%0a* Update documentation.%0a%0a!!! [[#v228]] Version 2.2.8 (2009-12-07)%0a* Fix apostrophes in Author field (PITS:01155).%0a* Fix Condition "exists" for PHP 5.3 (PITS:01156).%0a* Update documentation.%0a%0a!!! [[#v227]] Version 2.2.7 (2009-11-08)%0a* Fix GlobToPCRE() to work with !excl and -excl with PHP 5.3 (PITS:01149).%0a* Fix HandleDownload() correctly quote the filenames (PITS:01150).%0a* Fix SessionAuth() for PHP 5.3, the $_REQUEST array doesn't contain the $_COOKIE array (PITS:01141).%0a* Fix default timezone for PHP 5.3 (PITS:01141).%0a* Update documentation.%0a%0a!!! [[#v226]] Version 2.2.6 (2009-10-04)%0a* Escape apostrophes for multiline textarea/hidden form fields.%0a* Fix global unset of $MarkupRules in [[PmWiki/CustomMarkup|Markup()]] and DisableMarkup(), reported by D.Faure.%0a* Fix call to BuildMarkupRules() in MarkupToHTML(), suggested by Pm.%0a* Allow disabling of $PageListFilters and $FPLTemplateFunctions if set to -1 and thus allow replacing a core function with a custom one.%0a* Fix DRange() returned timestamps +1min or +1day when it shouldn't (PITS:01125).%0a* Add $MarkupWordwrapFunction to allow custom [@(:markup:)@] line width for multibyte wikis (PITS:00703).%0a* Add $MakeUploadNamePatterns to allow custom filename normalization for uploads.%0a* Add a fourth argument to PostRecentChanges() to allow this function to be called with a custom $RecentChangesFmt array.%0a* Add $RecentUploadsFmt, to allow logging of new uploads to the RecentChanges pages (PITS:00088).%0a* Fix Notify for some installations in safe_mode (PITS:00976).%0a* Add $HTMLHeaderFmt['guiedit'] variable in guiedit.php to allow customization (PITS:01146).%0a* Update documentation.%0a%0a!!! [[#v225]] Version 2.2.5 (2009-08-25)%0a* Add *.7z as accepted upload extension (PITS:00813).%0a* Fix global variable $HandleAttrFmt in HandleAttr (PITS:01126).%0a* Allow brackets in input element names (PITS:01131).%0a* Fix CSS class applied twice (PITS:01071).%0a* Fix Not-Modified headers could prevent caching (PITS:00802).%0a* Break FPLTemplate() into configurable sub-parts (PITS:01102).%0a* Add [@(:template none:)@] section for Pagelist templates.%0a* Fix attr-protected page could be deleted with edit permissions (PITS:00238).%0a* Update documentation.%0a%0a!!! [[#v224]] Version 2.2.4 (2009-07-16)%0a* Fix bug with page attributes, which somehow didn't make it in the 2.2.3 release.%0a* Fix bug with HTML entities in XLPages introduced earlier today in 2.2.3 (reverted, PITS:01114).%0a%0a!!! [[#v223]] Version 2.2.3 (2009-07-16)%0a* Fix action=logout could incorrectly set a session cookie (PITS:01062).%0a* Fix page history trim in vardoc.php (PITS:01103).%0a* Add $EnableUploadGroupAuth, use group password for downloads (PITS:01104).%0a* Fix recursive PTV loops, added $MaxPageTextVars (PITS:00915, PITS:01099).%0a* Fix mkdirp() messages for absolute paths (PITS:00396).%0a* Fix sample-config.php order for urlapprove.php (PITS:01037).%0a* Fix broken signature links on preview.%0a* Fix crypt.php (action=crypt) could malfunction for passwords with quotes or apostrophes.%0a* Fix @@ @_site_*@@ passwords to work in GroupAttributes (PITS:00836, PITS:00998).%0a* Fix possible XSS vulnerabilities, reported by Michael Engelke.%0a* Update documentation.%0a%0a!!! [[#v222]] Version 2.2.2 (2009-06-21)%0a* Fix class in pages not on the breadcrumbs trail, reported by Ed W.%0a* Fix @@tabindex@@ and @@onclick@@ to guiedit buttons.%0a* Fix $GroupPrintHeaderFmt in print.php (PITS:01073).%0a* Fix global vars in xlpage-utf-8.php (PITS:00980).%0a* Fix $txt in LinkPage (reported by Eemeli Aro).%0a* Add $EnableNotifySubjectEncode for international wikis (Cookbook:UTF-8).%0a* Fix international message in Abort().%0a* Fix security bug with AuthUser, reported by Eemeli Aro. See [[Release notes]].%0a* Fix $ActionTitleFmt for login and upload, reported by Eemeli Aro.%0a%0a!!! [[#v221]] Version 2.2.1 (2009-03-28)%0a* Fix $FPLTemplateMarkupFunction which somehow didn't get in the 2.2.0 archive.%0a* Fix wikitrails to work cross-group (PITS:00407).%0a* Add $EnableRedirectQuiet variable (PITS:00919).%0a* Fix [={$Title}=] could display global variables (reported by HansB).%0a* Fix reloaded form submissions could lose values (reported by DaveG).%0a* Fix preview while restoring a version from history (PITS:01081).%0a* Fix relative links with international characters (reported by G. Hermanowicz).%0a* Add in sample-config.php example call to xlpage-utf-8.php (PITS:01066).%0a* Update documentation.%0a* Fix guiedit.php to produce valid HTML.%0a%0a!! [[#v220]] Version 2.2.0 (2009-01-18)%0a* Convert beta series to official release series.%0a* Add $FPLTemplateMarkupFunction (PITS:00984, requested by John Rankin).%0a%0a!!! [[#beta68]] Version 2.2.0-beta68 (2008-08-14)%0a* Fix E_NOTICE errors reported by Dominique Faure.%0a* Enable [@(:redirect:)@] directives in pagelists.%0a%0a!!! [[#beta67]] Version 2.2.0-beta67 (2008-07-13)%0a* Add [={$LastModifiedTime}=] page variable.%0a* Add $EnableSessionPasswords variable to control session password usage.%0a* Add $SessionEncode and $SessionDecode variables to specify functions for encoding/decoding sensitive session data.%0a* Updated httpauth.php to use SessionAuth instead of poking in session guts directly.%0a%0a!!! [[#beta66]] Version 2.2.0-beta66 (2008-07-04)%0a* Add content-type/charset to Abort() output (suggested by Petko).%0a* Close minor XSS vulnerability (PITS:01030).%0a* Add "nested if" capability.%0a* Fix bug in $Transition handling that would enable all transitions if any were set (reported by John Rankin).%0a %0a%0a!!! [[#beta65]] Version 2.2.0-beta65 (2007-11-17)%0a* Fix SiteAdmin.AuthList so that it defaults to list=all (reported by Roman).%0a* Fix pmwiki skin to include xmlns= attribute in %3chtml> tag (PITS:00989, reported by Mateusz Czaplinski and Petko Yotov).%0a%0a!!! [[#beta64]] Version 2.2.0-beta64 (2007-11-13)%0a* Add times to PmWiki date parsing (e.g., 2007-08-09T12:22:04).%0a* Suppress warning from ini_set in diag.php (suggested by Petko).%0a* Fix handling of -> links in trails (reported by Eemeli Aro).%0a* Add .kml and .kmz as valid attachment types. %0a* Fix handling of [=&=] in markup (PITS:00988, reported by Stirling Westrup).%0a* Fix duplication of language markers in $XLLangs (PITS:00987, reported by Stirling Westrup).%0a* Correct typo in DRange() call in stdmarkup.php (reported by Stirling Westrup).%0a* Turn on error displays when diagnostics are enabled.%0a* Default PHP's pcre.backtrack_limit to at least 1000000.%0a%0a!!! [[#beta63]] Version 2.2.0-beta63 (2007-07-31)%0a* Added $SkinDirectivesPattern to allow adjustments to available skin directives (requested by Petko).%0a* Fix default permissions on Site.AuthUser and Site.AuthList (reported by Scott Connard).%0a* Add "monospace" to pmwiki.css default (reported by Joshua Timberman, with assistance from H. Fox)%0a* Fix problem with slashes in wildcards to name= and group= parameters (reported by Ian MacGregor).%0a%0a!!! Version 2.2.0-beta62 (2007-07-21)%0a* Fix bug in trails introduced by beta61 (reported by charlequin).%0a%0a!!! Version 2.2.0-beta61 (2007-07-19)%0a* Add ability to grab trails by section.%0a* Add an "ontrail" condition (from suggestions by charlequin).%0a%0a!!!Version 2.2.0-beta59, 2.2.0-beta60 (2007-07-18)%0a* Fix problem with upgrade.php on [[wiki farms]] (reported by Scott Connard).%0a* Fix problem with distributed version of Site.AuthUser (reported by Jon Haupt).%0a%0a!!!Version 2.2.0-beta58 (2007-07-17)%0a* Significant change: Site.AuthUser, Site.Blocklist, Site.ApprovedUrls, and Site.NotifyList now appear in the [[SiteAdmin]] group by default.%0a** Note: if you limit groups by setting $GroupPattern, you now need to include SiteAdmin (see [[Cookbook:LimitWikiGroups]])%0a* Abort if ldap: authentication requested and libraries aren't present.%0a* Added "upgrades.php" script to handle various migration issues.%0a* Current PmWiki [[version]] is now held in [[SiteAdmin.Status]] .%0a* Fix ?action=postupload to follow ?action=upload settings.%0a* Improvements to [[SiteAdmin.AuthList]] page (suggestions and fixes from Ian MacGregor).%0a* Allow leading underscores in attachment names (requested by Christophe David).%0a%0a!!!Version 2.2.0-beta57 (2007-06-15)%0a* Fix AsSpacedUTF8() to work like AsSpaced() (reported by Petko).%0a* Qualify page links that contain parentheses (reported by Petko).%0a* Fix bug in [@(:input default $:var ... :)@] (reported by Crisses).%0a%0a!!!Version 2.2.0-beta56 (2007-06-13)%0a* Fix AsSpaced() to not add spaces before leading digit, and treat hyphenated digits as complete numbers.%0a* Fix infinite recursion in self-referencing [[page text variables]] (PITS:00915).%0a* Fix bug introduced in beta55 not handling end [[links|anchors]] correctly (reported by Roman).%0a%0a!!!Version 2.2.0-beta55 (2007-06-11)%0a* Fix attributes to [@(:input e_form:)@] (PITS:00387, re-reported by Crisses).%0a* UpdatePage() now calls StopWatch() to record posting.%0a* Display stopwatch output as part of redirect.%0a* Fix [[wiki styles]] bug when $EnableLinkPageRelative is set (reported by Petko).%0a* Revise TextSection() code to hopefully avoid %25newwin%25[[http://pcre.org/|pcre]] limits (reported by Kathryn Andersen, Knut Alboldt).%0a* Add wrap=inline and wrap=none options to [[page list(s#pagelistwrap)]].%0a%0a!!!Version 2.2.0-beta53, 2.2.0-beta54 (2007-06-02)%0a* Improve error message reporting for markup rules (suggestion by Knut Alboldt).%0a* Clean up more E_NOTICE warnings (reported by Ian MacGregor).%0a* Add focus= option to [=(:=][[forms|input]]:) controls.%0a* Added CSS [@.faqtoc@] class, to be able to display only the questions coming from the #includefaq [[page list template(s)]].%0a* Changed [[PmWiki.FAQ]] to use .faqtoc class.%0a* Fix bug in TextSection (PITS:00935, reported by Jean-Fabrice).%0a* Fix bug in [[page list(s#pagelisttrail)]] caching of trails.%0a%0a!!!Version 2.2.0-beta52 (2007-05-26)%0a* Add per-PageStore attributes (from a suggestion by Tobias Thelen).%0a* Add [@{$PasswdRead}@], [@{$PasswdEdit}@], etc. to display page password settings.%0a* Add Site.AuthList to display all password permissions on a site.%0a* Reorder $PageListFilters slightly.%0a* Add "passwd=" option to [[page list(s#pagelistpasswd)]], to return only those pages that have some sort of [[password(s)]] attribute on them.%0a* Add line numbers to StopWatchHTML output.%0a* Clean up handling of $AuthCascade.%0a%0a!!!Version 2.2.0-beta51 (2007-05-23)%0a* Add fmt=count to [[page list(s#pagelistcount)]] (reminder from Hans).%0a* Ignore hidden files in [[skin(s)]] directories when searching for .tmpl (suggestion by Stephan Becker).%0a* Clean up queuing of pages to be updated in .pageindex .%0a* Reset $LinkTargets() at beginning of each UpdatePage() sequence.%0a%0a!!!Version 2.2.0-beta50 (2007-05-22)%0a* Fix HTML cache when drafts are enabled, or other recipes using CondAuth().%0a* Prevent [[page lists]] with protected pages from HTML cache.%0a%0a!!!Version 2.2.0-beta48, 2.2.0-beta49 (2007-05-21)%0a* Fix spurious value= attribute in <textarea> tag generated by [@(:input textarea ... :)@].%0a* Allow either [@(:input default ...:)@] or [@(:input defaults ...:)@].%0a* Fix problem with page text variable handling in [@(:input defaults:)@].%0a* Allow either [@(:template default:)@] or [@(:template defaults:)@] in [[page list templates]].%0a* Fix a bug handling dates with suffixes (reported by Crisses).%0a%0a!!!Version 2.2.0-beta47 (2007-05-20)%0a* Fix bug with quote handling in [@(:include:)@] options (reported by Hans).%0a%0a!!!Version 2.2.0-beta46 (2007-05-19)%0a* Moved $PageTextVarPatterns definition from scripts/stdmarkup.php to pmwiki.php.%0a* Ignore Markup() rules that have unresolved $when parameters.%0a* Fix issue in authuser.php when $auth array isn't set (contributed by Ben Stallings).%0a* The [@(:include:)@] directive now performs template argument processing on the included text.%0a* Optimized [@(:pagelist:)@] slightly when sorting on [[page variables]].%0a* Refactored [@(:input ... :)@] markups.%0a* Added HandleDispatch(), which allows action handlers to easily redispatch to other actions (and add messages).%0a* Added FmtTemplateVars(), to perform various template-substitutions.%0a%0a%0a!!!Version 2.2.0-beta45 (2007-05-02)%0a* Update pmwiki's date parsing to use a common routine, recognizing dates within strings and restricting range to 1900-2039.%0a* Add additional parameter to "date" conditional.%0a* Add if= option to [[page list(s#pagelistif)]] (suggested by Crisses).%0a* Refactor code to use TextSection() and RetrieveAuthSection() functions.%0a* The value= parameter to [@(:input textarea:)@] now works properly (including values loaded from $InputValues).%0a* The [@(:input default:)@] directive now allows loading input control defaults from another page via the [@source=@] parameter.%0a* Remove automatic call to FmtPageName() in $ROSPatterns. Add $ROEPatterns (from suggestions by JB and others).%0a* Fix minor variable bugs in scripts/crypt.php.%0a* Remove E_NOTICE errors (reported by Hans).%0a* Fix handling of page variables when pagename is empty or not provided.%0a* Add $EnableLinkPageRelative configuration option.%0a* Clean up handling of arguments to [@{(ftime ...)}@].%0a* Remove mailposts.php call in stdconfig.php (reported by Christophe David).%0a%0a!!!Version 2.2.0-beta44 (2007-04-16)%0a* Fix case conversion of U+027D and U+026B (reported by Petko).%0a* Add $FTimeFmt to set default formatting for [@{(ftime)}@].%0a* Add %25s conversion to [@{(ftime)}@] for systems that don't have it by default.%0a* Report an error if edit [[form(s)]] cannot be read (suggested by Hans).%0a* Don't report ?cannot acquire lockfile when simply browsing pages.%0a* Add $EnableReadOnly flag to signal when PmWiki is to be run in read-only mode.%0a%0a!!!Version 2.2.0-beta43 (2007-04-15)%0a* Update drafts code to add $EnablePublishAttr and change button labels when drafts are enabled (PITS:00755).%0a* Removed no-longer-needed 'compat1x.php' and 'mailposts.php' from distribution.%0a* Added $DraftRecentChangesFmt.%0a* Added "[[markup expressions]]" [@{(...)}@] into the core.%0a* Added charset= attribute to saved pages.%0a* Update pagelist.php and xlpage-utf-8.php to handle case-insensitive searches.%0a* Added some optimizations to phpdiff.php script to produce more useful history information.%0a%0a!!!Version 2.2.0-beta42 (2007-03-27)%0a* Fix a bug with order=title in pagelists (reported by Anno).%0a%0a!!!Version 2.2.0-beta41 (2007-03-26)%0a* Added $EnableWSPre option, which allows easy adjustment of the "leading space -> preformatted text" (or "whitespace") rule.%0a* Added a new "pre" wikistyle, to designate blocks that are to be treated as preformatted text.%0a%0a!!!Version 2.2.0-beta40 (2007-03-24)%0a* Fix bug with order=title in pagelists when using $Titlespaced (PITS:00906, reported by Feral).%0a* Report state of allow_url_fopen when downloads fail in blocklist.php.%0a%0a!!!Version 2.2.0-beta39 (2007-03-23)%0a* Allow page variable filters to appear as options in [@(:template defaults:)@] (reported by SteP).%0a* Updated [[Site.PageListTemplates]] to use [@(:template:)@] directives.%0a* Remove '#wikileft h1' and '#wikileft h5' from pmwiki default stylesheet.%0a%0a!!!Version 2.2.0-beta38 (2007-03-22)%0a* Strip control characters from $ChangeSummary.%0a* Fix problem with count=m..n where m..n is outside the range of available pages (reported by SteP).%0a* Allow [@(:template default ...:)@] to specify a class= option.%0a* [[PmWiki/PageDirectives#redirect|Redirect]] pagename can now include an anchor (PITS:00558)%0a%0a!!!Version 2.2.0-beta37 (2007-03-16)%0a* Allow an optional space after comma separators in wildcard patterns (reported by Han Baas).%0a%0a!!!Version 2.2.0-beta36 (2007-03-16)%0a* Allow nested [[page text variables]] to work, remove extraneous ENT_NOQUOTES parameter.%0a* Add new [@(:template ...:)@] directives for pagelist templates.%0a* Modify count= option to pagelists to allow for alternate ranges.%0a%0a!!!Version 2.2.0-beta35 (2007-03-05)%0a* Fix bug in [[conditional markup]] parsing (reported by Christophe David).%0a%0a!!!Version 2.2.0-beta33, 2.2.0-beta34 (2007-03-01)%0a* Refactor wildcard handling into its own GlobToPCRE function.%0a* Allow negated wildcards for page variable filters in pagelists (PITS:00878, reported by Jiri)%0a* Fix wildcards so that spaces no longer separate patterns (use commas).%0a* Fix handling of '&' prior to [@(:input:)@] and other directives (reported by Luigi).%0a* Adjust position of [@%25define=...%25@] [[wiki styles]] to occur after ampersands.%0a* Adjust copyright dates on many files.%0a* Allow spaces around text variable names in [[page text variable(s)]] markups.%0a%0a!!! [[#beta32]] Version 2.2.0-beta32 (2007-02-28)%0a* Fix erroneous $EnableCreole item in docs/sample-config.php (reported by Sigurd).%0a* Added [@(:elseif:)@] and [@(:else:)@] markups (PITS:00787).%0a* Fix global $Skin variable handling when using SetSkin from within markup.%0a* Make sure directives aren't treated like [[page text variables]] (reported by Petko).%0a* Remove call to ResolvePageName() from authuser.php .%0a* Simplify [[PmWiki/AuthUser#LDAP|LDAP]] authentication for Active Directory sites.%0a* Cache lowercase/uppercase patterns in AsSpacedUTF8().%0a%0a!!!Version 2.2.0-beta31 (2007-02-11)%0a* Fix bug with sorting on [[pagelist variables]] (reported by Kathryn Andersen).%0a%0a!!!Version 2.2.0-beta29, 2.2.0-beta30 (2007-02-09)%0a* MakePageName now uses the first matching entry of $PagePathFmt as the home page of groups without a home page.%0a* Add AsSpacedUTF8() to handle title spacing in utf-8 (PITS:00875, contributed by Petko, Celok)%0a* Fix $RequestedPage when running with utf-8.%0a* Add %3cmeta> content-type tag for utf-8.%0a* Add an experimental caching system for pagelists.%0a* Fix $SuffixPattern and link suffixes for utf-8 (PITS:00881, reported by ppip).%0a%0a!!!Version 2.2.0-beta28 (2007-02-03)%0a* Update blocklist.php so that all posted fields are checked for block values (PITS:00850).%0a%0a!!!Version 2.2.0-beta27 (2007-01-25)%0a* Fix markup processing sequence for [@(:input default:), (:input select:)@], etc. (problem noted by Marc).%0a* Fix default value of [@order=@] parameter to MakePageList().%0a%0a!!!Version 2.2.0-beta26 (2007-01-23)%0a* Fix a bug where pagelist list= option had no effect when reading from trails (from an rss problem noted by Russ Fink).%0a%0a!!!Version 2.2.0-beta24, 2.2.0-beta25 (2007-01-22)%0a* Add a scripts/creole.php module for Creole markup (http://www.wikicreole.org/).%0a* Move WikiWords out of the core defaults -- can be enabled via $EnableWikiWords.%0a* Fix handling of WikiWords following & or #, as in [=Æ and #FFFF00=] (reported by Moni Kellermann).%0a* Adjust FormatTableRow() to support Creole-style tables (using single |'s).%0a* Update docs/sample-config.php with new configurations and options.%0a* Added code to allow Abort() to refer to additional information on pmwiki.org.%0a* Added $EnableSkinDiag, which checks templates for required %3c!--HTMLHeader--> and %3c!--HTMLFooter--> directives.%0a* Removed deprecated $BasicLayoutVars support from skins.php.%0a%0a!!!Version 2.2.0-beta22, 2.2.0-beta23 (2007-01-17)%0a* Added $EnableActions, to allow pmwiki.php to be included without generating output (from a suggestion by Wouter Groeneveld).%0a* Fix bug in "order=" option to [@(:pagelist:)@] (reported by Mike Bishop).%0a* Change DisplayStopWatch() function to StopWatchHTML().%0a* Allow multiple lines for markup:, wiki:, and page: template directives (reported by Marc)%0a%0a!!!Version 2.2.0-beta21 (2007-01-12)%0a* Fix %3cvspace> bug in searchresults output (PITS:00846, reported by M. Czaplinski, marc, and others).%0a* Fix numerous E_NOTICE warnings and incorrect constants (PITS:00853, contributed by AndrewFyfe).%0a%0a!!!Version 2.2.0-beta20 (2007-01-11)%0a* $FeedPageListOpt needs to be declared global in feeds.php.%0a* Add "404 Not Found" status code to ?invalid page name aborts (PITS:00854, suggested by Athan).%0a* Remove stale entries from $PageExistsCache when a new PageStore is added (reported by Hans).%0a%0a!!!Version 2.2.0-beta19 (2006-12-29)%0a* Have blocklist check $_POST['text'] only when it is set (from a report by Simon).%0a%0a!!!Version 2.2.0-beta18 (2006-12-28)%0a* Change $pagename parameter in UpdatePage() to be passed by reference (suggestion by J. Meijer).%0a* Fix $EnableRobotsCloakActions so that it works again with page variables.%0a* Add "XML Sitemaps" to $RobotPattern.%0a* Change $MetaRobots to return "nofollow,noindex" for non-existent pages.%0a* Prefer "404 Not Found" to "403 Forbidden" for [[(PmWiki:)robots]] attempting to do invalid actions on non-existent pages.%0a* Add rel='nofollow' to "create attachment" links.%0a* Added class='inputbox' to select boxes (suggested by Hans).%0a* Added .odt, .ods, and .odp file extensions to allowed [[uploads]] (suggested by Algis Kabaila, Robin Sheat, and others).%0a* Clean up some error warnings (PITS:00801, contributed by psvo).%0a* Set $ScriptUrl to 'https:' when accessed via SSL link (suggestions from C. Ridderström, H. Fox, PITS:00410, PITS:00527, PITS:00595).%0a* Fix bug in link= and trail= options to [@(:pagelist:)@] (reported by C. Ridderström).%0a%0a!!!Version 2.2.0-beta17 (2006-12-13)%0a* Fix spurious hidden field in [@(:searchbox:)@] output (reported by Hans).%0a* Fix $CaseConversions array for \xc4\xb1 and \xc5\xbf (reported by Petko Yotov).%0a* Refactor [@(:input:)@] markup handling.%0a* Add [@(:input select ...:)@] markup (PITS:00567).%0a* Add [@(:input default ...:)@] markup -- may change before 2.2.0 release.%0a* Add ability to set defaults for radio/checkbox/select controls.%0a%0a%0a!!!Version 2.2.0-beta16 (2006-11-10)%0a* Fix problem with [@(:e_preview:)@] directive when viewing an edit form (reported by Dominique Faure).%0a* Fix out-of-memory problem in scripts/compat1x.php when dealing with large pages to be converted (contributed by Donald Gordon).%0a* Fix problem of Variable: lines immediately followed by newline (reported by Hans).%0a* Fix uninitialized variable errors in FormatTableRow() (reported by Bob Sanders).%0a* Fix second argument of MakeBaseName() (provided by Stirling Westrup).%0a%0a!!!Version 2.2.0-beta15 (2006-10-16)%0a* Fix bug with displaying multi-line [@(:var:value:)@] [[page text variables]] (reported by Pico).%0a* Improve PageStore ls() method slightly, to restrict pagename searches to directories of a given depth (based on an issue reported by Chris Cox).%0a* Added $IsBlocked status variable to scripts/blocklist.php.%0a* Added $UnapprovedLink array to report unapproved links.%0a* Added $TimeISOFmt, $TimeISOZFmt, and $CurrentTimeISO variables.%0a* Switched scripts/feeds.php to use $TimeISOZFmt instead of $ISOTimeFmt.%0a* Added [@request=@] option to [@(:pagelist:)@], switched pagelist to default to not use url/form parameters.%0a* Fixed bug with array [@{$$options}@] in pagelist.%0a%0a!!!Version 2.2.0-beta14 (2006-10-06)%0a* Fix problem with extra parameter to mail when $NotifyParameters is empty (reported by Tom Lederer).%0a* Improve configurability of $SearchPatterns (from suggestions by Stirling Westrup).%0a* Add ability for $WikiWordCount to disable wikiword spacing (PITS:00327).%0a%0a!!!Version 2.2.0-beta13 (2006-10-04)%0a* Fix handling of angle brackets (and potential XSS) in pagelists combined with page text variables (noted by Pico).%0a%0a!!!Version 2.2.0-beta12 (2006-10-03)%0a* Added the UpdatePage() function into the core. %0a%0a!!!Version 2.2.0-beta11 (2006-10-03)%0a* Added ability to automatically create targets.%0a* Added sample code to docs/sample-config.php for automatic generation of Category.* pages.%0a* Fixed character escapes in pagelist [@{$$option}@] variables.%0a%0a!!!Version 2.2.0-beta10 (2006-10-02)%0a* Added [@{$$option}@] variables to get option values from [@(:pagelist:)@] (based on a recipe from Martin Fick).%0a* Changed [@{$PageCount}, {$GroupPageCount}, and {$GroupCount}@] to be [@{$$PageCount}, {$$GroupPageCount}, and {$$GroupCount}@].%0a* Added [@{$BaseName}@] page variable and $BaseNamePatterns.%0a%0a!!!Version 2.2.0-beta9 (2006-10-01)%0a* Fix bug with $EnablePageListProtect (reported by Brent Zupp).%0a* Added ability to select based on page variables in [@(:pagelist:)@].%0a%0a!!!Version 2.2.0-beta8 (2006-09-30)%0a* Update scripts/blocklist.php to check only $_POST['text'] instead of entire markup text.%0a* Fix bug in pagelist.php that wouldn't return correctly formatted array in certain circumstances (noted by Florian Fischer and JDem).%0a%0a!!!Version 2.2.0-beta7 (2006-09-30)%0a* Added scripts/blocklist.php to core.%0a* Updated handling of $PageTextVarPatterns.%0a* Eliminated need for extra flush() steps in notify.php, pagelist.php.%0a%0a!!!Version 2.2.0-beta6 (2006-09-27)%0a* Fix bug with initialization of $FeedPageListOpt in scripts/feeds.php (reported by Roman).%0a* Fix bug with over-eager [@(:textvar:value:)@] markup (from a bug reported by Chris Cox).%0a%0a!!!Version 2.2.0-beta4, 2.2.0-beta5 (2006-09-27)%0a* Fix bug with name= option in pagelist (reported by Ben Wilson).%0a* Fix bug with array_merge under PHP 5 (reported by Kathryn Andersen).%0a%0a!!!Version 2.2.0-beta3 (2006-09-26)%0a* Remove extra %3c!----> comment at end of table directives (noted by Ben Stallings).%0a* Fix directive form of page text variables (reported by Kathryn Andersen).%0a* Add first version of new modular pagelist code.%0a%0a!!!Version 2.2.0-beta2 (2006-09-25)%0a* Add support for [@{$:var}@] page text variables, and [@(:var:...:)@] markup.%0a* Fix default setting of $EnableRelativePageVars in docs/sample-config.php .%0a%0a!!!Version 2.2.0-beta1 (2006-09-25)%0a* Added [@{*$var}@] page variables (always the currently browsed page).%0a* Convert link and page variable handling in [=(:include:)=] to be relative to the included page.%0a* Added $EnableRelativePageVars and $EnableRelativePageLinks variables, as well as transition options.%0a* Added basepage= option to [=(:include:)=].%0a* Updated $GroupHeaderFmt and $GroupFooterFmt to use basepage= option.%0a* Adjusted $MakePageNamePatterns to automatically strip any #... or ?... from the end of a pagename input string (solution to a problem reported by J. Meijer).%0a%0a!!!Version 2.1.27 (2006-12-11)%0a* Backport in bug fix for TableRowFormat (from 2.2.0-beta16).%0a* Add support for [@{*$Variable}@] syntax (from 2.2.0 page variables).%0a%0a!!!Version 2.1.26 (2006-09-11)%0a* Fix a bug with variable referencing that caused feeds.php to get a confused PCache (reported by Helge Larsen).%0a%0a!!!Version 2.1.25 (2006-09-08)%0a* Fixed a bug in authuser.php that would fail if $AuthUser isn't defined (reported by Hans Huijgen).%0a* Added %3c!--XMLHeader--> and %3c!--XMLFooter--> aliases to %3c!--HTMLHeader--> and %3c!--HTMLFooter--> directives in skin templates (suggested by John Rankin).%0a* Added $PageExistsCache (suggested by John Rankin).%0a%0a!!!Version 2.1.24 (2006-09-06)%0a* Fixed a bug in authuser.php that had trouble dealing with non-array entries in $AuthUser (reported by Udo).%0a* Can now specify authorization groups using $AuthUser['@group'] entries.%0a* Can now specify an Apache .htgroup-formatted file for authorization groups via $AuthUser['htgroup'].%0a%0a!!!Versions 2.1.21, 2.1.22, 2.1.23 (2006-09-05, 2006-09-06)%0a* Close a potential security hole with $FarmD when register_globals is set "On".%0a* Correct a syntax error in feeds.php (noted by Ben Wilson).%0a* Fix a bug that prevented PmWiki from reading page files generated by versions prior to 0.5.6 (discovered by Milan Avramovic).%0a%0a!!!Version 2.1.20 (2006-09-04)%0a* Fixed a bug in [[PageDirectives#attachlist| [@(:attachlist:)@] ]] when passed a wikiword argument (reported by Kathryn Andersen).%0a* Changed $HTMLStylesFmt['markup'] to honor config.php setting (reported by Hans).%0a%0a!!!Version 2.1.19 (2006-08-30)%0a* Corrected a bug in the pageindex code that was causing the .pageindex to not update as quickly as it should.%0a* Slightly changed the handling of 'width' and 'height' in wikistyles.php, so that they can be be applied as attributes to %3cobject> and %3cembed> tags.%0a* Updated the Keep() function to recognize closing block tags as being in the 'B' block pool.%0a* Fixed a bug with wikistyles and form tags.%0a%0a!!!Version 2.1.18 (2006-08-28)%0a* Closed a potential cross-site scripting vulnerability in table markups (reported by JB).%0a* Added [@(:input image:)@] markup (requested by JB).%0a* Fixed problem with ?action=print failing to set [@{$Action}@] (reported by Bart).%0a%0a!!!Version 2.1.17 (2006-08-26)%0a* Added some improvements to IMS caching to better handle logout and authorization actions (PITS:00573, reported by floozy and Henrik Bechmann).%0a%0a!!!Version 2.1.16 (2006-08-26)%0a* Added $SkinLibDirs variable, to select filesystem and url locations where skins may be found (resolves PITS:00708, as reported by Hagan Fox, with additional suggestions from Ben Wilson).%0a* Changed [@%3c!--HeaderText-->@] to [@%3c!--HTMLHeader-->@] in skin templates, and added an optional [@%3c!--HTMLFooter-->@] directive (PITS:00767).%0a* Adjusted the pmwiki and print skins to use the new directives.%0a%0a!!!Version 2.1.15 (2006-08-25)%0a* Fixed issue dealing with order of [@@_site_*@] passwords (reported by Jean-Fabrice and others).%0a* Added $LocalDir variable (requested by John Rankin).%0a* Removed an unnecessary setting of $DefaultPage in ''scripts/pgcust.php'' (it's now handled by ResolvePageName() ).%0a* Added some variables and changes in wikistyles.php to better support wikipublisher (contributed by John Rankin).%0a* RetrieveAuthPage (PmWikiAuth) now recognizes a $level of 'ALWAYS' as indicating that access should always be allowed, regardless of current passwords or identities.%0a* Added filter specifier for AuthUser LDAP authentication (contributed by Balu).%0a%0a!!!Version 2.1.13, 2.1.14 (2006-08-15, 2006-08-16)%0a* Updated scripts/authuser.php to allow ldaps://... authentications (contributed by Michael Brenner).%0a* Fixed problem with numeric passwords introduced in 2.1.beta20 (reported by Christophe David and Dirk Blaas).%0a%0a!!!Version 2.1.12 (2006-08-07)%0a* Corrected typo in Site.SideBar file (reported by Judith Zacharie).%0a* Suppressed warning message for search on sites without a wikilib.d/ directory.%0a* Added capability for nested divs.%0a* Use $Transition['nodivnest'] to restore previous non-nesting div/table behavior.%0a* Including authuser.php now automatically resolves pagename.%0a* Added [@(:noaction:)@] directive to turn off actions.%0a* Fixed bug in wikistyles prior to image blocks.%0a* Added white-space as allowed wikistyle (suggested by C. Ridderström).%0a* Allow colons, hyphens, and dots in id= tags.%0a%0a!!!Version 2.1.11 (2006-06-09)%0a* Fixed generation of empty paragraphs around [@%25define=...%25@] wikistyles (PITS:00753).%0a%0a!!!Version 2.1.10 (2006-06-04)%0a* Added a %3cspan> around the RecentChanges link in the pmwiki skin (PITS:00750, suggested by Hagan Fox).%0a* Changed the $Action variable to $ActionTitle (PITS:00749, reported by Hagan Fox).%0a* Changed $FPLTemplatePageFmt to be an array of pages to be searched for page templates, enabled searching of current page and Site.LocalTemplates page.%0a* Updated .vspace margin in sidebar for pmwiki skin (PITS:00751, by Hagan Fox).%0a%0a%0a!!!Version 2.1.9 (2006-06-02)%0a* Fixed a bug with [@[[~Author]]@] links (PITS:00530 reported by Klonk, PITS:00611 reported by weijang, PITS:00671 reported by Stirling Westrup, and helpful clues provided by Clayton Curtis).%0a%0a!!!Version 2.1.8 (2006-06-01)%0a* Added ability to specify notification entries from ''local/config.php'' as well as Site.Notify (suggested by Christophe David).%0a* Fixed $Transition['vspace'] from 2.1.7.%0a%0a!!!Version 2.1.7 (2006-05-31)%0a* Adjusted width of edit form for IE browsers (contributed by Roman and H. Fox).%0a* Suppress authentication failure error from LDAP (PITS:00739).%0a* Fixed problem with invalid page names resulting in redirect loop (PITS:00723, reported by jojoo).%0a* Added "Group." and "Group/" page name syntax, resolving PITS:00736 (from a suggestion by Pico).%0a* Changed handling of "vspace" paragraphs.%0a* Fixed some XSS vulnerabilities in uploads.php and url links (reported by Moritz Naumann, http://moritz-naumann.com).%0a* Added notify.php script, allowing finer control of email notifications.%0a%0a!!!Version 2.1.6 (2006-05-22)%0a* Optimized performance of urlapprove.php.%0a* Added [@(:if auth xyz PageName:)@] syntax.%0a* Corrected XSS bug in trails.php.%0a* Slightly improved performance of free links.%0a* Restore ability to use hyphens in InterMap links (reported by Henrik Bechmann).%0a%0a!!!Version 2.1.4, 2.1.5 (2006-03-29)%0a* Fixed problem with pagelist-based feeds (PITS:00709, reported by Jon Haupt).%0a* Added [@{$Action}@] page variable. (PITS:00696, reported by Sebastian Pipping).%0a* Added stripmagic() around variables submitted to authuser.php.%0a* Fixed problem with multi-term searches containing special characters (PITS:00713, reported by Leo).%0a* Switched [[PageDirectives#attachlist| [@(:attachlist:)@] ]] to use a natural case sort (suggested by H. Fox).%0a%0a!!!Version 2.1.3 (2006-03-17)%0a* Re-fixed problem with PHP 5.1.1 and lines= option to [@(:include:)@] (PITS:00620).%0a* Fixed empty LDAP password issue (reported by Thomas Lederer).%0a%0a!!!Version 2.1.2 (2006-03-16)%0a* Fixed %3ch1>/%3ch2> tag mismatches (PITS:00702, reported by Martin Hason).%0a* Fixed bug with $AllowPassword and "nopass" (reported by M. Weiner and bram brambring).%0a* Improved the speed of RSS and other web feeds when $EnablePageListProtect is not set.%0a%0a!!!Version 2.1.1 (2006-03-13)%0a* Fixed a bug with multiple authorization groups as a password (PITS:00699, reported by Ari Epstein).%0a* Updated the authorization code to be a bit more liberal with password/group settings.%0a* Updated PmWiki.FAQ page to be able to grab FAQ items from other pages in the documentation.%0a%0a!!Version 2.1.0 (2006-03-12)%0a* Many many documentation updates (special thanks to many authors).%0a* Allow trailing underscores in upload names (requested by Hans).%0a* Fixed 'ak_print' problem causing accesskey='a' for print (noted by Pico).%0a* Added code to make sure each anchor is generated only once per page (for XHTML validity).%0a* Added a $BlockPattern variable to recognize block HTML tags.%0a* Made an adjustment to Keep() so that it places strings with block HTML into the 'B' pool.%0a* Adjusted stdmarkup.php to not produce paragraphs for keep blocks in the 'B' pool.%0a* Corrected a variety of i18n phrases.%0a* Added class='escaped' to distinguish [=@@...@@=] from [=[@...@]=] (from a comment by Hans).%0a* Slightly changed styling of .faq divs.%0a* Made the edit textarea a couple of rows smaller to better fit on smaller displays (suggested by H. Fox).%0a----%0a[[(PmWiki:)ChangeLog Archive]] - changes prior to version 2.1.0.%0a
+time=1266769694
diff --git a/wikilib.d/PmWiki.ConditionalMarkup b/wikilib.d/PmWiki.ConditionalMarkup
new file mode 100644
index 0000000..dbd0bae
--- /dev/null
+++ b/wikilib.d/PmWiki.ConditionalMarkup
@@ -0,0 +1,11 @@
+version=pmwiki-2.2.10 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6 (.NET CLR 3.5.30729)
+author=DaveG
+charset=ISO-8859-1
+csum=Removed 'action' conditional markup; not defined in PmWiki
+host=173.72.32.221
+name=PmWiki.ConditionalMarkup
+rev=151
+targets=PmWiki.ReleaseNotes,PmWiki.ChangeLog,PmWiki.AuthUser,PmWiki.WikiTrails,PmWiki.PageTextVariables,PmWiki.PageVariables,PmWiki.MarkupExpressions,PmWiki.PageListTemplates,Site.PageListTemplates,Cookbook.ConditionalMarkupSamples
+text=(:Summary:The if directive allows portions of a page to be included or excluded from rendering:)%0a%25define=indent block margin-left=2em%25%0a(:Audience: authors, admins (advanced) :)%0a!! Using the [=(:if:)=] Directive%0aThe [@(:if:)@] directive allows portions of a page to be included or %0aexcluded from rendering. The generic forms of the [@(:if:)@] directive are%0a%0a-> [@(:if cond param:) body (:ifend:)@]%0a-> [@(:if cond param:) body (:else:) body (:ifend:)@]%0a-> [@(:if cond param:) body (:elseif cond param:) body (:ifend:)@] '^see [[PmWiki/ReleaseNotes#elseifelse|#]] [[PmWiki/ChangeLog#beta32|#]]^'%0a%0awhere "cond" names a [[#built-in-conditions | condition to be tested]], and "param" is a parameter or other argument to the condition.%0a%0a!! Markup Shortcut%0aYou can also use an abbreviated form of [@(:ifend:)@], [@(:if:)@] for brevity:%0a-> [@(:if cond1:) cond1 is true (:if:)@]%0a-> [@(:if cond1:) cond1 is true (:if cond2:) cond2 is true (:if:)@]%0aThe latter is identical to :%0a-> [@(:if cond1:) cond1 is true (:ifend:)(:if cond2:) cond2 is true (:ifend:)@]%0a%0a!! Built-in Conditions [[#built-in-conditions]]%0aThe built-in conditions include:%0a%0a(:table class='indent' border=0 cellpadding=0 cellspacing=0 valign=top:)%0a(:cellnr:)[@(:if name PAGENAME:)@]%0a(:cell:) - %0a(:cell:)current page is named "[@PAGENAME@]"%0a(:cellnr:)[@(:if group GROUPNAME:)@]%0a(:cell:) - %0a(:cell:)current group is named "[@GROUPNAME@]"%0a(:cellnr:)[@(:if auth LEVEL PAGENAME:)@]%0a(:cell:) - %0a(:cell:)viewer is authorized - meaning "what they are allowed to do" - matches a "[@LEVEL@]" where [@LEVEL@] can be: [@read@], [@edit@], [@upload@], [@attr@] or [@admin@]; [@PAGENAME@] is optional.%0a(:cellnr:)[@(:if authid:)@]%0a(:cell:) - %0a(:cell:)current viewer is authenticated - meaning they have proven who they are via login - to use this the wiki must include recipe [[PmWiki/AuthUser|AuthUser]] or others which set the [@$AuthId@] variable.%0a(:cellnr:)[@(:if enabled InvalidLogin:)@]%0a(:cell:) - %0a(:cell:)username and password not authenticated. To use this the wiki must include recipe AuthUser.%0a(:cellnr:)[@(:if true:)@]%0a(:cell:) - %0a(:cell:)always include text%0a(:cellnr:)[@(:if false:)@]%0a(:cell:) - %0a(:cell:)always exclude text (same as a comment)%0a(:cellnr:)[@(:if attachments:)@]%0a(:cell:) - %0a(:cell:)current page has one or more attachments%0aIf used in a sidebar, header, or footer the condition applies to the main page.%0a(:cellnr:)[@(:if date DATE VALUE:)@]%0a(:cell:) - %0a(:cell:)[@DATE@] may be year-month. year-month-day is optional. %0aEvaluates to true if [@VALUE@] is within [@DATE@] ("now" or "today" is assumed if VALUE is omitted, as in the following examples.) (Note that [@VALUE@] can be a recognizable date via strtotime() whereas DATE [or DATE1 and DATE2 below] have a more fixed format which explicitly must exclude spaces. Any spaces in DATE1 or DATE2 cause unpredictable results.)%0a(:cellnr:)[@(:if date DATE.. VALUE:)@]%0a(:cell:) - %0a(:cell:)true if [@VALUE@] (or current date if omitted) is [@DATE@] or later (unlimited)%0a(:cellnr:)[@(:if date ..DATE VALUE:)@]%0a(:cell:) - %0a(:cell:)true if [@VALUE@] (or current date if omitted) is [@DATE@] or earlier (unlimited)%0a(:cellnr:)[@(:if date DATE1..DATE2 VALUE:)@]%0a(:cell:) - %0a(:cell:)true if [@VALUE@] (or current date if omitted) is in range [@DATE1@] to [@DATE2@] (inclusive) %0a%25green newwin%25[-''dates are in [[http://w3.org/QA/Tips/iso-date|standard]] format yyyy-mm-dd or yyyymmdd or yyyymmddThhmm (note the "T" between the date and the hour, and also see comment above on format of VALUE).-]''%0a[[%3c%3c]][-Note the ".." cannot have leading or trailing spaces.-]%0a(:cellnr:)[@(:if enabled VAR:)@]%0a(:cell:) - %0a(:cell:)true if PHP VAR is true%0a(:cellnr:)[@(:if enabled AuthPw:)@]%0a(:cell:) - %0a(:cell:)true if user has entered any password during the current browser session.%0a- This does not mean the user has entered the correct password, just that they entered one.%0a(:cellnr:)[@(:if equal STRING1 STRING2:)@]%0a(:cell:) - %0a(:cell:)true if [@STRING1@] equals [@STRING2@], use quotes if the string or string variable contains spaces, eg [@"MY STRING"@]%0a(:cellnr:)[@(:if match REG_EXPRESSION:)@]%0a(:cell:) - %0a(:cell:)true if current page name matches the regular expression%0a(:cellnr:)[@(:if exists PAGENAME:)@]%0a(:cell:) - %0a(:cell:)true if the page ''pagename'' exists%0a(:cellnr:)[@(:if ontrail WikiTrailPage ThisPage:)@]%0a(:cell:) - %0a(:cell:)true if ThisPage is in a list used as a [[wiki trails | trail]] on WikiTrailPage%0a(:tableend:)%0a%0aThe name and group conditionals will work even for an included page, as the "name" and "group" conditionals always check the currently displayed page, as opposed to the page that the markup appears in.%0a%0a'''Note''': Although there is no built-in conditional markup to test ?action=, you can use [@(:if equal {$Action} ACTION:)@]%0ato test what the current action being requested is.%0a%0a!! Negated Conditions%0aNegated forms of conditions also work:%0a%0a(:table class='indent' border=0 cellpadding=0 cellspacing=0 valign=top:)%0a(:cellnr:)[@(:if !attachments:)@]%0a(:cell:) - %0a(:cell:)this page has no attachments%0a(:cellnr colspan=3:) %0a(:cellnr:)[@(:if ! name PAGENAME:)@]%0a(:cell rowspan=3:)%0a(:cell rowspan=3 valign=middle:)current page is NOT named "[@PAGENAME@]"%0a(:cellnr:)[@(:if name -PAGENAME :)@]%0a(:cell:)%0a(:cellnr:)[@(:if name !PAGENAME :)@]%0a(:tableend:)%0a%0a!! Nesting Conditions [[#nested-conditions]]%0aConditions may be nested (from 2.2.beta 66).%0a%0aNested [@(:if:)@] works the same way as nested [@(:div:)@]. To have nested conditionals you need to number the if, and the matching else/ifend:%0a->[@%0a(:if cond1:)%0a cond1 is true%0a (:if2 cond2:)%0a cond1 and cond2 are true%0a (:else2:)%0a cond1 is true, cond2 is not%0a (:if2end:)%0a(:else:)%0a cond1 is false, cond2 testing was skipped%0a(:ifend:)%0a@]%0a[-''Spaces were added for better readability.''-]%0a%0a!! Using wildcard placeholders(:if false:)%25green%25[-(new for pmwiki 2.1.beta21)-]:(:ifend:)%0aThe character [@*@] can be used as a wildcard to represent any character, zero, one, or multiple times.\\%0aThe character [@?@] can be used as a wildcard to represent any character exactly once.\\%0aWildcard characters ([@*@] and [@?@]) can be used with the ''name'' and ''group'' conditional markups, thus:%0a%0a(:table class='indent' border=0 cellpadding=0 cellspacing=0 valign=top:)%0a(:cellnr:)[@(:if name PmCal.2005* :)@]%0a(:cell:) - %0a(:cell:)current page is in group PmCal and begins with 2005%0a(:cellnr:)[@(:if group PmWiki* :)@]%0a(:cell:) - %0a(:cell:)current page is in group PmWiki or a group beginning with PmWiki%0a(:cellnr:)[@(:if name Profiles.*,-Profiles.Profiles :)@]%0a(:cell:) - %0a(:cell:)current page is in group [@Profiles@] but not [@Profiles.Profiles@]%0a(:tableend:)%0a%0a!!Using [[PmWiki/page text variables]], [[PmWiki/page variables]] and [[PmWiki/markup expressions]]%0aPage text variables (PTVs), page variables (PVs) and markup expressions can be used in conditional markup. They will be assigned/evaluated before the condition(s). %0a%0a!! Use with [[PmWiki/page list templates]]%0aConditional markup is used extensively with [[Site/page list templates]].%0a%0aUse with page variables:%0a-> = current item%0a-> %3c previous item%0a-> > next item%0a%0aConditionals used to structure pagelist output:%0a [@(:if equal {%3c$Group}:)@] deprecated in favour of [@(:template first:)@] At beginning of list%0a [@(:if equal {>$Group}:)@] deprecated in favour of [@(:template last:)@] At end of list%0a [@(:if ! equal {=$Group} {%3c$Group}:)@] deprecated in favour of [@(:template first {=$Group}:)@] First item in group%0a [@(:if ! equal {=$Group} {>$Group}:)@] deprecated in favour of [@(:template last {=$Group}:)@] Last item in group%0a%0a!! Combining conditions%0aConditions (as previously defined) may be combined into more complex conditional expressions using one of these three equivalent forms:%0a%0a->[@%0a(:if expr EXPRESSION :)%0a(:if [ EXPRESSION ] :)%0a(:if ( EXPRESSION ) :)@]%0a%0aConditions are combined into expressions with boolean operators and brackets. In the next table, A and B are either regular conditions or (round-)bracketed sub-expressions of regular conditions:%0a%0a>>indent%3c%3c%0a|| border=1 cellpadding=2 cellspacing=0%0a||! Expression ||! Operator ||! Result ||%0a|| [@A and B@] || And ||TRUE if both A and B are TRUE.||%0a|| [@A or B@] || Or ||TRUE if either A or B is TRUE.||%0a|| [@A xor B@] || Xor ||TRUE if either A or B is TRUE, but not both.||%0a|| [@! A@] || Not ||TRUE if A is not TRUE.||%0a|| [@A && B@] || And ||TRUE if both A and B are TRUE.||%0a|| [@A || B@] || Or ||TRUE if either A or B is TRUE.||%0a>>%3c%3c%0a%0aExample%0a->[@%0a(:if [ name SomePage and group SomeGroup ]:) equivalent to (:if name SomeGroup.SomePage:)@]%0a%0a'''Important Notes:'''%0a* Spaces are ''required'' around operators and brackets.%0a* No specific feedback is given for syntax errors or unbalanced brackets.%0a* Use round brackets (not square) for nested expressions.%0a%0aThus, the following is a valid way of building an expression that shows the following contents only when the user is either the administrator, or is logged in and the time is later than the given date:%0a%0a->[@(:if [ auth admin || ( authid && date 2006-06-01.. ) ] :)@]%0a%0aNesting with square brackets will silently fail to work as expected:%0a%0a->[@(:if [ auth admin || [ authid && date 2006-06-01 ] ] :) @] %25red%25NOTE: Doesn't Work!%0a%0aA common use of these complex tests are for expressions like:%0a%0a->[@(:if expr auth admin || auth attr || auth edit :)@]%0a->[@[[Logout -> {$Name}?action=logout]]@]%0a->[@(:ifend:)@]%0a%0awhich provides a ''logout'' link only when the browser has admin, attr, or edit permissions.%0a%0a%25audience%25 admins (advanced)%0a!! Creating new conditions%0aSee [[Cookbook:ConditionalMarkupSamples]].%0a%0aSee also [[PmWiki/PageVariables#specialreferences|special references]] for the use of [={*$Variables}=].%0a%0a>>faq%3c%3c [[#faq]]
+time=1264480206
diff --git a/wikilib.d/PmWiki.Contributors b/wikilib.d/PmWiki.Contributors
new file mode 100644
index 0000000..d55b917
--- /dev/null
+++ b/wikilib.d/PmWiki.Contributors
@@ -0,0 +1,12 @@
+version=pmwiki-2.2.4 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.19) Gecko/20081216 Ubuntu/8.04 (hardy) Firefox/2.0.0.19
+author=Petko
+charset=ISO-8859-1
+csum=-updateme
+host=86.69.109.9
+name=PmWiki.Contributors
+post= Save
+rev=57
+targets=PmWiki.PmWiki,PmWiki.Uploads,PmWiki.Links,PmWiki.WikiGroup
+text=(:Summary:A list of contributors to PmWiki development and improvement:)%0aHere's a list of contributors to [[PmWiki]] development and improvement. My apologies if I've forgotten anyone -- feel free to add your name if you've been left out, feel free to remove your name if you don't want to be associated with these people. :-)%0a%0a* GNUZoo - Several recipes, some security and bug fixes%0a* Scott Duff - pmwe, simple-journal.php, all-around Pm sanity checker %0a* Ross Kowalski - [[uploads]] and printable page research%0a* John Rankin - WikiTrails, [[Links]], `EditQuickReference, notify.php, documentation, debugging%0a* Joachim Durchholz - hacking documentation, general pest%0a* Jessica Tishmack - uploads, testing%0a* Jean-Claude Gorichon - voting%0a* Janice Heinold - early PmWiki testing and suggestions, documentation%0a* James Davis - WikiStyles markup, testing%0a* Isabelle Michaud - floating images markup, [[Wiki Group]]s, [[uploads]]/attachments%0a* Glenn Blalock - WikiStyles suggestions, testing, documentation%0a* Dawn Green - WikiStyles suggestions, [[uploads]], documentation%0a* Christian Ridderström - [[Cookbook:EmacsPmWikiMode |pmwiki-mode for Emacs]] and some other hacks/modifications.%0a* Carlo Strozzi - Internationalization, PmWiki on Boa, HTML redirection%0a* Michael Weiner - Modifications to the ToDo, RssFeedDisplay, MyPmWiki, and CommentBox recipes%0a* Criss Ittermann (aka Crisses/XES) - ye old best seller Blocklist2 that topped the charts for a while and many other recipes%0a* Rev. Dr. Ian MacGregor - I've contributed with monetary donations, skins, bug reports and continued testing. [[http://ardchoille.nfshost.com/ | My home page]]'^broken link^' is powered by PmWiki.%0a
+time=1251041328
diff --git a/wikilib.d/PmWiki.CreatingNewPages b/wikilib.d/PmWiki.CreatingNewPages
new file mode 100644
index 0000000..e3aaf25
--- /dev/null
+++ b/wikilib.d/PmWiki.CreatingNewPages
@@ -0,0 +1,12 @@
+version=pmwiki-2.2.6 ordered=1 urlencoded=1
+agent=Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; GTB6; .NET CLR 1.0.3705)
+author=SchreyP
+charset=ISO-8859-1
+csum=improve first section and one FAQ, remove double link in learn more
+host=81.243.199.60
+name=PmWiki.CreatingNewPages
+rev=93
+targets=PmWiki.Links,PmWiki.MyNewPage,Site.SideBar,PmWiki.WikiGroup
+text=(:Summary:How to create a new page:)%0a(:title Creating New Pages:)%0a(:Audience: authors (basic) :)%0aThe first step to create a new page, you need to edit an existing page, and on it add a link to the page you want to create. %0a%0a-> To link to your new page, you must choose a name for it. The best names describe the page's contents well, so that everyone can remember and type the name easily.%0a%0a-> To create a link, surround the page name with '''double brackets'''. Typing [@[[my new page]]@] will create a link to [[my new page]]. There's [[a lot you can do -> Links]] with double bracket links.%0a%0aYou can see that the links to [[my new page]] all have question marks after them. That's because [[my new page]] hasn't been written yet. Clicking the link as second step will take you to an edit form where you could write and finally save the new page. %0a%0a----%0aAnother way to create a page: in your browser's address bar (where the page URL is), replace the name of the current page with the name of the page you wish to create, and hit Enter or do whatever you would normally do to go to a new location. PmWiki will then dutifully tell you that the page you entered doesn't exist, but you can click on the "Edit" link in order to create, edit, and save the new page.%0a%0aThe bad thing about this method is that there are no links to your new page, so you're the only person who knows it is there. It will be an orphan, unread, unlinked, unloved. That's why adding a link to an existing page or to the [[Site/SideBar]] is a better way to create a page.%0a----%0a%0aLearn more:%0a* You can also organize related pages into [[wiki group | groups]], and link between pages in different groups.%0a%0a>>faq%3c%3c [[#faq]]%0a[[#beginning]]%0aQ: How do I create a new page?%0aA: Typing [=[[my new page]]=] will create a link to the new page. There's [[PmWiki.Links | a lot you can do]] with double bracket links.%0a%0aQ: Why do some new pages have a title with spaces like "Creating New Pages" and others end up with a WikiWord-like title like "CreatingNewPages"?%0aA: The default page title is simply the name of page, which is normally stored as "CreatingNewPages." However, you can override a page's title by using the [@(:title Creating New Pages:)@] directive. This is especially useful when there are special characters or capitalization that you want in the title that cannot be used in the page name.%0a
+time=1255895771
+title=Creating New Pages
diff --git a/wikilib.d/PmWiki.CustomInterMap b/wikilib.d/PmWiki.CustomInterMap
new file mode 100644
index 0000000..fd0f7e9
--- /dev/null
+++ b/wikilib.d/PmWiki.CustomInterMap
@@ -0,0 +1,12 @@
+version=pmwiki-2.2.2 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.19) Gecko/20081216 Ubuntu/8.04 (hardy) Firefox/2.0.0.19
+author=Petko
+charset=ISO-8859-1
+csum=links to pages not in the distribution should be absolute
+host=81.65.14.164
+name=PmWiki.CustomInterMap
+rev=48
+targets=PmWiki.InterMap,PmWiki.WikiAdministrator,Site.InterMap,PmWiki.WikiFarms,PmWiki.Upgrades
+text=(:Summary:PmWiki's default [[PmWiki/InterMap]] links, and how to can create additional InterMap links:)%0a(:title Custom InterMap:)%0a(:Audience: administrator (intermediate) :)%0a%0aThis page describes PmWiki's default [[InterMap]] links, and how a [[wiki administrator]] can create additional InterMap links.%0a%0aAn intermap entry takes the following format:%0a%0a-> [@%0aMapPrefix: http://example.com/partial/url/%0a@]%0a%0aThe InterMap entry can be for any of the [[(PmWiki:)link schemes]] supported by PmWiki.%0a[[%3c%3c]]%0aYou can create your own InterMap links by doing one or more of the following:%0a%0a* Modify the page called ''[[{$SiteGroup}.InterMap]]'' and place entries like the ones above in it.%0a* Create a file called ''local/localmap.txt'' and place entries like the%0a ones above in it.%0a* In a [[WikiFarm(s)]] installation you can create a file called%0a ''local/farmmap.txt'' and there place entries like the ones above in it.%0a These prefixes will be common to all the wikis in the farm.%0a* Ensure that there is a space after the colon%0a%0aDo not edit the file ''scripts/intermap.txt'' directly! If you do, you'll%0alose your changes when you [[PmWiki/upgrade(s)]] PmWiki.%0a%0a%0a!! Variables and InterMap links%0a%0aIt's possible to use variables within your InterMap entries. The following%0aentries create [@ThisWiki:@] and [@ThisPage:@] shortcuts:%0a%0a-> [@%0aThisWiki: $ScriptUrl%0aThisPage: {$PageUrl}%0a@]%0a%0aYou can also define InterMap entries where the text of the entry is%0asubstituted into the middle of the URL. Just include '$1' in the URL where%0ayou want the substitution to take place. For example:%0a%0a->[@Jargon: http://catb.org/~esr/jargon/html/$1.html@]%0a%0awould cause [@Jargon:F/feature-creep@] to be converted to [@http://catb.org/~esr/jargon/html/F/feature-creep.html@].%0a%0a%0a!! Tips and tricks%0a%0aIt is possible to document your intermap prefixes directly in the page%0a[[Site.InterMap]]. The extra text will not cause a performance penalty, nor%0awill it break the definition of prefixes. However, be aware that anything%0amatching a line starting with a word and a colon (''':''') will be%0aconsidered to define a prefix.%0a%0aThe order in which various sources are checked for definitions of prefixes%0ais controlled by the variable $InterMapFiles. Currently the precedence%0a(highest to lowest is as follows):%0a* ''local/localmap.txt''%0a* ''$SiteGroup.InterMap''%0a* ''$FarmD/local/farmmap.txt''%0a* ''$FarmD/scripts/intermap.txt''%0a%0a!! PmWiki InterMaps%0a(:include PmWiki/InterMap#custominclude#customincludeend:)%0a%0a>>faq%3c%3c [[#faq]]%0a%0aQ: Are InterMap names case sensitive?%0aA: Yes, thus [@eAdmin:@] is a different InterMap link than [@EAdmin:@].%0a%0aQ: How can I achieve a ''localmap.txt'' mapping with the effect of [@Pics: Path:/somepathto/pics/@]?%0aA: Use the following:%0a->[@Pics: /somepathto/pics/@]%0a%0a%0aQ: How can I define an InterMap in PHP?%0aA: Use the following:%0a->[@%0a $LinkFunctions['PmWikiHome:'] = 'LinkIMap';%0a $IMap['PmWikiHome:'] = 'http://pmwiki.org/wiki/$1';%0a@]%0a%0a%0a%0a%0a
+time=1247526419
+title=Custom InterMap
diff --git a/wikilib.d/PmWiki.CustomMarkup b/wikilib.d/PmWiki.CustomMarkup
new file mode 100644
index 0000000..6ad4ea9
--- /dev/null
+++ b/wikilib.d/PmWiki.CustomMarkup
@@ -0,0 +1,11 @@
+version=pmwiki-2.2.10 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20100106 Ubuntu/9.10 (karmic) Firefox/3.5.7
+author=Walter Keller
+charset=ISO-8859-1
+csum=
+host=85.2.209.6
+name=PmWiki.CustomMarkup
+rev=125
+targets=PmWiki.CustomMarkup,PmWiki.LocalCustomizations,Cookbook.ParseArgs,Cookbook.JavaScript,Cookbook.JavaScript-Editable,PmWiki.Skins,Cookbook.LinkTitles,PmWiki.CustomMarkupAlt
+text=(:Summary: Using the Markup() function for custom wiki syntax:)%0a(:Audience: administrators (intermediate) :)%0a!! Introduction%0a%0aPmWiki's markup translation engine is handled by a set of rules; each rule searches for a specific pattern in the markup text and replaces it with some replacement text. Internally, this is accomplished by using PHP's "[[(http://www.php.net/)preg_replace]]" function.%0a%0aRules are added to the translation engine via PmWiki's Markup() function, which looks like%0a%0a->[@Markup($name, $when, $pattern, $replace);@]%0a%0awhere [@$name@] is a unique name (a string) given to the rule, [@$when@] says when the rule should be applied relative to other rules, [@$pattern@] is the pattern to be searched for in the markup text, and [@$replace@] is what the pattern should be replaced with.%0a%0aFor example, here's the code that creates the rule for [@''emphasized text''@] (in ''scripts/stdmarkup.php''):%0a%0a->[@Markup("em", "inline", "/''(.*?)''/", "%3cem>$1%3c/em>");@]%0a%0aBasically this statement says to create a rule called "em" to be performed with the other "inline" markups, and the rule replaces any text inside two pairs of single quotes with the same text ($1) surrounded by [@%3cem>@] and [@%3c/em>@].%0a%0aThe first two parameters to Markup() are used to specify the sequence in which rules should be applied. The first parameter provides a name for a rule -- "[@em@]" in the example above. We could've chosen other names such as "[@''@]", or even "[@twosinglequotes@]". In general PmWiki uses the markup itself to name the rule (i.e., PmWiki uses "[@''@]" instead of "[@em@]"), but to keep this example easier to read later on we'll use a mnemonic name for now.%0a%0aThe second parameter says that this rule is to be done along with the other "inline" markups. PmWiki divides the translation process into a number of phases:%0a%0a[@%0a_begin start of translation%0afulltext translations to be performed on the full text %0asplit conversion of the full markup text into lines to be processed%0adirectives directive processing%0ainline inline markups%0alinks conversion of [[links]], url-links, and WikiWords %0ablock block markups%0astyle style handling %0a_end end of translation%0a@]%0a%0aThis argument is normally specified as a left-angle bracket ("before") or a right-angle bracket ("after") followed by the name of another rule. %0a%0aThus, specifying "inline" for the second parameter says that this rule should be applied when the other "inline" rules are being performed. If we want a rule to be performed with the directives -- i.e., before inline rules are processed, we would specify "directives" or "%3cinline" for the second parameter.%0a%0a->'- A significant rule in terms of ordering is "[={$var}=]" which substitutes variables -- if you say "%3c[={$var}=]" then your markup will be processed before variables are substituted whereas if you say ">[={$var}=]" then your markup will be processed after variables are substituted. -'%0a%0aThe third parameter is a Perl-compatible regular expression. Basically, it is a slash, a [[regular expression -> http://www.php.net/manual/en/reference.pcre.pattern.syntax.php]], another slash, and a set of optional [[modifiers -> http://www.php.net/manual/en/reference.pcre.pattern.modifiers.php]].%0a%0aThe example uses the pattern string [@"/''(.*?)''/"@], which uses [@''(.*?)''@] as the regular expression and no options. (The regular expression says "find two single quotes in succession, then as few arbitrary characters as are needed to make the match find something, then two additional single quotes in succession"; the parentheses "capture" a part of the wikitext for later use.)%0a%0aThe fourth parameter is the replacement text that should be inserted instead of the marked-up wikitext. You can use [@$1@], [@$2@], etc. to insert the text from the first, second etc. parenthesised part of the regular expression.%0a%0aIn the example, we have [@"%3cem>$1%3c/em>"@], which is an [@%3cem>@], the text matched by the first parentheses (i.e. by the [@.*?@] section of the pattern), and [@%3c/em>@].%0a%0aHere's a rule for [@@@monospaced@@@] text:%0a%0a->[@Markup("@@", "inline", "/@@(.*?)@@/", "%3ccode>$1%3c/code>");@]%0a%0aand for a [@[:comment ...:]@] directive that is simply removed from the output:%0a%0a->[@Markup("comment", "directives", "/\\[:comment .*?:\\]/", '');@]%0a%0aOkay, now how about the rule for [@'''strong emphasis'''@]? We have to be a bit careful here, because although this translation should be performed along with other inline markup, we also have to make sure that the rule for [@'''@] is handled ''before'' the rule for [@''@], because [@'''@] also contains [@''@]. The second parameter to Markup() can be used to specify the new rule's relationship to any other rule:%0a%0a->[@Markup("strong", "%3cem", "/'''(.*?)'''/", "%3cstrong>$1%3c/strong>");@]%0a%0aThis creates a rule called "strong", and the second parameter "%3cem" says to be sure that this rule is processed before the "em" rule we defined above. If we wanted to do something after the "em" rule, we would use ">em" instead. Thus, it's possible to add rules at any point in PmWiki's markup translation process in an extensible manner. (In fact, the "inline", "block", "directives", etc., phases above are just placeholder rules used to provide an overall sequence for other rules. Thus one can use "%3cinline" to specify rules that should be handled before any other inline rules.) %0a%0aIf you want to disable available markup just call e.g.:%0a%0a->[@DisableMarkup("strong")@]%0a%0aPmWiki's default markup rules are defined in the ''scripts/stdmarkup.php'' file. To see the entire translation table as the program is running, the scripts/diag.php module adds "[@?action=ruleset@]", which displays the set of defined markup rules in the sequence in which they will be processed. You can see it at [[CustomMarkup?action=ruleset | CustomMarkup?action=ruleset]]. You must first enable the action by setting $EnableDiag = 1 in your configuration file.%0a%0a!! Other common examples%0a%0a!!! Define a custom markup to produce a specific HTML or Javascript sequence%0a%0aSuppose an admin wants to have a simple "[@(:example:)@]" markup that will always produce a fixed HTML string in the output, such as for a webring, Google AdSense display, or Javascript. The Markup() call to do this would be:%0a%0a->[@%0aMarkup('example', 'directives',%0a '/\\(:example:\\)/',%0a Keep("%3cdiv class='example'>%3cp>Here is a %0a %3ca target='_blank' href='http://www.example.com'>link%3c/a> to%0a %3cem>example.com%3c/em>%3c/p>%3c/div>") );%0a@]%0a%0a* The first argument is a unique name for the markup ("example").%0a* The second argument says to perform this markup along with other directives.%0a* The third argument is the pattern to look for "(:example:)".%0a* The fourth argument is the HTML that "(:example:)" is to be replaced with. We use the Keep() function here to prevent the output from being further processed by PmWiki's markup rule -- in the above example, we don't want the http://www.example.com url to be again converted to a link.%0a%0a[[#random]]%0a!!! Define a markup to call a custom function that returns content%0a%0aAn 'e' option on the [@$pattern@] parameter will cause the [@$replace@] parameter to be treated as a PHP expression to be evaluated instead of replacement text. Thus, a markup to produce a random number between 1 and 100 might look like:%0a%0a->[@%0aMarkup('random', 'directives',%0a '/\\(:random:\\)/e',%0a "rand(1, 100)");%0a@]%0a%0aThis calls the PHP built-in rand() function and substitutes the directive with the result. Any function can be called, including functions defined in a [[local customization(s)]] file.%0a%0aArguments can also be passed by using regular expression capturing parentheses, thus%0a%0a->[@%0aMarkup('randomargs', 'directives',%0a '/\\(:random (\\d+) (\\d+):\\)/e',%0a "rand('$1', '$2')");%0a@]%0a%0awill cause the markup [@(:random 50 100:)@] to generate a random number between 50 and 100.%0a%0a->%25note%25 Note: Be very careful with the /e modifier in regular expressions; malicious authors may be able to pass strings that cause arbitrary and undesirable PHP functions to be executed.%0a%0aFor a PmWiki function to help with parsing arbitrary sequences of arguments and key=value pairs, see Cookbook:ParseArgs.%0a%0a%0a>>faq%3c%3c [[#faq]]%0aQ: How can I embed JavaScript into a page's output?%0aA: There are several ways to do this. The [[Cookbook:JavaScript]] recipe describes a simple means for embedding static JavaScript into web pages using [[custom markup]]. For editing JavaScript directly in wiki pages (which can pose various security risks), see the [[(Cookbook:)JavaScript-Editable]] recipe. For JavaScript that is to appear in headers or footers of pages, the [[skin(s)]] template can be modified directly, or %3cscript> statements can be inserted using the $HTMLHeaderFmt array.%0a%0aQ: How would I create a markup (''[=(:nodiscussion:)=]'') that will set a page variable (''[={$HideDiscussion}=]'') which can be used by ''[=(:if enabled HideDiscussion:)=]'' in [=.PageActions=]?%0aA: Add the following section of code to your config.php%0a-> [@%0aSDV($HideDiscussion, 0); #define var name%0aMarkup('hideDiscussion', '%3c{$var}',%0a '/\\(:nodiscussion:\\)/e', 'setHideDiscussion(true)'); %0afunction setHideDiscussion($val) { %0a global $HideDiscussion; %0a $HideDiscussion = $val;%0a} %0a@]%0a%0aThis will enable the @@[=(:if enabled HideDiscussion:)=]@@ markup to be used. If you want to print the current value of [={$HideDiscussion}=] (for testing purposes) on the page, you'll also need to add the line: \\%0a@@[=$FmtPV['$HideDiscussion'] = '$GLOBALS["HideDiscussion"]';=]@@%0a%0a%0aQ: PmWiki only supports tool tips for external links, can I use custom markup to add tool tips to internal links?%0aA: Yes, add the following custom markup to your config.php: \\%0a[= Markup('%25title%25', 'inline', '/%25title%25(.*?)"(.*?)"(.*?)%25%25/', '%3cspan title="$2">$1$3%3c/span>'); # Add tool tips to internal links, Example: %25title%25[[link"tool tip"]]%25%25 =]%0a%0aUse the markup with internal links such as: \\%0a[= %25title%25[[CookBook "cool" | Example]]%25%25 =]%0a%0aA: See also [[Cookbook:LinkTitles]].%0a%0aQ: It appears that (.*?) does not match newlines in these functions, making the above example inoperable if the text to be wrappen in %3cem> contains new lines.%0aA: If you include the "s" modifier on the regular expression then the dot (.) will match newlines. Thus your regular expression will be "/STUFF(.*?)/s". That s at the very end is what you are looking for. If you start getting into multi-line regexes you may be forced to look at the m option as well - let's anchors (^ and $) match not begin/end of strings but also begin/end of lines (i.e., right before/after a newline).%0a %0a%0aQ: How do I get started writing recipes and creating my own custom markup?%0aA: [[PmWiki:CustomMarkupAlt|(alternate) Introduction to custom markup for Beginners]]%0a
+time=1264710597
diff --git a/wikilib.d/PmWiki.CustomWikiStyles b/wikilib.d/PmWiki.CustomWikiStyles
new file mode 100644
index 0000000..93e58db
--- /dev/null
+++ b/wikilib.d/PmWiki.CustomWikiStyles
@@ -0,0 +1,11 @@
+version=pmwiki-2.2.0 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.19) Gecko/20081216 Ubuntu/8.04 (hardy) Firefox/2.0.0.19
+author=Petko
+charset=ISO-8859-1
+csum=rm link to a profile page that will not be in the core docs
+host=81.65.14.164
+name=PmWiki.CustomWikiStyles
+rev=46
+targets=PmWiki.WikiStyles,PmWiki.WikiAdministrator
+text=(:Summary: Predefined PmWiki styles & adding custom wiki styles:)%0a(:Audience: administrators (intermediate) :)%0aThis page describes the predefined [[Wiki Styles]] and how a [[Wiki Administrator]] can define additional [[Wiki Styles]] as a local customization for all pages (in local/config.php) or specific groups (in local/$Group.php).%0a%0aAll predefined [[Wiki Styles]] are setup in the global array $WikiStyle.%0aTo define your own [[Wiki Styles]], add the setting of the correspondent `WikiStyle within the array.%0a%0a[[#predef]]%0a!! Predefined Wiki Styles%0a%0aThe following array-values are set by [@scripts/wikistyles.php@] using the [[Cookbook:Functions#SDV |SDV()-function]] (so you can overwrite them by setting them prior in config.php or farmconfig.php):%0a%0a||width=70%25 border=1 cellpadding=3 cellspacing=0%0a||'''markup:''' ||'''definition:''' ||%0a||[[%3c%3c]]'''text colors:''' [[%3c%3c]] (equiv. to [@%25define=xxxx color=xxxx%25@] ||||%0a|| [@%25black%25@] ||[@$WikiStyle['black']['color'] = 'black';@] ||%0a|| [@%25white%25@] ||[@$WikiStyle['white']['color'] = 'white';@] ||%0a|| [@%25red%25@] ||[@$WikiStyle['red']['color'] = 'red';@] ||%0a|| [@%25yellow%25@] ||[@$WikiStyle['yellow']['color'] = 'yellow';@] ||%0a|| [@%25blue%25@] ||[@$WikiStyle['blue']['color'] = 'blue';@] ||%0a|| [@%25gray%25@] ||[@$WikiStyle['gray']['color'] = 'gray';@] ||%0a|| [@%25silver%25@] ||[@$WikiStyle['silver']['color'] = 'silver';@] ||%0a|| [@%25maroon%25@] ||[@$WikiStyle['maroon']['color'] = 'maroon';@] ||%0a|| [@%25green%25@] ||[@$WikiStyle['green']['color'] = 'green';@] ||%0a|| [@%25navy%25@] ||[@$WikiStyle['navy']['color'] = 'navy';@] ||%0a|| [@%25purple%25@] ||[@$WikiStyle['purple']['color'] = 'purple';@] ||%0a||[[%3c%3c]]'''list-styles:''' ||||%0a|| [@%25decimal%25@] ||[@$WikiStyle['decimal']['apply'] = 'list';@][[%3c%3c]][@$WikiStyle['decimal']['list-style'] = 'decimal';@] ||%0a|| [@%25roman%25@] ||[@$WikiStyle['roman']['apply'] = 'list';@][[%3c%3c]][@$WikiStyle['roman']['list-style'] = 'lower-roman';@] ||%0a|| [@%25ROMAN%25@] ||[@$WikiStyle['ROMAN']['apply'] = 'list';@][[%3c%3c]][@$WikiStyle['ROMAN']['list-style'] = 'upper-roman';@] ||%0a|| [@%25alpha%25@] ||[@$WikiStyle['alpha']['apply'] = 'list';@][[%3c%3c]][@$WikiStyle['alpha']['list-style'] = 'lower-alpha';@] ||%0a|| [@%25ALPHA%25@] ||[@$WikiStyle['ALPHA']['apply'] = 'list';@][[%3c%3c]][@$WikiStyle['ALPHA']['list-style'] = 'upper-alpha';@] ||%0a||[[%3c%3c]]'''special:''' ||||%0a||open links in a new browser-window: ||||%0a|| [@%25newwin%25@] ||[@$WikiStyle['newwin']['target'] = '_blank';@] ||%0a||Turns markup into a comment via display:none CSS ||||%0a|| [@%25comment%25@] ||[@$WikiStyle['comment']['display'] = 'none';@] ||%0a%0a!!Author-Defined Wiki Styles%0a%0a# The first index of the array defines the style name (e.g. mynewstyle, projectentry etc)%0a# the second index defines the attribute name (e.g. color, background-color, etc.)%0a# the value set defines the attribute value (e.g. red, bold, #00ffcc, etc.)%0a%0a'''Sample:''' If you want to define a (site-wide) style the same as the page style%0a->[@%25define=projectentry color:red%25@]%0ause%0a->[@$WikiStyle['projectentry']['color'] = 'red';@]%0a%0a%0aThe [@$WikiStyle['projectentry']['apply']@] variable may be defined if the wikistyle concerns a particular tag. It may be @@'item' (for li|dt), 'list' (for ul|ol|dl), 'div', 'pre', 'img', 'p'@@ or the combining @@'block' (for p|div|ul|ol|dl|li|dt|pre|h[1-6])@@. Example:%0a%0a [@$WikiStyle['top']['apply'] = 'item';@]%0a [@$WikiStyle['top']['class'] = 'top';@]%0a%0athen a markup%0a [@* %25top%25 An important list-item@]%0awill output%0a [@%3cli class="top">An important list-item%3c/li>@]%0a%0a!! Printer-Friendly Styles%0a%0aIf your custom-styles (in local/config.php) are getting very colorful it might be useful to disable them in print-view. This can be done easily by putting them into a condition.%0a%0a[@if($action!="print") {%0a // your custom-styles%0a}@]%0a%0a!!Notes%0a%0a!!!To be done:%0a%0a!!Questions:%0a'''I tried this but background didn't work, thou border and float worked?''' /Vincent 2008-04-08%0a[@%0a$WikiStyle['vMenu']['background']='#ffffcc' ;%0a$WikiStyle['vMenu']['float']='left' ;%0a$WikiStyle['vMenu']['border']='1px dotted red' ;%0a@]%0a->Try using [@$WikiStyle['vMenu']['background-color']='#ffffcc';@] -- unlike @@background@@, @@background-color@@ is defined in the $WikiStyleCSS array, which is checked for valid properties.%0a
+time=1234622201
diff --git a/wikilib.d/PmWiki.DebugVariables b/wikilib.d/PmWiki.DebugVariables
new file mode 100644
index 0000000..67231e4
--- /dev/null
+++ b/wikilib.d/PmWiki.DebugVariables
@@ -0,0 +1,12 @@
+version=pmwiki-2.2.0 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.19) Gecko/20081216 Ubuntu/8.04 (hardy) Firefox/2.0.0.19
+author=Petko
+charset=ISO-8859-1
+csum=+anchor [[#faq]]
+ctime=1156512549
+host=81.65.14.164
+name=PmWiki.DebugVariables
+rev=12
+targets=
+text=(:Summary:variables useful for debugging:)%0a%0a:$EnableDiag:%0a>>indent%3c%3c%0a(:include AvailableActions#BEGENABLEDIAG#ENDENABLEDIAG:)%0a>>%3c%3c%0a:$EnableIMSCaching:A variable which, when set equal to 1, recognizes the "If-Modified-Since" header coming from browsers and allows browsers to use locally cached pages. Disabled by default to help the administrator customize its page without needing permanent reloading.%0a%0a:$EnableStopWatch:This activates an internal stopwatch that shows how long it takes to render a page. (If you have a wiki that composes a HTML page from multiple pages, such as a normal layout with a sidebar, you'll get separate timings for each subpage and for the total page.)%0a%0a: :The timings can be displayed by adding [@%3c!--function:StopWatchHTML 1-->@] in the wiki template.%0a%0a: :Valid values are:%0a $EnableStopWatch = 0; # No timings (the default). No HTML will be generated.%0a $EnableStopWatch = 1; # Wall-clock timings only.%0a $EnableStopWatch = 2; # Wall-clock and CPU usage timings. Won't work on Windows.%0a%0a: :See [[(Cookbook:)Stopwatch]] for more details.%0a%0aSee also:%0a* scripts/refcount.php is useful for debugging%0a%0a%0a----%0a>>faq%3c%3c[[#faq]]%0aQ:Is it possible for someone with admin priviledges to always have access to debugging tools, without letting everyone else access them?%0aA:You can easily & automatically allow debugging for anyone with admin priviledges (meanwhile leaving it off for everyone else) by including this line in config.php - ''just be sure that 1) $EnableDiag is either null or set to 0, and 2) to include it near the end of config.php, AFTER declaring your passwords, and after any AuthUser or other priviledge settings'':%0a%0a-->@@if (CondAuth($pagename, 'admin')) $EnableDiag = 1; # allows admin to always call phpinfo, etc@@%0a%0a>>%3c%3c%0a
+time=1234622645
diff --git a/wikilib.d/PmWiki.DeletingPages b/wikilib.d/PmWiki.DeletingPages
new file mode 100644
index 0000000..11d3d8b
--- /dev/null
+++ b/wikilib.d/PmWiki.DeletingPages
@@ -0,0 +1,11 @@
+version=pmwiki-2.2.1 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/525.19 (KHTML, like Gecko) Chrome/1.0.154.53 Safari/525.19
+author=simon
+charset=ISO-8859-1
+csum=correct link
+host=203.97.214.12
+name=PmWiki.DeletingPages
+rev=28
+targets=PmWiki.WikiAdministrator,Site.AllRecentChanges,PmWiki.EditVariables,PmWiki.WikiGroup,PmWiki.Categories,PmWiki.RecentChanges
+text=(:Summary: Page maintenance:)%0aTo delete a page, edit the page, select (highlight) all text in the edit textarea and replace it with the single word%0a%0a->[@delete@]%0a%0aNote that it may be a good idea to add a comment to the field @@summary@@%0aexplaining why you deleted the page. (The field @@summary@@ is usually found%0ajust below the edit textarea).%0a%0aAfter saving the changes the page is deleted. As an added safety feature, the deleted page still exists on the server (with a timestamp) and can be restored to the former page by the [[wiki administrator]].%0a%0aIf you suspect that a page has been deleted but aren't sure, have a look at the wikigroup's [=RecentChanges=]. Erasing a page counts as editing the page, and the activity is recorded there and on [[{$SiteGroup}.AllRecentChanges]].%0a%0aThe default word used for page deletion ("delete") can be changed in config.php by setting the variable $DeleteKeyPattern (see [[Edit Variables]]). If there is a danger of malicious page deletion it may be a good idea to change the delete word to something more obscure. There is also a recipe for creating a separate delete action at Cookbook:DeleteAction.%0a%0a%0a>>faq%3c%3c [[#faq]]%0a%0aQ: Deleting [[Wiki Group]]s & [[Categories]]: Once I create a Group or Category, how can I get rid of that group or category?%0aA: An admin can just remove the unwanted pages from wiki.d/ . Normally, doing it via the wiki%0adoesn't resolve the problem, since it counts as an "update" which causes the [[Recent Changes]] page to be re-created, but it is possible to modify the site's configuration to allow deletion of the group's RecentChanges page -- see Cookbook:RecentChangesDeletion.%0a
+time=1238888092
diff --git a/wikilib.d/PmWiki.DesignNotes b/wikilib.d/PmWiki.DesignNotes
new file mode 100644
index 0000000..f0717c8
--- /dev/null
+++ b/wikilib.d/PmWiki.DesignNotes
@@ -0,0 +1,11 @@
+version=pmwiki-2.2.0-beta68 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; es-ES; rv:1.9.0.3) Gecko/2008092414 Firefox/3.0.3
+author=yo
+charset=ISO-8859-1
+csum=
+host=189.166.198.245
+name=PmWiki.DesignNotes
+rev=24
+targets=PmWiki.PmWikiPhilosophy,PmWiki.MailingLists,PmWiki.SimultaneousEdits,PmWiki.DesignNotes
+text=(:Summary:Some of the features and notes about PmWiki's design decisions:)%0aHere are some of the features and notes about PmWiki's design decisions. %0aMany of these derive directly from the [[PmWiki Philosophy]] and lots of discussion on the [[mailing lists]].%0a%0a* [[PmWiki:Flat File Advantages]] - why PmWiki uses flat files to store pages instead of an SQL database%0a* [[PmWiki:Hierarchical Groups]] - why PmWiki doesn't support nested groups%0a* [[PmWiki:Page Locking]] - how PmWiki works without locking pages (see also [[simultaneous edits]])%0a* [[PmWiki:Page File Format]] - the format of PmWiki's page files%0a* [[PmWiki:Search Improvements]] - why PmWiki has a native search engine%0a* [[PmWiki:File Permissions]] - some information about PmWiki's file permission settings%0a* [[PmWiki:Wiki Group Motivation]] - why WikiGroups%0a* [[PmWiki:WYSIWYG]] - why not WYSIWYG.%0a%0a>>faq%3c%3c [[#faq]]%0a%0aQ: Why doesn't PmWiki use hierarchical / nested groups?%0aA: It essentially comes down to figuring out how to handle %0apage links between nested groups; if someone can figure out %0aan obvious, intuitive way for authors to%0ado that, then nested groups become plausible. See [[Design Notes]]%0aand [[PmWiki:Hierarchical Groups]].%0a%0aQ: Why don't PmWiki's scripts have a closing ?> tag?%0aA: All of PmWiki's scripts now omit the closing ?> tag. The tag is not%0arequired, and it avoids problems with unnoticed spaces or blank%0alines at the end of the file. Also, some file transfer protocols%0amay change the newline character(s) in the file, which can also%0acause problems. See also the [[http://php.net/manual/en/language.basic-syntax.instruction-separation.php | Instruction separation ]] page in the [[http://php.net/manual/en/index.php | PHP manual ]].%0a%0aQ: Does PmWiki support WYSIWYG editing (or something like the FCKEditor)?%0aA: Short answer: PmWiki provides GUI buttons in a toolbar for common markups, but otherwise does not have WYSIWYG editing. For the reasons why, see PmWiki:WYSIWYG.%0a%0a%0a%0a
+time=1222901154
diff --git a/wikilib.d/PmWiki.DocumentationIndex b/wikilib.d/PmWiki.DocumentationIndex
new file mode 100644
index 0000000..c110ee1
--- /dev/null
+++ b/wikilib.d/PmWiki.DocumentationIndex
@@ -0,0 +1,12 @@
+version=pmwiki-2.2.6 ordered=1 urlencoded=1
+agent=Midori/0.1.9 (X11; Linux x86_64; U; en-us) WebKit/532+
+author=Petko
+charset=ISO-8859-1
+csum=de-sandbox
+host=81.65.12.233
+name=PmWiki.DocumentationIndex
+rev=380
+targets=PmWiki.Introduction,PmWiki.BasicEditing,PmWiki.CreatingNewPages,PmWiki.Links,PmWiki.Images,PmWiki.TextFormattingRules,PmWiki.MarkupMasterIndex,PmWiki.Uploads,PmWiki.Tables,PmWiki.TableDirectives,PmWiki.WikiStyles,PmWiki.WikiStyleExamples,PmWiki.AccessKeys,PmWiki.PageDirectives,PmWiki.IncludeOtherPages,PmWiki.InterMap,PmWiki.ConditionalMarkup,PmWiki.PageVariables,PmWiki.PageTextVariables,PmWiki.MarkupExpressions,PmWiki.Forms,PmWiki.SimultaneousEdits,PmWiki.WikiStructure,PmWiki.WikiGroup,PmWiki.GroupHeaders,PmWiki.WikiTrails,PmWiki.PageHistory,PmWiki.Passwords,PmWiki.Categories,PmWiki.PageLists,PmWiki.DeletingPages,PmWiki.Installation,PmWiki.InitialSetupTasks,PmWiki.Upgrades,PmWiki.BackupAndRestore,PmWiki.UploadsAdmin,PmWiki.Security,PmWiki.CustomInterMap,PmWiki.CustomMarkup,PmWiki.CustomWikiStyles,PmWiki.Internationalizations,PmWiki.LocalCustomizations,PmWiki.GroupCustomizations,PmWiki.Skins,PmWiki.SkinTemplates,PmWiki.SitePreferences,PmWiki.WebFeeds,PmWiki.WikiFarms,PmWiki.FAQ,PmWiki.Troubleshooting,PmWiki.AuthUser,PmWiki.Blocklist,PmWiki.Notify,PmWiki.PasswordsAdmin,PmWiki.RefCount,PmWiki.UrlApprovals,PmWiki.Variables,PmWiki.Functions,PmWiki.PageFileFormat,PmWiki.Audiences,PmWiki.Contributors,PmWiki.MailingLists,PmWiki.PmWikiPhilosophy,PmWiki.DesignNotes,PmWiki.ReleaseNotes,PmWiki.ChangeLog,PmWiki.Glossary,PmWiki.BasicVariables,PmWiki.EditVariables,PmWiki.FilePermissions,PmWiki.FmtPageName,PmWiki.I18nVariables,PmWiki.LayoutVariables,PmWiki.LinkVariables,PmWiki.OtherVariables,PmWiki.PagelistVariables,PmWiki.PageListTemplates,PmWiki.PathVariables,PmWiki.Requirements,PmWiki.SpecialCharacters,PmWiki.UploadVariables,PmWiki.WikiAdministrator,PmWiki.WikiPage,PmWiki.WikiWikiWeb,PmWiki.WikiWord
+text=(:title Documentation Index:)(:Summary: PmWiki documentation index:)%0a%0a>>rframe font-size:smaller%3c%3c%0a!! [[#contents]] Table of Contents%0a* [[#using | Beginner Topics for Creating/Editing Pages]]%0a* [[#intermed |Intermediate Editing Topics]]%0a* [[#struct | Wiki Structures: Organizing and Protecting Pages]]%0a* [[#admin | PmWiki Site Administration]]%0a** [[#install|Install]]%0a** [[#customise|Customise]]%0a** [[#troubleshoot|Troubleshoot]]%0a** [[#security|Security]]%0a* [[#development|Development]]%0a* [[#misc |About PmWiki]]%0a>>%3c%3c%0a%0aThe pages below describe various aspects of [[#using|using]], [[#admin|administering]] and [[#troubleshoot|troubleshooting]] a PmWiki installation, as well as aspects of the [[#misc|PmWiki community]].%0a%0aAs you know, documentation is ''always'' incomplete. %0aFeel free to help yourself and others by contributing to it. %0aJust edit the pages on %25newwin%25[[PmWiki:DocumentationIndex|pmwiki.org]]%25%25. %0aYou might want to follow or contribute to the %25newwin%25[[PmWiki:DocumentationGuidelines | documentation guidelines]]%25%25.%0a----%0a[[#trailstart]]%0a* [[Introduction]] %25item comment%25%0a%0a!! [[#using]] Beginner Topics for Creating and Editing Pages%0a%0a* [[Basic editing]] - {BasicEditing$:Summary}%0a* [[Creating new pages]] - {CreatingNewPages$:Summary}%0a* [[Links]] - {Links$:Summary}%0a* [[Images]] - {Images$:Summary}%0a* [[Text formatting rules]] - {TextFormattingRules$:Summary}%0a%0a!! [[#intermed]] Intermediate Editing Topics%0a* [[Markup master index]] - {MarkupMasterIndex$:Summary}%0a%0a* [[Uploads]] - {Uploads$:Summary}%0a* [[Tables]] - {Tables$:Summary}%0a* [[Table directives]] - {TableDirectives$:Summary}%0a* [[Wiki styles]] - {WikiStyles$:Summary}%0a** [[Wiki style examples]] - {WikiStyleExamples$:Summary}%0a%0a* [[Access keys]] - {AccessKeys$:Summary}%0a* [[Page directives]] - {PageDirectives$:Summary}%0a* [[Include other pages]] - {IncludeOtherPages$:Summary}%0a* [[InterMap]] links - {InterMap$:Summary}%0a* [[Conditional markup]] - {ConditionalMarkup$:Summary}%0a* [[Page variables]] - {PageVariables$:Summary}%0a* [[Page text variables]] - {PageTextVariables$:Summary}%0a* [[Markup expressions]] - {MarkupExpressions$:Summary}%0a* [[Forms]] - {Forms$:Summary}%0a%0a* [[Simultaneous edits]] - {SimultaneousEdits$:Summary}%0a%0a!! [[#struct]] Organizing and Protecting Pages%0a* [[Wiki structure]] - {WikiStructure$:Summary}%0a* [[Wiki group]]s - {WikiGroup$:Summary}%0a* [[Group headers]] - {GroupHeaders$:Summary}%0a* [[Wiki trails]] - {WikiTrails$:Summary}%0a* [[Page history]] - {PageHistory$:Summary}%0a%0a* [[Passwords]] - {Passwords$:Summary}%0a* [[Categories]] - {Categories$:Summary}%0a* [[Page lists]] - {PageLists$:Summary}%0a* %25%25 [[PageDirectives#attachlist|Attach lists]] - Get a list of files uploaded and attached to a group using [=(:attachlist:)=] [-({PageDirectives$:Summary})-]%0a* [[Deleting pages]] - {DeletingPages$:Summary}%0a%0a!! [[#admin]] PmWiki Site Administration%0a!!! [[#install]]Installation and maintenance%0a* [[Installation]] - {Installation$:Summary}%0a* [[Initial setup tasks]] - {InitialSetupTasks$:Summary}%0a* [[Upgrades]] - {Upgrades$:Summary}%0a* [[Backup and Restore]] - {BackupAndRestore$:Summary}%0a* [[Uploads admin]]istration - {UploadsAdmin$:Summary}%0a* [[Security]] - {PmWiki/Security$:Summary}%0a%0a!!! [[#customise]] Customisation%0a* [[Custom inter map]] - {CustomInterMap$:Summary}%0a* [[Custom markup]] - {CustomMarkup$:Summary}%0a* [[Custom wiki styles]] - {CustomWikiStyles$:Summary}%0a* [[Internationalizations]] - {Internationalizations$:Summary}%0a* [[Local customizations]] - {LocalCustomizations$:Summary}%0a* [[Group customizations]] - {GroupCustomizations$:Summary}%0a* [[Skins]] - {Skins$:Summary}%0a* [[Skin templates]] - {SkinTemplates$:Summary}%0a* [[Site Preferences]] - {SitePreferences$:Summary}%0a* [[Web feeds]] - {WebFeeds$:Summary}%0a* [[Wiki Farms]] - {WikiFarms$:Summary}%0a%0a!!! [[#troubleshoot]] Troubleshooting%0a* [[FAQ | Frequently answered questions]]%0a* [[(PmWiki:)AQ | Answers to some other questions]]%0a* [[(PmWiki:)FAQ Candidate]] - more answered questions%0a* [[(PmWiki:)Questions]]%0a* [[(PmWiki:)How to get assistance]]%0a* [[Troubleshooting]] - {Troubleshooting$:Summary}%0a* [[(PmWiki:)Available actions]] - documentation for developers%0a%0a!!! [[#security]] Security%0a* [[AuthUser]] - {AuthUser$:Summary}%0a* [[Blocklist]] - {Blocklist$:Summary} %0a* [[Notify]] - {Notify$:Summary}%0a* [[Passwords admin]]istration - {PasswordsAdmin$:Summary}%0a* [[Ref count]] - {RefCount$:Summary}%0a* [[Url approvals]] - {UrlApprovals$:Summary}%0a%0a!! [[#development]] Development%0a* [[Variables]] - {Variables$:Summary}%0a* [[Functions]] - {Functions$:Summary}%0a* [[Page file format]] - {PageFileFormat$:Summary}%0a%0a!! [[#misc]] About PmWiki%0a* [[Audiences]] - {Audiences$:Summary}%0a* [[Contributors]] - {Contributors$:Summary}%0a* [[Mailing lists]] - {MailingLists$:Summary}%0a* [[PmWiki philosophy]] - {PmWikiPhilosophy$:Summary}%0a* [[Design notes]] - {DesignNotes$:Summary}%0a* [[Release notes]] - {PmWiki/ReleaseNotes$:Summary}%0a* [[Change log]] - {PmWiki/ChangeLog$:Summary}%0a%0a* [[(PmWiki:)References]] - References to PmWiki media coverage%0a* [[Glossary]] - {PmWiki/Glossary$:Summary}%0a%0a* [[Introduction]] %25item comment%25 loop trail%0a[[#trailend]]%0a%0a>>comment%3c%3c%0aNote: The following pages are listed here so that they can include a #faq section and have the questions appear on the FAQ page. %0a%0aThe problem is that these pages become part of the trail %0a%0a* [[Basic Variables]]%0a* [[Edit Variables]]%0a* [[File Permissions]]%0a* [[Fmt Page Name]]%0a* [[I18n Variables]]%0a* [[Layout Variables]]%0a* [[Link Variables]]%0a* [[Other Variables]]%0a* [[Pagelist Variables]]%0a* [[PageList Templates]]%0a* [[Path Variables]]%0a* [[Requirements]]%0a* [[Skin Templates]]%0a* [[Special Characters]]%0a* [[Upload Variables]]%0a* [[Wiki Administrator]]%0a* [[Wiki Page]]%0a* [[Wiki Wiki Web]]%0a* [[Wiki Word]]
+time=1255033634
+title=Documentation Index
diff --git a/wikilib.d/PmWiki.Drafts b/wikilib.d/PmWiki.Drafts
new file mode 100644
index 0000000..db83060
--- /dev/null
+++ b/wikilib.d/PmWiki.Drafts
@@ -0,0 +1,12 @@
+version=pmwiki-2.2.5 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US) AppleWebKit/532.0 (KHTML, like Gecko) Chrome/3.0.195.21 Safari/532.0
+author=gb
+charset=ISO-8859-1
+csum=+doc (extracted from Pm answer, mailing list)
+ctime=1178938308
+host=82.238.179.202
+name=PmWiki.Drafts
+rev=9
+targets=PmWiki.Passwords,PmWiki.Drafts
+text=(:Summary: Draft versions of pages:)%0aPmWiki has the capability to stage ''draft'' versions of a page prior to them becoming "official". All of the draft pages end in "-Draft" by default (this can be changed by setting $DraftSuffix). Multiple interim edits to a page can be temporarily saved in a "-Draft" copy of a page until the draft is ready to be published to the original.%0a%0aWhen the site administrator sets $EnableDrafts in a local customization file, the "Save" button on the edit page is split into separate "Publish" and "Save draft" buttons. %0a%0aThe "Save draft" button causes any edits to be saved to a "-Draft" copy of the original page, leaving the original page intact. Subsequent requests to edit the page (either the original or -Draft) bring up the draft copy for further editing.%0a%0aThe "Publish" button saves back to the original non-Draft copy of the page, removing any -Draft page that may have been created.%0a%0aBy default, saving drafts and publishing are available to anyone with 'edit' permissions (see [[Passwords]]). However, the site administrator can also set the $EnablePublishAttr configuration variable, which provides a separate 'publish' permission that is required to publish to the original page.%0a%0a'''Drafts and pagelists (and RSS)'''%0a%0aThe drafts module also sets pagelists (and thus RSS feeds) to ignore "-Draft" pages by default; one has to do list=all or similar in order to have draft pages included in a pagelist or RSS feed.%0a%0a>>faq%3c%3c [[#faq]]%0a%0aQ: How do I moderate all postings?%0a%0aA: Start by [[Drafts | enabling drafts]] to change the "Save" button into separate "Publish" and "Save draft" buttons. Then set $EnablePublishAttr. This adds a "publish" authorization level to distinguish editing of page drafts from publishing.%0a
+time=1253660859
diff --git a/wikilib.d/PmWiki.EditVariables b/wikilib.d/PmWiki.EditVariables
new file mode 100644
index 0000000..0671ba6
--- /dev/null
+++ b/wikilib.d/PmWiki.EditVariables
@@ -0,0 +1,11 @@
+version=pmwiki-2.2.8 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.6) Gecko/20091215 Ubuntu/9.10 (karmic) Firefox/3.5.6
+author=Petko
+charset=ISO-8859-1
+csum=$DiffKeepNum
+host=81.65.12.233
+name=PmWiki.EditVariables
+rev=68
+targets=Cookbook.EditTemplates,Cookbook.ROEPatterns,Cookbook.ROSPatterns
+text=(:Summary:variables used when editing pages:)%0aTo set many of the variables below specify them in @@config.php@@.%0a%0a:$EnableGUIButtons:When set to '1', turns on the graphical buttons in the "Edit Page" form.%0a-> # turn on graphical edit buttons%0a-> $EnableGUIButtons = 1;%0a%0a:$EnablePostAuthorRequired:When set to '1', posting of pages requires the author to provide an author name. Otherwise, authors can post without a name.%0a-> # require authors to provide a name%0a-> $EnablePostAuthorRequired = 1; %0a%0a:$EnableDrafts:When set to '1', enables the "Save draft" button and built-in handling of "draft" versions of pages, where: %0a## initial "Save draft" of an existing page ("PageName") saves changes to a new name ("PageName-Draft")%0a## subsequent attempts to edit PageName causes PageName-Draft to be edited%0a## subsequent selections of "Save draft" cause PageName-Draft to be saved%0a## pressing "Publish" causes PageName-Draft to be posted to PageName, and deleted.%0a-> # turn on draft edits%0a-> $EnableDrafts = 1;%0a%0a->A related variable, $EnablePublishAttr, adds a new "publish" authorization level to distinguish editing of drafts from publishing them.%0a%0a:$DraftSuffix:The suffix to use for draft versions of pages (default "-Draft").%0a%0a:$DiffKeepDays:The $DiffKeepDays variable sets the minimum length of time that a page's revision history is kept. By default it is set to 3650 days, or a little less than ten years. You can change this value in a customization file to be something smaller, e.g.:%0a-> $DiffKeepDays = 30; # keep revisions at least 30 days%0a: :Note that a specific page revision isn't removed from the page until the first edit after the time specified by $DiffKeepDays has elapsed. Thus, it's still possible for some pages to have revisions older than $DiffKeepDays -- such revisions will be removed the next time those pages are edited.%0a%0a:$DiffKeepNum:This variable contains the minimum number of changes to be kept in the page history, even if some of them are older than the limit defined by $DiffKeepDays. It prevents lost history of pages that are older, but have few changes.%0a-> $DiffKeepNum = 50; # keep at least 50 revisions (default is 20)%0a%0a:$DeleteKeyPattern:The pattern used to determine if a page should be deleted. The default is to remove pages that contain only the single word "delete" (and optional spaces).%0a-> # change delete word to "remove"%0a-> $DeleteKeyPattern = "^\\s*remove\\s*$";%0a-> # delete any page with no visible text, i.e., empty%0a-> $DeleteKeyPattern = "^\\s*$";%0a%0a:$EditTemplatesFmt:Name of the page (or an array of names) to be used as the default text for any newly created pages.%0a-> [@# Use 'Main.NewPageTemplate' as default text of all new pages%0a$EditTemplatesFmt = 'Main.NewPageTemplate';%0a# Use 'Template' in the current group for new pages%0a$EditTemplatesFmt = '$Group.Template';%0a# Use 'Template' in the current group if it exists, otherwise%0a# use 'Main.NewPageTemplate'%0a$EditTemplatesFmt = array('$Group.Template', 'Main.NewPageTemplate');@]%0a-> See [[Cookbook:EditTemplates]] for more information.%0a%0a:$AutoCreate:Used in conjunction with the AutoCreateTargets edit function, this array records any sets of pages which should be created automatically if they don't exist. The syntax is %0a-> [@$AutoCreate[REGEXP] = PAGE_PARAMETERS;@]%0a-> where @@REGEXP@@ is a regular expression which will identify the pages to be autocreated, and @@PAGE_PARAMETERS@@ is an array of attributes for the page to be created. For example, %0a-> [@$AutoCreate['/^Category\\./'] = array('ctime' => $Now);@]%0a-> will create a blank page with a current creation time for any missing Category page.%0a%0a:$DefaultPageTextFmt:The text that should be displayed when browsing non-existent pages. As default PmWiki uses the contents of Site.PageNotFound %0a-> [@$DefaultPageTextFmt = '(:include $[{$SiteGroup}.PageNotFound]:)';@] %0a%0a:$EditFunctions: This array contains the sequence of functions that are called when a page is edited. It can be customized to provide additional functions to be called as part of the editing process. The standard setting is:%0a-> [@$EditFunctions = array('EditTemplate', 'RestorePage', 'ReplaceOnSave',%0a 'SaveAttributes', 'PostPage', 'PostRecentChanges', 'AutoCreateTargets', 'PreviewPage'); @]%0a%0a:$ROEPatterns: With this array you can add a pattern as ''key'' and set a text ''value'' which replace it on every edit request, using preg_replace function. Specifically it is replaced when the page is loaded into the editform, whenever a preview is done, and when the page is saved (from PmWiki 2.2.0beta45). See Cookbook:ROEPatterns for examples.%0a%0a:$ROSPatterns: With this array you can add patterns as ''key'' and set a text ''value'' which will replace it when the edited page is posted (as signaled by $EnablePost). It is not replaced when the page is loaded into the editform nor when a preview is done, but it is replaced only when the page is saved. See Cookbook:ROSPatterns for examples.%0a%0a:$IsPagePosted: Set to a true value if the page is actually saved (e.g., this is used to tell the RecentChanges handlers if they need to update).%0a %0a:$PageEditFmt: By default, this is the HTML to be displayed for an edit form.%0a%0a:$PageEditForm: Specifies the edit form for ?action=edit. Defaults to '$SiteGroup.EditForm'.%0a%0a:$HandleEditFmt: Like $HandleBrowseFmt, this specifies the entire output format for ?action=edit for a page.%0a%0a:$EditRedirectFmt: The page to which an author is sent after pressing "Save" or "Cancel" from an edit form. Defaults to "$FullName", which sends the author to the page just edited, but can be changed to specify another page.%0a-> [@# redirect to Main.HomePage%0a$EditRedirectFmt = 'Main.HomePage'; %0a# redirect to HomePage of current group%0a$EditRedirectFmt = '{$Group}.HomePage';%0a@]
+time=1263683153
diff --git a/wikilib.d/PmWiki.FAQ b/wikilib.d/PmWiki.FAQ
new file mode 100644
index 0000000..8d227e5
--- /dev/null
+++ b/wikilib.d/PmWiki.FAQ
@@ -0,0 +1,11 @@
+version=pmwiki-2.2.0-beta53 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (X11; U; Linux i686 (x86_64); en-US; rv:1.8.1.2) Gecko/20061023 SUSE/2.0.0.2-1.1 Firefox/2.0.0.2
+author=Pm
+charset=ISO-8859-1
+csum=
+host=76.183.97.54
+name=PmWiki.FAQ
+rev=580
+targets=Site.Search,PmWiki.DocumentationIndex
+text=(:Summary:List of frequently asked questions:)%0a%0aThis page will attempt to summarize some of the more commonly asked questions. The answers are on the corresponding pages (see link). If you have a question which isn't answered here, you can leave your question on the [[(PmWiki:)Questions]] page or search for documentation using the [[Site.Search | search]] facility. More documentation can be found on the [[PmWiki.DocumentationIndex | documentation index]] page.%0a%0a(:comment The questions and answers are held on their respective page(s), then collated below according to the pagelist. Please make changes to those page(s) rather than making the changes here .:)%0a%0a(:pagelist trail=PmWiki.DocumentationIndex "[[#faq]]" fmt=#includefaq class=faqtoc :)%0a%0a
+time=1180816327
diff --git a/wikilib.d/PmWiki.FilePermissions b/wikilib.d/PmWiki.FilePermissions
new file mode 100644
index 0000000..5ca7697
--- /dev/null
+++ b/wikilib.d/PmWiki.FilePermissions
@@ -0,0 +1,11 @@
+version=pmwiki-2.2.0-beta65 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.8.1.12) Gecko/20080201 Firefox/2.0.0.12
+author=simon
+charset=ISO-8859-1
+csum=see also Cookbook/DirectoryAndFilePermissions
+host=202.37.32.2
+name=PmWiki.FilePermissions
+rev=28
+targets=
+text=(:Summary: PmWiki's settings for file and directory permissions in a typical Unix environment:)%0a%0aThis page briefly describes PmWiki's settings for file and directory permissions in a typical Unix environment.%0a%0a!! Simple installation (out of the box)%0a%0aFirst, let's look at PmWiki without any cookbook scripts loaded. PmWiki needs to be able to write into the%0a* ''wiki.d/'' directory to be able to save pages%0a* ''uploads/'' directory to save uploads. %0aThose are the *only* directories that need to be writable by the webserver. %0aIt doesn't matter to PmWiki who owns or creates those directories, as long as it has write permission to them.%0a%0aEverything else should be owned by the account holder, and readable by the webserver account (but normally not writable by the webserver account).%0a%0aThat's it -- everything else depends on the specific PHP configuration and running environment, which is detailed below (and which is why there isn't a definitive answer that applies to every situation). But the above two rules are absolute and answer 95%25 of the questions about directory permissions. %0a%0aOn a Unix host the webserver typically runs with a userid and groupid that is different from the account holder. Usually the webserver account is something like "nobody", "apache", "www", or "httpd". Thus, in a standard installation, the account holder manually creates the wiki.d/ and uploads/ directories, and sets the permissions on the directories to be world-writable in order for PmWiki (running as the webserver account) to be able to create files there.%0a%0a-> [@%0a$ pwd%0a/home/pmichaud/public_html/pmwiki%0a$ mkdir uploads%0a$ mkdir wiki.d%0a$ chmod 777 uploads wiki.d %0a$ ls -ld . uploads wiki.d%0adrwxr-xr-x 12 pmichaud pmichaud 1024 Feb 10 11:51 . %0adrwxrwxrwx 8 pmichaud pmichaud 1024 Jan 23 11:58 uploads %0adrwxrwxrwx 2 pmichaud pmichaud 54272 Feb 10 15:29 wiki.d %0a@]%0a%0a!! Avoiding world-write directories%0a%0aHowever, lots of people don't like having those world-writable (rwx) permissions on the directories. The only practical way to eliminate the world write permissions is if we can get the webserver and account holder to be the owner and group of the directories and the files within them. Since Unix typically doesn't allow non-superusers to change ownerships of files or directories that already exist, we have to make sure they are created with the correct ownerships in the first place.%0a%0aTo get the directories to be owned by the webserver account, we let PmWiki take care of creating them. This means we temporarily grant write permission to the parent, and then execute PmWiki to allow it to create the directories. However, we also want the newly created directories to have the same group as the account holder, so the account holder can remove or manipulate files in the directories. Therefore, we use Unix's ''setgid'' capability (2777 or 'rws' permissions) to cause all newly created files to inherit the same group as the parent.%0a%0aTo avoid world-write directories, use the following instructions '''instead of''' the instructions above. If you already have created the ''wiki.d/'' and ''uploads/'' directories, use chown and chmod to match the following results.%0a%0a-> [@%0a$ pwd%0a/home/pmichaud/public_html/pmwiki%0a$ chmod 2777 . %0a$ ls -ld .%0adrwxrwsrwx 10 pmichaud pmichaud 4096 May 28 09:55 .%0a# %3c-- execute pmwiki.php script from web browser -->%0a$ ls -ld . uploads wiki.d%0adrwxrwsrwx 10 pmichaud pmichaud 4096 May 28 09:55 .%0adrwxrwsr-x 2 nobody pmichaud 4096 May 28 09:55 uploads%0adrwxrwsr-x 2 nobody pmichaud 4096 May 28 09:55 wiki.d%0a$ chmod 755 .%0adrwxr-xr-x 10 pmichaud pmichaud 4096 May 28 09:55 .%0adrwxrwsr-x 2 nobody pmichaud 4096 May 28 09:55 uploads%0adrwxrwsr-x 2 nobody pmichaud 4096 May 28 09:55 wiki.d%0a@]%0a%0aNow the two directories are owned by 'nobody', which means the webserver can write to them. We don't have world-writable permissions on the directories, and the account holder (pmichaud) still has write permissions to the files and directories by virtue of the group ownership and permissions. The setgid bit also ensures that any files or subdirectories created within ''uploads/'' or ''wiki.d/'' will belong to the same (pmichaud) group.%0a%0a!! Safe mode%0aHOWEVER, if a site is running in PHP's "%25newwin%25[[http://php.net/features.safe-mode|safe_mode]]", then the "let PmWiki create the directories" solution doesn't work, as PHP will only create files in directories that are owned by the same user that owns the pmwiki.php script itself. Thus, PmWiki (apache) ''cannot'' create the directories in this case, or safe_mode will complain when PmWiki attempts to write a file into those directories. The *only* way for things to work in safe_mode is to manually create the needed directories and set their permissions to 777, as outlined at the beginning of this section.%0a%0a!! PHP running as script owner%0a%0aThere are some webservers and PHP installations that are configured to run a PHP script with the same identity as the owner of the script. This is often called "suexec PHP" or even just "suPHP". In this case, since the PmWiki script ends up running with the same identity as the account holder, then everything "just works" out of the box without doing anything manually. PmWiki creates any directories and files as needed, each owned by the account holder, and permissions aren't generally an issue at all.%0a%0a!! Cookbook scripts%0aOkay, now let's look at cookbook scripts. %0aIf a cookbook script has files that it wants to make available to browsers, such files should generally be placed somewhere within the 'pub/' hierarchy and referenced via '$PubDirUrl'. %0a%0aIf a cookbook recipe needs to *write* files to disk, then the same rules apply to that directory as for the wiki.d/ and uploads/ directories above, with the exact ownerships and permissions depending on the webserver and PHP configuration. In general the cookbook recipe should do the same as PmWiki, and just call PmWiki's mkdirp($dir) function. PmWiki will then take care of creating the directory (if it can) or prompting for its creation as appropriate.%0a%0aFor example, if cookbook recipe 'frobot' wants to distribute a .css file, then that file should go somewhere like pub/css/frobot.css or pub/frobot/frobot.css. The directories and files in this case should be created and owned by the account owner, since the cookbook recipe doesn't need to create or modify any of the files when it runs. %0a%0aAs an alternate example, the Cookbook:MimeTeX recipe wants to be able to create cached images for the math markup, and those images need to be available to the browser. Thus, `MimeTeX uses a pub/cache/ directory, which should be created in whatever manner was used to create the wiki.d/ and uploads/ directories (i.e., according to the webserver and PHP configuration). Again, Cookbook:MimeTeX just solves this by calling mkdirp("pub/cache"), and letting that function create the directory or prompt the administrator for the appropriate action based upon the server settings encountered.%0a%0a!! See also%0a* [[Cookbook:Directory and file permissions]] [- {Cookbook/DirectoryAndFilePermissions$:Summary} -]%0a%0a
+time=1208205709
diff --git a/wikilib.d/PmWiki.FmtPageName b/wikilib.d/PmWiki.FmtPageName
new file mode 100644
index 0000000..f456d2e
--- /dev/null
+++ b/wikilib.d/PmWiki.FmtPageName
@@ -0,0 +1,11 @@
+version=pmwiki-2.2.7 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 FirePHP/0.3
+author=Frank
+charset=ISO-8859-1
+csum=updated link wikipedia variable interpolation
+host=145.18.29.245
+name=PmWiki.FmtPageName
+rev=41
+targets=PmWiki.Functions,PmWiki.Variables,PmWiki.Internationalizations,PmWiki.PageVariables
+text=(:Summary: Documentation for the PmWiki internal function [@FmtPageName()@] :)%0a(:Audience: admins (advanced) :)%0aThis page describes an internal function in PmWiki's engine called [=FmtPageName()=]. %0aThe contents are not intended for those with a weak heart%0a;-)%0a%0aAlso see: [[PmWiki.Functions]]%0a%0a!! [[#FmtPageName]] [@FmtPageName@]($fmt, $pagename)%0a%0a[[#FmtPageName-desc]]Returns [@$fmt@], with $variable and $[internationalisation] substitutions performed, under the assumption that the current page is [@pagename@]. As a rule is used to pre-process all variables which by convention have a "Fmt" suffix (like $GroupFooterFmt), but also other strings that require %25newwin%25[[Wikipedia:Variable_%2528programming%2529#Interpolation | interpolation]], notably the page template (.tmpl) file. See [[PmWiki.Variables]] for an (incomplete) list of available variables, [[PmWiki.Internationalizations]] for internationalisation.%0a%0aThe function [@FmtPageName()@] applies internationalization-substitutions%0aand $Variable-substitions to the string $fmt under the assumption that the%0acurrent page is $pagename.%0a%0aThe substitutions go as follows:%0a%0a# Replace any sequences of the form [@$XyzFmt@] with value of any \%0a corresponding global variable.%0a# Process the string for any [@$[...]@] phrases (internationalized phrase), \%0a using the currently loaded translation tables.%0a# Replace any instances of [@{$ScriptUrl}@] with [@$ScriptUrl@] \%0a (to defer processing to the URI processing phase)%0a# Replace any instances of standard [[PmWiki/PageVariables|Page Variables]] \%0a (beginning with an upper case letter, followed by at least one word character) \%0a with their values. \%0a If there are no more $-sequences, then return the formatted string and exit the function%0a# Perform any pattern replacements from the array $FmtP. Typically \%0a this is used to handle things like $Name and $Group etc that are \%0a specific to the name of the current page. %25green%25''?? Appears to be used in robots.php to hide actions from robots.''%0a# Replace any remaining instances of Page Variables with their values.%0a# If $EnablePathInfo isn't set, convert [@URIs@] to use the syntax \%0a $ScriptUrl?n=%3cGroup>.%3cName> instead of $ScriptUrl/%3cGroup>/%3cName>. \%0a In any case, replace $ScriptUrl with its value. \%0a If there are no more $-sequences, then return the formatted string and exit the function%0a# Replace any $-sequences with global variables (caching as needed) \%0a of the same name (in reverse alphabetical order, and filtering out any unsafe globals) *%0a# Replace any $-sequences with values out of the array $FmtV.%0a%0aNote that [@FmtPageName@]() is automatically aware of any global%0avariables. However, since modifying global variables may be expensive, the%0aarray $FmtV exists as a way to avoid rebuilding the variable cache for%0avalues that change frequently.%0a%0a!! Security%0a%0aAccording to PM, as a general rule it's unwise to be calling FmtPageName() on strings that are coming from page markup, as this exposes the ability for people to view the values of variables that perhaps they shouldn't see. This is also why page variables (which come from markup) use PageVar() and PageTextVar() and don't go through FmtPageName().%0a%0a!! Availability of Variables in FmtPageName%0a%0aTo be very specific, here's what Pm wrote regarding different ways of%0adefining a variable that can be used by FmtPageName (when it is formatting a%0astring):%0a%0a* Set a global variable. FmtPageName() automatically performs \%0a substitution on all global variables that aren't arrays. \%0a If the variable is going to change value over repeated calls \%0a to FmtPageName, it's probably better to use $FmtV as in the next item.%0a%0a* Set a value in the $FmtV array. $FmtV['$MyVariable']='something' \%0a means to replace instances of '$MyVariable' with 'something'. \%0a Use this for variables that change value frequently over \%0a multiple calls to FmtPageName. %0a%0a* Set a pattern/replacement in the $FmtP array. This is normally \%0a done for substitutions that have to be dynamic somehow based on \%0a the pagename being referenced, such as '$Title', '$Group', '$Name', \%0a '$PageUrl', etc.%0a%0aAlso see: [[Cookbook:Functions#FmtPageName]]%0a%0aFinally, here's something else Pm wrote that is related and explains%0awhy we have this function:%0a%0a-> In order to produce its output, PmWiki has to do a variety of string \%0a substitutions:%0a%0a## Generating the full name, group, title, or url of a page \%0a (other than the currently displayed page)%0a## Substituting the values of global variables%0a## Performing internationalization substitutions%0a## Converting $ScriptUrl/$Group/$Name to $ScriptUrl?n=$Group.$Name \%0a for sites that cannot handle PATH_INFO urls%0a## Other substitutions needed by specific functions%0a %0a-> PmWiki centralizes all of that substitute-a-dynamic-value-in-a-string \%0a into the FmtPageName() subroutine. Because some things are extremely \%0a dynamic, such as the url or group for an arbitrary page that is not the \%0a current one, those things cannot be simple global PHP variables. Or, if \%0a they do become global variables, they're variables that cannot be \%0a trusted to hold a value for very long because some other routine (that \%0a may happen to be formatting a string for a different page) will come \%0a along and change that global variable for whatever it happens to be doing.%0a%0a-> A limited set of $-substitutions -- basically anything that \%0a corresponds to a page attribute -- are not PHP variables and \%0a are only available through the FmtPageName() subroutine. \%0a The complete set of these special substitutions is $Group, \%0a $Name, $FullName, $PageUrl, $Title, $Titlespaced, $Namespaced, \%0a $Groupspaced, $LastModifiedBy, $LastModifiedHost, and $LastModified. \%0a These items cannot just be standard PHP variables because often\%0a PmWiki needs to obtain the url, name, group, title, etc. of a page \%0a other than the one currently being viewed by a browser.%0a%0a-> At the moment, $Title, $LastModified, $LastModifiedBy, and \%0a $LastModifiedHost can only work if the page's attributes have been \%0a loaded and cached using the `PCache function. So, to get\%0a at these values one must typically do:%0a%0a-> [@%0a$page = ReadPage($pagename);%0aPCache($pagename, $page);%0a$ptitle = FmtPageName('$Title', $pagename);%0a$pauthor = FmtPageName('$LastModifiedBy', $pagename);%0a@]%0a
+time=1259075447
diff --git a/wikilib.d/PmWiki.Forms b/wikilib.d/PmWiki.Forms
new file mode 100644
index 0000000..022a703
--- /dev/null
+++ b/wikilib.d/PmWiki.Forms
@@ -0,0 +1,12 @@
+version=pmwiki-2.2.10 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/532.5 (KHTML, like Gecko) Chrome/4.0.249.78 Safari/532.5
+author=Peter Bowers
+charset=ISO-8859-1
+csum=add note re name=FormName option on (:input form:) markup
+ctime=1181479161
+host=92.60.30.68
+name=PmWiki.Forms
+rev=45
+targets=Cookbook.InputDefault,Cookbook.FormValidation,Cookbook.FormExtensions,Cookbook.InputFormsAndJavaScript,Cookbook.PmForm,Cookbook.Fox,Cookbook.Input,Cookbook.WikiForms,Cookbook.ProcessForm
+text=(:Summary:How you can embed input forms into wiki pages:)%0aThis page explains how you can embed input forms into wiki pages.%0a%0aInput forms don't actually handle processing of the form data -- the feature simply allows creation of forms inside wiki pages. Forms processing can be found in the Cookbook (see below).%0a%0a!! Markup%0aTwo directives are used to begin and end forms:%0a%0a [=(:input=] form "''url''" ''method'':)%0a ...%0a [=(:input end:)=]%0a%0aThe [@(:input form:)@] directive starts a form that will post to ''url'' using the supplied ''method''. The ''url'' must be in quotes. If the url is omitted, then the current page is assumed. If ''method'' is omitted then "POST" is assumed. An optional [@name="FormName"@] argument can be used to name the form. The [@(:input end:)@] directive ends the current form.%0a%0aNote that this feature doesn't ensure that the form output is correct HTML -- it assumes the author knows a little bit of what he or she is doing. Notably, [=(:input form:) and (:input end:)=] shouldn't appear inside tables, and all form fields and controls should be inside an [=(:input form:)...(:input end:)=] block.%0a%0a[[#standardinputcontrols]]%0a!!!Standard input controls%0aThe standard input controls are:%0a%0a [=(:input=] text ''name'' ''value'' size=''n'':)%0a [=(:input=] hidden ''name'' ''value'':)%0a [=(:input=] password ''name'' ''value'':)%0a [=(:input=] radio ''name'' ''value'':)%0a [=(:input=] checkbox ''name'' ''value'':)%0a [=(:input=] [[#select|select]] ''name'' ''value'' ''label'':)%0a [=(:input=] [[Cookbook:InputDefault|default]] ''default-name'' ''default-value'':) %0a [=(:input=] submit ''name'' ''value'':)%0a [=(:input=] textarea ''name'' ''[@[=value=]@]'' rows=''n'' cols=''n'':)%0a [=(:input=] reset ''name'' ''label'':)%0a [=(:input=] file ''name'' ''label'':)%0a [=(:input=] image ''name'' ''"src"'' ''alt'':)%0a%0aWhere ''name'' and ''value'' are in the HTML syntax: name="addr" value="808 W Franklin".%0a%0aFor most controls the markup has the form:%0a%0a [=(:input=] ''type'' ''name'' ''value'' ''parameter=value'':)%0a%0awhere ''type'' is the type of input element (described below), ''name'' is the name of the control, ''value'' is its initial value, and parameters are used to specify additional attributes to the control. If ''value'' contains spaces, enclose it in quotes; if it contains newlines (for textarea and hidden elements), enclose it in [@[=...=]@]. %0a%0aFor example, the following creates a text input control with a size of 30 characters:%0a%0a(:markup:)%0a(:input text authorid "Jane Doe" size=30:)%0a(:markupend:)%0a%0aFor convenience, an author can also specify name and value arguments directly using [@name=@] and [@value=@] attributes (same as HTML):%0a%0a(:markup:) %0a(:input text name=authorid value="Jane Doe" size=30:)%0a(:markupend:)%0a%0aFor the @@textarea@@ control a value can be set from PmWiki 2.2.0beta45 onwards. Enclose the value in [@[=...=]@] if it contains spaces or new lines.%0a%0aThe [@submit@] control will more often be written as:%0a%0a [=(:input=] submit value=''label'':)%0a%0aHere's a more complete example, e.g., for a login prompt:%0a%0a(:markup:) [=%0a(:input form "http://www.example.com":)%0a(:input hidden action login:)%0a|| Name:||(:input text username:) ||%0a|| Password:||(:input password password:)||%0a|| ||(:input submit value="Log In":) ||%0a(:input end:)%0a=]%0a%0a%0a[[#select]]%0a!![@(:input select ... :)@]%0a%0aThe basic form of a select box is a sequence of options:%0a%0a(:markup:) [=%0a(:input form:)%0a(:input select name=abc value=1 label=alpha :)%0a(:input select name=abc value=2 label=beta :)%0a(:input select name=abc value=3 label=gamma :)%0a(:input submit:)%0a(:input end:)%0a=]%0a%0aThe values can be specified positionally:%0a [=(:input select abc 1 alpha :)=]%0a%0aWe can specify the size of the selection box:%0a [=(:input select abc 1 alpha size=3 :)=]%0a%0aYou can specify a multiple select box:%0a [=(:input select abc 1 alpha size=3 multiple:)=]%0a%0aTo have an element selected, use @@selected=selected@@:%0a [=(:input select abc 2 beta selected=selected:)=]%0a%0aNote that to have two select boxes inline, not only should you give them different @@name=@@ parameters, but also place a separator, like a character, [@ @] or even the null sequence [@[==]@] between them:%0a(:markup:)%0a(:input form:)%0a(:input select name=FIRST value=1:)(:input select name=FIRST value=2:)[==]%0a(:input select name=SECOND value=3:)(:input select name=SECOND value=4:)%0a(:input end:)%0a(:markupend:)%0a%0a!! See Also%0a*[[Cookbook:Input Default]] {Cookbook.InputDefault$:Summary}%0a*[[Cookbook:Form Validation]] {Cookbook.FormValidation$:Summary}%0a*[[Cookbook:Form Extensions]] {Cookbook.FormExtensions$:Summary}%0a*[[Cookbook:Input Forms and JavaScript]] {Cookbook.InputFormsAndJavaScript$:Summary}%0a%0aCompatible recipes:%0a* [[Cookbook:PmForm]] {Cookbook/PmForm$:Summary}%0a* [[Cookbook:Fox]] {Cookbook.Fox$:Summary}%0a* [[Cookbook:Wiki Forms]] {Cookbook/WikiForms$:Summary}%0a* [[Cookbook:ProcessForm]] {Cookbook/ProcessForm$:Summary}%0a%0a
+time=1265305024
diff --git a/wikilib.d/PmWiki.Functions b/wikilib.d/PmWiki.Functions
new file mode 100644
index 0000000..d0c785b
--- /dev/null
+++ b/wikilib.d/PmWiki.Functions
@@ -0,0 +1,11 @@
+version=pmwiki-2.2.6 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/532.0 (KHTML, like Gecko) Chrome/3.0.195.27 Safari/532.0
+author=simon
+charset=ISO-8859-1
+csum=link
+host=203.97.214.12
+name=PmWiki.Functions
+rev=85
+targets=PmWiki.CustomMarkup,PmWiki.Variables,PmWiki.Internationalizations,PmWiki.FmtPageName,PmWiki.ConditionalMarkup,PmWiki.Drafts
+text=(:Summary: How some of the functions in pmwiki.php work:)%0a(:Audience: admins (advanced) :)%0a%0aThis page describes some of the internal workings of PmWiki by explaining how some of the functions in pmwiki.php work. For a more brief list/overview on functions useful to for instance cookbook writers, see Cookbook:Functions. %0a%0aTo use this functions you have to make sure that all relevant internal variables have been initialized correctly. See [[Custom Markup]] and [[(PmWiki:)Custom Actions]] for more information on how these functions are typically called via [@Markup()@] or [@$HandleActions[]@].%0a%0a%0a!![[#PSS]] [@PSS($string)@]%0a%0aThe PSS() function removes the backslashes that are%0aautomatically inserted in front of quotation marks by%0athe /e option of PHP's preg_replace function. PSS() is%0amost commonly used in replacement arguments to Markup(),%0awhen the pattern specifies /e and one or more of the %0aparenthesized subpatterns could contain a quote or backslash. %0a("PSS" stands for "PmWiki Strip Slashes".)%0a-->From PM: PmWiki expects PSS() to always occur inside of double-quoted strings and to contain single quoted strings internally. The reason for this is that we don't want the $1 or $2 to accidentally contain characters that would then be interpreted inside of the double-quoted string when the PSS is evaluated.%0a--->@@Markup('foo', 'inline', '/(something)/e', 'Foo(PSS("$1"))'); # wrong@@%0a--->@@Markup('foo', 'inline', '/(something)/e', "Foo(PSS('$1'))"); # right@@%0a%0a!!! Example%0aThis is a fictitious example where PSS() should be used.%0aLet us assume that you wish to define a directive [@(:example:)@]%0asuch that [@(:example "A horse":)@] results in the HTML%0a-> [@%3cdiv>"A horse"%3c/div>@].%0aHere is how the markup rule can be created:%0a-> [@%0aMarkup('example', 'directives',%0a '/\\(:example\\s(.*?):\\)/e',%0a "Keep('%3cdiv>'.PSS('$1').'%3c/div>')");%0a@]%0aWe need to use PSS() around the '$1' because the matched text%0acould contain quotation marks, and the /e will add backslashes%0ain front of them.%0a%0a!![[#stripmagic]] [@stripmagic($string)@]%0a%0aThis function should be used when processing the contents of [@$_POST@] or [@_GET@] variables when they could contain quotes or backslashes. It verifies [@get_magic_quotes()@], if true,%0astrips the automatically inserted escapes from the string.%0a%0a!![[#FmtPageName]] [@FmtPageName@]($fmt, $pagename)%0a%0a[[#FmtPageName-desc]]Returns [@$fmt@], with $variable and [=$[internationalisation]=] substitutions performed, under the assumption that the current page is [@pagename@]. See [[PmWiki.Variables]] for an (incomplete) list of available variables, [[PmWiki.Internationalizations]] for internationalisation. Security: not to be run on user-supplied data.%0a%0aThis is one of the major functions in PmWiki, see [[PmWiki.FmtPageName]] for%0alots of details.%0a%0a%0a!![[#Markup]] [@Markup@]($name, $when, $pattern, $replace)%0a%0a[[#Markup-desc]]Adds a new markup to the conversion table. Described in greater detail at [[PmWiki.CustomMarkup]].%0a%0aThis function is used to insert translation rules into the PmWiki's%0atranslation engine. The arguments to [@Markup()@] are all strings, where:%0a%0a:[@$name@]: The string names the rule that is inserted. If a rule of the same name already exists, then this rule is ignored.%0a:[@$when@]: This string is used to control ''when'' a rule is to be applied relative to other rules. A specification of "[@%3cxyz@]" says to apply this rule prior to the rule named "xyz", while "[@>xyz@]" says to apply this rule after the rule "xyz". See [[(PmWiki:)CustomMarkup]] for more details on the order of rules.%0a:[@$pattern@]: This string is a [[regular expression -> http://www.php.net/preg_replace]] that is used by the translation engine to look for occurences of this rule in the markup source.%0a:[@$replace@]: This string will replace the matched text when a match occurs.%0a%0aAlso see: [[PmWiki.CustomMarkup]] and [[Cookbook:Functions#Markup]]%0a%0a!![[#MarkupToHTML]] [@MarkupToHTML@]($pagename, $str)%0a%0a[[#MarkupToHTML-desc]] Converts the string [@$str@] containing PmWiki markup into the corresponding HTML code, assuming the current page is [@$pagename@].%0a%0aAlso see: [[Cookbook:Functions#MarkupToHTML]]%0a%0a!![[#mkdirp]] [@mkdirp@]($dir)%0a%0aThe function [@mkdirp@]($dir) creates a directory, [@$dir@], if it doesn't%0aalready exist, including any parent directories that might be needed. For%0aeach directory created, it checks that the permissions on the directory are%0asufficient to allow PmWiki scripts to read and write files in that%0adirectory. This includes checking for restrictions imposed by PHP's%0asafe_mode setting. If [@mkdirp@]() is unable to successfully create a%0aread/write directory, [@mkdirp@]() aborts with an error message telling the%0aadministrator the steps to take to either create $dir manually or give%0aPmWiki sufficient permissions to be able to do it.%0a%0a!![[#MakeLink]] [@MakeLink@]($pagename, $target, $txt, $suffix, $fmt)%0a%0aThe function [@MakeLink@]($pagename, $target, $txt, $suffix, $fmt) returns a ???. Its arguments are as follows:%0a $pagename is the source page%0a $target is where the link should go%0a $txt is the value to use for '$LinkText' in the output %0a $suffix is any suffix string to be added to $txt%0a $fmt is a format string to use%0a%0aIf $txt is NULL or not specified, then it is automatically computed from $target.%0a%0aIf $fmt is NULL or not specified, then MakeLink uses the default%0aformat as specified by the type of link. For page links this%0ameans the $LinkPageExistsFmt and $LinkPageCreateFmt variables,%0afor intermap-style links it comes from either the $IMapLinkFmt%0aarray or from $UrlLinkFmt. Inside of the formatting strings,%0a$LinkUrl is replaced by the resolved url for the link, $LinkText%0ais replaced with the appropriate text, and $LinkAlt is replaced%0aby any "title" (alternate text) information associated with the%0alink.%0a%0aAlso see: [[PmWiki:MakeLink]] and [[Cookbook:Functions#MakeLink]]%0a%0a!![[#MakeUploadName]] [@MakeUploadName@]($pagename, $x)%0a%0a@@MakeUploadName()@@ simply takes a string @@$x@@ (representing an attachment's%0aname) and converts it to a valid name by removing any unwanted characters.%0aIt also requires the name to begin and end with an alphanumeric character,%0aand as of 2.0.beta28 it forces any file extensions to lowercase.%0aThis function is defined in @@scripts/upload.php@@ and only used when uploads%0aare enabled.%0a%0a!![[#SessionAuth]] [@SessionAuth@]($pagename, $auth=NULL)%0a%0a@@SessionAuth()@@ manages keeping authentication via cookie-sessions. Session contains%0aever password or vaidated id and associated groups from previous calls.It adds%0aelements passed by @@$auth@@ to session. It also writes every element%0asaved in session to @@$AuthPw@@(passwords) and @@$AuthList@@(ids and groups).%0a%0a!![[#IsAuthorized]] [@IsAuthorized@]($chal, $source, &$from)%0a@@IsAuthorized@@ takes a pageattributesstring (e. g. "id:user1 $1$Ff3w34HASH...") in @@$chal@@.%0a@@$source@@ is simply returned and used for building the authcascade (pageattributes - groupattributes - %0a@@$DefaultPassword@@). @@$from@@ will be returned if @@$chal@@ is empty, because it is not checked %0abefore calling @@IsAuthorized()@@, this is needed for the authcascade. @@IsAuthorized()@@ returns an array%0awith three values: @@$auth@@ @@1@@ - authenticated, @@0@@ - not authenticated, @@-1@@ - refused; @@$passwd@@; %0a@@$source@@ from the parameter list.%0a%0a!![[#CondAuth]] [@CondAuth@] ($pagename, 'auth level')%0a[@CondAuth@] implements the [[ConditionalMarkup]] for [@(:if auth level:)@]. For instance [@ CondAuth($pagename,'edit')@] is true if authorization level is 'edit'. Use inside local configuration files to build conditionals with a check of authorization level, similar to using [@(:if auth level:)@] on a wiki page.%0a%0aNote that CondAuth() should be called after all authorization levels and passwords have been defined. For example, if you use it with [[Drafts]], you should include the draft.php script before calling CondAuth():%0a[@%0a $EnableDrafts = 1;%0a $DefaultPasswords['publish'] = crypt('secret');%0a include_once("$FarmD/scripts/draft.php");%0a if (! CondAuth($pagename, 'edit')) { /* whatever */ }%0a@]%0aBest is to use CondAuth() near the bottom of your config.php script.%0a%0a!! [[#RetrieveAuthPage]] @@RetrieveAuthPage($pagename, $level, $authprompt=true, $since=0)@@%0a%0aUse e.g. [@$page = @RetrieveAuthPage('Main.MyPage', 'read')@] to obtain a page object that contains all the information of the correspondent file in separate keys, e.g. [@$page['text']@] will contain a string with the current wiki markup of Main.MyPage. Use this generally in preference to the alternative function [@ReadPage($pagename, $since=0)@] since it respects the authorisation of the user, i.e. it checks the authorisation level before loading the page, or it can be set to do so. [@ReadPage()@] reads a page regardless of permission.%0a%0a!! [[#UpdatePage]] @@UpdatePage($pagename, $old (page object), $new (page object));@@%0a''[[PmWiki:UpdatePage|More Technical Notes]]''%0a%0a[@UpdatePage()@] allows cookbook recipes to mimic the behavior of editing wiki pages via the browser. Internally, PmWiki does several house keeping tasks which are accessible via this function (preserving history/diff information, updating page revision numbers, updating RecentChanges pages, sending email notifications, etc._%0a* "Page object" refers to an array pulled from [@ReadPage($pagename); @] Note that $new['text'] should contain all page data for the new version of the page. %0a* If a page doesn't exist, UpdatePage() will attempt to create it.%0a* Ignoring $old (e.g. [@UpdatePage($pagename, '', $new);@]) will erase all historical page data---a ''tabula rasa''.%0a@@UpdatePage()@@ cannot be called directly from config.php because there are necessary initializations which occur later in pmwiki.php. It is not enough to just load stdconfig.php. If you want to use @@UpdatePage()@@ you will need to do it within a [[PmWiki:CustomMarkup | custom markup]], a [[Cookbook:MarkupExpressionSamples | custom markup expression]], or a [[PmWiki:CustomActions | custom action]].
+time=1255510067
diff --git a/wikilib.d/PmWiki.Glossary b/wikilib.d/PmWiki.Glossary
new file mode 100644
index 0000000..540d153
--- /dev/null
+++ b/wikilib.d/PmWiki.Glossary
@@ -0,0 +1,11 @@
+version=pmwiki-2.2.0-beta68 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.0.1) Gecko/2008070208 Firefox/3.0.1
+author=simon
+charset=ISO-8859-1
+csum=trail
+host=203.97.214.12
+name=PmWiki.Glossary
+rev=28
+targets=PmWiki.WikiFarmTerminology
+text=(:Summary: Terms related to PmWiki:)%0a%0aThis page describes various terms related to PmWiki.%0a%0a:Author: Any user with privileges to write to the wiki.%0a%0a:Admin: The person (or people) who controls access to the wiki, configures the wiki, and generally is the person who installed the wiki.%0a%0a:Configuration file: A specially-named PHP script file where local customizations can take place for a farm, a wiki, a group, or a page.%0a%0a:Default configuration: The way Pm has chosen to set all settings, or an individual setting, by default. For example, $EnablePathInfo is disabled by default. A wiki with no ''local/config.php'' file is using the default configuration. Likewise, a farm that only defines $FarmPubDirUrl in ''farmconfig.php'' is using the default configuration.%0a%0a[[#farm]]%0a:Farm: A group of wikis that share code. Content and formats may or may not be shared. For more farm-related terms, including several which have been deprecated, see [[WikiFarmTerminology]]%0a%0a:Farm-wide configuration file: A WikiFarm's ''local/farmconfig.php'' file, where any settings (besides $FarmPubDirUrl) customize the default configuration for all of the wikis in a farm.%0a%0a:Full page name: The ''full page name'' consists of a group and a name, e.g. [@Main.WikiSandbox@]. The variable for the full page name is [@{$FullName}@], which for this page is @@{$FullName}@@. Similarly, the variable for the group is [@{$Group}@] which here is @@{$Group}@@.%0a%0a:Group: A collection of associated wiki pages; by default this appears in the page name as "Group.PageName". Attributes can be set on all pages in the group simultaneously. The variable for the group is [@{$Group}@], which here is @@{$Group}@@.%0a%0a:Local configuration file: A specially-named PHP script where local customizations can take place for an individual wiki. For an entire wiki it's named ''local/config.php''. Individual groups and pages can also have their own local configuration files.%0a%0a:Local customization: Any deviation from the default configuration. A related phrase is "farm-wide customization".%0a%0a:Page file name: The ''page file name'' is the name of the file that normally stores the data of a page in the directory [@wiki.d/@]. This file name is normally built directly from the page name.%0a%0a:Page link: A ''page link'' is something that is used to generate a link to a page. For example, the markup [@[[wiki sandbox]]@], [@[[(wiki) sandbox]]@], [@WikiSandbox@], [@Main/WikiSandbox@], [@[[Main/wiki sandbox]]@], [@[[Main.WikiSandbox | click here]]@], etc all specify a link to the page '[=Main.WikiSandbox=]'. In each case PmWiki uses the context of the link to generate a page name from the page link -- normally by capitalizing each word found in the link and stripping any characters that aren't considered valid in page names.%0a%0a:Page name: The ''page name'' is a string that PmWiki uses to refer to a page - i.e. it ''names the page''. This could also be considered a ''handle'' for the page. The variable for the page name is simply called [@{$Name}@], which for this page is @@{$Name}@@.%0a-> Note that there is no whitespace in page names, and by default PmWiki capitalizes each word in a page's name. There is however a variable [@{$Namespaced}@] where spaces have been inserted, e.g. for the page [=WikiSandbox=] this variable would be [@Wiki Sandbox@].%0a-> Note that PmWiki also uses the page name to locate per-group and per-page customization files in the [@local/@] subdirectory. For example, browsing [=Main.WikiSandbox=] would cause [@local/Main.WikiSandbox.php@] and [@local/Main.php@] to be loaded if these files existed.%0a%0a:Page title: A ''page title'' is the title element of a page, i.e. what is usually shown above the page and in the browser window's name. This title is normally set via the directive [@(:title:)@], but if no such directive is given the title will be automatically generated from the page name. The title of a page is accessed via either the variable [@{$Title}@] or the variable [@{$Titlespaced}@]. The latter differs in that it uses the spaced version of the name.%0a%0a:Page URI: Page names are used in `URIs to tell PmWiki which page is to be loaded or acted upon. The normal form of a page URI is usually one of these two%0a--> [@http://www.example.com/pmwiki/pmwiki.php?n=Main.WikiSandbox@]%0a--> [@http://www.example.com/pmwiki/pmwiki.php/Main.WikiSandbox@]%0a-> Note that various aliasing and rewriting tricks can be used to modify this, but PmWiki expects to obtain a page name from the parameter 'n' or from the [@PATH_INFO@] component following the URI of the script ([@pmwiki.php@]).%0a-> Note that the parameter 'n' takes precedence over [@PATH_INFO@] if both are available.%0a%0a:Wikifarm:Synonymous for "[[#farm | farm]]".%0a%0a
+time=1220179150
diff --git a/wikilib.d/PmWiki.GroupCustomizations b/wikilib.d/PmWiki.GroupCustomizations
new file mode 100644
index 0000000..896fd78
--- /dev/null
+++ b/wikilib.d/PmWiki.GroupCustomizations
@@ -0,0 +1,12 @@
+version=pmwiki-2.2.5 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/530.5 (KHTML, like Gecko) Chrome/2.0.172.43 Safari/530.5
+author=Simon
+charset=ISO-8859-1
+csum=GroupCustomizations
+ctime=1250689504
+host=202.37.32.2
+name=PmWiki.GroupCustomizations
+rev=2
+targets=PmWiki.WikiGroup,PmWiki.WikiAdministrator,PmWiki.LocalCustomizations,PmWiki.GroupHeaders,PmWiki.GroupName,PmWiki.GroupAttributes,PmWiki.PasswordsAdmin,PmWiki.WikiFarms,PmWiki.GroupCustomizations
+text=(:Summary: How to customize a subset of your wiki:)%0a(:Audience: administrators (intermediate) :)%0aOne of the purposes of [[Wiki Group]]s is to allow a [[Wiki Administrator]] to customize the features of PmWiki on a per-group basis. Here is where ''per group customizations'' come into play.%0a%0a* The ''local/'' subdirectory (typically in $FarmD) is used to hold local configuration files. %0a* The ''css/'' subdirectory (typically in $FarmD) is used to hold local css files.%0a%0aTo perform [[local customizations]] for a particular WikiGroup, %0a* place the customizations in a file called "''%3cgroupname>.php''" (where ''%3cgroupname>'' is the actual name of the page group in question) in the ''local/'' subdirectory %0a* place the css customizations in a file called "''%3cgroupname>.css''" (where ''%3cgroupname>'' is the actual name of the page group in question) in the ''css/'' subdirectory.%0aThese files will be automatically processed after processing any local customizations in the ''config.php'' and ''local.css'' files.%0a%0aFor example, to change the image displayed in the upper-left corner of pages in the "GroupName" WikiGroup, one could create ''local/GroupName.php'' containing%0a-> [@%0a%3c?php%0a $PageLogoUrl = "/myimages/chess.gif";%0a@]%0aThe example's effect would cause all pages in the GroupName [[Wiki Group]] to use "/myimages/chess.gif" as the logo image instead of the default.%0a%0aTo add markup to the beginning or end of each page in a wiki group, see [[Group headers]].%0a%0a!!! Per-page customizations%0a[[#PerPage]] PmWiki also allows per-page customizations, simply use the full name of the page to be customized instead of the group. For example, one can use the file ''local/Chess.`HomePage.php'' to set local customizations for Chess.`HomePage.%0a%0aAlmost any customization that would be placed in ''config.php'' can be used as a per-group or per-page customization. %0a%0aAn important exception to this is setting '''per-group or per-page customizations for recipe scripts''' included in config.php. Most recipe scripts would need any customization variables defined before the script is included. Instead of using a per-group or per-page customization php file, use a per-group or per-page conditional statement in config.php, before including the recipe script. Example:%0a%0a>>frame%3c%3c%0a->[@$page = PageVar($pagename, '$FullName');%0a$group = PageVar($pagename, '$Group');%0a//per-group customizations:%0aif($group=='GroupName') {%0a $RecipeVariable = 'valueA';%0a etc. ...%0a}%0a//per-page customizations:%0aif($page=='GroupName.PageName) {%0a $RecipeVariable = 'valueB';%0a etc. ...%0a}%0a//include recipe after variables are set:%0ainclude_once('cookbook/recipescript.php');@]%0a>>%3c%3c%0a %0a!!! Processing order%0aFor all local customizations, PmWiki first processes the ''local/config.php'' file, and then looks for a per-page customization file in the ''local/'' subdirectory to process, followed by any per-group customization file. If no per-page or per-group customizations are loaded, then PmWiki loads ''local/default.php''. If a per-page customization wants to have the per-group customizations loaded first, it can do so directly by using PHP's [@include_once()@] function.%0aFor more information see [[(PmWiki:)wiki cascades]].%0a%0a!!! Custom CSS styles per group or per-page%0aTo apply CSS styles to pages of a specific group named [[Group Name]], create a file named ''GroupName.css'' in the ''pub/css/'' directory and add the CSS style rules there. To apply styles to a specific page, create a file ''GroupName.PageName.css'' in this directory with your style rules. Any CSS rules to be applied for all wiki pages can be put into ''pub/css/local.css''.%0a%0a->[@/pub/css/GroupName.css:%0a%0a body { background: #F4C4B4; }%0a@]%0a%0a!!! Preventing group-Level configurations%0aAny customization file can set $EnablePGCust=0; to prevent later page/group/default customizations from being automatically loaded. If a per-page customization needs to have the per-group customizations loaded first, it can do so directly by using PHP's [@include_once()@] function.%0a%0a!!! Authentication%0aAny passwords required for a group should be set in the group's [[Group Attributes]] page (see [[Passwords Admin]]istration) and not in a group customization file.%0a%0a!!! Consider Wiki Farms%0a[[Wiki Group]]s are an easy way to host multiple sites in a single PmWiki installation by giving each site its own group. Another approach is to use [[Wiki Farms]], which allows each site to have its own set of [[Wiki Group]] and local customization files. Read about %0a%0aIf you are looking for nested group levels, you may want to consider [[PmWiki:HierarchicalGroups|Pm's design considerations on hierarchical groups]].%0a%0a>>faq%3c%3c [[#faq]]%0aQ: How can I apply CSS styles to a particular group or page?%0a%0aA: Simply create a ''pub/css/Group.css'' or ''pub/css/Group.Page.css'' file containing the custom CSS styles for that group or page.%0a%0aQ: Why shouldn't passwords be set in group (or page) customization files?%0a%0aA: The reason for this advice is that per-group customization files are only loaded for the current page. So, if @@[=$DefaultPasswords['read']=]@@ is set in ''local/GroupA.php'', then someone could use a page in another group to view the contents of pages in GroupA. For example, Main.WikiSandbox could contain:%0a%0a--> [=(:include GroupA.SomePage:)=]%0a%0aand because the ''GroupA.php'' file wasn't loaded (we're looking at Main.WikiSandbox --> ''local/Main.php''), there's no read password set.%0a%0aThe same is true for page customization files.%0a%0aQ: Isn't that processing order strange? Why not load per page configuration last (that is after global configuration an per group configuration)?%0a%0aA: Many times what we want to do is to enable a certain capability for a group of pages, but disable it on a specific page, as if it was never enabled. If the per-group config file is processed first, then it becomes very difficult/tedious for the per-page one to "undo" the effects of the per-group page. So, we load the per-page file before the per-group.%0a%0aIf a per-page customization wants the per-group customizations to be performed first, it can use the techniques given in [[PmWiki.GroupCustomizations]] (using ''include_once()'' or setting @@[=$EnablePGCust = 0=]@@).
+time=1251406506
diff --git a/wikilib.d/PmWiki.GroupFooter b/wikilib.d/PmWiki.GroupFooter
new file mode 100644
index 0000000..c9848d9
--- /dev/null
+++ b/wikilib.d/PmWiki.GroupFooter
@@ -0,0 +1,12 @@
+version=pmwiki-2.2.6 ordered=1 urlencoded=1
+agent=Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; GTB6; .NET CLR 1.0.3705)
+author=SchreyP
+charset=ISO-8859-1
+csum=Add "|+" after Documentation index link so translation is shown
+ctime=1219202352
+host=81.243.199.60
+name=PmWiki.GroupFooter
+rev=61
+targets=PmWiki.DocumentationIndex,PmWiki.Variables,PmWiki.GroupF
+text=(:Summary:Trail and talk page links:)%0a[[#trailstart]] (:comment included in PmWiki localisation headers and footers :)%0a(:if ontrail {*$Group}.DocumentationIndex#trailstart#trailend {*$Name}:) %0a(:div style="clear:right; float:right; font-size:smaller; background-color:#eee;":)%0a%3c|[[{*$Group}/Documentation index(#trailstart#trailend)|+]]|> %25%25%0a(:divend:)%0a(:ifend:)%0a(:if ontrail {*$Group}.Variables {*$Name}:) %0a(:div style="clear:right; float:right; font-size:smaller; background-color:#ddd;":)%0a%3c|[[{*$Group}/Variables]]|> %25%25%0a(:divend:)%0a(:ifend:)%0a[[#trailend]]%0a[[%3c%3c]]%0a>>bgcolor=#ffe border-top="1px solid black" font-size=.8em%3c%3c%0a(:if name *-Talk:)%0aThis is a talk page for improving [[{(substr "{*$FullName}" 0 -5)}]].%0a(:else:)%0aThis page may have %25commentout-pmwikiorg%25 a more recent version on [[(http://www.)pmwiki.org]]: [[PmWiki:{*$Name}]], and %25%25 a talk page: [[PmWiki:{*$Name}-Talk]].%0a(:ifend:)%0a>>%3c%3c%0a
+time=1255900372
diff --git a/wikilib.d/PmWiki.GroupHeader b/wikilib.d/PmWiki.GroupHeader
new file mode 100644
index 0000000..0af8a83
--- /dev/null
+++ b/wikilib.d/PmWiki.GroupHeader
@@ -0,0 +1,11 @@
+version=pmwiki-2.2.0 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.19) Gecko/20081216 Ubuntu/8.04 (hardy) Firefox/2.0.0.19
+author=Petko
+charset=ISO-8859-1
+csum=
+host=81.65.14.164
+name=PmWiki.GroupHeader
+rev=59
+targets=
+text=(:Summary: PmWiki group header. Includes styles and trail.:)%0a%25define=note font-style=italic color=green%25\%0a%25define=important block bgcolor=#fcc border='1px solid black' padding=5px%25\%0a%25define=audience class='frame rfloat' font-size:smaller bgcolor=#ffffcc clear:right%25(:comment please leave the multiple style definitions concatenated as a single line. Linebreaks do appear in the output when the wiki is configured with linebreaks enabled -- thanks!:)%0a(:include PmWiki.GroupFooter#trailstart#trailend:)%0a(:if ! equal "{*$:Audience} "" :)(:div style="clear:right;":)%25audience%25{*$:Audience}%25%25%0a(:divend:)(:ifend:)
+time=1234642258
diff --git a/wikilib.d/PmWiki.GroupHeaders b/wikilib.d/PmWiki.GroupHeaders
new file mode 100644
index 0000000..c72a700
--- /dev/null
+++ b/wikilib.d/PmWiki.GroupHeaders
@@ -0,0 +1,11 @@
+version=pmwiki-2.2.5 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3 (.NET CLR 3.5.30729)
+author=DaveG
+charset=ISO-8859-1
+csum=Added definitions for GroupPrintHeaderFmt/FooterFmt
+host=173.72.59.202
+name=PmWiki.GroupHeaders
+rev=69
+targets=PmWiki.WikiGroup,PmWiki.WikiStyles,PmWiki.PageDirectives,PmWiki.WikiAdministrator,PmWiki.IncludeOtherPages,PmWiki.LayoutVariables
+text=(:Summary: Group Header and Group Footer page usage:)%0a(:Audience: authors (intermediate) :)%0aEvery [[WikiGroup]] can have `GroupHeader and `GroupFooter pages that contain markup that should be included at the beginning or end of each page within the group. This feature is useful for:%0a%0a* adding a disclaimer or heading to all of the pages of a group%0a* defining custom [[WikiStyles]] that may be used for all pages in a group%0a* replacing the default headers and/or footers for pages in a group (e.g., using [@(:noheader:)@] and or [@(:nofooter:)@] -- see [[PageDirectives]]).%0a%0aTo create a group header, just create a new page called [@YourGroup.GroupHeader@]. Group headers allow authors to create groups with custom headers and footers without having to coordinate with a [[wiki administrator]]. %0a%0aThe default `GroupHeader or `GroupFooter can be suppressed on an individual page (such as a group's `HomePage) by using the [@(:nogroupheader:)@] and [@(:nogroupfooter:)@] markups ''on that page''.%0a%0aIf a generic `GroupHeader is used in one wikigroup (say, the Site wikigroup), then the code can be easily duplicated in the `GroupHeader of any other group by using %0a[@(:include Site.GroupHeader:)@]. See [[IncludeOtherPages]].%0a%0aIf you want a header or footer to appear when you print a page (action '''print'''), simply create a page called [@YourGroup.GroupPrintHeader@] or [@YourGroup.GroupPrintFooter@] and fill it with your markup.%0a%0aYou can also set the variable [[LayoutVariables#GroupPrintHeaderFmt | [@$GroupPrintHeaderFmt@]]] and [[LayoutVariables#GroupPrintFooterFmt | [@$GroupPrintFooterFmt@]]] in the same way as [@$GroupHeaderFmt@] and [@GroupFooterFmt@] in order to change the header used when [@action=print@]. %0a%0aSee also%0a* [[Cookbook:All group header]] [- {Cookbook/AllGroupHeader$:Summary} -]%0a* [[Cookbook:Wiki footer]] [- {Cookbook/Wikifooter$:Summary} -]%0a%0a%0a>>faq%3c%3c [[#faq]]%0a%0aQ: How do I set one header for all pages/groups?%0aA: The header for each page is controlled by the $GroupHeaderFmt variable. Thus a site-wide groupheader can be added with%0a%0a->[@%0a$GroupHeaderFmt = '(:include {$SiteGroup}.SiteHeader%0a basepage={*$FullName}:)(:nl:)' . $GroupHeaderFmt;%0a@]%0a(:comment above line split as it breaks fixed width skins:)%0a%0aNote that single quotes must be used so that [@$Group@] (which is part of the default contents of $GroupHeaderFmt) will be substituted properly by PmWiki, and that this applies to all variables ending in $[@...Fmt@].%0a(:comment above note edited as it was breaking fixed width skins:)%0aSee also the Cookbook:AllGroupHeader page.%0a%0aA: Any form of markup is valid in $GroupHeaderFmt, thus one can do%0a%0a->[@$GroupHeaderFmt .= "Global markup text here.";@]%0a%0aQ: Would this then work for site footers?%0a->[@%0a$GroupFooterFmt = '(:include {$SiteGroup}.SiteFooter%0a basepage={*$FullName}:)(:nl:)' . $GroupFooterFmt;%0a@]
+time=1253459489
diff --git a/wikilib.d/PmWiki.I18nVariables b/wikilib.d/PmWiki.I18nVariables
new file mode 100644
index 0000000..60bb189
--- /dev/null
+++ b/wikilib.d/PmWiki.I18nVariables
@@ -0,0 +1,11 @@
+version=pmwiki-2.2.6 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3
+author=OliverBetz
+charset=ISO-8859-1
+csum=Clarification: $VarPagesFmt points to a trail page
+host=87.163.84.111
+name=PmWiki.I18nVariables
+rev=12
+targets=PmWiki.Internationalizations,Site.Preferences
+text=(:Summary:variables used for internationalization (i18n):)%0a%0aThis page describes the variables used by PmWiki for [[Internationalizations]] (i18n).%0a%0a:$VarPagesFmt:An array which contains the PageNames where you can find lists (trails) of pages containing variable definitions. To be modified when documentation is not in english. See ''scripts/vardoc.php''.%0a%0a:$XL:An array (hash) which contains pairs of language identifiers and translation hashes. Each translation hash maps a given lookup key (or phrase) into a corresponding text string for the given language. Thus, it is essentially a multi-lingual dictionary used for phrase translation. It is also used for handling user preference mappings. Thus, the 'e_row' value that one finds on the [[Site.Preferences]] page is loaded into $XL during preference processing.%0a%0a:$XLLangs:An array that contains the names of the currently active language definitions. Only dictionaries in $XL that are named in $XLLangs are used by the [=$[...]=] markup when performing a translation.%0a%0aSee also:%0a* $TimeFmt%0a
+time=1254734813
diff --git a/wikilib.d/PmWiki.Images b/wikilib.d/PmWiki.Images
new file mode 100644
index 0000000..1987cfa
--- /dev/null
+++ b/wikilib.d/PmWiki.Images
@@ -0,0 +1,12 @@
+version=pmwiki-2.2.4 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.19) Gecko/20081216 Ubuntu/8.04 (hardy) Firefox/2.0.0.19
+author=Petko
+charset=ISO-8859-1
+csum=+
+host=86.69.109.9
+keywords=graphics, pictures, photos
+name=PmWiki.Images
+rev=174
+targets=PmWiki.DocumentationIndex,PmWiki.Links,PmWiki.Uploads,PmWiki.InterMap,PmWiki.WikiStyles
+text=(:Summary:Placing images in pages:)%0aTo place an image into a page, enter the address (url) of the image into the markup text. %0aAny ''alternate text'' (used for tooltips and for browsers that do not display images) is placed in double quotes immediately following the image url.%0aA caption can follow separated by a vertical bar (|), and may include simple formatting%0a%0a(:markup:)%0ahttp://pmichaud.com/img/misc/pc.jpg"Paper clips" | [- %25newwin%25 [[ Wikipedia:Paper_clips | Paper clips ]] are ''fun'' to work with. -]%0a(:markupend:)%0a%0aImages can also be specified as [[upload(s)]]ed files (i.e., [@Attach:image.jpeg@]) and using [[InterMap]] links. %0aBy default PmWiki supports the following image types:%0a(:include PmWiki/Uploads#imagetypes#imagetypesend:)%0a%25note%25 (See also [[PmWiki/Uploads]] and [[#notes|Notes]] below for image files that lack extensions.)%0a%0aTo create a [[link(s)]] to an image (like [[http://pmichaud.com/img/misc/pc.jpg]] as opposed to displaying the image itself), use double brackets to mark the link, as in [@[[http://pmichaud.com/img/misc/pc.jpg]]@] or [@[[Attach:image.jpeg]]@].%0a%0aTo have an image link to another location, use the image as the link text as in %0a(:markup:)%0a[[http://pmwiki.org/ | http://pmichaud.com/img/misc/pc.jpg"PmWiki"]]%0a(:markupend:)%0aor [@[[http://example.com|Attach:Groupname./image.jpeg]]@].%0a%0a[[#captions]]%0a!! Captions%0aA caption can be added to an image using a vertical brace and the caption text.%0a%0a(:markup class=horiz:)%0ahttp://pmichaud.com/img/misc/pc.jpg"Paper clips" | '''Figure 1'''%0a(:markupend:)%0a%0aA caption can be added to an image using a vertical brace and the caption text.%0aNormally, images are displayed "in line" with the surrounding text. Use [@%25center%25@] to center an image. Use [@%25right%25@] to right-align an image.%0a%0a(:markup:)%0aLorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. %25center%25http://pmichaud.com/img/misc/pc.jpg"Paper clips"%25%25%0a%0aLorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. %25right%25 http://pmichaud.com/img/misc/gem.jpg%25%25%0a(:markupend:) %0a%0a[[#floating]]%0a!! Floating images%0aTo left or right-align an image with text wrapping around it, use the [@%25lfloat%25@] or [@%25rfloat%25@] [[wiki styles]]. %0a%0a(:markup:)%0a%25lfloat text-align=center margin-top=5px margin-right=25px margin-bottom=5px margin-left=25px%25 http://pmichaud.com/img/misc/gem.jpg | '''Rock on!'''%0a'''The image is left-aligned, with margins set; the caption is centered; the text wraps on the right side of the image.'''%0a%0aLorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim%0aveniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea%0acommodo consequat. %0a(:markupend:)%0a%0aThe [@[[%3c%3c]]@] markup breaks floating text, and the text continues at the bottom of the image.%0a%0a(:markup:) %0a%25lfloat%25 http://pmichaud.com/img/misc/gem.jpg%0a'''The image is left-aligned, and the text wraps on the right side of the image. The text after the ''[@[[%3c%3c]]@]'' markup continues below the image.'''%0a[[%3c%3c]]%0aLorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. %0a(:markupend:)%0a%0aUse the [@%25lframe%25@] or [@%25rframe%25@] styles to float an image and place a frame around the image and its caption. The frame can be formatted via wikistyles:%0a%0a(:markup:) %0a%25rframe%25 http://pmichaud.com/img/misc/gem.jpg | '''Rock on!'''%0a'''The image is right-aligned, and the text wraps on the left side of the image.'''%0a%0aLorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.%0a%0a%25cframe width=100px bgcolor=lightblue border='3px solid red' padding=20px%25 http://pmichaud.com/img/misc/gem.jpg%0a%0aExample to show failure to fully apply width setting:-%0a%25cframe width=50px bgcolor=lightblue border='3px solid red' padding=20px%25 http://pmichaud.com/img/misc/gem.jpg%0a(:markupend:)%0a%0aUse [@%25block rframe%25@] to set off multiple images and caption text to be stacked vertically in a right-floating frame.%0a%0a(:markup:) %0a%25block rframe width=300px%25http://pmichaud.com/img/misc/gem.jpg\\%0aLorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\\\%0ahttp://pmichaud.com/img/misc/bubble.jpg\\%0aLorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.%25%25%0a%0aText subsequent to the defined block wraps to the left of the frame. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.%0a(:markupend:)%0a%0a!!Resizing images [[#resizing]]%0a%0aTo resize an image via wikistyles, use [@%25width=50px%25@] or [@%25height=50px%25@] in front of an image. The [@%25thumb%25@] wikistyle is a helpful shortcut for [@%25width=100px%25@].%0a%0a(:markup:)%0a%25width=50px%25 http://pmichaud.com/img/misc/bubble.jpg \%0a%25height=50px%25 http://pmichaud.com/img/misc/bubble.jpg \%0a%25thumb%25 http://pmichaud.com/img/misc/bubble.jpg%0a(:markupend:)%0a%0aNote: Resizing an image via wikistyles only affects how it is displayed in a browser; it does not reduce the transfer size of the image itself - hence resizing via wikistyles is not an acceptable method of generating a page-full of images, or 'gallery'.%0a%0aIf you want a resized image within a link, you have to specify the size before the link as well as close it off with a [=%25%25=].%0a%0a(:markup:)%0a%25width=60%25[[http://pmwiki.org/ | http://pmichaud.com/img/misc/pc.jpg"PmWiki"]]%25%25 \%0a%25height=60%25[[http://pmwiki.org/ | http://pmichaud.com/img/misc/pc.jpg"PmWiki"]]%25%25 \%0a(:markupend:)%0a%0aTo open the link in new window, you place [=%25newwin%25=] before the size specification.%0a%0a(:markup:)%0a%25newwin%25[[http://pmwiki.org/ | http://pmichaud.com/img/misc/pc.jpg"PmWiki"]]%25%25%0a(:markupend:)%0a%0aResized images using [@%25thumb%25@] can also be floated with frames, as well as made into links.%0a%0a(:markup:) %0a%25lframe thumb%25 [[http://pmichaud.com/img/misc/bubble.jpg | http://pmichaud.com/img/misc/bubble.jpg"Burst the bubble"]] | [-Bubble-]%0a%25lframe thumb%25 http://pmichaud.com/img/misc/pc.jpg"Clip the ticket" | [-Paper Clips-]%0a%25lframe thumb%25 [[DocumentationIndex | http://pmichaud.com/img/misc/gem.jpg"Visit the Documentation Index"]] | [[DocumentationIndex | [-Rock On-]]]%0a(:markupend:)%0a%0a[[#links]]%0a!!! Images as [[PmWiki/links]]%0aTo use an image as a link specify an image instead of text in the [[PmWiki/link(s)]] markup.%0a(:markup:)%0a[[PmWiki/Links | http://pmichaud.com/img/2003/atc-1.gif"Information about wiki links"]]%0a(:markupend:)%0a%0a[[#notes]]%0a!!!Notes%0a* '''An image file that lacks a correct extension''' can be displayed by addition of a "false" extension to the URL. For example, if the url is [@http://example.com/script/tux@], add a fake query string on the end with the desired extension (e.g., [@http://example.com/script/tux?format=.png@]). If query strings are unsuitable, a fragment identifier should work, e.g. [@http://example.com/script/tux#file.png@].%0a%0a* Relative width is possible by using percentages.%0a(:markup:)%0a%25width=10pct%25 http://pmichaud.com/img/misc/bubble.jpg \%0a%25height=30pct%25 http://pmichaud.com/img/misc/bubble.jpg %0a(:markupend:)%0a%0a* '''Flowing text is possible, like captions, within a frame'''%0a(:markup:)%0a>>lframe width=130px%3c%3c%0a%25thumb width=130%25 [[http://pmichaud.com/img/misc/bubble.jpg | http://pmichaud.com/img/misc/bubble.jpg"Burst the bubble"]] | [--Long caption for an image like [[http://pmichaud.com/img/misc/bubble.jpg | the bubble]]. This is just to show some text flowing within the frame.--]%0a>>%3c%3c%0a(:markupend:)%0a%0a%0a%0a!!!See also%0a* [[Cookbook:Images]] - adding image galleries, automatic thumbnails, background images and more. %0a%0a!!!Credits%0aThe images on this page were obtained from http://flickr.com and are redistributed under a Creative Commons License.%0a%0a(:keywords graphics, pictures, photos:)%0a%0a>>faq%3c%3c [[#faq]]%0a%0aQ: Is it possible to link an image on PmWiki without using a fully qualified URL?%0aA: Yes. For images that are attachments, the general format is [@Attach:Groupname./image.gif@]. To link to an image that is on the same server, use [@Path:/path/to/image.gif@].%0a%0aQ: Can I attach a client image file on PmWiki?%0aA: Yes, see [[PmWiki/Uploads]] .%0a%0aQ: How can I include a page from another group that contains an attached image?%0aA: Include the page in the normal way, ie [@(:include GroupName.Pagename:)@]. In the page to be included (that contains the image) change [@Attach:filename.ext@] to [@Attach:{$Group}./filename.ext@]. %0a%0aQ: Why, if I put an image with rframe or rfloat and immediatly after that I open a new page section with ! the section title row is below the image instead of on the left side?%0aA: Because the CSS for '''headings''' such as ! contains an element '''clear:both''' which forces this behaviour. Redefine the CSS locally if you want to stop this happening, but I think the bottom border (that underlines the heading) would need further re-definition. I just use bolding for the title, and 4 dashes below [=-=]--- to separate a new section, and it saves the effort of fiddling with the core definitions.%0a%0aUnlike the '''lframe''' and '''rframe''' directives, '''cframe''' does not fully honour the width setting. While the frame itself resizes to match the request, the enclosed image does not, and retains its original width. Effect is the same in IE and Fx. I've added an example beneath the standard example above.%0a%0aQ: Is it possible to disallow all images? I already disabled uploads but I also want to disallow external images from being shown on my wiki pages.%0a%0aA: Yes, add to config.php [@DisableMarkup('img');%0a$ImgExtPattern = "$^";@]%0a%0aQ: How can I make it so that when I place an image in a page, the block of text it is in is a %3cp> (paragraph) rather than a %3cdiv> (division)?%0a%0aA: If you just want it to happen for a single image (instead of all), then%0atry putting [@[==]@] at the beginning of the line, as in:%0a%0a->[@[==] http://www.pmwiki.org/pub/pmwiki/pmwiki-32.gif@]%0a%0aHaving [@[==]@] at the beginning of a line forces whatever follows to%0abe part of a paragraph.%0a%0aQ: Is there any way to use relative paths for images?%0aA: See Cookbook:RelativeLinks and $EnableLinkPageRelative.%0a%0aQ: Is there a way to attach a BMP and have it display rather than link?%0aA: Add to config.php the following line:\\%0a @@$ImgExtPattern = "\\.(?:gif|jpg|jpeg|png|bmp|GIF|JPG|JPEG|PNG|BMP)";@@\\%0aNote that BMP images are uncompressed and quite heavy. You may wish to convert them to PNG (lossless) or JPG (lossy) format, and thus reduce 5-20 times their filesizes.%0a%0aQ: Is there a way to have a table to the left or right of an image?%0aA: Yes, see [[(http://www.pmwiki.org/wiki/Test/)TableAndImage]].%0a
+time=1250711511
diff --git a/wikilib.d/PmWiki.IncludeOtherPages b/wikilib.d/PmWiki.IncludeOtherPages
new file mode 100644
index 0000000..f1e322a
--- /dev/null
+++ b/wikilib.d/PmWiki.IncludeOtherPages
@@ -0,0 +1,11 @@
+version=pmwiki-2.2.10 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/532.5 (KHTML, like Gecko) Chrome/4.0.249.78 Safari/532.5
+author=simon
+charset=ISO-8859-1
+csum=add anchor
+host=202.37.32.2
+name=PmWiki.IncludeOtherPages
+rev=119
+targets=PmWiki.Links,PmWiki.WikiGroup,PmWiki.PageTextVariables,PmWiki.IncludeOtherPages-Talk,Cookbook.IncludeSection,Site.PageListTemplates,Cookbook.IncludeUrl,PmWiki.WikiStyles,PmWiki.ConditionalMarkup,PmWiki.PageVariables,PmWiki.WikiAdministrator,PmWiki.PageLists
+text=(:Summary: Include contents from other PmWiki pages:)%0a(:Audience: authors (intermediate) :)%0aThe [@(:include:)@] directive makes it possible to insert (or [[Wikipedia:Transclusion|"transclude"]]) the contents of other pages into the current wiki page. All of the include directives below perform a straight text inclusion. In particular, any page [[links]] in the included text are assumed to link to pages in the current [[(wiki) group]] if not otherwise qualified.%0a%0a!! Syntax%0aThe basic syntax is%0a* [=(:=]include PageName:)%0a-> with pagename includes the full page from the same group.%0a* [={Group/PageName$:=][[#includeptv|PTVar]]}%0a-> includes a [[PageTextVariables|named variable]] from a page, [[(Wiki)Group]] and PageName are options%0a%0aThe full syntax is%0a* [=(:=]include%0a [[#includefullname|FullName]]#[[#includeanchor|fromanchor]]#[[#includeanchor|toanchor]] \%0a [[#includelines|lines]]=''123'' \%0a [[#includeself|self]]=''0'' \%0a [[#includebasepage|basepage]]=''abc'' \%0a [[#includevariable|variable]]=''value'' \%0a :)%0a-> includes a page or pages according to the parameters supplied. Parameters are optional.%0a[[#firstanchor]]%0a%0a!! Parameters%0aName parameters with or without anchors, and [[#includevariable| variable]] parameters, may be repeated.%0a%0a[[#includefullname]]%0a!!! Named pages%0a-%3c [@(:include PageName:)@]%0a-%3c [@(:include Group.PageName:)@]%0a-%3c [@(:include Page1 Page2 Group1.Page3 Group2.Page4:)@]%0a-> Includes the entire text of another page into the current page. Multiple pages may be specified, but only the first available is included.%0a%0a[[#errormessage]]%0aYou can use the above feature to '''display an error message if an include fails'''. Create a page, eg. Site.IncludeFailed containing the error message. You can use any page name. Then, in your include markup, append this page at the end of the page list:%0a [=(:include Page1 Page2 Page3 Site.IncludeFailed:)=]%0aA slightly more complex approach is outlined at [[PmWiki:IncludeOtherPages-Talk|the talk page]].%0a%0a[[#includeanchor]]%0a!!! Anchors%0a|| width=*%0a||[@(:include PageName#from#to:)@] ||include lines from ''`PageName'' between the [@[[#from]]@] and [@[[#to]]@] [[Links#anchors|anchors]]%0a||[@(:include PageName#from#:)@] ||include all lines after [@[[#from]]@] to the end of the page%0a||[@(:include PageName##to:)@] ||include all lines from the start of the page to [@[[#to]]@]%0a||[@(:include PageName#from:)@] ||include everything between [@[[#from]]@] and the next anchor%0a||[@(:include PageName#:)@] ||include everything from the top of the page to the first anchor%0a||[@(:include PageName##:)@] ||include everything from the top of the page to the bottom of the page%0a-> %25note%25 Note: do not put whitespace between "#from" "#to"%0a%0a-> %25note%25 Note: text on the same line as a closing anchor but preceding the closing anchor will '''NOT''' be included in the text. Example Below:%0a--> [@[[#start]]some text on the first line@]%0a--> [@some text on the last line [[#end]]@]%0a-> %25note%25The above, when included via [@(:include PageName#start:)@] will have the text on the first line but not the text on the last line.%0a%0a-%3c [@(:include Page1 Page2 #from#to:)@]%0a-> Include from the first available of Page1, Page2 between the [@[[#from]]@] and [@[[#to]]@] %0a-> %25note%25 Note: put whitespace between "Page2" and "#from#to". The same anchors "#from#to" should be in both pages. If proper anchors are missing in the first available of Page1, Page2 the whole contents of the page is included.%0a-> This does not seem to work in 2.2 betas. See Cookbook:IncludeSection for a fix.%0a%0a-%3c [@(:include Page1#from1#to1 Page2#from2#to2:)@]%0a-> Include the first from the first available of Page1 (between the [@[[#from1]]@] and [@[[#to1]]@]) or Page2 (between the [@[[#from2]]@] and [@[[#to2]]@] ) %0a%0a-%3c %25green%25Note%25%25: Previous versions of PmWiki allowed whitespace between [@#from@] and [@#to@] anchors even though it was not designed to. Newer versions do not allow whitespace anymore. To re-enable this "exploited misbehavior" put this into your config.php or farmconfig.php%0a%0a-> [@Markup('includeanchors', '%3cinclude', '/(\\(:include.*?#\\w+)\\s+(#\\w+)/', '$1$2');@]%0a%0a[[#includelines]]%0a!!! Lines=%0a-%3c [@(:include PageName lines=10:)@]%0a-%3c [@(:include PageName lines=5..10:)@]%0a-%3c [@(:include PageName lines=5..:)@]%0a-> Include the first 10 lines, lines 5-10, or lines 5 and up from ''`PageName''. A "line" in this context refers to a line of source. ''Thus a line may be a paragraph that wraps over several lines on the screen, or a completely blank line.''%0a%0a-%3c [@(:include Page1 Page2 Page3 lines=1..5:)@]%0a-> Include the first five lines from the first available of Page1, Page2, or Page3. (To include lines from a list of pages, use a separate include for each.)%0a%0a[[#includeself]]%0a!!! Self=%0a-%3c [@(:include PageName self=0:)@]%0a-> The parameter @@self@@ can be @@0@@ or @@1@@. It tells the include directive if it is allowed to include the current page. This is useful if PageName is a variable like [@{$Name}@] and you want to prevent the directive from including the current page.%0a%0a[[#includeptv]]%0a!!! [[Page text variables]]%0a-%3c [@{Group/PageName$:Var}@]%0a-> Includes definition list values from an (optional) page as [[page text variables]]. These are defined using a definition list ([@:item:description@]), simple colon delimiter ([@item:description@]), or special markup ([@(:item:description:)@]).%0a%0a[[#includebasepage]]%0a!!! Basepage=%0a%0a-%3c [@(:include PageName basepage=BasePageName:)@]%0a-> Include PageName, but treat all relative links and page variables on ''PageName`'' as relative to ''BasePageName''.%0aIf @@basepage=@@ is provided all relative links and page variables are interpreted relative %0ato basepage.%0aSo, if one creates [@TemplateName@] as%0a-> [@Name: {$:Name}%0aAddress: {$:Address}@]%0athen the directive%0a-> [@(:include TemplateName basepage=PageName:)@]%0awill retrieve the contents of [@TemplateName@], treating any page variables and links as being relative to [@PageName@]. %0aIn particular, the values for [@{$:Name}@] and [@{$:Address}@] will be taken from [@PageName@], but things like [@{$Title}@] and [@{$LastModifiedBy}@] would also work here.%0a%0a!!!! Basepage usage%0aThe primary purpose of basepage is to allow the include of pages in a way that mimics the 2.1.x behavior where page variables %0aand links are interpreted relative to the currently displayed page.%0aThis is done with:%0a-> [@(:include SomeOtherPage basepage='' :)@]%0a -or-%0a-> [@(:include SomeOtherPage basepage={*$FullName} :)@]%0a%0aIt also allows [=GroupHeader and GroupFooter=] to have their page variables and links be relative to the currently displayed page %0a(instead of [=GroupHeader and GroupFooter=]):%0a>>pre%3c%3c%0a ## PmWiki default $GroupHeaderFmt setting%0a $GroupHeaderFmt = %0a [='(:include {$Group}.GroupHeader self=0 basepage={*$FullName}:)(:nl:)';=]%0a>>%3c%3c%0a%0aOtherwise, using {$Name} inside of a [=GroupHeader=] would display '[=GroupHeader=]' and not the name of the currently displayed page.%0a%0aAs has been discovered, the basepage= parameter is general enough that it can also be used as a templating engine, so that%0awe can grab a template page containing variables that are then filled in with values from another page:%0a->[@(:include TemplatePage basepage=DataPage :)@]%0a%0aAnd, of course, a single TemplatePage can actually contain multiple templates delimited by anchors, so that we end up with a syntax eerily similar'^[[#footnote|#]]^' to pagelist-templates:%0a>>pre%3c%3c%0a [@(:include TemplatePage#abc basepage=DataPage :)@]%0a (:include TemplatePage#def basepage=DataPage :)%0a (:include TemplatePage#xyz basepage=DataPage :)%0a>>%3c%3c%0a%0aSo then [=TemplatePage=] can use a syntax like:%0a>>pre%3c%3c%0a [@%0a [[#abc]]%0a ...template stuff here...%0a [[#abcend]]%0a @]%0a>>%3c%3c%0a%0aand it's possible to display [=TemplatePage=] as a template without it being interpreted... same as we do for [[Site.PageListTemplates]].%0a%0a%0a-%3c [[#footnote]] [- '^[1]^'Okay, maybe it's not so eerie, given that the pagelist template code actually uses the same function as (:include:) to grab its templates. But it's still a useful parallel. -]%0a%0a[[#includevariable]]%0a!!! Specifying variables as parameters%0aYou can also specify variable values inline with the include statement, and refer to the variables in the template using the [@{$$variable1}@] format:%0a-> [@(:include TemplatePage variable1="value" variable2="value2":)@]%0a%0aThis assumes that a site has $EnableRelativePageVars enabled, which is recommended in PmWiki 2.2.0 -- but disabled by default to help people upgrading from 2.1.x.%0a%0aFor example, on my included page ("template") I might have this:%0a%0a(:markup class=horiz:)%0a[[#ivars]]%0aHi, {$$Name}, how are you today?%0a[[#ivarsend]]%0a(:markupend:)%0a%0aThen, including that section above (that section is available via the section @@[@{$FullName}#ivars)@]@@) you get this type of behavior:%0a%0a(:markup class=horiz:)%0a(:include {$FullName}#ivars Name=Sam:)%0a(:markupend:)%0a%0aIf a value contains spaces, quote it:%0a%0a(:markup class=horiz:)%0a(:include {$FullName}#ivars Name="my friend":)%0a(:markupend:)%0a%0a!! See Also%0a* [[PmWiki/Page text variables]] {PmWiki/PageTextVariables$:Summary}%0a* [[Cookbook:IncludeUrl]] {Cookbook.IncludeUrl$:Summary}%0a%0a!! Styling Note%0aBy default, Included pages or lines cannot be distinguished from other text on the page. To provide a visual indication that this text is special, you can apply [[PmWiki/Wiki Styles]]. For example:%0a%0a(:markup:)%0a%25define=leftborder border-left="2px solid #88f" margin-left="2px" padding="1px 0 3px 10px"%25%0aWhat is PmWiki?%0a>>leftborder%3c%3c (:include PmWiki.PmWiki lines=1..4:) %0a>>%3c%3c%0a''Have a very nice day!''%0a(:markupend:)%0a%0a!!! Parameter References%0a%0aAny parameters supplied to an include statement (whether they are keywords or not) are accessible inside the included page as a special [@{$$...}@] variable of the same name. This feature can be used to provide extra information to use when displaying the included page.%0a%0a!!! Notes%0a* You can also say [@(:include My/Page#myanchor lines=4:)@] which starts from, and includes, the line with the anchor [@[[#myanchor]]@] for four lines.%0a%0a!! Notes about use with [[conditional markup]]%0aThe [@(:include ...:)@] markup is processed after conditional markup is evaluated.\\%0aTherefor you can include a page or page section as part of a condition, like%0a->[@(:if some condition:)(:include SomePage#section:)(:if:) @] %0aBut [@(:include SomePage#section:)@] doesn't look to see if [@[[#section]]@] is part of a conditional, like %0a->[@(:if some condition:)[[#section]]...[[#sectionend]](:ifend:)@]%0a[@(:include SomePage#section:)@] will ignore such a condition. %0a%0aWhen [[Conditional Markup|testing variables]] in included pages the context of the page (source or target) can be useful.%0aSee [[PmWiki/PageVariables#specialreferences|special references]] for details.%0a%0a----%0a%0a>>faq%3c%3c [[#faq]]%0a%0aQ: [[#maxincludes]] What's the maximum number of includes that can exist in a page? %0a-> My site seems to stop including after 48 includes. ($MaxIncludes)%0a%0aA: By default, PmWiki places a limit of 50 include directives for any given page, to prevent runaway infinite loops and other situations that might eat up server resources. (Two of these are GroupHeader and GroupFooter.) The limit can be modified by the [[wiki administrator]] via the $MaxIncludes variable.%0a%0aQ: Is there any way to include from a group of pages without specifying by exact name, e.g. between Anchor X and Y from all pages named IFClass-* ?%0aA: This can be achieved using [[page lists]].%0a%0a%0aQ: There appears to be a viewing issue when the included page contains the [=(:title:)=] directive.%0aA: As of version 2.2.0, the ''last'' title in the page overrides previous ones. In future versions, this may be configurable, but for the moment, best is to place your [=(:title :)=] directive at the bottom of the page, after any includes.%0a
+time=1265925586
diff --git a/wikilib.d/PmWiki.InitialSetupTasks b/wikilib.d/PmWiki.InitialSetupTasks
new file mode 100644
index 0000000..dffe010
--- /dev/null
+++ b/wikilib.d/PmWiki.InitialSetupTasks
@@ -0,0 +1,11 @@
+version=pmwiki-2.2.8 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6
+author=Peter Bowers
+charset=ISO-8859-1
+csum=add scripturl and pubdirurl
+host=92.60.31.216
+name=PmWiki.InitialSetupTasks
+rev=91
+targets=PmWiki.Installation,Site.Site,SiteAdmin.SiteAdmin,Site.SideBar,PmWiki.Variables,PmWiki.UTF-8,PmWiki.Security,PmWiki.PasswordsAdmin,PmWiki.Upgrades,PmWiki.UploadsAdmin,PmWiki.LocalCustomizations,PmWiki.WikiFarms,PmWiki.MailingLists,PmWiki.WikiAdministrator
+text=(:Summary:First steps following a fresh installation:)%0a(:Audience: administrators (basic) :)%0aOnce you have PmWiki running on your site (see [[Installation]]), you can customize it for your particular needs.%0a%0aMost PmWiki configuration is performed in files called ''local/config.php'' and ''pub/css/local.css''. %0aSome configuration is done on special pages in the [[{$SiteGroup}/]] and [[SiteAdmin/]] groups, such as the [[{$SiteGroup}.SideBar]] menu.%0a%0a!! The local configuration file (''local/config.php'')%0aWhen you first install PmWiki, the ''local/config.php'' file does not exist. Copy the ''sample-config.php'' file (in the ''docs/'' directory) to ''local/config.php'' and use it as a starting point. You could create ''local/config.php'' from scratch, but ''sample-config.php'' is already populated with many of the options you might want to adjust.%0a%0aHere is a simple ''config.php'' file:%0a%0a-> [@%0a%3c?php if (!defined('PmWiki')) exit();%0a$WikiTitle = "My New Wiki";%0a$PageLogoUrl = "http://example.com/mylogo.gif";%0a%0a# Uncomment these if needed%0a#$ScriptUrl = 'http://example.com/pmwiki/pmwiki.php';%0a#$PubDirUrl = 'http://example.com/pmwiki/pub';%0a%0a$DefaultPasswords['admin'] = crypt('onesecret');%0a%0a$EnableUpload = 1;%0a$DefaultPasswords['upload'] = crypt('secrettwo');%0a%0aputenv("TZ=EST5EDT");%0a$TimeFmt = '%25B %25d, %25Y, at %25I:%25M %25p EST';%0a@]%0a%0aNote that ''config.php'' begins with @@%3c?php@@ . The PHP end tag @@?>@@ is optional, and can be left off to improve compatibility with some operating systems. Be sure there aren't any blank lines or spaces before the @@%3c?php@@ or after any closing @@?>@@, or else you may get strange PHP error messages at the beginning of your wiki pages.%0a%0aThe ''config.php'' file above sets the value of PHP variables used by PmWiki:%0a* The $WikiTitle variable gives the name of your site as it will appear in a user's browser title bar.%0a* The @@$ScriptUrl@@ and @@$PubDirUrl@@ variables tell your wiki where it is located. Often pmwiki can guess, but if you have difficulty with links not working or skins not being found then try uncommenting these lines.%0a* The $PageLogoUrl variable specifies the URL of the icon image that will appear in the upper-left corner of each wiki page.%0a* The @@$DefaultPasswords['admin']@@ sets an administrative password.%0a* Setting $EnableUpload to "1" enables Uploads ("Attached files"). @@$DefaultPasswords['upload']@@ sets an upload password.%0a* The TZ environment variable defines a particular time zone (see [[Cookbook:ChangeTimeFormat]]).%0a* The $TimeFmt variable defines the appearance of time strings and (along with TZ) localizes the wiki to a specific time zone (see [[Cookbook:ChangeTimeFormat]]).%0a%0aBy setting these (and other) variables in ''local/config.php'', you can change the look and feel of PmWiki from its default, sometimes substantially so. See [[PmWiki.Variables]] for a list of variables that PmWiki uses, and see PmWiki:PmWikiUsers for examples of sites that use PmWiki in customized ways.%0a%0a!!! Other common setup tasks%0aThe following [[variables]] are often requested when preparing a new wiki%0a* Author required when editing a page @@$EnablePostAuthorRequired = 1;@@ %0a* Set the $DefaultGroup %0a%0aThese common [[(Cookbook:)Cookbook]] recipes are also often installed immediately%0a* [[(Cookbook:)Clean Urls]] - Remove the @@?n=Group.Page@@ arguments from the end of URLs%0a%0aIf you prepare an international wiki, potentially with characters in different alphabets (Cyrillic, Greek, Chinese) or many diacritical symbols (Czech + French), please look at [[PmWiki.UTF-8]] and Cookbook:UTF-8.%0a%0a!! Security%0aReview and set up any [[security]] required.%0a%0a!!!Setting an administrative password%0a%0aThe pages in the [[{$SiteGroup}/Site]] group (except the {$SiteGroup}.SideBar) are locked by default. In order to edit pages in this group you need to create a site-wide admin password in ''local/config.php''. To set the site-wide admin password to "@@mysecret@@", change the line to the following:%0a%0a->[@$DefaultPasswords['admin'] = crypt('mysecret');@]%0a%0aYou must use the [@crypt()@] function, but set the password to a value with meaning for you. See [[PasswordsAdmin]] for details about making the password more secure.%0a%0a!![[#dontmodify]]Don't modify or rename ''pmwiki.php''%0a%0aPmWiki has been designed so that all customizations can be made without changing the distribution files -- one of its design goals is to provide seamless upgrades. PmWiki never writes to files in the ''local/'' or ''cookbook/'' directories, so placing your customizations here makes it easier to track the changes and [[upgrades | upgrade PmWiki]] without losing the changes.%0a%0aWhen changing the configuration of your site, always change the ''local/config.php'' file or add files to the ''cookbook/'' or ''pub'' directories. Do not change ''pmwiki.php'' or the files in the ''scripts/'' directory because the files are supposed to be overwritten upon upgrading.%0a%0aYou shouldn't rename ''pmwiki.php'' either. If you rename the file it will not be overwritten during an upgrade of the software and there will be a version mismatch. Many administrators add an ''index.php'' "wrapper script" in the pmwiki directory that contains the following single line:%0a%0a->[@%3c?php include('pmwiki.php');@]%0a%0aJust make an text-file. Paste %3c?php include('pmwiki.php'); into it.%0aSave the file as index.php%0aSend it via FTP to the same directory as pmwiki.php is located. %0a%0a!! Other organisation%0a!!! Upload directories%0aBy default Pmwiki uses an upload directory for each group%0a(see [[Uploads admin(#uploaddirectoryconfiguration)]]istration.%0aDeciding on accepting the default, or choosing an alternative (eg one directory for the entire wiki, or one directory per page) is best done when setting up your wiki.%0a%0a!!! Page store directories%0aBy default Pmwiki uses a single page store directory (wiki.d).%0aDeciding on accepting the default (recommended), or choosing the alternative (one directory per group) is best done when setting up your wiki. '^[[Cookbook:PerGroupSubDirectories|#]]^'%0a%0a!!Other customization%0a%0aAfter setting up ''local/config.php'' file, you may wish to make other [[local customizations]]. See the [[Cookbook:CookbookBasics | PmWiki Cookbook]] for a large number of customizations that have been contributed. And don't fear Cookbook recipes - they're well prepared, so that most of them require only to download a single file, add a one-line include command to @@config.php@@, and ''voilà!'' - they're working!%0a%0aIf you (or others sharing your server) want to maintain more than one wiki on the same server, see [[Wiki Farms]].%0a%0a!!Now what?%0a%0aDon't forget to join a [[MailingLists | PmWiki mailing list]], where you can email other [[wiki administrator]]s for help on customizing PmWiki and participate in discussions about PmWiki improvements. Once you have your site operational, be sure to add it to PmWiki:PmWikiUsers so others will know about it!%0a
+time=1261647603
diff --git a/wikilib.d/PmWiki.Installation b/wikilib.d/PmWiki.Installation
new file mode 100644
index 0000000..9c9c9c8
--- /dev/null
+++ b/wikilib.d/PmWiki.Installation
@@ -0,0 +1,12 @@
+version=pmwiki-2.2.10 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.7) Gecko/20100106 Ubuntu/9.10 (karmic) Firefox/3.5.7
+author=Petko
+charset=ISO-8859-1
+csum=If you upgrade, please read the page [[Upgrades]]
+host=86.69.109.228
+name=PmWiki.Installation
+rev=373
+targets=PmWiki.Requirements,PmWiki.Upgrades,PmWiki.WikiFarms,PmWiki.ChangeLog,PmWiki.ReleaseNotes,PITS.PITS,PmWiki.MailingLists,PmWiki.Download,Cookbook.Cookbook,PmWiki.Skins,Cookbook.Skins,PmWiki.InitialSetupTasks,PmWiki.Internationalizations,Group.Name,Cookbook.SimultaneousEdits,PmWiki.SimultaneousEdits,PmWiki.Troubleshooting,Cookbook.PHP,Cookbook.InstallOnIIS,Cookbook.CleanUrls,Cookbook.SourceForgeServers,Cookbook.Standalone,Cookbook.WikiOnAStick
+text=(:title PmWiki Installation :)%0a(:Summary: Obtaining and installing PmWiki:)%0a(:Audience: administrators (basic) :)%0aThis page explains how to download and install PmWiki 2.1 and 2.2. %0aHere's a list of related pages:%0a%0a* [[Requirements]] - {Requirements$:Summary}%0a* [[Upgrades]] - {Upgrades$:Summary}%0a* [[Wiki Farms]] - {WikiFarms$:Summary}%0a* [[Change Log]] - {ChangeLog$:Summary}%0a%0a'''Improvements''' to these instructions are always appreciated. Just report any problems you encounter to the pmwiki-users [[mailing list(s)]] or use the [[PITS:PITS |PmWiki Issue Tracking System]].%0a%0a!! Installing PmWiki%0aIf you upgrade, please read the page [[Upgrades]].%0a%0a!!! 1. Download%0aDownload the latest version of PmWiki as a%0a* zip archive ([[(http://pmwiki.org/pub/pmwiki/)pmwiki-latest.zip]]), or a%0a* gzipped tarball ([[(http://pmwiki.org/pub/pmwiki/)pmwiki-latest.tgz]]) from [[http://pmwiki.org/pub/pmwiki/]], or%0a* download the latest beta from the [[PmWiki:Download]] page.%0a%0a%0a!!! [[#unpack]] 2. Unpack%0aUnpack the archive ([@tar zxvf pmwiki-latest.tgz@] or [@unzip pmwiki-latest.zip@]). This will create a ''pmwiki-x.y.z'' directory containing the PmWiki software. For example, the current "latest" should unpack to a directory named ''{$Version}''. The files in this directory include:%0a>>pre%3c%3c%0a README.txt An introductory document%0a pmwiki.php The main PmWiki script%0a local/ Configuration scripts (local configuration files)%0a cookbook/ Recipes (add-ons) from the [[(Cookbook:)Cookbook]]%0a docs/ Brief documentation, sample configuration scripts%0a pub/ Publicly accessible files%0a pub/css/ Extra CSS stylesheet files '^[[PmWiki/Skins#further|#]]^'%0a pub/guiedit/%0a pub/skins/ Layout templates for [[Cookbook:Skins|custom]] look and feel%0a scripts/ Scripts that are part of PmWiki%0a wikilib.d/ Bundled default PmWiki pages%0a>>%3c%3c%0a%0aThe ''pmwiki-x.y.z'' directory needs to be placed into a location accessible by your webserver (e.g., in a ''public_html'' directory of some sort). You can place files and directories using a number of methods -- FTP, or a Unix [@mv@] or [@cp@] command generally does the job.%0a%0a->%25note%25 Note: It is recommended to change the "''pmwiki-x.y.z''" directory name to be simply "''pmwiki''".%0a%0a!!! [[#directories]] 3. Create directories%0a[[#dirsetup]]In most cases PmWiki will do this for you.%0aOpen a web browser to the ''pmwiki.php'' script on the server (i.e., not the one on your local computer or accessed using a [=file://...=] URL). PmWiki will then analyze your system configuration and provide instructions (if needed) for creating the ''wiki.d/'' directory which will be used to hold the pages created for your site. %0a%0aOtherwise, there are two ways to achieve this. (Use %25newwin%25[[http://filezilla-project.org/download.php|Filezilla]] or [[http://winscp.net/eng/download.php|WinSCP]] to change FTP file/folder permissions.)%0a%0a->3a. You can create the ''wiki.d/'' directory manually, and then give it full write permissions (i.e., "[@chmod 777 wiki.d@]"). Use this method when "safe mode" is activated in the server's PHP installation.%0a%0a->3b. On some systems you can let PmWiki create ''wiki.d/'' by temporarily changing the permissions on the directory containing the ''pmwiki.php'' file to 2777. In Unix this is commonly done by changing to the directory containing ''pmwiki.php'' and executing the command%0a%0a->@@chmod 2777 .@@%0a%0a->(note the dot at the end). The [@chmod@] command also works in many FTP programs. Creating ''wiki.d/'' in this manner will (1) make the directory writable so the web server can create the data directory it needs for the wiki files, (2) preserve group ownership of the directory so the installer account can manipulate the files created in this directory, and (3) make it more difficult for other accounts on the same server to access the files in ''wiki.d/''.%0a%0aAfter establishing directory permissions, try opening a browser to the ''pmwiki.php'' script again. If all is well, the ''wiki.d'' directory will have been created and you'll see the default home page.%0a%0a%25red%25'''Important:''' If you used method 3b, you should reset permissions by executing "[@chmod 755 .@]" in the directory containing pmwiki.php.%25%25%0a%0a[[#dirsetupend]]%0a!!! 4. Initialize%0aCheck out [[Initial Setup Tasks]] for other tasks you may want to perform to begin customizing your PmWiki installation. You might also want to peruse the [[Release Notes]] for further information.%0a%0a%0a!!! 5. Set language%0aIf you want to use PmWiki in a different language download the [[Internationalizations|international]] language pack as zip archive ([[(http://pmwiki.org/pub/pmwiki/i18n/)i18n-all.zip]]) from [[http://pmwiki.org/pub/pmwiki/i18n/]]. Then extract it and copy the files into the ''wikilib.d/'' directory as described above. Besides the ''-all'' file you can also download your country localization file only.%0a%0aLanguages available are:%0a(:pagelist fmt=#listlanguage name=PmWiki* list=normal order=$:Language $:Language=- :)%0a(:if false:)%0a[[#listlanguage]]%0a(:template first:)%0a->%0a(:template each:)%0a[[{=$Group}/{=$Name} | {=$:Language} ]]%0a[[#listlanguageend]]%0a(:ifend:)%0a%0aThere are two directories in the decompressed i18n archive, ''scripts'' and ''wikilib.d''. Copy the files respectively contained in these directories to the ''scripts'' and ''wikilib.d'' of your PmWiki directory. For example, for French localization, PmWikiFr.* and PmWiki.* must be contained in the '''same''' directory.%0a%0aThen, enable localization by adding an instruction to local/config.php to load the language translation page of your choice. For instance, [@XLPage('fr','PmWikiFr.XLPage');@] loads the French language page PmWikiFr.XLPage.%0a%0aRead more about this on [[Internationalizations]].%0a%0a!! [[#notes]] Notes%0a%0a* [[#indexphp]] The PmWiki distribution deliberately doesn't include an ''index.php'' file. You can easily add your own "wrapper script" in the same directory as ''pmwiki.php''. Create a new file called ''index.php'' with the following single line of text (missing a closing "[@ ?>@]" tag deliberately):%0a%0a-->[@%3c?php include_once('pmwiki.php');@]%0a%0aResist the temptation to rename ''pmwiki.php'' to ''index.php'' because if you rename the file it will not be overwritten during an upgrade.%0a%0a* If using the Unix ''tar'' command to unpack the archive in step 2 above, be sure that the files are created with sufficient permissions for the webserver to be able to access them. Usually you can ensure this by typing @@umask 002@@ on the command line before unpacking the tar file.%0a%0a* When installing on Windows you should take a look at [[Cookbook:SimultaneousEdits]] to enable [[simultaneous edits]] on that platform.%0a%0a* Additional tips can be found at [[Troubleshooting]].%0a%0aSee also:%0a* [[Cookbook:PHP]] {Cookbook/PHP$:Summary}%0a* [[Cookbook:InstallOnIIS]] {Cookbook/InstallOnIIS$:Summary}%0a%0a%0a%0a>>faq%3c%3c [[#faq]]%0aQ: Should I rename pmwiki.php to index.php?%0aA: Renaming pmwiki.php is not recommended. Instead, create an ''index.php'' file that contains this single line%0a%0a->[@%3c?php include_once('pmwiki.php');@]%0a%0aQ: How do I make pmwiki.php the default page for a website?%0aA: Create an ''index.php'' file that runs PmWiki from a subdirectory (''pmwiki/'' for example) and place it in the site's web document root (the main directory for the website).%0a%0a->[@%3c?php chdir('pmwiki'); include_once('pmwiki.php');@]%0a%0aNote: You will also need to explicitly set the $PubDirUrl variable (e.g. to [@"http://example.com/pmwiki/pub"@]) in ''local/config.php'' .%0a%0aQ: How do I enable "Clean URLs" that are shorter and look like paths to my wiki pages? Why does pmwiki.org appear to have a directory structure rather than "?n=pagename" in URLs?%0aA: See [[Cookbook:CleanUrls]].%0a%0aQ: Is it possible to move wiki.d to /tmp/persistent/foo/wiki.d (a new sourceforge rule)?%0aA: Sourceforge suggests moving everything to ''/tmp/persistent/new-folder-of-your-choice/'' and creating a symbolic link to the new folder on /tmp . It works -- see [[Cookbook:SourceForgeServers]].%0a%0aQ: How can I run PmWiki on a standalone (offline, portable) machine ?%0aA: See [[Cookbook:Standalone]] or [[Cookbook:WikiOnAStick]].%0a%0a
+time=1265885641
+title=PmWiki Installation
diff --git a/wikilib.d/PmWiki.InterMap b/wikilib.d/PmWiki.InterMap
new file mode 100644
index 0000000..01da050
--- /dev/null
+++ b/wikilib.d/PmWiki.InterMap
@@ -0,0 +1,11 @@
+version=pmwiki-2.2.5 ordered=1 urlencoded=1
+agent=Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.0.3705; .NET CLR 1.1.4322; .NET CLR 2.0.50727)
+author=SchreyP
+charset=ISO-8859-1
+csum=improve former change, show InterMaps by example
+host=81.240.23.93
+name=PmWiki.InterMap
+rev=47
+targets=PmWiki.WikiWikiWeb,Site.InterMap,PmWiki.CustomInterMap
+text=(:Summary: Interwiki links definition and use:)%0a(:Audience: author (intermediate) :)%0a%0aThe InterMap (also called InterWiki in some other wikis) is a system for defining links between [[WikiWikiWeb]] sites that was first developed by UseMod and Meatball (see UseMod:InterWiki and Meatball:InterWiki). The method is to use a word that stands for a path that is defined. InterMap links have the form [@MapPrefix:PagePath@], where the host prefix is converted to a partial URL based on entries in the site's ''intermap.txt'' and ''localmap.txt'' files.%0a%0a[[#custominclude]]%0aThe default ''intermap.txt'' distributed with PmWiki (in the ''scripts/'' directory) includes the following InterMap entries:%0a>>pre%3c%3c%0a PmWiki: http://www.pmwiki.org/wiki/PmWiki/ %0a Cookbook: http://www.pmwiki.org/wiki/Cookbook/ %0a Wiki: http://www.c2.com/cgi/wiki? %0a UseMod: http://www.usemod.com/cgi-bin/wiki.pl? %0a Meatball: http://www.usemod.com/cgi-bin/mb.pl? %0a Wikipedia: http://www.wikipedia.com/wiki/ %0a PITS: http://www.pmwiki.org/PITS/ %0a Path:%0a>>%3c%3c%0a%0a(:if exists {$SiteGroup}.InterMap:)%0a[[{$SiteGroup}.InterMap]] includes the following entries:%0a(:include {$SiteGroup}.InterMap#include#includeend:)%0a(:else:)%0aYou can map your own prefixes in your local page [[{$SiteGroup}.InterMap]].%0a(:ifend:)%0a[[#customincludeend]]%0a%0aThus, "PmWiki:Variables" becomes "http://www.pmwiki.org/wiki/PmWiki/" + "Variables," a link to the [[PmWiki.Variables->http://www.pmwiki.org/wiki/PmWiki/Variables]] page on the official PmWiki web site, Wiki:FrontPage is a link to the front page of the first WikiWikiWeb, and Wikipedia:Stonehenge takes you to the Wikipedia article about the famous megaliths in England. %0a%0aLike other links, you can use the double-bracket syntax to get different link text:%0a(:markup class=horiz:)%0a* [[Meatball:StartingPoints | starting points]] over at Meatball%0a* [[starting points -> Meatball:StartingPoints]] over at Meatball%0a(:markupend:)%0a%0aIf you want to link just to what the intermap says (e.g. http://www.wikipedia.com/wiki/ for Wikipedia), then do [@[[Wikipedia:. | Wikipedia's main page]]@], which produces [[Wikipedia:. | Wikipedia's main page]]. Note the . (period) after the Map: reference.%0a%0a[[#path]]%0aThe special [@Path:@] InterMap entry can be used to create "[[Cookbook:RelativeUrls|relative urls]]" in [[Cookbook:RelativeLinks|links]].%0a%0aThe actual set of InterMap links at any site is defined by the site administrator via the [[Site.InterMap]] page and the ''local/localmap.txt'' file; for more details, see [[PmWiki.CustomInterMap]]s.%0a
+time=1253825216
diff --git a/wikilib.d/PmWiki.Internationalizations b/wikilib.d/PmWiki.Internationalizations
new file mode 100644
index 0000000..833c659
--- /dev/null
+++ b/wikilib.d/PmWiki.Internationalizations
@@ -0,0 +1,11 @@
+version=pmwiki-2.2.5 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/530.5 (KHTML, like Gecko) Chrome/2.0.172.43 Safari/530.5
+author=Simon
+charset=ISO-8859-1
+csum=GroupCustomizations
+host=202.37.32.2
+name=PmWiki.Internationalizations
+rev=88
+targets=Group.Name,Group.XLPage,Group.XLPageLocal,PmWiki.UTF-8,PmWikiFr.XLPage,PmWiki.WikiGroup,PmWiki.GroupCustomizations
+text=(:Summary: Language internationalisation of web pages:)%0a[[#include]]%0aPmWiki supports internationalization (internationalisation) of web pages, allowing accented characters to appear in page names and almost complete customization of PmWiki's prompts. %0a[[#includeend]]%0aMost customization is provided via the XLPage() function in PmWiki, which loads a set of translation variables from a wiki page (typically named XLPage, but it can be named anything you wish).%0a%0a>>rframe font-size:smaller clear:right%3c%3c%0a(:pagelist fmt=#languagelist name=PmWiki* list=normal order=$:Language $:Language=- :)%0a(:if false:)%0a[[#languagelist]]%0a(:template each:)%0a-%3c [[{=$Group}/{=$Name}]] {=$:Language} ~ [-[[{=$Group}/XLPage]]-] (:if exists {=$Group}.XLPageLocal:) [-[[{=$Group}/XLPageLocal]]-] (:ifend:)%0a[[#languagelistend]]%0a(:ifend:)%0a>>%3c%3c%0a!! Loading Translation Pages%0a%0aPages for many [[(PmWiki:)other languages]] have already been created and maintained at the pmichaud.com site. You can download an archive of these translations from http://www.pmwiki.org/pub/pmwiki/i18n/ . Simply download the appropriate language archive(s), and unpack the archive(s) into the directory containing your ''pmwiki.php'' installation. Each archive contains a number of page files that are placed in your ''wikilib.d/'' directory, and some special scripts for translations that use a character set other than iso-8859-1 (PmWiki's default). You can also use [[UTF-8]] charset.%0a%0aOnce the translation pages are installed, you enable a language by adding a call to `XLPage() in your ''config.php'' file. For example, to select French language prompts, one would specify%0a%0a->[@XLPage('fr','PmWikiFr.XLPage');@]%0a%0awhich says to load the translations for French ('fr') from the page [[PmWikiFr.XLPage]]. It's perfectly okay to load multiple pages; so if you want to create your own local translations without changing the ones you got from from an i18n archive, just create another page (see below) and load it on top. Be sure that you load first the page with your local changes:%0a%0a-> [@%0aXLPage('fr','PmWikiFr.XLPageLocal'); # my local translations%0aXLPage('fr','PmWikiFr.XLPage'); # from i18n.tgz%0a@]%0a%0aIf your intention is to offer multiple languages on your site, and use [[Wiki Group]]s as language selectors, you may want to place this code in local customizations files (see [[Group Customizations]]). For example, if your site is published in French and English, and the French pages are in a group called Fr, you could create a file named Fr.php in the ''local/'' directory which contains:%0a%0a-> [@%0a%3c?php if (!defined('PmWiki')) exit();%0a##change to French language%0aXLPage('fr','PmWikiFr.XLPage');%0a@]%0a%0aYou may wish to create a page called ''PmwikiFr.php'' with the same content to access the French documentation in the PmwikiFr group. ''En.php'' is not necessary in this case since English is the default language.%0a%0aAn alternative to the above would be to add to ''config.php'' the following, which tests if there is an XLPage in a group, and if it finds one it gets loaded:%0a%0a-> [@ %0a$xlpage = FmtPageName('$Group.XLPage', $pagename);%0aif (PageExists($xlpage)) XLPage($xlpage, $xlpage);%0a@]%0a%0aWith this method you would need to copy any relevant XLPage into any group which needs the different language support.%0a%0aSee also [[Cookbook:MultiLanguage]] {Cookbook/MultiLanguage$:Summary}%0a%0a!![[#CreatingNewTranslations]]Creating New Translations%0a%0aIf language pages don't exist for your desired language, it's easy to create one! An XLPage translation file simply contains lines of the form%0a%0a->[@'phrase' => 'translated phrase',@]%0a%0awhere "phrase" is an internationalized phrase (denoted by [@$[phrase]@]) in PmWiki's $...Fmt variables, and "translated phrase" is what should be printed in your particular language. For example, the line (in [@PmWikiFr.XLPage@])%0a%0a->[@'Search' => 'Rechercher',@]%0a%0aconverts "[@$[Search]@]" to "Rechercher" on output. The file PmWiki:XLPageTemplate is a good starting point for creating a new XLPage and has most of PmWiki's key phrases already listed in it. %0a%0aIf you create new versions of PmWiki pages in other languages, please consider adding them to the [[PmWiki:PmWiki | main PmWiki site]] so that they can be made available to others in the i18n archives!%0a%0a->%25note%25 The term "i18n" is commonly used as an abbreviation for the English word "internationalization". The abbreviation is derived from the fact that there are 18 letters between the "i" and the final "n" and few people want to type them all out.%0a%0a!! Enabling "Special" Characters in WikiLinks%0a%0aTo enable "special" characters like for example German umlauts in WikiLinks, it is necessary to configure the server locale to ensure that PmWiki uses the proper character set definition.%0a%0aIf this is not possible due to limited access to the server configuration, PmWiki can be configured to use a specific locale by using the XLPage options (see [[(PmWiki:)XLPageTemplate]]).%0a%0aFor German umlauts, you'd need for example:%0a%0a*[='Locale' => 'deu',=] %3c- for Windows servers, see [[http://msdn.microsoft.com/en-us/library/39cwe7zf.aspx|MSDN List of locale identifiers]]%0a*[='Locale' => 'de_DE',=] %3c- for Linux servers%0a%0aNote that the locale identifier depends on the operation system and perhaps on the specific installation.%0a%0a[[#notes]]%0a!! Notes%0a%0a%0a%0a>>faq%3c%3c [[#faq]]%0a%0aQ: If my wiki is internationalized by ''config.php'', how do I revert a specific group to English?%0a%0aA: Use [@$XLLangs = array('en');@] in the group's [[ group customization(s)]] file.%0a%0aQ: If my wiki is in English and I want just one page, or group, in Spanish do I say [@XLPage('es','PmWikiEs.XLPage');@] in the group or page configuration file?%0a%0aA: Yes, that is usually the best method. If you were doing this with many scattered pages, or with several languages, you might find it easier to maintain if you load the translations all in config.php like this:%0a%0a XLPage('es','PmWikiEs.XLPage');%0a XLPage('fr','PmWikiFr.XLPage');%0a XLPage('ru','PmWikiRu.XLPage');%0a $XLLangs = array('en');%0a%0aA: Then in each group or page configuration file, you'd just use $XLLangs = array('es'); to set the language to use (in this case, Spanish). Note that though this method is easier to maintain, its somewhat slower because it loads all the dictionaries for each page view, even if they won't be used.%0a%0aQ: What does the first parameter of this function stand for? How can it be used?%0a%0aA: The XLPage mechanism allows multiple sets of translations to be loaded,%0aand the first parameter is used to distinguish them. %0a%0aFor example, suppose I want to have translations for both normal French%0aand "Canadian" French. Rather than maintain two entirely separate sets%0aof pages, I could do:%0a%0a XLPage('fr', 'PmWikiFr.XLPage');%0a XLPage('fr-ca', 'PmWikiFrCa.XLPage');%0a%0aPmWikiFr.XLPage would contain all of the standard French translations,%0awhile PmWikiFrCA.XLPage would only need to contain "Canada-specific"%0atranslations -- i.e., those that are different from the ones in the%0aFrench page.%0a%0aThe first parameter distinguishes the two sets of translations.%0aIn addition, a ''config.php'' script can use the $XLLangs variable%0ato adjust the order of translation, so if there was a group or%0apage where I only wanted the standard French translation, I%0acan set%0a%0a $XLLangs = array('fr', 'en');%0a%0aand PmWiki will use only the 'fr' and 'en' translations (in that order),%0ano matter how many translations have been loaded with XLPage().%0a%0a!!Tools for PmWiki Localization%0a%0aYou can help to localize PmWiki in your language in the original site:%0a* [[(http://www.pmwiki.org/wiki/Localization/)Localization]] %0a* [[(PmWiki:)Translation Portal]]%0a
+time=1251406850
diff --git a/wikilib.d/PmWiki.Introduction b/wikilib.d/PmWiki.Introduction
new file mode 100644
index 0000000..d64334b
--- /dev/null
+++ b/wikilib.d/PmWiki.Introduction
@@ -0,0 +1,12 @@
+version=pmwiki-2.2.6 ordered=1 urlencoded=1
+agent=Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; GTB6; .NET CLR 1.0.3705)
+author=SchreyP
+charset=ISO-8859-1
+csum=add link for wiki-based and remove a double link in same paragraph
+ctime=1180819909
+host=217.136.7.159
+name=PmWiki.Introduction
+rev=23
+targets=PmWiki.WikiWikiWeb,PmWiki.PmWiki,Main.WikiSandbox,PmWiki.BasicEditing,PmWiki.TextFormattingRules,PmWiki.Requirements,PmWiki.DocumentationIndex,PmWiki.Installation
+text=>>faq%3c%3c [[#faq]]%0aQ: What is PmWiki?%0aA: PmWiki is a [[WikiWikiWeb|wiki-based]] system for collaborative creation and maintenance of websites. See [[PmWiki/PmWiki]].%0a%0aQ: What can I do with it?%0aA: PmWiki pages look and act like normal web pages, except they have an "Edit" link that makes it easy to modify existing pages and add new pages into the website, using [[basic editing]] rules. You do not need to know or use any HTML or CSS. Page editing can be left open to the public or restricted to small groups of authors. Feel free to experiment with the [[PmWiki/Text Formatting Rules]] in the "[[Main/WikiSandbox?action=edit | Wiki sandbox]]". The website you're currently viewing is built and maintained with PmWiki.%0a%0aQ: What are the requirements?%0aA: See the [[PmWiki.Requirements | PmWiki requirements]] page.%0a%0aQ: Where can I find documentation?%0aA: See the [[PmWiki.DocumentationIndex | documentation index]] page.%0a%0aQ: How can I download PmWiki?%0aA: See the [[PmWiki:Download | download]] page.%0a%0aQ: How do I install PmWiki?%0aA: Instructions for installation are on the [[PmWiki.Installation | installation page]].%0a%0aQ: How do I get help with PmWiki?%0aA: See [[(PmWiki:)Mailing lists]] and [[(PmWiki:)How to get assistance]].%0a
+time=1255724136
diff --git a/wikilib.d/PmWiki.LayoutVariables b/wikilib.d/PmWiki.LayoutVariables
new file mode 100644
index 0000000..bfe8dcd
--- /dev/null
+++ b/wikilib.d/PmWiki.LayoutVariables
@@ -0,0 +1,11 @@
+version=pmwiki-2.2.12 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.7) Gecko/20100106 Ubuntu/9.10 (karmic) Firefox/3.5.7
+author=Petko
+charset=ISO-8859-1
+csum=$EnableDiffInline
+host=81.65.12.233
+name=PmWiki.LayoutVariables
+rev=102
+targets=PmWiki.PageDirectives,PmWiki.PageHistory,PmWiki.SkinTemplates,PmWiki.WikiGroup,PmWiki.Questions,Cookbook.RecentUploadsLog,PmWiki.CustomWikiStyles,PmWiki.Tables,PmWiki.EditVariables
+text=(:Summary:variables that control page layout:)%0aVariable substitutions in the skin template are all managed by the `FmtPageName() function from pmwiki.php. Pmwiki variable substitutions available on pages are managed by the {$var} substitutions from stdmarkup.php or superseded in local/config files. %0a%0a:$ActionSkin:This array is used to override the current skin when performing a given action. The most common use is to set @@$ActionSkin['print']='foo'@@ to use the 'foo' skin when printing, regardless of what the @@$Skin@@ variable is set to.%0a%0a:$WikiTitle:A variable which contains the Wiki title as displayed by the browser%0a%0a:$EnablePageTitlePriority:A variable defining how to treat multiple @@ [=(:title ...:)=] @@ [[page directives]] (added in PmWiki 2.2.9).%0a: : @@$EnablePageTitlePriority = 0;@@ # PmWiki default, last encountered title wins (the title may be changed from included pages or GroupFooter).%0a: : @@$EnablePageTitlePriority = 1;@@ # First title wins; if a title is defined in the page, directives from included pages cannot change it.%0a%0a:$EnableDiffInline:If set to 0, this variable switches off the word-level highlighting on the markup in the [[page history]].%0a: : @@$EnableDiffInline = 0;@@ # Disable colors, show plain text differences%0a%0a:$HTMLStylesFmt:An array of CSS statements to be included in the page's output along with other HTML headers. This array provides an easy place for scripts to add custom CSS statements.%0a%0a:$HTMLHeaderFmt:An array of HTML text to be included in the page's %3chead> section, at the point where the [[skin template(s)]] specifies a [@%3c!--HTMLHeader-->@] directive. This array provides an easy place for scripts to add custom HTML headers.%0a%0a->For example, if you want to specify a logo for all the pages of your wiki (a png image for Firefox (and others...), an ico for Internet Explorer):%0a-->[@ %0a$HTMLHeaderFmt['logo'] =%0a '%3clink href="http://path/to/logo.png" type="image/png" rel="icon" />%0a %3clink href="http://path/to/logo.ico" type="image/x-icon" rel="shortcut icon" />';%0a@]%0a%0a->Another example, if you want to get the rss notification on some browsers (the rss icon in firefox for instance):%0a-->[@ %0a$HTMLHeaderFmt['rss'] =%0a '%3clink rel="alternate" type="application/rss+xml" title="Rss All recent Changes" %0a href="$ScriptUrl/Site/AllRecentChanges?action=rss" />';%0a@]%0a%0a:$HTMLFooterFmt:Like $HTMLHeaderFmt above, this contains an array of HTML text to be included near the end of an HTML document, at the point where the [[skin template(s)]] specifies a [@%3c!--HTMLFooter-->@] directive (usually just before a closing %3c/body> tag). Primarily used by scripts to add custom HTML output after the body of the page output. %0a%0a:$MetaRobots:Sets the value of the [@%3cmeta name='robots' ... />@] tag generated by PmWiki to control search engine robots accessing the site. PmWiki's default setting tells robots to not index anything but the normal page view, and to not index pages in the PmWiki [[wiki group]]. Explicitly setting $MetaRobots overrides this default.%0a # never index this site%0a $MetaRobots = 'noindex,nofollow';%0a # disable the robots tag entirely%0a $MetaRobots = '';%0a%0a:$MessagesFmt:An array of HTML text to be displayed at the point of any [@(:messages:)@] markup. Commonly used for displaying messages with respect to editing pages.%0a%0a:$RecentChangesFmt:An array specifying the format of the RecentChanges listing.%0a%0a->The key of the array specifies the page where changes will be logged, as in%0a-->[@%0a$RecentChangesFmt['$SiteGroup.AllRecentChanges']%0a@]%0a->The value of the array specifies the format in which the changes will be logged, as in%0a-->[@%0a'* [[{$Group}.{$Name}]] . . . $CurrentTime $[by] $AuthorLink: [=$ChangeSummary=]'%0a@]%0a->Note the two consecutive spaces before the three dots (@@. . .@@). The two spaces separate two parts of the format: the first part doesn't change (e.g. a link to the changed page) and the second part does change (e.g. the date and author of the change). Upon saving a page, PmWiki removes a line that matches the first part and adds a line with the current format before the first line with 2 spaces. This way, any line without two consecutive spaces stays at the top of the recent changes page.%0a%0a->You can use and adapt the following to change the format (put it in config.php):%0a-->[@%0a$RecentChangesFmt['$SiteGroup.AllRecentChanges'] = %0a '* [[{$Group}.{$Name}]] . . . $CurrentTime $[by] $AuthorLink: [=$ChangeSummary=]';%0a$RecentChangesFmt['$Group.RecentChanges'] =%0a '* [[{$Group}/{$Name}]] . . . $CurrentTime $[by] $AuthorLink: [=$ChangeSummary=]';%0a@]%0a%0a->Note that changes made to the format will only affect new edits. In other words, you will need to edit a page for your new format to be visible. Note also that you need to have two spaces between the page name and the other information about the edit.%0a%0a->Also note that this variable has other uses, such as not reporting at all to RecentChanges and AllRecentChanges as found here [[PmWiki:Questions|PmWiki Questions]].%0a%0a:$RecentUploadsFmt:An array specifying the format for uploaded files at the RecentChanges listing. It is similar to $RecentChangesFmt. If enabled, newly uploaded files will be logged to the RecentChanges pages. Default is disabled. See Cookbook:RecentUploadsLog for more information.%0a%0a:$DraftRecentChangesFmt:An array specifying the format of the RecentChanges listing when saving Draft pages.%0a%0a->$RecentChangesFmt is set to $DraftRecentChangesFmt when a Draft page is saved. For example, you could save drafts in a separate Recent Draft Changes page and not list in the normal group's Recent Changes page:%0a-->[@%0a$DraftRecentChangesFmt['$Group.RecentDraftChanges'] =%0a '* [[{$Group}/{$Name}]] . . . $CurrentTime $[by] $AuthorLink: [=$ChangeSummary=]';%0a$DraftRecentChangesFmt['$Group.RecentChanges'] = '';%0a@]%0a%0a:$RCLinesMax:The maximum number of lines to be stored in RecentChanges pages. The default is zero, meaning "no limit".%0a $RCLinesMax = 1000; # maintain at most 1000 recent changes%0a%0a:$PageRedirectFmt:The text to be used when a page is redirected via the [@(:redirect:)@] markup.%0a-->[@%0a$PageRedirectFmt = '%3cp>%3ci>redirected from $FullName%3c/p>';%0a$PageRedirectFmt = '';%0a@]%0a->For display options, see also the FAQ on [[(PmWiki:)PageDirectives(#faq)]].%0a%0a:$WikiStyle:An array which contains the predefined WikiStyles which can be used on a textpage.[[%3c%3c]]See: [[PmWiki.CustomWikiStyles]]%0a%0a:$MaxIncludes:Controls the number of times that pages can be included via the [@(:include:)@] and other directives, used to control recursion and otherwise pose a sanity check on page contents. $MaxIncludes defaults to 50, but can be set to any value by the wiki administrator.%0a $MaxIncludes = 50; # default%0a $MaxIncludes = 1000; # allow lots of includes%0a $MaxIncludes = 0; # turn off includes%0a%0a:$[=Skin=]:Lists the name(s) of skins to load, unless overridden by $ActionSkin. Normally $Skin contains a single string which is a the name of a skin directory, but it may also be an array of names, in which case the first skin found from the list is used.%0a%0a:$SkinDirUrl:Set by ''scripts/skins.php'' to be the base url of the current skin's directory (i.e., within a 'pub/skins/' directory). This variable is typically used inside of a skin .tmpl file to provide access to .css files and graphic images associated with the skin.%0a%0a:$SkinLibDirs:An array which, given the filesystem path (array key) to a skin (or a directory containing several skins), provides the corresponding URL (array value).%0a%0a->The array key is the directory containing the skin.tmpl and skin.php files, as seen by the PmWiki program. It does not have to be publicly accessible.%0a%0a-> The value is the URL (web address) of the directory containing the .css, .gif, and other files which appear in the HTML code sent by PMWiki to the browser. This directory must be publicly accessible.%0a%0a->By default $SkinLibDirs is set to:\\%0a[@%0a$SkinLibDirs = array(%0a "./pub/skins/\$Skin" => "$PubDirUrl/skins/\$Skin",%0a "$FarmD/pub/skins/\$Skin" => "$FarmPubDirUrl/skins/\$Skin");%0a@]%0a%0a->Extra details: When PMWiki is searching for a skin it looks for a directory named for the skin in the array index/keys, and if it finds it then it will use the files in that directory and also the files in the matching array value url. The two sides normally point to the same publicly accessible directory, but they do not have to.%0a%0a:$PageLogoUrl: is the url that refers to a logo image which most skins display somewhere in the page's header (top left usually).%0a%0a:$EnablePathInfo:Changes the handling of the page URL. When set to @@1@@ page URL will be @@...wiki.php/Main/Main@@, when set to @@0@@ (default) it will be @@...wiki.php?n=Main.Main@@.%0a%0a:$EnableFixedUrlRedirect:When PmWiki is given a partial page name (e.g., just the name of a WikiGroup), it uses $PagePathFmt in order to make a complete page name from the partial one, then issues a "redirect" to the browser to tell it to reload the page with the correct full page name. Setting $EnableFixedUrlRedirect=0; blocks the redirect, so that PmWiki continues processing with the adjusted page name rather than issuing the redirect. %0a%0a:$GroupHeaderFmt:Defines the markup placed at the top of every page. Default value is:%0a [@$GroupHeaderFmt = '(:include $Group.GroupHeader:)(:nl:)';@]%0a%0a:$GroupPrintHeaderFmt:Defines the markup placed at the top of every page when [@action=print@]. Default value is:%0a [@SDV($GroupPrintHeaderFmt,'(:include $Group.GroupPrintHeader:)(:nl:)');@]%0a%0a:$GroupFooterFmt:Defines the markup placed at the bottom of every page. Default value is:%0a [@$GroupFooterFmt = '(:include $Group.GroupFooter:)(:nl:)';@]%0a%0a:$GroupPrintFooterFmt:Defines the markup placed at the bottom of every page when [@action=print@]. Default value is:%0a [@SDV($GroupPrintFooterFmt,'(:nl:)(:include $Group.GroupPrintFooter:)');@]%0a%0a:$PageNotFoundHeaderFmt:Specifies the HTTP header to send when attempting to browse a page that doesn't exist. Some webserver packages (notably Microsoft's "Personal Web Server") require that this variable be changed in order to work.%0a%0a-->[@%0a# default%0a$PageNotFoundHeaderFmt = 'HTTP/1.1 404 Not Found';%0a# return all pages as found%0a$PageNotFoundHeaderFmt = 'HTTP/1.1 200 Ok';%0a@]%0a%0a->Beware when expecting to return the content of a Group(header|footer) for an non existent page! By default PmWiki returns 404 (because the page does not exist), despite there is some content to show. Firefox shows the content, while Internet Explorer displays its default 404 page. $PageNotFoundHeaderFmt MUST be set to return 200 as described above in order to get the expected behaviour with all browsers.%0a%0a:$HTMLVSpace:Setting [@$HTMLVSpace = '';@] in a local customizationfile (e.g., [@local/config.php@]) prevents insertion of spacer paragraphs ([@%3cp class='vspace'>%3c/p>@]) in generated HTML code. To limit this change to a single skin, place the [@$HTMLVSpace = '';@] statement in a skin.php file, preceded by the statement [@global $HTMLVSpace;@].%0a%0a:$TableCellAttrFmt:For [[Tables]], defines the HTML attributes given to each @@%3ctd>@@ or @@%3cth>@@ cell in the output. Can contain references to $TableCellCount which holds the horizontal column number of the current cell.%0a%0a:$TableRowAttrFmt:For [[Tables]], defines the HTML attributes given to each @@%3ctr>@@ element in the output. Can contain references to $TableRowCount to give the absolute row number within the table, or $TableRowIndex to provide a repeating row index from 1 to $TableRowIndexMax.%0a # Give each row a unique CSS class based on row number (tr1, tr2, tr3, ... )%0a $TableRowAttrFmt = "class='tr\$TableRowCount'";%0a # Give each row alternating CSS classes (ti1, ti2, ti1, ti2, ti1, ... )%0a $TableRowIndexMax = 2;%0a $TableRowAttrFmt = "class='ti\$TableRowIndex'";%0a%0a:$TableRowIndexMax:The maximum value for $TableRowIndex in [[Tables]].%0a # Set rows indexes as 1, 2, 3, 1, 2, 3, 1, 2, ...%0a $TableRowIndexMax = 3;%0a %0a:$FmtV['$TableCellCount']:PMWiki internal variable - Horizontal column number of the current cell. For use in $TableCellAttrFmt and $TableRowAttrFmt. Administrators can use in $TableCellAttrFmt and/or $TableRowAttrFmt.%0a [@Example: $TableCellAttrFmt = 'class=col\$TableCellCount';@] %0a%0a:$FmtV['$TableRowCount']:PMWiki internal variable - Current row number. Administrators can use in $TableCellAttrFmt and/or $TableRowAttrFmt.%0a [@Example: TableRowAttrFmt = "class='row\$TableRowCount'";@] %0a%0a:$FmtV['$TableRowIndex']:PMWiki internal variable - Row index number derived from $TableRowIndexMax. (1,2,3,1,2,3,...). Administrators can use in $TableCellAttrFmt and/or $TableRowAttrFmt.%0a [@Example: $TableRowAttrFmt = "class='ind\$TableRowIndex'";@]%0a%0aSee also: [[Edit Variables]]%0a
+time=1266768255
diff --git a/wikilib.d/PmWiki.LinkVariables b/wikilib.d/PmWiki.LinkVariables
new file mode 100644
index 0000000..f770fb5
--- /dev/null
+++ b/wikilib.d/PmWiki.LinkVariables
@@ -0,0 +1,11 @@
+version=pmwiki-2.2.2 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.19) Gecko/20081216 Ubuntu/8.04 (hardy) Firefox/2.0.0.19
+author=Petko
+charset=ISO-8859-1
+csum=changing $MakePageNamePatterns
+host=81.65.14.164
+name=PmWiki.LinkVariables
+rev=58
+targets=PmWiki.CustomInterMap,PmWiki.PageDirectives
+text=(:Summary:variables that control the display of links in pages:)%0a(:Audience: admins (advanced):)%0a:$EnableLinkPageRelative:When enabled, causes PmWiki to use relative urls for page links instead of absolute urls.%0a $EnableLinkPageRelative = 1;%0a%0a:$PagePathFmt: This array lists the order in which PmWiki looks for the page that you ''most likely'' are attempting to link to. The default is listed below. Look at Cookbook:PagePaths for some ideas.%0a [=array('{$Group}.$1','$1.$1'.'$1.{$DefaultName}')=]%0a%0a:$LinkPageExistsFmt:The (HTML) string to output for links to already existing wiki pages. Defaults to %0a %3ca class='wikilink' href='\$LinkUrl'>\$LinkText%3c/a>%0a%0a:$LinkPageCreateFmt:The (HTML) string to output for links to non-existent wiki pages. The default is to add a '?' after the link text with a link to the page edit/create form. Defaults to%0a %3ca class='createlinktext' href='\$PageUrl?action=edit'>\$LinkText%3c/a>%0a %3ca class='createlink' href='\$PageUrl?action=edit'>?%3c/a>%0a%0a:$LinkPageCreateSpaceFmt:Same as $LinkPageCreateFmt, but used when the link text has a space in it. %0a%0a:$LinkPageSelfFmt:The (HTML) string to output for self-referencing links (i.e. links to the page itself). Defaults to%0a %3ca class='selflink' href='\$LinkUrl'>\$LinkText%3c/a>%0a%0a:$UrlLinkFmt:The (HTML) string to output for URL-links that begin with 'http:', 'ftp:', etc. Defaults to%0a %3ca class='urllink' href='\$LinkUrl' rel='nofollow'>\$LinkText%3c/a>%0a%0a:$IMapLinkFmt: an array of link formats for various link "schemes". Not set as default.%0a->Examples of custom formats to allow different styling via classes: %0a->Links to http: standard url links:%0a $IMapLinkFmt['http:'] = "%3ca class='httplink urllink' href='\$LinkUrl'>\$LinkText%3c/a>"; %0a->Links to https: secure pages:%0a $IMapLinkFmt['https:'] = "%3ca class='httpslink urllink' href='\$LinkUrl'>\$LinkText%3c/a>"; %0a->Links to PmWiki: InterMap shortcut:%0a $IMapLinkFmt['PmWiki:'] = "%3ca class='pmwikilink urllink' href='\$LinkUrl'>\$LinkText%3c/a>";%0a%0a:$InterMapFiles:An array consisting a list of files and pages containing InterMap entries to be loaded (see [[CustomInterMap]]).%0a%0a:$MakePageNameFunction:Name of a custom function to replace `MakePageName(), which converts strings into valid page names.%0a%0a:$MakePageNamePatterns: $MakePageNamePatterns is an array of regular expression replacements that is used to map the page link in a ''free link'' such as [@[[free link]]@] into a page name. Currently the default sequence is: [@%0a "/'/" => '', # strip single-quotes%0a "/[^$PageNameChars]+/" => ' ', # convert non-alnums to spaces%0a "/((^|[^-\\w])\\w)/e" %0a => "strtoupper('$1')", # initial caps after spaces%0a "/ /" => '' # strip spaces%0a@]%0a: :Note that if you change $MakePageNamePatterns, the documentation links may break. This can be fixed by re-setting $MakePageNamePatterns to the default in local/PmWiki.php.%0a%0a:$WikiWordCountMax:The maximum number of times to convert each WikiWord encountered on a page. Defaults to 1,000,000. Common settings for this variable are zero (disable WikiWord links) and one (convert only the first occurrence of each WikiWord).%0a $WikiWordCountMax = 0; # disable WikiWord links%0a $WikiWordCountMax = 1; # convert only first WikiWord%0a%0a:$WikiWordCount:An array that allows the number of WikiWord conversions to be set on a per-WikiWord basis. The default is to use $WikiWordCountMax unless a value is set in this array. By default PmWiki sets @@$WikiWordCount['PmWiki']=1@@ to limit the number of conversions of "PmWiki".%0a $WikiWordCount[=['PhD']=0; # Don't convert "PhD"=]%0a $WikiWordCount['WikiWord']=5; # Convert WikiWord 5 times%0a # the following lines keep a page from linking to itself%0a $title = [=FmtPageName=]('$Title_',$pagename);%0a $WikiWordCount[$title]=0; %0a %0a:$EnableRedirectQuiet:Enable the @@quiet=1@@ parameter for the [[PmWiki.PageDirectives#redirect|redirect directive]]. On publicly edited wikis it is advisable not to enable quiet redirects.%0a $EnableRedirectQuiet = 0; # disable quiet redirects (default)%0a $EnableRedirectQuiet = 1; # enable quiet redirects%0a
+time=1247410666
diff --git a/wikilib.d/PmWiki.Links b/wikilib.d/PmWiki.Links
new file mode 100644
index 0000000..a14008c
--- /dev/null
+++ b/wikilib.d/PmWiki.Links
@@ -0,0 +1,11 @@
+version=pmwiki-2.2.7 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/532.0 (KHTML, like Gecko) Chrome/3.0.195.32 Safari/532.0
+author=simon
+charset=ISO-8859-1
+csum=separate out markup
+host=202.37.32.2
+name=PmWiki.Links
+rev=146
+targets=PmWiki.WikiWikiWeb,PmWiki.WikiSandbox,PmWiki.Installation,PmWiki.WikiWord,PmWiki.BasicEditing,PmWiki.Categories,PmWiki.InterMap,PmWiki.WikiGroup,Main.WikiSandbox,PmWiki.PageLists,PmWiki.Images
+text=(:Summary:Linking within and between wiki pages:)%0a(:Audience: authors (basic) :)%0aA key feature of [[Wiki Wiki Web]]s is the ease of creating %25newwin%25[[Wikipedia:Hyperlink|hyper links]]%25%25 in the text of a document. %0aPmWiki provides multiple mechanisms for creating such links.%0a%0a!! Links to other pages in the wiki%0a%0aTo create a link to another page, simply enclose the name of the page inside double square brackets, as in [@[[wiki sandbox]]@] or [@[[installation]]@]. These result in links to [[wiki sandbox]] and [[installation]], respectively.%0a%0aPmWiki creates a link by using the text inside the double brackets. It does this by removing spaces between words, and automatically capitalizing words following spaces or other punctuation (like ~). Thus [@[[Wiki sandbox]]@], [@[[wiki sandbox]]@], and [@[[WikiSandbox]]@] all display differently but create the same link to the page titled ''WikiSandbox''.%0a%0aIn other words, PmWiki will automatically create the link path name using title case as a rule, but link text will display in the format you have entered it.%0a%0aA suffix can also be added to the end of a link, which becomes part of the link text but not the target. Thus [@[[wiki sandbox]]es@] is a link to ''[=WikiSandbox=]'' but displays as [[wiki sandbox]]es.%0a%0aLink text in (parentheses) will not be not displayed, so that [@[[(wiki) sandbox]]@] links to ''[=WikiSandbox=]'' and displays as [[(wiki) sandbox]].%0a%0aFinally, you can specify the link text via a vertical brace, thus [@[[WikiSandbox | a play area]]@], which links to ''WikiSandbox'' but displays as [[WikiSandbox | a play area]]. You can use an arrow ([@->@]) to reverse the order of the text and target, as in [@[[a play area -> WikiSandbox]]@] ([[a play area -> WikiSandbox]]).%0a%0aSome sites also recognize [[WikiWord]] links, in which a camel case (capitalised) ''[=WikiWord=]'' appearing in the text is automatically treated as a link to a page of the same name.%0a%0a!!! [[#linkshortcuts]]Link shortcuts%0a%0aUse of special characters in title is not a problem for PmWiki, but sometimes the character set is different from your computer and the server computer or the client computer that is used to read your wiki. Specially UTF-8 gives some problems. So it's better not to use these and keep ASCII characters if possible. Any page can have a [=(:title %3cname>:)=] directive to display a localized title instead of the page file name. In this case, the following tip is important and usefull.%0a%0a'''[@[[PageName|+]]@]''' creates a link to PageName and uses that page's title as the link text, e.g., [=[[PmWiki.BasicEditing|+]]=] where the page BasicEditing has the directive [=(:title=] {BasicEditing$Title}:) gives [[PmWiki.BasicEditing|+]]. %0a%0a%0a'''[@[[PageName|#]]@]''' creates a [[#reference|reference]] link as shown below'^[[#reference|#]]^'.%0a%0a'''[@[[!PageName]]@]''' creates a link to the PageName in the group called Category. See [[PmWiki/Categories]].%0a%0a'''[@[[~Author]]@]''' link creates a link to the page called Author in the Profiles group. %0a%0a'''[@~@][@~~@]''' markup creates a link for the current Author when it encounters three tilde characters ([@~@]) in a row ([@~@][@~@][@~@]). %0a%0a'''[@~~@][@~~@]''' markup creates a link for the current author and appends the current date and time when four tilde characters ([@~@]) in a row are encountered%0a%0a!!! [[#anchors]]Links to specific locations within a page -- "anchors"%0a%0aTo define a location within a page to which you may jump directly, use the markup [@[[#name]]@]. This creates an "anchor" that uniquely identifies that location in the page. Then to have a link jump directly to that anchor, use one of%0a%0a* [@[[#name|link text]]@] within the same page, or%0a* [@[[PageName#name]]@] or [@[[PageName#name|link text]]@] for a location on another page%0a* The form [@[[PageName(#name)]]@] may be useful for hiding the anchor text in a link. %0a%0aFor example, here's a link to the [[#intermaps | Intermaps]] section, below. %0a%0aNotes:%0a* %25red%25the anchor itself must begin with a letter%25%25, '''not a number'''%0a* a link to an anchor must have the '''same capitalization as the anchor''' itself. %0a* Spaces are not allowed in an anchor: "[@[[#my anchor]]@]" won't work, "[@[[#myanchor]]@]" will.%0a%0a!!! [[#actions]]Links to actions%0a%0aTo link to a specific action for the current page use [@[[{$FullName}?action=actionname|linkname]]@].%0a%0aExamples:%0a* [@[[{$FullName}?action=edit|Edit]]@] for the editing or%0a* [@[[{$FullName}?action=diff|differences]]@] for differences.%0a%0a!! Links outside the wiki%0a[[#externallinks]]%0a!!! Links to external sites ([=URLs=])%0a%0aLinks to external sites simply begin with a prefix such as 'http:', 'ftp:', etc. Thus [@http://google.com/@] and [@[[http://google.com/]]@] both link to Google. As with the above, an author can specify the link text by using the vertical brace or arrow syntax, as in [@[[http://google.com/ | Google]]@] and [@[[Google -> http://google.com]]@].%0a%0aIf the external link includes (parentheses), escape these using [=%2528=] for "(" and [=%2529=] for ")" : %0a(:markup:)[=[[http://en.wikipedia.org/wiki/Wiki_%2528disambiguation%2529 | link to "Wiki (disambiguation)" ]]=]%0a%0a!!! Links to intranet (local) files%0a%0aYou can link to a file system by including the prefix [@'file:///'@] (for Internet Explorer at least). So [@file:///S:\ProjPlan.mpp@] and [@[[Shared S drive->file:///S:\]]@] are both valid links. On a Windows file system you may want to use network locations (eg \\server1\rootdirectory\subdirectory) rather than drive letters which may not be consistent across all users. Not all browsers will follow such links.%0a%0a!! Link characteristics%0a!!! [[#reference]]Links as References%0a%0aLinks may also be specified as '''References''', so the target appears as an anonymous ''numeric'' reference rather than a ''textual'' reference. The following markup is provided to produce sequential reference numbering within a PmWiki page:%0a%0aFormatting the link as: [@[[http://google.com |#]]@] produces: [[http://google.com |#]] as the link.%0a%0aSubsequent occurrence of the reference link format on the same page will be incremented automatically as per the following example: Entering [@[[http://pmwiki.com |#]]@] produces [[http://pmwiki.com |#]], [@[[#intermaps |#]]@] produces [[#intermaps |#]], and so on for further reference links.%0a%0a!!! [[#intermaps]]Intermaps%0a%0a[[Inter Map]] links are also supported (see [[Inter Map]]). In particular, the [@Path:@] InterMap entry can be used to create links using relative or absolute paths on the current site (e.g., [@Path:../../somedir/foo.html@] or [@Path:/dir/something.gif@]).%0a%0a%0a!!! Links to pages in other [[wiki group]]s%0a%0aSee [[Wiki Group]].%0a%0a!!! Links that open a new browser window%0a%0aTo have a link open in another window, use [@%25newwin%25...%25%25@]:%0a%0a* [@%25newwin%25 http://pmichaud.com %25%25@] produces %25newwin%25 http://pmichaud.com %25%25%0a* [@%25newwin%25 [[http://google.com/ | Google]] %25%25@] produces %25newwin%25 [[http://google.com/ | Google]]%25%25%0a* [@%25newwin%25 [[Main.WikiSandbox]] %25%25@] produces %25newwin%25 [[Main.WikiSandbox]]%25%25%0a%0aYou can also specify that links should open in a new window via the @@[=%25target=_blank%25...%25%25=]@@ attribute:%0a%0a(:markup class=horiz:)%0aThe following link %25target=_blank%25 http://pmichaud.com %25%25%0awill open in a new window.%0a(:markupend:)%0a%0a!!! [[#robots]]Links that are not followed by [[(PmWiki:)robots]]%0a%0aPrefix a link with [=%25rel=nofollow%25=] to advise %25newwin rel=nofollow%25[[http://robotstxt.org/|robots]] and [[http://validator.w3.org/checklink|link checkers]]%25%25 not to follow it.%0a%0a%0a!! Links and CSS Classes%0a%0aPmWiki automatically gives classes to several types of links. Among other things, this enables you to format each type differently.%0a%0aNote: This may be an incomplete list.%0a:.selflink:A link to the current page. Useful in sidebars to show "you are here".%0a:.wikilink:A link to another page within the wiki.%0a:.urllink:A link to a page outside the wiki.%0a%0a!! Notes%0a%0a'''Note:''' The default behavior of "+" above can be overridden to display the spaced title, rather than simply the title by adding the following to config.php:%0a->[@%0a## [[target |+]] title links%0aMarkup('[[|+', '%3c[[|',%0a "/(?>\\[\\[([^|\\]]+))\\|\\s*\\+\\s*]]/e",%0a "Keep(MakeLink(\$pagename, PSS('$1'),%0a PageVar(MakePageName(\$pagename,PSS('$1')), '\$Titlespaced')%0a ),'L')");%0a@]%0a%0a%0a>>faq%3c%3c [[#faq]]%0a%0aQ: How do I create a link that will open as a new window?%0a%0aA: Use the [@%25newwin%25@] wikistyle, as in:%0a(:markup class=horiz:) [=%25newwin%25 http://example.com/ %25%25=]%0a%0aQ: How do I create a link that will open a new window, and configure that new window?%0a%0aA: This requires javascript. See [[Cookbook:PopupWindow]].%0a%0aQ: How do I place a mailing address in a page?%0a%0aA: Use the [@mailto:@] markup, as in one of the following:%0a%0a(:markup class="horiz":)%0a* mailto:myaddress@example.com%0a* [[mailto:myaddress@example.com]]%0a* [[mailto:myaddress@example.com | email me]]%0a* [[mailto:myaddress@example.com?subject=Some subject | email me]]%0a(:markupend:)%0aThe markup @@[=[[mailto:me@example.=]com?%25red%25cc=%25%25someoneelse@example.com%25red%25&bcc=%25%25else@example.com%25red%25&subject=%25%25Pre-set Subject%25red%25&body=%25%25Pre-set body | display text]] =]@@ lets you specify more parameters like the message body and more recipients (may not work in all browsers and e-mail clients).%0a%0aSee also [[Cookbook:DeObMail]] for information on protecting email addresses from spammers.%0a%0aQ: How can I enable links to other protocols, such as nntp:, ssh:, xmpp:, etc?%0a%0aA: See [[Cookbook:Add Url schemes]] {Cookbook.AddUrlSchemes$:Summary}%0a%0aQ: How do I make a WikiWord link to an external page instead of a WikiPage?%0a%0aA: Use link markup. There are two formats:%0a%0a->[@[[http://example.com/ | WikiWord]]%0a[[WikiWord -> http://example.com/]]@]%0a%0aQ: How do I find all of the pages that link to another page (i.e., backlinks)?%0a%0aA: In the wiki search form, use @@link=Group.Page@@ to find all pages linking to Group.Page.%0a%0aA: Use the [@link=@] option of the [[[@(:pagelist:)@] directive -> PmWiki/PageLists#pagelistlink]], as in%0a%0a->[@(:pagelist link=SomePage list=all:) -- show all links to SomePage%0a(:pagelist link={$FullName} list=all:) -- show all links to the current page@]%0a%0a%0aQ: What link schemes does PmWiki support?%0aA: See [[PmWiki:Link schemes]] {PmWiki.LinkSchemes$:Summary}%0a%0aQ: How do I open external links in a new window or mark them with an icon?%0aA: See [[Cookbook:External links]] {Cookbook.ExternalLinks$:Summary}%0a%0aQ: How can I use an image as a link?%0aA: Use [=[[Page| Attach:image.jpg ]] or [[ http://site | http://site/image.jpg ]]=] See [[PmWiki/Images#links]]%0a
+time=1257824436
diff --git a/wikilib.d/PmWiki.LocalCustomizations b/wikilib.d/PmWiki.LocalCustomizations
new file mode 100644
index 0000000..12c13ae
--- /dev/null
+++ b/wikilib.d/PmWiki.LocalCustomizations
@@ -0,0 +1,11 @@
+version=pmwiki-2.2.10 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.7) Gecko/20100106 Ubuntu/9.10 (karmic) Firefox/3.5.7
+author=Petko
+charset=ISO-8859-1
+csum=this very much depends on the scripts/recipes, could be after
+host=81.65.12.233
+name=PmWiki.LocalCustomizations
+rev=60
+targets=PmWiki.GroupCustomizations,PmWiki.WikiAdministrator,PmWiki.PmWikiPhilosophy,PmWiki.Variables,PmWiki.DocumentationIndex,PmWiki.Skins,PmWiki.Internationalizations,PmWiki.CustomMarkup,PmWiki.CustomInterMap,PmWiki.InterMap,Cookbook.ControllingWebRobots,Cookbook.Cookbook,PmWiki.MailingLists,PmWiki.Upgrades,Site.PageNotFound,Cookbook.SQLite,Cookbook.CompressedPageStore,Cookbook.PerGroupSubDirectories
+text=(:Summary:Customize your PmWiki installation through @@config.php@@ and @@local.css@@:)%0aA [[Wiki Administrator]] can make a lot of customizations simply by setting variables in the ''/local/config.php'' and defining cascading style sheets in ''/pub/css/local.css'' files. Any group or page can also have [[GroupCustomizations|its own configuration file and configuration css file]].%0a%0aFrom its inception, PmWiki has been designed so that [[Wiki Administrator]]s can greatly customize the way PmWiki displays pages and the markup sequences used to generate pages. (This is even mentioned explicitly in [[PmWiki Philosophy]] #4.) As a result, the core ''pmwiki.php'' script makes extensive use of [[PmWiki.Variables]] to determine how markup sequences will be processed and what each individual page will output.%0a%0aThe bulk of this page describes how customizations work in general, see [[PmWiki.Documentation Index]] for specific customizations that are commonly performed at many PmWiki installations, including:%0a%0a* [[Skins]] - {Skins$:Summary}%0a* [[Internationalizations]] - {Internationalizations$:Summary}%0a* [[Custom Markup]] - {CustomMarkup$:Summary}%0a* [[Custom InterMap]]s - {CustomInterMap$:Summary}%0a%0aThe simplest type of customization is merely setting a variable to 1 (or TRUE). Here's an example that enables ?action=diag and ?action=phpinfo actions:%0a%0a->[@$EnableDiag = 1;@]%0a%0aYou can begin a line with a "#" (an octothorpe, a.k.a. a hash symbol or pound sign) to add a comment. Additionally, some built-in PmWiki variables take values other than 1 or 0 (true or false). Here's another example that customizes the wiki's behavior with respect to search engine web robots (see [[Cookbook:ControllingWebRobots]]):%0a%0a->[@%0a# Remove the default "rel='nofollow'" attribute for external links.%0a$UrlLinkFmt = "%3ca class='urllink' href='\$LinkUrl'>\$LinkText%3c/a>";%0a@]%0a%0aThe ''scripts/'' subdirectory (below the directory holding the ''pmwiki.php'' script) has many customizations.%0aThe PmWiki [[(Cookbook:)Cookbook]] contains many example customizations (recipes) that you can download into the ''cookbook/'' subdirectory,%0aThe first few lines of each of these scripts generally contain instructions about how to enable (and use) the feature provided by the script.%0a%0aThese customizations are included in your ''config.php'' site configuration. For most scripts this is done by simply adding lines like:%0a->[@include_once("cookbook/recipefile.php");@]%0aand%0a->[@include_once("scripts/scriptfile.php");@]%0aat the end of the ''config.php'' file to enable them. %0a%0aSome of the scripts are automatically enabled for you via the ''scripts/stdconfig.php'' script unless you disable it by setting @@$EnableStdConfig=0;@@ in ''local/config.php''.%0a%0aNote that you should strongly resist the temptation to directly modify the ''pmwiki.php'' script or the files in the ''scripts/'' subdirectory. Any modifications you make to these files will probably be overwritten whenever you perform a [[PmWiki.Upgrade(s)]]. Instead, look at some of the sample scripts for examples of customizations that can be performed from ''config.php''. You can even create your own script to do a customization and use @@include_once(...)@@ to include it from ''config.php''. If you do make your own customization script, you can safely put it in the ''cookbook/'' subdirectory--it won't get overwritten by an upgrade there. You might also want to submit your customization to the [[MailingLists|pmwiki-users mailing list]] or the [[(Cookbook:)Cookbook]] so that others can benefit from your effort and so that it can perhaps be included in future releases of PmWiki.%0a%0a>>faq%3c%3c [[#faq]]%0aQ: There's no "config.php"; it's not even clear what a "local customisation file" is!%0aA: The "sample-config.php" file in the "docs" folder, is given as an example. Copy it to the "local" folder and rename it to "config.php". You can then remove the "#" symbols or add other commands shown in the documentation. See also [[Group Customizations]].%0a%0aQ: Can I change the default page something other than Main.HomePage ($DefaultPage)?%0aA: Yes, just set the $DefaultPage variable to the name of the page you want to be the default. You might also look at the $DefaultGroup and $DefaultName configuration variables.%0a%0a->[@$DefaultPage = 'ABC.StartPage';@]%0a%0aQ: How do I get the group / page name in a local configuration file (e.g. ''local/config.php'')?%0aA: Use the following markup in pmwiki-2.1.beta21 or newer:%0a%0a->[@%0a## Get the group and page name%0a$pagename = ResolvePageName($pagename);%0a$page = PageVar($pagename, '$FullName');%0a$group = PageVar($pagename, '$Group');%0a$name = PageVar($pagename, '$Name');%0a@]%0a%0a%0aQ: Can I remove items from the wikilib.d folder on my site?%0aA: Yes, the files in ''wikilib.d/'' can be safely removed. They'll reappear again when you upgrade, however.%0a%0a%0aQ: How do I customize my own 404 error page for non-existent pages?%0aA: To change the text of the message, try editing the [[Site.PageNotFound]] page.%0a%0aQ: [[#configphp-order]] Is the order of customizations in config.php important? Are there certain things that should come before or after others in that file? '^[[{$PageUrl}#configphp-order|#]]^'%0aA: Yes, the following has been recommended on the mailing list:%0a%0a* define $ScriptUrl and $PubDirUrl, if needed,%0a* define any custom PageStore class, like [[(Cookbook:)SQLite]], [[(Cookbook:)CompressedPageStore]] or [[(Cookbook:)PerGroupSubDirectories]],%0a* next include_once scripts/xlpage-utf-8.php,%0a* next call XLPage() which needs the definitive (rw) $WikiDir already set in order to find the wiki page containing the translations,%0a* next include authuser.php (if needed), because PmWiki caches some group and page authorization levels when a page is accessed,%0a* next include any other scripts and recipes,%0a* any direct function call in config.php, like ResolvePageName(), CondAuth(), PageTextVar(), PageVar(), RetrieveAuthPage(), or others, if possible, should be done near the end of config.php.%0a%0a''Note, each part is '''not''' required, but if your wiki needs it, this is the recommended order in config.php.''%0a
+time=1264848337
diff --git a/wikilib.d/PmWiki.MailingLists b/wikilib.d/PmWiki.MailingLists
new file mode 100644
index 0000000..fcf3fc0
--- /dev/null
+++ b/wikilib.d/PmWiki.MailingLists
@@ -0,0 +1,11 @@
+version=pmwiki-2.2.2 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.19) Gecko/20081216 Ubuntu/8.04 (hardy) Firefox/2.0.0.19
+author=Petko
+charset=ISO-8859-1
+csum=
+host=81.65.14.164
+name=PmWiki.MailingLists
+rev=105
+targets=PmWiki.PmWiki
+text=(:Summary:The email discussion lists available and their archives:)%0aThere are several mailing lists available for [[PmWiki]].%0a %0a:[ [[(http://pmichaud.com/lists/)pmwiki-users]] ]: This is a great resource where a very helpful group of people will answer questions and discuss PmWiki development. Traffic is around 20-40 messages a day (on slow days). %0a->''If you ask a question on the list and it doesn't get answered, don't feel let down. Just'' '''''ask it again'''''. It probably slipped by unnoticed.%0a%0a->Archives are available from:%0a-->http://pmichaud.com/pipermail/pmwiki-users/%0a-->http://news.gmane.org/gmane.comp.web.wiki.pmwiki.user ([[http://search.gmane.org/search.php?group=gmane.comp.web.wiki.pmwiki.user|searchable]])%0a-->http://groups.google.com/group/pmwiki-users (searchable)%0a-->http://www.mail-archive.com/pmwiki-users@pmichaud.com/info.html (searchable)%0a%0a%0a-->(:input form action='http://search.gmane.org/' method='get':)(:input text query:)(:input hidden group gmane.comp.web.wiki.pmwiki.user:) (:input submit value='Search pmwiki-users archives at gmane':)(:input end:)%0a%0a:[ [[(http://pmichaud.com/lists/)pmwiki-users-de]] ]: A mailing list for german-speaking users of PmWiki. Archived at%0a-->http://pmichaud.com/pipermail/pmwiki-users-de%0a%0a:[ [[(http://pmichaud.com/mailman/listinfo/)pmwiki-users-es]] ]: Lista de usuarios PmWiki en Español.%0a%0a:[ [[(http://pmichaud.com/mailman/listinfo/)pmwiki-users-fr]] ]: A mailing list for french-speaking users of PmWiki.%0a%0a:[ [[(http://pmichaud.com/mailman/listinfo/)pmwiki-devel]] ]: This list was created to lower the traffic on pmwiki-users, it focuses on discussions surrounding code development for PmWiki (both core and recipe development).%0a%0a->Archives are available from:%0a-->http://pmichaud.com/pipermail/pmwiki-devel/%0a-->http://news.gmane.org/gmane.comp.web.wiki.pmwiki.devel ([[http://search.gmane.org/search.php?group=gmane.comp.web.wiki.pmwiki.devel|searchable]])%0a-->http://groups.google.com/group/pmwiki-devel (searchable)%0a-->http://www.mail-archive.com/pmwiki-devel@pmichaud.com/info.html (searchable)%0a%0a:[ [[(http://pmichaud.com/lists/)pmwiki-announce]] ]: Announcements of new version releases and urgent information. If you use PmWiki in a production environment, this low-volume list is highly recommended. The archive is at:%0a-->http://pmichaud.com/pipermail/pmwiki-announce%0a%0aSuggestions:%0a* If you reply to a digest message, please remove the messages irrelevant to your reply before sending it back to the list. %0a** It's also helpful (but less important) to change "Re: pmwiki-users Digest, Vol [...]" to "Re: [the original subject]" because some mail programs determine threads based on the subject.%0a* If you address a reply to a single list member, please take the [pmwiki-users] off the subject line, or it's possible for your message to get lost in the mailing list traffic. Many people filter list traffic to a separate mailbox.%0a%0a!! Changing mail list settings%0a%0aHere are some tips regarding changing the mailing list settings:%0a%0a* Logging in...%0a** First go to [[http://pmichaud.com/mailman/listinfo/pmwiki-users]]%0a and enter your e-mail address in the field at the bottom of the page,%0a to the left of the button ''Unsubscribe or edit options''.%0a** Next you need to enter your password. As you've probably forgotten this,%0a use the button ''Remind'' at the bottom of the page to get a new password.%0a** Finally enter the password you should get momentarily via e-mail.%0a%0a* You can directly go to the options web page through a URI such as the%0a following:%0a-> [@http://host.pmichaud.com/mailman/options/pmwiki-users/%3cuser>%2540%3cdomain>@]%0a-> where [@%3cuser>@] is everything before the [@@@] in an e-mail address,%0a and [@%3cdomain>@] is everything after (%0a For those who wonder, the [@%2540@] in the URI just stands for '[@@@]'.%0a%0a* You can also obtain various help by sending an email to%0a mailto:pmwiki-users-request@pmichaud.com with the text [@help@] in either%0a the subject or the body.%0a%0a!! Newsgroups (NNTP)%0aYou may be interested, that the lists are also accessible as newsgroups.%0a%0aThe NNTP server is:%0a* news.gmane.org '^[[http://news.gmane.org/search.php?match=pmwiki|#]]^'%0a%0aThe groups are:%0a* gmane.comp.web.wiki.pmwiki.user%0a* gmane.comp.web.wiki.pmwiki.announce%0a* gmane.comp.web.wiki.pmwiki.user.de%0a
+time=1246997130
diff --git a/wikilib.d/PmWiki.MarkupExpressions b/wikilib.d/PmWiki.MarkupExpressions
new file mode 100644
index 0000000..2907d9a
--- /dev/null
+++ b/wikilib.d/PmWiki.MarkupExpressions
@@ -0,0 +1,12 @@
+version=pmwiki-2.2.5 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.8) Gecko/2009033100 Ubuntu/9.04 (jaunty) Firefox/3.0.8
+author=Rafa
+charset=ISO-8859-1
+csum=
+ctime=1176718061
+host=194.51.102.250
+name=PmWiki.MarkupExpressions
+rev=60
+targets=PmWiki.PageVariables,PmWiki.PageTextVariables,PmWiki.ConditionalMarkup
+text=(:Summary:String and formatting operations:)%0a(:Audience: authors (advanced) :)%0a%0aThe [@{(...)}@] "expression markup" allows for a variety of string and formatting operations to be performed from within markup. Operations defined by this recipe include ''[[#substr|substr]]'', ''[[#ftime|ftime]]'', ''[[#strlen|strlen]]'', ''[[#rand|rand]]'', ''[[#to|toupper / tolower]]'', ''[[#ucfirst|ucfirst]]'', ''[[#ucwords|ucwords]]'', ''[[#pagename|pagename]]'' and ''[[#asspaced|asspaced]]''.%0a%0a[[#substr]]%0a!! ''substr''%0a%0aThe "substr" expression extracts portions of a string. The arguments are%0a# the string to be processed. Always quote the string to be processed.%0a# the initial position of the substring. Note that the initial position argument is zero-based (i.e., the first character is referenced via a "0").%0a# the number of characters to extract%0a(:markup class="horiz":)%0a {(substr "PmWiki" 2 3)}%0a {(substr "PmWiki" 2)}%0a {(substr "PmWiki" 0 1)}%0a {(substr "PmWiki" 0 -3)}%0a {(substr "PmWiki" -3)}%0a(:markupend:)%0a%0aTo obtain the last n characters of a string use [@{(substr "string" -n)}@]%0a[[%3c%3c]]%0aTo truncate the last n characters of a string use [@(substr "string" 0 -n)}@]%0a%0a[[#ftime]]%0a!! ''ftime''%0a%0a"Ftime" expressions are used for date and time formatting. The generic form is%0a%0a->[@{(ftime "fmt" "when")}@]%0a->[@{(ftime fmt="fmt" when="when")}@]%0a%0awhere ''fmt'' is a formatting string and ''when'' is the time to be formatted. The arguments can be in either order and may use the optional "fmt=" and "when=" labels.%0a%0aExamples:%0a(:markup class="horiz":)%0a {(ftime)}%0a {(ftime fmt="%25F %25H:%25M")}%0a {(ftime %25Y)}%0a {(ftime fmt=%25T)}%0a {(ftime when=tomorrow)}%0a {(ftime fmt="%25Y-%25m-%25d" yesterday)}%0a {(ftime week %25F)}%0a {(ftime fmt=%25D month)}%0a {(ftime fmt="%25a%25e %25b" when="next week")}%0a(:markupend:)%0a%0aThe ''fmt'' parameter is whatever is given by "fmt=", the first parameter containing a '%25', or else the site's default. The formatting codes are described at %25newwin%25 http://php.net/strftime. In addition to those, '%25F' produces ISO-8601 dates, and '%25s' produces Unix timestamps.%0aSome common formatting strings:%0a%0a [= %25F =] # ISO-8601 dates "{(ftime %25F)}"%0a [= %25s =] # Unix timestamp "{(ftime %25s)}"%0a [= %25H:%25M:%25S =] # time as hh:mm:ss "{(ftime %25H:%25M:%25S)}"%0a [= %25m/%25d/%25Y =] # date as mm/dd/yyyy "{(ftime %25m/%25d/%25Y)}"%0a [= "%25A, %25B %25d, %25Y" =] # in words "{(ftime "%25A, %25B %25d, %25Y")}"%0a%0aThe ''when'' parameter understands many different date formats. The when parameter is whatever is given by "when=", or whatever parameter remains after determining the format parameter. Some examples:%0a%0a 2007-04-11 # ISO-8601 dates%0a 20070411 # dates without hyphens, slashes, or dots%0a 2007-03 # months%0a @1176304315 # Unix timestamps (seconds since 1-Jan-1970 00:00 UTC)%0a now # the current time%0a today # today @ 00:00:00%0a yesterday # yesterday @ 00:00:00%0a "next Monday" # relative dates%0a "last Thursday" # relative dates%0a "-3 days" # three days ago%0a "+2 weeks" # two weeks from now%0a%0a'''Note:''' If you want to convert a Unix timestamp you '''must''' prefix with the @. Thus, [@"{(ftime "%25A, %25B %25d, %25Y" @1231116927)}"@].%0a%0aThe ''when'' parameter uses PHP's %25newwin%25[[(http://www.php.net/)strtotime]] function to convert date strings according to the GNU [[http://www.gnu.org/software/tar/manual/html_node/Date-input-formats.html|date input formats]]; as of this writing it only understands English phrases in date specifications.%0a%0aThe variable $FTimeFmt can be used to override the default date format used by the "ftime" function. The default $FTimeFmt is $TimeFmt.%0a%0a[[#strlen]]%0a!! ''strlen''%0a%0aThe "strlen" expression returns the length of a string. The first argument is the string to be measured.%0a%0a(:markup class="horiz":)%0a {(strlen "{$:Summary}")}%0a(:markupend:)%0a%0a[[#rand]]%0a!! ''rand''%0a%0aThe "rand" expression returns a random integer. The first argument is the minimum number to be returned and the second argument is the maximum number to be returned. If called without the optional min, max arguments rand() returns a pseudo-random integer between 0 and RAND_MAX. If you want a random number between 5 and 15 (inclusive), for example, use rand (5, 15).%0a%0a(:markup class="horiz":)%0a {(rand)}%0a(:markupend:)%0a%0a[[#to]]%0a!! ''toupper'' / ''tolower''%0a%0aThe "toupper" and "tolower" expressions convert a string into uppercase or lowercase. The first argument is the string to be processed.%0a%0a(:markup class="horiz":)%0a {(toupper "{$:Summary}")}%0a {(tolower "{$:Summary}")}%0a(:markupend:)%0a%0a[[#ucfirst]]%0a!!''ucfirst''%0a%0aThe "ucfirst" expression converts the first character of a string to uppercase. The first argument is the string to be processed.%0a%0a(:markup class="horiz":)%0a {(ucfirst "{$:Summary}")}%0a(:markupend:)%0a%0a[[#ucwords]]%0a!! ''ucwords''%0a%0aThe "ucwords" expression converts the first character of each word in a string to uppercase. The first argument is the string to be processed.%0a%0a(:markup class="horiz":)%0a {(ucwords "{$:Summary}")}%0a(:markupend:)%0a%0a[[#pagename]]%0a!! ''pagename''%0a%0aThe "pagename" expression builds a pagename from a string. The first argument is the string to be processed.%0a%0a(:markup class="horiz":)%0a {(pagename "{$:Summary}")}%0a(:markupend:)%0a%0a[[#asspaced]]%0a!! ''asspaced''%0a%0aThe "asspaced" expression formats wikiwords. The first argument is the string to be processed.%0a%0a(:markup class="horiz":)%0a {(asspaced "{$FullName}")}%0a(:markupend:)%0a%0a[[#nesting]]%0a!! Nesting expressions%0a%0aMarkup expressions can be nested:%0a%0a(:markup class="horiz":)%0a {(tolower (substr "Hello World" 2))}%0a(:markupend:)%0a%0a[[#notes]] %0a!! Notes%0a%0a* Some of the string-processing markups may not work properly on UTF-8 characters or escaped sequences.%0a* The ftime markup does not work with some [[http://mcs.vuw.ac.nz/technical/software/SGML/doc/iso8601/ISO8601.html | ISO 8601]] dates (because a time of 24:00 [[http://gnu.org/software/tar/manual/html_node/tar_114.html | is invalid]])such as: %0a(:markup class=horiz:)%0a {(ftime fmt="%25m/%25d/%25Y @ %25H:%25M:%25S" when="20070626T2400")}%0a {(ftime fmt="%25H:%25M:%25S" when="20070626T2400")}%0a(:markupend:)%0a* is it possible to display the time in another [[http://gnu.org/software/tar/manual/html_node/tar_122.html#SEC122 | time zone]], eg%0a(:markup class=horiz:)%0aNowTime: {(ftime fmt="%25F %25H:%25M")}%0a {(ftime when='TZ=:Europe/London" ')}%0a {(ftime when='TZ=Europe/London" 0 days')}%0a {(ftime when="TZ='Europe/London' 2004-10-31 08:00")}%0a {(ftime when='TZ="Pacific/Auckland" {$:NowTime}')}%0a(:markupend:)%0a%0a!! See also%0a* [[Page variables]], [[Page text variables]]%0a* [[Conditional markup]]%0a* Cookbook:MarkupExpressionSamples — '-custom markup expression samples-'%0a* Cookbook:MarkupExprPlus%0a
+time=1254220873
diff --git a/wikilib.d/PmWiki.MarkupMasterIndex b/wikilib.d/PmWiki.MarkupMasterIndex
new file mode 100644
index 0000000..c50ff01
--- /dev/null
+++ b/wikilib.d/PmWiki.MarkupMasterIndex
@@ -0,0 +1,12 @@
+version=pmwiki-2.2.7 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/532.3 (KHTML, like Gecko) Chrome/4.0.223.16 Safari/532.3
+author=simon
+charset=ISO-8859-1
+csum=Add (:messages:)
+host=203.97.214.12
+name=PmWiki.MarkupMasterIndex
+rev=249
+targets=PmWiki.Links,PmWiki.WikiWord,PmWiki.Categories,PmWiki.InterMap,PmWiki.Uploads,PmWiki.Images,PmWiki.TextFormattingRules,PmWiki.WikiStyles,PmWiki.PageDirectives,PmWiki.Tables,PmWiki.TableDirectives,PmWiki.GroupHeaders,PmWiki.PageVariables,PmWiki.IncludeOtherPages,PmWiki.PageTextVariables,PmWiki.ConditionalMarkup,PmWiki.PageLists,PmWiki.Forms,PmWiki.WikiTrails,PmWiki.MarkupExpressions
+text=(:title Markup Master Index:)%0a(:Summary:Tabulation of all PmWiki markup:)%0a>>rframe font-size:smaller noprint%3c%3c%0a'''Table of contents'''%0a* [[#LinkMarkups|Links]]%0a** [[#ExternalLinks|To external urls]]%0a** [[#InternalLinks|To internal pages and more]]%0a** [[#WikiGroupLinks|To WikiGroups]]%0a** [[#IntermapLinks|To Intermap Destinations]]%0a** [[#EmailLinks|To email addresses]]%0a** [[#UploadLinks|To uploaded files]]%0a* [[#Images|Images]]%0a** [[#ImagesAsImages|as images]]%0a** [[#ImagesAsLinks|as links]]%0a* [[#StartOfLine|Start-of-line markup]]%0a** [[#Lists|Lists]]%0a** [[#Headings|Headings]]%0a** [[#BlockMarkups|Paragraph blocks]]%0a** [[#DivisionBlocks|Division blocks]]%0a* [[#Text|Text]]%0a** [[#InlineMarkups|Character format]]%0a** [[#PostingMarkups|Posting markup]]%0a* [[#Tables|Tables]]%0a** [[#PlainTables|Plain tables]]%0a** [[#TablesAndDivs|Structured tables]]%0a* [[#Directives|Directives]]%0a** [[#PageDirectives|Page directives]]%0a** [[#Display|Display]]%0a** [[#Metadata|Metadata]]%0a** [[#IncludeOtherPages|Include other pages]]%0a** [[#ConditionalMarkup|Conditional markup]]%0a** [[#PageLists|Page lists]]%0a** [[#OtherDirectives|Other directives]]%0a* [[#Forms|Forms]]%0a* [[#WikiTrails|WikiTrails]]%0a* [[#PageVariables|Page variables]]%0a* [[#Expressions|Expressions]]%0a>>%3c%3c%0aThis page contains the most frequently used wiki markup, briefly. Follow the links in each section to learn more.%0a%0a!! [[#LinkMarkups]] Links%0a%0aSee [[Links]]%0a!!![[#ExternalLinks]]External links%0a-%3c [@http://example.com@]%0a-%3c [@ [[http://example.com]] @]%0a-%3c [@ [[http://example.com | link text]] @]%0a-%3c [@ [[link text -> http://example.com]] @]%0a%0a%0a[[#InternalLinks]]%0a!!! Page links%0a-%3c [@ [[PageName]] @]%0a-%3c [@ [[page name]] @]%0a-%3c [@ [[page (name)]] @]%0a-%3c [@ [[PageName | link text]] @]%0a-%3c [@ [[PageName | + ]] @] ''(titled link)''%0a-%3c [@ [[PageName | # ]] @] ''(anonymous numerical reference link)''%0a-%3c [@ [[link text -> PageName]] @]%0a-%3c [@ [[#anchor]] @] ''(to create an anchor)''%0a-%3c [@ [[#anchor | link text]] @] ''(to refer to an anchor)''%0a-%3c [@ [[PageName#anchor | link text]] @] ''(to refer to an anchor in another page)''%0a%0a%0aSee also [[WikiWord]] on how to enable [@WikiWord@] links.%0a%0a[[#WikiGroupLinks]]%0a!!! WikiGroup links%0aSee [[Links]] and [[Categories]] %0a-%3c [@ [[GroupName/]] or [[Group name/]] @]%0a-%3c [@ [[GroupName.]] @]%0a-%3c [@ [[GroupName/PageName]] or [[GroupName/page name]] @]%0a-%3c [@ [[(GroupName.)page name]] @]%0a%0a-%3c [@ [[~Author Name]] @]%0a-%3c [@ [[!Category Name]] @]%0a%0a[[#IntermapLinks]]%0a!!! InterMap links%0aSee [[InterMap]]%0a-%3c [@ [[Path:/path/local_document.html]] @]%0a-%3c [@ [[Wikipedia:WikiWikiWeb]] @]%0a%0a[[#EmailLinks]]%0a!!! Email links%0a-%3c [@ mailto:someone@example.com @]%0a-%3c [@ [[(mailto:)someone@example.com]] @]%0a-%3c [@ [[mailto:someone@example.com | display text]] @]%0a-%3c [@ [[display text -> mailto:someone@example.com]] @]%0a%0a[[#UploadLinks]]%0a!!! Upload links%0aSee [[Uploads]] and [[#Images|Images]]%0a-%3c [@ Attach:file.odt @]%0a-%3c [@ [[(Attach:)file.odt]] @]%0a-%3c [@ [[Attach:file.odt | alternative text ]] @]%0a-%3c [@ [[Attach:file with spaces.pdf]] @]%0a-%3c [@ [[Attach:Groupname./file with spaces.pdf]] @]%0a%0a!! [[#Images]] Images%0a%0aSee [[Images]] and [[Uploads]]%0a!!! [[#ImagesAsImages]] Images as Images%0a-%3c [@http://example.com/image.gif@]%0a-%3c [@http://example.com/image.gif"alt text"@]%0a-%3c [@Attach:image.gif"My image"@]%0a-%3c [@Attach:Groupname./image.gif"image in another group"@]%0a-%3c [@Attach:Groupname.Pagename/image.gif"image on another page"@]%0a-%3c [@%25lfloat%25 Attach:image.gif | Caption %25%25@] ''(could be [=%25rfloat%25, %25center%25, %25rframe%25, %25lframe%25 =])''%0a-%3c [@%25width=200px%25 Attach:image.gif %25%25@]%0a-%3c [@%25thumb%25 Attach:image.gif %25%25@]%0a%0a%0a!!! [[#ImagesAsLinks]] Images as links%0a%0a-%3c [@ [[Attach:image.gif]] @]%0a-%3c [@ [[(Attach:)image.gif]] @]%0a-%3c [@ [[PageName | Attach:image.gif"alt text"]] @]%0a-%3c [@ [[http://example.com/ | Attach:image.gif"alt text"]] @]%0a-%3c [@%25rframe thumb%25 [[Attach:image.gif | Attach:image.gif"alt text"]] | Caption @]%0a%0a%0a!! [[#StartOfLine]] Start-of-line markup%0a%0aSee [[Text formatting rules]]%0a%0a!!! [[#Lists]] [[PmWiki/TextFormattingRules#BulletedLists| Lists]]%0a%0aSee [[(PmWiki:)List Styles]], [[Wiki styles]] and [[Cookbook:Outline lists]]%0a-%3c [@* unordered list@]%0a-%3c [@** deeper list@]%0a-%3c [@# ordered list@]%0a-%3c [@# %25item value=#%25@] arbitrary start number%0a-%3c [@# %25decimal%25, %25roman%25, %25ROMAN%25, %25alpha%25, %25ALPHA%25 @]%0a-%3c [@:term:definition@]%0aAlso%0a-%3c [@Q:@] start a question paragraph%0a-%3c [@A:@] start an answer paragraph%0a%0a%0a!!! [[#Headings]] Headings%0a%0a-%3c [@!! Heading@]%0a-%3c [@!!! Deeper heading@]%0a%0a%0a!!! [[#BlockMarkups]] Paragraph blocks%0a%0a-%3c [@-> indented text@]%0a-%3c [@-%3c hanging indent@]%0a-%3c [@%3cspace> preformatted text@]%0a-%3c @@[=[@...@]=]@@ preformatted block%0a-%3c [@----@] (horizontal rule)%0a-%3c [@blank line@] is vertical space%0a-%3c [@\@] at end of line joins next line%0a-%3c [@\\@] at end of line produces a line break%0a-%3c [@\\\@] at the end of a line produces a blank line, even within a list item%0a-%3c [@ [[%3c%3c]] @] produces a line break that clears floating content%0a%0a%0a!!! [[#DivisionBlocks]] Division blocks%0a%0aSee [[Wiki styles]] and [[Page directives]]%0a-%3c [@>>wikistyle%3c%3c@]%0a-> [@ (:div attr:) @]%0a-> [@ (:divend:) @]%0a-%3c [@>>%3c%3c@]%0a%0a%0a!! [[#Text]] Text markup%0a%0aSee [[Text formatting rules]]%0a!!! [[#InlineMarkups]] Character format%0a%0a-%3c [@''emphasized''@] %0a-%3c [@'''strong'''@]%0a-%3c [@'''''strong emphasis'''''@]%0a-%3c [@@@monospaced@@@]%0a-%3c [@[-small-], [--smaller--]@]%0a-%3c [@[+big+], [++bigger++]@]%0a-%3c [@'-small-', '+big+'@]%0a-%3c [@'^superscript^', '_subscript_'@]%0a-%3c [@{+inserted+} (underscore)@]%0a-%3c [@{-deleted-} (strikethrough)@]%0a-%3c @@[=[@escaped code@]=]@@%0a-%3c [@[=escaped text=]@]%0a%0a%0a!!! [[#PostingMarkups]] Posting markup%0a%0a-%3c @@~~@@@@~@@ (author's signature)%0a-%3c @@~~@@@@~~@@ (author's signature and date)%0a-%3c @@[=(:encrypt=] ''phrase''[=:)=]@@ -- replaced with encrypted form of ''phrase''%0a%0a%0a!! [[#Tables]] Tables%0a%0a!!! [[#PlainTables]] Plain rows and columns of text%0a%0aSee [[Tables]]%0a-%3c [@||table attributes@]%0a-%3c [@||!table caption!||@]%0a-%3c [@||left aligned || centered || right aligned||@]%0a-%3c [@||!column heading||@]%0a-%3c [@||spanned columns ||||||@]%0a%0a!!! [[#TablesAndDivs]] Structured tables%0a%0aSee [[Table directives ]]%0a-%3c [@ (:table attr:) @]%0a-%3c [@ (:cellnr attr:) @]%0a-%3c [@ (:cell attr:) @]%0a-%3c [@ (:tableend:) @]%0a%0a!! [[#Directives]] Directives%0a%0a!!! [[#PageDirectives]] Page directives%0a%0aSee [[Page directives]]%0a-%3c [@ (:redirect PageName:) @]%0a%0a-%3c [@ (:(no)spacewikiwords:) @]%0a-%3c [@ (:(no)linkwikiwords:) @]%0a-%3c [@ (:(no)linebreaks:) @]%0a-%3c [@ (:nl:) @] insert newline in the *markup* only if one isn't present. The purpose of [@ (:nl:) @] is to be able to write things like:%0a--> [@ (:include Page1:)(:nl:)(:include Page2:) @]%0a-> which guarantees that the first line of Page2 is treated as a separate line from the last line of Page1, but without inadvertently generating a blank line between them.%0a%0a!!! [[#Display]] Display%0a%0aSee [[Page directives]] [[Group headers]]%0a-%3c [@ (:noheader:), (:nofooter:) @]%0a-%3c [@ (:notitle:) @]%0a-%3c [@ (:noleft:), (:noright:) @]%0a-%3c [@ (:nogroupheader:), (:nogroupfooter:) @]%0a-%3c [@ (:noaction:) @]%0a%0a%0a!!! [[#Metadata]] Metadata%0a%0aSee [[Page directives]], [[(PmWiki:)Comment markup]], [[Page variables]]%0a-%3c [@ (:title text:) @]%0a-%3c [@ (:keywords word, ...:) @]%0a-%3c [@ (:description text:) @]%0a-%3c [@ (:comment text:) @]%0a-%3c [@{Group/PageName$:Var}@] [-includes from [@ (:name:text:) @]-]%0a%0a%0a!!! [[#IncludeOtherPages]] Include%0a%0aSee [[Include other pages]], [[Page text variables]]%0a-%3c [@ (:include PageName:) @]%0a-%3c [@ (:include PageName#start#end lines=n paras=n:) @]%0a-%3c [@ (:include Page1 Page2 Page3:) @]%0a-%3c [@{Group/PageName$:Var}@] [-includes from [@ (:name:text:) @]-]%0a%0a!!! [[#ConditionalMarkup]] Conditional markup%0a%0aSee [[Conditional markup]]%0a-%3c [@ (:if (!)@] ''cond param''[@:)...(:ifend:)@]%0a-%3c [@ (:if (!)@] ''cond param''[@:)...(:else:)...(:ifend:)@]%0a-%3c [@ (:if (!)@] ''cond param''[@:)...(:elseif (!)@] ''cond param''[@:)...(:ifend:) @]%0a%0a%0a!!! [[#PageLists]] Pagelists%0a%0aSee [[Page lists]]%0a-%3c [@ (:searchbox label=label order=-time:) @]%0a-%3c [@ (:searchresults incl -excl group=abc fmt=def:) @]%0a-%3c [@ (:pagelist incl -excl group=abc fmt=def:) @]%0a%0a%0a!!! [[#OtherDirectives]] Other directives%0a%0aSee [[Page directives]]%0a-%3c [@ (:@][[PageDirectives#attachlist|attachlist]][@:) @]%0a-%3c [@ (:@][[PageDirectives#markup]][@:) @] [@ [=...=] @]%0a-%3c [@ (:markup:)...(:markupend:) @]%0a-%3c [@ (:markup class=horiz:)...(:markupend:) @]%0a-%3c [@ (:markup caption='...':)...(:markupend:) @]%0a-%3c [@ (:messages:) @]%0a%0a%0a!! [[#Forms]] Forms%0a%0aSee [[PmWiki/Forms]]%0a-%3c [@ (:input form method=get action=url enctype=multipart/form-data:) @]%0a--%3c [@ (:input default name=xyz value="abc":) @]%0a--%3c [@ (:input text name=first value="Bob" size=20:) @]%0a--%3c [@ (:input submit name=post value="Go" accesskey=g:) @]%0a--%3c [@ (:input reset:) @]%0a--%3c [@ (:input hidden name=action value=edit:) @]%0a--%3c [@ (:input radio name=xyz value="abc" checked=1:) @]%0a--%3c [@ (:input checkbox name=xyz value="abc" checked=1:) @]%0a--%3c [@ (:input password name=authpw:) @]%0a--%3c [@ (:input file name=upload:) @]%0a--%3c [@ (:input image name=xyz src="http:..." alt="Alt Text":) @]%0a--%3c [@ (:input select name=xyz value="val1" label="Value 1":) @]%0a--%3c [@ (:input select name=xyz value="val2" label="Value 2":) @]%0a-%3c [@ (:input end:) @]%0a%0aSee also [[PmWiki/Forms#pageeditcontrols|PmWiki Edit forms]].%0a%0a!! [[#WikiTrails]] Wiki trails%0a%0aSee [[Wiki trails]]%0a-%3c [@%3c%3c|[[TrailPage]]|>>@]%0a-%3c [@%3c|[[TrailPage]]|>@]%0a-%3c [@^|[[TrailPage]]|^@]%0a%0a%0a!! [[#PageVariables]] Page variables%0a%0aSee [[Page variables]], [[Page text variables]], [[PmWiki/PageLists#pagetextvariables|Page lists]]%0a-%3c [@ {@]''[@$variable@]''[@} @]%0a-%3c [@ {@]''[@pagename$variable@]''[@} @]%0a-%3c [@ (:name:description:) @] [-sets a [[page text variable(s)]]-]%0a%0a%0a!! [[#Expressions]] Expressions%0a%0aSee [[Markup expressions]]%0a-%3c [@ {(@]''[@function args@]''[@)} @]%0a%0a%0a
+time=1258098471
+title=Markup Master Index
diff --git a/wikilib.d/PmWiki.Notify b/wikilib.d/PmWiki.Notify
new file mode 100644
index 0000000..b8fc8d9
--- /dev/null
+++ b/wikilib.d/PmWiki.Notify
@@ -0,0 +1,12 @@
+version=pmwiki-2.2.8 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.6) Gecko/20091215 Ubuntu/9.10 (karmic) Firefox/3.5.6
+author=Petko
+charset=ISO-8859-1
+csum=fix link for a release
+ctime=1149115706
+host=81.65.12.233
+name=PmWiki.Notify
+rev=69
+targets=PmWiki.LocalCustomizations,SiteAdmin.NotifyList,PmWiki.PageLists,PmWiki.WikiTrails,PmWiki.UTF-8,PITS.01159
+text=(:Summary:Allows a site administrator to configure PmWiki to send email messages whenever pages are changed on the wiki site:)%0a(:Audience: administrators (basic) :)%0aThe ''notify.php'' script allows a site administrator to configure PmWiki to send email messages whenever pages are changed on the wiki site. Notifications can be configured so that multiple page changes over a short period of time are combined into a single email message (to avoid flooding mailboxes).%0a%0aThis feature is useful for sites and pages that have infrequent updates, as it eliminates the need to frequently check `RecentChanges pages just to see if anything has changed.%0a%0aIn order for notifications to work, the notify.php script must be enabled in the site's [[local customization(s)]]. Usually this is as simple as placing the following in ''local/config.php'':%0a%0a->$EnableNotify = 1;%0a%0a!! Notification configuration%0aOnce enabled, the notification system gets its configuration from the [[SiteAdmin.NotifyList]] wiki page. The SiteAdmin.NotifyList page contains entries of the form:%0a%0a->notify=alice@example.com%0a%0aThis says that information about page changes should be periodically emailed to ''alice@example.com''. The SiteAdmin.NotifyList page can contain multiple "notify=" lines to cause notifications to be sent to multiple addresses; the "notify=" lines can be concealed by placing them inside of an [@(:if false:)@] conditional section on the page.%0a%0aNOTE: Do not put any spaces around the equal sign! Notifications will fail silently if you have%0a->notify = fred@example.com%0arather than%0a->notify=fred@example.com%0a(:comment this is a really easy mistake to make because all of the other assignments have spaces around the equal sign.:)%0a%0a!! Notification options%0aThe basic syntax is %0a->@@notify=''email@address'' \%0a [[#notifyname|name]]=''abc'' \%0a [[#notifygroup|group]]=''def'' \%0a [[#notifytrail|trail]]=''ghi'' \%0a [[#notifysquelch|squelch]]=''123'' \%0a [[#notifydelay|delay]]=''123'' \%0a @@%0a%0aA number of options exist for limiting the pages that result in a notification. The [@group=@] and [@name=@] parameters can be used to restrict notifications to specific pages or groups:%0a%0a[[#notifygroup]]%0a-># send notifications about the Main group to alice@example.com%0a->notify=alice@example.com '''group'''=Main%0a%0a[[#notifyname]]%0a-># notify bob@example.com of any changes to the home page%0a->notify=bob@example.com '''name'''=Main.HomePage%0a%0a-># notify charles@example.com of changes to pages except in Main%0a->notify=charles@example.com '''group'''=-Main%0a%0a(Note: The options are similar to [[PmWiki/PageLists | the PageList syntax]].)%0a%0a[[#notifytrail]]%0aFor maintaining arbitrary lists of pages, i.e., "watchlists", it's generally easier to build a [[trail -> WikiTrails]] of pages to be watched. The following entry in SiteAdmin.NotifyList will send alice@example.com an email containing changes to any of the pages listed in the Profiles.Alice trail:%0a%0a-># notify Alice of changes to pages listed in Profiles.Alice%0a->notify=alice@example.com '''trail'''=Profiles.Alice%0a%0aNote that once this entry has been added to SiteAdmin.NotifyList, Alice can easily change her watchlist by editing the Profiles.Alice page, and doesn't need to edit the SiteAdmin.NotifyList page. In particular, this means that an administrator can restrict editing of SiteAdmin.NotifyList, yet allow individuals to maintain custom watchlists in other pages. %0a%0aLimitations of this feature:%0a* only manually-added links on a trail will be acknowledged by the Notify List (no "group=" or other pagelist syntax, nor any "Group.RecentChanges" links, will generate notifications)%0a* using an [@(:include:)@] directive on the page SiteAdmin.NotifyList is not an operational work-around.%0a%0aThis is probably a good place to point out that edit access to SiteAdmin.NotifyList should be controlled, otherwise malicious persons can use the notification capability to flood others' electronic mailboxes. By default, SiteAdmin.NotifyList is blocked against reading or edits except by the admin (as is the case for most pages in the SiteAdmin group).%0a%0a!! Adding notification entries via local customizations%0a%0aNotification entries can also be added via the $NotifyList array in ''local/config.php''. Simply add a line like the following:%0a->$EnableNotify = 1;%0a->$NotifyList[] = 'notify=alice@example.com group=Main';%0a->$NotifyList[] = 'notify=bob@example.com name=Main.HomePage';%0a%0a[[#controlling_notification_frequency]]%0a[[#notifysquelch]]%0a!! Controlling notification frequency%0a%0aTo prevent flooding of recipients' mailboxes, the notify script uses a "'''squelch'''" value as the minimum amount of time that must elapse between messages sent to any given email address. The ''default squelch setting is 10800 seconds (three hours)'', which means that once a recipient address is sent a notification message, it will not receive another for at least three hours. Any edits that occur during the squelch interval are queued for the next notification message.%0a%0aThe site administrator can change the default squelch interval via the $NotifySquelch parameter %0a%0a-># enable notifications%0a->$EnableNotify = 1;%0a->$NotifySquelch = 86400; # wait at least one day (in seconds) between notifications%0a%0aIn addition, individual addresses can specify a custom squelch parameter in the SiteAdmin.NotifyList page:%0a%0a-># Alice receives at most one email per day%0a->notify=alice@example.com '''squelch'''=86400%0a%0a-># Bob can get notifications hourly%0a->notify=bob@example.com trail=Profiles.Bob '''squelch'''=3600%0a%0a-># Charles uses the site default squelch%0a->notify=charles@example.com %0a%0a[[#notifydelay]]%0a!! Controlling notification delay%0aBecause a page will often receive several edits in rapid succession (e.g., a long post followed by several minor edits), a site administrator can also set a $NotifyDelay value that specifies how long to wait after an initial post before sending notifications:%0a%0a-># enable notifications%0a->$EnableNotify = 1;%0a->$NotifySquelch = 86400; # wait at least one day between notifications%0a->$NotifyDelay = 300; # wait five minutes after initial post%0a%0aNote that the squelch and delay values are minimums; notifications are sent on the first execution of PmWiki after the delay period has expired. For inactive sites, this could be much longer than the specified delay periods. This isn't really considered an issue since timely notifications are less important on relatively inactive sites. However, changes within the squelch time after the last notification will remain unnoticed if the wiki is not even visited for a long period after. If this matters it might be necessary to make the server call pmwiki.php regularly (e.g. [[Wikipedia:Cron | cron job]]).%0a%0aCustom delay parameters cannot be specified for individual addresses in the [[SiteAdmin.NotifyList]] page:%0a%0a-># the @@delay=@@ parameter will be ignored%0a->notify=edgar@example.com trail=Profiles.Edgar '''delay'''=600%0a%0a!! Note for Windows installations%0a%0aSites running PHP under Windows may not have PHP's [[http://php.net/mail | mail]] function configured correctly. Such sites may need to add a line like%0a%0a->ini_set('SMTP','smtp.server.com');%0a%0ato ''config.php'', where ''smtp.server.com'' is the name of your host's preferred outgoing mail server. You may also need to set the sendmail_from value if that is not configured:%0a%0a->ini_set('sendmail_from','noreply@foo.com');%0a%0a%0a!![[#variables]] Notify Variables%0a%0a:$EnableNotify:Tells ''stdconfig.php'' to enable the notify script.%0a: :$EnableNotify = 1; # enable notify%0a: :$EnableNotify = 0; # disable notify%0a%0a:$NotifyFrom:Return email address to be used in the sent email.%0a: :$NotifyFrom = 'wiki@example.com';%0a: :$NotifyFrom = 'Wiki server %3cwiki@example.com>';%0a%0a:$NotifyDelay:The length of time (seconds) to wait before sending mail after the first post. Defaults to zero - posts are sent as soon as any squelch period has expired.%0a: :$NotifyDelay = 300; # send mail 5+ min after first post%0a%0a:$NotifySquelch:The default minimum time (seconds) that must elapse between sending mail messages. Useful when $NotifyDelay is set to a small value to keep the number of mail notification messages down. Defaults to 10800 (three hours). Individual recipients can override this value in the SiteAdmin.NotifyList page.%0a: :$NotifySquelch = 43200; # wait 12+ hours between mailings%0a%0a:$NotifyItemFmt:The text to be sent for each changed item in the post. The string "$PostTime" is substituted with the time of the post (controlled by $NotifyTimeFmt below).%0a: :# default%0a: :$NotifyItemFmt = ' * $FullName . . . $PostTime by $Author';%0a%0a: :# include the page's URL in the message%0a: :$NotifyItemFmt =%0a: :" * \$FullName . . . \$PostTime by \$Author\n \$PageUrl";%0a%0a: :# include the change summary and link to the page's history in the message%0a: :$NotifyItemFmt = %0a: :" * {\$FullName} . . . \$PostTime by {\$Author}%0a: :\n Summary: {\$LastModifiedSummary}\n {\$PageUrl}?action=diff";%0a%0a%0a:$NotifyTimeFmt:The format for dates/times in $PostTime above. Defaults to the value of $TimeFmt.%0a: :$NotifyTimeFmt = [='%25Y-%25m-%25d %25H:%25M'=]; # 2004-03-20 17:44%0a%0a:$NotifyBodyFmt:The body of the message to be sent. The string "$NotifyItems" is replaced with the list of posts (as formatted by $NotifyItemFmt above). Use single quotation marks ' to prevent substring "$NotifyItems" from being untimely evaluated as variable in config.php. %0a: :$NotifyBodyFmt = "Changed items:\n\n" . '$NotifyItems' . "\n\n Best regards...";%0a%0a:$NotifySubjectFmt:The subject line of the mail to be sent.%0a%0a:$NotifyHeaders:String of extra mail headers to be passed to the mail() function.%0a%0a:$NotifyParameters:String of additional parameters to be passed to PHP's mail() function [[http://www.php.net/mail|#]].%0a%0a:$NotifyFile:The scratch file where Notify keeps track of recent posting information. Defaults to @@[="$WorkDir/.notifylist"=]@@. Note that this file must generally be writable by the webserver process.%0a%0a:$NotifyListPageFmt:The name of the page containing [@notify=@] lines for use by ''notify.php''. Defaults to [@$SiteAdminGroup.NotifyList@].%0a%0a:$NotifyList:An array of [@notify=@] specifications that can be specified from a local customization file (used in addition to entries in SiteAdmin.NotifyList).%0a: :# send notifications to alice@example.com%0a: :$NotifyList[] = 'notify=alice@example.com';%0a%0a:$EnableNotifySubjectEncode:Apply a standard (base64) encoding for the e-mail subject. Notify e-mails from international wikis may otherwise have unreadable subjects (added for version 2.2.2).%0a: :$EnableNotifySubjectEncode = 1; # encode subject%0a: :$EnableNotifySubjectEncode = 0; # use subject as is (default)%0a: : To fix encodings with the message body, add to config.php the following line (after XLPage and/or [[UTF-8]]):\\%0a @@$NotifyHeaders = "Content-type: text/plain; charset=$Charset";@@%0a%0a!! Notification only for major edits%0a%0aIt is possible to send notifications only in case of major edits. In your config.php, replace "$EnableNotify=1;" with the following: %0a%0aif ( @$_POST['diffclass'] != 'minor' ) $EnableNotify=1;%0a%0aThis way, only 'major' edits send notify messages (when the author doesn't select the checkbox for minor edit). If you want minor edits and not major edits to send the message then you would use:%0a%0aif ( @$_POST['diffclass'] == 'minor' ) $EnableNotify=1;%0a%0ainstead.%0a%0a!! Disabling notifications for downloads%0a%0aIf you use "$EnableDirectDownloads=0;" (eg. for privacy on a password-protected wiki) then attached images may generate duplicate notification messages. To prevent that disable notifications for downloads via%0a%0aif ( $action != 'download' ) $EnableNotify=1;%0a%0aThat way, only page views (and not images within the page) will generate notifications. See PITS:01159 for more information.%0a
+time=1263683730
diff --git a/wikilib.d/PmWiki.OtherVariables b/wikilib.d/PmWiki.OtherVariables
new file mode 100644
index 0000000..c28f56e
--- /dev/null
+++ b/wikilib.d/PmWiki.OtherVariables
@@ -0,0 +1,11 @@
+version=pmwiki-2.2.2 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.19) Gecko/20081216 Ubuntu/8.04 (hardy) Firefox/2.0.0.19
+author=Petko
+charset=ISO-8859-1
+csum=$MaxPageTextVars
+host=81.65.14.164
+name=PmWiki.OtherVariables
+rev=69
+targets=PmWiki.FmtPageName,PmWiki.PageVariables,PmWiki.PageTextVariables
+text=(:Summary:Variables not yet classified:)%0a[[#FmtV]]%0a:$FmtV: %0a: :This variable is an array that is used for string substitutions at the end of a call to @@[[FmtPageName]]()@@. For each element in the array, the "key" (interpreted as a string) will be replaced by the corresponding "value". The variable is intended to be a place to store substitution variables that have frequently changing values (thus avoiding a rebuild of the variable cache making @@[[FmtPageName]]()@@ faster). Also see $FmtP. %25green%25''Values of $FmtV are set by the internal functions FormatTableRow, LinkIMap, HandleBrowse, PreviewPage, HandleEdit, PmWikiAuth, and PasswdVar, apparently to set values for system generated string substitutions like PageText.''%25%25%0a%0a[[#FmtP]]%0a:$FmtP:%0a: :This variable is an array that is used for pattern substitutions near the beginning of a call to [@FmtPageName@]. For each element in the array, the "key" (interpreted as a pattern) will be replaced by the corresponding value evaluated for the name of the current page. This is for instance used to handle $-substitutions that depend on the pagename passed to [@FmtPageName()@]. Also see $FmtV. %25green%25From robots.php: ''If $EnableRobotCloakActions is set, then a pattern is added to $FmtP to hide any "?action=" url parameters in page urls generated by PmWiki for actions that robots aren't allowed to access. This can greatly reduce the load on the server by not providing the robot with links to pages that it will be forbidden to index anyway.''%0a%0a%0a[[#FmtPV]]%0a:$FmtPV:%0a: :This variable is an array that is used for defining [[Page Variables]]. New variables can be defined with [@$FmtPV['$VarName'] = 'variable definition';@] which can be used in markup with [@{$VarName}@]. Please note that the contents of [@$FmtPV['$VarName']@] are [@eval()@]ed to produce the final text for [@$VarName@], so the contents must be a PHP expression which is valid at the time of substitution. In particular, %25red%25this does not work:%25%25%0a%0a:: :%25red%25[@#This doesn't work@]%25%25%0a:: :[@$FmtPV['$MyText'] = "This is my text."; # WARNING: Doesn't work!@]%0a%0a: :The problem is that the text %25blue%25[@This is my text.@]%25%25 is not a valid PHP expression. To work it would need to be placed in quotes, so that what actually gets stored in [@$FmtPV['$MyText']@] is %25blue%25[@"This is my text."@]%25%25 which '''is''' a valid PHP expression for a text string. Thus the correct way to do this would be with an extra set of quotes:%0a%0a:: :[@#This will work@]%0a:: :[@$FmtPV['$MyText'] = '"This is my text."';@]%0a%0a: :This also has implications for how internal PHP or PmWiki variables are accessed. To have the page variable [@$MyVar@] produce the contents of the internal variable [@$myvar@], many folks try the following %25red%25which does not work:%25%25%0a%0a:: :%25red%25[@#This doesn't work either!@]%0a:: :[@$myvar = SomeComplexFunction();@]%0a:: :[@$FmtPV['$MyVar'] = $myvar; # WARNING: Doesn't work!@]%0a%0a: :There are several correct ways to do this, depending on whether you need the value of the [@$myvar@] variable as it was at the time the [@$FmtPV@] entry was created, or at the time that a particular instance of [@$MyVar@] is being rendered on a page. For most simple page variables that don't change during the processing of a page its more efficient to set the value when the entry is created:%0a%0a:: :[@$myvar = SomeComplexFunction();@]%0a:: :[@$FmtPV['$MyVar'] = "'" . $myvar . "'"; #capture contents of $myvar@]%0a%0a: :NOTE: If [@$myvar@] should contain single quotes, the above won't work as is, and you'll need to process the variable to escape any internal quotes.%0a%0a: :For more complex cases where an internal variable may have different values at different places in the page (possibly due to the effects of other markup), then you need to make the [@$FmtPV@] entry make an explicit reference to the global value of the variable (and the variable had better be global) like this:%0a%0a:: :[@global $myvar;@]%0a:: :[@$FmtPV['$MyVar'] = '$GLOBALS["myvar"]';@]%0a%0a: :Finally, there's nothing to stop you from simply having the evaluation of the [@$FmtPV@] entry execute a function to determine the replacement text:%0a%0a:: :[@# add page variable {$Today}, formats today's date as yyyy-mm-dd@]%0a:: :[@$FmtPV['$Today'] = 'strftime("%25Y-%25m-%25d", time() )';@]%0a%0a: :See [[Cookbook:MoreCustomPageVariables]] for more examples of how to use [@$FmtPV@].%0a%0a:$MaxPageTextVars: This variable prevents endless loops in accidental recursive [[PageTextVariables]] which could lock down a server. Default is 500 which means that each PageTextVariable from one page can be displayed up to 500 times in one wiki page.%0a
+time=1246800413
diff --git a/wikilib.d/PmWiki.PageDirectives b/wikilib.d/PmWiki.PageDirectives
new file mode 100644
index 0000000..37e7661
--- /dev/null
+++ b/wikilib.d/PmWiki.PageDirectives
@@ -0,0 +1,13 @@
+version=pmwiki-2.2.8 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.6) Gecko/20091215 Ubuntu/9.10 (karmic) Firefox/3.5.6
+author=Petko
+charset=ISO-8859-1
+csum=see also $EnablePageTitlePriority
+description=PmWiki Page Directives
+host=81.65.12.233
+keywords=description, keywords, markup, header, redirect
+name=PmWiki.PageDirectives
+rev=80
+targets=PmWiki.Uploads,PmWiki.LayoutVariables,PmWiki.GroupHeaders,PmWiki.Skins,PmWiki.Links,PmWiki.IncludeOtherPages
+text=(:description PmWiki Page Directives:)(:Summary: Directives to specify page titles, descriptions, keywords, and display:)(:Keywords description, keywords, markup, header, redirect:)%0aPmWiki uses a number of directives to specify page titles, descriptions, page keywords, and control the display of various components.%0aKeywords are not case sensitive.%0a%0a[[#attachlist]]%0a:[@(:attachlist:)@]:%0a->Shows a list of attachments of the current group or page, depending on whether attachments are organised per group or per page. The attachlist is displayed at the foot of the [[uploads]] page form.%0a->The parameter to [=(:attachlist:)=] always resolves to a pagename. The directive then displays all of the attachments currently available for that page.%0a%0a::Options: [@(:attachlist NAME:)@] shows a list of attachments of the group or page NAME. %0a-->[@(:attachlist ext=xxx:)@] specifies an extension for filtering by type of file. %0a-->[@(:attachlist *:)@] shows the uploads directory and permits browsing of all uploaded files by directory (''will not work if $EnableDirectDownload is set to 0'').%0a%0a[[#description]]%0a:[@(:description text:)@]:Descriptive text associated with the page. (Generates a [@%3cmeta name='description' content='...' />@] element in the page output.)%0a%0a[[#keywords]]%0a:[@(:keywords word1, word2, ...:)@]:Identifies keywords associated with the page. These are not displayed anywhere, but are useful to help search engines locate the page. (Essentially, this generates a [@%3cmeta name='keywords' content='...' />@] element in the output.)%0a%0a[[#linebreaks]]%0a:[@(:linebreaks:)@], [@(:nolinebreaks:)@]: Honors any newlines in the markup; i.e., text entered on separate lines in the markup will appear as separate lines in the output. Use [@(:nolinebreaks:)@] to cause text lines to automatically join again.%0a%0a[[#linkwikiwords]]%0a:[@(:linkwikiwords:), (:nolinkwikiwords:)@]: Enables/disables WikiWord links in text.%0a%0a[[#markup]]%0a:[@(:markup:) ... (:markupend:)@] or [@(:markup:)@][@[=...=]@]: Can be used for markup examples, showing first the markup and then the result of the markup. %0a%0a::Options: [@(:markup class=horiz:)@] will show the markup side by side instead of one upon the other.%0a-->[@(:markup caption='...':)@] adds a caption to the markup example.%0a-->[@(:markupend:)@] is not required when using [@(:markup:)@] [@[=...=]@].%0a%0a->''Note'' that the placement of newlines is very important for this markup. If you are using the [@[=...=]@] option then the opening [@[=@] MUST occur on the same line as the [@(:markup:)@]. If you are using the full [@(:markup:) ... (:markupend:)@] form then your markup code must appear AFTER a newline after the initial [@(:markup:)@].%0a%0a[[#message]]%0a:[@(:messages:)@]: Displays [[PmWiki/LayoutVariables#MessagesFmt|messages]] from PmWiki or recipes, for instance from editing pages.%0a%0a%0a[[#noaction]]%0a:[@(:noaction:)@]: Turns off the section of the skin marked by %3c!--PageActionFmt--> thru %3c!--/PageActionFmt-->. In the pmwiki skin, this turns off the display of the actions at the top-right of the page (other skins may locate the actions in other locations).%0a%0a[[#nogroupheader]]%0a:[@(:nogroupheader:)@]:%0a:[@(:nogroupfooter:)@]: Turns off any groupheader or groupfooter for the page. (See [[GroupHeaders]].)%0a%0a[[#noheader]]%0a:[@(:noheader:), (:nofooter:)@]: %0a:[@(:noleft:), (:noright:), (:notitle:)@]: If supported by the [[skin(s)]], each of these turns off the corresponding portion of the page.%0a%0a[[#redirect]]%0a:[@(:redirect PageName:)@]: Redirects to another wiki page.%0a:[@(:redirect PageName#anchor:)@]: Redirects to an [[PmWiki/Links#anchors|anchor]] within a page%0a:[@(:redirect PageName status=301 from=name quiet=1:)@]:Redirects the browser to another page, along with a redirect message. For security reasons this only redirects to other pages within the wiki and does not redirect to external urls. The [@status=@] option can be used to return a different HTTP status code as part of the redirect. The [@from=@] option limits redirects to occuring only on pages matching the wildcarded ''name'' (helpful when [@(:redirect:)@] is in [[include other pages|another page]]). The [@quiet=1@] option allows the target page not to display a link back to the original page ($EnableRedirectQuiet variable should be set to 1).%0a%0a[[#spacewikiwords]]%0a:[@(:spacewikiwords:), (:nospacewikiwords:)@]:%0a->Enables/disables automatic spacing of WikiWords in text.%0a%0a[[#title]]%0a:[@(:title text:)@]: Sets a page's title to be something other than the page's name. The title text can contain apostrophes and other special characters. If there are multiple titles in a page, the last one encountered wins (see also $EnablePageTitlePriority about how to change it).%0a%0a[[#nl]]%0a:[@(:nl:)@]:Creates a new line if there isn't one already there. See [[http://thread.gmane.org/gmane.comp.web.wiki.pmwiki.user/15031/focus=15079 | this thread]] for more info.%0a: : Similar to [@[[%3c%3c]]@]%0a%0a%0a%0a>>faq%3c%3c [[#faq]]%0aQ: Can I get [@(:redirect:)@] to return a "moved permanently" (HTTP 301) status code?%0aA: Use [@(:redirect PageName status=301:)@].%0a%0aQ: Is there any way to prevent the "redirected from" message from showing at the top of the target page when I use [@(:redirect:)@]?%0aA: From version 2.2.1 on, set in config.php @@$EnableRedirectQuiet=1;@@ and in the page @@[=(:redirect OtherPage quiet=1:)=]@@ for a quiet redirect.%0a%0aQ: Is there any method for redirecting to the equivalent page in a different group, i.e. from BadGroup/thispage => GoodGroup/thispage using similar markup to (:redirect Goodgroup.{Name}:)?%0aA:%0a->[=(:redirect Goodgroup.{$Name}:)=] works if you want to put it in one page. %0a%0a->If you want it to work for the entire group, put [=(:redirect Goodgroup.{*$Name}:)=] into Badgroup.GroupHeader - however, that only works with pages that really exist in Goodgroup; if you visit a page in Badgroup without a corresponding page of the same name in Goodgroup, instead of being redirected to a nonexistant page, you get the redirect Directive at the top of the page.%0a%0a->With [=(:if exists Goodgroup.{*$Name}:)(:redirect Goodgroup.{*$Name}:)(:ifend:)=] in Badgroup.GroupHeader you get redirected to Goodgroup.Name if it exists, otherwise you get Badgroup.Name without the bit of code displayed.
+time=1263764403
diff --git a/wikilib.d/PmWiki.PageFileFormat b/wikilib.d/PmWiki.PageFileFormat
new file mode 100644
index 0000000..ca494e0
--- /dev/null
+++ b/wikilib.d/PmWiki.PageFileFormat
@@ -0,0 +1,11 @@
+version=pmwiki-2.2.5 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.19) Gecko/20081216 Ubuntu/8.04 (hardy) Firefox/2.0.0.19
+author=Petko
+charset=ISO-8859-1
+csum=mv non-FAQ section to talk
+host=86.69.109.9
+name=PmWiki.PageFileFormat
+rev=46
+targets=SiteAdmin.Status
+text=(:Summary:Create wiki formatted pages in bulk and for upload to your pmwiki site:)%0aYou may have many documents that you would like to use a local program to format in a format PmWiki can display.%0a%0aYou could open each document and copy/paste the content to new pmwiki pages or you could format the document in advance and upload it using a FTP client.%0a%0aOnly two lines are necessary in a PmWiki page file:%0a%0a->[@%0aversion=pmwiki-2.1.0 urlencoded=1%0atext=Markup text%0a@]%0a%0a"version=" tells PmWiki that the values are urlencoded. The actual value doesn't matter, as long as "urlencoded=1" appears somewhere in the line.%0a%0a"text=" ''needs'' to have the markup text with newlines converted to "%250a" and percent signs converted to "%2525".%0a%0a-> In addition, ''PmWiki writes'' pages with '%3c' encoded as "%253c" (to help with security), but it doesn't require that %3c's be encoded that way in order to be able to read the page. More conversions are possible to be added in the future.%0a%0aIn order to let the [@(:pagelist :)@] markup work, make sure the filename begins with an uppercase letter.%0a%0aIn order to have the [@(:pagelist link= ... :)@] markup on other pages list this page, a third attribute is required:%0a%0a->[@%0atargets=GroupName1.Pagename1,GroupName2.Pagename2,...%0a@]%0a%0a"targets=" is a comma delimited list of all links from the current page.%0a%0a----%0a%0aKeys you could see in a raw PmWiki file:%0a%0a:'''version''': Version of PmWiki used to create the file %25comment%25 More??? (ordered, urlencoded)%25%25%0a:'''agent''': Author's browser when saving the page%0a:'''author''': Last author to save page%0a:'''charset''': The character encoding of the page text, may be used by future upgrades%0a:'''csum''': Change summary%0a:'''ctime''': Page creation time%0a:'''host''': Host created this page%0a:'''name''': Name of the page (e.g., [@Main.WikiSandbox@])%0a:'''rev''': Number of times the page has been edited%0a:'''targets''': Targets for links in the page%0a:'''text''': The page's wiki markup%0a:'''time''': Time the page was last saved (seconds since 1 Jan 1970 00:00 UTC)%0a:'''title''': Page title set via [@(:title The Page Title:)@].%0a:'''newline''': Character used for newlines (deprecated)%0a:'''passwdedit''': encrypted version of the password%0a:'''updatedto''': The version to which PmWiki has been updated to by [@upgrades.php@] (only on [[SiteAdmin.Status]])%0a%0aBelow these you will see information used to keep track of the page's revision history.%0a%0a!![[#creating]] Creating a Page for Distribution%0a%0aA simple way to create a wikipage file to use for distribution (for example with a recipe or a skin) is to create the page with PmWiki and then use a text editor to delete all lines but ''version'', ''text'', and ''ctime''. Example:%0a%0a->[@%0aversion=pmwiki-2.1.0 ordered=1 urlencoded=1%0atext=This is a line.%250aThis is another.%0actime=1142030000%0a@]%0a%0a!! Keeping track of page history%0a%0aInside of a page file, PmWiki stores the latest version of the markup text, and uses this to render the page. The page history is kept as a sequence of differences between the latest version of the page and each previous version.%0a%0aPmWiki normally puts the page history at the end of each page file in reverse chronological sequence, and sets the "ordered=1" items in the header. If an operation needs only the most recent version of a page, then PmWiki will stop reading and processing a page file at the point where the history begins, potentially saving a lot of time and memory. If the "ordered=1" flag isn't present, PmWiki makes no assumptions about the ordering of items in the pagefile and processes the entire file.%0a%0a!! Load pages from text files%0aSee [[Cookbook: Import text]]. {Cookbook/ImportText$:Summary}%0a%0a!! Unix utility to extract wiki text%0a%0aThe following unix script (tested on MacOSX) will extract and decode the current text from a wiki file:%0a%0a->[@%0a#!/bin/tcsh%0a# wtext - extract wiki text%0a#%0a# wtext wikifile > output%0a%0aset fn = "$1"%0aif ("$fn" == "") then%0a echo "need input file parameter"%0a exit 999%0aendif%0aif (! -f $fn) then%0a echo "$fn does not exist"%0a exit 999%0aendif%0arm sedin.$$ >& /dev/null%0aset ch = `grep ^newline= $fn | cut -d= -f2`%0aif ("$ch" == "") set ch = "%250a"%0acat %3c%3ceof > sedin.$$%0as/^text=//%0as/$ch/\%0a/g%0as/%253c/%3c/g%0as/%2525/%25/g%0aeof%0agrep "^text=" "$1" | sed -f sedin.$$%0arm sedin.$$ >& /dev/null%0a@]%0a%0a----%0a%0a%0a!!See also%0a* [[Cookbook:AdminByShell]] [-A collection of ways to assist sysadmin of pmwiki using shell tools-]%0a* [[Cookbook:PageTopStore]] [-A PageStore alternative which doesn't mangle page contents when viewed outside PmWiki-]%0a
+time=1251288392
diff --git a/wikilib.d/PmWiki.PageHistory b/wikilib.d/PmWiki.PageHistory
new file mode 100644
index 0000000..068e30f
--- /dev/null
+++ b/wikilib.d/PmWiki.PageHistory
@@ -0,0 +1,11 @@
+version=pmwiki-2.2.12 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.7) Gecko/20100106 Ubuntu/9.10 (karmic) Firefox/3.5.7
+author=Petko
+charset=ISO-8859-1
+csum=updated for 2.2.13, see also Cookbook:ViewDiff
+host=81.65.12.233
+name=PmWiki.PageHistory
+rev=37
+targets=PmWiki.WikiAdministrator,Cookbook.ExpireDiff,Cookbook.LimitDiffsPerPage,Cookbook.ViewDiff,Cookbook.TrackChanges,PmWiki.PageFileFormat
+text=(:Summary: History of previous edits to a page:)%0a(:Audience: authors (basic) :)%0aWhen PmWiki is called with '?action=diff', it displays a summary of past edits on a page. Each past edit is shown in a box which shows lines added, changed or deleted during that edit in a before & after format.%0a%0aBelow each box is a "Restore" link. Clicking the link will open an edit box with the page as it was ''before'' that edit. You can make changes or simply click Save to restore the text.%0a%0aThere are two additional options specific to Page''''History:%0a%0a* '''Hide minor edits''' - hides any edit that the author marked as 'minor'. - This is done by adding "&minor=n" to "?action=diff". The default value for this is to show minor edits with "&minor=y"%0a%0a* '''Show changes to output''' - It shows changes to the rendered output (as opposed to the normal display which shows changes to the wiki-markup). This is done by adding "&source=n" to "?action=diff". You can show changes to markup (the default behavior from 2.2.13) with "&source=y".%0a%0a* You can set both by using "?action=diff&source=y&minor=y".%0a%0aIn the default mode "Show changes to markup", you can disable word-level highlighting of differences by adding to config.php such a line:%0a $EnableDiffInline = 0;%0a%0aA page's history is kept for the number of days given by the $DiffKeepDays and $DiffKeepNum variables (set by the site's [[wiki administrator]]). When a page is edited, any page history information older than both these values is automatically discarded.%0a%0aNote that a specific page revision isn't removed from the page until the first edit ''after'' the time specified by $DiffKeepDays has elapsed. Thus, it's still possible for some pages to have revisions older than $DiffKeepDays -- such revisions will be removed the next time those pages are edited.%0a%0a!! See also%0a* Cookbook:ExpireDiff%0a* Cookbook:LimitDiffsPerPage%0a* Cookbook:ViewDiff%0a* Cookbook:TrackChanges%0a%0a>>faq%3c%3c [[#faq]]%0a%0aQ: [[#removepagehistory]] Is there a way to remove page history from page files?%0aA: 1. Administrators can clean page histories using the Cookbook:ExpireDiff recipe. %0a%0aA: 2. Administrators with FTP file access can download individual pages from the wiki.d directory, open them in a text editor, manually remove history, and re-upload the files to wiki.d/ directory. Care must be exercised, when manually editing a page file, to preserve the minimum required elements of the page and avoid corrupting its contents. See [[PmWiki/PageFileFormat#creating]].%0a%0aA: 3. Edit the page. Select ''all'' the contents of the edit text area and cut them to the clipboard. Enter @@delete@@ into the text area and click on the ''save and edit'' button. Select ''all'' the contents of the edit text area and paste the contents of the clipboard over them. Click on the ''save'' button. This will remove all of the page's history up to the final save in which the pasted material is re-added.%0a%0aQ: [[#restrictpagehistory]] How can I restrict viewing the page history [@(?action=diff)@] to people with edit permission?%0aA: In the ''local/config.php'' file, set%0a%0a->[@$HandleAuth['diff'] = 'edit'@];%0a%0aIn case of this restriction is set up on a farm, and you want to allow it on a particular wiki, set in your local/config.php :%0a%0a->[@$HandleAuth['diff'] = 'read'@];%0a
+time=1266768820
diff --git a/wikilib.d/PmWiki.PageListTemplates b/wikilib.d/PmWiki.PageListTemplates
new file mode 100644
index 0000000..1273ade
--- /dev/null
+++ b/wikilib.d/PmWiki.PageListTemplates
@@ -0,0 +1,12 @@
+version=pmwiki-2.2.10 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/532.5 (KHTML, like Gecko) Chrome/4.0.249.78 Safari/532.5
+author=simon
+charset=ISO-8859-1
+csum=special references
+ctime=1176759249
+host=202.37.32.2
+name=PmWiki.PageListTemplates
+rev=29
+targets=PmWiki.PageLists,Site.PageListTemplates,Site.LocalTemplates,Cookbook.PagelistTemplateSamples,PmWiki.PageVariables,PmWiki.PageTextVariables,Cookbook.DictIndex,Cookbook.SimpleForum,Cookbook.Cookbook
+text=(:Summary: Creating [[PmWiki/page list(s)]] format templates:)%0a!! Default [[page list(s)]] templates%0a%0aPmWiki's default templates for [[page lists]] are in [[Site.PageListTemplates]], which is replaced during upgrades. %0aThese default templates can be supplemented or overridden with custom templates stored in other locations. %0a %0aIf the page name is not specified as part of the template name, PmWiki's default configuration looks for templates in the following locations in the following order%0a# the current page%0a# [[Site.LocalTemplates]], %0a# [[Site.PageListTemplates]]%0aAdministrators can change those locations by using the $FPLTemplatePageFmt variable. %0a%0aIf the template is on the current page, the current page must be saved for changes involving the template to show up ''(preview alone will not work)''.%0a%0a!! Custom page list templates%0aCustom templates are used in the same way as default templates: by referencing the desired format with the @@fmt=#''anchor''@@ option. %0aThere are several ways to indicate which template to use:%0a* [@fmt=#custom@] uses the #custom section from the current page, [[Site.LocalTemplates]], or [[Site.PageListTemplates]], (sections are denoted by [@[[#custom]]@] anchors.%0a* [@fmt=MyTemplatePage#custom@] uses a custom format from page @@MyTemplatePage@@ from its @@#custom@@ section.%0a* [@fmt=MyTemplatePage@] uses a custom format from the entire page @@MyTemplatePage@@.%0a* [@fmt=custom@] uses custom format which is defined in a cookbook script as ''custom''.%0a%0aSee Cookbook:PagelistTemplateSamples for examples of custom pagelist formats.%0a%0a!! Creating page list templates%0aA pagelist template contains standard pmwiki markup. %0aWhen creating pagelist output, pmwiki iterates over each page returned from the pagelist and will include the pagelist template markup once for every page in the list. %0a%0a[[#specialreferences]]%0a!!! Special references %0aDuring the page list iteration pmwiki sets 3 special page references: '''=''', '''%3c''' and '''>'''. %0aThese special page references are updated on each pagelist iteration and can be used with the [[page variables]] syntax, such as ''{=$variable}'', to define a pagelist template which will format the pagelist output. The meaning of the special references are:%0a||width=*%0a|| = ||current page ||so ''[@{=$Title}@]'' ||displays the title of the current page in the iteration%0a|| %3c ||previous page ||so ''[@{%3c$Group}@]'' ||displays the group of the previous page in the iteration%0a|| > ||next page ||so ''[@{>$Name}@]'' ||displays the name of the next page in the iteration%0a%0a%0aThe > and %3c references are most useful to help structure pagelist output before and after the actual pagelist. Some common tests used to structure pagelist output are:%0a(:table class=frame:)%0a(:cellnr:)[@(:template first:)@]%0a(:cell:)[- {- [@(:if equal {%3c$Group}:)@] -} -]%0a(:cell:)Iteration is at the beginning of list%0a(:cellnr:)[@(:template last:)@]%0a(:Cell:)[- {- [@(:if equal {>$Group}:)@] -} -]%0a(:cell:)Iteration is at the end of list%0a(:cellnr:)[@(:template first {=$Group}:)@]%0a(:cell:)[- {- [@(:if ! equal {=$Group} {%3c$Group}:)@] -} -]%0a(:cell:)Iteration is at the first item in a group%0a(:cellnr:)[@(:template last {=$Group}:)@]%0a(:cell:)[- {- [@(:if ! equal {=$Group} {>$Group}:)@] -} -]%0a(:cell:)Iteration is at the last item in a group %0a(:cellnr:)[@(:template defaults:)@]%0a(:cell:)%0a(:cell:)Default options to be used in the pagelist command%0a(:cellnr:)[@(:template each:)@]%0a(:cell:)%0a(:cell:)Signifies the repeated part%0a(:tableend:)%0a[[#specialreferencesend]]%0a''Note'': the markup in column 2 is deprecated.%0a-%3c See also [[PageVariables#specialreferences|page variable special references]].%0a%0a!! Page list template special markup%0aPagelist templates may have special %0a* [@(:template first ...:)@]%0a* [@(:template last ...:)@] sections to specify output for the first or last page in the list or a group. %0aThere's also a %0a* [@(:template defaults ...:)@] %0a to allow a template to specify default options,%0a* [@(:template each ...:)@]%0a to signify the repeated part, and%0a* [@(:template none:)@]%0a whose content will appear if no page was found (from version 2.2.5).%0a%0aThese allow Pagelist templates to be easily separated into "sections"%0athat are included or not included in the output based on a variety of%0aconditions. These are intended to be improved versions of the%0a[=(:if ...:)=] conditions that have traditionally been used to control%0apagelist output (however, the [=(:if:)=] conditions still work as before).%0a%0a!!! First, Each, Last, None%0aThe simplest versions of the directives are:%0a-> [@%0a(:template first:) # markup to display only for first page in list%0a(:template each:) # markup to display for each page in list%0a(:template last:) # markup to display only on last page in list%0a(:template none:) # markup to display only if no pages were found@]%0a%0aSo, a pagelist template can specify:%0a%0a->[@(:template first:)%0aPages in the list:%0a(:template each:)%0a* [[{=$FullName}]]%0a(:template last:)%0aDisplayed {$$PageCount} pages.@]%0a%0aIn addition, the "first" and "last" options can have control break%0aarguments that identify markup to be displayed on the first or last%0apage within a particular control section. For example, to specify%0amarkup to be displayed upon reaching the first or last page of%0aa group, one can use%0a%0a->[@(:template first {=$Group}:)%0a(:template last {=$Group}:)@]%0a%0aThus, instead of writing control breaks using (:if:) directives, as in%0a%0a->[@(:if ! equal {%3c$Group} {=$Group}:)%0aGroup: {=$Group}%0a(:ifend:)%0a* [[{=$FullName}]]@]%0a%0aone can now write%0a%0a->[@(:template first {=$Group}:)%0aGroup: {=$Group}%0a(:template each:)%0a* [[{=$FullName}]]@]%0a%0a!!! Default options%0aIn addition, a template may specify default options to be used%0ain the pagelist command. For example, a pagelist template to%0adisplay a list of pages by their titles (and sorted by title)%0amight use:%0a%0a->[@[[#bytitle]]%0a(:template defaults order=title:)%0a* [[{=$FullName}|+]]%0a[[#bytitleend]]@]%0a%0aThen an author could write [=(:pagelist fmt=#bytitle:)=] and the%0apages would automatically be sorted by title without having to%0aspecify an additional "order=title" option to the [=(:pagelist:)=]%0adirective.%0a%0aTo specify multiple parameters to an option enclose the parameters in double quotes, eg to sort by a [[page text variable(s)]] and then the page name%0a-> [@ (:template defaults order="$:Database,name" :) @]%0a%0a!!! Examples%0a:[=(:template defaults ... :)=] : default options for pagelists using this template%0a:[=(:template each:)=] : markup for each page in the pagelist%0a:[=(:template first:)=] : markup output only for the first page in the pagelist%0a:[=(:template last:)=] : markup output only for the last page in the pagelist%0a:[=(:template first {=$Group}:)=] : markup output only for a page where the value of {=$Group} has just changed%0a:[=(:template last {=$Group}:)=] : markup output only for a page where the value of {=$Group} will change with the next page%0a%0aSo, we have:%0a%0a->[@[[#template]]%0a(:template defaults order=name:)%0a(:template first:)%0aPages ordered by group%0a(:template first {=$Group}:)%0a%0aPages in group [[{=$Group}/]]%0a(:template each:)%0a* [[{=$FullName}]]%0a(:template last {=$Group}:)%0a {=$Group} contains {$$GroupPageCount} pages.%0a(:template last:)%0a {$$PageCount} pages total.%0a[[#templateend]] @]%0a%0a!! Page list template additional page variables%0aAdditional [[Page Variables]] that are only available during pagelist are: %0a->[@%0a{$$PageCount} The current page count of this iteration%0a{$$GroupCount} The current group count of this iteration%0a{$$GroupPageCount} The current page count within the current group of this iteration %0a{$$option} The argument option values from (:pagelist:)@]%0a%0aUse of {$$option}: For example {$$trail} returns the page name entered in the trail= option of the pagelist directive. You can make up custom "options" with no other purpose than being displayed in the pagelist.%0a%0a[[#redirect]]%0a!! Redirect %0aTo enable searches that return only one page to automatically redirect to that page add the following to a pagelist template where the "jump to a page" functionality is desired:%0a%0a-> [@(:template last:)%0a(:if equal {$$PageCount} 1:)(:redirect {=$FullName}:)(:ifend:)%0a@]%0a%0a[[#closure]]%0a!! Closure of markup%0aAny open tables, divs, or other%0astructures inside of [=(:pagelist:)=] are, by default, automatically closed at the%0aend of the pagelist command. In other words, [=(:pagelist:)=] acts like%0aits own complete page, as opposed to generating markup that is then%0ainserted into the enclosing page.%0a%0aFor example a table generated by the [=(:cell:)=]%0adirective in the first [=(:pagelist:)=] command is automatically closed%0aat the end of the pagelist. The [=(:cell:)=] in the second [=(:pagelist:)=]%0acommand then starts a new table.%0a%0aNote that the [=(:table:)=] directive doesn't actually start a new table,%0ait's the [=(:cell:)=] or [=(:cellnr:)=] directive that does it. All that the%0a[=(:table:)=] directive does is set attributes for any tables that follow.%0a%0a!! Usage%0aIt is advisable to not modify the page [[Site.PageListTemplates]] directly so that you will still benefit from upgrades. %0aInstead, modify your [[Site.LocalTemplates]] page (which is not part of the PmWiki distribution). Cookbook:PagelistTemplateSamples has many examples of custom pagelist formats.%0a%0a!! Other recipes%0aIn addition, the [[(Cookbook:)Cookbook]] has other recipes for special [@fmt=@] options, including [[Cookbook:DictIndex | [@fmt=dictindex@] ]] (alphabetical index) and [[Cookbook:SimpleForum | [@fmt=forum@] ]] (forum postings).%0a
+time=1265925647
diff --git a/wikilib.d/PmWiki.PageLists b/wikilib.d/PmWiki.PageLists
new file mode 100644
index 0000000..970a98c
--- /dev/null
+++ b/wikilib.d/PmWiki.PageLists
@@ -0,0 +1,12 @@
+version=pmwiki-2.2.7 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (X11; U; Linux i686; en-GB; rv:1.9.1.5) Gecko/20091109 Ubuntu/9.10 (karmic) Firefox/3.5.5
+author=cda
+charset=ISO-8859-1
+csum=
+ctime=1138643894
+host=67.159.26.71
+name=PmWiki.PageLists
+rev=198
+targets=PmWiki.PageListTemplates,PmWiki.DocumentationIndex,PmWiki.PageTextVariables,PmWiki.WikiTrails,Site.PageListTemplates,PmWiki.Categories,PmWiki.ConditionalMarkup,PmWiki.PagelistVariables,PmWiki.PageDirectives
+text=(:Audience: authors, admins (intermediate) :)%0a(:Summary:Listing pages by multiple criteria with templated output:)%0aPmWiki comes with two directives for generating lists of pages -- [@(:pagelist:)@] and @@[=(:=]searchresults:)@@. Both directives are basically the same and each accepts the parameters documented below. The primary difference between the two is that searchresults generates the "Results of search for ..." and "### pages found out of ### searched" messages around the results.%0a%0aThe [@(:searchbox:)@] directive generates a search form (input text box) to submit search queries. The markup generally accepts the same parameters as [@(:pagelist:)@], which makes it possible to restrict, order and format searchresults in the same ways that are described below for a [@(:pagelist:)@]. For more information about the [@(:searchbox:)@] directive, and the ways in which it differs from a [@(:pagelist:)@], skip to the section [[#searchbox|below]].%0a%0a!! Basic syntax%0a%0a* [@(:pagelist:)@] %0a->without any arguments shows a bulleted list of all pages, as links, ordered alphabetically and in groups.%0a* @@[=(:=]pagelist [[#pagelistgroup|group]]=''ab'' \%0a [[#pagelistname|name]]=''cd'' \%0a [[#pagelistfmt|fmt]]=''[[page list templates|template]]'' \%0a [[#pagelistlist|list]]=''ef'' \%0a [[#pagelistorder|order]]=''gh'' \%0a [[#pagelistcount|count]]=''123'' \%0a [[#pagelistlink|link]]=''ij'' \%0a [[#pagelisttrail|trail]]=''kl'' \%0a [[#pagelistwrap|wrap]]=''mn'' \%0a [[#pagelistpasswd|passwd]]=''op'' \%0a [[#pagelistif|if]]=''qr'' \%0a [[#pagetextvariables|$:''ptv'']]=''st'' \%0a [[#pagevariables|$''pv'']]=''uv'' \%0a [[#pagelistcache|cache]]=0 \%0a ''[[#pagelistarg|argument]]1'' -''[[#pagelistarg|argument]]2'' ''etc'' \%0a [[#includevariable|variable]]=''value'' \%0a [[#pagelistclass|class]]=''class'' \%0a :)@@ %0a->shows a pagelist according to the parameters supplied. Parameters are optional.%0a* @@[=(:=][[#searchbox|searchbox]] value=''abc'' size=''99'' target=''def'':)@@%0a* @@[=(:=][[#searchresults|searchresults]] [[#pagelistreq|''request=1 req=1'']] :)@@%0a%0a!! Parameters%0a[[#pagelistarg]]%0aAny argument supplied within [@(:pagelist:)@] that isn't in the form @@'key=value'@@ is treated as text that either must (or must not) exist in the page text.%0a%0aThe minus sign (-) or exclamation mark (!) can be used to indicate the logical ''not''. Thus%0a->[@(:pagelist trail=PmWiki.DocumentationIndex list=normal apple !pie:)@]%0alists all "normal" pages listed in the [[Documentation Index ]] trail that contain the word "apple" but not "pie".%0a%0a!!![[#pagetextvariables]]With page text variables%0aYou can also use [[page text variables]] as a ''key'' to list pages according to the existence of a page text variable. Eg : %0a->[@(:pagelist $:pagetextvar=avalue:)@]%0alists pages having ''$:pagetextvar'' set to ''avalue''.%0a[[%3c%3c]]%0aMinus sign (-), wildcards (?*) and a comma separated list of values also works when specifying a selection based on pagetextvariables. Eg :%0a->[@(:pagelist $:apagetextvar=t*,-test:)@]%0alists pages having $:apagetextvar like 't*' but not 'test'.%0a[[%3c%3c]]%0aExamples:%0a||width=* class="tabtable" rules=rows%0a||PTV is set (is not empty): ||[@(:pagelist $:MyPageTextVariable=- :)@]||%0a||PTV is empty or not set:[[%3c%3c]] (ie, is not set to one char followed by 0 or more chars) ||[@(:pagelist $:MyPageTextVariable=-?* :)@]||%0a||PTV is not VALUE: ||[@(:pagelist $:MyPageTextVariable=-VALUE :)@]||%0a||PTV is set and not YES: ||[@(:pagelist $:MyPageTextVariable=?*,-YES :)@]||%0aBe aware that if using [@(:pagelist $:MyPTV=$:YourPTV :)@] PTVs include PmWiki formatting, so you may not get the matches you expect. Currently the only way around this is to use wild cards, so if the formatting is embedded you may be out of luck.%0a%0a!!![[#pagevariables]]With page variables (PV)%0a%0aPage variables can be used within pagelists in the same way as page text variables. See [[#pagetextvariables|Page Text Variables]] above for more details. Simply use $var instead of $:var.%0a%0a!!![[#pagelistgroup]] group= and [[#pagelistname]]name= %0a%0aThe "[@group=@]" and "[@name=@]" parameters limit results to pages in a specific group or with a specific name:%0a(:table class='tabtable' rules=rows:)%0a(:cellnr:)All pages in the Pmwiki group:%0a(:cell:)[@(:pagelist group=PmWiki :)@]%0a(:cellnr:)All pages except those in the PmWiki or Site groups:%0a(:cell:)[@(:pagelist group=-PmWiki,-Site :)@]%0a(:cellnr:)All RecentChanges pages%0a(:cell:)[@(:pagelist name=RecentChanges :)@]%0a(:cellnr:)All pages except RecentChanges%0a(:cell:)[@(:pagelist name=-RecentChanges :)@]%0a(:tableend:)%0a%0a!!! Wildcards%0aName and group parameters can contain ''wildcard'' characters that display only pages matching a given pattern:%0a* An asterisk (*) represents zero or more characters%0a* A question mark (?) represents exactly one character%0a%0aExamples:%0a(:table class='tabtable' rules=rows:)%0a(:cell:)All pages in any group beginning with "PmWiki"%0a(:cell:)[@(:pagelist group=PmWiki* :)@]%0a(:cellnr:)All pages in any group beginning with "PmWiki", except for Chinese%0a(:cell:)[@(:pagelist group=PmWiki*,-PmWikiZh :)@]%0a(:cellnr:)All pages in the PmCal group with names starting with "2005":%0a(:cell:)[@(:pagelist name=PmCal.2005* :)@]%0a(:cellnr:)All Cookbooks with names beginning with a A and a B letter%0a->note the different separators used for the same result%0a(:cell:)[@%0a(:pagelist group=Cookbook name=A*,B* :)%0a(:pagelist group=Cookbook name="A* B*" :)%0a(:pagelist group=Cookbook name=[AB]* :)%0a(:pagelist group=Cookbook, name=[AB]* :)@]%0a(:tableend:)%0a%0aIf you want to use multiples conditions in name you need to use quotes or commas to delimit the string. %0a%0a!!![[#pagelisttrail]] trail= %0aThe "[@trail=@]" option obtains the list of pages to be displayed from a [[WikiTrail(s)]]:%0a* Display pages in the documentation by modification time%0a->[@(:pagelist trail=PmWiki.DocumentationIndex order=-time:)@]%0a* Display five most recently changed pages%0a-%3c[@(:pagelist trail=RecentChanges count=5:)@]%0a%0a!!![[#pagelistlist]] list= %0a%0aThe "[@list=@]" option allows a search to include or exclude pages according to predefined patterns set by the administrator. %0a* "[@list=normal@]" is predefined, and which excludes things like AllRecentChanges, RecentChanges, GroupHeader, GroupFooter, GroupAttributes, and the like from being displayed in the list results. Note that list=normal also excludes the current page.%0a* "[@list=all@]" over-rides a "default" list that may be set by the wiki's administrator to exclude groups such as PmWiki or Site from regular search results.%0a* Wiki administrators can define custom lists via the $SearchPatterns array (see [[Cookbook:SearchResults]]).%0a%0a!!![[#pagelistfmt]] fmt= %0a%0aThe "[@fmt=@]" option determines how the resulting list should be displayed. %0aPmWiki [[Site/PageListTemplates|predefines]] several formats:%0a* @@fmt=#bygroup@@ - Display pages within groups (default format)%0a* @@fmt=#simple@@ - Display a simple ordered list of pages in the form Group.Name%0a* @@fmt=#title@@ - Display a list of pages by page title. Use "[@order=title@]" to have them sorted by title (default is to order by page name).%0a* @@fmt=#group@@ - Display a list of wikigroups (without listing the pages in the groups)%0a* @@fmt=#include@@ - Display the contents of each page in the list (note, this could take a very long time for long lists!)%0aThese formats are defined by [[page list templates]], which can be customized.%0a%0aThis format is not predefined by a page list template:%0a* @@fmt=count@@ - Display the number of pages in the list (note the absence of the "#").%0a%0a%0a!!![[#pagelistlink]] link= %0a%0aThe "[@link=@]" option implements "backlinks" -- i.e., it returns a list of pages with a link to the target. It's especially useful for [[categor(ies)]]y pages and finding related pages.%0a%0a* all pages with a link to PmWiki.DocumentationIndex%0a->[@(:pagelist link=PmWiki.DocumentationIndex:)@]%0a* all pages with links to the current page%0a->[@(:pagelist link={$FullName}:)@]%0a* all pages in the "Skins" category%0a->[@(:pagelist link=Category.Skins:)@]%0a%0a!!![[#pagelistcount]] count= %0a%0aThe "[@count=@]" option provides the ability to%0a* limit the pagelist to a specific number of pages%0a* subsets of a list%0a* return items from the end of a list, subsets of a list%0a* display pages in reverse sequence%0a%0a(:table class=tabtable rules=rows:)%0a(:cellnr:)A simple bullet list of ten most recently modified pages%0a(:cell:)%0a[@(:pagelist trail=Site.AllRecentChanges count=10 fmt=#simple:)@]%0a(:cellnr:)Display the first ten pages of a list%0a(:cell:)%0a[@count=10 # display the first ten pages of list@]%0a(:cellnr:)Negative numbers specify pages to be displayed from the end of the list:%0a(:cell:)%0a[@count=-10 # display last ten pages of list@]%0a(:cellnr:)Ranges may be specified using '..', thus:%0a(:cell:)%0a[@count=1..10 # first ten pages of list%0acount=5..10 # 5th through 10th pages of list@]%0a(:cellnr:)Negative numbers in ranges count from the end of the list:%0a(:cell:)%0a[@count=-10..-5 # 10th from end, 9th from end, ..., 5th from end@]%0a(:cellnr:)Omitting the start or end of the range uses the start or end of the list:%0a(:cell:)%0a[@count=10.. # skip first ten pages%0acount=..10 # 1st through 10th page of list%0acount=-10.. # last ten pages of list%0acount=..-10 # all but the last nine pages@]%0a(:cellnr:)Ranges can be reversed, indicating that the order of pages in the output should likewise be reversed:%0a(:cell:)%0a[@count=5..10 # 5th through 10th pages of list%0acount=10..5 # same as 5..10 but in reverse sequence%0acount=-1..1 # all pages in reverse sequence@]%0a(:cellnr:)"Reverse sequence" here refers to the sequence ''after'' any sorting has taken place. Therefore the three directives to the right are equivalent:%0a(:cell:)%0a[@(:pagelist order=-name count=10:)%0a(:pagelist order=-name count=1..10:)%0a(:pagelist order=name count=-1..-10:) @]%0a(:tableend:)%0a%0a!!![[#pagelistwrap]] wrap=%0aThe "[@wrap@]" option has the values, ''none'' and ''inline''.%0a%0aWith "wrap=inline" and "wrap=none", the output from pagelist (markup or HTML) is directly embedded in a page's markup without any surrounding %3cdiv> class=...%3c/div> tags.%0a%0aWith "wrap=inline", any surrounding %3cul> is continued. Without "wrap=inline", the HTML output starts a new %3cul>. This is important if you want to get a second level %3cul> produced by the page list since starting a new %3cul> with "**" doesn't yield a second level %3cul> but %3cdl>%3cdd>%3cul>...%0a%0a"wrap=inline" likely has other effects since it suppresses the call to $FPLTemplateMarkupFunction (being MarkupToHTML by default).%0a%0a!!![[#pagelistclass]] class=%0aBy default, a pagelist has the 'fpltemplate' class. The 'bygroup', 'simple', 'group' and 'title' page list formats have specific class names fplbygroup, fplsimple etc. You can set any class using the class= parameter or by setting the $FPLFormatOpt array.%0a%0a!!![[#pagelistpasswd]] passwd=%0aThe "[@passwd@]" option returns only those pages that have some sort of password attribute on them.%0a%0a!!![[#pagelistif]] if=%0aThe "[@if@]" option allows a condition to be specified as part of the pagelist processing, rather than from within the [[page list template(s)]]. Only those pages for which the condition is true are retrieved. Anything that could [[ConditionalMarkup | go within an [@(:if ...:)@]]] can be used as a condition. For example%0a%0a [@(:pagelist if="date {(ftime %25GW%25V {*$Name})} {=$Name}" :)@]%0a%0areturns all of the pages where the name is in the same week as that of the current page.%0a%0aIf any arguments within the quotes could contain a space they must be quoted:%0a%0a [@(:pagelist if="date 2009-01-01..2009-12-31 '{=$:Mydate}'" :)@]%0a%0a!!![[#pagelistorder]] order=%0a%0aThe "[@order=@]" option allows the pages in the list to be sorted according to different criteria. Use a minus sign to indicate a reverse sort. Multiple sorting criteria can be specified using a comma, and you can create your own [[(PmWiki:)custom pagelist sort order]]:%0a* [@order=name@] - alphabetically by name (default order)%0a* [@order=title@] - alphabetically by title rather than names%0a* [@order=time@] - most recently changed pages '''last'''%0a* [@order=ctime@] - time of page creation (see note)%0a* [@order=size@] - page size (not file size), smallest pages first%0a* [@order=group,title@] - by multiple criteria, in this instance sort by title within groups%0a* [@order=random@] - shuffle the pages into random sequence%0a* [@order=$:pagetextvarname@] - alphabetically by [[PageTextVariables|page text variable]] value%0a%0aAlso, the [@order=@] option allows custom ordering functions to be written.%0a%0a* Note: trail= preserves the order of the pages as they appear on the trail (unless you've specified order= explicitly or there is a default order in the page list template). So PmWiki's alphabetical default order does not apply when trail= is specified.%0a* Note: ctime was added to pages only from pmwiki 2.1.beta15 onwards, pages created by earlier versions don't carry a ctime attribute and can't be sorted that way.%0a%0a[[#pagelistcache]]%0a!!! cache=0%0aPagelist has the capability to cache lists which greatly speeds up processing (when [[PmWiki/PagelistVariables#PageListCacheDir|$PageListCacheDir]] is set). Every once in a while this caching can result in undesired results. Specifying @@cache=0@@ disables caching.%0a%0a%0a[[#includevariable]]%0a!!!! Specifying variables as parameters%0aYou can also specify variable values inline with the pagelist statement, and refer to the variables in the template using the [@{$$variable1}@] format:%0a-> [@(:pagelist fmt=#pagelist variable1="value" variable2="value2":)@]%0a%0aThis assumes that a site has $EnableRelativePageVars enabled, which is recommended in PmWiki 2.2.0 -- but disabled by default to help people upgrading from 2.1.x.%0a%0aFor example, in the template:%0a%0a(:markup:)%0a>>comment%3c%3c%0a[[#tvars]]%0a(:template default count=1 ParamName=Simon:)%0aHi, {$$ParamName}, how are you today?%0a[[#tvarsend]]%0a>>%3c%3c%0a(:markupend:)%0a%0aThis gives:%0a%0a(:markup class=horiz:)%0a(:pagelist fmt=#tvars ParamName="Sam":)%0a%0a(:pagelist fmt=#tvars ParamName="Sally":)%0a%0a(:pagelist fmt=#tvars:)%0a(:markupend:)%0a%0a!! Examples%0a%0aInclude the contents of a random page from the Banners group:%0a->[@(:pagelist group=Banners order=random count=1 fmt=#include list=normal:)@]%0a%0aDisplay a simple list of the last ten recently changed pages:%0a->[@(:pagelist trail=Site.AllRecentChanges count=10 fmt=#simple:)@]%0a%0aDisplay the "top twenty" biggest cookbook pages:%0a->[@(:pagelist group=Cookbook order=-size count=20 :)@]%0a%0a!![[#searchbox]] The Searchbox Directive%0a%0aThe [@(:searchbox:)@] directive generally accepts the same parameters as [@(:pagelist:)@] and [@(:input text:)@] directives:%0a* Pagelist parameters can be added to the input text of a searchbox (or to the markup, or both)%0a* Input text box parameters can be added to the searchbox markup%0a** An initial search string can be specified in the searchbox markup, but it must be in the form @@value='search string'@@. That search string is displayed in the input text and can be modified by when the search is run.%0a** The size of the text input field can be specified with the size parameter, where "size=40" would specify the current default value.%0a*** Tip: If more than one searchbox appears on a page, adding a blank initial value like this @@value=''@@, to the markup for each searchbox will prevent a search string for one box from populating all of the other boxes.%0a* The target page for displaying searchbox results can be set with the parameter @@target=''GroupName.PageName''@@. The default is the current page. %0a* The entire searchbox form can be overridden by defining the $SearchBoxFmt variable in one's configuration file. If $SearchBoxFmt is defined, then the parameters to [@(:searchbox:)@] are ignored, and the content of the $SearchBoxFmt variable are used instead.%0a%0a[[#searchresults]]%0a!! The Searchresults directive%0aThe [@(:searchresults:)@] directive generally accepts the same parameters as [@(:pagelist:)@] and [@(:input text:)@] directives:%0a%0a!!![[#pagelistreq]] request=1 req=1%0a[=(:searchresults:)=] without the introductory line that says "Results of search for..."%0a%0a!! See Also%0a%0a* [[PageDirectives#attachlist]] - display a list of attachments%0a* [[Site.PageListTemplates]] - default pmwiki pagelist templates%0a* [[Cookbook:PagelistTemplateSamples]] - contributed pagelist template samples%0a* [[PmWiki/PageListTemplates]] - how to create custom pagelist templates for the fmt= option%0a* [[(PmWiki/)PagelistVariables]] - ''local/config.php'' customizations%0a* [[Cookbook:Forms]] - documentation for [@(:input text:)@] markup, which applies to [@(:searchbox:)@]%0a* [[(PmWiki:)CustomPagelistSortOrder]] - creating custom order sort functions%0a* [[Cookbook:CustomPagelistSortOrderFunctions]] - {Cookbook.CustomPagelistSortOrderFunctions$:Summary}%0a
+time=1258537977
diff --git a/wikilib.d/PmWiki.PageTextVariables b/wikilib.d/PmWiki.PageTextVariables
new file mode 100644
index 0000000..fbf5596
--- /dev/null
+++ b/wikilib.d/PmWiki.PageTextVariables
@@ -0,0 +1,12 @@
+version=pmwiki-2.2.5 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/532.0 (KHTML, like Gecko) Chrome/3.0.195.21 Safari/532.0
+author=simon
+charset=ISO-8859-1
+csum=force formatting
+ctime=1159470179
+host=203.97.214.12
+name=PmWiki.PageTextVariables
+rev=130
+targets=PmWiki.Name,PmWiki.FullName,PmWiki.TextFormattingRules,PmWiki.PageDirectives,PmWiki.IncludeOtherPages,PmWiki.PageLists,Site.PageListTemplates,PmWiki.PageListTemplates,PmWiki.PageVariables,Site.LocalTemplates,PmWiki.ConditionalMarkup
+text=(:Summary:Page variables automatically made available through natural or explicit page markup:)%0a>>comment%3c%3c%0a[[#singleline]]%0a[-[[{=$FullName}|+]],-] \%0a[[#singlelineend]]%0a>>%3c%3c%0a%0a>>rframe font-size:smaller noprint clear=right%3c%3c%0a!!!! Table of contents%0a* [[#defining | Defining page text variables]]%0a* [[#usage | Usage]]%0a** [[#usagesamepage | On the same page]]%0a** [[#usageotherpage | From other pages]]%0a** [[#usageincludedpage | On included pages]]%0a** [[#nested | Nested]]%0a** [[#pagelists | With pagelists]]%0a** [[#templates | In templates]]%0a** [[#conditionals| With conditionals]]%0a** [[#usageother | Other usage]]%0a** [[#withincode | Within code]]%0a** [[#usagenotes | Usage notes]]%0a>>%3c%3c%0a%0aPage text variables are string variables automatically made available through [[PmWiki/TextFormattingRules | natural page]] markup or explicitly with [[PmWiki/PageDirectives | page directive]] markup within the wiki text of the page.%0a%0a[[#defining]]%0a!! Defining Page Text Variables%0a%0aThere are three ways to define automated Page Text Variables:%0a%0a* use a [[TextFormattingRules#DefinitionLists | definition list]] - the normal pmwiki markup for a definition list will create a page text variable%0a(:markup caption='Example definition list:' class="horiz":)%0a:Name: Crisses%0a"{$:Name}"%0a(:markupend:)%0a->This creates a new variable that can be accessed by [@{$:Name}@] (becomes: "{$:Name}") in the page.%0a%0a* use a simple colon delimiter in normal text%0a(:markup caption='Example colon delimited:' class="horiz":)%0aAddress: 1313 Mockingbird Lane%0a%0a"{$:Address}"%0a(:markupend:)%0a->This creates the [@{$:Address}@] variable (variable markup becomes: "{$:Address}") in the page.%0a%0a* hidden [[PmWiki/PageDirectives | directive]] form - PmWiki markup that doesn't render on the page, but defines the variable%0a(:markup caption='Example directive:' class="horiz":)%0a(:Country: Transylvania :)%0a"{$:Country}"%0a(:markupend:)%0a->This creates the [@{$:Country}@] variable (variable markup becomes: "{$:Country}") in the page.%0a%0a[[#usage]]%0a!! Usage%0a[[#usagesamepage]]%0a!!! Usage on the same page%0a%0aOn the same page you can resolve page text variables through the [@{$:Var}@] format (shown above).%0a%0a!!! Usage in headers and footers%0a%0aIf you want a GroupHeader, GroupFooter, SideBar, etc to call on page text variable in the main page, you need to include reference information. %0aTo explicitly reference the page text variable from the page being displayed add an asterisk to the page text variable's markup: [@{*$:Address}@] on the GroupFooter or GroupHeader page. %0a(:markup caption='Example' class=horiz:)%0a{*$:City}%0a(:markupend:)%0aTo include a page text variable ''from'' a header or footer see [[#usageotherpage |usage from other pages]] below.%0a%0a%0a[[#usageotherpage]]%0a!!! Usage from other pages%0a%0aIf you want to pull the data from another page, use the [@{Group/PageName$:Var}@] format.%0a(:markup caption='Example:' class="horiz":)%0aSuburb: Khandallah%0a(:Lake:Taupo:)%0a:Mountain:Mt Ruapehu%0a%0a->"{PmWiki/PageTextVariables$:Suburb}"%0a->"{{$FullName}$:Lake}"%0a->"{PmWiki/PageTextVariables$:Mountain}"%0a(:markupend:)%0a%0a[[#usageincludedpage]]%0a!!! Usage from included pages%0a%0aPage text variables are never [[IncludeOtherPages|included]] from their source page.%0aSee [[#usageotherpage|Usage from other pages]] above to refer to a page text variable on another page.%0a%0a[[#nested]]%0a!!! Nested page text variables%0a%0aPage text variables can be nested%0a(:markup caption='Example:' class="horiz":)%0a: MailingAddress : {$:Address}, {$:City}, {$:Country}%0a"{$:MailingAddress}"%0a(:markupend:)%0a%0aAnother way you may nest PTVs is to make (part of) the variable name a variable in itself:%0a(:markup caption='Example:' class="horiz":)%0ax:Test/Ptvb%0aContents of y on page {$:x}:%0a{{$:x}$:y}%0a(:markupend:)%0a%0a[[#pagelists]]%0a!!! Usage with pagelists%0a%0a[[Page lists]] can also access the page text variables:%0a(:markup caption='Example:' class="horiz":)%0a(:pagelist group=PmWiki order=$:Summary count=6 fmt=#singleline:)%0a(:markupend:)%0a%0aAnd to create pagelist formats (such as those documented at [[Site.Page List Templates]], [[PmWiki/Page Lists]], [[PmWiki/Page List Templates]], [[PmWiki/Page Variables]]. Store custom pagelists at [[Site.Local Templates]]).%0a%0a[[Page lists]] can also use page text variables to select pages :%0a(:markup caption='Example:' class="horiz":)%0a(:pagelist group=PmWiki $:City=Paris count=8 fmt=#singleline order=-name:)%0a(:markupend:)%0a->lists pages having '$:City' set to 'Paris'.%0a%0a(:markup caption='Example: multiple selections' class="horiz":)%0a(:pagelist group=PmWiki $:Audience="*authors (intermediate)*,*administrators (intermediate)*" order=-$:Audience,name count=10 fmt=#singleline:)%0a(:markupend:)%0a->lists pages having a '$:Audience' of 'authors (intermediate)' or 'administrators (intermediate)'.%0a%0a(:markup caption='Example: multiple selections with spaces' class="horiz":)%0a(:pagelist group=PmWiki $:City="Addis Ababa,Paris" order=-$:Version count=8 fmt=#singleline:)%0a(:markupend:)%0a->'quotes' must surround ''all'' the selections.%0a%0a%0a(:markup caption='Example: Pages with City variable set' class="horiz":)%0aCity: Addis Ababa%0a(:pagelist group=PmWiki $:City=- count=10 fmt=#singleline:)%0a(:markupend:)%0a->City variable is set.%0a%0a* When using page text variables for selection or ordering, don't put the curly braces around the variable name. The curly forms do a replacement before the pagelist command is evaluated. %0a%0a[[#set]]%0a!!! Testing if set or not set%0a(:table:)%0a(:cellnr:)'''=-''' %0a(:cell:)PTV is set (is not empty), eg [@(:pagelist $:MyPageTextVariable=- :)@]%0a(:cellnr:)%0a%25pre%25'''=-?*''' %0a(:cell:)PTV is not set (is empty), ie is not set to one char followed by 0 or more chars, eg%0a-> [@(:pagelist $:MyPageTextVariable=-?* :) @]%0a(:cellnr:)'''=*''' %0a(:cell:)display ''all'' pages, the page text variable is irrelevant%0a(:cellnr:)'''=-*''' %0a(:cell:)display ''no'' pages, the page text variable is irrelevant%0a(:tableend:)%0a%0a(:markup caption='Example: Pages without a summary' class="horiz":)%0a(:pagelist group=PmWiki $:Summary=-?* count=6 fmt=#singleline:)%0a(:markupend:)%0a%0a[[#templates]]%0a!!! Use page text variable in a template%0aDisplay pages by Audience page text variable.%0a(:markup caption='Example:' class="horiz":)%0a>>comment%3c%3c%0a[[#byaudience]]%0a(:if ! equal '{=$:Audience}' '{%3c$:Audience}':)%0a-%3c'''{=$:Audience}''': %0a(:ifend:)%0a[[{=$Name}]]%0a[[#byaudienceend]]%0a>>%3c%3c%0a(:pagelist group=PmWiki count=10 fmt=#byaudience order=-$:Audience:)%0a(:markupend:)%0a%0a[[#conditionals]]%0a!!! Use page text variables in [[PmWiki/conditional markup]]%0aPage text variables will be assigned/evaluated before any conditional markup is evaluated. That means you can use page text variables with conditional markup, but not conditional markup within page text variables. For instance a PTV will have a value even if it is set within a [@(:if false:)....(:if:)@] condition. %0a%0a%0a[[#usageother]]%0a!!! Usage - other%0a%0aData relevant to a page (the "Base" page) may now also be found in other groups. If the Base page is Main/HomePage, the data page could be Data-Main/HomePage. A new variable called $BaseName, which automatically calculates the Base page name from the Data page name, and can be defined by including the following in config.php:%0a%0a->[@// The pattern for figuring out the basename of a page%0a$BaseNamePatterns['/^Data-/'] = '';@]%0a%0aYour pattern may vary.%0a%0a[[#withincode]]%0a!!! Usage - from within code (developers only)%0a%0aThe standard @@PageVar($pagename,$varname)@@ function can return page text variables, but remember to include the dollar and colon like this:%0a%0a->@@$var=PageVar($pagename,'$:City')@@%0a%0aActually, for text variables, @@PageVar@@ just calls @@PageTextVar($pagename,$varname)@@, so your code can be sped up slightly by calling it directly, but it takes just the raw variable name without any leading characters, like this: %0a%0a->@@$var=PageTextVar($pagename,'City')@@%0a%0aIt works by caching all page text-variables it finds in a page (in @@$PCache@@) and returns the one requested.%0a%0a!! Feature availability%0aPage text variables were introduced in 2.2.0 beta 2.%0a
+time=1254026595
diff --git a/wikilib.d/PmWiki.PageVariables b/wikilib.d/PmWiki.PageVariables
new file mode 100644
index 0000000..0d3304e
--- /dev/null
+++ b/wikilib.d/PmWiki.PageVariables
@@ -0,0 +1,14 @@
+version=pmwiki-2.2.10 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.7) Gecko/20100106 Ubuntu/9.10 (karmic) Firefox/3.5.7
+author=Petko
+charset=ISO-8859-1
+csum=See also $EnableRelativePageVars
+ctime=1135816487
+description=Documentation for "variables" that are associated with pages.
+host=86.69.109.228
+name=PmWiki.PageVariables
+rev=79
+targets=PmWiki.PageVariables,PmWiki.Variables,Cookbook.Functions,PmWiki.FmtPageName,PmWiki.IncludeOtherPages,PmWiki.PageListTemplates,Site.PageNotFound,PmWiki.ConditionalMarkup,Cookbook.MoreCustomPageVariables,PmWiki.MarkupMasterIndex,PmWiki.PageTextVariables,PmWiki.MarkupExpressions
+text=(:title Page specific variables:)%0a(:description Documentation for "variables" that are associated with pages. :)%0a(:Summary: variables that are associated with pages:)%0a(:Audience: authors (intermediate) :)%0a%0a[[#desc]]This page describes the "variables" that are associated with pages. Page variables have the form @@{$''variable''}@@, and can be used in page markup or in certain formatting strings in PmWiki. For example, the markup "[@{$Group}@]" renders in this page as "{$Group}".%0a%0aNote: Do not confuse these variables (set and used only in PmWiki pages) with [[PmWiki/Variables|PHP variables]]. Page variables can be read in PHP with the [[Cookbook:Functions#PageVar|PageVar()]] function.%0a%0aNote that these variables do not necessarily exist in the PHP code, because they have to be determined for a specific page. (However, they are usable in [[FmtPageName]] strings.)%0a%0aThere is also the form @@{''pagename''$''variable''}@@, which returns the value of the variable for another page. For example, "[@{MarkupMasterIndex$Title}@]" displays as "{MarkupMasterIndex$Title}".%0a%0a[[#specialreferences]]%0a!! Special references%0aSpecial referenced variables are used to retain the context of the target page or main page for a [[variable(s)]] when:%0a* the variable is [[PmWiki/IncludeOtherPages|included]] into a destination (target) page)%0a* the variable is part of a sidebar, header, or footer for a main page%0a%0aPrefixing the variable name with an asterisk (*) means the variable reflects the value related to the target page or main page.%0a* '''[@*$@]'''PageVariablename - prefixed by an asterisk (*) - value reflects target page context%0aWithout the asterisk it reflects the value of the page in which it originates.%0a* '''[@$@]'''PageVariablename - retains value in source page context%0a%0aSee also $EnableRelativePageVars.%0a%0aSpecial references are also used in [[page list templates(#specialreferences)]].%0a%0aFor example you can test to see if the page is part of another page%0a(:markup:)%0a(:if ! name {$FullName}:) %0a%25comment%25 name of this page is not the same as the page this text was sourced from%0a->[[{$FullName}#anchor | more ...]]%0a(:ifend:)%0a(:markupend:)%0aor refer to the main page in a sidebar, footer, or header%0a(:markup class=horiz:)%0aThis page is [[{*$FullName}]]%0a(:markupend:)%0a%0a[[#specialreferencesend]]%0a%0a!! Default page variables%0a%0aThe page variables defined for PmWiki are:%0a%0a->[@{$Action}@] - page's url action argument, as in "{$Action}"%0a->[@{$BaseName}@] - page's "base" form (stripping any prefixes or suffixes defined via @@$BaseNamePatterns@@) as in "`{$BaseName}"%0a->[@{$DefaultGroup}@] - default group name, as in "{$DefaultGroup}"%0a->[@{$DefaultName}@] - name of default page, as in "`{$DefaultName}"%0a->[@{$Description}@] - page's description from the [@(:description:)@] markup, as in "{$Description}"%0a->[@{$FullName}@] - page's full name, as in "`{$FullName}"%0a->[@{$Group}@] - page's group name, as in "`{$Group}"%0a->[@{$Groupspaced}@] - spaced group name, as in "{$Groupspaced}"%0a%0a->[@{$LastModified}@] - date page was edited, as in "{$LastModified}"%0a->[@{$LastModifiedBy}@] - page's last editor, as in "{$LastModifiedBy}"%0a->[@{$LastModifiedHost}@] - IP of page's last editor, as in "{$LastModifiedHost}"%0a->[@{$LastModifiedSummary}@] - Summary from last edit, as in "{$LastModifiedSummary}"%0a->[@{$LastModifiedTime}@] - time page was edited in unix-style timestamp, as in "{$LastModifiedTime}" %25green%25added version 2.2 beta 67%25%25%0a-->This can be used (preceded by '@') in [@{(ftime)}@] and other date/time markups.%0a%0a->[@{$Name}@] - page name, as in "`{$Name}"%0a->[@{$Namespaced}@] - spaced page name, as in "{$Namespaced}"%0a->[@{$PageUrl}@] - page's url, as in "{$PageUrl}"%0a->[@{$PasswdRead}@] - "read" permissions for the page e.g. "{$PasswdRead}"%0a->[@{$PasswdEdit}@] - "edit" permissions for the page e.g. "{$PasswdEdit}"%0a->[@{$PasswdAttr}@] - "attr" permissions for the page e.g. "{$PasswdAttr}"%0a->[@{$RequestedPage}@] - page requested in URL, used on [[Site.PageNotFound]]. e.g. "{$RequestedPage}"%0a->[@{$SiteGroup}@] - default group name for e.g. RecentChanges, as in "{$SiteGroup}"%0a->[@{$Title}@] - page title (may differ from Name), as in "{$Title}"%0a->[@{$Titlespaced}@] - either the page title (if defined), or the spaced page name, as in "{$Titlespaced}"%0a%0aIn addition to the above, there are some page-invariant variables available through this markup:%0a%0a->[@{$Author}@] - the name of the person currently interacting with the site, as in "{$Author}"%0a->[@{$AuthId}@] - current authenticated id, as in "{$AuthId}" %25red%25Please note the lower case 'd'. [@{$AuthID}@] returns nothing%0a%0a->[@{$Version}@] - PmWiki version, as in "{$Version}"%0a->[@{$VersionNum}@] - The internal version number, as in "{$VersionNum}"%0a->[@{$ScriptUrl}@] - The url to the pmwiki script, as in "{$ScriptUrl}"%0a%0a%0a!! Custom page variables%0a%0aYou may add custom page variables as a local customization. In a local configuration file or a recipe script, use the variable $FmtPV:%0a%0a->[@%0a$FmtPV['$VarName'] = "'variable definition'";%0a$FmtPV['$CurrentSkin'] = '$GLOBALS["Skin"]';%0a$FmtPV['$WikiTitle'] = '$GLOBALS["WikiTitle"]';%0a@]%0a%0aDefines new Page Variable of name $CurrentSkin, which can be used in the page with [@{$CurrentSkin}@] (also for [[Conditional markup]]). It's necessary to use the single quotes nested inside double-quotes as shown above (preferred) or a double-quoted string nested inside single-quotes like ''[@'"this"'@]''.%0a%0aIf you want to have a Page Variable that returns the currently used password (more precisely, the last password entered), you can use%0a%0a->[@%0a$FmtPV['$AuthPw'] = 'reset(array_keys((array)@$_SESSION["authpw"]))';%0a@]%0a%0a!! See also%0a%0a* [[Cookbook:More custom page variables]]%0a* [[PmWiki.Variables]] — about variables internal to PmWiki.%0a* [[PmWiki.MarkupMasterIndex]] — complete list of PmWiki markups.%0a* [[PmWiki/PageTextVariables]] — page variables automatically made available through natural page markup or explicit page markup within the wiki text of the page.%0a* [[PmWiki.Markup Expressions]] — markup expressions can manipulate page variables%0a%0a>>faq%3c%3c [[#faq]]%0a%0aQ:Is there a variable like $LastModified, but which shows me the creation time?%0aA:No, but you can create one in config.php. For instance:%0a->[@# add page variable {$PageCreationDate} in format yyyy-mm-dd%0a$FmtPV['$PageCreationDate'] = 'strftime("%25Y-%25m-%25d", $page["ctime"])';@]%0a%0aIf you like the same format that you define in config.php with $TimeFmt use%0a[@ $FmtPV['$Created'] = "strftime(\$GLOBALS['TimeFmt'], \$page['ctime'])";%0a@]
+time=1265899656
+title=Page specific variables
diff --git a/wikilib.d/PmWiki.PagelistVariables b/wikilib.d/PmWiki.PagelistVariables
new file mode 100644
index 0000000..4e6b2d1
--- /dev/null
+++ b/wikilib.d/PmWiki.PagelistVariables
@@ -0,0 +1,12 @@
+version=pmwiki-2.2.0 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.19) Gecko/20081216 Ubuntu/8.04 (hardy) Firefox/2.0.0.19
+author=Petko
+charset=ISO-8859-1
+csum=revert sandbox
+ctime=1136054369
+host=81.65.14.164
+name=PmWiki.PagelistVariables
+rev=27
+targets=PmWiki.PageLists,Site.LocalTemplates,Site.PageListTemplates
+text=(:Summary:variables used with [[PmWiki/page lists]] and search results:)%0a:$EnablePageListProtect:When set to 1 (which is the default), causes [@(:pagelist:)@] and [@(:searchresults:)@] to exclude listing any pages for which the browser does not currently have read authorization. Setting this to zero means that read-protected pages can appear in a listing, but can also speed up searches considerably (because page permissions do not need to be checked).%0a%0a:$SearchPatterns:An array of page name patterns to be required or excluded from search and [[PmWiki/PageLists|pagelist]] results. In order to be included in a search listing or page listing, a page's name must not match any pattern that is delimited by exclamation points (!) and must match all other patterns. See [[Cookbook:SearchPatterns]].%0a--> [@# Limit all searches to Main group%0a$SearchPatterns['default'][] = '/^Main\\./';%0a# Exclude the Main group from search results%0a$SearchPatterns['default'][] = '!^Main\\.!';%0a# Exclude RecentChanges pages from search results%0a$SearchPatterns['default'][] = '!\\.(All)?RecentChanges$!';%0a# Prevent a page from listing itself in (:pagelist:) or (:searchresults:)%0a$SearchPatterns['default'][] = FmtPageName('!^$FullName$!', $pagename);%0a@]%0a%0a:$SearchBoxOpt:%0a--> For example [@ $SearchBoxOpt ['target'] = '$DefaultGroup.Search'; @]%0a%0a%0a:$EnablePageIndex:When set to 1, causes PmWiki to maintain a "link and word index" in $PageIndexFile which significantly speeds up categories, backlinks, and searches.%0a%0a:$PageIndexFile:The location of the "page index" file for [@(:pagelist:)@], defaults to @@$WorkDir/.pageindex@@.%0a%0a:$PageListCacheDir:The name of a writable directory where PmWiki can cache results of [@(:pagelist:)@] directives to speed up subsequent displays of the same list. Default is empty, which disables the pagelist cache.%0a--> [@# Enable pagelist caching in work.d/%0a$PageListCacheDir = 'work.d/';%0a@]%0a%0a:$PageSearchForm:The page to be used to format search results for [@?action=search@] (unless the current page has a "searchresults" directive in it). This variable can be an array, in which case the first page found from the array is used.%0a--> [@# Use Search page in current group if it exists, otherwise use Site.Search%0a$PageSearchForm = array('$Group.Search', '[=$[$SiteGroup/Search]=]');%0a@]%0a%0a:$FPLTemplatePageFmt:The pages to be searched for a pagelist template specified by a [@fmt=#xyz@] parameter. Defaults to searching the current page, [[Site.LocalTemplates]] and [[Site.PageListTemplates]].%0a%0a--> [@# PMWiki default setup%0aglobal $FPLTemplatePageFmt;%0a$FPLTemplatePageFmt = array(%0a '{$FullName}', %0a '{$SiteGroup}.LocalTemplates', %0a '{$SiteGroup}.PageListTemplates');@]%0a%0a-> It can be customized to look in other pages.%0a%0a--> [@# Search a Group.Templates page as well as the Site templates%0aglobal $FPLTemplatePageFmt;%0a$FPLTemplatePageFmt = array(%0a '{$Group}.Templates',%0a '{$SiteGroup}.LocalTemplates',%0a '{$SiteGroup}.PageListTemplates');@]%0a%0a-> Or declare defaults for the template array:%0a--> [@# Search a Group.Templates page as well as the Site templates%0aglobal $FPLTemplatePageFmt;%0aSDV($FPLTemplatePageFmt, array('{$FullName}',%0a '{$Group}.Templates',%0a '{$SiteGroup}.LocalTemplates', '{$SiteGroup}.PageListTemplates')%0a );@]%0a
+time=1234650768
diff --git a/wikilib.d/PmWiki.Passwords b/wikilib.d/PmWiki.Passwords
new file mode 100644
index 0000000..a7980aa
--- /dev/null
+++ b/wikilib.d/PmWiki.Passwords
@@ -0,0 +1,12 @@
+version=pmwiki-2.2.5 ordered=1 urlencoded=1
+agent=Midori/0.1.9 (X11; Linux x86_64; U; en-us) WebKit/532+
+author=Petko
+charset=ISO-8859-1
+csum=
+host=81.65.12.233
+name=PmWiki.Passwords
+post= Save
+rev=207
+targets=PmWiki.PasswordsAdmin,PmWiki.PmWiki,PmWiki.WikiGroup,PmWiki.Security,PmWiki.AvailableActions,PmWiki.SpecialPages,PmWiki.GroupAttributes,PmWiki.Uploads
+text=(:Summary:General use of passwords:)(:Audience: authors :)%0a>>rframe font-size:smaller%3c%3c%0a!!!! Table of contents%0a* [[#pageattr|Protect an individual page]]%0a* [[#groupattr|Protect a group of pages]]%0a* [[#siteattr|Protect the site]]%0a>>%3c%3c%0a[[PmWiki]] has built-in support for password-protecting various areas of the wiki site. Authors generally want to be able to apply passwords to individual pages or to [[wiki group]]s. Wiki Administrators can apply passwords to individual pages, to wiki groups, or to the [[PasswordsAdmin#settingsitewidepasswords|entire site]]. As with any access control system, the password protection mechanisms described here are only a small part of overall system and wiki [[security]].%0a%0a!! As an author editing pages...%0a%0aAn author will generally set 3 types of passwords:%0a# to control who can see a page or group, use @@read@@ passwords%0a# to control who can edit a page or group, use @@edit@@ passwords%0a# to control who can alter the passwords used to protect a page or group, use @@attr@@ passwords%0a%0aIf required most [[AvailableActions|page actions]] can be password protected.%0a%0a[[#pageattr]]%0a!!! Protect an individual page%0aTo set a password on an individual wiki page, add the [[AvailableActions|page action]]%0a%0a->@@?action=attr@@ %0a%0ato the page's URL (address) to access its attributes. Using the form on the attributes page, you can set or clear the @@read@@, @@edit@@, or @@attr@@ passwords on the page. In the form you enter the passwords as cleartext; PmWiki encrypts them for you automatically when it stores them. %0a%0a%0aAdditional options:%0a%0a* Leaving a field blank will leave the attribute unchanged. %0a* To remove a password from a page (''reverting back'' to the group's or site's default), enter %0a%0a-> @@ clear @@%0a%0a* To indicate that the page can be edited ''even if a group or site password is set'', enter %0a%0a-> @@ @nopass @@%0a%0a* To lock a page for everybody but the admin, enter %0a%0a-> @@ @lock @@%0a%0a* To assign the site's site-wide passwords to the @@read@@, @@edit@@, or @@attr@@ password for the page, enter %0a%0a-> @@ @_site_edit, @_site_read, @_site_admin or @_site_upload @@%0a%0a[[#groupattr]]%0a!!! Protect a wiki group of pages%0aTo set a password on a [[wiki group]] is slightly more difficult -- you just set the passwords on a [[special page(s)]] in each group called %0a%0a->[[GroupAttributes]]%0a%0aFirst, you can get to the attributes page for `GroupAttributes by entering a URL (address) like %0a%0a->[@http://example.com/pmwiki/pmwiki.php?n=GroupName.GroupAttributes?action=attr@]%0a%0aReplace example.com with your domain name, and GroupName with the name of the group%0a%0aThen, using the form on the attributes page, you can set or clear the @@read@@, @@edit@@, or @@attr@@ passwords for the entire group. In the form you enter the passwords as cleartext; PmWiki encrypts them for you automatically.%0a%0aAdditional options:%0a%0a* To remove a password from a group (''reverting back'' to the site's default), enter %0a%0a->clear%0a%0a* To indicate that the group can be edited ''even if a site password is set'', enter %0a%0a->@nopass%0a%0a* To lock a group for everybody but the admin, enter %0a%0a->@lock%0a%0a* (Beginning with Ver 2.2.3) To assign the site's site-wide passwords to the @@read@@, @@edit@@, or @@attr@@ password for the group, enter %0a%0a-> @@ @_site_edit, @_site_read, @_site_admin or @_site_upload @@%0a%0a%0a!! Passwords%0aPasswords may consist of any combination of characters, except quotes.. %0aObviously longer is [[http://www.microsoft.com/protect/fraud/passwords/create.aspx|better]].%0a%0a!! Multiple passwords%0aMultiple passwords for a page, group or site are allowed. %0aSimply enter multiple passwords separated by a space. This allows you to have a read password, a write password, and have the write password allow read/write access. In other words, if the read password is %0a%0a->alpha%0a%0aand the edit password is %0a%0a->beta%0a%0athen enter%0a%0a-> [@%0aSet new read password: alpha beta%0aSet new edit password: beta%0a@]%0a%0aThis says that either %0a%0a->alpha%0a%0aor %0a%0a->beta%0a%0acan be used to read pages, but only %0a%0a->beta%0a%0amay edit. Since PmWiki checks the passwords you've entered since the browser has been opened, entering a read password that is also a write password allows both reading and writing.%0a%0a[[#siteattr]]%0a!!! Protect the site%0aPasswords can be applied to the entire wiki website in ''config.php''.%0aSee [[PasswordsAdmin#settingsitewidepasswords|passwords]] administration for details.%0a%0a%0a%25audience%25 administrator%0a%0a[[#administrators]]%0a!! As an administrator ...%0a%0aYou can set passwords on pages and groups exactly as described above for authors. You can also:%0a# set site-wide passwords for pages and groups that do not have passwords%0a# use @@attr@@ passwords to control who is able to set passwords on pages%0a# use @@upload@@ passwords to control access to the file [[upload(s)]] capabilities (if uploads are enabled)%0a# use an @@admin@@ password to override the passwords set for any individual page or group %0aFor more information on password options available to administrators, see [[PasswordsAdmin]].%0a%0a!! Which password wins?%0a%0aIn PmWiki, page passwords override group passwords, group passwords override the ''default'' passwords, and the @@admin@@ password overrides all passwords. This gives a great deal of flexibility in controlling access to wiki pages in PmWiki. %0a%0a!! Opening access to pages in protected groups/sites%0a%0aSometimes we want to "unprotect" pages in a group or site that is otherwise protected. In these cases, the special password %0a%0a->@nopass%0a%0ais used to indicate that access should be allowed to a page without requiring a password. %0a%0aFor example, suppose `Main.GroupAttributes has an edit password set, thus restricting the editing of all pages in Main. Now we want `Main.WikiSandbox to be editable without a password. Using %0a%0a->clear%0a%0afor the edit password for `Main.WikiSandbox ''doesn't unprotect the page'', because the password is being set by the group. Instead, we set the edit password for `Main.WikiSandbox to the special value %0a%0a->@nopass%0a%0awhich tells PmWiki to ignore any site-wide or group-level passwords for that page.%0a%0a%0a>>faq%3c%3c [[#faq]]%0a%0aQ: How can I password protect all the pages and groups on my site? Do I really have to set passwords page by page, or group by group?%0a%0aA: Administrators can set passwords for the entire site by editing the config.php file; they don't have to set passwords for each page or group. For example, to set the entire site to be editable only by those who know an "edit" password, an administrator can add a line like the following to local/config.php:%0a%0a $DefaultPasswords['edit'] = crypt('edit_password');%0a%0aFor more information about the password options that are available only to administrators, see [[PasswordsAdmin]].%0a%0aQ: I get http error 500 "Internal Server Error" when I try to log in. What's wrong?%0a%0aA: This can happen if the encrypted passwords are not created on the web server that hosts the PmWiki.\\%0aThe crypt function changed during the PHP development, e.g. a password encrypted with PHP 5.2 can not be decrypted in PHP 5.1, but PHP 5.2 can decrypt passwords created by PHP 5.1.\\%0aThis situation normally happens if you prepare everything on your local machine with the latest PHP version and you upload the passwords to a webserver which is running an older version.\\%0aThe same error occurs when you add encrypted passwords to local/config.php.%0a%0aSolution: Create the passwords on the system with the oldest PHP version and use them on all other systems.%0a%0aQ: How can I create private groups for users, so that each user can edit pages in their group, but no one else (other than the admin) can?%0a%0aA: Administrators can use the [[(PmWiki:)AuthUser]] recipe and add the following few lines to their local/config.php file to set this up:%0a%0a $group = FmtPageName('$Group', $pagename); \\%0a $DefaultPasswords['edit'] = 'id:'.$group; \\%0a include_once("$FarmD/scripts/authuser.php");%0a%0aThis automatically gives edit rights to a group to every user who has the same user name as the group name.%0a%0aQ: [[#farm]] How come when I switch to another wiki within a farm, I keep my same authorization?%0a%0aA: PmWiki uses PHP sessions to keep track of authentication/authorization information, and by default PHP sets things up such that all interactions with the same server are considered part of the same session.%0a%0aAn easy way to fix this is to make sure each wiki is using a different cookie name for its session identifier. Near the top of one of the wiki's local/config.php files, before calling authuser or any other recipes, add a line like:%0a%0a session_name('XYZSESSID');%0a%0aYou can pick any alphanumeric name for XYZSESSID; for example, for the cs559-1 wiki you might choose%0a%0a session_name('CS559SESSID');%0a%0aThis will keep the two wikis' sessions independent of each other.
+time=1254656607
diff --git a/wikilib.d/PmWiki.PasswordsAdmin b/wikilib.d/PmWiki.PasswordsAdmin
new file mode 100644
index 0000000..b1f2159
--- /dev/null
+++ b/wikilib.d/PmWiki.PasswordsAdmin
@@ -0,0 +1,12 @@
+version=pmwiki-2.2.7 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_2; en-us) AppleWebKit/531.21.8 (KHTML, like Gecko) Version/4.0.4 Safari/531.21.10
+author=RandyB
+charset=ISO-8859-1
+csum=Documented the ability to change passwords by reference
+host=70.112.179.65
+name=PmWiki.PasswordsAdmin
+post= Save
+rev=172
+targets=PmWiki.Passwords,PmWiki.WikiGroup,PmWiki.Security,PmWiki.WikiAdministrator,PmWiki.AvailableActions,PmWiki.AuthUser,PmWiki.PasswordsAdmin,PmWiki.ConditionalMarkup,PmWiki.GroupCustomizations,Site.AuthForm,Site.AttrForm
+text=(:Summary:More password options for the administrator:)(:Audience: administrators (basic) :)%0aPmWiki has built-in support for [[Passwords|password-protecting]] various areas of the wiki site. Passwords can be applied to individual pages, to [[Wiki Group]]s, or to the entire wiki site. Note that the password protection mechanisms described here are only a small part of overall system (and wiki) security, see [[PmWiki.Security]] for more discussion of this.%0a%0aAuthors can use PmWiki to add passwords to individual pages and WikiGroups as described in [[Passwords]]. However, [[WikiAdministrator]]s can also set passwords in ''local/config.php'' as described below. (Please note that one cannot set passwords reliably in per group or per page customization files. See the [[#faq | FAQ section]] for details.)%0a%0a[[#authlevel]]%0a!! Password basics%0a%0aPmWiki supports several levels of access to wiki pages, known as authorisation level:%0a* '''@@read@@''' passwords allow viewing the contents of wiki pages%0a* '''@@edit@@''' passwords control editing and modification of wiki pages%0a* '''@@attr@@''' passwords control who is able to set passwords on pages (and potentially other future attributes)%0a* '''@@upload@@''' password, if uploads are enabled, controls uploading of files and attachments%0a* in addition all [[available actions]] can be password authorised%0a* '''@@admin@@''' password allows an administrator to override the passwords set for any individual page or group.%0a%0aBy default, PmWiki has the following password settings:%0a* The @@admin@@ and @@upload@@ passwords are locked by default.%0a* The Main and PmWiki groups have a locked @@attr@@ password (in their respective `GroupAttributes pages).%0a* The pages in the Site group except `Site.SideBar are locked against editing; by default the Site.SideBar page requires the admin or the site-wide edit password.%0a%0aAn @@admin@@ password can be used to overcome "locked" passwords, other than that, no password will allow access.%0a%0aSee [[Passwords]] for information about setting per-page and per-group passwords. %0aThe remainder of this page describes setting site-wide passwords from the ''local/config.php'' file.%0a%0a[[#settingsitewidepasswords]]%0a!! Setting site-wide passwords%0a%0aOne of the first things an admin should do is set an @@admin@@ password for the site. This is done via a line like the following in the ''local/config.php'' file:%0a%0a-> $DefaultPasswords['admin'] = crypt('secret_password');%0a%0aNote that the crypt() call is required for this -- PmWiki stores and processes all passwords internally as encrypted strings. See the [[#crypt | crypt section]] below for details about eliminating the cleartext password from the configuration file.%0a%0aTo set the entire site to be editable only by those who know an "edit" password, add a line like the following to ''local/config.php'':%0a%0a-> $DefaultPasswords['edit'] = crypt('edit_password');%0a%0aSimilarly, you can set a password for any [[available action(s)]], viz [@$DefaultPasswords['read']@], [@$DefaultPasswords['edit']@], and [@$DefaultPasswords['upload']@] to control default @@read@@, @@edit@@, and @@upload@@ passwords for the entire site. The default passwords are used only for pages and groups which do not have passwords set. Also, each of the $DefaultPasswords values may be arrays of encrypted passwords:%0a%0a-> $DefaultPasswords['read'] = array(crypt('alpha'), crypt('beta'));%0a-> $DefaultPasswords['edit'] = crypt('beta');%0a%0aThis says that either "alpha" or "beta" can be used to read pages, but only the "beta" password will allow someone to edit a page. Since PmWiki remembers any passwords entered during the current session, the "beta" password will allow both reading and writing of pages, while the "alpha" password allows reading only. A person without either password would be unable to view pages at all.%0a%0a!! Setting passwords by reference%0a%0aSetting passwords by reference allows you to change the password for a whole set of pages as easily as you can change site-wide passwords. (Otherwise you would have to update each page's attributes individually.) Enter in the Group or Page Attributes:%0a-> @_site_MyPassword2%0a%0aAnd in the local configuration file set the actual password with lines like this:%0a-> $DefaultPasswords['MyPassword2'] = array(crypt('secret'), '@admins');%0a-> $DefaultPasswords['MyPassword9'] = array('$1$NuBV/Mcc$GG3J60h.TLczUTRKhoVPM.');%0a%0a%0a!! Identity-based authorization (username/password logins, [[AuthUser]])%0a%0aUnlike many systems which have '''identity-based''' systems for controlling access to pages (e.g., using a separate ''username'' and ''password'' for each person), PmWiki defaults to a ''password-based'' system as described above. In general password-based systems are often easier to maintain because they avoid the administrative overheads of creating user accounts, recovering lost passwords, and mapping usernames to permitted actions.%0a%0aHowever, PmWiki's ''authuser.php'' script augments the password-based system to allow access to pages based on a username and password combination. See [[AuthUser]] for more details on controlling access to pages based on user identity.%0a%0a!!Security holes ...%0a%0aAdministrators need to carefully plan where passwords are applied to avoid opening inadvertent security holes. If your wiki is open (anyone can read and edit), this would not seem to be a concern, '''except''', a malicious or confused user could apply a read password to a group and make the group completely unavailable to all other users. At the very least, even an open wiki should have a site-wide "admin" password and a site-wide "attr" password set in config.php. The ''sample-config.php'' file distributed with PmWiki indicates that the PmWiki and Main groups have "attr" locked by default, but if anyone creates a new group, "attr" is unlocked. Administrators must remember to set "attr" passwords for each new group (if desired) in this case. An easier solution is to include these lines in ''config.php'' :%0a%0a-> [@%0a$DefaultPasswords['admin'] = crypt('youradminpassword');%0a$DefaultPasswords['attr'] = crypt('yourattrpassword');%0a@]%0a%0a!! Encrypting passwords in ''config.php'' [[#crypt]]%0a%0aOne drawback to using the crypt() function directly to set passwords in ''config.php'' is that anyone able to view the file will see the unencrypted password. For example, if ''config.php'' contains%0a%0a-> $DefaultPasswords['admin'] = crypt('mysecret');%0a%0athen the "mysecret" password is in plain text for others to see. However, a wiki administrator can obtain and use an encrypted form of the password directly by using [@?action=crypt@] on any PmWiki url (or just jump to [[{$Name}?action=crypt]]). This action presents a form that generates encrypted versions of passwords for use in the ''config.php'' file. For example, when [@?action=crypt@] is given the password "@@mysecret@@", PmWiki will return a string like%0a%0a-> [@$1$hMMhCdfT$mZSCh.BJOidMRn4SOUUSi1@]%0a%0aThe string returned from [@?action=crypt@] can then be placed directly into config.php, as in:%0a%0a-> $DefaultPasswords['admin'] = [='$1$hMMhCdfT$mZSCh.BJOidMRn4SOUUSi1'=]; %0a%0aNote that in the encrypted form the ''crypt'' keyword and parentheses are removed, since the password is already encrypted. Also, the encrypted password must be in single quotes. In this example the password is still "@@mysecret@@", but somebody looking at ''config.php'' won't be able to see that just from looking at the encrypted form. ''Crypt'' may give you different encryptions for the same password--this is normal (and makes it harder for someone else to determine the original password).%0a%0a!! Removing passwords%0a%0aTo remove a site password entirely, such as the default locked password for uploads, just set it to empty:%0a%0a-> $DefaultPasswords['upload'] = '';%0a%0aYou can also use the special password "@nopass" via @@?action=attr@@ to have a non-password protected page within a password-protected group, or a non-password protected group with a site-wide default password set.%0a%0a!! Revoking or invalidating passwords%0a%0aIf a password is compromised and the wiki administrator wants to quickly invalidate all uses of that password on a site, a quick solution is the following in ''local/config.php'':%0a%0a-> [@%0a$ForbiddenPasswords = array('secret', 'tanstaafl');%0aif (in_array(@$_POST['authpw'], $ForbiddenPasswords)) %0a unset($_POST['authpw']);%0a@]%0a%0aThis prevents "secret" and "tanstaafl" from ever being accepted as a%0avalid authorization password, regardless of what pages may be%0ausing it.%0a%0a!! See Also%0a%0a* The $HandleAuth array, which sets the required authentication level that is necessary to perform an action.%0a* [[Cookbook:RequireAuthor]]%0a%0a!! Protecting actions (example)%0a%0aEach [[(available) action(s)]] can be password protected. Cookbook authors providing scripts with own actions can use this also, but I'll limit the example to a (by default) not protected [@?action=source@]. This action shows the wikisource of the actual page. Sometimes you don't want that especially to [[Cookbook:protect email]] or when using some [[PmWiki/conditional markup]] which should not be discovered easily or only by persons that are allowed to edit the page.%0a%0aThere are several solutions for that:%0a# Limit "source" only to editors add the following to your ''local/config.php'':%0a %0a--> [@$HandleAuth['source'] ='edit';@]%0a%0a# For using "source" with an own password, then add:%0a%0a--> [@$HandleAuth['source'] ='source';@]%0a--> [@$DefaultPasswords['source'] = crypt(secret);@] # ''see above''%0a%0aIf you additionally want to set the password in the attributes page add:%0a%0a--> [@$PageAttributes['passwdsource'] = "$['Set new source password']";@]%0a%0aIn general, adding the prefix 'passwd' to an action name in the [@$PageAttributes@] array indicates that you wish for the given field to be encrypted when saved to disk.%0a%0aThe full set of steps to add new password handling for an action such as "diff" would be:%0a%0a->[@%0a# add a new (encrypted) field to the attr page%0a$PageAttributes['passwddiff'] = '$[Set new history password]';%0a%0a# clear the default password for 'diff'%0a$DefaultPasswords['diff'] = '';%0a%0a# Tell PmWiki that the 'diff' password allows action 'diff'.%0a$HandleAuth['diff'] = 'diff';%0a%0a# Tell PmWiki that a 'read' password %0a# (or optionally the 'edit') password%0a# is also sufficient to enable 'diff'.%0a# Of course, the 'admin' password will work too.%0a$AuthCascade['diff'] = 'read'; ## or 'edit'%0a@]%0a%0a>>faq%3c%3c [[#faq]]%0a%0aQ: There seems to be a default password. What is it? [[#pwlocked]]%0aA: There isn't any valid password until you set one. [[Passwords admin]] describes how to set one.%0a%0aPmWiki comes "out of the box" with $DefaultPasswords['admin'] set to '*'. This doesn't mean the password is an asterisk, it means that default admin password has to be something that encrypts to an asterisk. Since it's impossible for the crypt() function to ever return a 1-character encrypted value, the admin password is effectively locked until the admin sets one in config.php.%0a%0aQ: How do I use passwd-formatted files (like .htpasswd) for authentication?%0aA: See [[AuthUser]], Cookbook:HtpasswdForm or Cookbook:UserAuth.%0a%0aQ: Is there anything I can enter in a GroupAttributes field to say 'same as the admin password'? If not, is there anything I can put into the config.php file to have the same effect?%0a%0aA: Enter '@lock' in GroupAttributes?action=attr to require an admin password for that group.%0a%0aQ: How do I edit protect, say, all RecentChanges pages?%0aA: see [[PmWiki/Security#wikivandalism]].%0a%0aQ: How can I read password protect all pages in a group except the HomePage using configuration files?%0a%0aA: As described in [[PmWiki.GroupCustomizations]] per-group or per-page configuration files should not be used for defining passwords. The reason is that per-group (or per-page) customization files are only loaded for the current page. So, if @@[=$DefaultPasswords['read']=]@@ is set in ''local/GroupA.php'', then someone could use a page in another group to view the contents of pages in GroupA. For example, Main.WikiSandbox could contain:%0a%0a--> [=(:include GroupA.SomePage:)=]%0a%0aand because the ''GroupA.php'' file wasn't loaded (we're looking at Main.WikiSandbox --> ''local/Main.php''), there's no read password set.%0a%0aQ: How can I password protect the creation of new pages?%0aA: See Cookbook:LimitWikiGroups, Cookbook:NewGroupWarning, Cookbook:LimitNewPagesInWikiGroups.%0a%0aQ: How do I change the password prompt screen?%0aA: If your question is about how to make changes to that page... edit [[Site.AuthForm]]. If your question is about how to change which page you are sent to when prompted for a password, you might check out the [[Cookbook:CustomAuthForm]] for help.%0a%0aQ: How do I change the prompt on the attributes (@@?action=attr@@) screen?%0aA: Simply create a new page at [[Site.AttrForm]], and add the following line of code to @@config.php@@:%0a-->@@$PageAttrFmt = 'page:Site.AttrForm';@@%0a%0aNote that this only changes the text above the password inputs on the attributes page, but doesn't change the inputs themselves - the inputs have to be dealt with separately. See [[Cookbook:CustomAttrForm]] for more info.%0a%0aQ: I get http error 500 "Internal Server Error" when I try to log in. What's wrong?%0aA: This can happen if the encrypted passwords are not created on the web server that hosts the PmWiki.\\%0aThe crypt function changed during the PHP development, e.g. a password encrypted with PHP 5.2 can not be decrypted in PHP 5.1, but PHP 5.2 can decrypt passwords created by PHP 5.1.\\%0aThis situation normally happens if you prepare everything on your local machine with the latest PHP version and you upload the passwords to a webserver which is running an older version.\\%0aThe same error occurs when you add encrypted passwords to local/config.php.%0a%0aSolution: Create the passwords on the system with the oldest PHP version and use them on all other systems.%0a%0aQ: I only want users to have to create an 'edit' password, which is automatically used for their 'upload' & 'attr' passwords (without them having to set those independently). How do I do this?%0aA: By setting [@$HandleAuth@] like so:%0a $HandleAuth['upload'] = 'edit';%0a // And to prevent a WikiSandbox from having it's 'attr' permissions changed %0a // except by the admin (but allowing editors to change it on their own pages/group)%0a if(($group=="Site") || ($group=="Main") || ($group=="Category") || %0a ($group=="SiteAdmin") || ($group=="PmWiki") ) {%0a $HandleAuth['attr'] = 'admin'; // for all main admin pages, set 'attr' to 'admin' password%0a } else { %0a $HandleAuth['attr'] = 'edit'; // if you can edit, then you can set attr%0a }%0a%0a
+time=1259868588
diff --git a/wikilib.d/PmWiki.PathVariables b/wikilib.d/PmWiki.PathVariables
new file mode 100644
index 0000000..2e590ef
--- /dev/null
+++ b/wikilib.d/PmWiki.PathVariables
@@ -0,0 +1,11 @@
+version=pmwiki-2.2.1 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.19) Gecko/20081216 Ubuntu/8.04 (hardy) Firefox/2.0.0.19
+author=Petko
+charset=ISO-8859-1
+csum=fix link
+host=81.65.14.164
+name=PmWiki.PathVariables
+rev=59
+targets=PmWiki.LocalCustomizations,PmWiki.WikiFarms,PmWiki.LayoutVariables,PmWiki.LinkVariables,PmWiki.EditVariables,PmWiki.UploadVariables
+text=(:Summary:variables used to specify various locations on the server:)%0a%0aWhen dealing with file or path variables, one has to recognize the difference between working with URLs and files on disk. For example:%0a* The include() statements are used to include other files (on disk) into the currently running PmWiki script. Thus they require paths on the server's filesystem. %0a* The $ScriptUrl and $PubDirUrl variables are used to tell a ''browser'', connecting via the webserver, how to execute the pmwiki script ($ScriptUrl) and the base url for getting files from PmWiki's pub/ directory ($PubDirUrl).%0a%0aNote that a browser needs a URL (http://example.com/pmwiki/pub) while an include statement requires a server file path ($FarmD/scripts/something.php).%0a%0a:$FarmD:The directory on the server where the farm is located (i.e., the directory containing the farm's copy of ''pmwiki.php'' and the ''scripts/'' directory). This directory is automatically determined by pmwiki.php when it runs, and can be used to distinguish the farm's ''cookbook/'' and ''pub/'' subdirectories from a field's subdirectories.%0a%0a:$FarmPubDirUrl:is the url that refers to the @@pub@@ directory for an entire farm. It defaults to the same value as $PubDirUrl. %0a%0a:$PageCSSListFmt:is an associative array which PmWiki uses to find any local css configuration files. It consists of a set of (''key'',''value'') pairs %25green%25 that point to the same file%25%25. The ''key'' is a possible path to a file on disk holding the css data, while the ''value'' is the coresponding URL for that %25green%25same file%25%25. They keys are tested in turn, and for each named file that exists, the browser is instructed to load the corresponding URL. This allows for PMWiki to only load the css file if it exists. ([[PmWiki:WhySeeIfCSSExists|Why see if a CSS exists?]]) The default value for this variable is:%0a%0a->[@%0a$PageCSSListFmt = array(%0a 'pub/css/local.css' => '$PubDirUrl/css/local.css',%0a 'pub/css/{$Group}.css' => '$PubDirUrl/css/{$Group}.css',%0a 'pub/css/{$FullName}.css' => '$PubDirUrl/css/{$FullName}.css');%0a@]%0a%0a->Note that the default (as of version pmwiki-2.1.beta26) makes no reference to $FarmPubDirUrl for css configuration files. If you wish to be able to place css configuration files in both the field's @@pub@@ directory, and the farm's @@pub@@ directory, you may want to add these lines to your @@local/config.php@@ file (as described in [[Cookbook:SharedPages]]):%0a%0a-> %25green%25# this adds farm.css to all wikis%0a->[@%0a$PageCSSListFmt = array(%0a '$FarmD/pub/css/farm.css' => '$FarmPubDirUrl/css/farm.css',%0a 'pub/css/local.css' => '$PubDirUrl/css/local.css',%0a 'pub/css/$Group.css' => '$PubDirUrl/css/$Group.css',%0a 'pub/css/$FullName.css' => '$PubDirUrl/css/$FullName.css');%0a@]%0a%0a-> %25green%25# this enables farm css files in a similar manner to a local wiki%0a->[@%0a$PageCSSListFmt = array(%0a '$FarmD/pub/css/local.css' => '$FarmPubDirUrl/css/local.css',%0a '$FarmD/pub/css/$Group.css' => '$FarmPubDirUrl/css/$Group.css',%0a '$FarmD/pub/css/$FullName.css' => '$FarmPubDirUrl/css/$FullName.css',%0a 'pub/css/local.css' => '$PubDirUrl/css/local.css',%0a 'pub/css/$Group.css' => '$PubDirUrl/css/$Group.css',%0a 'pub/css/$FullName.css' => '$PubDirUrl/css/$FullName.css');%0a@]%0a%0a->Note the difference between CSS configuration files and CSS files associated with a skin. Skin files, including associated CSS, can be put in either the farm or the field @@pub/skins@@ directory, and the program will find them.%0a%0a:$PubDirUrl: is the URL that refers to the @@pub@@ directory. That directory contains all the files and subdirectories that must be directly accessible from a browser (e.g. CSS and HTML files). Most prominent here is the @@skins@@ subdirectory.%0a->The following may work for you'^[[Cookbook:CleanUrls#multiviews|#]]^'%0a->[@ $ScriptUrl = 'http://'.$_SERVER['HTTP_HOST'].'/pmwiki/pmwiki.php';%0a $PubDirUrl = 'http://'.$_SERVER['HTTP_HOST'].'/pmwiki/pub';@]%0a%0a:$ScriptUrl: is the URL that you want people's browsers to use when accessing PmWiki, either as a field or farm. It's used whenever PmWiki needs to generate a link to another PmWiki page or action. PmWiki is usually fairly good about "guessing" the correct value for $ScriptUrl on its own, but sometimes an admin needs to set it explicitly because of URL manipulations by the webserver (such as Cookbook:CleanUrls, mod_rewrite, bizarre PHP configurations, and so on).%0a%0a:$SkinDirUrl:Set by ''scripts/skins.php'' to be the base url of the current skin's directory (i.e., within a 'pub/skins/' directory). This variable is typically used inside of a skin .tmpl file to provide access to .css files and graphic images associated with the skin.%0a%0a:$WorkDir:%0a: :This variable is a string that gives a local path to a directory where the pmwiki engine can create temporary files etc. PmWiki needs this for a variety of things, such as building merged edits, caching mailposts entries, keeping track of the last modification time of the site, other types of cache, etc. Do not confuse this variable with $WikiDir; the reason that both $WorkDir and $WikiDir refer by default to the directory [@wiki.d/@] is merely to simplify things for the administrator. %0a%0a:$WikiDir: %0a: :$WikiDir is a `PageStore-object that refers to how wiki pages are stored. This can be a simple reference to a directory (typically ''wiki.d/''), or something more advanced such as a `MySQL backend or a .dbm-file. Do not confuse this variable with $WorkDir; the reason that both $WorkDir and $WikiDir refer by default to the directory [@wiki.d/@] is merely to simplify things for the administrator.%0a: :To store groups of pages in subdirectories add [@$WikiDir = new PageStore('wiki.d/$Group/$FullName');@] to the start of your config file. '^[[Cookbook:PerGroupSubDirectories|#]]^'%0a%0a:$WikiLibDirs:%0a: :$WikiLibDirs is an array of `PageStore objects that specify where to look for pages. By default it is set up to look in ''wiki.d/'' and ''wikilib.d/'', but can be changed to look other places. %0a: :For example, to exclude the pages that are bundled in the PmWiki distribution, use the line below. (Note that some features such as editing and search rely on having certain pages available, so you may need to copy them to the $WikiDir.)%0a $WikiLibDirs = array(&$WikiDir);%0a: :Another example%0a->[@%0a ## for any page name, use the version located in wiki.d if it exists,%0a ## use the version located in wikilib2.d, if a wiki.d version does not, and%0a ## the version located in wikilib.d, if neither of the above exists%0a $WikiLibDirs = array(&$WikiDir,%0a new PageStore('wikilib2.d/{$FullName}'),%0a new PageStore('$FarmD/wikilib.d/{$FullName}'));%0a@]%0a: : See also [[(http://www.pmwiki.org/wiki/Category/)CustomPageStore]].%0a%0a%0a:$LocalDir:The filesystem location of the ''local/'' directory, holding [[local customization(s)]] and [[(PmWiki:)per group customizations]] files. Typically set in a [[WikiFarm(s)]]'s ''farmconfig.php''. (Note that farm configuration files always occur in ''$FarmD/local/farmconfig.php'', regardless of any setting for $LocalDir.)%0a%0a%0a!!See also%0a* [[Layout Variables]] for URL layout options%0a* [[Link Variables]] - variables that control the display of links in pages%0a* [[Edit Variables]] - variables used when editing pages%0a* [[Upload Variables]] - variables used for uploads/attachments%0a
+time=1238276292
diff --git a/wikilib.d/PmWiki.PatrickMichaud b/wikilib.d/PmWiki.PatrickMichaud
new file mode 100644
index 0000000..f361078
--- /dev/null
+++ b/wikilib.d/PmWiki.PatrickMichaud
@@ -0,0 +1,10 @@
+version=pmwiki-2.1.beta38 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (Windows; U; Win98; en-US; rv:1.7.12) Gecko/20050915
+author=HaganFox
+csum=Removed self-referencing link
+host=216.161.175.221
+name=PmWiki.PatrickMichaud
+rev=12
+targets=
+text=Patrick Michaud (Pm) is the author of PmWiki. More information about him can be found at http://www.pmichaud.com.
+time=1142132859
diff --git a/wikilib.d/PmWiki.PerGroupCustomizations b/wikilib.d/PmWiki.PerGroupCustomizations
new file mode 100644
index 0000000..0920a18
--- /dev/null
+++ b/wikilib.d/PmWiki.PerGroupCustomizations
@@ -0,0 +1,11 @@
+version=pmwiki-2.2.4 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.19) Gecko/20081216 Ubuntu/8.04 (hardy) Firefox/2.0.0.19
+author=Petko
+charset=ISO-8859-1
+csum=redirect GroupCustomizations
+host=86.69.109.9
+name=PmWiki.PerGroupCustomizations
+rev=38
+targets=
+text=(:redirect GroupCustomizations:)%0a(:Summary: Redirects to [[PmWiki.GroupCustomizations]]:)
+time=1250689588
diff --git a/wikilib.d/PmWiki.PmWiki b/wikilib.d/PmWiki.PmWiki
new file mode 100644
index 0000000..fa1939e
--- /dev/null
+++ b/wikilib.d/PmWiki.PmWiki
@@ -0,0 +1,10 @@
+version=pmwiki-2.1.beta38 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (X11; U; Linux i686 (x86_64); en-US; rv:1.8) Gecko/20051128 SUSE/1.5-0.1 Firefox/1.5
+author=Pm
+csum=
+host=24.1.26.255
+name=PmWiki.PmWiki
+rev=121
+targets=PmWiki.WikiWikiWeb,Main.WikiSandbox,PmWiki.BasicEditing,PmWiki.Skins,PmWiki.PmWikiPhilosophy,PmWiki.Installation
+text=PmWiki is a [[wiki(WikiWeb)]]-based system for collaborative creation and maintenance of websites.%0a%0aPmWiki pages look and act like normal web pages, except they have an "[[Main/WikiSandbox?action=edit|Edit]]" link that makes it easy to modify existing pages and add new pages into the website, using [[basic editing]] rules. You do not need to know or use any HTML or CSS. Page editing can be left open to the public or restricted to small groups of authors.%0a%0a!!Key PmWiki Features%0a%0a-%3c'''Custom look-and-feel''': A site administrator can quickly change the appearance and functions of a PmWiki site by using different [[skins]] and HTML templates. If you can't find an appropriate skin [[already made -> Cookbook:Skins]], you can easily modify one or create your own.%0a%0a-%3c'''Access control''': PmWiki password protection can be applied to an entire site, to groups of pages, or to individual pages. Password protection controls who can read pages, edit pages, and upload attachments. PmWiki's access control system is completely self-contained, but it can also work in conjunction with existing password databases, such as ''.htaccess'', LDAP servers, and MySQL databases.%0a%0a-%3c'''Customization and plugin architecture''': One principle of the [[PmWikiPhilosophy]] is to only include essential features in the core engine, but make it easy for administrators to customize and add new markup. Hundreds of features are already available by using extensions (called "recipes") that are available from the PmWiki [[(Cookbook:)Cookbook]].%0a%0aPmWiki is written in %25newwin%25[[http://php.net/|PHP]] and distributed under the %25newwin%25[[http://www.gnu.org/copyleft/gpl.html|General Public License]]. It is designed to be simple to [[PmWiki/install(ation)]], customize, and maintain for a variety of applications. This site is running {$Version}.%0a%0aPmWiki is a registered trademark of [[http://www.pmichaud.com/ | Patrick R. Michaud ]].%0a%0aPmWiki's home on the web is at [[(http://)pmwiki.org(/)]].%0a
+time=1142195525
diff --git a/wikilib.d/PmWiki.PmWikiPhilosophy b/wikilib.d/PmWiki.PmWikiPhilosophy
new file mode 100644
index 0000000..ddb9892
--- /dev/null
+++ b/wikilib.d/PmWiki.PmWikiPhilosophy
@@ -0,0 +1,11 @@
+version=pmwiki-2.2.0-beta68 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.0.1) Gecko/2008070208 Firefox/3.0.1
+author=simon
+charset=ISO-8859-1
+csum=trail
+host=203.97.214.12
+name=PmWiki.PmWikiPhilosophy
+rev=48
+targets=PmWiki.PatrickMichaud,PmWiki.Audiences,PmWiki.WikiWikiWeb,PmWiki.CustomMarkup
+text=(:Summary:This page describes some of the ideas that guide the design and implementation of PmWiki:)%0aThis page describes some of the ideas that guide the design and implementation of PmWiki. [[Patrick Michaud]] doesn't claim that anything listed below is an original idea; these are just what drive the development of PmWiki. You're welcome to express your disagreement with anything listed below. [[PmWiki.Audiences]] also describes much of the reasoning behind the ideas given below.%0a%0a:''1. Favor writers over readers'':At its heart, PmWiki is a collaborative authoring system for hyperlinked documents. It's hard enough to get people (including Pm) to contribute written material; making authors deal with HTML markup and linking issues places more obstacles to active contribution. So, PmWiki aims to make it easier to author documents, even if doing so limits the types of documents being authored.%0a%0a:''2. Don't try to replace HTML'':PmWiki doesn't make any attempt to do everything that can be done in HTML. There are good reasons that people don't use web browsers to edit HTML--it's just not very effective. If you need to be writing lots of funky HTML in a web page, then PmWiki is not what you should be using to create it. What PmWiki does try to do is make it easy to link PmWiki to other "non-wiki" web documents, to embed PmWiki pages inside of complex web pages, and to allow other web documents to easily link to PmWiki.%0a%0a: :This principle also follows from the "favor writers over readers" principle above--every new feature added to PmWiki requires some sort of additional markup to support it. Pretty soon the source document looks pretty ugly and we'd all be better off just writing HTML. %0a%0a: :Another reason for avoiding arbitrary HTML is that ill-formed HTML can cause pages to stop displaying completely, and arbitrary HTML can be a security risk--more so when pages can be created anonymously. See http://www.cert.org/advisories/CA-2000-02.html for more information. %0a%0a:''3. Avoid gratuitous features (or "creeping featurism")'':In general PmWiki features are implemented in response to specific needs, rather than because someone identifies something that "might be useful". In any sort of useful system, it's hard to change a poorly designed feature once people have built a lot of structure based on it. (Need an example? Look at MS-DOS or Windows.) One way to avoid poor design is to resist the temptation to implement something until you have a clearer idea of how it will be used. %0a%0a:''4. Support collaborative maintenance of public web pages'':Although this wasn't at all the original intent of PmWiki, it became quickly obvious that [[WikiWikiWeb]] principles could be used to make it easier for groups to collaboratively design and maintain a public web site presence. PmWiki allows individual pages to be password protected, and a couple of local customizations makes it easy to protect large sections of PmWiki pages. Furthermore, in many ways PmWiki provides "style sheets on steroids": you can quickly change the headers, footers, and other elements on a large group of pages without ever having to touch the individual page contents. Finally, it's relatively easy to add [[custom markup]] for specialized applications.%0a%0a:''5. Be easy to install, configure, and maintain'': With a gzip-compressed file size of just around 200K, uploading PmWiki to your server is a speedy operation. Do a chmod or two, update a few settings in config.php and you should be up and running. PmWiki stores all data in flat files, so there is no need for `MySQL or other utilities. Upgrading is usually a simple matter of copying the latest version's files over the files of your existing PmWiki installation. (One of the biggest reasons for the creation of PmWiki was that other wiki engines at the time required modifications to the distribution files, so admins ended up losing their customizations on every upgrade.)%0a%0a
+time=1220178849
diff --git a/wikilib.d/PmWiki.RefCount b/wikilib.d/PmWiki.RefCount
new file mode 100644
index 0000000..97d50c3
--- /dev/null
+++ b/wikilib.d/PmWiki.RefCount
@@ -0,0 +1,11 @@
+version=pmwiki-2.2.0 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.19) Gecko/20081216 Ubuntu/8.04 (hardy) Firefox/2.0.0.19
+author=Petko
+charset=ISO-8859-1
+csum=refactored
+host=81.65.14.164
+name=PmWiki.RefCount
+rev=37
+targets=PmWiki.WikiAdministrator,PmWiki.LocalCustomizations,PmWiki.RefCount
+text=(:Summary: Link references counts on pages:)%0aRefCount performs link reference counts on pages in the PmWiki database (i.e., counts of links between pages). Before using RefCount, it must be enabled by the [[wiki administrator]] by placing the following line in a [[local customization(s)]] file:%0a%0a->[@include_once("$FarmD/scripts/refcount.php");@]%0a%0aTo use refcount add [@?action=refcount@] to the URL of any wiki page to bring up the reference count form. For example:%0a%0a->%25newwin%25[[{$FullName}?action=refcount]]%0a%0aThe refcount form contains the following controls:%0a[[#refcountcontrols]]%0a*'''Show''' ~ This selects which pages will appear in the output%0a**all ~ Shows all references %0a**missing ~ Shows only references to pages that don't exist%0a**existing ~ Shows only references to pages that do exist%0a**orphaned ~ Shows pages that exist but don't have any references to them. There is no way to browse to an orphaned page.%0a*'''page names in group''' ~ Selects which group(s) to the referenced pages can be in%0a*'''referenced from pages in''' ~ Selects which group(s) the referencing pages can be in%0a*'''Display referencing pages''' ~ Includes a link to the referencing page -- this can make for a very long output unless you limit the groups searched%0a[[#refcountcontrolsend]]%0a%0aThe output is a table where each row of the table contains a page name or link reference, the number of (non-RecentChanges) pages that contain links to the page and the number of Recent Changes pages with links to the page.%0a%0a
+time=1234652365
diff --git a/wikilib.d/PmWiki.ReleaseNotes b/wikilib.d/PmWiki.ReleaseNotes
new file mode 100644
index 0000000..d18d390
--- /dev/null
+++ b/wikilib.d/PmWiki.ReleaseNotes
@@ -0,0 +1,12 @@
+version=pmwiki-2.2.12 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.7) Gecko/20100106 Ubuntu/9.10 (karmic) Firefox/3.5.7
+author=Petko
+charset=ISO-8859-1
+csum=
+host=81.65.12.233
+name=PmWiki.ReleaseNotes
+rev=446
+targets=PmWiki.PageHistory,PmWiki.Uploads,PmWiki.Passwords,PmWiki.SiteAnalyzer,PmWiki.WikiTrails,Site.Site,SiteAdmin.SiteAdmin,PITS.00961,Site.PageActions,Site.EditForm,Site.PageNotFound,PmWiki.PageLists,PmWiki.Drafts,PmWiki.Blocklist,SiteAdmin.AuthList,Cookbook.Cookbook,Cookbook.DebuggingForCookbookAuthors,PmWiki.SkinTemplates,PmWiki.AuthUser,Site.AuthUser,Cookbook.Flash,PITS.00573,PmWiki.WikiFarms,PmWiki.MailPosts,PmWiki.Notify,PmWiki.LocalCustomizations,Site.PageListTemplates,Site.SideBar,PmWiki.PageVariables,PmWiki.WebFeeds,PmWiki.InterMap,PITS.00563,PmWiki.WikiStyles,PITS.00560,Cookbook.SharedPages,PITS.00459,PITS.00590,PmWiki.ConditionalMarkup,PITS.00566,PITS.00588,PmWiki.Subversion,PmWiki.ReleaseNotesArchive
+text=(:title Release Notes:)(:Summary: Notes about new versions, important for upgrades:)%0a!! Version 2.2.13 (2010-02-21)%0aThis release fixes a bug with $DiffKeepNum introduced in 2.2.10 -- the count of revisions was incorrect and a page could drop more revisions than it should.%0a%0aThe [[page history]] layout was modified with a rough consensus in the community. The history now defaults to "source" view with word-level highlighting of the differences. Authors can see the changes in rendered output by clicking on the link "Show changes to output". Admins can switch back the default by adding such a line to config.php:%0a%0a $DiffShow['source'] = (@$_REQUEST['source']=='y')?'y':'n';%0a%0aTo disable word-level highlighting and show plain text changes:%0a%0a $EnableDiffInline = 0;%0a%0aIn the page history rendering, a few minor bugs were fixed and the code was slightly optimized.%0a%0aThe documentation was updated.%0a%0a!! Version 2.2.12 (2010-02-17)%0aThis release adds simple word-level highlighting of differences in the page history, when "Show changes to markup" is selected. To enable the feature, add to config.php such a line:%0a $EnableDiffInline = 1;%0a%0aThis feature is like what the InlineDiff recipe provides, but not exactly the same, and the implementation is simpler. It is enabled on PmWiki.org and can be improved -- your comments are welcome.%0a%0a!! Version 2.2.11 (2010-02-14)%0aThis release adds two new table directives for header cells, [=(:head:) and (:headnr:)=]. They work the same way as [=(:cell:) and (:cellnr:)=] except that create %3cth> instead of %3ctd> html tags.%0a%0aThe pagerev.php script was refactored into separate functions to allow easier integration of recipes displaying the page history.%0a%0aA couple of minor bugs were fixed and the documentation was updated.%0a%0a!! Version 2.2.9, 2.2.10 (2010-01-17)%0aMost important in this release is the official change of $EnableRelativePageVars to 1. The change is about how [={$Variable}=] in included pages is understood by PmWiki.%0a* When $EnableRelativePageVars is set to 0, [={$Name}=] displays the name of the currently browsed page. Even if [={$Name}=] is in an included page, it will display the name of the browsed page.%0a* When $EnableRelativePageVars is set to 1, [={$Name}=] displays the name of the physical page where it written. If [={$Name}=] is in an included page, it will display the name of the included page.%0a* [={*$Name}=] always displays the name of the currently browsed page, regardless of $EnableRelativePageVars.%0a%0aSo, if your wiki relies on page variables from included pages, and doesn't have $EnableRelativePageVars set to 1, after upgrading to 2.2.9, you can revert to the previous behavior by adding to config.php such a line:%0a $EnableRelativePageVars = 0;%0a%0aMore information about page variables can be found at:%0a http://www.pmwiki.org/wiki/PmWiki/PageVariables%0a%0aThis release adds a new variable $EnablePageTitlePriority which defines how to treat multiple [=(:title..:)=] directives. If set to 1, the first title directive will be used, and if a page defines a title, directives from included pages cannot override it. PmWiki default is 0, for years, the last title directive was used (it could come from an included page or GroupFooter).%0a%0aThis release also adds a new variable $DiffKeepNum, specifying the minimum number (default 20) of edits that will be kept even if some of them are older than the limit of $DiffKeepDays.%0a%0aA number of bugs were fixed and the documentation was updated.%0a%0a!! Version 2.2.8 (2009-12-07)%0aThis release fixes another PHP 5.3 compatibility issue with conditional markup. The Author field now handles apostrophes correctly. The documentation was updated.%0a%0a!! Version 2.2.7 (2009-11-08)%0aThis release fixes most PHP 5.3 compatibility issues. Unfortunately some specific builds for Windows may still have problems, which are unrelated to PmWiki. Notably, on Windows, all passwords need to be 4 characters or longer.%0a%0aUpload names with spaces are now correctly quoted. The documentation was updated.%0a%0a!! Version 2.2.6 (2009-10-04)%0aWith this release it is now possible to display recently uploaded files to the RecentChanges pages -- if you have been using the RecentUploadsLog recipe, please uninstall it and follow the instructions at http://www.pmwiki.org/wiki/Cookbook/RecentUploadsLog.%0a%0aThe release also introduces $MakeUploadNamePatterns to allow custom filename normalization for attachements. It is now possible to replace $PageListFilters and $FPLTemplateFunctions with custom functions. Notify should now work in safe_mode. Some bugs were fixed, among which one with conditional markup with dates. The documentation was updated.%0a%0a!! Version 2.2.5 (2009-08-25)%0aThis release adds a new markup for Pagelist templates, [@(:template none:)@] which allows a message to be set when the search found no pages. The FPLTemplate() function was broken into configurable sub-parts to allow development hooks. A number of bugs were fixed, and the documentation was updated.%0a%0a!! Version 2.2.4 (2009-07-16)%0aThis release fixes a bug introduced earlier today with HTML entities in XLPages.%0a%0a!! Version 2.2.3 (2009-07-16)%0aThis release fixes six potential XSS vulnerabilities, reported by Michael Engelke. The vulnerabilities may affect wikis open for editing and may allow the injection of external JavaScripts in their pages. Public open wikis should upgrade.%0a%0aA new variable $EnableUploadGroupAuth was added; if set to 1, it allows password-protected [[uploads]] to be checked against the Group password. %0a%0aIt is now possible to use @@ @_site_edit, @_site_read, @_site_admin@@ or @@ @_site_upload @@ global [[passwords]] in GroupAttributes pages.%0a%0aA number of other small bugs were fixed, and the documentation was updated.%0a%0a!! Version 2.2.2 (2009-06-21)%0aThe major news in this release is a fix of an AuthUser vulnerability.%0a%0aThe vulnerability affects only wikis that (1) rely on the AuthUser core module %0afor User:Password authentication, -AND- (2) where the PHP installation runs %0awith the variable "magic_quotes_gpc" disabled.%0a%0aAll PmWiki 2.1.x versions from pmwiki-2.1.beta6 on, all 2.2.betaX, 2.2.0, and %0a2.2.1 are affected.%0a%0aThe PmWiki [[SiteAnalyzer]] can detect if your wiki needs to upgrade:%0a http://www.pmwiki.org/wiki/PmWiki/SiteAnalyzer%0a%0aIf your wiki is vulnerable, you should do one of the following at the earliest %0aopportunity:%0a%0a* Upgrade to a version of PmWiki at least 2.2.2 or greater.%0a* Turn on magic_quotes_gpc in the php.ini file or in a .htaccess file.%0a%0aAlternatively, you can temporarily disable AuthUser until you upgrade.%0a%0aNote that even if your wiki does not have the AuthUser vulnerability at the %0amoment, you are strongly encouraged to upgrade to PmWiki version 2.2.2 or %0alater, as some future configuration of your hosting server might put you at %0arisk.%0a%0aThis release also comes with minor updates in the local documentation; fixes %0awere applied for international wikis - notably global variables in %0axlpage-utf-8.php and a new variable $EnableNotifySubjectEncode, which allows %0ae-mail clients to correctly display the Subject header; and a number of other %0asmall bugs were fixed.%0a%0a!! Version 2.2.1 (2009-03-28)%0aThis release comes with an updated local documentation; [[wiki trails]] now work cross-group; guiedit.php now produces valid HTML, and other small bugs were fixed. We also added $EnableRedirectQuiet, which allows redirects to take place without any mention of "redirected from page ....".%0a%0a!! Version 2.2.0 (2009-01-18)%0a%0aThis is a summary of changes from 2.1.x to 2.2.0.%0a%0a* Several pages that were formerly in the [[Site]].* group are now in a separate [[SiteAdmin]].* group, which is read-restricted by default. The affected pages include Site.AuthUser, Site.AuthList, Site.NotifyList, Site.Blocklist, and Site.ApprovedUrls . If upgrading from an earlier version of PmWiki, PmWiki will prompt to automatically copy these pages to their new location if needed. If a site wishes to continue using the old Site.* group for these pages, simply set%0a%0a-> $SiteAdminGroup = $SiteGroup;%0a%0a-> when carrying out this upgrade inspect your config files for lines such as%0a--> $BlocklistDownload['Site.Blocklist-PmWiki'] = array('format' => 'pmwiki');%0a->as you may wish to fix then, eg%0a--> $BlocklistDownload[$SiteAdminGroup . '.Blocklist-PmWiki'] = array('format' => 'pmwiki');%0a%0a* Important Change in Passwords in PmWiki 2.2 indicating that the group can be edited even if a site password is set will be done by @@"@nopass"@@ prior it was done by @@"nopass"@@%0a-> When migrating a wiki you will have to manually modify the permission or by a script replace in all the page concerned @@passwdread=nopass:@@ by @@passwdread=@nopass@@ (see PITS:00961) --isidor%0a%0a* PmWiki now ships with WikiWords entirely disabled by default. To re-enable them, set either $LinkWikiWords or $EnableWikiWords to 1. To get the 2.1 behavior where WikiWords are spaced and parsed but don't form links, use the following:%0a-> $EnableWikiWords = 1;%0a-> $LinkWikiWords = 0;%0a%0a* It's now easy to disable the rule that causes lines with leading spaces to be treated as preformatted text -- simply set $EnableWSPre=0; to disable this rule.%0a%0a--> '''Important:''' There is ongoing discussion that the leading whitespace rule may be disabled ''by default'' in a future versions of PmWiki. If you want to make sure that the rule will continue to work in future upgrades, set $EnableWSPre=1; in ''local/config.php''.%0a%0a* The $ROSPatterns variable has changed somewhat -- replacement strings are no longer automatically passed through FmtPageName() prior to substitution (i.e., it must now be done explicitly).%0a%0a* Page variables and page links inside of [@(:include:)@] pages are now treated as relative to the included page, instead of the currently browsed page. In short, the idea is that links and page variables should be evaluated with respect to the page in which they are written, as opposed to the page in which they appear. This seems to be more in line with what authors expect. There are a number of important ramifications of this change:%0a%0a[[#relativeurls]]%0a** We now have a new [@{*$var}@] form of page variable, which always refers to "the currently displayed page". Pages such as Site.PageActions and Site.EditForm that are designed to work on "the currently browsed page" should generally switch to using [@{*$FullName}@] instead of [@{$FullName}@].%0a%0a** The $EnableRelativePageLinks and $EnableRelativePageVars settings control the treatment of links and page variables in included pages. However, to minimize disruption to existing sites, $EnableRelativePageVars defaults to '''disabled'''. This will give existing sites an opportunity to convert any absolute [@{$var}@] references to be [@{*$var}@] instead.%0a%0a** Eventually $EnableRelativePageVars will be enabled by default, so we highly recommend setting [@$EnableRelativePageVars = 1;@] in ''local/config.php'' to see how a site will react to the new interpretation. Administrators should especially check any customized versions of the following:%0a---> [[Site.PageActions]]%0a---> [[Site.EditForm]]%0a---> [[Site.PageNotFound]]%0a---> SideBar pages with ?action= links for the current page%0a---> $GroupHeaderFmt, $GroupFooterFmt%0a---> [[Page lists]] that refer to the current group or page, etc in sidebars, headers, and footers%0a%0a** The [@(:include:)@] directive now has a [@basepage=@] option whereby an author can explicitly specify the page upon which relative links and page variables should be based. If no basepage= option is specified, the included page is assumed to be the base.%0a%0a* Sites that want to retain the pre-2.2 behavior of [@(:include:)@] and other items can set [@$Transition['version'] = 2001900;@] to automatically retain the 2.1.x defaults.%0a%0a* Text inserted via [@(:include:)@] can contain "immediate substitutions" of the form [@{$$option}@] -- these are substituted with the value of any options provided to the include directive.%0a%0a* PmWiki now recognizes when it is being accessed via "https:" and switches its internal links appropriately. This can be overridden by explicitly setting $ScriptUrl and $PubDirUrl.%0a%0a* A new $EnableLinkPageRelative option allows PmWiki to generate relative urls for page links instead of absolute urls.%0a%0a* Draft handling capabilities have been greatly improved. When $EnableDrafts is set, then the "Save" button is relabeled to "Publish" and a "Save draft" button appears. In addition, an $EnablePublishAttr configuration variable adds a new "publish" authorization level to distinguish editing from publishing. See [[PmWiki:Drafts]] for more details.%0a%0a[[#ptvstart]]%0a* There is a new [@{$:var}@] "page text variable" available that is able to grab text excerpts out of markup content. For example, [@{SomePage$:Xyz}@] will be replaced by a definition of "Xyz" in SomePage. Page text variables can be defined using definition markup, a line beginning with the variable name and a colon, or a special directive form (that doesn't display anything on output):%0a%0a-->[@%0a:Xyz: some value # definition list form%0aXyz: some value # colon form%0a(:Xyz: some value:) # directive form%0a@]%0a[[#ptvend]]%0a%0a* The [@(:pagelist:)@] command can now filter pages based on the contents of page variables and/or page text variables. For example, the following directive displays only those pages that have an "Xyz" page text variable with "some value":%0a%0a-->[@(:pagelist $:Xyz="some value":)@]%0a%0a Wildcards also work here, thus the following pagelist command lists pages where the page's title starts with the letter "a":%0a%0a-->[@(:pagelist $Title=A* :)@]%0a%0a* The if= option to [@(:pagelist)@] can be used to filter pages based on conditional markup:%0a%0a-->[@(:pagelist if="auth upload {=$FullName}":)@] pages with upload permission%0a-->[@(:pagelist if="date today.. {=$Name}":)@] pages with names that are dates later than today%0a%0a* Spaces no longer separate wildcard patterns -- use commas. (Most people have been doing this already.)%0a%0a* Because page variables are now "relative", the [@{$PageCount}, {$GroupCount}, {$GroupPageCount}@] variables used in pagelist templates are now [@{$$PageCount}, {$$GroupCount}, {$$GroupPageCount}@].%0a%0a* One can now use [@{$$option}@] in a pagelist template to obtain the value of any 'option=' provided to the [@(:pagelist:)@] command.%0a%0a* The [@(:pagelist:)@] directive no longer accepts parameters from urls or forms by default. In order to have it accept such parameters (which was the default in 2.1 and earlier), add a [@request=1@] option to the [@(:pagelist:)@] directive.%0a%0a* The [@count=@] option to pagelists now accepts negative values to count from the end of the list. Thus [@count=5@] returns the the first five pages in the list, and [@count=-5@] returns the last five pages in the list. In addition, ranges of pages may be specified, as in [@count=10..19@] or [@count=-10..-5@].%0a%0a* Pagelist templates may have special [@(:template first ...:)@] and [@(:template last ...:)@] sections to specify output for the first or last page in the list or a group. There's also a [@(:template defaults ...:)@] to allow a template to specify default options.%0a%0a* PmWiki comes with an ability to cache the results of certain [@(:pagelist:)@] directives, to speed up processing on subsequent visits to the page. To enable this feature, set $PageListCacheDir to the name of a writable directory (e.g., ''work.d/'').%0a%0a* [[#elseifelse]]The [@(:if ...:)@] conditional markup now also understands [@(:elseif ...:)@] and [@(:else:)@]. In addition, markup can nest conditionals by placing digits after if/elseif/else, as in [@(:if1 ...)@], [@(:elseif1 ...:)@], [@(:else1:)@], etc.%0a%0a* The [@(:if date ...:)@] conditional markup can now perform date comparisons for dates other than the current date and time.%0a%0a* [[WikiTrails]] can now specify #anchor identifiers to use only sections of pages as a trail.%0a%0a* A new [@(:if ontrail ...:)@] condition allows testing if a page is listed on a trail.%0a%0a* The extensions .odt, .ods, and .odp (from OpenOffice.org) are now recognized as valid attachment types by default.%0a%0a* A new [[blocklist]] capability has been added to the core distribution. It allows blocking of posts based on IP address, phrase, or regular expression, and can also make use of publicly available standard blocklists. See [[PmWiki.Blocklist]] for details.%0a%0a* There is a new [[SiteAdmin.AuthList]] page that can display a summary of all password and permissions settings for pages on a site. This page is restricted to administrators by default.%0a%0a* There are new [@{$PasswdRead}@], [@{$PasswdEdit}@], etc. variables that display the current password settings for a page (assuming the browser has attr permissions or whatever permissions are set in $PasswdVarAuth).%0a%0a* Forms creation via the [@(:input:)@] markup has been internally refactored somewhat (and may still undergo some changes prior to 2.2.0 release). The new [@(:input select ...:)@] markup can be used to create select boxes, and [@(:input default ...:)@] can be used to set default control values, including for radio buttons and checkboxes.%0a%0a* The [@(:input textarea:)@] markup now can take values from other sources, including page text variables from other pages.%0a%0a* Specifying [@focus=1@] on an [@(:input:)@] control causes that control to receive the input focus when a page is loaded. If a page has multiple controls requesting the focus, then the first control with the lowest value of [@focus=@] "wins".%0a%0a* PmWiki now provides a ''scripts/creole.php'' module to enable Creole standard markup. To enable this, add [@include_once('scripts/creole.php')@] to a local customization file.%0a%0a* PmWiki adds a new [@{(...)}@] ''markup expression'' capability, which allows various simple string and data processing (e.g., formatting of dates and times). This is extensible so that recipe authors and system administrators can easily add custom expression operators.%0a%0a* It's now possible to configure PmWiki to automatically create Category pages whenever a page is saved with category links and the corresponding category doesn't already exist. Pages are created only if the author has appropriate write permissions into the group. To enable this behavior, add the following to ''local/config.php'':%0a%0a-->[@$AutoCreate['/^Category\\./'] = array('ctime' => $Now);@]%0a%0a* Sites with wikiwords enabled can now set $WikiWordCount['WikiWord'] to -1 to indicate that 'WikiWord' should not be spaced according to $SpaceWikiWords.%0a%0a* WikiWords that follow # or & are no longer treated as WikiWords.%0a%0a* Links to non-existent group home pages (e.g., [@[[Group.]]@] and [@[[Group/]]@]) will now go to the first valid entry of $PagePathFmt, instead of being hardcoded to "Group.Group". For example, to set PmWiki to default group home pages to [@$DefaultName@], use%0a%0a-->[@$PagePathFmt = array('{$Group}.$1', '$1.{$DefaultName}', '$1.$1');@]%0a%0a* PmWiki now provides a $CurrentTimeISO and $TimeISOFmt variables, for specifying dates in ISO format.%0a%0a* [[(Cookbook:)Cookbook]] authors can use the internal PmWiki function UpdatePage (temporarily documented at [[(Cookbook:)DebuggingForCookbookAuthors]]) to change page text while preserving history/diff information, updating page revision numbers, updating RecentChanges pages, sending email notifications, etc.%0a%0a* [[Skin templates]] are now required to have %3c!--HTMLHeader--> and %3c!--HTMLFooter--> directives. Setting $EnableSkinDiag causes PmWiki to return an error if this isn't the case for a loaded skin. Skins that explicitly do not want HTMLHeader or HTMLFooter sections can use %3c!--NoHTMLHeader--> and %3c!--NoHTMLFooter--> to suppress the warning.%0a%0a* Added a new "pre" wikistyle for preformatted text blocks.%0a%0a* The xlpage-utf-8.php script now understands how to space UTF-8 wikiwords. %0a%0a* Searches on utf-8 site are now case-insensitive for utf-8 characters.%0a%0a* Many Abort() calls now provide a link to pages on pmwiki.org that can explain the problem in more detail and provide troubleshooting assistance.%0a%0a* PmWiki no longer reports "?cannot acquire lockfile" if the visitor is simply browsing pages or performing other read-only actions.%0a%0a* The $EnableReadOnly configuration variable can be set to signal PmWiki that it is to run in "read-only" mode (e.g., for distribution on read-only media). Attempts to perform actions that write to the disk are either ignored or raise an error via Abort().%0a%0a* Including authuser.php no longer automatically calls ResolvePageName().%0a%0a* Authentication using Active Directory is now simplified. In Site.AuthUser or the $AuthUser variable, set "ldap://name.of.ad.server/" with no additional path information (see PmWiki.AuthUser for more details).%0a%0a* Pages are now saved with a "charset=" attribute to identify the character set in effect when the page was saved.%0a%0a* The phpdiff.php algorithm has been optimized to be smarter about finding smaller diffs.%0a%0a* Removed the (deprecated) "#wikileft h1" and "#wikileft h5" styles from the pmwiki default skin.%0a%0a* The mailposts.php and compat1x.php scripts have been removed from the distribution.%0a%0a!! Version 2.1.27 (2006-12-11)%0a%0aThis version backports from 2.2.0-beta a bugfix for $TableRowIndexMax and also support for the [@{*$Variable}@] markup.%0a%0a!! Version 2.1.26 (2006-09-11)%0a%0aThis version fixes a bug in feeds.php that would cause feed entries to be mixed up.%0a%0a!! Version 2.1.25 (2006-09-08)%0a%0aThis release fixes a bug in authuser.php introduced by the 2.1.24 release.%0a%0aThe skin template code has also been extended to allow [@%3c!--XMLHeader-->@] and [@%3c!--XMLFooter-->@] as aliases for [@%3c!--HTMLHeader-->@] and [@%3c!--HTMLFooter-->@].%0a%0a!! Version 2.1.24 (2006-09-06)%0a%0aThis release makes some improvements and fixes to the [[AuthUser]]%0acapability.%0a%0aA bug in authuser.php that had trouble dealing with non-array values in $AuthUser has been fixed.%0a%0aIt is now possible to specify group memberships from ''local/config.php'' (remember that such entries must come ''before'' including the ''authuser.php'' script):%0a%0a # alice and bob's passwords%0a $AuthUser['alice'] = crypt('alicepassword');%0a $AuthUser['bob'] = crypt('bobpassword');%0a%0a # members of the @writers and @admins groups%0a $AuthUser['@writers'] = array('alice', 'bob');%0a $AuthUser['@admins'] = array('alice', 'dave');%0a%0a # carol is a member of @editors and @writers%0a $AuthUser['carol'] = array('@editors', '@writers');%0a%0aAuthUser can now read from Apache-formatted .htgroup files. The location of the .htgroup file can be done either in ''local/config.php'' or [[Site.AuthUser]]%0a%0a # local/config.php:%0a $AuthUser['htgroup'] = '/path/to/.htgroup';%0a%0a # Site.AuthUser%0a htgroup: /path/to/.htgroup%0a%0a%0a!! Versions 2.1.21, 2.1.22, 2.1.23 (2006-09-05, 2006-09-06)%0a%0aThis release closes a potential security vulnerability for sites %0athat are running with 'register_globals' set to on. Details of%0athe vulnerability will be forthcoming on the mailing list%0aand site.%0a%0aSites that are running with PHP 'register_globals' and 'allow_url_fopen'%0aset to 'On' should upgrade to this release at the earliest%0aopportunity. If upgrading isn't an option, contact Pm for%0aa patch to older versions.%0a%0aThere is now a tool available to analyze PmWiki sites for security%0aand other configuration settings, see [[PmWiki:SiteAnalyzer]].%0a%0aVersion 2.1.23 also corrects a bug that prevented PmWiki from being%0aable to read pagefiles created by versions of PmWiki before 0.5.6.%0a%0a!! Version 2.1.20 (2006-09-04)%0a%0aMore minor bugfixes:%0a* Corrected a bug with WikiWord references appearing in the [@(:attachlist:)@] markup.%0a* Restore ability to remove/override PmWiki's default CSS settings.%0a%0a!! Version 2.1.19 (2006-08-30)%0a%0aThis release provides a number of very minor bugfixes and%0aenhancements:%0a%0a* Fixed a bug in the pageindex code that was causing it to not regenerate as quickly as it should.%0a* Fixed image/object/embed handling in wikistyles to better support the [[Cookbook:Flash]] recipe.%0a* Fixed a bug with wikistyles and input form tags.%0a%0aThe next release(s) may have a number of substantial code%0aenhancements and changes, so this release simply closes out%0aa few items before introducing those changes.%0a%0a%0a!! Version 2.1.18 (2006-08-28)%0a%0aThis release closes a potential cross-site scripting vulnerability%0athat could allow authors to inject Javascript code through the%0avarious table markups.%0a%0aThe release also adds a new [@(:input image:)@] markup to generate%0aimage input tags in forms.%0a%0aFinally, this release corrects a problem with [@?action=print@]%0afailing to properly set the [@{$Action}@] page variable.%0a%0a!! Version 2.1.17 (2006-08-26)%0a%0aThis release fixes a long-standing bug with $EnableIMSCaching%0a(PITS:00573), whereby login/logout operations wouldn't invalidate %0abrowser caches, causing some people to see versions of a page prior%0ato the login/logout taking place. %0a%0aThe new IMS caching code maintains a "imstime" cookie in the %0avisitor's browser that keeps track of the time of last login, %0alogout, author name change, or site modification. This cookie%0ais then used to determine the proper response to browser requests%0acontaining If-Modified-Since headers. (Previously only the%0atime of the last site modification was available.) %0a%0aBrowsers which do not accept cookies will effectively act as%0athough IMS caching is disabled.%0a%0a%0a!! Version 2.1.16 (2006-08-26) [[#v2116]]%0a%0aThis release makes some improvements to skin handling -- primarily%0athis improves the capability of relocating skin files to other%0alocations, and to provide the ability for recipes to insert items%0aat the ''end'' of HTML output.%0a%0aThis release introduces a [@%3c!--HTMLFooter-->@] directive into%0a[[skin templates]], which allows recipes and local%0acustomizations to insert output near the end of a document %0ausing a $HTMLFooterFmt array from PHP.%0a%0aAlso, the [@%3c!--HeaderText-->@] directive, which inserts the%0acontents of $HTMLHeaderFmt into the output, has now been%0arenamed to [@%3c!--HTMLHeader-->@]. PmWiki will continue to%0arecognize [@%3c!--HeaderText-->@] to preserve compatibility with%0aexisting skins, but [@%3c!--HTMLHeader-->@] is preferred.%0a%0aA new $SkinLibDirs array has been introduced which allows%0athe source locations and urls for skins to be specified from%0aa customization file. By default $SkinLibDirs is set as%0a%0a $SkinLibDirs = array("./pub/skins/\$Skin" => "$PubDirUrl/skins/\$Skin",%0a "$FarmD/pub/skins/\$Skin" => "$FarmPubDirUrl/skins/\$Skin");%0a%0aThe keys (on the left) indicate the places to look for a "skin .tmpl %0afile" in the filesystem, while the values (on the right) indicate the%0aurl location of the "skin css file". Modifying the value of %0a$SkinLibDirs allows a skin .tmpl file to be located anywhere on the %0afilesystem.%0a%0aAs far as I can see, none of the changes introduced by this%0arelease should have any sort of negative impact on existing%0asites, so it should be safe to upgrade. (If I'm wrong, please%0alet me know.)%0a%0a%0a!! Version 2.1.15 (2006-08-25)%0a%0aThis release includes a number of feature enhancements and code cleanups%0aas reported or requested by administrators.%0a%0aFirst, AuthUser's LDAP authentication system now allows the use of%0aa [@?filter@] parameter, consistent with urls used for mod_auth_ldap%0aauthorization in Apache. See the newly updated LDAP section of the%0a[[AuthUser]] documentation for more details.%0a%0aA chicken-and-egg problem with the [@@_site_*@] authorization groups%0ahas been resolved. It's now possible to have a page's read authorization%0arefer to things such as [@_site_edit@].%0a%0aAlso, the RetrieveAuthPage() function -- used for retrieving pages only%0aif the visitor is authorized to do so -- now recognizes a special%0alevel parameter of 'ALWAYS', which means to always authorize access%0aregardless of the browser or visitors current permissions. This%0amay be useful for allowing certain operations to take place from%0awithin trusted scripts without having to grant full authorization%0ato the browser.%0a%0aHardcoded instances of the ''local/'' directory now use a%0acustomizable $LocalDir variable. This variable controls where%0aPmWiki looks for ''local/config.php'' and per-group customization %0afiles. It may be useful for some [[Wiki Farm(s)]] contexts. Note that%0athis does not change or affect the location of %0a''$FarmD/local/farmconfig.php''.%0a%0aSome minor internal changes have been made to %0a''scripts/wikistyles.php'' to better accommodate the %0awikipublisher recipe. It's probably better if we don't try%0ato explain them. :-)%0a%0a%0a!! Version 2.1.13, 2.1.14 (2006-08-15, 2006-08-16)%0a%0aThis release fixes a bug in handling numeric passwords, and also%0aallows ldaps:// authentication sources.%0a%0a!! Version 2.1.12 (2006-08-07)%0a%0aThis version introduces the ability to nest divs and tables.%0aThe standard [@(:table:)@] and [@(:div:)@] markups are still%0aavailable, except that a [@(:div:)@] may contain a [@(:table:)@]%0aand vice-versa. %0a%0aAs in previous versions of PmWiki, the [@(:div:)@] markup%0aautomatically closes any previous [@(:div:)@]. However, there%0aare now [@(:div1:)@], [@(:div2:)@], etc. markups (and the%0acorresponding [@(:div1end:)@], [@(:div2end:)@], ...) which can be%0aused to uniquely distinguish divs for nesting purposes.%0a%0aTo restore PmWiki's previous "non-nested" div behavior, set%0a$Transition['nodivnest'] = 1; in a local customization file.%0a%0aOther changes in this release:%0a* Add a [@(:noaction:)@] directive to suppress display of page actions.%0a* Allow anchor tags to contain colons, hyphens, and dots.%0a* Add "white-space" as an allowed wikistyle.%0a* Other minor bug fixes and typographical corrections.%0a%0a%0a!! Version 2.1.11 (2006-06-09)%0a%0aThis is a minor update that prevents [@%25define=%25@] wikistyles%0afrom generating empty paragraphs in the HTML output. Prior to%0athis release, markup lines containing only wikistyle definitions%0awould often generate empty paragraphs (%3cp>%3c/p>), this release%0achanges things so that a markup line beginning with [@%25define=@]%0aand containing only wikistyle definitions will not initiate%0aa new paragraph.%0a%0a%0a!! Version 2.1.10 (2006-06-03)%0a%0aVersion 2.1.4 introduced an [@{$Action}@] page variable that would%0acontain the current [@?action=@] value. Unfortunately, this page%0avariable conflicted with a pre-existing [@$Action@] global variable%0athat was being used by skins to display a human-friendly form of%0athe current action. Since there's not really a clean way to resolve%0athis, I've decided to keep [@{$Action}@] as a page variable%0awith the current action value (as introduced in 2.1.4), and change %0athe global for skins to be $ActionTitle. This will require updating%0askins to use $ActionTitle instead of $Action. I apologize for the%0aconflict.%0a%0aThis release adds a Site.LocalTemplates page for the [@fmt=#xyz@]%0aoption in pagelist and search results. The list of pages to be%0asearched can be customized via the $FPLTemplatePageFmt variable.%0aThe [@fmt=#xyz@] option will now also search the current page for%0aa matching template before searching Site.LocalTemplates%0aand Site.PageListTemplates.%0a%0aThe 'pmwiki' skin now places a %3cspan> around the "Recent Changes"%0alink in the header to make it somewhat easier to style.%0a%0a!! Version 2.1.9 (2006-06-02)%0a%0aThis release fixes a long-standing and difficult-to-find bug with%0athe handling of [@[[~Author]]@] links.%0a%0a!! Version 2.1.8 (2006-06-01)%0a%0aThis release simply changes the $NotifyListFmt variable to be%0a$NotifyListPageFmt (more descriptive), and adds a $NotifyList%0aarray that can be used to specify notification entries from%0aa configuration file.%0a%0a!! Version 2.1.7 (2006-05-31)%0a%0aThis release introduces a variety of improvements and bugfixes.%0a%0a'''Vspace paragraphs are now divs:'''%0aVersion 2.1.7 changes the way that PmWiki handles vertical%0aspace in output (the infamous [@%3cp class='vspace>%3c/p>@] sequence).%0aInstead of using paragraphs, PmWiki now generates %0a[@%3cdiv class='vspace'>%3c/div>@] for vertical space sequences.%0aIn addition, PmWiki is able to collapse the vspace %3cdiv> with%0aany subsequent paragraph tags, such that a sequence like%0a%0a %3cdiv class='vspace>%3c/div>%3cp>...paragraph text...%3c/p>%0a%0ais automatically converted to%0a%0a %3cp class='vspace'>...paragraph text...%3c/p>%0a%0aThis allows for better control over paragraph spacing. It is%0aexpected that this change in vspace handling will not have%0aany detrimental effects on existing sites. Sites that have%0aset custom values for $HTMLVSpace will continue to use the%0acustom value. A site that wants to restore PmWiki's earlier%0ahandling of vspace can do so by adding the following to%0a''local/config.php'':%0a%0a $HTMLVSpace = "%3cp class='vspace'>%3c/p>";%0a%0a'''Improved email notifications of changes:''' Version 2.1.7%0aincorporates a ''notify.php'' script that provides improved%0acapabilities for sending email notifications in response to%0apage changes. This script is intended to replace the previous%0a[[(PmWiki:)MailPosts]] capability, which is now deprecated (but will%0acontinue to be supported in PmWiki 2.1.x). Details and %0ainstructions for using notify.php are in the [[PmWiki.Notify]] page.%0a%0a'''Added 'group home page' syntax:''' A group name followed%0aby only a dot or slash is automatically treated as a reference%0ato the group's home page, whatever it happens to be. This simplifies%0asome pagelist templates as well as a number of other items. %0aIn particular, group links in pagelist output now points to the%0acorrect locations (instead of being a page in the current group).%0a%0aSeveral bugs and vulnerabilities have been fixed:%0a* The default width of edit forms is now more appropriate for Internet Explorer.%0a* Authentication failure messages from LDAP are now suppressed.%0a* Some cross-site scripting vulnerabilities in uploads and page links have been corrected (courtesy Moritz Naumann, http://moritz-naumann.com).%0a* A problem with invalid pagenames resulting in redirect loops has been corrected.%0a%0a!! Version 2.1.6 (2006-05-22)%0a%0aThe primary improvement in this release is the addition of %0aa pagename argument to the [@(:if auth:)@] conditional markup.%0aThus one can display markup based on a visitor's authorization%0ato a page other than the current one. For example, to test%0afor edit privileges to `Main.WikiSandbox, one would use%0a[@(:if auth edit Main.WikiSandbox:)@]. As before, if the%0apagename is omitted the directive tests authorization to%0athe current page.%0a%0aThis release also restores the ability to have hyphens in%0aInterMap link names.%0a%0aLastly, the release closes a potential cross-site scripting%0avulnerability in the WikiTrail markup, and provides some small%0aperformance improvements.%0a%0a!! Version 2.1.4, 2.1.5 (2006-03-29)%0a%0aThis release fixes a few more bugs:%0a* Pagelist-based feeds using ?action=rss work again.%0a* Multi-term searches with special characters is fixed.%0a%0aThe release also adds a couple of items:%0a* There is now an [@{$Action}@] page variable.%0a* Usernames and passwords submitted to authuser.php can contain quotes.%0a* The [@(:attachlist:)@] command now uses a natural case sort.%0a%0a!! Version 2.1.3 (2006-03-17)%0a%0aThis release fixes a bug that prevents the [@lines=@] option from%0aworking on sites running PHP 5.1.1 or later. It also re-fixes%0aa bug involving empty passwords and LDAP authentication.%0a%0a!! Version 2.1.2 (2006-03-16)%0a%0aThis release fixes a bug with handling "nopass" passwords. It also%0amakes some speed improvements to large web feeds, and fixes a couple%0aof minor HTML tag mismatches.%0a%0a!! Version 2.1.1 (2006-03-13)%0a%0aThis release primarily fixes a bug with passwords containing%0amultiple authorization groups, and in the process slightly liberalized%0athe formatting of "@group" and "id:name" handling. This release also %0aadds a new mechanism for managing and displaying FAQ pages.%0a%0a!! Version 2.1.0 (2006-03-12)%0a%0aThis set of release notes is fairly lengthy, as it chronicles all of the changes since 2.0.13 (four months of development). A lot remains the same, but some changes warrant extra care when upgrading from a 2.0.x version to 2.1.0 (thus the major revision number change). As always, questions and issues can be mailed to the pmwiki-users mailing list.%0a%0aHere's the list:%0a%0a* WikiWords are now disabled by default. To enable them, set "$LinkWikiWords = 1;" in a [[local customization(s)]] file. As of 2.1.beta2, you can now leave WikiWords enabled but have links to non-existent pages display without decoration -- to do this, place the following lines in ''pub/css/local.css'':%0a%0a span.wikiword a.createlink { display:none; }%0a span.wikiword a.createlinktext %0a { border-bottom:none; text-decoration:none; color:inherit; }%0a%0a* The [@(:pagelist:)@] code has been substantially revised. Pagelist formatting can now be specified using markup, and several defaults are available from [[Site.PageListTemplates]]. Also, several built-in pagelist formatting functions (FPLSimple, FPLByGroup, FPLGroup) are now removed in favor of the template code. The FPLByGroup function can be restored by setting $Transition['fplbygroup']=1; . '''Remark:''' Check to see if your page [[Site.PageListTemplates]] is not passwordprotected for viewing, otherwise the resulting pagelist will not be shown. %0a%0a* [@(:pagelist:)@] now also understands wildcards in @@group=@@ and @@name=@@ arguments, as well as excluding specific names and groups.%0a%0a* [@(:pagelist:)@] now has an "order=random" option.%0a%0a* [@(:searchbox:)@] now accepts "group=", "link=", "list=", etc. options to be passed along to the search results. It also accepts a "target=" option that identifies the page on which to send the search query.%0a%0a* [@?action=search@] will display the contents of the current page if it contains a [@(:@][@searchresults:)@] directive, otherwise it uses the content of the page identified by $PageSearchForm (default is the search page for the current language translation). %0a%0a* PmWiki no longer maintains a ".linkindex" file -- it now has a ".pageindex" file that contains not only a table of links, but also words used in each page (to speed up term searches). The maintenance of the .pageindex file can be disabled by setting $PageIndexFile=''; %0a %0a* The $EnablePageListProtect variable now defaults to true, so that read-only pages appear in pagelists only if the visitor has read authorization. Note that this can also slow down some [@(:pagelist:)@] and search commands, so if the site doesn't have any read-only pages or if you aren't worried with cloaking read-only pages from searchlists, it might be worth setting $EnablePageListProtect=0; .%0a%0a* Whitespace indentation rules now exist and are enabled by default. Any line that begins with whitespace and aligns with a previous list item is considered to be "within" that list item. Text folds and wraps as normal, and the [@(:linebreaks:)@] directive is honored. To turn off whitespace indentation, use [@DisableMarkup('^ws');@].%0a%0a* A single blank line after a [@!!Heading@] is silently ignored.%0a%0a* The [@(:redirect:)@] directive is now a true markup, and can be embedded inside conditional markups or includes. It also allows redirecting to an anchor in a page, such as [@(:redirect PageName#anchor:)@]. A new [@from=@] option allows the redirect to take place only from pages that match the given wildcard specification. The [@status=@] option allows a 301, 302, 303, or 307 HTTP status code to be returned.%0a%0a* The built-in authorization function has gone through some substantial internal changes, however these changes should be fully backward compatible so that it doesn't impact any existing sites. (If it ''does'' cause a problem, please let me know so I can investigate why!) The password prompts are now specified by an admin-customizable Site.AuthForm page. In addition, the authorization function no longer creates PHP sessions for visitors that aren't being authenticated.%0a%0a* The authuser.php has likewise been substantially updated. The new version should have complete backwards compatibility with previous authuser.php settings, but this version also offers the ability to configure authentication resources and authorization groups through the [[Site.AuthUser]] page. Note that by default the Site.AuthUser page can only be edited using the admin password.%0a%0a* The $EnableSessionPasswords variable can be used to control whether passwords are held in PHP sessions. (This does not affect user authentication via [[AuthUser]], however.)%0a%0a* The $Author variable now defaults to $AuthId if not otherwise set by a script or cookie.%0a%0a* The [[Site.SideBar]] page now defaults its edit password to the sitewide edit password (in $DefaultPasswords['edit']).%0a%0a* PmWiki now supports a "draft edit" mode, enabled by $EnableDrafts = 1. This creates a "Save as draft" button that will save a page under a "-Draft" suffix, for intermediate edits.%0a%0a* There is now an ?action=login action available.%0a%0a* A potential security vulnerability for sites running PHP 5 with register_globals enabled has been fixed.%0a%0a* The [@[[PageName |+]]@] markup is now available by default; this creates a link to `PageName and uses that page's title as the link text.%0a%0a* What used to be "markup variables" are now "[[page variables]]". These are always specified using the @@{$''variable''}@@ syntax, and can be used in markup and in $...Fmt strings. In addition, one can request a value for a specific page by placing the pagename in front of the variable, as in @@{''pagename''$''variable''}@@.%0a%0a* The ''scripts/rss.php'' script is now ''scripts/feeds.php'', and is a complete redesign for [[web feed(s)]] generation. The new version supports UTF-8 and other encodings, can generate Atom 1.0 ([@?action=atom@]), Dublin Core Metadata ([@?action=dc@]) output, and enclosures for podcasting. It also allows feeds to be generated from trails, groups, categories, and backlinks, and provides options (same as pagelists) for sorting and filtering the contents of the feed. Most sites can simply switch to using [@include_once("scripts/feeds.php");@] instead of the previous ''rss.php'' include. The ''rss.php'' file has been removed from the distribution (but still works with PmWiki 2.1 for those sites that wish to continue using it).%0a%0a* [[PmWiki/InterMap]] entries can now come from a `Site.InterMap page as well as the ''local/localmap.txt'' and ''local/farmmap.txt'' files. The format of these files has changed slightly, in that the InterMap name should now have a colon after it (previously the colon was omitted).%0a%0a* We can now provide better control of robot (webcrawler) interactions with a site to reduce server load and bandwidth. The $RobotPattern variable is used to detect robots based on the user-agent string, and any actions not listed in the $RobotActions array will return a 403 Forbidden response to robots. In addition, setting $EnableRobotCloakActions will eliminate any forbidden ?action= values from page links returned to robots, which will reduce bandwidth loads from robots even further (PITS:00563).%0a%0a* Non-existent page handling has been improved; whenever a browser hits a non-existent page, PmWiki returns the contents of Site.PageNotFound and a 404 ("Not Found") status code.%0a%0a* Page links that have "?action=" in their query arguments are now treated as "existing page" links even if the page does not exist.%0a%0a* The PmWiki default skin now adds rel='nofollow' to various action links.%0a%0a* Some of the CSS styles in the PmWiki default skin have been changed for better presentation.%0a%0a* The gui edit buttons have transparent (instead of white) borders so they integrate better into skins.%0a%0a* The $EnableIMSCaching variable is now much smarter, it can detect changes in local customization files as well as pages.%0a%0a* [[PmWiki/WikiStyles]] can now make percentage specifications by using "pct" to mean "%25".%0a%0a* Class attributes in [[WikiStyle(s)]] shortcuts are now cumulative, so that [@%25class1 class2%25@] results in [@class='class1 class2'@] instead of just [@class='class2'@] in the output.%0a%0a* A problem with the [@(:include PageName#from#:)@] markup not working has been fixed (PITS:00560).%0a%0a* Viewing a GroupHeader or GroupFooter page no longer displays the contents twice.%0a%0a* It's now easier to share pages among multiple sites (e.g., [[WikiFarms]]), see Cookbook:SharedPages (PITS:00459).%0a%0a* A problem with nested apostrophe markups has been fixed (PITS:00590).%0a%0a* PmWiki is now smarter about not surrounding block HTML tags with %3cp>...%3c/p> tags.%0a%0a* If an [@[[#anchor]]@] is used more than once in a page, only the first generates an actual anchor (to preserve XHTML validity).%0a%0a* There are now [@(:if equal ...:)@] and [@(:if exists pagename:)@] [[conditional markup]]s.%0a%0a* Compound conditional markup expressions are now possible -- e.g. [@(:if [ group PmWiki && ! name PmWiki ] :)@] .%0a%0a* Added an $InputValues array that can supply default values for certain form controls (PITS:00566).%0a%0a* The default setting of $UploadUrlFmt is now based on $PubDirUrl instead of $ScriptUrl.%0a%0a* The $text global variable has been removed (use $_GET['text'], $_POST['text'], or $_REQUEST['text']).%0a%0a* A possible problem with url-encoding of attachments with non-ASCII characters has been addressed (PITS:00588).%0a%0a* Page actions in non-existent pages no longer display with non-existent link decorations.%0a%0a* A README.txt file has been added, and several documentation files are now available through the docs/ directory.%0a %0a* PmWiki is no longer available through CVS on sourceforge.net. It is now available via SVN on pmwiki.org, at svn://pmwiki.org/pmwiki/tags/latest . For more details, see PmWiki:Subversion.%0a%0a* The $NewlineXXX variable (deprecated in 2.0.0) has been removed.%0a%0a* There is experimental support for server-side caching of pages that take a long time to render; this is currently an unsupported feature and may be removed in future releases.%0a%0a%25red%25Wiki administrators should note that from this release on PmWiki defaults to having WikiWords disabled.%0a%0aTo make sure WikiWords are enabled, use [@$LinkWikiWords = 1;@] in%0athe ''local/config.php'' file.%0a%0a----%0aBugs and other requests can be reported to the PmWiki Issue Tracking %0aSystem at http://www.pmwiki.org/wiki/PITS/PITS. Any help%0ain testing, development, and/or documentation is greatly appreciated..%0a%0a[[(PmWiki:)Release Notes archive]] - notes for versions older than 2.1.0.%0a%0a%0a%0a%0a%0a%0a%0a%0a%0a%0a
+time=1266769737
+title=Release Notes
diff --git a/wikilib.d/PmWiki.Requirements b/wikilib.d/PmWiki.Requirements
new file mode 100644
index 0000000..8dcba29
--- /dev/null
+++ b/wikilib.d/PmWiki.Requirements
@@ -0,0 +1,11 @@
+version=pmwiki-2.2.6 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.4) Gecko/20091028 Ubuntu/9.10 (karmic) Firefox/3.5.4
+author=Petko
+charset=ISO-8859-1
+csum=refactor, +PHP 5.3 on Windows
+host=81.65.12.233
+name=PmWiki.Requirements
+rev=49
+targets=
+text=(:Summary:Pre-requisites for running the PmWiki wiki engine:)(:Audience: administrators (basic) :)%0aPrerequisites for running the PmWiki wiki engine:%0a# [[http://php.net/ | PHP]] 4.1 or later%0a** [[http://gophp5.org/ | PHP 5]] or later is recommended%0a# Some sort of webserver that can run PHP scripts.%0a%0aPmWiki has been reported to work with the following OS/webserver combinations:%0a* Apache 1.3 or 2.0, on roughly anything (Unix, Linux, Windows, and Mac OS/X)%0a** [[http://httpd.apache.org/ | Apache 2.2]] or later is recommended%0a* Microsoft Internet Information Server, on Windows%0a* Linux + [[http://www.litespeedtech.com/|LiteSpeedWeb Server]] Standard Edition %0a* appWeb (a small, php-enabled webserver) executing on a Linksys NSLU2 Network Storage Link device%0a%0aPmWiki has been reported not to work on:%0a* Mac OS before Mac OS X because there's no PHP available%0a* Specific Release Candidate builds of PHP 5.3 for Windows may not work correctly with passwords%0a%0aThe [[(Cookbook:)Standalone]] recipe provides a special, bare-bones webserver application that can be used to run PmWiki in places where another webserver isn't available.%0aPmWiki can also be run from a [[Cookbook:WikiOnAStick | USB drive]].%0a
+time=1257638028
diff --git a/wikilib.d/PmWiki.Search b/wikilib.d/PmWiki.Search
new file mode 100644
index 0000000..895de12
--- /dev/null
+++ b/wikilib.d/PmWiki.Search
@@ -0,0 +1,14 @@
+version=pmwiki-2.2.1 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.0.8) Gecko/2009032609 Firefox/3.0.8
+author=simon
+charset=ISO-8859-1
+csum=remove link
+ctime=1150411168
+description=A page for advanced and customized search options
+host=202.37.32.2
+name=PmWiki.Search
+rev=117
+targets=PmWiki.WikiTrails,PmWiki.PageLists,Site.PageListTemplates,Site.LocalTemplates,PmWiki.Search,Site.AllRecentChanges,Cookbook.Cookbook,PITS.PITS,Group.Name
+text=(:description A page for advanced and customized search options:)%0a(:Summary:Targeting and customising search results:)%0a(:if !equal {$Action} "search":)%0a>>rframe width=300pcx font-size=smaller%3c%3c%0a-%3c '''This page uses [[#example|custom]] searches.'''%0aFor regular searches, view another page.%0a>>%3c%3c%0aPmWiki provides a basic search function. While it is not powered by a "search engine", it can be tweaked to produce results that are ''targeted'' and ''customized.'' %0a%0a!!!! Targeted searches%0aSearches can be targeted to restrict the search to certain pages. For example, a search can be restricted based on groups, where, for instance, "group=PmWiki" searches only the PmWiki group, and "group=-PmWiki" searches only pages that are not in the PmWiki group. In addition to groups, searches can be restricted based on page names ("name="), [[wiki trails]] ("trail="), backlinks ("link=") and other criteria (e.g. "list=normal") and capped at a maximum number ("count="). For documentation about each of these parameters, see [[page lists]]. %0a%0a!!!! Customized display%0aThe display of search results can be customized to control the format, content and order of the returned results. Format and content are selected by using "fmt=" to specify a pagelist template that determines layout, such as list styles, and page elements, such as title and description. The "order=" option allows results to be sorted according to different criteria, such as name and title. For documentation about each of these parameters, see [[page lists]]. For examples of pagelist template formats see [[Site.Page List Templates]], (:if exists Site.LocalTemplates:)[[Site.Local Templates]],(:ifend:) and [[Cookbook:Pagelist Template Samples]].%0a%0a!!!! Anyone, anywhere%0a'''Readers''' can create targeted and customized search results simply by typing the relevant parameters , e.g. "group=PmWiki", into search boxes together with their search string. '''Authors''' can predefine such targeted and customized searches by incorporating the parameters into pages using the [@(:searchbox:)@] and [@(:searchresults:)@] directives (documented at [[PageLists]]).%0a%0a[@(:searchresults:)@] can be customized by editing page [@Site.Search@].%0a%0aSee also%0a* $PageSearchForm %0a* $SearchBoxOpt%0a* $SearchPatterns%0a%0a%0a[[#example]]%0a!!!!Try it: this page generates custom searches%0aAny search that is run from this page will automatically generate pre-defined sets of search results that: '''''target''''' different clusters of pages (documentation, cookbook and PITS, if available); use '''''customized''''' formats, content and ordering; and '''''reveal''''' the specific parameters used to generate each search result. Whether you use the search box below, or the regular search box that appears at the top of this page, any search that you run from this page will provide the customized results. %0a(:searchbox size=20:)%0a%0a%0a%0a(:ifend:)%0a(:if equal {$Action} "search":)%0a[[{$Name}|back]]\%0a%0a(:table border=0 width=100%25:)\%0a%0a(:cell width=30%25:)\%0a%0a!!!! [[Site/AllRecentChanges?q=PmWiki/+order%253Dname&action=search|All Documentation]]%0a(:searchresults group=PmWiki fmt=#onegroupdesc order=name:)%0a(:if expr exists Cookbook.Cookbook and equal {$Action} "search":)%0a(:cell width=35%25:)\%0a%0a!!!! [[Cookbook.Cookbook|All Cookbook Recipes]]%0a(:searchresults group=Cookbook fmt=#summary order=name:)%0a(:if expr exists PITS.PITS and equal {$Action} "search":)%0a(:cell width=35%25:)\%0a%0a!!!! [[PITS.PITS|PITS (Issue Tracking)]]%0a(:searchresults group=PITS fmt=#summary name=0* order=-name:)%0a(:if equal {$Action} "search":)%0a(:tableend:)%0a%0aNote: The strings that were used to target and format each search result are shown above in '''italics'' and can be entered directly into a regular search box.%0a%0a%0a(:title Search:)%0a(:if false:)%0a%0a[[#onegroupdesc]]%0a[[{=$Group}/{=$Name}]] %25font-size=smaller font-style=italic%25{=$Description}%25%25\\%0a[[#onegroupend]]%0a%0a[[#summary]]%0a[[{=$Group}/{=$Name}]] %25font-size=smaller font-style=italic%25{=$:Summary}%25%25\\%0a[[#summaryend]]%0a(:ifend:)
+time=1238621785
+title=Search
diff --git a/wikilib.d/PmWiki.Security b/wikilib.d/PmWiki.Security
new file mode 100644
index 0000000..cadce2c
--- /dev/null
+++ b/wikilib.d/PmWiki.Security
@@ -0,0 +1,11 @@
+version=pmwiki-2.2.10 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7
+author=HansB
+charset=ISO-8859-1
+csum=added Authuser and HtpasswdForm
+host=80.41.210.230
+name=PmWiki.Security
+rev=84
+targets=PmWiki.Passwords,PmWiki.PasswordsAdmin,PmWiki.AuthUser,PmWiki.UrlApprovals,PmWiki.AnalyzeResults,PmWiki.SiteAnalyzer,PmWiki.Blocklist,PmWiki.Notify,PmWiki.SecurityVariables,Cookbook.Cookbook,Cookbook.HtpasswdForm,Cookbook.SecureAttachments,Cookbook.WebServerSecurity,Cookbook.FarmSecurity,Cookbook.DeObMail,Cookbook.ProtectEmail,Cookbook.AuditImages,Cookbook.PrivateGroups,Cookbook.OnlyOneLogin,Cookbook.SessionGuard,PmWiki.DeletingPages,PmWiki.AvailableActions,Cookbook.DeleteAction,Cookbook.Captchas,Cookbook.Captcha,Site.AuthForm,Cookbook.LimitWikiGroups,Cookbook.LimitNewPagesInWikiGroups,Profiles.HomePage,PmWiki.Drafts,PmWiki.Uploads,PmWiki.UploadsAdmin
+text=(:Summary: Resources for securing your PmWiki installation:)%0aAspects of PmWiki security are found on the following pages:%0a%0aPages distributed in a PmWiki release:%0a* [[PmWiki/Passwords]] {PmWiki/Passwords$:Summary}%0a* [[PmWiki/Passwords Admin]] {PmWiki/PasswordsAdmin$:Summary}%0a* [[PmWiki/AuthUser]] {PmWiki/AuthUser$:Summary}%0a* [[PmWiki/Url Approvals]] {PmWiki/UrlApprovals$:Summary}%0a* [[(PmWiki:)Site Analyzer]] {PmWiki/SiteAnalyzer$:Summary}%0a* [[PmWiki/Blocklist]] {PmWiki/Blocklist$:Summary}%0a* [[PmWiki/Notify]] {PmWiki/Notify$:Summary}%0a* [[PmWiki/Security variables]] {PmWiki/SecurityVariables$:Summary}%0a%0a[[Cookbook(:/)]] Pages%0a%0a* [[Cookbook:Cookbook#Security | Cookbook index for Security recipes]]%0a* [[Cookbook:HtpasswdForm]] Form based management of users and passwords using .htpasswd/.htgroup files%0a* [[Cookbook:Secure attachments]] Protecting uploaded attachments%0a* [[Cookbook:Web server security]] Making the server more secure with .htaccess%0a* [[Cookbook:Farm security]] Making Farm installations secure%0a* [[Cookbook:DeObMail]] Hide e-mail address%0a* [[Cookbook:Protect email]] Obfusticate email addresses%0a* [[Cookbook:Audit images]] Check to see what images have been uploaded to your wiki.%0a* [[Cookbook:Private groups]] Create and secure private groups on a public wiki%0a* [[Cookbook:Only one login]] Only allow 1 login at the same time for a username%0a* [[Cookbook:Session guard]] Protects against Session Theft%0a%0a%0a>>faq%3c%3c [[#faq]]%0a%0aQ: How do I report a possible security vulnerability of PmWiki?%0a%0aA: [[http://www.pmichaud.com|Pm]] wrote about this in [[http://pmichaud.com/pipermail/pmwiki-users/2006-September/031793.html | a post to pmwiki-users from September 2006]]. In a nutshell he differentiates two cases:%0a## The possible vulnerability isn't already known publicly: In this case please contact Pm by private mail.%0a## The possible vulnerability is already known publicly: In this case feel free to discuss the vulnerability in public (e.g. on [[http://www.pmichaud.com/mailman/listinfo/pmwiki-users | pmwiki-users]]).%0aSee [[http://pmichaud.com/pipermail/pmwiki-users/2006-September/031793.html | his post mentioned above]] for details and rationals.%0a%0aQ: What about the botnet security advisory at %25newwin%25[[http://isc.sans.org/diary.php?storyid=1672]]?%0a%0aA: Sites that are running with PHP's ''register_globals'' setting set to "On" and versions of PmWiki prior to 2.1.21 may be vulnerable to a botnet exploit that is taking advantage of a bug in PHP. The vulnerability can be closed by turning ''register_globals'' off, upgrading to PmWiki 2.1.21 or later, or upgrading to PHP versions 4.4.3 or 5.1.4. [[%3c%3c]]In addition, there is a test at [[PmWiki:SiteAnalyzer]] that can be used to determine if your site is vulnerable.%0a%0a[[#wikivandalism]]%0a!! Wiki Vandalism%0a:Assumptions: you are using a [[PmWiki/Blocklist]] and [[PmWiki/Url approvals]].%0a: :You don't want to resort to [[PmWiki/password(s)]] protecting the entire wiki, that's not the point after all.%0a: :Ideally these protections will be invoked in @@config.php@@%0a%0a%0aQ: How do I stop pages being [[PmWiki/DeletingPages|deleted]], eg password protect a page from deletion?%0aA: Use Cookbook:DeleteAction and password protect the page deletion [[(available) action(s)]] by adding [@$DefaultPasswords['delete'] = '*';@] to @@config.php@@ or password protect the action with @@$HandleAuth['delete'] = 'edit';@@%0a->or @@$HandleAuth['delete'] = 'admin';@@ to require the edit or admin password respectively.%0a%0aQ: How do I stop pages being replaced with an empty (all spaces) page?%0aA: Add [@block: /^\s*$/@] to your [[PmWiki/blocklist]].%0a%0aQ: how do I stop pages being completely replaced by an inane comment such as ''excellent site'', ''great information'', where the content cannot be blocked?%0aA: Try using the newer [[PmWiki/Blocklist#automaticblocklists | automatic blocklists]] that pull information and IP addresses about known wiki defacers.%0a%0aA: (OR) Try using [[Cookbook:Captchas]] or [[Cookbook:Captcha]] (note these are different).%0a%0aA: (OR) Set an edit password, but make it publicly available on the [[{$SiteGroup}.AuthForm]] template.%0a%0aQ: How do I password protect all common pages in all groups such as recent changes, search, group header, group footer, and so on?%0aA: Insert the following lines into your local/config.php file. Editing these pages then requires the admin password.%0a->[@%0a## Require admin password to edit RecentChanges (etc.) pages.%0aif ($action=='edit'%0a && preg_match('/\\.(Search|Group(Header|Footer)|(All)?RecentChanges)$/', $pagename))%0a { $DefaultPasswords['edit'] = crypt('secret phrase'); }%0a@]%0a%0aNote that all GroupAttributes pages are protected by the attr password.%0a%0a'''Alternative:''' you can require 'admin' authentication for these pages:%0a->[@%0a## Require admin password to edit RecentChanges (etc.) pages.%0aif ($action=='edit' %0a && preg_match('(Search|Group(Header|Footer)|(All)?RecentChanges)', $pagename))%0a { $HandleAuth['edit'] = 'admin'; }%0a@]%0a%0aQ: How do I password protect the creation of new groups?%0aA: See [[Cookbook:Limit Wiki Groups]] {Cookbook.LimitWikiGroups$:Summary}%0a%0aQ: How do I password protect the creation of new pages?%0aA: See [[Cookbook:Limit new pages in Wiki Groups]] {Cookbook.LimitNewPagesInWikiGroups$:Summary}%0a%0aQ: How do I take a whitelist approach where users from known or trusted IP addresses can edit, and others require a password?%0aA: Put these lines to local/config.php:%0a[@%0a## Allow passwordless editing from own turf, pass for others.%0aif ($action=='edit'%0a && !preg_match("/^90\\.68\\./", $_SERVER['REMOTE_ADDR']) ) %0a { $DefaultPasswords['edit'] = crypt('foobar'); }%0a@]%0aReplace 90.68. with the preferred network prefix and foobar with the default password for others.%0a%0aQ: How do I password protect [[PmWiki/AvailableActions|page actions]]?%0aA: See [[PmWiki/Passwords]] for setting in config.php %0a-> @@$HandleAuth['[==]''pageactionname''[==]'] = 'pageactionname'; # along with :@@%0a-> @@$DefaultPasswords['[==]''pageactionname''[==]'] = crypt('secret phrase');@@%0aA: or %0a-> @@$HandleAuth['[==]''pageactionname''[==]'] = 'anotherpageactionname';@@%0a%0aQ: How to make a rule that allows only authors to edit their own wiki page in [[Profiles]] group?%0aA: Add this to your ''local/config.php''%0a%0a->@@$name = PageVar($pagename, '$Name');@@%0a->@@$group = PageVar($pagename, '$Group');@@%0a->@@if($group=='Profiles') $DefaultPasswords['edit'] = 'id:'.$name;@@%0a%0aQ: How do I moderate all postings?%0aA: Enable [[PmWiki.Drafts]]%0a* Set $EnableDrafts, this relabels the "Save" button to "Publish" and a "Save draft" button appears. %0a* Set $EnablePublish, this adds a new "publish" authorization level to distinguish editing from publishing.%0a%0aQ: How do I make a read only wiki?%0aA: In config.php [[PmWiki/PasswordsAdmin | set]] an "edit" password.%0a%0aQ: How do I restrict access to [[PmWiki/Uploads|uploaded attachments]]?%0aA: See%0a* [[PmWiki/UploadsAdmin#direct_download|instructions]] for denying public access to the uploads directory%0a* see [[Cookbook:Secure attachments]] {Cookbook.SecureAttachments$:Summary}%0a%0a%0a%0a
+time=1265191198
diff --git a/wikilib.d/PmWiki.SecurityVariables b/wikilib.d/PmWiki.SecurityVariables
new file mode 100644
index 0000000..d2415ce
--- /dev/null
+++ b/wikilib.d/PmWiki.SecurityVariables
@@ -0,0 +1,12 @@
+version=pmwiki-2.2.0 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.19) Gecko/20081216 Ubuntu/8.04 (hardy) Firefox/2.0.0.19
+author=Petko
+charset=ISO-8859-1
+csum=mv question to talk
+ctime=1156512569
+host=81.65.14.164
+name=PmWiki.SecurityVariables
+rev=26
+targets=PmWiki.AuthUser,PmWiki.PasswordsAdmin,PmWiki.Security
+text=(:Summary:variables crucial for site security:)%0a%0a:$AuthUserFunctions: (Present only when the in-built [[AuthUser]] username/password functionality is used). An array of different authentication mechanisms to be used for user authentication. Array keys are a tag for the mechanism; values are a function callback that will be called with the properties $pagename, $id, $password, and $pwlist. Oh... could someone else make this make sense, please?!%0a%0a:$DefaultPasswords: Specifies default passwords for user admin or actions (edit, read, upload). See [[PmWiki/PasswordsAdmin#settingsitewidepasswords]].%0a%0a:$EnablePostAttrClearSession:A switch to control whether or not changing a page's attributes causes any existing passwords to be forgotten. The default is that changing attributes forgets any passwords entered; this can be changed by setting $EnablePostAttrClearSession to zero.%0a%0a:$EnableSessionPasswords: Control whether passwords are saved as part of the session. If set to zero, then session passwords are never saved (although any [[AuthUser]] authentications are still remembered).%0a%0a:$SessionEncode: Function to use to encode sensitive information in sessions. Set this to NULL if you want to not use any encoding. (See also $SessionDecode below.)%0a%0a:$SessionDecode: Function to reverse the decoding given by $SessionEncode above. Set this to NULL if sensitive session values are not encoded.%0a%0a:$HandleAuth:This sets the required authentication Level that is necessary to perform an action. When using the following example in your @@config.php@@ you need to be authenticated as editor in order to view the page history:%0a $HandleAuth['diff'] = 'edit';%0a%0a:$PageAttributes:Set the string shown on the attributes page when entering a password for an action.%0a%0a:$AuthLDAPBindDN:For sites using [[AuthUser]] with LDAP authentication, this specifies the distinguished name (DN) to be used to bind to the LDAP server to check identity.%0a%0a:$AuthLDAPBindPassword:For [[AuthUser]] with LDAP authentication, this specifies the password used for binding (in conjunction with $AuthLDAPBindDN above).%0a%0a:$EnablePublishAttr:Adds a new "publish" authorization level to distinguish editing of drafts from publishing - See $EnableDrafts.%0a%0aSee also:%0a* [[Security]]%0a* $EnablePageListProtect%0a%0a
+time=1234653712
diff --git a/wikilib.d/PmWiki.SimultaneousEdits b/wikilib.d/PmWiki.SimultaneousEdits
new file mode 100644
index 0000000..43e5752
--- /dev/null
+++ b/wikilib.d/PmWiki.SimultaneousEdits
@@ -0,0 +1,11 @@
+version=pmwiki-2.2.0-beta68 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.0.1) Gecko/2008070208 Firefox/3.0.1
+author=simon
+charset=ISO-8859-1
+csum=trails
+host=203.97.214.12
+name=PmWiki.SimultaneousEdits
+rev=18
+targets=Main.WikiSandbox
+text=(:Summary: Handling multiple attempts to edit a page nearly simultaneously:)%0aPmWiki has support for handling the case where multiple authors attempt to edit the same page nearly simultaneously. Here's the basic scenario for systems where simultaneous edits are ''not'' handled:%0a%0a* Alice starts to edit a page.%0a* Before Alice saves her edits, Bob requests an edit of the same page, and receives the page text prior to Alice's edits.%0a* Bob finishes with his edits and hits "save".%0a* Alice finishes editing her page, hits "save", and since she was working from a version of the page from before Bob had made his changes, she wipes out Bob's edits in the process.%0a%0aPmWiki's simultaneous edit feature detects when this occurs, and instead of saving Alice's edits PmWiki presents Alice with a message that someone else changed the page while she was editing it. Furthermore, Bob's changes are merged into Alice's copy of the page, with any conflicts highlighted by %3c%3c%3c%3c%3c%3c%3c and >>>>>>>. Alice can then fix things as appropriate and save the updated page, or, if Alice is lazy, she can just hit "save" a second time and leave it to someone else to fix.%0a%0aThe simultaneous edits feature is also invoked whenever someone requests a page preview; thus if a page changes while previewing a page the author gets notification and can see the merged results.%0a%0a!!!How can I test/experiment with this feature?%0a%0a# Open up two browser windows and select the same page to be edited in each window (e.g., try [[Main/WikiSandbox?action=edit]]).%0a# In one browser window, make some changes to the page and then save those changes.%0a# In the second browser window, make some different changes to the same page and hit "save". Since the page changed after the edit form was loaded into the second window, there's a potential edit conflict and you'll receive the "edit conflict message".%0a# You can make any adjustments in the second window, and press "Save" again to save the changes.%0a%0a!!!Notice%0a%0aSome server environments such as Windows and PHP running in safe_mode are unable to use the simultaneous edits capability distributed with PmWiki. See Cookbook:SimultaneousEdits for a solution for these environments.%0a
+time=1220179690
diff --git a/wikilib.d/PmWiki.SitePageActions b/wikilib.d/PmWiki.SitePageActions
new file mode 100644
index 0000000..717365f
--- /dev/null
+++ b/wikilib.d/PmWiki.SitePageActions
@@ -0,0 +1,12 @@
+version=pmwiki-2.2.0 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.5) Gecko/2008120122 Firefox/3.0.5
+author=HansB
+charset=ISO-8859-1
+csum=update
+ctime=1160022336
+host=80.41.219.196
+name=PmWiki.SitePageActions
+rev=7
+targets=Site.PageActions,PmWiki.BasicEditing,PmWiki.Skins,PmWiki.WikiStyles,PmWiki.AccessKeys,Site.Preferences,PmWiki.Internationalizations,PmWiki.Links,PmWiki.PageVariables,PmWiki.SitePageActions,PmWiki.ConditionalMarkup,PmWiki.DocumentationIndex,PmWiki.MailingLists,PmWiki.PageActions
+text=%25audience%25 authors (basic)%0a%0aThe [[Site.PageActions]] uses a large number of PmWiki features in concert. %0aThis page gives a brief explanation of the features commonly used on [[Site.PageActions]], and pointers to where more information can be found.%0a%0aTo start with, lets look at a typical Site.PageActions page.\\%0aBelow is what is currently shipping with PmWiki version 2.2.0:%0a->[@%0a* %25item rel=nofollow class=browse accesskey='$[ak_view]'%25 [[{*$FullName} | $[View] ]]%0a* %25item rel=nofollow class=edit accesskey='$[ak_edit]'%25 [[{*$FullName}?action=edit | $[Edit] ]]%0a* %25item rel=nofollow class=diff accesskey='$[ak_history]'%25 [[{*$FullName}?action=diff | $[History] ]]%0a(:if auth upload:)%0a* %25item rel=nofollow class=upload accesskey='$[ak_attach]'%25 [[{*$FullName}?action=upload | $[Attach] ]]%0a(:ifend:)%0a* %25item rel=nofollow class=print accesskey='$[ak_print]'%25 [[{*$FullName}?action=print | $[Print] ]]%0a(:if group Site,SiteAdmin,Cookbook:) (:comment delete if and ifend to enable backlinks:)%0a* %25item rel=nofollow class=backlinks accesskey='$[ak_backlinks]'%25 [[{*$Name}?action=search&q=link={*$FullName} | $[Backlinks] ]]%0a(:ifend:)%0a(:if enabled AuthPw:)%0a* %25item rel=nofollow class=logout accesskey='$[ak_logout]'%25'' [-[[{*$FullName}?action=logout | $[logout] ]]-]''%0a(:ifend:)%0a@]%0a%0aThat can seem a bit daunting, but we'll take it piece by piece. To start with, we'll look at just the first line, and take it apart. This will also give us a good handle on how most of the other lines work.%0a%0a!! List%0aThe first line, and in fact every line, begins with an unindented '@@*@@', which means its an item in an unordered list. %0aYou can find out more about lists on the [[Basic Editing]] page. %0aPmWiki will normally display an unordered list as a set of bulleted items, but they can appear differently depending on the context they are displayed in. This difference in display is generally controlled by CSS defined in the Skin.%0a%0aIf you take a look at the [[Site.PageActions]] page with the default PmWiki [[PmWiki.Skins|skin]], you'll see that the list appears twice, once as a normal bulleted list in the middle of the page, and once as a row of unbulleted actions at the top right corner of the page. This is controlled by the fact that they are being rendered inside an HTML [@%3cdiv>@] with an [@id@] of 'wikicmds' and the CSS for the default PmWiki skin asks that list items inside a wikicmds element be displayed that way.%0a%0aYou can see the difference for yourself since PmWiki has markup that lets you ask for something to be rendered inside a div with a given [@id@]:%0a(:markup class=horiz:)%0a* test1%0a* test2%0a* test3%0a%0a(:div id=wikicmds:)%0a* test1%0a* test2%0a* test3%0a(:divend:)%0a(:markupend:)%0a%0a!! Style%0aFollowing the '[@*@]', on the line we have [@%25item ... %25@] which is a [[WikiStyles|WikiStyle]]. It is used to control the properties of a given output element, like its size or color. By default they apply to the text between them and the end of the line or a closing [@%25%25@], whichever is sooner. So, for example, one can enter [@"this %25blue%25text%25%25 is blue"@] and it will appear as "this %25blue%25text%25%25 is blue".%0a%0aIn this case the WikiStyle starts with the word [@item@], and that says to apply the given style to the entire list item as opposed to just the text that follows. In particular, it causes PmWiki to generate HTML of%0a%0a->[@%3cli class='edit'>...%3c/li>@]%0a%0ainstead of%0a%0a->[@%3cli>%3cspan class='edit'>...%3c/span>%3c/li>@]%0a%0aSetting the class attribute of the list item allows CSS properties to be applied to the item that corresponds to the current action. For example, to have the current action display with a background color of blue, a wiki administrator can do:%0a%0a->@@$HTMLStylesFmt[]@@[@ = ' .{$Action} { background-color: blue; }';@]%0a%0aThen if the current action is 'edit' (as in "?action=edit"), the list item corresponding to the edit action will be drawn with a blue background.%0a%0aThe other property inside the [@%25item ... %25@] WikiStyle is the accesskey='$[ak_view]' statement. [[AccessKeys]] are keyboard shortcuts for tasks that would otherwise require a mouse. They can be attached to links or to form elements and the WikiStyle will use whichever it finds first on the line. In this case they will attach to the link [@[[{*$FullName} | $[View] ]]@].%0a%0a!! Accesskey%0aAn accesskey can be defined in a number of locations, but essentially it is a phrase translation following the model used for internationalizations. PmWiki's accesskey defaults are defined in @@scripts/prefs.php@@, but can be overridden in lots of different places, including skins, language translation pages (XLPage), and even per-browser preferences (see [[Site.Preferences]]).%0a%0aThe [@$[...]@] markup defines phrase translations, used for internationalizations (and access keys, as noted above). In the first line of [[Site.PageActions]] it is used in both [@$[ak_view]@] and [@$[View]@]. Essentially [@$[View]@] tells PmWiki to substitute the current translation of "View". If no translation is defined for "View", then PmWiki just uses the phrase inside the brackets.%0a%0aYou can most easily see this working in the other languages sections of PmWiki. For example, at [[(http://pmwiki.org/wiki/)PmWikiDe/PmWikiDe]] you'll notice that the default "View", "Edit", "History", and "Print" actions are displayed as "Artikel", "Bearbeiten", "Historie", and "Druckansicht".%0aThis is because the PmWikiDe group is loading in a set of translations from [[(http://pmwiki.org/wiki/)PmWikiDe.XLPage]] %0a%0aThat page defines things like%0a%0a->[@'View' => 'Artikel'%0a'Edit' => 'Bearbeiten'%0a'History' => 'Historie'%0a'Print' => 'Druckansicht'@]%0a%0awhich says that things like [@$[View]@] and [@$[Edit]@] should be replaced by "Artikel" and "Bearbeiten".%0a%0aThis makes it very easy for PmWiki to support multiple languages, since a recipe author can simply put any translatable prompts or phrases inside of [@$[...]@], and leave it to others to actually build the translation tables (either locally or on [[(http://)pmwiki.org]] for others to use). More information about [@$[...]@] is available at [[PmWiki/Internationalizations]].%0a%0a!! Link%0aAll that leaves on the first line to be explained is the [[PmWiki.Links|link]] itself: [@[[{*$FullName} | $[View] ]]@]. Links are not complex, but this one is using both the internationalization feature and a [[PageVariables|Page Variable]]. The [@$[View]@] has already been explained and it shows up in the link text section of link markup, so that, if viewed in English, the link will appear as [[[[{*$FullName} |$[View]]].%0a%0aThe link target section contains the [@{*$FullName}@] variable. This variable expands to the full name of the page on which it is being displayed, including the group and page names. For simple browsing, this is good enough, because viewing a page is the default action to perform on a page. Later lines use link targets like [@{*$FullName}?action=edit@] which says to go to the currently displayed page and start editing it.%0a%0a!! If%0aThis explains what all of the '[@*@]' lines are about. That only leaves the [@(:if auth upload:)@] and [@(:ifend:)@] lines, and they go together. The first starts some [[Conditional Markup]] and the second ends it. The [@(:if test :)@] markup only lets the following text be displayed if the test succeeds. The text that conditionally displayed ends at the next [@(:if...:)@] statement so an empty [@(:ifend:)@] is a convenient way to end the conditional block. The particular test being used here is [@auth upload@] which is only true if the current user is authorized to upload files to the wiki. Thus, the conditional block says to only display a link to perform an upload if the user is actually allowed to upload.%0a%0aDepending on the security and permissions model on a given site, its not unusual to see many more conditional markups that test if, for example, a user has editing rights to the current page. More information on all the different conditions can be found at the [[Conditional Markup]] page, and a general index of all the PmWiki documentation can be found at [[Documentation Index]].%0a%0aHopefully this bit of documentation has answered your questions about the [[Site.PageActions]] page. %0aIf not, you may wish to consult the helpful people on one of the [[MailingLists|PmWiki Mailing Lists]].%0a%0a----%0a%0a%25green%25Note that any Group can have a [[Page Actions]] page, not just '''Site''' - this page should be edited to reflect that.%0a
+time=1233331974
diff --git a/wikilib.d/PmWiki.SitePreferences b/wikilib.d/PmWiki.SitePreferences
new file mode 100644
index 0000000..b2a57b6
--- /dev/null
+++ b/wikilib.d/PmWiki.SitePreferences
@@ -0,0 +1,11 @@
+version=pmwiki-2.2.0 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.9.0.5) Gecko/2008120122 Firefox/3.0.5
+author=OliverBetz
+charset=ISO-8859-1
+csum=
+host=87.163.109.22
+name=PmWiki.SitePreferences
+rev=11
+targets=Site.Preferences,PmWiki.AccessKeys,Site.EditForm
+text=(:Summary: Customisable browser setting preferences: Access keys, edit form:)%0aThe page [[{$SiteGroup}.Preferences]] contains customisable browser preference settings.%0aThese include [[access keys]] (keyboard shortcuts to certain actions like edit, history, browse) and settings of the [[{$SiteGroup}.EditForm]] (width and height of the edit textarea) as well as the name of the edit form in use.%0a%0aA different page than [[{$SiteGroup}.Preferences]] can be chosen by making a copy of that page under a new name, customising it, and setting a cookie which will point to this page for the browser being used, through %0a%0a ?setprefs=`SomeGroup.`CustomPreferences %0a%0a`SomeGroup.`CustomPreferences being the name of the new customised preference page.%0a%0a!!Notes and Comments%0a%0aNote that in order to enable parsing of [[{$SiteGroup}.Preferences]] by default, a line like the following needs to be added to local/config.php:%0a%0a XLPage('prefs', "Site.Preferences");%0a
+time=1234194118
diff --git a/wikilib.d/PmWiki.SkinTemplates b/wikilib.d/PmWiki.SkinTemplates
new file mode 100644
index 0000000..24260be
--- /dev/null
+++ b/wikilib.d/PmWiki.SkinTemplates
@@ -0,0 +1,11 @@
+version=pmwiki-2.2.6 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.4) Gecko/20091028 Ubuntu/9.10 (karmic) Firefox/3.5.4
+author=Petko
+charset=ISO-8859-1
+csum=refactor, absolute Cookbook links, to pmwiki.org and not to the downloaded documentation
+host=81.65.12.233
+name=PmWiki.SkinTemplates
+rev=52
+targets=PmWiki.Skins,PmWiki.LayoutVariables,PmWiki.PageVariables,PmWiki.PageDirectives,PmWiki.Internationalizations
+text=(:Summary:[[PmWiki/Skin(s)]] templates (.tmpl files):)%0a%25define=box block bgcolor=#f9f9fc border='1px solid #666666' margin=10px padding=5px%25%0aThis page describes the skin template files (.tmpl) that are used to create PmWiki ''skins'', and how PmWiki uses them. As described in the [[skins]] page, a skin is a collection of files that specifies the layout for PmWiki pages. Each skin must include a template file that provides the skeleton for displaying a PmWiki page.%0a%0a!! [[#findingprocessing]]Finding and Processing Templates%0a%0aWhen you set the value of the $Skin variable in a configuration file like @@local/config.php@@, like this%0a-> [@%0a## Use the Foo Skin.%0a$Skin = 'foo';%0a@]%0a%0ait tells PmWiki to search for a skin of that name, and use it. The usual result of the search is for PmWiki to load a template file from the appropriate skin directory. In this example, that would probably be the file @@pub/skins/foo/foo.tmpl@@.%0a%0aThe actual processing that PmWiki goes through to find a template file is important for those who are making complex skins, so its worth mentioning what those steps are:%0a%0a>>rframe width=25pct margin-left:2em font-size:smaller%3c%3c%0a!! [[#security]]Security Note%0aThe default value for @@[=$=]SkinLibDirs@@ has server-side and client-side files stored in the same publicly-accessible directory. That is, @@$SkinDir@@ and @@$SkinDirUrl@@ point to the same place. This is done for convenience (both for the skin user, and the skin writer), but it is not necessary.%0a%0aIt has the side effect that its possible to construct a URL ([[http://www.pmwiki.org/pmwiki/pub/skins/pmwiki/pmwiki.tmpl|like this one]]) that will let you look at the contents of the the @@.tmpl@@ or @@.php@@ files that a skin uses. This is usually not an issue as skin files should not contain any sensitive information.%0a%0aStill, a purist might want to move their @@.tmpl@@ and @@.php@@ files out of the directories that are accessible as URLs, and modify their @@[=$=]SkinLibDirs@@ array to reflect this.%0a>>%3c%3c%0a%0a#When @@$PageTemplateFmt@@ is blank (as it should be), PmWiki gathers the names of all candidate skins. It starts with any action-specific skin that is specified in @@[[LayoutVariables#ActionSkin|$ActionSkin]][$action]@@. Thus, if the current action is 'login', and @@$ActionSkin['login']@@ is @@'Bar'@@, then PmWiki will look for a skin named 'Bar'. %0a%0a#If no skin has been found yet, it looks for the skin(s) named in the @@$Skin@@ variable (which is allowed to be an array) and uses the first skin it can find. If it gets to the end of the list without finding a skin, it issues an error.%0a%0a#To attempt to find a skin, PmWiki first consults the @@[[LayoutVariables#SkinLibDirs|[=$=]SkinLibDirs]]@@ variable to know where to look. Skins consist of server-side files that are loaded by PmWiki (such as .php and .tmpl files) and client-side files (such as .css files and images) that will be requested by the user's browser when they look at a skinned PmWiki page. @@$SkinLibDirs@@ is an array of key/value pairs. The key is a directory to look in for the server-side files, while the corresponding value is a URL that points to the public client-side resources used by the skin. The default value of @@[=$=]SkinLibDirs@@ is:%0a -> [@%0a$SkinLibDirs = array(%0a "./pub/skins/\$Skin" => "$PubDirUrl/skins/\$Skin",%0a "$FarmD/pub/skins/\$Skin" => "$FarmPubDirUrl/skins/\$Skin");%0a@]%0a%0a So, using the above definitions, PmWiki would try to find the skin 'foo' by looking for a directory called @@./pub/skins/foo@@ and then for @@$FarmD/pub/skins/foo@@ (with the value of @@$FarmD@@ replaced by the root server directory for Farm files). The first such directory that was found would be assumed to contain the skin it was looking for. It would then set @@$SkinDir@@ to the name of this directory and @@$SkinDirUrl@@ to the corresponding URL.%0a%0a#Once a valid skin directory has been found, PmWiki starts processing the files in that directory, looking for a @@.php@@ skin file to run. It first looks for one with the same name as the skin. So, if the skin is 'foo', it looks for @@foo.php@@. If no such file is found, it then checks for a file named @@skin.php@@. If one of these @@.php@@ files is found, PmWiki loads and runs it. This allows a skin to define custom markup, or custom configuration parameters. It also allows a skin to choose between which of several different @@.tmpl@@ files to load.%0a%0a To specify which @@.tmpl@@ file to load, simply call @@LoadPageTemplate()@@ inside the skin @@.php@@ file, with the name of the @@.tmpl@@ file to be loaded:%0a%0a -> @@LoadPageTemplate($pagename, "$SkinDir/xyz.tmpl");@@%0a%0a For example, a skin might specify a special template to be used if the action is 'print':%0a%0a -> [@%0aif ($GLOBALS['action'] == 'print')%0a LoadPageTemplate($pagename, "$SkinDir/print.tmpl");%0a@]%0a%0a When the action is something else, PmWiki will fall back to loading the default @@.tmpl@@ file instead.%0a%0a#If no appropriate @@.php@@ file is found, or if that file doesn't load a template, then PmWiki falls back to looking for a template with the same name as the skin, or, failing that, any @@.tmpl@@ file at all, so long as its the only one in the directory. If it finds one, it will load and process it. If not, it will issue an error.%0a%0a!![[#fileformat]]Template file format%0a%0aA template file is basically an HTML file that also contains variable substitutions (indicated by '$') and special directives embedded in HTML comments. The following special directives are ''required'' in the template file. %0a# The directive [@%3c!--PageText-->@] belongs to the %3cbody> section of the HTML document, and tells PmWiki where the main content of each wiki page should be placed. %0a# The directive [@%3c!--HTMLHeader-->@], which goes somewhere in the %3chead> section of the HTML document.%0a# The directive [@%3c!--HTMLFooter-->@] directive, which typically goes before the final %3c/body> tag and is used by some recipes to insert things at the end of the HTML document. [- %25green%25''Prior to PmWiki 2.2.0 the [@%3c!--HTMLFooter-->@] directive was optional.'' -]%0a%0aWhen PmWiki displays a page, it replaces the directives and variable substitutions with the values appropriate to the current page. For example, the [@%3c!--PageText-->@] directive is replaced with the page's contents, while any instances of $PageUrl are replaced with the url (address) of the current page.%0a%0aThere is a long list of variables available for substitution in pages; some of the%0amost useful include:%0a-> [@%0a$PageUrl the url of the current page%0a$ScriptUrl the base url to the pmwiki.php script%0a$Title the page's title (e.g., "`SkinTemplates")%0a$Titlespaced the page's title with spaces (e.g., "Skin Templates")%0a$Group the name of the current group (e.g., "`PmWiki")%0a$FullName the page's full name (e.g., "`PmWiki.SkinTemplates")%0a$LastModified the page's last modification time%0a$PageLogoUrl the url of a site logo%0a$WikiTitle the site's title%0a$SkinDirUrl the url of the skin's folder%0a@]%0a%0aThis last variable, $SkinDirUrl, is particularly useful in templates as it allows the skin designer to refer to other files (such as images or style sheets) in the skin folder without having to know the exact url.%0a%0aThe template is not limited to using the variables listed here; nearly any PHP global variable that begins with a capital letter can be used in a skin template. [[Page variables]] can also be used in templates.%0a%0a!![[#directives]] Skin directives%0a%0aBesides the required [@%3c!--PageText-->@] and [@%3c!--HTMLHeader-->@] directives, PmWiki provides other built-in directives for generating page output. It's not necessary to use any of these directives, but they can often add capabilities to a skin %0a%0a:[@%3c!--wiki:Main.SomePage-->@]:%0a:[@%3c!--page:Main.SomePage-->@]:%0a: :The [@%3c!--wiki:Main.SomePage-->@] directive outputs the contents of `Main.SomePage. $-substitutions are allowed in directives, thus a directive like [@%3c!--wiki:$Group.SomePage-->@] will include "`SomePage" of the current group. %0a%0a: :If multiple pages are listed in the directive, then only the first available page is used. Thus [@%3c!--wiki:$Group.SomePage Site.SomePage-->@] will display the contents of `SomePage in the current group if it exists, and `Site.SomePage if it doesn't. To always display `Site.SomePage, even if $`Group.SomePage exists, use two consecutive [@%3c!--wiki:...-->@] directives.%0a%0a: :The [@%3c!--wiki:...-->@] directive only displays pages for which the browser has read permissions. The [@%3c!--page:...-->@] directive displays pages even if the browser doesn't have read permission.%0a%0a%0a:[@%3c!--file:somefile.txt-->@]:%0a: :The directive [@%3c!--file:somefile.txt-->@] outputs the contents of another file (on the local filesystem) at the point of the directive. If the file to be included is a .php script, then the PHP script is executed and its output is sent to the browser. Like the [@%3c!--wiki:...-->@] directive above, $-substitutions are available to be able to output files based on the current page name or group.%0a%0a:[@%3c!--markup:...-->@]:%0a: :The markup directive processes any text that follows the colon as wiki markup and displays that in the output. %0a%0a:[@%3c!--function:SomeFunction args-->@]:%0a: :This directive calls a PHP function named "`SomeFunction", passing the current page's name and the text following the function name as arguments. PHP functions called in this manner are typically defined in a local customization file. Args allows only one argument, which has to be splitted then. [@%3c!--function:SomeFunction arg1 arg2 arg3-->@] generates one parameter "arg1 arg2 arg3". However variables can be used (like $LastModifiedBy).%0a%0a!![[#sections]] Page sections%0a%0aA template file can designate "sections" that are included or excluded from the output based on [[page directives]] or other criteria. A section always begins with [@%3c!--Page...Fmt-->@] and continues to the next section, the end of the template file, or [@%3c!--/Page...Fmt-->@]. For example, a template can specify a [@%3c!--PageLeftFmt-->@] section that is excluded from the output whenever the [@(:noleft:)@] directive is encountered in the page's contents. PmWiki's predefined sections (and their corresponding page directives) are:%0a-> [@%0a%3c!--PageHeaderFmt--> (:noheader:)%0a%3c!--PageFooterFmt--> (:nofooter:)%0a%3c!--PageTitleFmt--> (:notitle:)%0a%3c!--PageLeftFmt--> (:noleft:)%0a%3c!--PageRightFmt--> (:noright:)%0a%3c!--PageActionFmt--> (:noaction:)%0a@]%0a%0aSkin designers can define custom sections and markups, but currently all section names in the template must begin with "Page" and end with "Fmt". As mentioned you also have to define the corresponding markup (for example in your config.php) like this: %0a%0a->[@Markup('noxyz', 'directives', '/\\(:noxyz:\\)/ei',%0a "SetTmplDisplay('PageXYZFmt',0)");@] %0a%0a!![[#i18n]] Internationalization (i18n)[[#Internationalization]]%0a%0aSkins can also be [[internationaliz(ations)]]ed by using [@$[...]@] substitutions. Any string placed inside of [@$[...]@] is treated as a "translatable phrase", and the phrase is looked up in the current translation tables for a corresponding output phrase. If a translation is available, then the translated phrase is substituted at that point, otherwise the original phrase is left intact.%0a%0aFor example, the substitution [@$[Edit]@] will display the current translation of "Edit" if it is known, otherwise it displays "Edit". Thus, the same template can be used for multiple languages, displaying "Editer" when French translations are loaded, "Bearbeiten" when German translations are loaded, and "Edit" when no translation is available.%0a%0a!! Understanding old config files%0a-%3c %25red%25This information is deprecated%25%25, but we're still including it in the docs so you can better understand any really old @@local/config.php@@ files you look at. %0aThe original method of telling PmWiki where to find a skin used to be to set @@$PageTempateFmt@@ to the path of a @@.tmpl@@ file on the server. This is still respected by PmWiki, so if, for example, you were to set @@$PageTemplateFmt@@ to @@./pub/skins/foo/foo.tmpl@@ then PmWiki would simply load and use that file, but without setting the special @@$SkinDir@@ and @@$SkinDirUrl@@ variables that are required by all modern skins.%0a-> %25red%25DO NOT USE @@$PageTemplateFmt@@%25%25%0a%0a%0a>>faq%3c%3c [[#faq]]%0a%0aQ: How do I customize the CSS styling of my PmWiki layout?[[#customcss]]%0a%0aA: See [[Skins]] for how to change the default PmWiki skin. See also [[Cookbook:Skins]], where you will find pre-made templates you can use to customize the appearance of your site. You can also create a file called ''local.css'' in the ''pub/css/'' directory and add CSS selectors there (this file gets automatically loaded if it exists). Or, styles can be added directly into a local customization file by using something like:%0a%0a-> [@$HTMLStylesFmt[] = '.foo { color:blue; }';@]%0a%0a%0aQ: Where can the mentioned "translation table" be found for adding translated phrases?%0aA: See [[Internationalizations]].%0a%0aQ: Is it possible to have the edit form in full page width, with no sidebar?%0aA: If the sidebar is marked with [@%3c!--PageLeftFmt-->@], adding [@(:noleft:)@] to Site.EditForm will hide it when a page is edited.%0a%0aQ: Can I easily hide the Home Page title from the homepage?%0aA: Yes, you can use in the wiki page either @@[=(:title Some other title:)=]@@ to change it or @@[=(:notitle:)=]@@ to hide it.%0a%0aQ: Is it possible to hide the Search-Bar in the default PmWiki Skin?%0aA: Yes, please see [[Cookbook:HideSearchBar]].%0a%0a
+time=1257638176
diff --git a/wikilib.d/PmWiki.Skins b/wikilib.d/PmWiki.Skins
new file mode 100644
index 0000000..e136830
--- /dev/null
+++ b/wikilib.d/PmWiki.Skins
@@ -0,0 +1,11 @@
+version=pmwiki-2.2.2 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.19) Gecko/20081216 Ubuntu/8.04 (hardy) Firefox/2.0.0.19
+author=Petko
+charset=ISO-8859-1
+csum=the link to the talk page is in the bottom (GroupFooter)
+host=81.65.14.164
+name=PmWiki.Skins
+rev=99
+targets=PmWiki.Skins,PmWiki.SkinTemplates,PmWiki.Installation,Site.EditQuickReference
+text=(:Summary: Change the look and feel of part or all of PmWiki:)(:Audience: administrators (basic) :)%0a(:div class='rfloat frame' style="font-size:smaller; clear:right;" :)%0a!!Contents%0a* [[#what | What is a skin?]]%0a* [[#where | Where do I get skins?]]%0a* [[#use | How do I use a skin?]]%0a* [[#modify | How can I modify an existing skin?]]%0a* [[#make | How can I make a skin?]]%0a(:divend:)%0a!!What's a skin? [[#what]]%0a%0aA skin changes the look and feel of a PmWiki page, Group of pages, or the entire wiki.%0aTo see this try some skins out using the links below.%0a%0a* [[PmWiki:Skins?skin=beeblebrox-gila2 | BeeblebroxNetGila ]]%0a* [[PmWiki:Skins?skin=jhskin | JHSkin ]]%0a* [[PmWiki:Skins?skin=gemini | GeminiSkin ]]%0a* [[PmWiki:Skins?skin=light | LightSkin ]]%0a* [[PmWiki:Skins?skin=monobook | Monobook Skin ]]%0a* [[PmWiki:Skins?skin=simple | Simple Skin ]]%0a* [[PmWiki:Skins?skin= | PmWiki (default) Skin ]]%0a%0aAs you see, all skins show the same page contents, but the other elements such as the sidebar, header, and footer, have changed. %0aFor example, different skins may display the sidebar on the left, on the right, or even not at all. %0aSome skins have action links and features that others do not, especially if they were designed to take advantage of particular [[cookbook recipes -> Cookbook:Cookbook]].%0a%0aSo, a skin is just the set of files that determine how pages are displayed in PmWiki. Skins are stored as subfolders of ''pub/skins/''. For example you might create the ''example'' skin in ''pub/skins/example/''. Each skin typically has one or more of the following kinds of files:%0a* A template file, such as ''skin.tmpl'' or ''gemini.tmpl''. The template is written in HTML or XHTML, and is the skeleton for the skin. It contains special markers that tell PmWiki where to insert the page's contents.%0a* CSS stylesheet files, which can control the skin's appearance.%0a* Image files, for decorating a page with images.%0a* PHP files, such as ''skin.php''. These let skins provide extra customization setting or capabilities that HTML and CSS alone cannot.%0a* Documentation files for the administrator, usually with names like ''readme.txt'', ''install.txt'' or ''skinname.txt''. These usually give you information about any special installation steps or nifty features the skin has.%0a%0a!! Where do I get skins? [[#where]]%0a%0aSkins are available in the [[Cookbook:Skins]] collection. %0aThe skins in the collection have been contributed by other PmWiki administrators for others to use, and typically have their own set of customization possibilities. %0aWhen you find a skin you like, follow the link to download the skin package.%0aYou can also [[{$FullName}#make|make your own]] skin.%0a%0a!!How do I use or install a skin? [[#use]]%0a%0aMost skin packages are .zip, .tgz, or .tar.gz files. You should be able to unpack these with most archiving software.%0a%0a# Unpack the skin to ''pub/skins/'' inside your pmwiki folder. Most well-designed skin packages will create a subfolder in ''pub/skins/'' named after the skin.%0a** If the skin did not make a folder of its own, create one and move the skin files to it.%0a%0a# Open up your ''local/config.php'' file, and add a line like\\%0a\\%0a[@$Skin = 'my-favourite-skin';@]\\%0a\\%0awhere 'my-favourite-skin' is the name of the skin's folder.%0a%0aReload a page from your wiki in the browser, and you should be able to see the difference.%0a%0aIf you'd like to let your site's visitors choose one skin from a selection of skins you've installed, look at the [[Cookbook:SkinChange]] recipe. (That's what we used for the demo above.)%0a%0a!! How can I modify an existing skin? [[#modify]] [[#further]]%0a%0aThere are a number of ways to further customize the appearance of a skin, including %0a* adding statements to /local/config.php that are compatible with your chosen skin; %0a* adding css files to /pub/css/, such as local.css (for your entire wiki) and MyGroup.css (for MyGroup); and %0a* directly editing the skin's files. %0aIf the skin is updated regularly, you probably will want to avoid editing the files in the skin's folder. %0aCheck the skin's page in the Cookbook for specific suggestions.%0a%0aIf you want to modify the default pmwiki or print skins included with the PmWiki distribution, you should copy the pub/skins/pmwiki/ and pub/skins/print/ directories to another name and then use those skins instead of the default ones. While the name of the skin.tmpl and skin.css files don't usually matter, the optional skin.php file MUST match the name of the skin.%0a%0a!!How can I make a skin? [[#make]]%0a%0aThe best way to make your first skin is to modify a copy of PmWiki's default skin. %0a%0a# Make a copy of the folder ''pub/skins/pmwiki'' and name it whatever your new skin should be named.%0a# In your ''local/config.php'' file, set $Skin to be the name of your new skin.%0a# Modify the template and CSS files to suit you.%0a# Test your new skin.%0a# Repeat steps 3 and 4 until you're happy with the results.%0a%0aThe reason we recommend starting with the default PmWiki skin is that it's quite a simple skin, much more so than many of the skins you'll find in [[Cookbook:Skins]]. The starting point is the template (.tmpl) file, which provides the overall layout of the page. Inside of the template file are a number of special substitutions and directives that provide places for PmWiki to insert the data relevant to the current page being displayed. [[SkinTemplates]] describes the format and directives in more detail. There are also [[Cookbook:SkinGuidelines|skin guidelines]] available on pmwiki.org.%0a%0aIt's beyond the scope of this page to explain how to write HTML (hypertext markup language), XHTML (extensible HTML, which is a bit newer) or CSS (cascading style sheets), but there are many good tutorials on the web for all three of them. One caution: if you run into an HTML tutorial that explains about how to use %3cfont> or %3cblink> tags, or spacer gifs, it's at least five years out of date, so skip it and find another one. %0a%0aYou should test your skin on a variety of browsers -- ideally as many as you can, on as many different platforms as you can -- but at minimum you should be testing on Internet Explorer 7 and Firefox 2 or Mozilla, since those are the most common, and have different bugs. Don't forget to do things like resize windows and change text size during your testing.%0a%0a!! Print Skins%0aBy default your new skin will use the standard /pub/skins/print/ skin. %0a%0aTo over-ride this add the following to local/config.php:%0a%0a->[@$ActionSkin['print'] = 'yourprintskin';@]%0a%0aThis says to use 'yourprintskin' for ?action=print instead of the default.%0a%0a!!!Tools that you'll need%0a%0aThere are good examples of all these programs available for free. %0a%0a'''HTML and CSS editor(s).''' There are two types of editors: graphical (WYSIWYG, or "what you see is what you get"), and hand-coding or programmer's editors. Graphical editors are less intimidating to novices, but you won't learn as much, or know your code as intimately as you will by using a hand-coding editor. Whichever you choose, get one that has syntax highlighting for the code, because it will help you spot mistakes. Also, live preview features are not that helpful when writing a PmWiki skin, because PmWiki does stuff that the live preview won't, such as substitute values for variables and insert sidebar content.%0a%0a'''Test wiki'''. You don't want to be wreaking havoc on your skin while visitors can see your site. It's a better idea to set up a test wiki, either on your real webserver or on your own machine. Linux or [=MacOS=] computer owners may have webservers and PHP already running on their machines, but Windows users often don't. If that describes you, then you might want to take a look at the Cookbook:Standalone recipe, which runs PmWiki without needing a complex webserver. Or, you can find many local server packages which install a webserver, PHP, and other stuff (e.g. `MySQL), all configured to work together. Try to get a package that has the same software and versions as used on your live setup, since then there will be less to go wrong when the site goes live.%0a%0a'''FTP client''' to transfer files to your webserver. You probably had one of these already.%0a%0a'''Color picker'''. Your editor might include one, or you could pick up a standalone application. Extremely helpful for creating and saving color palettes.%0a%0a!!See also%0a%0a* [[PmWiki/Skin Templates]]%0a* [[Cookbook:Skins]]%0a* [[Cookbook:Skin Guidelines]]%0a* [[Cookbook:Standalone]]%0a* [[PmWiki/Installation]]%0a%0a>>faq%3c%3c [[#faq]]%0a%0aQ: How do I change the Wiki's default name in the upper left corner of the Main Page?%0a%0aA: Put the following config.php%0a%0a->[@$WikiTitle = 'My Wiki Site';@]%0a%0aThe ''docs/sample-config.php'' file has an example of changing the title.%0a%0a%0aQ: How can I embed PmWiki pages inside a web page?%0a%0aA: Source them through a PHP page, or place them in a frame.%0a%0a%0aQ: How do I change the font or background color of the hints block on the Edit Page?%0a%0aA: Add a CSS style to pub/css/local.css: [@.quickref {background:...; color:... }@]. The hints are provided by the [[Site.EditQuickReference]] page, which is in the PmWiki or Site wikigroup. Edit that page, and change the "bgcolor" or specify the font "color" to get the contrast you need.%0a%0a
+time=1247444629
diff --git a/wikilib.d/PmWiki.SpecialCharacters b/wikilib.d/PmWiki.SpecialCharacters
new file mode 100644
index 0000000..e37e583
--- /dev/null
+++ b/wikilib.d/PmWiki.SpecialCharacters
@@ -0,0 +1,10 @@
+version=pmwiki-2.1.19 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.0.6) Gecko/20060728 Firefox/1.5.0.6
+author=TeganDowling
+csum=cross-reference
+host=69.131.28.243
+name=PmWiki.SpecialCharacters
+rev=12
+targets=
+text=When creating pages it's common to use commercial trademarks, copyright, umlaut, and other non-keyboard symbols. therefore it's important that you have the means to input these special characters. %0a%0a!!!ISO Standard codes%0aPmWiki supports the HTML special character listings by the w3c. [[http://www.w3.org/MarkUp/html-spec/html-spec_13.html | W3C Page of Special Character codes ISO standard.]]%0a%0aHere are some samples: %0a(:markup:)[=%0a© | ¼ | ½ | ® | µ | ¨ =]%0a%0a(:markup:)[=%0aÆ | 32° | Unïted Stätes | ¶ | ¥Yen | PmWiki™=]%0a%0aFor a nice table of the same codes that show the codes with the output go to the [[http://www.nobledesktop.com/specialcharacters.html | Noble Desktop]] special character page. %0a%0a!!!Other ways to do it: %0a%0a!!!!Character Map%0aFind the "Character Map" utility in your computer's System Tools folder. Click the symbol you're interested in, and note the keystroke information at the bottom of the box. You execute these by ''holding "Alt"'' while keying the numbers ''on the numerical keypad'' of your keyboard (not the numbers across the top of the board).%0a%0a[=©=] = Alt+0169 = © | [=®=] = Alt+0174 = ® | [=°=] = Alt+0176 = ° (degrees).%0a%0a!!!!Paste%0a*Use Word or another desktop application to create your text with the special characters that you want. Copy and paste the text to the wiki page you're editing or creating.%0a*Find an instance of a special character in an online document; copy and paste the character to your wiki page: ©%0a%0aThere's a list of special characters at [[PmWiki:SpecialCharactersList]].%0aThere's another illustration at [[PmWiki:Characters]]
+time=1157030301
diff --git a/wikilib.d/PmWiki.TableDirectives b/wikilib.d/PmWiki.TableDirectives
new file mode 100644
index 0000000..42685b1
--- /dev/null
+++ b/wikilib.d/PmWiki.TableDirectives
@@ -0,0 +1,12 @@
+version=pmwiki-2.2.10 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.7) Gecko/20100106 Ubuntu/9.10 (karmic) Firefox/3.5.7
+author=Petko
+charset=ISO-8859-1
+csum=
+host=81.65.12.233
+name=PmWiki.TableDirectives
+rev=71
+targets=PmWiki.Tables,PmWiki.TableDirectives,PmWiki.Audiences,PmWiki.PmWikiPhilosophy,PmWiki.LocalCustomizations,PmWiki.IncludeOtherPages,Cookbook.AdvancedTableDirectives,Cookbook.BackgroundImages
+text=(:Summary:Directives for table processing:)(:Audience: authors (intermediate) :)(:title Table directives:)%0aThere are six directives for table processing. All must be at the beginning of a line to have any effect.%0a%0a!!!@@[=(:table [attr...]:)=]@@%0a%0aGenerates a new HTML %3ctable> tag with the attributes provided in ''attr...''.%0aCloses the previous table, if any.%0aValid attributes and values are:%0a* border ''(a positive integer)''%0a* bordercolor ''(a color name or hex number; doesn't display in all browsers)''%0a* cellspacing ''(a positive integer indicating the space between cells)''%0a* cellpadding ''(a positive integer indicating the interior border of a cell)''%0a* width ''(a positive integer or percent)''%0a* bgcolor ''(a color name or hex number)''%0a* align ''(left, center or right)''%0a* summary ''(does not display; used primarily to help visually disabled people navigate)''%0a%0a!!!@@[=(:cellnr [attr...]:), (:cell [attr...]:), (:headnr [attr...]:), (:head [attr...]:) =]@@%0a%0a* The @@ [=(:head:)=] @@ directive opens a new "header cell" of the table (creates @@ %3cth> @@ tag in HTML).%0a* The @@ [=(:cell:)=] @@ directive opens a new "regular cell" of the table (creates @@ %3ctd> @@ tag in HTML).%0a* The directives @@ [=(:headnr:)=] @@ and @@ [=(:cellnr:)=] @@ open a new cell on a new row in the table.%0a%0aThese directives close any previous cell and/or row. Note, the @@ [=(:head:)=] @@ and @@ [=(:headnr:)=] @@ directives exist from PmWiki version 2.2.11 or newer.%0a%0aValid attributes and values are:%0a* align ''(left, center or right)''%0a* valign ''(top, middle or bottom)'' * ''default is "top", see note below''%0a* colspan ''(a positive integer)''%0a* rowspan ''(a positive integer)''%0a* bgcolor ''(a color name or hex number)''%0a* width ''(a positive integer or percent)''%0a* class ''(a CSS class of the cell)''%0a* style ''(custom CSS styles of the cell)''%0a%0a!!! @@ [=(:tableend:)=] @@%0a%0aCloses the previous table cell and closes off any table. Generates %3c/th>, %3c/td>, %3c/tr>, and %3c/table> tags as needed.%0a%0a!!!* valign attribute%0a%0aIf not already set, PMWiki will automatically include the attribute valign='top' with all [@(:cell[nr]:)@] and [@(:head[nr]:)@]. Pm said "Table Directives were created for layout purposes and in that case it makes the most sense for each cell (column) to have its content at the top of the row. The attribute is placed in each cell and not in the row because certain browsers didn't recognize valign='top' in the row tag.%0a%0a!! Notes%0a%0aFor the table, cell, and cellnr tags the author can specify any attributes that would be valid in the HTML %3ctable> or %3ctd> tags. Thus you can specify rowspan, colspan, etc. arguments to build arbitrary tables. However, it's not possible to nest a [@(:table:)@] inside of a [@(:cell:)@] or [@(:cellnr:)@] -- the next paragraph explains why.%0a%0aMany are likely to ask why we didn't just use the standard HTML table markup (%3ctable>, %3ctr>, %3ctd>, %3cth>) instead of creating a new markup, and allowing nested tables as a result. There are two answers: first, the HTML table markup is very ugly for naive authors (see [[PmWiki.Audiences]] and [[PmWikiPhilosophy]] #2), and second, it'd be very easy for authors to create tables that are incorrect HTML and that display incorrectly (or not at all) on some browsers. Even seasoned web professionals sometimes get the table markup wrong, so it's a bit unrealistic to expect the average author to always get it right, or to be able to read arbitrary HTML table markup that someone else has created.%0a%0a-> %25color=green%25 ''Common comment:'' Surely, the average or naive author would not be writing HTML directly, but using a tool, such as [=FrontPage=], or even [=MSWord=], to generate the HTML. This would be a lot simpler than learning even the simplest PmWiki markups.%0a>>%3c%3c%0a%0a-> %25color=green%25 ''Pm's Response:'' And once the HTML has been generated and posted, how is someone else going to edit or modify the table if they don't have the original [=FrontPage or MSWord=] file used to create it? Remember that we're talking about ''collaborative'' authoring. The HTML that those packages generate is among the hardest to read and edit of all!%0a%0aIt's difficult to write the code needed to make PmWiki understand and fix arbitrary table markup, so PmWiki uses the simplified version above. Still, this version is able to handle most table requirements (with the possible exception of nested tables).%0a%0aAnd, this is not to say that nested HTML tables are impossible in PmWiki --they just can't be easily created by wiki authors using the default wiki markup. A site administrator can of course create header/footer HTML code and other [[local customizations]] that make use of nested tables.%0a%0a!!!Example 1. A table using table directive markup.%0a%0a"[@ @]" is a non-breaking space in html. Place it in a cell if a cell is to be empty or the border of the cell will not be drawn properly.%0a%0a(:markup:)%0a(:table border=1 cellpadding=5 cellspacing=0:)%0a(:head:) a1%0a(:cell:) b1%0a(:cell:) c1%0a(:cell:) d1%0a(:headnr:) a2%0a(:cell:) b2%0a(:cell:) c2%0a(:cell:) %0a(:tableend:)%0a(:markupend:)%0a%0a%0aIn HTML, this is the same as%0a%0a-> [@%0a%3ctable border='1' cellpadding='5' cellspacing='0'>%0a %3ctr>%0a %3cth>a1%3c/th>%0a %3ctd>b1%3c/td>%0a %3ctd>c1%3c/td>%0a %3ctd>d1%3c/td>%0a %3c/tr>%0a %3ctr>%0a %3cth>a2%3c/th>%0a %3ctd>b2%3c/td>%0a %3ctd>c2%3c/td>%0a %3ctd> %3c/td>%0a %3c/tr>%0a%3c/table>%0a@]%0a%0a%0a-----%0a!!!Floating Table with bulleted navigation list%0a%0aWhat if you wanted to create a nice little table like a table of contents in a page like this? In this example, the table is floating right and contains some links in a bulleted list. This is a nice demonstration of how it's possible to build a little table of contents in the page, which might navigate to other pages just within the same wiki group. Note that having a bulleted list ''won't work in a ordinary table'' - it only works inside an table created with table directives such as the example code used here.%0a%0a(:markup:)%0a(:table border=1 width=30%25 align=right bgcolor=#cccc99 cellspacing=0 :)%0a(:cellnr:)%0a'''Navigation Links'''%0a(:cellnr:)%0a*[[Tables]]%0a*[[Table directives]]%0a(:tableend:)%0a(:markupend:)%0a%0a(:markup:)%0a(:table border=1 width=30%25 align=right bgcolor=#cccc99 cellspacing=0 :)%0a(:cellnr colspan=2 align=center:)%0a'''Navigation Links'''%0a(:cellnr align=center:)%0a[[Tables]]%0a(:cell align=center:)%0a[[Table directives]]%0a(:tableend:)%0a(:markupend:)%0a%0aLooking at the markup here, notice that we have used a #cccc99 hex color for the table background. Also, the [@(:cellnr:)@] markup creates a new row, a new cell and closes the row at the end.%0a%0aYou could take this concept a little further: since you might want each page in the group to contain the same table of contents, you can make ONE table like the above and put it in its own page. Then use an [[include (other pages)]] on any of your pages and bring in the table. The float (align) property will be honored in each page where it's included.%0a%0a>>faq%3c%3c [[#faq]]%0a%0aQ: Can I define table headers using the table directive markup?%0aA: Yes, with PmWiki version 2.2.11 or newer. See also Cookbook:AdvancedTableDirectives.%0a%0aQ: Is it possible to do nested tables?%0aA: Yes, if you nest [[Tables|simple tables]] inside advanced tables. See also Cookbook:AdvancedTableDirectives.%0a%0aQ: Is it possible to add background images to tables and table cells?%0aA: Yes, see Cookbook:BackgroundImages.%0a
+time=1265589379
+title=Table directives
diff --git a/wikilib.d/PmWiki.Tables b/wikilib.d/PmWiki.Tables
new file mode 100644
index 0000000..0f69b99
--- /dev/null
+++ b/wikilib.d/PmWiki.Tables
@@ -0,0 +1,12 @@
+version=pmwiki-2.2.6 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.1.4) Gecko/20091016 Firefox/3.5.4 FirePHP/0.3
+author=Frank
+charset=ISO-8859-1
+csum=
+ctime=1141945978
+host=77.249.44.121
+name=PmWiki.Tables
+rev=59
+targets=PmWiki.TableDirectives
+text=(:Audience: authors (basic) :)%0a(:Summary:Simple tables with double pipe markup, one row per line:)%0a!! Table basics%0a%0aPmWiki has two types of table markup; the markup described in this page is useful for creating ''simple'' tables with lots of small cells, while [[table directive(s)]] markups help with larger scale tables. For more possibilities with table formatting see [[Cookbook:Rowspan in simple tables]] and [[Cookbook:Formatting tables]].%0a%0aTables are created via use of double pipe characters: @@||@@. Lines beginning with this markup denote rows in a table or a formatting line. Within table row lines the double-pipe is used to delimit cells. In the examples below a border is added for illustration (the default is no border).%0a%0aThe first line in the markup contains formatting commands for the table. It only has double pipe characters at the start of the line.%0a%0a(:markup caption='Basic table' class=horiz:)%0a|| border=1%0a|| cell 1 || cell 2 || cell 3 ||%0a|| cell 1 || cell 2 ||%0a(:markupend:)%0a%0aHeader cells can be created by placing ! as the first character of a cell. Note that these are ''table headers'', not ''headings'', so it doesn't extend to !!, !!!, etc.%0a%0a(:markup caption='Table headers' class=horiz:)%0a|| border=1%0a||! cell 1 ||! cell 2 ||! cell 3 ||%0a|| cell 1 || cell 2 || cell 3 ||%0a(:markupend:)%0a%0aA table can have a caption, indicated by [@||!caption!||@]. Any caption must appear prior to other rows of the table.%0a%0a(:markup caption='Table caption' class=horiz:)%0a|| border=1%0a||! A special table !||%0a||! cell 1 ||! cell 2 ||! cell 3 ||%0a|| cell 1 || cell 2 || cell 3 ||%0a(:markupend:)%0a%0a%0a!! Formatting cell contents%0a%0aCell contents may be aligned left, centered, or aligned right. %0a* To left-align contents, place the cell contents next to the leading @@||@@.%0a* To center contents, add a space before and after the cell contents.%0a* To right-align contents, place a space before the cell contents and leave the cell contents next to the trailing @@||@@.%0a%0a(:markup caption='Cell alignments':)%0a|| border=1 width=100%25%0a||!cell 1 ||! cell 2 ||! cell 3||%0a||left-aligned || centered || right-aligned||%0a(:markupend:)%0a%0a(:markup caption='Default cell alignments':)%0a|| border=1 width=100%25%0a||!cell default||!cell left ||%0a||default-aligned||left-aligned ||%0a(:markupend:)%0a%0aNote that header and detail cells have different default alignments.%0a%0aTo get a cell to span multiple columns, follow the cell with empty cells.%0a(At present there is no markup for spanning rows.)%0a%0a(:markup caption='Column spanning':)%0a|| border=1 width=100%25%0a|| |||| right column ||%0a|| || middle column ||||%0a|| left column ||||||%0a|| left column || middle column || right column ||%0a(:markupend:)%0a%0a!! Table attributes%0a%0aAny line that begins with [@||@] but doesn't have a closing [@||@] sets the ''table attributes'' for any tables that follow. These attributes can control the size and position of the table, borders, background color, and cell spacing. (In fact these are just standard HTML attributes that are placed in the %3ctable> tag.)%0a%0aUse the [@width=@] attribute to set a table's width, using either a percentage value, an absolute size, or '''*'''.%0a%0a(:markup caption='Table width':)%0a|| border=1 width=100%25 %0a|| cell 1 || cell 2 || cell 3 ||%0a|| c1 || cellcellcellcell2 || cell 3 ||%0a(:markupend:)%0a%0aThe [@border=@] attribute sets the size of a table's borders.%0a%0a(:markup caption='Bordered table' class=horiz:)%0a|| border=10 width=70%25%0a||!cell 1 ||! cell 2 ||! cell 3||%0a||left-aligned || centered || right-aligned||%0a(:markupend:)%0a%0a(:markup caption='Borderless table' class=horiz:)%0a|| border=0 width=70%25%0a||!cell 1 ||! cell 2 ||! cell 3||%0a||left-aligned || centered || right-aligned||%0a(:markupend:)%0a%0aUse [@align=center@], [@align=left@], and [@align=right@] to center, left, or right align a table. Note that [@align=left@] and [@align=right@] create a ''floating table'', such that text wraps around the table.%0a%0a(:markup caption='Table alignment: center':)%0a|| border=1 align=center width=50%25%0a||!cell 1 ||! cell 2 ||! cell 3||%0a||left-aligned || centered || right-aligned||%0aNotice how text does not wrap with a table using "align=center".%0a(:markupend:)%0a%0a(:markup caption='Table alignment: left':)%0a|| border=1 align=left width=50%25%0a||!cell 1 ||! cell 2 ||! cell 3||%0a||left-aligned || centered || right-aligned||%0aNotice how text wraps to the right of a table using "align=left".%0a(:markupend:)%0a%0a(:markup caption='Table alignment: right':)%0a|| border=1 align=right width=50%25%0a||!cell 1 ||! cell 2 ||! cell 3||%0a||left-aligned || centered || right-aligned||%0aNotice how text wraps to the left of a table using "align=right".%0a(:markupend:)%0a%0aNote: to get a table to align left (but not "float left") requires CSS, as in%0a->[@||style="margin-left:0px;"@]%0a%0aThe [@bgcolor=@] attribute sets the background color for a table. At present there is no way to specify the color of individual rows or cells in this type of table (but see Cookbook:FormattingTables).%0a%0a(:markup class=horiz:)%0a|| border=1 align=center bgcolor=yellow width=70%25%0a||!cell 1 ||! cell 2 ||! cell 3||%0a||left-align || center || right-align||%0a(:markupend:)%0a%0a>>faq%3c%3c [[#faq]]%0aQ: How do I create a basic table? %0aA: Tables are created via use of the double pipe character: @@||@@. Lines beginning with this markup denote rows in a table; within such lines the double-pipe is used to delimit cells. In the examples below a border is added for illustration (the default is no border).%0a%0a(:markup caption='Basic table' class=horiz:)%0a|| border=1 rules=rows frame=hsides%0a|| cell 1 || cell 2 || cell 3 ||%0a|| cell 1 || cell 2 || cell 3 ||%0a(:markupend:)%0a%0aQ: How do I create cell headers?%0aA: Header cells can be created by placing ! as the first character of a cell. Note that these are ''table headers'', not ''headings'', so it doesn't extend to !!, !!!, etc.%0a%0a(:markup caption='Table headers' class=horiz:)%0a|| border=1 rules=cols frame=vsides%0a||! cell 1 ||! cell 2 ||! cell 3 ||%0a|| cell 1 || cell 2 || cell 3 ||%0a(:markupend:)%0a%0aQ: How do I obtain a table with thin lines and more distance to the content?%0aA: "Thin lines" is tricky and browser dependent, but the following works for Firefox and IE (Nov. 2009):%0a%0a(:markup caption='Thin lines and cell padding' class=horiz:)%0a||border="1" bordercolordark="black" bordercolorlight="black" style="border-collapse:collapse" cellpadding="5" width=66%25%0a||!Header || !Header|| '''Header'''||%0a||cells || with || padding||%0a|| || || ||%0a(:markupend:)%0a%0aQ: How do I create an advanced table? %0aA: See [[PmWiki.TableDirectives | table directives]]%0a%0aQ: My tables are by default centered. When I try to use '||align=left' they don't align left as expected. %0aA: Use ||style="margin-left:0px;" instead. %0a%0aQ: How can I specify the width of columns?%0aA: You can define the widths via custom styles, see Cookbook:FormattingTables and $TableCellAttrFmt. Add in config.php :%0a[@$TableCellAttrFmt = 'class=col\$TableCellCount';@]%0a-> And add in pub/css/local.css : %0a[@%0atable.column td.col1 { width: 120px; }%0atable.column td.col3 { width: 40px; }%0a@]%0a%0aQ: How can I display a double pipe "||" in cell text using basic table markup?%0aA: Escape it with [@[=||=]@] to display || unchanged.%0a
+time=1257441937
diff --git a/wikilib.d/PmWiki.TextFormattingRules b/wikilib.d/PmWiki.TextFormattingRules
new file mode 100644
index 0000000..57f7b44
--- /dev/null
+++ b/wikilib.d/PmWiki.TextFormattingRules
@@ -0,0 +1,12 @@
+version=pmwiki-2.2.7 ordered=1 urlencoded=1
+agent=Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; GTB6.3; .NET CLR 1.0.3705; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)
+author=SchreyP
+charset=ISO-8859-1
+csum=infobox section Definition Lists: pages now part of distribution
+host=80.200.31.89
+name=PmWiki.TextFormattingRules
+post= Save
+rev=494
+targets=PmWiki.SpecialCharacters,Main.WikiSandbox,PmWiki.PageTextVariables,PmWiki.PageLists,PmWiki.WikiStyles,PmWiki.WikiWord,PmWiki.Links,PmWiki.Tables,PmWiki.TableDirectives,PmWiki.MarkupMasterIndex
+text=(:Summary: A list of some of the markup sequences available:) %0a>>rframe font-size:smaller%3c%3c%0a!! Table of contents%0a* [[#Paragraphs|Paragraphs]]%0a* [[#IndentedParagraphs|Indented Paragraphs ''(Quotes)'']]%0a* [[#BulletedLists|Bulleted and Numbered Lists]]%0a* [[#DefinitionLists|Definition Lists]]%0a* [[#WhitespaceRules|Whitespace Rules]] %0a* [[#HorizontalLine|Horizontal Line]]%0a* [[#Emphasis|Emphasis]]%0a* [[#References|References]]%0a* [[#Headings|Headings]]%0a* [[#EscapeSequence|Escape sequence]]%0a* [[Special Characters | Special characters]]%0a* [[#Tables | Tables]]%0a>>%3c%3c%0aThis page provides a more complete list of some of the markup sequences available in PmWiki. %0aNote that it's easy to create and edit pages without using any of the markups below, but ''if'' you ever need them, they're here. %0a%0aTo experiment with the rules, please edit the [[Main/Wiki Sandbox]].%0a----%0a%0a!! [[#Paragraphs]] Paragraphs%0a%0aTo create paragraphs, simply enter text. Use a blank line to start a new paragraph.%0a%0aWords on two lines in a row will '''wrap and fill''' as needed (the normal XHTML behavior). To turn off the automatic filling, use the [@(:linebreaks:)@] directive above the paragraph.%0a%0a* Use [@\@] (single backslash) at the end of a line to join the current line to the next one.%0a* Use [@\\@] (two backslashes) at the end of a line to force a line break.%0a* Use [@\\\@] (three backslashes) at the end of a line to force 2 line breaks.%0a* Use [@[[%3c%3c]]@] to force a line break that will clear floating elements.%0a%0a%0a!! [[#IndentedParagraphs]] Indented Paragraphs ''(Quotes)''%0a%0aArrows ([@->@]) at the beginning of a paragraph can be used to produce an indented paragraph. More hyphens at the beginning ([@--->@]) produce larger indents.%0a%0a(:markup:)%0a->Four score and seven years ago our fathers placed upon this continent a new nation, conceived in liberty and dedicated to the proposition that all men are created equal.%0a(:markupend:)%0a%0aInverted Arrows ([@-%3c@]) at the beginning of a paragraph can be used to produce a paragraph with a hanging indent. Adding hyphens at the beginning ([@---%3c@]) causes all the text to indent.%0a%0a(:markup:)%0a-%3cFour score and seven years ago our fathers placed upon this continent a new nation, conceived in liberty and dedicated to the proposition that all men are created equal. %0a(:markupend:)%0a%0a(:markup:)%0a--%3cFour score and seven years ago our fathers placed upon this continent a new nation, conceived in liberty and dedicated to the proposition that all men are created equal. And that food would be good too.%0a(:markupend:)%0a%0aBlocks of text to which [@(:linebreaks:)@] has been applied can be indented by preceding the first line of the block with indention arrows ([@->@]) and aligning subsequent lines under the first. An unindented line stops the block indentation. See [[Cookbook:Markup Tricks]] for an example.%0a%0a%0a!! [[#BulletedLists]] Bulleted and Numbered Lists%0a%0aBullet lists are made by placing asterisks at the beginning of the line. Numbered lists are made by placing number-signs (#) at the beginning of the line. More asterisks/number-signs increases the level of bullet:%0a%0a(:markup:) %0a* First-level list item%0a** Second-level list item%0a### Order this%0a#### And this (optional)%0a### Then this%0a** Another second-level item%0a* A first-level item: cooking%0a## Prepare the experiment%0a### Unwrap the pop-tart%0a### Insert the pop-tart into the toaster%0a## Begin cooking the pop tart%0a## Stand back%0a(:markupend:)%0a%0a(:markup:)%0a# A list is terminated%0aby the first line that is not a list.%0a# Also terminate a list using the escape sequence [@[==]@]%0a[==]%0a# Continue a list item by lining%0a up the text with leading whitespace.%0a# Use a forced linebreak \\%0a to force a newline in your list item.%0a(:markupend:)%0a%0a(:markup:)%0a## Text between list items can cause numbering to restart%0a## %25item value=3%25 this can be dealt with%0a(:markupend:)%0a%0aAlso see: [[(PmWiki:)ListStyles]], [[Cookbook:WikiStylesPlus]].%0a%0a%0a!! [[#DefinitionLists]] Definition Lists%0a>>rframe%3c%3c%0a'''Powerful new%25red%25*%25%25 feature'''\\%0aWhen you define terms using this markup\\%0aPmWiki will recognize them as [[PageTextVariables]]\\%0athat you can use on any page or [[PageList(s)]].\\%0a[-%25red%25* Added%25%25 in PmWiki version %25red%252.2.0%25%25-]%0a>>%3c%3c%0aDefinition lists are made by placing colons at the left margin (and between each term and definition):%0a%0a(:markup:)%0a:term:definition of term%0a::second-level item: definition of 2nd-level item%0a(:markupend:)%0a%0a[[#WhitespaceRules]]%0a!! Whitespace Rules%0a%0aWhitespace indentation in lists. Any line that begins with whitespace ''and aligns'' with a previous list item (whether bulleted, numbers or definitional) is considered to be "within" that list item. Text folds and wraps as normal, and the [@(:linebreaks:)@] directive is honored. %0a%0a(:markup:) %0a# First-level item\\%0a Whitespace used to continue item on a new line%0a# Another first-level item%0a # Whitespace combined with a single # to create a new item one level deeper%0a(:markupend:)%0a%0aOtherwise, lines that begin with whitespace are treated as ''preformatted text'', using a monospace font and not generating linebreaks except where explicitly indicated in the markup. Note to administrators: Starting with version 2.2.0-beta41, this feature can be modified using $EnableWSPre. (Another way to create preformatted text blocks is by using the [=[@...@]=] markup.)%0a%0a!! [[#HorizontalLine]] Horizontal Line%0a%0aFour or more dashes ([=----=]) at the beginning of a line produce a horizontal line.%0a%0a[[#Emphasis]]%0a!! Emphasis and character formatting%0a%0a* Enclose text in doubled single-quotes ([=''text''=]), i.e., ''two apostrophes'', for emphasis (usually ''italics'')%0a* Enclose text in tripled single-quotes ([='''text'''=]), i.e. ''three apostrophes'', for strong (usually '''bold''')%0a* Enclose text in five single-quotes ([='''''text'''''=]), or triples within doubles (''five apostrophes''), for strong emphasis (usually '''''bold italics''''')%0a* Enclose text in doubled at-signs ([=@@text@@=]) for @@monospace@@ text%0a* Use [=[+large+]=] for [+large+] text, [=[++larger++]=] for [++larger++], [=[-small-]=] for [-small-] text, and [=[--smaller--]=] for [--smaller--].%0a* Emphasis can be used multiple times within a line, but cannot span across markup line boundaries (i.e., you can't put a paragraph break in the middle of bold text).%0a* [='~italic~'=] and [='*bold*'=] are available if enabled in config.php%0a%0aOther styling %0a(:markup:)%0a'+big+', '-small-', '^super^', '_sub_', %0a%0a{+insert or underscore+}, %0a%0a{-delete or strikethrough or strikeout-}%0a(:markupend:)%0a* [@`WikiWord@] `WikiWord neutralisation%0a%0aSee also [[Wiki Styles]] for advanced text formatting options.%0a%0a[[#References]]%0a!! References%0a%0a* Use words and phrases in double brackets (e.g., [=[[text formatting rules]]=]) to create links to other pages on this wiki.%0a* On some PmWiki installations, capitalized words joined together (e.g., [[WikiWord]]s) can also be used to make references to other pages without needing the double-brackets.%0a* Precede [=URLs=] with "@@http:@@", "@@ftp:@@", "@@gopher:@@", "@@mailto:@@", or "@@news:@@" to create links automatically, as in http://www.pmichaud.com/toast.%0a* [=URLs=] ending with @@.gif@@, @@.jpg@@, or @@.png@@ are displayed as images in the page%0a* Links with arbitrary text can be created as either [=[[=]''target'' | ''text'']] or [=[[=]''text'' -> ''target''[=]]=]. ''Text'' can be an image URL, in which case the image becomes the link to the remote ''url'' or ''[[WikiWord]]''.%0a* [[#Anchors]] Anchor targets within pages (#-links) can be created using @@[=[[#target]]=]@@.%0aSee [[Links]] for details.%0a%0a[[#Headings]]%0a!!Headings%0a%0aHeadings are made by placing an exclamation mark ('''!''') at the left margin. More exclamation marks increase the level of heading. For example,%0a%0a(:markup:)%0a!! Level 2 Heading%0a!!! Level 3 Heading%0a!!!! Level 4 Heading%0a!!!!! Level 5 Heading%0a(:markupend:)%0a%0aNote that level 1 heading is already used as page title (at least in the PmWiki skin), so you should start with level 2 headings to create well formed, search engine optimized web pages.%0a%0aSee [[Cookbook:Numbered Headers]] for numbered headings.%0a%0a[[#EscapeSequence]]%0a!!Escape sequence%0a%0aAnything placed between [=[= and =]=] is not interpreted by PmWiki, but paragraphs are reformatted. This makes it possible to turn off special formatting interpretations and neutralise [=WikiWords=] that are not links (even easier is to use a tick ` in front, like [=`WikiWord=]).%0a%0a%0aFor preformatted text blocks, use the [=[@...@]=] markup. It does neither reformat paragraphs nor process wiki markup:%0a%0a(:markup:)%0a[@%0aCode goes here like [[PmWiki.PmWiki]]%0a'$CurrentTime $[by] $AuthorLink: [=$ChangeSummary=]'; #just some code%0a@]%0a(:markupend:)%0a%0aThe multiline @@[=[@...@]=]@@ is a block markup, and in order to change the styling of these preformatted text blocks, you need to apply a "block" WikiStyle.%0a%0a(:markup:)[=%25block blue%25[@ %0a The font color of %0a this text is blue%0a@]=]%0a%0aIt is also useful to use [@[= =]@] within other wiki structures, as this enables the inclusion of new lines in text values. The example below shows how to include a multi-line value in a hidden form field.%0a%0a->[@(:input hidden message "[=Line1%0aLine2=]":)@]%0a%0a!! Comments%0a[@ (:comment Some information:) @] can be very kind to subsequent authors, especially around complicated bits of markup.%0a%0a[[#SpecialCharacters]]%0a!! Special Characters%0a(:include SpecialCharacters:)%0a%0a[[#Tables]]%0a!! Tables%0a%0a[[Tables]] are defined by enclosing cells with '||'. %0aA cell with leading and trailing spaces is centered; a cell with leading spaces is right-aligned; all other cells are left-aligned. An empty cell will cause the previous cell to span multiple columns. (There is currently no mechanism for spanning multiple rows.) A line beginning with '||' specifies the table attributes for subsequent tables. A '!' as the first character in a cell provides emphasis that can be used to provide headings.%0a%0a(:markup:)%0a||border=1 width=50%25%0a||!Table||!Heading||!Example||%0a||!Left || Center || Right||%0a||A ||! a B || C||%0a|| || single || ||%0a|| || multi span ||||%0a(:markupend:)%0a%0aSee [[Table Directives]] for advanced tables.%0a%0a!!!Can't find it here?%0aSee [[Markup Master Index]].%0a
+time=1257804246
diff --git a/wikilib.d/PmWiki.Troubleshooting b/wikilib.d/PmWiki.Troubleshooting
new file mode 100644
index 0000000..b91ae41
--- /dev/null
+++ b/wikilib.d/PmWiki.Troubleshooting
@@ -0,0 +1,11 @@
+version=pmwiki-2.2.10 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7
+author=Peter Bowers
+charset=ISO-8859-1
+csum=add some anchors to communicate on mailing list
+host=92.60.18.108
+name=PmWiki.Troubleshooting
+rev=93
+targets=PmWiki.HowToGetAssistance,PmWiki.MailingLists,PmWiki.Questions,PmWiki.Upgrades,PmWiki.Installation,PmWiki.InitialSetupTasks,PmWiki.FilePermissions,PmWiki.WikiGroup,PmWiki.LocalCustomizations,PmWiki.UploadsAdmin,PmWiki.Tables
+text=(:Summary:Advice for troubleshooting an installation:)%0a(:Audience: administrators :)%0a%0aPmwiki is pretty robust and can automatically adapt to a very wide variety of environments. %0aHowever, sometimes things don't go as we expect, so we're cataloging common errors and their fixes here.%0a%0a!! Troubleshooting Frequently Asked Questions%0a%0a->%25note%25 Note: This page on pmwiki.org is probably not the best place to post questions. Consider [[PmWiki:HowToGetAssistance | seeking assistance]] from the pmwiki-users [[mailing list(s)]], or post your question on the [[PmWiki:Questions]] page.%0a%0a>>faq%3c%3c [[#faq]]%0aQ: Why am I seeing strange errors after [[(PmWiki.)upgrad(es)]]ing?%0aA: Make sure all of the files were updated, in particular ''pmwiki.php''.%0a%0aA: This question sometimes arises when an administrator hasn't%0afollowed the advice, which used to be less prominent, on the%0a[[(PmWiki.)installation(#notes)]] and%0a[[(PmWiki.)initial setup tasks(#dontmodify)]] pages and has renamed%0a''pmwiki.php'' instead of creating an ''index.php'' wrapper script.%0aIf you have renamed ''pmwiki.php'' to ''index.php'', then the upgrade procedure%0awon't have updated your ''index.php'' file. Delete the old version and%0acreate a wrapper script so it won't happen again.%0a%0aA: Sometimes an FTP or other copy program will fail to transfer all of the%0afiles properly. One way to check for this is by comparing file sizes.%0a%0aA: Be sure all of the files in the ''wikilib.d/'' directory%0awere also upgraded. Sometimes it's a good idea to simply delete the ''wikilib.d/''%0adirectory before upgrading. (Local copies of pages are stored in ''wiki.d/'' and not ''wikilib.d/''.)%0a%0aA: If you use a custom pattern for $GroupPattern make sure that it includes Site ($SiteGroup) and since PMWiki 2.2 also SiteAdmin ($SiteAdminGroup).%0aOtherwise migration may fail (e.g. missing SiteAdmin for PMWiki 2.2 and later) and/or login does not work.\\%0aAdditionally Main ($DefaultGroup) should be included too.%0a%0a[[#flock]]%0aQ: I'm suddenly getting messages like "@@Warning: fopen(wiki.d/.flock): failed to open stream: Permission denied...@@" and @@Cannot acquire lockfile@@"... what's wrong?%0a%0aA: Something (or someone) has changed the [[PmWiki/FilePermissions | permissions]] on the ''wiki.d/.flock'' file or the ''wiki.d/'' directory such that the webserver is no longer able to write the lockfile. The normal solution is to simply delete the ''.flock'' file from the ''wiki.d/'' directory -- PmWiki will then create a new one. Also be sure to check the permissions on the ''wiki.d/'' directory itself. (One can easily check and modify permissions of the ''wiki.d/'' directory in %25newwin%25[[http://filezilla-project.org/ | FileZilla]] (open-source FTP app) by right-clicking on the file > File attributes)%0a%0a[[#sidebar]]%0aQ: My links in the sidebar seem to be pointing to non-existent pages, even though I know I created the pages. Where are the pages?%0a%0aA: Links in the sidebar normally need to be qualified by a [[WikiGroup]] in order to work properly (use [=[[Group.Page]] instead of [[Page]]=]).\\%0aAlso: Make sure you type Side'''B'''ar with a capital B.%0a%0a[[#headers]]%0aQ: Why am I seeing "@@Warning: Cannot modify header information - headers already sent ...@@" messages at the top of my page.%0a%0aA: If this is the first or only error message you're seeing, it's usually an indication that there are blank lines or spaces before the [@%3c?php@] or after the [@?>@] in a [[local customization(s)]] file. Double-check the file and make sure there aren't any blank lines or spaces before the initial [@%3c?php@]. It's often easiest and safest to eliminate any closing [@?>@] altogether. On Windows, it may be necessary to use a hex editor to convert LFCR line endings to LF line endings in the local\config.php file.%0a%0aA: If the warning is appearing after some other warning or error message, then resolve the other error and this warning may go away.%0a%0a[[#session_write_close_error]]%0aQ: How do I make a PHP Warning about @@function.session-write-close@@ go away?%0a%0aA: If you are seeing an error similar to this%0a%0a->[@%0aWarning: session_write_close() [function.session-write-close]:%0aopen(/some/filesystem/path/to/a/directory/sess_[...]) failed: No such file%0aor directory (2) in /your/filesystem/path/to/pmwiki.php on line NNN%0a@]%0a%0aPmWiki sometimes does session-tracking using PHP's%0a[[http://php.net/session | session-handling functions ]].%0aFor session-tracking to work, some information needs to be written%0ain a directory on the server. That directory needs to exist and%0abe writable by the webserver software. For this example, the%0awebserver software is configured to write sessions in this%0adirectory%0a%0a->[@/some/filesystem/path/to/a/directory/@]%0a%0abut the directory doesn't exist. The solution is to do at least one%0aof these:%0a* Create the directory and make sure it's writable by the webserver software%0a* Provide a session_save_path value that points to a directory that is writable by the server, e.g.%0a%0a->[@session_save_path('/home/someuser/tmp/sessions');@]%0a%0a%0a[[#multiplepwprompts]]%0aQ: Why is PmWiki prompting me multiple times for a password I've already entered?%0a%0aA: Usually this is an indication that the browser isn't accepting cookies, or that PHP's session handling functions on the server aren't properly configured. If the browser is accepting cookies, then try setting $EnableDiag=1; in ''local/config.php'', run PmWiki using [@?action=phpinfo@], and verify that sessions are enabled and that the session.save_path has a reasonable value. Note that several versions of PHP under Windows require that a session_save_path be explicitly set (this can be done in the ''local/config.php'' file). You might also try setting session.auto_start to 1 in your php.ini.%0a%0aQ: I edited ''config.php'', but when I look at my wiki pages, all I see is "@@Parse error: parse error, unexpected T_VARIABLE in ''somefile'' on line ''number''.@@"%0a%0aA: You've made a mistake in writing the PHP that goes into the ''config.php'' file. The most common mistake that causes the T_VARIABLE error is forgetting the semi-colon (;) at the end of a line that you added. The line number and file named are where you should look for the mistake.%0a%0a%0aQ: Searches and pagelists stopped working after I upgraded -- no errors are reported, but links to other pages do not appear (or do not appear as they should) -- what gives?%0a%0aA: Be sure all of the files in the ''wikilib.d/'' directory%0awere also upgraded. In particular, it sounds as if the Site.PageListTemplates page is either missing (if no links are displayed) or is an old version (if the links do not appear as they should). Allso make sure that read-permissions (attr) are set for the pages Site.PageListTemplates and Site.Search.%0a%0a[[#mod_security]]%0aQ: Some of my posts are coming back with "403 Forbidden" errors, "Not Acceptable", or "Internal Server Error". This happens with some posts but not others.%0a%0aA: Your webserver probably has [[http://modsecurity.org | mod_security]] enabled. The mod_security "feature" scans all incoming posts for forbidden words or phrases that might indicate someone is trying to hack the system, and if any of them are present then Apache returns the 403 Forbidden error. Common phrases that tend to trigger mod_security include "curl ", "wget", "file(", and "system(", although there are many others.%0a%0aSince mod_security intercepts the requests and sends the "forbidden"%0amessage before PmWiki ever gets a chance to run, it's not a bug in PmWiki, and%0athere's little that PmWiki can do about it. Instead, one has to alter the%0awebserver configuration to disable mod_security or reconfigure it to allow%0awhatever word it is forbidding. Some sites may be able to disable mod_security%0aby placing [@SecFilterEngine off@] in a ''.htaccess'' file.%0a%0aQ: I get the following message when attempting to upload an image, what do I do?%0a[-@@'''Warning''': move_uploaded_file(): SAFE MODE Restriction in effect. The script whose uid is 1929 is not allowed to access /home/onscolre/public_html/pmwikiuploads/Photos owned by uid 33 in '''/home/onscolre/public_html/pmwiki/scripts/upload.php''' on line '''198'''@@-]%0a%0a@@'''PmWiki can't process your request'''@@%0a%0a[-@@?cannot move uploaded file to /home/onscolre/public_html/pmwikiuploads/Photos/FoundationPupilsIn1958.jpeg@@-]%0a%0a[-@@We are sorry for any inconvenience.@@-]%0a%0aA: Your server is configured with PHP [[http://php.net/manual/en/features.safe-mode.php|Safe Mode]] enabled. Configure your wiki to use a [[PmWiki/UploadsAdmin#sitewideprefix|site-wide uploads prefix]], then create the ''uploads/'' directory manually and set 777 permissions on it (rather than letting PmWiki create the directory).%0a%0a[[#TableRowIndexMax]] [[#divisionbyzero]]%0aQ: I'm starting to see "Division by zero error in pmwiki.php..." on my site. What's wrong?%0a%0aA: It's a bug in PmWiki that occurs only with the [[tables]] markup and only for versions of PHP >= 4.4.6 or >= 5.2.0. Often it seems to occur "out of nowhere" because the server administrator has upgraded PHP. Try [[upgrad(es)]]ing to a later version of PmWiki to remove the error, or try setting the following in ''local/config.php'':%0a%0a $TableRowIndexMax = 1;%0a%0aQ: I have to log in twice [-(two times) (2 times)-]. -or- My password is not being required even though it should. -or- I changed the password but the old password is still active. -or- My config.php password is not over-riding my farmconfig.php password.%0aA: It could happen if (farm)config.php, or an included recipe, directly calls the functions CondAuth(), or RetrieveAuthPage(), PageTextVar(), PageVar() and possibly others, before defining all passwords and before including AuthUser (if required). %0a%0aThe [[PmWiki/LocalCustomizations#configphp-order|order of config.php]] is very significant.
+time=1265029074
diff --git a/wikilib.d/PmWiki.UTF-8 b/wikilib.d/PmWiki.UTF-8
new file mode 100644
index 0000000..9829b5e
--- /dev/null
+++ b/wikilib.d/PmWiki.UTF-8
@@ -0,0 +1,11 @@
+version=pmwiki-2.2.4 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.19) Gecko/20081216 Ubuntu/8.04 (hardy) Firefox/2.0.0.19
+author=Petko
+charset=ISO-8859-1
+csum=fix link
+host=86.69.109.9
+name=PmWiki.UTF-8
+rev=13
+targets=
+text=!!!Enabling UTF-8 Unicode language encoding in your page header. %0a%0aUTF-8 allows for support of various languages, including Asian languages and their character depth. It is a widely supported and flexible character encoding, used for many European languages and can also represent Chinese, Japanese and Korean. %0a%0aIt's fairly simple to enable UTF-8 on your wiki pages. Currently PmWiki 2.0 versions have the UTF-8 file needed already loaded. %0a%0a!!!!Here are the steps to enable UTF-8 %0a%0a*Open your config.php file%0a*Add this line:[[%3c%3c]]'''include_once($FarmD.'/scripts/xlpage-utf-8.php');'''%0a*save and upload your config.php file back to the server.%0a%0aIf you validate your site you should see that UTF-8 is default encoding.%0a%0a'' '''NOTE: ''' The encoding type used when [@config.php@] is saved has an effect if you will be converting between character encodings on your wiki. Refer to [[Cookbook:ISO8859MakePageNamePatterns#page-encoding | page encoding]] for more details. If you are not using international characters then you do not need to be concerned about this.''%0a%0aSee also [[Cookbook:UTF-8]] for tips.%0a
+time=1251047160
diff --git a/wikilib.d/PmWiki.Upgrades b/wikilib.d/PmWiki.Upgrades
new file mode 100644
index 0000000..a43e964
--- /dev/null
+++ b/wikilib.d/PmWiki.Upgrades
@@ -0,0 +1,12 @@
+version=pmwiki-2.2.12 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.7) Gecko/20100106 Ubuntu/9.10 (karmic) Firefox/3.5.7
+author=Petko
+charset=ISO-8859-1
+csum=admins should always read the release notes
+host=81.65.12.233
+name=PmWiki.Upgrades
+post= Save
+rev=82
+targets=PmWiki.PmWiki,PmWiki.UpgradingFromPmWiki1,PmWiki.ReleaseNotes,PmWiki.BackupAndRestore,PmWiki.Download,PmWiki.SiteAnalyzer,PmWiki.LocalCustomizations,PmWiki.Troubleshooting,PmWiki.Version
+text=(:Summary:How to upgrade an existing PmWiki installation:)%0a[[PmWiki]] is designed to make it easy to upgrade the PmWiki software without affecting your existing data files or installation. For most upgrades, you simply copy the files in the new release over your existing installation.%0a%0a%25block bgcolor=#f7f7f7 color=black border='1px solid black' padding=5px%25 '''Note for PmWiki 1.0 sites:''' Upgrading from 1.0.x to 2.0 requires more than simply copying the 2.0 software over the 1.0 installation. See [[(PmWiki:)Upgrading From PmWiki 1]] for more details.%0a%0a!! To upgrade PmWiki: %0a%0a!!! 1. Read the release notes%0aPlease read carefully the [[(PmWiki:)ReleaseNotes]] before performing an upgrade, about the changes between your previous version and the new one. See if there are any significant changes or preparation tasks that must be handled before performing the upgrade.%0a%0a!!! 2. Backup%0aIt's ''always'' a good idea to have a [[(PmWiki:)backup( and Restore)]] copy of your existing PmWiki installation before starting. You can copy the entire directory containing your existing installation, or you can just make copies of the ''wiki.d/'' directory and any other local customization files you may have created (e.g., ''config.php'', ''localmap.txt'', etc.).%0a%0a!!! 3. Download and extract%0aDownload the version of PmWiki that you want from the [[(PmWiki:)download]] page.%0a%0aExtract the tar image using @@tar -xvzf ''tgzfile''@@, where ''tgzfile'' is the tar file you downloaded above. This will create a @@pmwiki-x.y.z@@ directory with the new version of the software.%0a%0a!!! 4. Copy%0aCopy the files in @@pmwiki-x.y.z@@ over the files of your existing PmWiki installation. For example, if your existing PmWiki installation is in a directory called ''pmwiki'', then one way to copy the new files over the existing ones is to enter the command:%0a%0a->@@cp -a pmwiki-x.y.z/. pmwiki@@%0a%0aNote that BSD systems will not have the -a option as a command-line argument for ''cp'', but that's okay, since it's just shorthand for ''cp -dpR'', so use that instead of ''-a''.%0a%0aSome environments have an alias established for ''cp'' that enable interactive prompts before overwriting a file. To work around this specify the absolute path to ''cp'', such as ''/bin/cp''.%0a%0aOn (some) [=FreeBSD=] servers and Mac OS X systems you need to use %0a%0a->@@cp -Rpv pmwiki-x.y.z/. pmwiki@@%0a%0a!!! 5. Update customisations and recipes%0aThat's it! Your base PmWiki installation is complete.%0a%0aNow use the [[PmWiki:Site Analyzer]] to determine which recipes could be updated to the most recent version.%0a%0aUnless you have made customizations to the ''pmwiki.php'' script or to the files in ''scripts/'', your PmWiki installation should continue to run correctly! (Changes to these files are {+not+} recommended).%0a%0a([[Local customizations]] should go in ''local/config.php'', ''pub/css'', and ''pub/skins/''yourskinname)%0a%0a'''Note''': Additional tips can be found on the [[PmWiki:Troubleshooting]] page.%0a%0a%0a>>faq%3c%3c [[#faq]]%0a%0aQ: How can I determine what version of PmWiki I'm running now?%0aA: See [[version]] - {Version$:Summary}.%0a%0aQ: How can I test a new version of PmWiki on my wiki without changing the prior version used by visitors?%0aA: The easy way to do this is to install the new version in a separate%0adirectory, and for the new version set (in local/config.php):%0a[@%0a%0a $WikiLibDirs = array(&$WikiDir,%0a new PageStore('/path/to/existing/wiki.d/{$FullName}'),%0a new PageStore('wikilib.d/{$FullName}'));%0a%0a@]%0aThis lets you test the new version using existing page content%0awithout impacting the existing site or risking modification of%0athe pages. (Of course, any recipes or local customizations have to%0abe installed in the new version as well.) %0a%0aThen, once you're comfortable that the new version seems to work%0aas well as the old, it's safe to upgrade the old version (and one%0aknows of any configuration or page changes that need to be made).%0a
+time=1266722980
diff --git a/wikilib.d/PmWiki.UpgradingFromPmWiki1 b/wikilib.d/PmWiki.UpgradingFromPmWiki1
new file mode 100644
index 0000000..d091ed2
--- /dev/null
+++ b/wikilib.d/PmWiki.UpgradingFromPmWiki1
@@ -0,0 +1,11 @@
+version=pmwiki-2.2.0-beta68 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.0.1) Gecko/2008070208 Firefox/3.0.1
+author=simon
+charset=ISO-8859-1
+csum=not on trail
+host=202.37.32.2
+name=PmWiki.UpgradingFromPmWiki1
+rev=34
+targets=PmWiki.WikiAdministrator,PmWiki.Upgrades,PmWiki.MailingLists,PmWiki.Installation,PmWiki.InitialSetupTasks,PmWiki.LocalCustomizations,PmWiki.CustomMarkup,PmWiki.WikiWord
+text=This page gives suggestions for upgrading an existing PmWiki 1.x installation to use PmWiki 2.0. In this page we assume that a site [[(wiki) administrator]] already has a site running using PmWiki version 1.x or earlier in a somewhat standard configuration, and wants to upgrade to the 2.0 software.%0a%0a->'''Important note:''' The normal PmWiki [[upgrade(s)]] procedure (i.e., copy the new software over the existing one) won't work for moving from 1.x to 2.0. Either start over with a new installation, or use some of the conversion scenarios listed below.%0a%0aAs always, questions and requests for assistance can be posed to [[Mailing lists | pmwiki-users]]. Errors or problems with the methods below can be corrected here, or posted to the [[PITS:PITS |PmWiki Issue Tracking System]].%0a%0a!!!Method 1: Test conversion%0a%0aBecause of the substantial redesign of PmWiki for 2.0, converting an existing site to 2.0 is likely to cause a [[wiki administrator]] a fair amount of apprehension. The approach given here allows the administrator to install, configure, and test PmWiki 2.0 on an existing set of pages without risking an existing 1.x installation.%0a%0a'''Step 0:''' It's always a very good idea to back up your existing PmWiki 1.x installation before doing anything else -- especially save the files in the ''local/'' and ''wiki.d/'' directories.%0a%0a'''Step 1:''' [[Install(ation)]] PmWiki 2.0 into a new directory away from the existing 1.x installation.%0a%0a'''Step 2:''' Briefly test the PmWiki 2.0 installation and make sure it is working properly -- i.e., edit and save a couple of pages. Then, remove the pages you created (you can just remove the files from PmWiki 2.0's ''wiki.d/'' directory, or remove the ''wiki.d/'' directory altogether).%0a%0a'''Step 3:''' Add the following lines to the ''local/config.php'' file in the 2.0 installation, replacing "[@/path/to/pmwiki1/wiki.d@]" below with the location of your PmWiki 1.x installation's ''wiki.d/'' directory on disk.%0a [=%0a include_once("$FarmD/scripts/compat1x.php");%0a UseV1WikiD("/path/to/pmwiki1/wiki.d");%0a =]%0aFor example, my 2.0 test conversion uses:%0a [=%0a include_once("$FarmD/scripts/compat1x.php");%0a UseV1WikiD("/home/pmichaud/pmwiki/wiki.d");%0a =]%0a'''Step 4:''' After making the above change, all of your existing pages should appear in the new 2.0 installation. Furthermore, if you "edit page" on any of the existing pages, you should see that any PmWiki 1.x markups (links, etc.) have been converted to the new markup syntax.%0a%0aAny pages edited/saved by the 2.0 wiki installation are kept separate from the pages in the previous installation. Thus you can safely experiment with editing and changing pages in the new site without affecting the existing 1.x site. %0a%0a'''Step 5:''' Once you see that your existing pages are available in the 2.0 installation, you can then begin going through the remaining [[initial setup tasks]] for the 2.0 site to enable any [[local customizations]] you may want for your site. Many local customizations (e.g. page layout templates) remain the same between 1.x and 2.0, others such as [[custom markup]] or [[Cookbook:Cookbook |cookbook recipes]] need to be converted to 2.0 as well. %0a%0a'''Note:''' [[WikiWord]] links are disabled by default since Pmwiki version 2.1 beta2. So you may either enable WikiWord links by setting [@$LinkWikiWords = 1;@] in config.php, or convert your existing WikiWord links manually to bracketed links. To find those WikiWord links easier you can highlight them by setting in config.php%0a%0a [=$HTMLStylesFmt['wikiword'] = "%0a span.wikiword { background:yellow; }%0a ";=] %0a%0a'''Step 6:''' Continue configuring the new installation just as if you were setting up a new PmWiki site. If you find PmWiki 1.x markups that aren't converted or convert incorrectly, be sure to enter a [[PITS:NewIssue |new PITS issue]] so that we can improve the conversion script.%0a%0a'''Step 7:''' If you're comfortable with the conversion and want to go ahead and convert all of the 1.x pages into 2.0 format, change the [@UseV1WikiD(...)@] call in ''local/config.php'' above to [@ConvertV1WikiD(...)@] instead, as in:%0a [=%0a include_once("$FarmD/scripts/compat1x.php");%0a ConvertV1WikiD("/path/to/pmwiki1/wiki.d");%0a =]%0aRunning the pmwiki.php script will then bring up some forms to allow you to bulk migrate some or all of your 1.x pages to 2.0 format. After you've converted pages, you can then just eliminate these two lines from the configuration and your PmWiki 2.0 site will be running standalone.%0a%0aIf you have local customisations that require you to specify $Compat1x['/match/'] = 'replace'; entries so they are correctly converted, make sure these are defined ''before'' the call to ConvertV1WikiD.%0a%0aNote that there's nothing that requires you to convert all of the pages or get rid of the 1.x ''wiki.d/'' directory -- PmWiki works just fine with it in place. And it's good to have a backup.%0a%0a'''Step 8:''' Once you're comfortable that the PmWiki 2.0 site will meet your needs, you can then discontinue the 1.x site and just start using the 2.0 site. Or, if you decide that 2.0 isn't for you, then the 1.x site is still intact and can continue to be used.%0a%0a'''Step 9:''' If your previous site had an ''uploads/'' directory, you'll probably want to copy it or move it into the new location.%0a
+time=1220229688
diff --git a/wikilib.d/PmWiki.UploadVariables b/wikilib.d/PmWiki.UploadVariables
new file mode 100644
index 0000000..74f95c4
--- /dev/null
+++ b/wikilib.d/PmWiki.UploadVariables
@@ -0,0 +1,11 @@
+version=pmwiki-2.2.8 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.19) Gecko/20081216 Ubuntu/8.04 (hardy) Firefox/2.0.0.19
+author=Petko
+charset=ISO-8859-1
+csum=no need for red color
+host=81.65.12.233
+name=PmWiki.UploadVariables
+rev=57
+targets=PmWiki.Uploads,PmWiki.UploadsAdmin,PmWiki.AvailableActions
+text=(:Summary:variables used for uploads/attachments:)%0a%0aSee also: [[Uploads]], [[Uploads admin]].%0a%0a:$EnableUpload:The upload.php script is automatically included from stdconfig.php if the $EnableUpload variable is true in config.php. Note that one may still need to set an upload password before users can upload (see [[UploadsAdmin]]).%0a%0a:$UploadDir:The directory where uploads are to be stored. Defaults to ''uploads/'' in the pmwiki directory, but can be set to any location on the server. This directory must be writable by the webserver process if uploading is to occur.%0a%0a:$UploadUrlFmt:The url of the directory given by $UploadDir. By default, $UploadUrlFmt is derived from $PubDirUrl and $UploadDir.%0a%0a$IMapLinkFmt['Attach:'] %0a->The format of the upload link displayed when an attachment is present. No default is set. %0a%0a:$LinkUploadCreateFmt: The format of the upload link displayed when an attachment not present. Defaults to%0a %3ca class='createlinktext' href='\$LinkUpload'>\$LinkText%3c/a>\\%0a %3ca class='createlink' href='\$LinkUpload'> Δ%3c/a>");%0a%0a:$UploadPrefixFmt:Sets the prefix for uploaded files to allow attachments to be organized other than by groups. Defaults to [@'/$Group'@] (uploads are organized per-group), but can be set to other values for sitewide or per-page attachments.%0a $UploadPrefixFmt = '/$Group/$Name'; # per-page attachments%0a $UploadPrefixFmt = ''; # sitewide attachments%0a%0a: : It is recommended to have the $UploadPrefixFmt variable defined in config.php, the same for all pages in the wiki, and not in group/page local configuration files. Otherwise you ''will'' be unable to link to attachments in other wikigroups.%25%25%0a%0a:$EnableDirectDownload:When set to 1 (the default), links to attachments bypass PmWiki and come directly from the webserver. Setting $EnableDirectDownload=0; causes requests for attachments to be obtained via [[PmWiki/AvailableActions#download|[@?action=download@]]]. This allows PmWiki to protect attachments using a page's read permissions, but also increases the load on the server. Don't forget to protect your directory /uploads/ with a .htaccess file (Order Deny,Allow / Deny from all).%0a%0a:$EnableUploadGroupAuth:Set @@$EnableUploadGroupAuth = 1;@@ to authenticate downloads with the group password. This could be used together with @@$EnableDirectDownload = 0;@@.%0a%0a:$EnableUploadVersions:When set to 1 (default is 0), uploading a file to a location where a file of the same name already exists causes the old version to be renamed to @@file.ext,timestamp@@ (instead of being overwritten). @@timestamp@@ is a Unix-style timestamp.%0a%0a:$EnableUploadOverwrite:When set to 1 (the default), determines if overwriting previously uploaded files is allowed.%0a%0a:$UploadNameChars:The set of characters allowed in upload names. Defaults to [@"-\w. "@], which means alphanumerics, hyphens, underscores, dots, and spaces can be used in upload names, and everything else will be stripped.%0a: :$UploadNameChars = "-\\w. !=+"; # allow exclamations, equals, and plus%0a: :$UploadNameChars = "-\\w. \\x80-\\xff"; # allow unicode%0a%0a:$MakeUploadNamePatterns: An array of regular expression replacements that is used to normalize the filename of an attached file. First, everything but $UploadNameChars will be stripped, then the file extension will be converted to lowercase. Administrators can override these replacements with a custom definition.%0a%0a:$UploadDirQuota:Overall size limit for all uploads.%0a%0a->[@%0a $UploadDirQuota = 100*1024; # limit uploads to 100KiB%0a $UploadDirQuota = 1000*1024; # limit uploads to 1000KiB%0a $UploadDirQuota = 1024*1024; # limit uploads to 1MiB%0a $UploadDirQuota = 25*1024*1024; # limit uploads to 25MiB%0a $UploadDirQuota = 2*1024*1024*1024; # limit uploads to 2GiB%0a@]%0a%0a:$UploadPrefixQuota:Overall size limit for one directory containing uploads. This directory is usually @@uploads/GroupName@@ (one for every WikiGroup), or @@uploads/Group/PageName@@ (one for every page), depending on the variable $UploadPrefixFmt.%0a%0a:$UploadMaxSize:Maximum size for uploading files, 50000 octets (bytes) by default.%0a%0a
+time=1260918925
diff --git a/wikilib.d/PmWiki.Uploads b/wikilib.d/PmWiki.Uploads
new file mode 100644
index 0000000..4bd6b52
--- /dev/null
+++ b/wikilib.d/PmWiki.Uploads
@@ -0,0 +1,11 @@
+version=pmwiki-2.2.4 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.0.12) Gecko/2009070811 Ubuntu/9.04 (jaunty) Firefox/3.0.12
+author=Petko
+charset=ISO-8859-1
+csum=+
+host=81.65.12.233
+name=PmWiki.Uploads
+rev=120
+targets=PmWiki.PmWiki,PmWiki.Images,PmWiki.UploadsAdmin,PmWiki.WikiGroup,PmWiki.PageDirectives,PmWiki.WikiAdministrator,PmWiki.Passwords,PmWiki.PasswordsAdmin,Site.PageActions,PmWiki.AvailableActions
+text=(:Summary:Allow authors to upload files, also known as page attachments:)%0a(:Audience: authors (intermediate) :)%0a[[PmWiki]] can be configured to allow authors to upload and store files and [[images]] (known as attaching them).%0aThese attachments may then be referenced from any page. %0a%0a-> ''Note'': ''[[PmWiki]] is distributed with uploads disabled by default. See [[Uploads Admin]] for information about how to enable and configure the upload feature.''%0a%0a-> ''Note2'': ''Uploads can be configured site-wide, by-group, or by-page; see [[Uploads Admin]] for details. This determines whether all uploads go in one directory for the site, an individual directory for each group, or an individual directory for each page. The default is to organize uploads by [[WikiGroup | group]].''%0a%0a!! [@Attach:@] Syntax%0aTo add or link to an attachment, an author edits a page to include the markup "@@Attach:@@" followed by a name of an attachment (e.g., "@@[=Attach:resume.pdf=]@@"). When the page is displayed, the @@Attach:@@ markup becomes one of the following:%0a%0a* A link to the named attachment (if uploaded, ie already in the upload directory)%0a* A link to a form whereby the author can specify a file to be uploaded and used as the new attachment (if not yet uploaded, ie not in the upload directory)%0a* If the attachment is an [[image(s)]] file with an extension such as .gif, .jpeg, or .png, it is displayed as an [[image(s)]].%0a%0aThe behaviour of links can be modified to%0a* prevent an image attachment from displaying as an image, place it in double brackets (e.g., [@[[Attach:image.jpg]]@]).%0a* have a link to an attachment appear without the "[@Attach:@]" at the beginning of the link, use [@[[(Attach:)file.ext]]@].%0a%0a!! Attachments on other pages and groups%0aTo link to an uploaded attachment (image or file) from another group, you simply refer the group itself (make sure "Groupname" has the dot in it).%0a->[@Attach:Groupname./file_name.ext@] (note the dot after the groupname)%0aIf PmWiki is configured with an individual directory per page use%0a->[@Attach:Pagename/file_name.ext@] (Pagename is in the same WikiGroup)%0a->[@Attach:Groupname.Pagename/file_name.ext@]%0a%0a!! Names with spaces%0aTo link to a filename with spaces in it use the bracket link notation, eg%0a->[@[[Attach:a filename with spaces.txt]]@]%0aTo attach an [[PmWiki/image(s)]] file with spaces in the name so that is shows as an image use one of these {+workarounds+}%0a->[@[[#blank | Attach:image space.jpeg]]@]%0a->[@[[#1 | Attach:image space.jpeg]]@]%0a%0a!! Listing Uploaded Files On A Page%0aTo list files that have been uploaded, use the markup:%0a[[PmWiki/PageDirectives#attachlist | [@(:attachlist:)@] ]]%0a%0aThis will list attachments to the current group or page, depending whether attachments are organised per group or per page; each instance includes a link to the attachment for viewing or downloading. A list of attachments is also shown as part of the uploads page form.%0a%0a!!!Upload Form / Upload Replacement%0aOne can go directly to the upload form by appending "?action=upload" to the URI for any page that has file uploads enabled by the [[Wiki Administrator]]. Replace a file by simply uploading a new version of the file with the same name. %0a* Be sure to clear your browser cache after replacing an upload. Otherwise, it may appear that the original upload is still on the server. %0aIf you put @@$EnableUploadVersions=1;@@ in your @@local/config.php@@, the old versions of the same files are renamed and not removed.%0a%0a%0a!!!Type and Size Restrictions%0aFor security reasons, the upload feature is disabled when PmWiki is first installed.%0aWhen enabled uploads are restricted as to the types and sizes of files that may be uploaded to the server (see [[UploadsAdmin]]). PmWiki's default configuration limits file sizes to 50 kilobytes and file extensions to common types such as ".gif", ".jpeg", ".doc", ".txt", and ".pdf". %0a%0aIn addition, the administrator can configure the system to require an @@upload@@ password--see [[Passwords]] and [[PasswordsAdmin]].%0a%0aBy default the upload allows the following extensions:%0a%0a[[#imagetypes]] %0a->[@'gif','jpg','jpeg','png','bmp','ico','wbmp', # images%0a@]%0a[[#imagetypesend]]%0a->[@'mp3', 'au','wav', # audio%0a'mpg','mpeg','wmf','mov','qt','avi', # video%0a'zip', 'gz','tgz','tar','rpm','hqx','7z' # archives%0a'odt','ods','odp', # OpenOffice.org%0a'doc','ppt','xls','exe','mdb', # MSOffice%0a'pdf','psd', 'ps','ai','eps', # Adobe%0a'htm','html','fla','swf', # web stuff%0a'txt','rtf','exe','tex','dvi','' # misc@]%0a%0a!!!Removal%0aAt present uploaded files can only be deleted from the server by the [[wiki administrator]]. Any uploads-authorized user may over-write an existing file by uploading another of the same name and extension to the same location.%0a%0aThe administrator may remove an uploaded file by accessing the server via ftp (or via a control panel, if the host offers such a feature). The recipe Cookbook:Attachtable allows the deletion of the files from the wiki.%0a%0a>>faq%3c%3c [[#faq]]%0a%0aQ: When I upload a file, how do I make the link look like "file.doc" instead of "Attach:file.doc"?%0aA: Use parentheses, as in [@[[(Attach:)file.doc]]@]. There is also a configuration change that can eliminate the [@Attach:@] -- see [[Cookbook:AttachLinks]].%0a%0aQ: Why can't I upload files of size more than 50kB to my newly installed PmWiki?%0aA: Out of the box PmWiki limits the size of files to be uploaded to 50kB. Add%0a->@@$UploadMaxSize = 1000000; # limit upload file size to 1 megabyte@@%0a->to your ''config.php'' to increase limit to 1MB (for example). See [[UploadsAdmin]] for how to further customize limits. Note that both PHP and webservers also place their own limits on the size of uploaded files.%0a%0aQ: Why does my upload exit unexpectedly with "Incomplete file received"?%0aA: You may be running out of space in a 'scratch' area, used either by PmWiki or by PHP. On *nix, check that you have sufficient free space in /tmp and /var/tmp.%0a%0aQ: How do I make it so that the upload link still allows one to make another upload (if someone wants to replace the old version of a file with a newer version, for example). Currently you only get the upload link when there is no file in the upload directory.%0aA: Use the Attach [[Site/page action(s)]], and click on the delta symbol %25blue%25(Δ)%25%25 shown against each of files listed. If you can't see the attach action either uploads are not enabled, you are not not authorized to upload, or the attach action has been commented out or is missing. See also [[PmWiki/available actions]].%0a%0aQ: How do I hide the "[=Attach:=]" for all attachments%0aA: See Cookbook:AttachLinks, note that this does not currently work for [@ [[Attach:my file.ext]] @].%0a%0aQ: How to avoid problems with non-ASCII characters in attachment names (i.e. "Zażółć geślą jaźń.doc")?%0aA: See $UploadNameChars[@ = "-\w. !=+#";@]%25%25 # allow exclamations, equals, plus, and hash%0a%0aQ: How can I link a file that have a 4-letter file extension such like 'abc.pptx'?%0aA: See [[Cookbook:Upload Types]]%0a%0aQ: How can I prevent others from using the url's of my images on their site%0aA: See [[Cookbook:Prevent Hotlinking]] {Cookbook.PreventHotlinking$:Summary}%0a%0a
+time=1250793393
diff --git a/wikilib.d/PmWiki.UploadsAdmin b/wikilib.d/PmWiki.UploadsAdmin
new file mode 100644
index 0000000..c68765e
--- /dev/null
+++ b/wikilib.d/PmWiki.UploadsAdmin
@@ -0,0 +1,12 @@
+version=pmwiki-2.2.8 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.6) Gecko/20091215 Ubuntu/9.10 (karmic) Firefox/3.5.6
+author=Petko
+charset=ISO-8859-1
+csum=corrected note about .htaccess
+host=81.65.12.233
+name=PmWiki.UploadsAdmin
+rev=139
+targets=PmWiki.PmWiki,PmWiki.Uploads,PmWiki.Security,PmWiki.WikiAdministrator,PmWiki.PasswordsAdmin,PmWiki.Passwords,Cookbook.UploadGroups,PmWiki.GroupCustomizations,PmWiki.LocalCustomizations,Cookbook.UploadTypes,Cookbook.SecureAttachments,PmWiki.WikiGroup,PmWiki.PageDirectives,Cookbook.AttachlistEnhanced,Cookbook.PreventHotlinking
+text=(:title Uploads Administration:)%0a(:Summary:Administration of PmWiki [[uploads]]:)%0a[[PmWiki]] includes a script called ''upload.php'' that allows users to [[upload(s)]] files to the wiki server using a web browser. Uploaded files (also called ''attachments'') can then be easily accessed using markup within wiki pages. This page describes how to install and configure the upload feature.%0a%0a%0a!! Some notes about [[security]]%0a%0aPmWiki takes a somewhat, but justifiable, paranoid stance%0awhen it comes to the uploads feature. Thus, the default settings for%0auploads tend to try to restrict the feature as much as possible:%0a%0a* The upload function is disabled by default%0a* Even if you enable it, the function is password locked by default%0a* Even if you remove the password, you're restricted to uploading files with certain names, extensions, and sizes%0a* The characters that may appear in upload filenames are (default) alphanumerics, hyphen, underscore, dot, and space ([[#restrictinguploadedfiles|see also here]]).%0a* The maximum upload size is small (50K by default)%0a%0aThis way the potential damage is limited until/unless the wiki%0aadministrator explicitly relaxes the restrictions.%0a%0aKeep in mind that letting users (anonymously!) upload files to your web server does entail some amount of risk. The ''upload.php'' script has been designed to reduce the hazards, but [[wiki administrator]]s should be aware that the potential for vulnerabilities exist, and that misconfiguration of the upload utility could lead to unwanted consequences.%0a%0aBy default, authorized users are able to overwrite files that have already been uploaded, without the possibility of restoring the previous version of the file. If you want to disallow users from being able to overwrite files that have already been uploaded, add the following line to ''config.php'':%0a%0a->[@$EnableUploadOverwrite = 0;@]%0a%0aAlternatively, an administrator can [[#upload_versions|keep older versions]] of uploads.%0a%0aAn administrator can also [[#direct_download|configure]] PmWiki so the password mechanism controls access to uploaded files.%0a%0a%0a!! Basic installation%0a%0aThe ''upload.php'' script is automatically included from ''stdconfig.php'' if the $EnableUpload variable is true in ''config.php''. In addition, ''config.php'' can set the $UploadDir and $UploadUrlFmt variables to specify the local directory where uploaded files should be stored, and the URL that can be used to access that directory. By default, $UploadDir and $UploadUrlFmt assume that uploads will be stored in a directory called ''uploads/'' within the current directory (usually the one containing ''pmwiki.php''). In addition, ''config.php'' should also set a default upload password (see [[PasswordsAdmin]]).%0a%0aThus, a basic ''config.php'' for uploads might look like:%0a%0a->[@%0a%3c?php if (!defined('PmWiki')) exit();%0a## Enable uploads and set a site-wide default upload password.%0a$EnableUpload = 1;%0a$DefaultPasswords['upload'] = crypt('secret');%0a@]%0a%0aIf you have edit passwords and wish to allow all users with edit rights to upload, instead of $DefaultPasswords['upload'], you can set @@$HandleAuth['upload'] = 'edit';@@ in config.php.%0a%0a'''Important''': do NOT create the uploads directory yet! See the next paragraph.%0a%0aYou may also need to explicitly set which filesystem directory will hold uploads and provide a URL that corresponds to that directory like:%0a%0a->[@%0a$UploadDir = "/home/foobar/public_html/uploads";%0a$UploadUrlFmt = "http://example.com/~foobar/uploads";%0a@]%0a%0a[[#uploaddirectoryconfiguration]]%0a!!! Upload directory configuration%0aUploads can be configured site-wide, by-group, or by-page by changing $UploadPrefixFmt. This determines whether all uploads go in one directory for the site, an individual directory for each group, or an individual directory for each page. The default is to organize upload by group. ''It is recommended to have the $UploadPrefixFmt variable defined in config.php, the same for all pages in the wiki, and not in group/page local configuration files. Otherwise you '''will''' be unable to link to attachments in other wikigroups.''%0a%0a[[#sitewideprefix]]For site-wide uploads, use%0a%0a->[@$UploadPrefixFmt = '';@]%0a%0aTo organize uploads by page, use:%0a->[@%0a$UploadPrefixFmt = '/$Group/$Name';%0a@]%0a%0a!!! The upload directory%0a%0aFor the upload feature to work properly, the directory given by [=$UploadDir=] must be writable by the web server process, and it usually must be in a location that is accessible to the web somewhere (e.g., in a subdirectory of ''public_html''). Executing PmWiki with uploads enabled will prompt you with the set of steps required to create the uploads directory on your server (it differs from one server to the next). ''Note that you are likely to be required to explicitly create writable group- or page-specific subdirectories as well!''%0a%0a%0a!!! Uploading a file%0a%0aOnce the upload feature is enabled, users can access the upload form by adding "@@?action=upload@@" to the end of a normal PmWiki URL. The user will be prompted for an upload password similar to the way other pages ask for passwords (see [[Passwords]] and [[PasswordsAdmin]] for information about setting passwords on pages, groups, and the entire site).%0a%0aAnother way to access the upload form is to insert the markup "[@Attach:filename.ext@]" into an existing page, where @@filename.ext@@ is the name of a new file to be uploaded. When the page is displayed, a '?-link' will be added to the end of the markup to take the author to the upload page. (See [[Uploads]] for syntax variations.)%0a%0aBy default, PmWiki will organize the uploaded files into separate subdirectories for each group. This can be changed by modifying the $UploadPrefixFmt variable. See [[Cookbook:UploadGroups]] for details.%0a%0a%0a!! [[#upload_versions]] Versioning Uploaded Files%0a%0aPmWiki does not manage versioning of uploaded files by default. However, by setting $EnableUploadVersions=1; an administrator can have older versions of uploads preserved in the uploads directory along with the most recent version.%0a%0a!! Upload restrictions%0a!!! Restricting uploaded files for groups and pages%0a%0aUploads can be enabled only for specific groups or pages by using a [[group customization(s)]]. Simply set @@$EnableUpload=1;@@ for those groups or pages where uploading is to be enabled; alternately, set @@$EnableUpload=1;@@ in the config.php file and then set @@$EnableUpload=0;@@ in the per-group or per-page customization files where uploads are to be disabled.%0a%0a!!! Restricting total upload size for a group or the whole wiki%0a%0aUploads can be restricted to an overall size limit for groups. In the group configuration file (i.e., local/Group.php), add the line%0a%0a->$UploadPrefixQuota = 1000000; # limit group uploads to 1000KB (1MB)%0a%0aThis will limit the total size of uploads for that group to 1000KB --any upload that pushes the total over the limit will be rejected with an error message. This value defaults to zero (unlimited).%0a%0aUploads can also be restricted to an overall size limit for all uploads. Add the line%0a%0a->$UploadDirQuota = 10000000; # limit total uploads to 10000KB (10MB)%0a%0aThis will limit the total size of uploads for the whole wiki to 10000KB --any upload that pushes the total over the limit will be rejected with an error message. This value defaults to zero (unlimited).%0a%0a%0a[[#restrictinguploadedfiles]]%0a!!!Restricting uploaded files type and size%0a%0aThe upload script performs a number of verifications on an uploaded file before storing it in the upload directory. The basic verifications are described below.%0a:'''filenames''': the name for the uploaded file can contain only letters, digits, underscores, hyphens, spaces, and periods, and the name must begin and end with a letter or digit. %0a:'''file extension''': only files with approved extensions such as "@@.gif@@", "@@.jpeg@@", "@@.doc@@", etc. are allowed to be uploaded to the web server. This is vitally important for server security, since the web server might attempt to execute or specially process files with extensions like "@@.php@@", "@@.cgi@@", etc. %0a:'''file size''': By default all uploads are limited to 50K bytes, as specified by the $UploadMaxSize variable. Thus, to limit all uploads to 100KB, simply specify a new value for $UploadMaxSize in ''config.php'':%0a%0a->[@$UploadMaxSize = 100000;@]%0a%0aHowever, maximum file sizes can also be specified for each type of file uploaded. Thus, an administrator can restrict "@@.gif@@" and "@@.jpeg@@" files to 20K, "@@.doc@@" files to 200K, and all others to the size given by $UploadMaxSize. The $UploadExtSize array is used to determine which file extensions are valid and the maximum upload size (in bytes) for each file type. For example:%0a%0a->[@$UploadExtSize['gif'] = 20000; # limit .gif files to 20KB@]%0a%0aSetting an entry to zero disables file uploads of that type altogether:%0a%0a->[@%0a$UploadExtSize['zip'] = 0; # disallow .zip files%0a$UploadExtSize[''] = 0; # disallow files with no extension@]%0a%0aYou can limit which types of files are uploadable by disabling all defaults and specifying only desired types%0aSetting the variable $UploadMax to zero will disable all default file types. Individual file types may then be enabled by setting their maximum size with the variable $UploadExtSize.%0a%0a-> [@# turns off all upload extensions%0a$UploadMaxSize = 0;%0a%0a# enable only these file types for uploading%0a$aSize=100000; // 100 KB file size limitation%0a$UploadExtSize['jpg' ] = $aSize;%0a$UploadExtSize['gif' ] = $aSize;%0a$UploadExtSize['png' ] = $aSize;%0a@]%0a%0a[[#newuploadfiletypes]]%0a!! Adding new file types to permitted uploads%0a%0aTo add a new extension to the list of allowed upload types, add a line like the following to a [[local customization(s)]] file:%0a%0a->[@$UploadExts['ext'] = 'content-type';@]%0a%0awhere ''ext'' is the extension to be added, and ''content-type'' is the "[[(Wikipedia:)MIME type]]", or content-type (which you may find %25newwin%25[[http://www.iana.org/assignments/media-types/ | here]] or on the lower part of %25newwin%25[[http://www.w3schools.com/media/media_mimeref.asp | this page]]) to be used for files with that extension. For example, to add the '[@dxf@]' extension with a Content-Type of '[@image/x-dxf@]', place the line%0a%0a->[@$UploadExts['dxf'] = 'image/x-dxf';@]%0a%0aEach entry in $UploadExts needs to be the extension and the%0amime-type associated with that extension, thus:%0a%0a->[@%0a$UploadExts = array(%0a 'gif' => 'image/gif',%0a 'jpeg' => 'image/jpeg',%0a 'jpg' => 'image/jpeg',%0a 'png' => 'image/png',%0a 'xxx' => 'yyyy/zzz'%0a);%0a@]%0a%0aFor the types that PmWiki already knows about it's not necessary to repeat them here (the ''upload.php'' script adds PmWiki's defaults to whatever the administrator supplies).%0a[[#newuploadfiletypesend]]%0aSee also Cookbook:UploadTypes for additional types.%0a%0a[[#otherfilesizelimits]]%0a!!Other file size limits%0a%0aThere are other factors involved that affect upload file sizes. In Apache 2.0, there is a `[[http://httpd.apache.org/docs/2.2/mod/core.html#limitrequestbody|LimitRequestBody]] directive that controls the maximum size of anything that is posted (including file uploads). Apache has this defaulted to unlimited size. However, some Linux distributions (e.g., Red Hat Linux) limit postings to 512K so this may need to be changed or increased. (Normally these settings are in an ''httpd.conf'' configuration file or in a file in ''/etc/httpd/conf.d''.)%0a%0aProblem noted on Red Hat 8.0/9.0 with Apache 2.0.x, the error "Requested content-length of 670955 is larger than the configured limit of 524288" was occurring under Apache and a "Page not found" would appear in the browser. Trying the above settings made no change with PHP, but on Red Hat 8.0/9.0 there is an additional PHP config file, /etc/httpd/conf.d/php.conf, and increasing the number on the line "`LimitRequestBody 524288" solves the issue.%0a%0aPHP itself has two limits on file uploads (usually located in @@/etc/php.ini@@). The first is the @@upload_max_filesize@@ parameter, which is set to 2MB by default. The second is @@post_max_size@@, which is set to 6MB by default.%0a%0aWith the variables in place--PmWiki's maximum file size, Apache's request-size limits, and the PHP file size parameters, the maximum uploaded file size will be the smallest of the three variables.%0a%0a!!! [[#direct_download]] Password protecting uploaded files%0aSetting a read password for pages (and groups) will prevent an attached file from being seen or accessed through the page, but to prevent direct access to the file location (the uploads/ directory) one can do the following:%0a %0a* In local/config.php set @@$EnableDirectDownload=0@@;%0a* If you use per-group upload directories (PmWiki default, see $UploadPrefixFmt), add to config.php @@$EnableUploadGroupAuth = 1;@@%0a* Deny public access to the uploads/ directory through moving it out of the html/ or public_html/ directory tree, or through a .htaccess file.%0a%0a%0aSee [[Cookbook:Secure attachments]] {Cookbook.SecureAttachments$:Summary}%0a%0a%0a!! Other notes%0a%0a* If uploads doesn't seem to work, make sure that your PHP installation allows uploads. The ''php.ini'' file (usually ''/etc/php.ini'' or ''/usr/local/lib/php.ini'') should have %0a%0a->[@file_uploads = On@]%0a%0a* Another source of error in the ''php.ini'' file is a not defined ''upload_tmp_dir''. Just set this variable to your temp directory, e.g.%0a%0a->[@upload_tmp_dir = /tmp@]%0a%0a%0aNote that if you change this values, httpd must generally be restarted. Another way to check if uploads are allowed by the server is to set $EnableDiag to 1 in ''config.php'', and set ?action=phpinfo on a URL. The "@@file_uploads@@" variable must have a value of 1 (if it says "@@no value@@", that means it's off).%0a%0a%0a%0a%0a>>faq%3c%3c [[#faq]]%0a%0aQ: How do I disable uploading of a certain type of file?%0aA: Here's an example of what to add to your ''local/config.php'' file to disable uploading of .zip files, or of files with no extension:%0a%0a->[@%0a$UploadExtSize['zip'] = 0; # Disallow uploading .zip files%0a$UploadExtSize[''] = 0; # Disallow files with no extension@]%0a%0aQ: How do I attach uploads to individual pages or the entire site, instead of organizing them by [[wiki group]]?%0aA: Use the $UploadPrefixFmt variable (see also the Cookbook:UploadGroups recipe).%0a%0a->[@$UploadPrefixFmt = '/$FullName'; # per-page@]%0a->[@$UploadPrefixFmt = ''; # site-wide@]%0a%0aQ:For $UploadDirQuota - can you provide some units and numbers? Is the specification in bytes or bits? What is the number for 100K? 1 Meg? 1 Gig? 1 Terabyte?%0aA: Units are in bytes. %0a%0a $UploadDirQuota = 100*1024; # limit uploads to 100KiB%0a $UploadDirQuota = 1000*1024; # limit uploads to 1000KiB%0a $UploadDirQuota = 1024*1024; # limit uploads to 1MiB%0a $UploadDirQuota = 25*1024*1024; # limit uploads to 25MiB%0a $UploadDirQuota = 2*1024*1024*1024; # limit uploads to 2GiB%0a%0aQ: Is there a way to allow file names with Unicode or addtiional characters? %0aA: Yes, see $UploadNameChars%0a%0aQ:Where is the list of attachments stored?%0aA: It is generated on the fly by the [[PageDirectives#attachlist|(:attachlist:)]] markup.%0a%0aQ: How can I find orphaned or missing attachments%0aA: See [[Cookbook:Attachlist enhanced]] {Cookbook.AttachlistEnhanced$:Summary}%0a%0aQ: How can I prevent hotlinking of my uploaded images%0aA: See [[Cookbook:Prevent Hotlinking]] {Cookbook.PreventHotlinking$:Summary}%0a%0aQ: I have limited the max upload size to 8 MB in config.php, however only files smaller than 2MB can be uploaded.%0aA: Check your php.ini for ''upload_max_filesize''%0a->[@%0aupload_max_filesize = 8M%0a@]%0a%0aIf you cannot access your php.ini directly try to soften server limits in the root .htaccess file:%0a%0a->[@php_value post_max_size 63M%0aphp_value upload_max_filesize 62M%0aphp_value memory_limit 64M%0aphp_value max_execution_time 600%0aphp_value default_socket_timeout 600%0a@]
+time=1263683961
+title=Uploads Administration
diff --git a/wikilib.d/PmWiki.UrlApprovals b/wikilib.d/PmWiki.UrlApprovals
new file mode 100644
index 0000000..337e47e
--- /dev/null
+++ b/wikilib.d/PmWiki.UrlApprovals
@@ -0,0 +1,11 @@
+version=pmwiki-2.2.5 ordered=1 urlencoded=1
+agent=Midori/0.1.9 (X11; Linux x86_64; U; en-us) WebKit/532+
+author=Petko
+charset=ISO-8859-1
+csum=refactor
+host=81.65.12.233
+name=PmWiki.UrlApprovals
+rev=71
+targets=SiteAdmin.ApprovedUrls,Site.AllRecentChanges,PmWiki.Blocklist,PmWiki.Security
+text=(:Summary:Require approval of Url links:)%0aThis page explains how to discourage "link spamming" on your wiki site using PmWiki's ''urlapprove.php'' script. This script is already included in PmWiki files, but not activated by default.%0a%0a%0a!! Using ''urlapprove.php''%0aOccasionally spammers may try to add large number of (sometimes hidden) `URLs to pages because they think it will improve their search engine rankings -- which it [[#nofollow |probably won't]]. The ''urlapprove.php'' script works against these spammers' purpose by%0a%0a* requiring approval of links to Internet sites before a link to them are created in the wiki, and%0a* allowing you to limit the number of unapproved links that may be added to a page.%0a%0aTo enable ''urlapprove.php'', add the following line to a configuration file:%0a%0a->[@include_once("$FarmD/scripts/urlapprove.php");@]%0a%0aBy default, unapproved links display what ever should be displayed normally (the URL or a text), but not linked and next to it a link [-%25blue%25(approve links)%25%25-].%0aA click on the link will approve all unapproved `URLs on the page, %25green%25but ''only'' if you are authorized to edit the ''SiteAdmin.ApprovedUrls'' page%25%25. You may also pre-approve sites by by adding them directly to the [[SiteAdmin.ApprovedUrls]] page.%0a%0a%0a!!! Limiting unapproved urls per page%0aYou can limit the number of unapproved links per page. If the limit is exceeded, the page cannot be saved. This is useful because spammers like to write long link lists, which is rare for normal authors.%0a%0aExample: To set the limit to 5 unapproved links, add the following line to a configuration file:%0a%0a->[@$UnapprovedLinkCountMax = 5;@]%0a->[@include_once('scripts/urlapprove.php');@]%0a%0aNote that $UnapprovedLinkCountMax must be set ''before'' including the ''urlapprove.php'' script.%0a%0a%0a!!! Handling of Unapproved Links%0aYou can also change the disapproval message defined in the $UnapprovedLinkFmt variable, for example:%0a%0a-> [@%0ainclude_once('scripts/urlapprove.php');%0a$UnapprovedLinkFmt =%0a "[$[Link requires approval]]%3ca class='apprlink'%0a href='\$PageUrl?action=approvesites'>$[(approve)]%3c/a>";%0a@]%0a%0a"Link requires approval" is whatever you want to see in place of the unapproved link and "(approve)" is the blue text. Using this feature may prove usefull if you want to always hide the unapproved link.%0a%0aIf you wish to totally forbid unapproved links you can use%0a%0a->[@$UnapprovedLinkFmt = "%3cb>external link not allowed%3c/b>";@]%0a%0a%0a!!! `SideBar caveat [[#sidebar]]%0aPlease note that in general you need to go to the sidebar page in order to approve links in the sidebar. The reason for this is that the approve mechanism only approves links on the ''current'' page.%0a%0a%0a!!! Initial setup%0aAfter initial setup all existing links become unapproved. You need to visit your pages and approve all links, where needed. See [[Site/AllRecentChanges]] for a list of all pages that were created on your wiki.%0a%0a!! Password approval of URLs%0aTo approve external links, an author needs permissions to edit the page [[SiteAdmin.ApprovedUrls]].%0a%0a!! Technical tips%0a[[#whiteurls]]%0a!!! URL Whitelist%0aUrls can also be approved by adding them to a "white list", %0adefined in the variable @@$WhiteUrlPatterns@@, %0awhich is set in the ''local/config.php'' file.\\%0aTo add multiples urls, use the separator @@|@@ (vertical bar). For example:%0a%0a-> [@%0a$WhiteUrlPatterns =%0a "http://example.com/|http://example.net/|http://example.org/";%0a@]%0a%0aTo add all urls from, say New Zealand and Australia, use:%0a%0a-> [@%0a$WhiteUrlPatterns[] = 'http://[^/] \\.nz';%0a$WhiteUrlPatterns[] = 'http://[^/] \\.au';%0a@]%0a%0a%0a!!! Change Approved URLs page name%0aIf you want to change the default name of ''SiteAdmin.ApprovedUrls'', set the following in ''local/config.php'':%0a%0a->[@$ApprovedUrlPagesFmt = array('OtherGroup.OtherName');@]%0a%0a!!! Previewing the unapproved URL%0aTo see what link is to be approved without editing the page a tool tip can be displayed when the cursor hovers over the [-%25blue%25(approve links)%25%25-] link that displays the URL. e.g. [[http://uuu.example.com|Example]].%0a%0aAdd the following setting in your ''local/config.php'':%0a%0a-> [@%0a$UnapprovedLinkFmt =%0a "\$LinkText%3ca class='apprlink' href='\$PageUrl?action=approvesites'%0a title='\$LinkUrl'>$[(approve links)]%3c/a>";%0a@]%0a%0a->Some browsers show only the link and not the tooltip title. In this case, you can use the following code to see the unapproved link at the end of the tooltip :%0a-> [@$UnapprovedLinkFmt =%0a "\$LinkText%3ca class='apprlink' href='\$PageUrl?action=approvesites&XES_url=\$LinkUrl'%0a title='\$LinkUrl'>$[(approve sites)]%3c/a>";%0a@]%0a%0a%0a!! About rel='nofollow' [[#nofollow]]%0aBy default, PmWiki creates external links that are not followed by search engines. %0aHere are release notes from pmwiki-2.0.beta20 (30-Jan-2005):%0a%0a->''First, the $UrlLinkFmt variable has been modified so that links to external urls automatically have a rel='nofollow' attribute added to them, to help combat wiki spam as described in [[http://googleblog.blogspot.com/2005/01/preventing-comment-spam.html]]. Site administrators can customize $UrlLinkFmt and $UnapprovedLinkFmt to supply or omit rel='nofollow' as appropriate.''%0a%0a!! See Also%0a%0a* [[PmWiki/Blocklist]] - Blocking postings based on content or IP address%0a* [[PmWiki/Security]] - Securing your PmWIki%0a
+time=1254657391
diff --git a/wikilib.d/PmWiki.Variables b/wikilib.d/PmWiki.Variables
new file mode 100644
index 0000000..61d651e
--- /dev/null
+++ b/wikilib.d/PmWiki.Variables
@@ -0,0 +1,11 @@
+version=pmwiki-2.2.8 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/532.5 (KHTML, like Gecko) Chrome/4.0.249.43 Safari/532.5
+author=simon
+charset=ISO-8859-1
+csum=smaller
+host=203.97.214.12
+name=PmWiki.Variables
+rev=73
+targets=PmWiki.LocalCustomizations,PmWiki.PageVariables,PmWiki.PageTextVariables,PmWiki.BasicVariables,PmWiki.DebugVariables,PmWiki.EditVariables,PmWiki.I18nVariables,PmWiki.LayoutVariables,PmWiki.LinkVariables,PmWiki.OtherVariables,PmWiki.PagelistVariables,PmWiki.PageLists,PmWiki.PathVariables,PmWiki.SecurityVariables,PmWiki.UploadVariables,PmWiki.Blocklist,PmWiki.Notify,PmWiki.Functions
+text=(:Summary:Variables available for local customisation:)%0a(:Audience: administrators (basic) :)%0a%0aThis page documents the PHP variables available in PmWiki for [[local customizations]]. Much of this documentation is still incomplete but people are working on it now. Feel free to add placeholders for variables you want to have documented if you don't know what the variable does.%0a%0aNote: Do not confuse these PHP variables with [[Page Variables]] and [[Page TextVariables]] being used in page markup.%0a%0aThe variables documentation is divided into several pages:%0a%0a* [[Basic Variables]] - {BasicVariables$:Summary}%0a* [[Debug Variables]] - {DebugVariables$:Summary}%0a* [[Edit Variables]] - {EditVariables$:Summary}%0a* [[I18n Variables]] - {I18nVariables$:Summary}%0a* [[Layout Variables]] - {LayoutVariables$:Summary}%0a* [[Link Variables]] - {LinkVariables$:Summary}%0a* [[Other Variables]] - {OtherVariables$:Summary}%0a* [[Pagelist Variables]] - {PagelistVariables$:Summary}%0a* [[Path Variables]] - {PathVariables$:Summary}%0a* [[Security Variables]] - {SecurityVariables$:Summary}%0a* [[Upload Variables]] - {UploadVariables$:Summary}%0a%0aThe following functions are also controlled by several variables:%0a* [[Blocklist(#variables)]] - {Blocklist$:Summary}%0a* [[Notify(#variables)]] - {Notify$:Summary}%0a* [[Basic Variables]] %25item comment%25 to provide circular trail%0a%0aAn complete index of documented PHP variables is given below.%0a%0aIn general, variables with names ending in 'Fmt' (such as $PageLayoutFmt) have their values processed for $-variable substitutions prior to being output. Thus strings such as [@{$Name}@] and [@{$PageUrl}@] are replaced with the name and URL of the page when the string is printed.%0a%0aNote: The automatic variable index and link generation is done by scripts/vardoc.php using $VarPagesFmt to find the pages containing trails of pages with the variable documentation.%0a%0aThere is a slight discrepancy between index generation and link generation: The index generation finds lines starting with a colon followed by "$" and an uppercase word. In contrast, the automatic link generation works only with WikiWords ($WikiWordPattern) preceded by "$". Therefore all "non WikiWord" variables are shown as link only in the list below, but not elsewhere in PmWiki, as $Author, $Version and $XL.%0a%0a!!See Also%0a%0a* %25%25 [[PmWiki/Functions]] - {Functions$:Summary} (:comment why? Could be removed IMO --OliverBetz:)%0a----%0a[[#index]]List of documented PHP variables%0a>>font-size:smaller%3c%3c%0a(:varindex:) %25comment%25 where is this documented?%25%25%0a>>%3c%3c%0a
+time=1262759520
diff --git a/wikilib.d/PmWiki.Version b/wikilib.d/PmWiki.Version
new file mode 100644
index 0000000..4e67ed2
--- /dev/null
+++ b/wikilib.d/PmWiki.Version
@@ -0,0 +1,12 @@
+version=pmwiki-2.2.2 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.19) Gecko/20081216 Ubuntu/8.04 (hardy) Firefox/2.0.0.19
+author=Petko
+charset=ISO-8859-1
+csum=links to pages not in the distribution should be absolute
+ctime=1176363304
+host=81.65.14.164
+name=PmWiki.Version
+rev=9
+targets=PmWiki.PageVariables,SiteAdmin.Status,PmWiki.BasicVariables
+text=(:Summary: Determining and displaying the current version of PmWiki ({$Version}):)%0a!! Obtaining the PmWiki version%0aUse the [@{$Version}@] [[page variable(s)]] to display the current version of PmWiki.%0a%0aSee the [[SiteAdmin.Status]] page for the current version and version number.%0a%0aFor example%0a(:markup:)%0aThis wiki installation is running PmWiki {$Version}, version number {$VersionNum}.%0a-%3cThe default group is {$DefaultGroup}.%0a-%3cThe default name is {$DefaultName}.%0a-%3cThe site group is {$SiteGroup}%0a(:markupend:)%0a%0aSee also [[basic variables]].%0a%0aThe script @@version.php@@ contains the declaration of the version number.%0a%0a!! Obtaining recipe versions%0aThe [[(PmWiki:)Site Analyzer]] can be used to display the current version of %0a[[Cookbook(:/)]] recipes.%0a%0aSee also [[Cookbook:RecipeCheck]]%0a%0a%0a
+time=1247526506
diff --git a/wikilib.d/PmWiki.WebFeeds b/wikilib.d/PmWiki.WebFeeds
new file mode 100644
index 0000000..6788f88
--- /dev/null
+++ b/wikilib.d/PmWiki.WebFeeds
@@ -0,0 +1,11 @@
+version=pmwiki-2.2.10 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7
+author=Diafygi
+charset=ISO-8859-1
+csum=added pmwiki.org enabling
+host=206.104.202.203
+name=PmWiki.WebFeeds
+rev=74
+targets=PmWiki.WikiTrails,Site.AllRecentChanges,Cookbook.Backlinks,PmWiki.WikiGroup,PmWiki.Categories,PmWiki.PageLists,Cookbook.RssFeedDisplay,PmWiki.LocalCustomizations,Cookbook.FeedLinks,Cookbook.PageFeed,Cookbook.CustomRecentChanges,PITS.01161
+text=(:Summary:Web feed notification of changes:)%0a(:Audience: visitors (intermediate) :)%0aWeb feeds are a convenient mechanism to let visitors be notified of changes to a site. Instead of repeatedly checking [=RecentChanges=] every day to see what is new, a visitor can use a [[news aggregator -> Wikipedia:Aggregator]] to quickly see what pages of interest have changed on a site. Web feeds are commonly recognized by terms such as [[(Wikipedia:)RSS]], [[(Wikipedia:)Atom(_%2528standard%2529)]], and ''[[Wikipedia:web_syndication | web syndication]]''. They are also the foundation for podcasting.%0a%0aIn its simplest form, web feeds in PmWiki are built on [[WikiTrails]]. Using a feed action such as [@?action=rss@] or [@?action=atom@] on a trail generates a web feed (often called a "channel") where each page on the trail is an item in the feed. Since the RecentChanges and [[{$SiteGroup}.AllRecentChanges]] pages are effectively trails, one can easily get an RSS feed for a group or site by simply adding [@?action=rss@] to the url for a RecentChanges page. For example, to get the site feed for pmwiki.org, one would use%0a%0a->http://pmwiki.org/wiki/Site/AllRecentChanges?action=rss%0a%0aAuthors can also create custom feeds by simply creating a wiki trail of the pages they want included in the feed. Feeds can also be generated from [[groups -> WikiGroup]], [[categories]], and %25newwin%25[[Cookbook:Backlinks|backlinks]], and the order and number of items in the feed can be changed using options in the feed url. Thus, one can obtain a feed for the ''Skins'' category (sorted with most recent items first) by using%0a%0a->http://pmwiki.org/wiki/Category/Skins?action=rss&order=-time%0a%0aPmWiki is able to generate feeds in many formats, including RSS 2.0 ([@?action=rss@]), Atom 1.0 ([@?action=atom@]), and RSS 1.0 ([@?action=rdf@]). In addition, although it is not normally considered a web feed, PmWiki can generate metadata information using the Dublin Core Metadata extensions ([@?action=dc@]).%0a%0a!!How to read a PmWiki syndicated feed%0a%0a# You'll need a [[news aggregator -> Wikipedia:List_of_feed_aggregators]], which is a piece of software designed to read news feeds. Many different news aggregators are available. Some run on your own computer, either on their own or as plugins for email clients, web browsers, or newsreaders. Others are web applications that you can use from any Internet-connected computer. Some are in between (technically web applications, but ones designed to run on your computer, not some remote server). Get one that you like.%0a# Subscribe to the [[WikiTrail(s)]] you desire by supplying the feed url to the aggregator. The feed url will be the name of a trail page with [@?action=rss@] or [@?action=atom@] added to the end of the url.%0a%0a!!Feed options%0a%0aAdd any of the following options to the end of a PmWiki web feed url to change its output (basically any [[pagelist->PageLists]] option is available for web feeds):%0a%0a:?count=''n'': Limit feed to ''n'' items%0a:?order=-time : Display most recently changed items first%0a:?trail=''page'': Obtain items from trail on ''page''%0a:?group=''group'': Limit feed to pages in ''group''%0a:?name=''name'': Limit feed to pages with specific ''name''%0a:?link=''page'': Create feed from pages linked to ''page''%0a:?list=normal: Exclude things like RecentChanges, AllRecentChanges, etc.%0a%0a%25audience%25 authors (intermediate)%0a!!Configure PmWiki for feeds%0a%0aThis section describes how to syndicate portions of a wiki to appear in a web feed. It does not describe how to display a web feed within a wiki page -- for that, see Cookbook:RssFeedDisplay.%0a%0aTo enable web feed generation for a site, add one or more of the following to a [[local customization(s)]] file:%0a%0a->[@%0aif ($action == 'rss') include_once("$FarmD/scripts/feeds.php");%0aif ($action == 'atom') include_once("$FarmD/scripts/feeds.php");%0aif ($action == 'rdf') include_once("$FarmD/scripts/feeds.php");%0aif ($action == 'dc') include_once("$FarmD/scripts/feeds.php");%0a@]%0a%0aor you can combine multiple feeds into a single expression using "||" to separate each feed type. For example, if you want to enable RSS and Atom feeds you would use%0a%0a->[@%0aif ($action == 'rss' ||%0a $action == 'atom' ||%0a $action == 'rdf' ||%0a $action == 'dc') include_once("$FarmD/scripts/feeds.php");%0a@]%0a%0a!!Configure feed content%0aWeb feeds are highly configurable, new elements can be easily added to feeds via the $FeedFmt array. Elements in $FeedFmt look like%0a%0a[@$FeedFmt['atom']['feed']['rights'] = 'All Rights Reserved';@]%0a%0awhere the first index corresponds to the action (?action=atom), the second index indicates a per-feed or per-item element, and%0athe third index is the name of the element being generated. The above setting would therefore generate a "%3crights>All Rights Reserved%3c/rights>" in the feed for ?action=atom.%0a%0a[[#pitfall1]]%0aIf the value of an entry begins with a '%3c', then feeds.php doesn't automatically add the tag around it. Elements can also be callable functions which are called to generate the appropriate output. See [[http://blogs.law.harvard.edu/tech/rss | RSS specification]] or other feed specifications for what feed content you can use.%0a%0aYou can also change an existing element rather than add a new one. You can use the following lines to ensure that changes made to the wiki will be picked up by some RSS readers that wouldn't otherwise "notice" a page has been changed:%0a%0a->[@%0a# Change the link URL when an item is edited.%0a$FeedFmt['rss']['item']['link'] = '{$PageUrl}?when=$ItemISOTime';%0a$FeedFmt['atom']['item']['link'] =%0a "%3clink rel=\"alternate\" href=\"{\$PageUrl}?when=\$ItemISOTime\" />\n";%0a@]%0a%0a%0a!!See Also%0a%0a* [[Cookbook:FeedLinks]] - Add HTML %3chead> links for auto-discovery of your feeds.%0a* [[WikiTrails]]%0a* Wikipedia:Web_feed, Wikipedia:Web_syndication, Wikipedia:RSS_%2528file_format%2529, Wikipedia:Atom_%2528standard%2529%0a%0a>>faq%3c%3c [[#faq]]%0a%0aQ: How do I include text from the page (whole page, or first X characters) in the feed body? (note: markup NOT digested)%0a%0a function MarkupExcerpt($pagename) {%0a $page = RetrieveAuthPage($pagename, 'read', false);%0a return substr(@$page['text'], 0, 200);%0a }%0a%0a $FmtPV['$MarkupExcerpt'] = 'MarkupExcerpt($pn)';%0a $FeedFmt['rss']['item']['description'] = '$MarkupExcerpt';%0a%0a%25green%25 Q:Does this mean if I want to include the time in the rss title and "summary" to rss body I call [@$FeedFmt@] twice like so:%0a->[@$FeedFmt['rss']['item']['description'] = '$LastSummary'; %0a$FeedFmt['rss']['item']['title'] = '{$Group} / {$Title} @ $ItemISOTime';@] %25%25%0a%0a---> From mailing list Feb 13,2007, a response by Pm: Yes%0a%0aQ: How can I use the RSS %3cenclosure> tag for podcasting?%0a%0aA: For podcasting of mp3 files, simply attach an mp3 file to the page%0awith the same name as the page (i.e., for a page named Podcast.Episode4,%0aone would attach to that page a file named "Episode4.mp3"). The%0afile is automatically picked up by ?action=rss and used as an%0aenclosure.%0a%0aThe set of potential enclosures is given by the $RSSEnclosureFmt%0aarray, thus%0a%0a->[@$RSSEnclosureFmt = array('{$Name}.mp3', '{$Name}.wma', '{$Name}.ogg');@]%0a%0aallows podcasting in mp3, wma, and ogg formats.%0a%0a%0aQ: [[#AddSummary]] How to add "summary" to the title in a rss feed (ie. with [@?action=rss@])?%0a%0aA: Add this line in you [@local/config.php@]%0a%0a->[@$FeedFmt['rss']['item']['title'] = '{$Group} / {$Title} : $LastModifiedSummary';@]%0a%0a%0aQ: [[#AddDescriptionSummary]] How to add "description" to the title in an rss feed, and summary to the body?%0a%0aA: Add these lines to your [@local/config.php@]%0a%0a->[@$FeedFmt['rss']['item']['title'] = '{$Group} / {$Title} : {$Description}';@]%0a->[@$FeedFmt['rss']['item']['description'] = '$LastModifiedSummary';@]%0a%0a%0a'''NOTES:'''%0a* you need to replicate these lines for each type (atom, rdf, dc) of feed you provide.%0a* the RSS '''[@description@]'''-tag is not equivalent to the pmWiki ''[@$Description@]'' variable, despite the confusing similarity.%0a%0aQ: Some of my password-protected pages aren't appearing in the feed... how do I work around this?%0a%0aA: From a similar question on the newsgroup, Pm's reply:%0a%0aThe last time I checked, RSS and other syndication protocols didn't%0areally have a well-established interface or mechanism for performing%0aaccess control (i.e., authentication). As far as I know this is%0astill the case.%0a%0aPmWiki's WebFeeds capability is built on top of pagelists, so it%0acould simply be that the $EnablePageListProtect option is preventing%0athe updated pages from appearing in the feed. You might try%0asetting $EnablePageListProtect=0; and see if the password-protected%0apages start appearing in the RSS feed.%0a%0aThe "downside" to setting $EnablePageListProtect to zero is that%0aanyone doing a search on your site will see the existence of the%0apages in the locked section. They won't be able to read any of%0athem, but they'll know they are there!%0a%0aYou could also set $EnablePageListProtect to zero only if ?action=rss:%0a%0a if ($action == 'rss') $EnablePageListProtect = 0;%0a%0aThis limits the ability to see the protected pages to RSS feeds;%0anormal pagelists and searches wouldn't see them.%0a%0aLastly, it's also possible to configure the webfeeds to obtain%0athe authentication information from the url directly, as in:%0a%0a .../Site/AllRecentChanges?action=rss&authpw=secret%0a%0aThe big downside to this is that the cleartext password will%0aend up traveling across the net with every RSS request, and%0amay end up being recorded in Apache's access logs.%0a%0aQ: How to add feed image?%0a%0aA: Add the following to ''local/config.php'' (this example is for [@?action=rss@]):%0a%0a->[@%0a$FeedFmt['rss']['feed']['image'] =%0a" %3ctitle>Logo title%3c/title>%0a %3clink>http://example.com/%3c/link>%0a %3curl>http://example.com/images/logo.gif%3c/url>%0a %3cwidth>120%3c/width>%0a %3cheight>60%3c/height>";%0a@]%0a%0a-> %25red%25Do not forget NOT to start with a '%3c' as there would be no %3cimage> tag around this... See [[#pitfall1|here]].%0a%0aQ: How do I insert RSS news feeds into PmWiki pages?%0a%0aA: See [[Cookbook:RssFeedDisplay]].%0a%0aQ: How can I specify default feed options in a configuration file instead of always placing them in the url?%0aA: For example, if you want [@?action=rss@] to default to [@?action=rss&group=News&order=-time&count=10@], try the following in a [[local customization(s)]] file:%0a%0a->[@%0a if ($action == 'rss')%0a SDVA($_REQUEST, array(%0a 'group' => 'News',%0a 'order' => '-time',%0a 'count' => 10));%0a@]%0a%0aQ: Are there ways to let people easily subscribe to a feed?%0a%0aA: On some browsers (Mozilla Firefox), the visitor can see an orange RSS icon in the address bar, and subscribe to the feed by clicking on it. To enable the RSS icon, add this to config.php :[@%0a$HTMLHeaderFmt['feedlinks'] = '%3clink rel="alternate" type="application/rss+xml" %0a title="$WikiTitle" href="$ScriptUrl?n=Site.AllRecentChanges&action=rss" />%0a%3clink rel="alternate" type="application/atom+xml" title="$WikiTitle"%0a href="$ScriptUrl?n=Site.AllRecentChanges&action=atom" />';@]%0a%0aYou can also add such a link, for example in your SideBar, @@[=[[Site.AllRecentChanges?action=atom | Subscribe to feed]]=]@@. %0a%0aQ: Can I create an RSS feed for individual page histories?%0aA: See Cookbook:PageFeed.%0a%0a%0aQ: How do I create a custom FeedPage similar to RecentChanges or AllRecentChanges, but with only certain groups or pages recorded?%0aA: See Cookbook:CustomRecentChanges. In a nutshell, you'll declare a $RecentChangesFmt variable with your dedicated FeedPage, and then wrap it in a condition of your choice. For example:%0a[@%0a if (PageVar($pagename, '$Group')!='ForbiddenGroup') {%0a $RecentChangesFmt['Site.MyFeedPage'] =%0a '* [[{$FullName}]] . . . $CurrentTime $[by] $AuthorLink: [=$ChangeSummary=]';%0a }%0a@]%0a%0aQ: How can I update my RSS feed to show every edit for pages on that feed, not just new pages added to the feed?%0aA: Add unique guid links for each edit to your to congif.php file (see PITS [[PITS:01161|entry]]):%0a[@%0a $FeedFmt['rss']['item']['guid'] = '{$PageUrl}?guid=$ItemISOTime';%0a@]%0a%0aAlternatively, you can create the option for edit monitoring by adding a qualifier for RSS links. This allows the user to choose between default ''new pages'' RSS feeds and ''new edits'' RSS feeds (pmwiki.org has this option enabled).%0a[@%0a ## For new pages updates: http://example.com/wiki/HomePage?action=rss%0a ## For edits updates: http://example.com/wiki/HomePage?action=rss&edits=1%0a if(@$_REQUEST['edits'] && $action == 'rss')%0a $FeedFmt['rss']['item']['guid'] = '{$PageUrl}?guid=$ItemISOTime';%0a@]
+time=1265173959
diff --git a/wikilib.d/PmWiki.WikiAdministrator b/wikilib.d/PmWiki.WikiAdministrator
new file mode 100644
index 0000000..522881a
--- /dev/null
+++ b/wikilib.d/PmWiki.WikiAdministrator
@@ -0,0 +1,11 @@
+version=pmwiki-2.2.1 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.19) Gecko/20081216 Ubuntu/8.04 (hardy) Firefox/2.0.0.19
+author=Petko
+charset=ISO-8859-1
+csum=fix link
+host=81.65.14.164
+name=PmWiki.WikiAdministrator
+rev=12
+targets=PmWiki.Installation,PmWiki.InitialSetupTasks,PmWiki.DocumentationIndex,PmWiki.Security,PmWiki.Audiences
+text=A Wiki Administrator is a person (or persons) who installs, configures, and administers a PmWiki system for authors and site visitors. PmWiki has been designed to make the [[installation]] and [[initial setup tasks]] as easy as possible for people who do not have a lot of knowledge about HTML, PHP, or even web server software. At the same time, PmWiki is designed to be flexible enough so that someone with just a little bit of knowledge about HTML and PHP can customize PmWiki to their specific needs. %0a%0aSee the [[PmWiki.documentation index]] for pages about administering PmWiki, [[PmWiki:AdminTask|administration tasks]], %0a[[PmWiki/security]],%0aand [[PmWiki.audiences]] for more details of PmWiki's target audiences.%0a
+time=1238276208
diff --git a/wikilib.d/PmWiki.WikiFarmTerminology b/wikilib.d/PmWiki.WikiFarmTerminology
new file mode 100644
index 0000000..6c72981
--- /dev/null
+++ b/wikilib.d/PmWiki.WikiFarmTerminology
@@ -0,0 +1,11 @@
+version=pmwiki-2.1.3 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.0.1) Gecko/20060111 Firefox/1.5.0.1
+author=Susan
+csum=Added cross ref to PmWiki:Glossary
+ctime=1142751483
+host=70.50.209.203
+name=PmWiki.WikiFarmTerminology
+rev=19
+targets=PmWiki.Glossary,Category.WikiFarms
+text=%25audience%25 administrators (intermediate)%0aThere are many ways to configure [[PmWiki:WikiFarms]], and some of the documentation uses different terminology to describe the same things. This page attempts to explain the terminology.%0a%0aFor terms not related to farms, see [[Glossary]].%0a%0a!!Why is this page needed?%0a* to provide a place to find the preferred terminology with definitions%0a* to explain where the term "farm" came from%0a* to list various terms that have been deprecated but still exist in the docs%0a* to suggest alternate terms for the deprecated ones%0a%0a%0a!!The origins of WikiFarms%0aThe term WikiFarm is based on the computing term "server farm", which is a collection of servers that use a common infrastructure. A wiki farm is nothing more than multiple wikis that share the same installation of the PmWiki software.%0a%0aSome recipe and documentation authors, however, began writing about WikiFarms using agricultural terms such as "field", "farmer", "barn", "crop", and "tractor". In some cases these terms made the documentation more confusing. It is suggested that documentation authors avoid the agricultural terms, as tempting as they may be, and keep in mind that a wiki in a wiki farm is like a server in a server farm.%0a%0a%0a!!Wikis and components in a WikiFarm%0aAll of the wikis in a farm are more or less the same, except the "home wiki" is a wiki that is located in the same directory as the PmWiki software. The home wiki needs special consideration because it holds the components that are shared by or affect the operation of all the wikis in the farm. In particular:%0a*the ''scripts/'' directory%0a*the ''cookbook/'' directory%0a*the ''pub/'' directory%0a*the ''wikilib.d/'' directory%0a%0a%0aIt is possible to move the PmWiki software outside of the web document tree, but the ''pub/'' directory needs to be in a web-servable directory (one that can be accessed by a URL).%0a%0aAuthors writing about complex farm setups often have difficulty describing the components and their locations. However, it is probably not necessary or desirable to coin new terms for the components and their locations.%0a%0a%0a!! [[#suggested_terms]] Suggested terms%0a%0a:WikiFarm: An installation where one copy of PmWiki is configured to run multiple wikis. Analogous to the computing phrase "server farm". The wikis in a farm can be configured farm-wide (using the farm's ''local/farmconfig.php'') or individually (using the wiki's ''local/config.php'').%0a:Wiki: A site with it's own URL and ''wiki.d/'' directory. All of the wikis in a wiki farm are simply called wikis.%0a:Home wiki:A wiki in a farm that's located in the same directory as the PmWiki software and therefore shares the farm's ''cookbook/'' and ''pub/'' directories. If you start with a stand-alone installation and add a wiki, the original wiki becomes a home wiki.%0a:Farm-wide: Something available to or affecting all wikis in the farm. Typically this means modifying the ''farmconfig.php'' file or the contents of the farm's cookbook/ or pub/ directories.%0a:Local: Something available to or affecting a specific wiki. Typically this means modifying the wiki's ''local/config.php'' file or the contents of the wiki's ''cookbook/'' or ''pub/'' directories.%0a%0a:PmWiki {-engine-} : The software that makes PmWiki work, as opposed to the content of the wiki that readers see.%0a:PmWiki {-installation-} directory: The directory PmWiki is installed to. It contains pmwiki.php and its subdirectory scripts/, which is used by all the wikis in the WikiFarm. {-If you do a standard, single install of PmWiki, it goes into this directory.-}%0a%0a%0a!!Ambiguous terms%0a%0a:Installation directory: Installation of what? Some authors have used this to mean the directory that contains most of the shared components on a wiki farm. Others use it to mean a directory that has a complete standalone installation of PmWiki that is not part of a farm. Use PmWiki directory instead.%0a:PmWiki installation: This is sometimes used to indicate a process, sometimes used to mean a single wiki in a farm, and sometimes refers only to the shared components of a farm.%0a%0a%0a!!Deprecated terms that should not be used%0a%0aThese terms still exist in the documentation (pending revisions), and will live forever in the PmWiki-Users list archive.%0a%0a:farm directory: The directory in which the home wiki lives or a directory where the shared components are stored. Use PmWiki directory instead.%0a:field: Any wiki in a farm which is '''not''' the home wiki.%0a:farm administrator: An administrator who has access to all of the wikis in a farm, particularly the home wiki. Use administrator instead.%0a:field administrator: An administrator who has access to one or more wikis in a farm, but '''not''' the home wiki. Use administrator instead.%0a:barn: The place where common components are stored. Use PmWiki directory instead.%0a:crop: Packaged content and customizations that can be added to a wiki. See [[Cookbook:ListOfBundles]] for similar ideas. Use component bundles instead.%0a:tractor: The PmWiki engine or ''pmwiki.php'' itself. Use PmWiki instead.%0a%0a----%0aCategories: [[!WikiFarms]]%0a
+time=1143234494
diff --git a/wikilib.d/PmWiki.WikiFarms b/wikilib.d/PmWiki.WikiFarms
new file mode 100644
index 0000000..b465440
--- /dev/null
+++ b/wikilib.d/PmWiki.WikiFarms
@@ -0,0 +1,12 @@
+version=pmwiki-2.2.5 ordered=1 urlencoded=1
+agent=Midori/0.1.9 (X11; Linux x86_64; U; en-us) WebKit/532+
+author=Petko
+charset=ISO-8859-1
+csum=fix category link for a release
+ctime=1142482306
+host=81.65.12.233
+name=PmWiki.WikiFarms
+rev=78
+targets=PmWiki.WikiFarms,PmWiki.WikiGroup,PmWiki.Installation,PmWiki.LocalCustomizations,PmWiki.WikiFarmTerminology
+text=(:Audience: administrators (intermediate) :)%0a(:Summary:Running multiple wikis from a single installation:)%0aAlso see: [[Cookbook:Farm Setup By Example]], [[Cookbook:Wiki Farm Alternative]]%0a%0aA [[WikiFarm(s)]] is a collection of two or more wikis running on the same web server and sharing a set of common components. The term is based on the computing phrase "server farm".%0a%0aThis page provides some background information about WikiFarms and describes how to turn a "normal" configuration into a farm by adding a wiki. There are many ways to configure wiki farms; this page describes only one, in an effort to make it as simple as possible for the administrator who is creating a farm for the first time.%0a%0a!! Why use a farm?%0aThe primary motivation for using a wiki farm is to reduce the amount of administrative work involved in managing several wikis. In a farm, most of the PmWiki code is stored in one place and is shared by all the wikis. An administrator can (for example) upgrade to a new version of PmWiki on every wiki in the farm by simply updating the shared components in a single location.%0a%0aFrom a reader's point of view, each wiki in a farm is completely independent, and appears as a separate web site. Each wiki in a farm:%0a* has its own URL, and the URLs can be in different domains%0a* can have its own look and feel by using different skins%0a* can have its own add-ons or "recipes" from the [[(Cookbook:)Cookbook(Basics)]]%0a* can have its own administrator responsible for local configuration%0a%0a!! Why not to use a farm%0aBecause the wikis in a farm are all independent, it is difficult (but not impossible) to provide services that require access to more than one wiki. For example, the PmWiki search function can only search within one wiki. Using a farm as a way of subdividing related content is generally a bad idea. A much better way to subdivide content is to use [[(PmWiki:)WikiGroup | WikiGroups]].%0a%0a!! I still can't decide if I need a farm ...%0aThe good news is that you don't have to decide in advance. In fact, the recommended procedure is to first do a "normal" or single [[installation]] of PmWiki. Use it for a while. Create pages and edit them. Get to know how to add recipes. Be sure to try out [[WikiGroup | WikiGroups]] (they may be all you need).%0a%0aOnce you have decided that you need another wiki, you have two basic choices:%0a# Do a complete [[installation]] of PmWiki in a new directory. This gives you two totally independent wikis that are completely self-contained. This is '''not''' a wiki farm.%0a# Create a wiki farm using your existing wiki as the "home wiki" where most of the shared PmWiki components will live.%0a%0aChoice number 1 can be a good choice for several reasons:%0a* it is not a wiki farm, and requires no additional administrative knowledge - it's just two installations%0a* if you decide to move one of the wikis to another server, you can simply copy the wiki directory structure to the second server, and it will work (assuming there is a web server and PHP in place).%0a* you can run different versions of PmWiki on each wiki (good for testing new versions)%0a* no matter how badly you mess up one installation, it doesn't affect the other%0a%0aIf you choose to create a wiki farm, then read on ...%0a%0a!! Prerequisites%0aBefore you create a farm, make sure that:%0a* you have a working installation of PmWiki ready to become the home wiki for your farm%0a* all of the wikis in your farm will be on the same web server%0a* each wiki will have a unique URL, such as http://www.example.com/wiki1/, http://www.example.com/wiki2/, http://another.example.com/wiki1/ and so on.%0a%0a!! Creating the home wiki%0aYou do have a working installation of PmWiki at this point, don't you? That's good, because your existing wiki is about to become the home wiki of your farm.%0a%0aIn the directory that contains your existing wiki, create the file ''local/farmconfig.php''. This file is used to hold any [[local customizations]] that apply across the whole farm. For example, you could assign an admin password in ''farmconfig.php'' that will be used by all of the wikis in your farm.%0a%0aIf the URL used to access your existing wiki is http://www.example.com/pmwiki/ then a minimal ''farmconfig.php'' file would look like this:%0a%0a-> [@%3c?php if (!defined('PmWiki')) exit();%0a$FarmPubDirUrl = 'http://www.example.com/pmwiki/pub';@]%0a%0aThis loads the variable $FarmPubDirUrl with the URL location of your home wiki's ''pub/'' directory. All of the wikis in your farm share this ''pub/'' directory. The ''pub/'' directory holds skin definitions and GUI-edit buttons to be shared by all the wikis in the farm.%0a%0aAmazing as it may sound, this completes all of the changes you need to make in order to turn your existing wiki into the home wiki of your farm.%0a%0a!! Creating an additional wiki in your farm%0a-%3c 1. Create a directory to hold the new wiki. This directory must be web-accessible, just like the directory that holds your home wiki.%0a%0a-%3c 2. Create a file called ''index.php'' in the directory with the following contents:%0a%0a--> [@ %3c?php include('path/to/pmwiki.php'); @]%0a%0a-> This allows your new wiki to share the PmWiki code stored in your home wiki. The ''[@path/to/pmwiki.php@]'' is the file path to ''pmwiki.php'' in your home wiki. Use an absolute file path ([@/home/username/pmwiki/pmwiki.php@]) or a relative file path ([@../pmwiki/pmwiki.php@]). Do not use a url path - there should not be an '[@http://@]' in it anywhere. For a web server running under Windows, you need to use a complete file path as in [@C:/Apache Group/Apache2 /www/mynewwiki/@].%0a%0a-%3c 3. Open a web browser and browse the URL of the new wiki. This will be a web address starting with '[@http://@]'. PmWiki will attempt to automatically create a writable ''wiki.d/'' directory where the wiki's pages will be stored. If you see an error message, follow the instructions. If you choose the option for a "slightly more secure installation" be sure to execute both commands.%0a%0aYour new wiki is now set up, and your farm now contains 2 wikis. To add more wikis, just repeat these 3 steps.%0a%0a%0a!! Customization%0aEach wiki in a farm inherits the settings stored in ''farmconfig.php''. Do any customization that you want to apply farm-wide (to all the wikis) in ''farmconfig.php''.%0a%0aCreate a ''local/'' directory within each wiki's directory to hold [[local customizations]] that apply only to that wiki. You should at least create the local/config.php file with a new title, like so : %0a%0a->[@%0a%3c?php if (!defined('PmWiki')) exit();%0a ## Title of your farmed wiki%0a $WikiTitle = 'New Wiki';%0a?>%0a@]%0a%0aFarm-wide customizations are processed before the individual wiki local customizations.%0a%0aThe PmWiki variable ''$FarmD'' points to the directory in which pmwiki.php is installed, and your home wiki, and it is used as a prefix to allow the other wikis to share PmWiki components. For example:%0a* ''$FarmD/scripts/'' points to the shared ''scripts/'' directory%0a* ''$FarmD/pub/'' points to the shared ''pub/'' directory%0a* ''$FarmD/cookbook/'' points to the shared ''cookbook/'' directory%0a%0aAny [[Cookbook(:.)]] scripts you include in farmconfig.php must be included with a line such as:%0a-> @@include_once("$FarmD/cookbook/scriptfile.php");@@\\%0aNote the double quotes - single quotes may work for per farm inclusions, but they will not work for $FarmD.%0a%0a!! Notes%0a* The terminology used to describe wiki farms is not used consistently. See [[WikiFarmTerminology]] for more info.%0a* It is important to remember that not all of the recipes in the Cookbook have been written for or tested with farms. Be sure to look for instructions on how to use a recipe on a farm.%0a* There are many, many more things you can do with farms. Some are described on [[PmWiki:WikiFarmsAdvanced]] which also contains links to step-by-step examples of setting up a farm.%0a%0a!! Password use/authorization on farm wikis:%0a%0a''' How come when I switch to another wiki within a farm, I keep my same authorization?'''%0a%0aPmWiki uses PHP sessions to keep track of authentication/authorization information, and by default PHP sets things up such that all interactions with the same server are considered part of the same session.%0a%0aAn easy way to fix this is to make sure each wiki is using a different cookie name for its session identifier. Near the top of one of the wiki's local/config.php files, before calling authuser or any other recipes, add a line like:%0a%0a-> @@ session_name('XYZSESSID'); @@%0a%0aYou can pick any alphanumeric name for XYZSESSID; for example, for the cs559-1 wiki you might choose%0a%0a-> @@ session_name('CS559SESSID'); @@%0a%0aThis will keep the two wikis' sessions independent of each other.%0a%0aCategories: [[(http://www.pmwiki.org/wiki/Category)WikiFarms]]%0a%0a
+time=1254657553
diff --git a/wikilib.d/PmWiki.WikiGroup b/wikilib.d/PmWiki.WikiGroup
new file mode 100644
index 0000000..76b980d
--- /dev/null
+++ b/wikilib.d/PmWiki.WikiGroup
@@ -0,0 +1,12 @@
+version=pmwiki-2.2.5 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/530.5 (KHTML, like Gecko) Chrome/2.0.172.43 Safari/530.5
+author=Simon
+charset=ISO-8859-1
+csum=GroupCustomizations
+host=202.37.32.2
+keywords=trailing dot, trailing slash, default group
+name=PmWiki.WikiGroup
+rev=102
+targets=Main.WikiSandbox,Main.HomePage,PmWiki.MailingLists,PmWiki.Links,PmWiki.CreatingNewPages,PmWiki.PmWiki,Site.Site,SiteAdmin.SiteAdmin,PmWiki.Search,PmWiki.WikiGroup,PmWiki.RecentChanges,Site.AllRecentChanges,PmWiki.GroupHeaders,PmWiki.Passwords,PmWiki.WikiAdministrator,PmWiki.LocalCustomizations,PmWiki.GroupCustomizations
+text=(:Audience: authors (basic) :)%0a(:Summary: Organising pages into related groups:)%0a(:keywords trailing dot, trailing slash, default group:)%0aPmWiki pages are organized into groups of related pages. This feature was added to PmWiki to allow authors to create their own ''wiki spaces'' of specialized content on their own, without having to become, or rely on, wiki administrators. See [[http://pmichaud.com/|Pm]]'s [[http://pmichaud.com/pipermail/pmwiki-users/2006-March/024838.html|post]] to the pmwiki-users [[mailing list(s)]].%0a%0aBy default, page [[links]] are between pages of the same group; to create a link to a page in another group, add the name of the other group and a dot or slash to the page name. For example, links to [=Main/WikiSandbox=] could be written as:%0a%0a(:markup class=horiz:)%0a* [[Main.WikiSandbox]]%0a* [[Main/WikiSandbox]]%0a* [[(Main.Wiki)Sandbox]]%0a* [[Main.WikiSandbox | link text]]%0a* [[Main.WikiSandbox | +]]%0a(:markupend:)%0a%0aTo link to the [[#groupdefaultpage | default home page]] of a group, the name of the page can be omitted, like this:%0a%0a(:markup class=horiz:)%0a* [[Main.]]%0a* [[Main/]]%0a(:markupend:)%0a%0a!! Creating groups%0aCreating a new group is as easy as [[creating new pages]]; simply edit an existing page to include a [[link(s)]] to the new group's default home page (or any page in the new group) then click on the '?' to edit the page. As a rule, group names must start with a letter (but this can be changed by the wiki administrator by adding %0a-> @@[@$GroupPattern = '[[:upper:]\\d][\\w]*(?:-\\w+)*';@]@@%0ain config.php).%0a%0aFor example, to make a default page in the group Foo, create a link to [=[[Foo/]]=] (or [=[[Foo.]]=]). %0aTo make a page called Bar in the group Foo, create a link to [=[[Foo/Bar]]=] and follow the link to edit that page.%0a%0a!! Groups in a standard PmWiki distribution%0a* [[Main]]: The default group. On many wikis, it contains most of the author-contributed content. Main.HomePage and Main.WikiSandbox come pre-installed.%0a* [[PmWiki]]: An edit-protected group that contains PmWiki documentation and help pages.%0a* [[Site]]: Holds a variety of utility and configuration pages used by PmWiki, including [[%3c%3c]][=SideBar=], Search, Preferences, Templates, and [=AllRecentChanges=].%0a* [[SiteAdmin/]]: Holds a number of password protected administration and configuration pages used by PmWiki, including [[%3c%3c]] [=ApprovedUrls=], and Blocklist%0a%0a* To list all the groups in a site, try [[PmWiki/Search | searching]] for "[[{$FullName}?action=search&q=fmt%253Dgroup|fmt=group]]".%0a* To list all the pages in a group, try [[PmWiki/Search | searching]] for "[[{$FullName}?action=search&q={$Group}%252F|GroupName/]]".%0a%0a[[#specialpages]]%0a!! [[(PmWiki:)Special Pages]] in a Group%0aBy default, the ''[[Recent Changes]]'' page of each group shows only the pages that have changed within that group; the ''[[Site.All Recent Changes]]'' page shows all pages that have changed in all groups.%0a%0aEach group can also have ''[[Group Header(s)]]'' or ''Group Footer'' pages that contain text to be automatically prepended or appended to every page in the group. A group can also have a ''Group Attributes ''page that defines attributes (read and edit passwords) shared by all pages within the group. %0a%0aEach page can also have its own individual read/edit password that overrides the group passwords (see [[Passwords]]).%0a%0aFinally, [[wiki administrator]]s can set [[local customizations]] on a per-group basis--see [[Group Customizations]].%0a%0a[[#groupdefaultpage]]%0a!! Group's default page%0a%0aThe default "start page" for a group is a page whose name is: %0a# the same as the group (Foo/Foo)%0a# HomePage (Foo/HomePage)%0a# a name that the administrator has assigned to the [={$DefaultName}=] variable in the configuration.php file. %0a%0aNote, on this site, the value of [={$DefaultName}=] is ''{$DefaultName}'' and, thus, the default home page would be Foo/{$DefaultName}. %0a%0aYou can usefully change the default ''search'' order for an entered page name by setting the variable @@$PagePathFmt @@ in @@config.php@@, eg%0a-> @@ $PagePathFmt = array('$Group.$1', '$1.$DefaultName', '$1.$1', '$DefaultGroup.$1', 'Profiles.$1'); @@%0awhere "$1" is the name of the page entered. %0a%0aAs noted above, when linking to the default home page, authors can omit the page name and simply identify the group followed by a forward slash ([=[[Foo/]]=]).%0a%0aNote the forward slash is required to ensure that the link unambiguously points to the identified group. %0aIf the slash is omitted, the link can end up being interpreted as pointing to an existing (or new) page in the current group (if the group, or its default home page, do not exist). %0a%0a!! Subgroups? Subpages?%0aNo, PmWiki does not have subpages. Pm's reasons for not having subgroups are described at [[PmWiki:Hierarchical Groups]], but it comes down to not having a good page linking syntax. If you create a link or pagename like [@[[A.B.C]]@] PmWiki doesn't think of "B.C" as being in group "A", it instead thinks of "C" as being in group "AB", which is a separate group from "A". Wiki administrators can look at [[Cookbook:Subgroup Markup]] and [[Cookbook:Include With Edit]] for recipes that may be of some help with developing subgroups or subpages.%0a%0a!! Restricting the creation of new groups%0aYou can set PmWiki's $GroupPattern variable to only accept the group names you want to define. For example, to limit pages to the "PmWiki", "Main", "Profiles", and "Example" groups, add the following to local/config.php:%0a%0a-> $GroupPattern = '(?:Site|SiteAdmin|PmWiki|Main|Profiles|Example)';%0a%0aWith this setting, only the listed groups will be considered valid WikiGroups. You can add more groups to the list by placing additional group names separated by pipes (|).%0a%0aSee other solutions to this at [[Cookbook:Limit Wiki Groups]] and [[Cookbook:New Group Warning]].%0a%0a>>faq%3c%3c [[#faq]]%0aQ: How can I get rid of the 'Main' group in urls for pages pointing to Main?%0a%0aA: See [[Cookbook:Get Rid Of Main]].%0a%0aQ: How can I limit the creation of new groups?%0a%0aA: See [[Cookbook:Limit Wiki Groups]].%0a%0aQ: Why doesn't [=[[St. Giles and St. James]]=] work as a link? (It doesn't display anything.)%0a%0aA: Because it contains periods, and destroys PmWiki's file structure, which saves pages as [=Group.PageName=]. Adding those periods disrupts this format. Links may only contain words. If you need a link precisely as shown, the page must be named eg StGilesAndStJames then you can use the [=(:title:)=] directive to have the page's title appear with periods [=(:title St. Giles and St. James:)=]. (Although modern US and UK grammar now tend to drop the period to simplify style).%0a%0aQ: How can I delete a wiki group?%0a%0aA: Normally you can't, as this requires an admin with server-side access to delete the file that makes up the group's RecentChanges page. But there is an option method of making it possible to delete RecentChanges pages from within the wiki if the admin enables the code found on [[Cookbook:RecentChanges Deletion]].%0a%0aQ: How can I delete a wiki group's Group.RecentChanges page?%0a%0aA: Normally you can't, as this requires an admin with server-side access to delete a file. But there is an optional method of making it possible to delete RecentChanges pages from within the wiki if the admin enables the code found on [[Cookbook:RecentChanges Deletion]].%0a
+time=1251406827
diff --git a/wikilib.d/PmWiki.WikiGroups b/wikilib.d/PmWiki.WikiGroups
new file mode 100644
index 0000000..bedd048
--- /dev/null
+++ b/wikilib.d/PmWiki.WikiGroups
@@ -0,0 +1,11 @@
+version=pmwiki-2.2.0-beta62 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.1) Gecko/20061204 Firefox/2.0.0.1
+author=simon
+charset=ISO-8859-1
+csum=Add summary
+host=202.37.32.2
+name=PmWiki.WikiGroups
+rev=4
+targets=
+text=(:Summary: Redirects to [[PmWiki/Wiki Group]]:)%0a(:redirect PmWiki/WikiGroup:)
+time=1185140280
diff --git a/wikilib.d/PmWiki.WikiPage b/wikilib.d/PmWiki.WikiPage
new file mode 100644
index 0000000..29cf3ab
--- /dev/null
+++ b/wikilib.d/PmWiki.WikiPage
@@ -0,0 +1,12 @@
+version=pmwiki-2.2.1 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.19) Gecko/20081216 Ubuntu/8.04 (hardy) Firefox/2.0.0.19
+author=Petko
+charset=ISO-8859-1
+csum=fix link
+host=81.65.14.164
+name=PmWiki.WikiPage
+post= Save
+rev=17
+targets=PmWiki.WikiStructure,PmWiki.WikiWikiWeb,PmWiki.PageFileFormat
+text=(:Summary: Wiki page information:)%0aA WikiPage is simply the basic building block of a WikiWikiWeb that contains text and images. See [[WikiStructure]]s and [[WikiWikiWeb]] for more information.%0a%0aWiki pages can have an edit template to predefine initial content, see [[Cookbook:Edit Templates]] [-{Cookbook/EditTemplates$:Summary}-]%0a%0aWiki pages are stored in individual flat files, see [[PmWiki/Page File Format]] and [[(PmWiki:)Flat File Advantages]].%0a%0a%0a%0a%0a
+time=1238276180
diff --git a/wikilib.d/PmWiki.WikiSandbox b/wikilib.d/PmWiki.WikiSandbox
new file mode 100644
index 0000000..fd877c9
--- /dev/null
+++ b/wikilib.d/PmWiki.WikiSandbox
@@ -0,0 +1,11 @@
+version=pmwiki-2.2.0 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.19) Gecko/20081216 Ubuntu/8.04 (hardy) Firefox/2.0.0.19
+author=Petko
+charset=ISO-8859-1
+csum=revert sandbox
+host=81.65.14.164
+name=PmWiki.WikiSandbox
+rev=7
+targets=
+text=(:redirect Main.WikiSandbox:)%0a
+time=1237078663
diff --git a/wikilib.d/PmWiki.WikiStructure b/wikilib.d/PmWiki.WikiStructure
new file mode 100644
index 0000000..e5be3ef
--- /dev/null
+++ b/wikilib.d/PmWiki.WikiStructure
@@ -0,0 +1,12 @@
+version=pmwiki-2.2.0 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.19) Gecko/20081216 Ubuntu/8.04 (hardy) Firefox/2.0.0.19
+author=Petko
+charset=ISO-8859-1
+csum=refactored
+host=81.65.14.164
+name=PmWiki.WikiStructure
+post= Save
+rev=38
+targets=PmWiki.WikiPage,PmWiki.WikiWord,PmWiki.Links,PmWiki.WikiGroup,PmWiki.WikiTrails,PmWiki.Categories,PmWiki.PageTextVariables,PmWiki.PageLists,Site.PageListTemplates,PmWiki.IncludeOtherPages,PmWiki.Search
+text=(:Summary: PmWiki structural support for page organization:)%0aAuthors have a range of options to choose from when organizing a collection of [[wiki page]]s. %0aUsed in combination, these give a lot of flexibility.%0aAn effective wiki will use all of these to optimize%0a* content%0a* navigation%0aThese are the two most important aspects of a website.%0a%0a:[[Wiki Word]]: The most powerful organizing principle is the author's choice of page names. When a search returns a list of pages, their names need to be clear enough to guide a visitor to the right place.%0a: : Providing a network of [[PmWiki/links]] to other points in the wiki, with or without wiki words, is the primary means of navigating a wiki.%0a%0a:[[Wiki Page]]: A page with text (and images), where the text can contain for instance [[WikiWord]]s that automatically becomes a link to another WikiPage.%0a%0a:[[Wiki Group]]: PmWiki requires every page to be a member of a group. A group is like a wiki within a wiki; it can have its own presentation look, security controls and navigation aids. With default configuration, [[WikiWord]]s are only searched inside the current group, and you use either [@OtherGroup/MyWikiWord@] or [@OtherGroup.MyWikiWord@] to refer to pages in other groups (see [[Links]]).%0a%0a:[[Wiki Trails]]: A collection of pages, either in the same group or across multiple groups, can be designated as a trail. A visitor can move from stop to stop by clicking on ''next'' and ''previous'' links.%0a%0a:[[Categories]]: Individual wiki pages can also be grouped by having tags and links to a common "category" page; we say that any pages that link to a common page are in a "category" defined by that page. PmWiki uses the [@[[!category]]@] markup as a shorthand to place a page into a category with other pages containing the same markup.%0a: : The shortcoming of categories is that categories do not distinguish between the declaration of a category ([=[[!structure]]=]) and the link to a category ([=[[Category/Structure]]=]).%0a%0a:[[Page text variables]]: A newer and more powerful concept than [[Categories]], pages can use one of more [[page text variables]] to store page attributes. These can the be used in [[page lists]].%0a%0a:[[Page lists]]: Page lists provide a powerful means of presenting lists of relevant pages, or selection of data from within a page. Lists are [[Site/PageListTemplates|template]] based and are highly customizable.%0a%0a:[[Include other pages]]: The capability to include parts of other pages also provides a flexible means of sharing content between pages.%0a%0a:[[Search]]: Being able to search is a fundamental requirement of a website. In PmWiki search, like pagelists is both powerful and highly customizable.%0a
+time=1237078922
diff --git a/wikilib.d/PmWiki.WikiStyleExamples b/wikilib.d/PmWiki.WikiStyleExamples
new file mode 100644
index 0000000..47e28b3
--- /dev/null
+++ b/wikilib.d/PmWiki.WikiStyleExamples
@@ -0,0 +1,11 @@
+version=pmwiki-2.2.1 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.19) Gecko/20081216 Ubuntu/8.04 (hardy) Firefox/2.0.0.19
+author=Petko
+charset=ISO-8859-1
+csum=fix link
+host=81.65.14.164
+name=PmWiki.WikiStyleExamples
+rev=181
+targets=PmWiki.WikiStyles
+text=(:Summary: Styling text for colour and other attributes:)%0aSee also [[Cookbook:WikiStylesPlus | Wiki Styles Plus]] and [[(PmWiki:)Wiki style colors]].%0a%0aPmWiki uses [[WikiStyles]] for styling text with color and other attributes. PmWiki 2.0 introduced the ability to control the styling further and to even place styles on blocks.%0a%0aA style is specified within a pair of %25-signs and styles the text that follows, as in:%0a%0a(:markup class=horiz:)%0aThis text is %25color=red%25 red, %25color=blue%25 blue, %25%25 and normal (black).%0a(:markupend:)%0a%0aThere are a wide number of available style properties, borrowed primarily from HTML and CSS. In addition, an author can define a style "shortcut" by using the [@define=@] property. For example, to define a style of [@%25red%25@], one can use:%0a%0a(:markup class=horiz:)%0a%25define=mystyle color=red%25%0aHere is some %25mystyle%25 red text created using a style shortcut.%0a(:markupend:)%0a%0aShortcuts can be combined with other styles, including other shortcuts:%0a%0a(:markup class=horiz:)%0a%25define=lovelyred color=red%25%0a%25define=likegrapefruit bgcolor=yellow%25%0a%0a%25red%25 This text is red, %25red bgcolor=#ccc%25 red on a grey background, and %25lovelyred likegrapefruit%25 red on a yellow background. %0a(:markupend:)%0a%0aSo far, this is all basically the same as what was available in PmWiki 1.0. PmWiki 2.0 includes the capability to style blocks, by using the [@apply=@] style property. Specifying [@apply=block@] in a `WikiStyle will cause that style to be applied to the entire block, instead of just the text that follows:%0a%0a(:markup:)%0aThis entire block %25apply=block bgcolor=yellow%25 has a yellow background, even though the `WikiStyle appears in the middle of the line. %25bgcolor=pink%25 Other inline (non-block) WikiStyles can appear in the middle of the line,%25%25 as before.%0a(:markupend:)%0a%0aThis means it's now possible to do right-aligned and centered text:%0a%0a(:markup:)%0a%25block text-align=right%25 The text of this paragraph is right-aligned. %0a%0a%25block text-align=center%25 The text of this paragraph is centered. %0a(:markupend:)%0a%0a%0aIn fact, PmWiki predefines [@%25right%25@] and [@%25center%25@] style shortcuts so that you can do this more simply:%0a%0a(:markup class=horiz:)%0a%25right%25 This is right-aligned.%0a%0a%25center%25 This is centered.%0a(:markupend:)%0a%0aAuthors can define their own custom styles:%0a%0a(:markup:)%0a%25define=Pm block bgcolor=#fdf%25%0a%25define=goofy center bgcolor=#dfd border='3px dotted green'%25%0a%25define=rediguana right bgcolor=#ffffcc border='1px dotted red' padding=5px%25%0a%25define=strike text-decoration=line-through%25%0a%0a%25Pm%25 Any text that is on a light purple background is a comment from "Pm".%0a%0a%25goofy%25 Here's some text from Goofy.%0a%0a%25rediguana%25 bla bla by rediguana!%0a%0a%25goofy%25Hello, I am %25strike%25upset%25%25 %25strike%25disheartened%25%25 happy to meet you.%0a(:markupend:)%0a%0aStyles can be applied to almost any kind of block:%0a%0a(:markup class=horiz:)%0a* %25block bgcolor=yellow%25 Here is a list item%0a* Here's another list item%0a%0a* Here's more of a list%0a%0a# A new list%0a(:markupend:)%0a%0aIn particular, this means that outlines are now possible using the predefined [@%25ROMAN%25@], [@%25roman%25@], [@%25ALPHA%25@], and [@%25alpha%25@] list-block styles. The style has to be specified on the first item in the list (and we may develop an alternate syntax for this sort of ordered list):%0a%0a(:markup class=horiz:)%0a# %25ROMAN%25 Top level%0a## %25ALPHA%25 second-level%0a## second-level%0a## second-level%0a### third-level%0a### third-level%0a## second-level%0a### third-level%0a#### %25alpha%25 fourth-level%0a##### %25roman%25 fifth-level%0a##### fifth-level%0a#### fourth-level%0a# top-level%0a# top-level%0a(:markupend:)%0a%0a[[Wiki styles]] can be combined with CSS stylesheets to do this automatically -- see [[Cookbook:OutlineLists]].%0a%0a%0a!! Q & A%0a%0a!!! How do I get a block of preformatted text?%0a%0aUse something similar to this (assuming you want markup within the block to be interpreted as wiki markup and URIs to be recognized).%0a%0a(:markup:)%0a>>white-space=pre%3c%3c%0aThis block of text is ''preformatted'', see all the white-space%0aand linebreaks%0aare preserved. Links such as [[wiki styles]] etc still work.%0a>>%3c%3c%0a(:markupend:)%0a%0a!!! How do I get a block of preformatted text with a colored background and a border?%0a%0aUse something similar to this (note that wiki markup etc is not recognized within the block):%0a%0a(:markup:)%0a%25block bgcolor=#f0f9ff border='1px solid gray' padding=5px%25[@%0aip access-list extended example-acl%0aremark ** This is an example acl **%0adeny ip any host 10.0.0.1%0apermit ip any any%0a@]%0a(:markupend:)%0a%0a!!! How do I get a block of text (including wiki markup) with a colored background and a border?%0a(:markup class=horiz:)%0a>>teal background-color:silver border:'medium dotted green'%3c%3c%0aHello world%0a* bullet%0a# number%0a>>%3c%3c%0a(:markupend:)%0a%0a!!! How do I get a block of text (including wiki markup) with a border that is indented on the left and does NOT extend all the way to right? I'm not interested in having later text to the right as would occur with lfloat...%0a%0aYou can use the @@indent lframe@@ class and follow the block by a forced line break [=[[%3c%3c]]=].%0a%0a(:markup class=horiz:)%0aBefore indention...%0a>>indent lframe%3c%3c%0aHello world%0a* bullet%0a# number%0a>>%3c%3c%0a[[%3c%3c]]%0a... after indention!%0a(:markupend:)
+time=1238271815
diff --git a/wikilib.d/PmWiki.WikiStyles b/wikilib.d/PmWiki.WikiStyles
new file mode 100644
index 0000000..a887f17
--- /dev/null
+++ b/wikilib.d/PmWiki.WikiStyles
@@ -0,0 +1,12 @@
+version=pmwiki-2.2.10 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.7) Gecko/20100106 Ubuntu/9.10 (karmic) Firefox/3.5.7
+author=Petko
+charset=ISO-8859-1
+csum=fix link
+host=81.65.12.233
+name=PmWiki.WikiStyles
+post= Save
+rev=183
+targets=PmWiki.WikiStyles,PmWiki.WikiWord,PmWiki.WikiStyleColors,PmWiki.Tables,PmWiki.TableDirectives,PmWiki.GroupHeaders,PmWiki.WikiAdministrator,PmWiki.LocalCustomizations,PmWiki.CustomWikiStyles,Cookbook.OutlineLists,PmWiki.WikiStyleExamples,PmWiki.TextFormattingRules,PmWiki.ListStyles,Cookbook.WikiStylesPlus
+text=(:Summary: Modifying the style of page contents:)%0a(:div class='rfloat frame' style='clear:right; font-size:small;':)%0a'''Contents'''%0a*[[#Basics|Basics]]%0a*[[#Scopes|Scopes]]%0a*[[#Blocks|In tables and directives]]%0a*[[#Attributes|Attributes]]%0a*[[#Styles|Enabling Styles]]%0a*[[#Shortcuts|Custom style shortcuts]]%0a*[[#predefined|Predefined Style Shortcuts]]%0a*[[#Examples|Examples]]%0a*[[#KnownIssues|Known Issues]]%0a*[[#SeeAlso|See Also]]%0a(:divend:)%0a(:Audience: authors (basic) :)%0a%0a[[#Basics]]%0a!! Wiki style basics%0a%0a[[Wiki styles]] allow authors to modify the color and other styling attributes of a page's contents. %0aA wikistyle is written using percent-signs, as in %25red%25[@%25red%25@]%25%25 or %25bgcolor=lightblue%25[@%25bgcolor=lightblue%25@]%25%25.%0a%0a!!! Text color and font%0aThe most basic use of wiki styles is to change text attributes such as color, background color, and font. %0aPmWiki defines several wikistyles for changing the text color to [=%25black%25, %25white%25, %25red%25, %25yellow%25, %25blue%25, %25gray%25, %25silver%25, %25maroon%25, %25green%25, %25navy%25, and %25purple%25=].%0a%0a(:markup class=horiz:)%0aThe basket contains %25red%25 apples, %25blue%25 blueberries, %25purple%25 eggplant, %25green%25 limes, %25%25 and more.%0a(:markupend:)%0a%0aFor colors other than the predefined colors, use the [@%25color=...%25@] wikistyle. (Note: RGB colors (#rrggbb) should always be specified with lowercase letters to avoid [[WikiWord]] conflicts.)%0a%0a(:markup class=horiz:)%0aI'd like to have some %25color=#ff7f00%25 tangerines%25%25, too!%0a(:markupend:)%0a%0aTo change the background color, use [@%25bgcolor=...%25@] as a wikistyle:%0a%0a%0a(:markup class=horiz:)%0aThis sentence contains %25bgcolor=green yellow%25 yellow text on a green background.%0a(:markupend:)%0a%0aSee [[(PmWiki:)Wiki Style Colors]] for more color help.%0a%0a!!!Text justification%0aStyles are used to control the text justification%0a%0a(:markup class=horiz:)%0a%25center%25 This text is centered. %0a%0a%25right%25 Right justified.%0a(:markupend:)%0a%0aand to create floating text:%0a%0a(:markup class=horiz:)%0a%25rfloat%25 This text floats to the right%0a%0a%25rframe%25 floats to the right with a frame%0a%0aLorem ipsum dolor sit amet, consectetuer sadipscing elitr%0a(:markupend:)%0a%0a%0a[[#Scopes]]%0a!! Scopes%0a%0aWikistyles can also specify a ''scope''; with no scope, the style is applied to any text that follows up to the next wikistyle specification or the end of the paragraph, whichever comes first. The '''apply=''' attribute and its shortcuts allow to change the scope as follows:%0a%0a||border=1 cellpadding=3 cellspacing=0%0a||apply attribute ||shortcut ||style applies to... ||%0a||[@%25apply=img ...%25@] ||- ||any image that ''follows''||%0a||[@%25apply=p ...%25@] ||[@%25p ...%25@] ||the current paragraph||%0a||[@%25apply=pre ...%25@] ||- ||the current preformatted text||%0a||[@%25apply=list ...%25@] ||[@%25list ...%25@] ||the current list||%0a||[@%25apply=item ...%25@] ||[@%25item ...%25@] ||the current list item||%0a||[@%25apply=div ...%25@] ||- ||the current div||%0a||[@%25apply=block ...%25@] ||[@%25block ...%25@] ||to the current block, whether it's a paragraph, list, list item, heading, or division.||%0a%0athus '''[@%25p color=blue%25@]''' is the same as '''[@%25apply=p color=blue%25@]''', and '''[@%25list ROMAN%25@]''' is the same as '''[@%25apply=list list-style=upper-roman%25@]'''.%0a%0aSome [[#predefined|predefined style shortcuts]] also make use of apply, thus '''[@%25right%25@]''' is a shortcut for '''[@%25text-align=right apply=block%25@]'''.%0a%0aExample: Apply a style to a paragraph:%0a(:markup:)%0a%25p bgcolor=#ffeeee%25 The wikistyle specification at the beginning of this line applies to the entire paragraph, even if there are %25blue%25 other wikistyle specifications %25%25 in the middle of the paragraph.%0a(:markupend:)%0a%0a%0a'''Caveat''': An applied wikistyle will only take effect if it's on the%0aline that starts the thing it's supposed to modify. In other%0awords, a wikistyle in the third markup line of a paragraph%0acan't change the attributes of the paragraph:%0a%0a(:markup class=horiz:) %0aafter the first line of the paragraph,%0awe try to %25apply=p color=blue%25 change color.%0aThis does't work because the style comes%0a(:markupend:)%0a%0a(:markup class=horiz:)%0aHowever, this %25p color=red%25 paragraph%0a''will'' be in red because its block style does%0aoccur in the first line of its text.%0a(:markupend:)%0a%0a(:markup class=horiz:) %0a* Here's a list item%0a* %25list red%25 Oops, too late to affect the list!%0a(:markupend:)%0a%0a[[#blocks]]%0a!! Wiki style syntax for tables and directives%0aWiki styles can also be applied to [[PmWiki/tables]] and [[PmWiki/table directives]].%0aUnfortunately the syntax is inconnsistent, so you will have to experiment to get the result you require.%0a(:markup class=horiz:)%0a||class="green" style="font-style:italic; border:1px solid blue; background-color:#ffffcc"%0a||Everything after the above line is styled with green italic text, ||%0a|| ||%0a||This includes ||%0a|| preformatted text ||%0a||* lists ||%0a||-> indented items ||%0a(:markupend:)%0a%0a(:markup class=horiz:)%0a(:table class="green" style="font-style:italic; border:1px solid blue; background-color:#ffffcc":)%0a(:cellnr:)%0aEverything after the above line is styled with green italic text,%0a%0aThis includes%0a preformatted text%0a* lists%0a-> indented items%0a(:tableend:)%0a(:markupend:)%0a%0a%0aThe '''[@>>style%3c%3c@]''' block can be used to apply a wikistyle to a large block of items. %0aThe style is applied until the next [@>>%3c%3c@] is encountered.%0a%0a(:markup class=horiz:)%0a>>blue font-style:italic bgcolor=#ffffcc%3c%3c%0aEverything after the above line is styled with blue italic text,%0a%0aThis includes%0a preformatted text%0a* lists%0a-> indented items%0a>>%3c%3c%0a(:markupend:)%0a%0aThe '''[@(:div style:)@]''' works in ''almost'' the same way as [@>>style%3c%3c@],%0abut the style information is encapsulated in a @@style=""@@ attribute and nested div blocks are possible.%0a(:markup class=horiz:)%0a(:div class="green" style="font-style:italic; border:1px solid blue; background-color:#ffffcc":)%0aEverything after the above line is styled with green italic text,%0a%0aThis includes%0a preformatted text%0a* lists%0a-> indented items%0a(:divend:)%0a(:markupend:)%0a%0a(:markup class=horiz:)%0a(:div1 style="font-style:italic; background-color:#ffffcc":)%0aouter style%0a(:div2 style="color:red; background-color:lightblue":)%0anested style%0a(:div2end:)%0aagain outer style%0a(:div1end:)%0a(:markupend:)%0a%0a%0a[[#Attributes]]%0a!! Wikistyle attributes%0a%0aThe style attributes recognized within a wikistyle specification are:%0a%0a ------------ CSS ------------- --HTML--%0a color bgcolor class %0a background-color margin id%0a text-align padding hspace%0a text-decoration border vspace%0a font-size float target%0a font-family list-style rel%0a font-weight width[[#fn|*]] accesskey%0a font-style height[[#fn|*]] value%0a display%0a%0a Special: define, apply%0a%0aThe attributes in the first two columns correspond to the ''[[cascading style sheet -> http://blooberry.com/indexdot/css/propindex/all.htm]]'' (CSS) properties of the same name. The attributes in the last column apply only to specific items:%0a%0a* '''[@class=@]''' and '''[@id=@]''' assign a CSS class or identifier to an HTML element%0a* '''[@target=name@]''' opens links that follow in a browser window called "name"%0a* '''[@rel=name@]''' in a link identifies the relationship of a target page%0a* '''[@accesskey=x@]''' uses 'x' as a shortcut key for the link that follows%0a* '''[@value=9@]''' sets the number of the current ordered list item%0a%0a-%3c[[#fn]][=*=] The width and height attributes have asterisks because they are handled specially for %3cimg .../> tags. If used by themselves (i.e., without anything providing an "apply=" parameter to the wikistyle), then they set the 'width=' and 'height=' attributes of any %3cimg ... /> tags that follow. Otherwise, they set the 'width:' and 'height:' properties of the element being styled.%0a%0a[[#Styles]]%0a!! Enabling Styles%0aStyles not listed above can be enabled by a PmWiki Administrator by modifying the local/config.php file. %0aFor instance to enable the "line-height" style attribute add the line %0a%0a->$WikiStyleCSS[] = 'line-height';%0a%0ato the local/config.php file.%0a%0a[[#Shortcuts]]%0a!! Custom style shortcuts%0a%0aThe '''[@define=@]''' attribute can be used to assign a shorthand name to any wikistyle specification.\\ %0aThis shorthand name can then be reused in later wikistyle specifications.%0a%0a(:markup class=horiz:)%0a%25define=box block bgcolor=#ddddff border="2px dotted blue"%25%0a%0a%25box%25 [@some sort of text@]%0a%0a%25box font-weight=bold color=green%25 [@some sort of text@]%0a(:markupend:)%0a%0a-%3c '''Tip:''' It's often a good idea to put common style definitions into [[Group Header(s)]] pages so that they can be shared among multiple pages in a group. Or, the [[wiki administrator]] can predefine styles site-wide as a [[local customization(s)]] (see [[Custom Wiki Styles]]).%0a%0a-%3c '''Tip:''' Use custom style definitions to associate meanings with text instead of just colors. For example, if warnings are to be displayed as green text, set [@%25define=warn green%25@] and then use [@%25warn%25@] instead of [@%25green%25@] in the document. Then, if you later decide that warnings should be styled differently, it's much easier to change the (one) definition than many occurrences of [@%25green%25@] in the text.%0a%0a-%3c '''Tip:''' Any undefined WikiStyle is automatically treated as a request for a class, thus [@%25pre%25@] is the same as saying [@%25class=pre%25@].%0a%0a!![[#predefined]] Predefined style shortcuts%0a%0aPmWiki defines a number of style shortcuts.%0a%0a* Text colors: %25black%25black%25%25, %25white bgcolor=black%25white%25%25, %25red%25red%25%25, %25yellow%25yellow%25%25, %25blue%25blue%25%25, %25gray%25gray%25%25, %25silver%25silver%25%25, %25maroon%25maroon%25%25, %25green%25green%25%25, %25navy%25navy%25%25, %25purple%25purple%25%25 (shortcut for [@%25color=...%25@])%0a* Justification: [@%25center%25@] and [@%25right%25@]%0a* Images and boxes%0a** Floating left or right: [@%25rfloat%25@] and [@%25lfloat%25@]%0a** Framed items: [@%25frame%25@], [@%25rframe%25@], and [@%25lframe%25@]%0a** Thumbnail sizing: [@%25thumb%25@]%0a* Open link in new window: [@%25newwin%25@] (shortcut for [@%25target=_blank%25@])%0a* Comments: [@%25comment%25@] (shortcut for [@%25display=none%25@])%0a* Ordered lists: [@%25decimal%25@], [@%25roman%25@], [@%25ROMAN%25@], [@%25alpha%25@], [@%25ALPHA%25@] (see also Cookbook:OutlineLists)%0a%0a[[#Examples]]%0a!! Examples%0a%0a[[Wiki Style Examples]] contains a number of examples of ways to use wikistyles in pages.%0a%0a[[#KnownIssues]]%0a!! Known Issues%0a* Percents in style definitions (like: [@%25block width=50%25 %25@]) require the use of "pct" instead of "%25".%0a* If you specify multiple values for an attribute, like @@border="2px solid blue"@@ make sure you place the values in quotes.%0a* Be sure to use lowercase letters for red-green-blue hex colors, [@%25color=#aa3333%25@] will work, [@%25color=#AA3333%25@] may not.%0a%0a[[#SeeAlso]]%0a!!See Also%0a* [[PmWiki/Custom Wiki Styles]] {PmWiki/CustomWikiStyles$:Summary}%0a* [[PmWiki:List Styles]] {PmWiki/ListStyles$:Summary}%0a* [[Cookbook:WikiStylesPlus | WikiStylesPlus]] {Cookbook.WikiStylesPlus$:Summary}%0a%0a>>faq%3c%3c [[#faq]]%0aQ: %0aA:%0a
+time=1265570127
diff --git a/wikilib.d/PmWiki.WikiTrails b/wikilib.d/PmWiki.WikiTrails
new file mode 100644
index 0000000..139afc1
--- /dev/null
+++ b/wikilib.d/PmWiki.WikiTrails
@@ -0,0 +1,11 @@
+version=pmwiki-2.2.7 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.19) Gecko/20081216 Ubuntu/8.04 (hardy) Firefox/2.0.0.19
+author=Petko
+charset=ISO-8859-1
+csum=fix intermap link
+host=81.65.12.233
+name=PmWiki.WikiTrails
+rev=162
+targets=PmWiki.PageLists,PmWiki.Links,PmWiki.Installation,PmWiki.LocalCustomizations,PmWiki.PmWiki,PmWiki.PmWikiPhilosophy,PmWiki.WikiStyles,PmWiki.Uploads,PmWiki.InterMap,PmWiki.TextFormattingRules,PmWiki.DesignNotes,PmWiki.Security,PmWiki.Troubleshooting,PmWiki.GroupHeaders,PmWiki.FullName,PmWiki.WebFeeds
+text=(:Summary: Trails from lists items from a single page:)%0a(:div class="rfloat frame" style="font-size:smaller; clear:right;" :)%0a!! Table of contents%0a* [[#creating | Creating a trail]]%0a* [[#types | Types of trail]]%0a* [[#linksyntax | Trail link syntax]]%0a* [[#using | Using a trail]]%0a** [[#pathtrail | Path trail]]%0a** [[#circular-trails | Circular trail]]%0a* [[#crossgroup | Cross group trails]]%0a* [[#trailstyle | Trail style]]%0a* [[#trailpagelists | Trail page lists]]%0a(:divend:)%0a(:Audience: authors (basic) :)%0aThe WikiTrails feature allows wiki authors to create "trails" through sequences of pages in the wiki. You simply specify pages and their order on a "trail index", and then place the navigation markup on the pages that you will be navigating. %0a%0a(Don't confuse the [[PmWiki/PageLists|pagelist]] directive with WikiTrails - they are different animals as explained in the [[#faq|Q and A]] below.)%0a%0a[[#creating]]%0a!! Creating a trail%0a%0aBefore you can use a trail through a group of pages, you have to create a "trail index" on a separate page, which we will call the "trail index page". %0aOn that trail index page, you simply create a numbered or bulleted [[PmWiki:ListStyles|list]] of links. (So every numbered or bulleted list of links implicitly creates a trail.) %0aIt is important that each page name ([[Links|link]]) be the first item following each bullet; any text or formatting in front of the page name will exclude it from the trail.\\%0aIf you want to format your trail (list), you can [[Cookbook:CSSInWikiPages|include a CSS]].%0a%0aAn example trail index page might contain the list:%0a[[#trailstart]]%0a* [[Installation]] how to install%0a* [[The customisation page->LocalCustomizations]]%0a* [[PmWiki]] some other text [[PmWiki Philosophy]] [-(The latter won't be in the trail because it is preceded by text)-]%0a* Yet some other text. [[PmWiki.WikiStyles]] [-(This won't be in the trail because it follows text)-]%0a* %25center%25[[PmWiki/Uploads]] [-(This won't be in the trail because it is preceded by the [=%25center%25=] style.)-]%0a%0a* Some text [-(This won't be in the trail because it is not a link)-]%0a* [[PmWiki/PageLists]] {PmWiki/PageLists$:Summary}%0a* [[http://pmwiki.org]] [-(This won't be in the trail because it is not a page link)-]%0a** [[PmWiki:InterMap]] [-(This won't be in the trail because it is an [[InterMap]] link)-]%0a* [[Cookbook:Cookbook]] [-(This won't be in the trail because it is an [[InterMap]] link)-] %0a: [[PmWiki philosophy]] : [[Design notes]] [-(The first link will, and the second link won't, be in the trail defined by ([[TextFormattingRules#DefinitionLists | definition list]]))-]%0a* [[#security]][[Security]] [-(This won't be in the trail because its preceded by a (hidden) [[Links#anchors | anchor]])-]%0a* %25newwin%25[[Links]] [-(This won't be in the trail because its preceded by a (hidden) [=%25newwin%25=] style)-]%0a* ''[[PmWiki/Troubleshooting]]'' [-(This won't be in the trail because its preceded by (hidden) ''italic'' style markup)-]%0a[[#trailend]]%0a%0aThe list above creates the following "wikitrail", displayed using a [[PageLists|pagelist]]:%0a(:markup:)%0a(:pagelist trail={$FullName}#trailstart#trailend fmt={$FullName}#traillist:)%0a(:markupend:)%0a%0a!!! Observations%0a%0a# In general, indentation levels in the page list don't matter -- trails are a linear sequence of pages.%0a# A page is part of the trail only if the page link immediately follows the list markup.%0a#The list itself can be [[#linksyntax|delineated]] by the use of [[#list#anchors|anchors]], allowing for multiple lists on a page, or for some list items to be excluded.%0a%0a[[#types]]%0a!! Trail types%0aPmWiki defines 2 trail markups:%0a%0a* '''[@%3c%3c|[[Trail Index Page]]|>>@]''' displays as "[=%3c%3c PreviousPage | Trail Index Page | NextPage >>=]".%0a%0a* '''[@%3c|[[Trail Index Page]]|>@]''' displays as "[=%3c PreviousPage | Trail Index Page | NextPage >=]", except the appropriate arrow is omitted at the beginning and end of the trail.%0a%0a[[#linksyntax]]%0a!! Trail link syntax%0aThe trail link has the same syntax as a standard [[link(s)]], %0athis means for example you can specify %0a* [@%3c|[[TrailIndexPage | +]]|>@]%0a%0aTrail links can be restricted by [[links#anchors|anchors]] (links to a specific location within a page),%0athis means you can have more than one trail on a page, or start a trail from a specific location in a page.%0a* [@%3c|[[Trail Index Page#trailstart#trailend]]|>@]%0a%0a[[#using]]%0a!! Using the trail%0a%0aWhat makes a trail "work" is adding ''trail markup'' on the pages in the trail (i.e. the pages that are listed in the bullet/numbered list on the trail index page).%0a%0aTo build a trail, add ''trail markup'' like [@%3c%3c|[[TrailIndexPage]]|>>@] to a page, where `TrailIndexPage is the page, described above, containing the bulleted list of pages in the trail. PmWiki will display the trail markup with links to any previous and next pages in the trail. %0a%0aThe trail markup can be placed anywhere in a page, and a page can contain multiple trail markups. If you are adding a trail to every page in a group, consider setting the trail markup in the [[Group Headers | GroupHeader]] or GroupFooter pages instead of on every individual page in your group.%0a%0a[[#pathtrail]]%0a!!! Path trail[[#path-trail]]%0a%0a[@^|[[TrailIndexPage]]|^@] treats the list levels as a hierarchy and displays the "path" to reach the current page (i.e., a "breadcrumb" trail). In the example trail above, the markup [@^|TrailIndexPage|^@] on [@TrailPage4@] would display as "[=TrailIndexPage | TrailPage2 | TrailPage4=]".%0a%0aWiki administrators can change the trail separator of the "path" trail ( [@^|[[TrailIndexPage]]|^@] ) from the default | by setting the variable $TrailPathSep in the ''config.php'' file. For instance $TrailPathSep = ' > '; will output "[=TrailIndexPage > TrailPage2 > TrailPage4=]".%0a%0a[[#circular-trails]]%0a!! Circular trails%0a%0aTypically, a trail is a linear list with a first and a last page. However, the trail can be made "circular" by repeating the first page as the last item in the trail index:%0a%0a->[@%0a * [[TrailPage1]]%0a * [[TrailPage2]]%0a ...%0a * [[TrailPageN]]%0a * [[TrailPage1]]%0a@]%0a%0aIf the trail index page is intended to be read by others, the last item can be made invisible inside an [@(:if false:)@] block:%0a%0a->[@%0a * [[TrailPage1]]%0a * [[TrailPage2]]%0a ...%0a * [[TrailPageN]]%0a (:if false:)%0a * [[TrailPage1]]%0a (:ifend:)%0a@]%0a%0a[[#crossgroup]]%0a!! Cross Group Trails%0aBefore version 2.2.1, if your trail contains pages in different groups, it should use full [=[[Group.Name]]=] links instead of just [=[[Name]]=].%0a%0a!! Other notes%0a* There is no space between @@%3c|@@ and @@[=[[link]]=]@@ and @@|>@@; same for the other trail markups.%0a* Note that non-existing pages will appear in the WikiTrail as links.%0a%0a[[#trailstyle]]%0a!!! Trail style%0aPmWiki encapsulates the trail with a ''wikitrail'' css class. %0aThis allows the wiki trail to be [[LocalCustomizations | customised]] by defining CSS for the ''wikitrail'' in the ''local.css'' file.%0a%0a%0a[[#trailpagelists]]%0a!!! Trail in [[page lists]]%0aTrails from a single page can only be displayed using the pagelist [[PmWiki/PageLists#pagelisttrail|trail]] parameter. For example%0a(:markup class="horiz":)%0a(:pagelist trail=PmWiki/WikiTrails fmt=PmWiki.WikiTrails#traillist order=random count=3:)%0a(:markupend:)%0a%0a!!!A simple example of a WikiTrail%0a%0a1) On the TrailIndexPage:%0a%0a[@%0a* [[MyTrailPage1]]%0a* [[MyTrailPage2]]%0a* [[MyTrailPage3]]%0a@]%0a%0a2) On the pages MyTrailPage1, 2, and 3:%0a%0a[@%0a%3c%3c|[[TrailIndexPage]]|>>%0a@]%0a%0a>>comment%3c%3c%0a[[#traillist]]%0a%25font-size:small green%25> [[{=$FullName}|{=$Groupspaced}.{=$Namespaced}]] %3c%0a[[#traillistend]]%0a>>%3c%3c%0a%0a!! Questions%0a[[#faq]]%0a>>faq%3c%3c%0aQ: What's the difference between a [[[[PmWiki/PageLists|PageList]] and a WikiTrail?%0aA: The pagelist directive dynamically generates a list of pages. There are many ways to generate the list, including using a WikiTrail as the source. The pagelist directive then displays the pages that match the criteria using an optional template - for example displaying each page name on a separate line as a link or including the entire content. The pagelist directive currently does not have built-in navigation markup that you can put on the pages in the list. By contrast, WikiTrails are simply specified via links on an "index" page and you ''can'' put previous-next navigation markup on each page. The two serve very different purposes. WikiTrails are useful for specifying the pages in [[PmWiki/WebFeeds|web feeds]], for creating a "tour" through a predefined set of pages, and many other things.%0a
+time=1259791272
diff --git a/wikilib.d/PmWiki.WikiWikiWeb b/wikilib.d/PmWiki.WikiWikiWeb
new file mode 100644
index 0000000..855bb60
--- /dev/null
+++ b/wikilib.d/PmWiki.WikiWikiWeb
@@ -0,0 +1,11 @@
+version=pmwiki-2.2.6 ordered=1 urlencoded=1
+agent=Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.0.3705; .NET CLR 1.1.4322; .NET CLR 2.0.50727)
+author=SchreyP
+charset=ISO-8859-1
+csum=repair broken/redirecting links & make WikiWord a link
+host=81.243.197.239
+name=PmWiki.WikiWikiWeb
+rev=69
+targets=PmWiki.Links,PmWiki.TextFormattingRules,PmWiki.WikiWord,Site.AllRecentChanges,PmWiki.BasicEditing,Main.WikiSandbox
+text=(:Summary: An introduction to the Wiki Wiki Web (www):)%0a'''WikiWikiWeb''' is an "open-editing" system where the emphasis is on the ''authoring'' and ''collaboration'' of documents rather than the simple browsing or viewing of them. %0aThe name "wiki" is based on the Hawaiian term "wiki wiki", meaning "quick" or "super-fast". %0aThe basic concept of a WikiWikiWeb (or "wiki") is that (almost) anyone can edit any page. While at first this sounds like a recipe for complete anarchy, the truth is that sites using this system have developed surprisingly complex and rich communities for online collaboration and communication. Yes, it's possible for someone to go and destroy everything on a page, but it doesn't seem to happen often. And, many systems (including this one) have built-in mechanisms to restore content that has been defaced or destroyed.%0a%0a''The point of the system is to simply make it as ''quick'', ''easy'' and ''rewarding'' as possible to create or edit online content.''%0a%0aUsing any standard Web browser, a person can edit (almost) any page on the system using relatively simple [[text formatting rules]]. [[Links | Creating a link]] to a new or existing page simply involves putting the word or phrase that will be your link text inside of [=[[double square brackets]]=] to reference and serve as a title for the target page. In the process of creating the link you're ''creating the new page'', if it doesn't already exist. On some sites (depending on the configuration of PmWiki), a link can also be created by entering a [[WikiWord]] -- a word consisting of two or more capitalized words joined together.%0a%0aIt's not even necessary to learn all of the formatting rules; others will often come in and reformat things for you. After all, anyone can edit! '''You''' can see some of the [[({$SiteGroup}.All) recent changes]] that others have posted to this site.%0a%0aTo learn more about adding pages to this Wiki site, see [[basic editing]], then try editing pages in the [[Main/WikiSandbox]].%0a%0aIf you want to learn more about the WikiWikiWeb concept, try some of these Web sites:%0a%0a* %25newwin%25[[Wiki:WikiWikiWeb]]%25%25 -- The original WikiWikiWeb%0a* %25newwin%25[[Meatball:WhyWikiWorks]]%25%25 -- how and why Wiki works%0a* %25newwin%25[[Meatball:SoftSecurity]]%25%25 -- how open editing can result in good Web sites%0a* %25newwin%25[[http://www.communitywiki.org/cw/CategoryWiki|Wiki]]%25%25 on %25newwin%25[[http://www.communitywiki.org/en/SiteMap|CommunityWiki]]%25%25%0a* %25newwin%25[[Wikipedia:Wiki#Characteristics|WikiFeatures]]%25%25 -- for info on features in wikis and how to use them%0a* %25newwin%25[[Wikipedia:Wikipedia:Why_Wikipedia_is_so_great]]%25%25 -- how and why the biggest wiki in the world made a comprehensive free-content encyclopedia%0a* %25newwin%25[[http://wikitravel.org/en/Wikitravel:Wiki | Wikitravel:Wiki]]%25%25 -- another introduction to wikis, on another exemplary site%0a%0aOr, send email to Patrick Michaud at mailto:pmichaud@pobox.com.
+time=1254861178
diff --git a/wikilib.d/PmWiki.WikiWord b/wikilib.d/PmWiki.WikiWord
new file mode 100644
index 0000000..8e7d867
--- /dev/null
+++ b/wikilib.d/PmWiki.WikiWord
@@ -0,0 +1,11 @@
+version=pmwiki-2.2.6 ordered=1 urlencoded=1
+agent=Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; GTB6; .NET CLR 1.0.3705)
+author=SchreyP
+charset=ISO-8859-1
+csum=improvement and adding one subheading
+host=81.243.197.239
+name=PmWiki.WikiWord
+rev=27
+targets=PmWiki.WikiWikiWeb,PmWiki.Links
+text=(:Summary:Definition and usage of WikiWord:)%0aA '''WikiWord''' is a set of two or more words run together, where the first letter of each word is capitalized. This syntax is also sometimes referred to as "mixed case" or "camel case". Other descriptions of WikiWords are available from [[Wiki:WikiWord]] and [[Wikipedia:WikiWord]].%0a%0a!!Usage as page titles%0aWikiWords are used as '''page titles''' in a [[WikiWikiWeb|wiki-based system]]. %0a%0a!!Usage as links%0aIn some wikis (depending on the configuration of PmWiki), a valid '''link''' can be created by writing it as WikiWord. In such PmWiki installations, WikiWords surrounded by [=[=...=]=] or preceded by a backquote (`) are not turned into links: %0a%0a(:linkwikiwords:)%0a(:markup:)[@LikeThis compared to `LikeThis or even [=LikeThis=]@]%0a(:nolinkwikiwords:)%0a%0aSee [[Links]] for information about `PmWiki's rules for forming links and forming page titles.%0a%0a!!!Enabling WikiWord links%0aWikiWord links are disabled by default since Pmwiki version 2.1 beta2. To enable WikiWord links you need to set in ''config.php'' %0a%0a-> [@$LinkWikiWords = 1;@] %0a%0a!!!WikiWord links to non-existent pages without decoration%0aIf you want to display links to non-existent pages without decoration, place the following lines in ''pub/css/local.css'': %0a%0a-> [@span.wikiword a.createlink { display:none; }%0aspan.wikiword a.createlinktext { border-bottom:none; text-decoration:none; color:inherit; }@]%0a %0a!!!Finding WikiWord links%0aIf you upgraded from an earlier version and want to convert WikiWord links to standard [[links]], the following will help to find those WikiWord links easier by highlighting them. Set in ''config.php'':%0a%0a-> [@$HTMLStylesFmt['wikiword'] = "span.wikiword { background:yellow; }";@] %0a%0a!!!Disabling certain WikiWords links%0aThe variable $WikiWordCount controls WikiWord conversion on a per word basis.%0a
+time=1254954497
diff --git a/wikilib.d/PmWiki.WikiWords b/wikilib.d/PmWiki.WikiWords
new file mode 100644
index 0000000..d866293
--- /dev/null
+++ b/wikilib.d/PmWiki.WikiWords
@@ -0,0 +1,11 @@
+version=pmwiki-2.2.0-beta65 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.8.1.11) Gecko/20071127 Firefox/2.0.0.11
+author=simon
+charset=ISO-8859-1
+csum=summary
+host=202.37.32.2
+name=PmWiki.WikiWords
+rev=3
+targets=
+text=(:Summary:Redirects to [[PmWiki.WikiWord]]:)%0a(:redirect WikiWord:)
+time=1201746704
diff --git a/wikilib.d/Site.AuthForm b/wikilib.d/Site.AuthForm
new file mode 100644
index 0000000..921a8f2
--- /dev/null
+++ b/wikilib.d/Site.AuthForm
@@ -0,0 +1,11 @@
+version=pmwiki-2.2.0-beta65 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.8.1.11) Gecko/20071127 Firefox/2.0.0.11
+author=simon
+charset=ISO-8859-1
+csum=ifend
+host=202.37.32.2
+name=Site.AuthForm
+rev=16
+targets=
+text=(:Summary:form displayed when requesting a [[PmWiki/password(s)]] or username/password:)%0a'''$[Password required]'''%0a(:messages:)%0a(:if enabled InvalidLogin:)* $[Name/password not recognized]%0a(:ifend:)%0a(:input auth_form:)%0a(:if enabled EnableAuthUser:)$[Name]: (:input text name=authid:)\\%0a(:if:)$[Password]: (:input password name=authpw:)%0a(:input submit value='OK':)%0a(:input end:)%0a(:ifend:)%0a
+time=1203896259
diff --git a/wikilib.d/Site.AuthUser b/wikilib.d/Site.AuthUser
new file mode 100644
index 0000000..24a471b
--- /dev/null
+++ b/wikilib.d/Site.AuthUser
@@ -0,0 +1,8 @@
+version=pmwiki-2.2.0-beta57 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (X11; U; Linux i686 (x86_64); en-US; rv:1.8.1.2) Gecko/20061023 SUSE/2.0.0.2-1.1 Firefox/2.0.0.2
+charset=ISO-8859-1
+name=Site.AuthUser
+passwdattr=*
+passwdedit=*
+text=(:redirect SiteAdmin.AuthUser:)%0a
+time=1000000000
diff --git a/wikilib.d/Site.EditForm b/wikilib.d/Site.EditForm
new file mode 100644
index 0000000..bbf54b4
--- /dev/null
+++ b/wikilib.d/Site.EditForm
@@ -0,0 +1,11 @@
+version=pmwiki-2.2.1 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.19) Gecko/20081216 Ubuntu/8.04 (hardy) Firefox/2.0.0.19
+author=Petko
+charset=ISO-8859-1
+csum=fix for dist
+host=81.65.14.164
+name=Site.EditForm
+rev=60
+targets=
+text=(:Summary:contains the edit page layout form:)%0a!! $[Editing {*$FullName}] %25block class=wikiaction%25%0a(:messages:)%0a(:div id='wikiedit':)%0a(:input e_form:)[[#top]](:e_guibuttons:)\\%0a(:input e_textarea:)\\%0a$[Summary]: (:input e_changesummary:)\\%0a$[Author]: (:input e_author:) (:input e_minorcheckbox:) $[This is a minor edit]\\%0a(:input e_savebutton:) (:input e_savedraftbutton:) (:input e_saveeditbutton:) (:input e_previewbutton:) (:input e_cancelbutton:)%0a(:input end:)%0a(:divend:)%0a(:include $[{$SiteGroup}/EditQuickReference]:)%0a(:if e_preview:)%0a!! $[Preview {*$FullName}]%0a'''$[Page is unsaved]'''%0a(:e_preview:)%0a----%0a'''$[End of preview -- remember to save]'''\\%0a[[#top | $[Top] ]]%0a(:ifend:)%0a
+time=1238832950
diff --git a/wikilib.d/Site.EditQuickReference b/wikilib.d/Site.EditQuickReference
new file mode 100644
index 0000000..0dda921
--- /dev/null
+++ b/wikilib.d/Site.EditQuickReference
@@ -0,0 +1,11 @@
+version=pmwiki-2.2.2 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.19) Gecko/20081216 Ubuntu/8.04 (hardy) Firefox/2.0.0.19
+author=Petko
+charset=ISO-8859-1
+csum=fix link for a release
+host=81.65.14.164
+name=Site.EditQuickReference
+rev=41
+targets=PmWiki.BasicEditing,PmWiki.TextFormattingRules,PmWiki.DocumentationIndex,PmWiki.Tables,PmWiki.TableDirectives
+text=(:Summary:quick reference for [[PmWiki/BasicEditing|editing]] pages:)%0a%25define=em font-weight=bold%25%0a(:table width='100%25' cellspacing='0' cellpadding='0' style='font-size:80%25; font-family:Arial; padding:2px; border:1px solid #cccccc;' class='quickref' :) (:comment Use 'quickref' class to override formatting :)%0a(:cellnr:)%0a%25target=_blank%25 [[PmWiki/Basic editing]] - [[PmWiki/Text formatting rules]] - [[PmWiki/Documentation index]]%0a(:cell align=right:)%0a%25em%25Tables%25%25: %25target=_blank%25[[PmWiki/Tables | simple ]] - [[PmWiki/TableDirectives | advanced ]]%0a(:cellnr:)%0a%25em%25Paragraphs%25%25: for a new paragraph, use a blank line;%0a(:cell align=right:)%0a%25em%25Line break%25%25: %0a%25em%25[=\\=]%25%25, %0a%25em%25[=[[%3c%3c]]=]%25%25, or %0a%25em%25[=(:nl:)=]%25%25%0a(:cellnr:)%0a%25em%25[=->=]%25%25 to indent text, %0a%25em%25[=-%3c=]%25%25 hanging text %0a(:cell align=right:)%0a%25em%25Join line%25%25: %25em%25\%25%25%0a(:cellnr colspan='2':)%0a%25em%25Lists%25%25: %0a%25em%25*%25%25 for bulleted, %0a%25em%25#%25%25 for numbered, %0a%25em%25:%25%25term%25em%25:%25%25definition for definition lists%0a(:cellnr colspan='2':)%0a%25em%25Emphasis%25%25: %0a%25em%25[=''=]%25%25''italics''%25em%25[=''=]%25%25 %0a%25em%25[='''=]%25%25'''bold'''%25em%25[='''=]%25%25 %0a%25em%25[='''''=]%25%25'''''bold italics'''''%25em%25[='''''=]%25%25 %0a%25em%25[=@@=]%25%25@@monospaced@@%25em%25[=@@=]%25%25%0a(:cellnr colspan='2':)%0a%25em%25References%25%25: %0a%25em%25[=[[=]%25%25another page%25em%25[=]]=]%25%25, %0a%25em%25[=[[=]%25%25[=http://example.com/=]%25em%25[=]]=]%25%25, %0a%25em%25[=[[=]%25%25another page %25em%25[=|=]%25%25 link text%25em%25[=]]=]%25%25, %0a%25em%25[=[[#=]%25%25anchor%25em%25[=]]=]%25%25,%0a%25em%25[=[[#=]%25%25anchor %25em%25[=|=]%25%25 link text%25em%25[=]]=]%25%25%0a(:cellnr colspan='2':)%0a%25em%25Groups%25%25: %0a%25em%25[=[[=]%25%25Group%25em%25[=/=]%25%25Page%25em%25[=]]=]%25%25 [-displays Page,-] %0a%25em%25[=[[=]%25%25Group%25em%25[=.=]%25%25Page%25em%25[=]]=]%25%25 [-displays [=Group.Page=],-] %0a%25em%25[=[[=]%25%25Group%25em%25[=(.=]%25%25Page%25em%25[=)]]=]%25%25 [-displays Group,-]%0a%25em%25[=[[=]%25%25Group%25em%25[=/]]=]%25%25 [-links Group homepage-]%0a(:cellnr:)%0a%25em%25Separators%25%25: %0a%25em%25!!%25%25, %0a%25em%25!!!%25%25 for headings, %0a%25em%25[=----=]%25%25 for horizontal line%0a(:cell align=right:)%0a%25em%25Prevent formatting%25%25: %0a%25em%25[=[==]%25%25...%25em%25[==]=]%25%25%0a(:cellnr:)%0a%25em%25Other%25%25: %0a%25em%25[=[+=]%25%25[+big+]%25em%25[=+]=]%25%25 %0a%25em%25[=[++=]%25%25[++bigger++]%25em%25[=++]=]%25%25 %0a%25em%25[=[-=]%25%25[-small-]%25em%25[=-]=]%25%25 %0a%25em%25[=[--=]%25%25[--smaller--]%25em%25[=--]=]%25%25 %0a%25em%25[='^=]%25%25'^superscript^'%25em%25[=^'=]%25%25 %0a%25em%25[='_=]%25%25'_subscript_'%25em%25[=_'=]%25%25 %0a%25em%25[={+=]%25%25{+inserted+}%25em%25[=+}=]%25%25 %0a%25em%25[={-=]%25%25{-deleted-}%25em%25[=-}=]%25%25%0a(:cell align=right:)%0a%25em%25Preformatted%25%25: %0a%25em%25[=[@=]%25%25...%25em%25[=@]=]%25%25 or %0a%25em%25[=>>=]pre%3c%3c%25%25...%25em%25[=>>=]%3c%3c%25%25%0a(:tableend:)
+time=1247701402
diff --git a/wikilib.d/Site.GroupAttributes b/wikilib.d/Site.GroupAttributes
new file mode 100644
index 0000000..9707fcd
--- /dev/null
+++ b/wikilib.d/Site.GroupAttributes
@@ -0,0 +1,3 @@
+name=Site.GroupAttributes
+passwdedit=@lock
+passwdattr=@lock
diff --git a/wikilib.d/Site.PageActions b/wikilib.d/Site.PageActions
new file mode 100644
index 0000000..76a1a9e
--- /dev/null
+++ b/wikilib.d/Site.PageActions
@@ -0,0 +1,11 @@
+version=pmwiki-2.2.0-beta65 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.14) Gecko/20080419 Ubuntu/8.04 (hardy) Firefox/2.0.0.14
+author=Petko
+charset=ISO-8859-1
+csum=$[Logout], for XLPage
+host=213.251.133.101
+name=Site.PageActions
+rev=44
+targets=Site.PageActions
+text=(:Summary:Contains the '[[PmWiki/AvailableActions|action]]' links (like Browse, Edit, History, etc.), placed at the top of the page, see [[PmWiki/site page actions]]:)%0a(:comment This page can be somewhat complex to figure out the first time you see it. Its contents are documented at PmWiki.SitePageActions if you need help. :)%0a* %25item rel=nofollow class=browse accesskey='$[ak_view]'%25 [[{*$FullName} | $[View] ]]%0a* %25item rel=nofollow class=edit accesskey='$[ak_edit]'%25 [[{*$FullName}?action=edit | $[Edit] ]]%0a* %25item rel=nofollow class=diff accesskey='$[ak_history]'%25 [[{*$FullName}?action=diff | $[History] ]]%0a(:if auth upload:)%0a* %25item rel=nofollow class=upload accesskey='$[ak_attach]'%25 [[{*$FullName}?action=upload | $[Attach] ]]%0a(:ifend:)%0a* %25item rel=nofollow class=print accesskey='$[ak_print]'%25 [[{*$FullName}?action=print | $[Print] ]]%0a(:if group Site,SiteAdmin,Cookbook,Profiles,PmWiki*:) (:comment delete if and ifend to enable backlinks:)%0a* %25item rel=nofollow class=backlinks accesskey='$[ak_backlinks]'%25 [[{*$Name}?action=search&q=link={*$FullName} | $[Backlinks] ]]%0a(:ifend:)%0a(:if enabled AuthPw:)%0a* %25item rel=nofollow class=logout accesskey='$[ak_logout]'%25'' [-[[{*$FullName}?action=logout | $[Logout] ]]-]''%0a(:ifend:)
+time=1214148387
diff --git a/wikilib.d/Site.PageListTemplates b/wikilib.d/Site.PageListTemplates
new file mode 100644
index 0000000..d1b43ec
--- /dev/null
+++ b/wikilib.d/Site.PageListTemplates
@@ -0,0 +1,12 @@
+version=pmwiki-2.2.4 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.19) Gecko/20081216 Ubuntu/8.04 (hardy) Firefox/2.0.0.19
+author=Petko
+charset=ISO-8859-1
+csum=rm pmwiki_i18n
+ctime=1135725585
+host=86.69.109.9
+name=Site.PageListTemplates
+rev=81
+targets=Group.Group,Group.Name,Site.FullName,Group.Namespaced,Site.LocalTemplates,PmWiki.PageLists,PmWiki.PageListTemplates,PmWiki.PageVariables,PmWiki.PageTextVariables,PmWiki.ConditionalMarkup
+text=(:Summary:[[(PmWiki/PageList)Templates]] for PmWiki's [[PmWiki/Page lists]] directive:)%0aThis page contains "templates" for PmWiki's [@(:pagelist:)@] directive. The [[Site.LocalTemplates]] page can be created and used to store pagelist templates that are local to a site.%0a%0a%0a!!Page list template documentation%0a* [[PmWiki.Page Lists]] - {PmWiki/PageLists$:Summary}%0a* [[PmWiki.Page List Templates]] - {PmWiki/PageListTemplates$:Summary}%0a* [[PmWiki.Page Variables]] - {PmWiki/PageVariables$:Summary}%0a* [[PmWiki.PageTextVariables|Page Text Variables]] - {PmWiki/PageTextVariables$:Summary}%0a* [[PmWiki.Conditional Markup]] - {PmWiki/PageLists$:Summary}%0a* [[Cookbook:Pagelist Template Samples]] - {Cookbook/PagelistTemplateSamples$:Summary}%0a%0a%0a!!fmt=#default%0a%0aThe default template for pagelists when [@fmt=@] isn't specified (and note that on the PmWiki.org wiki, this template is over-ridden by the one on the [[Site.LocalTemplates]] page).%0a%0a(:markup class="horiz":)%0a(:if false:)%0a[[#default]]%0a(:template first {=$Group}:)%0a%0a:[[{=$Group}/]] /:%0a(:template each:)%0a: :[[{=$Group}/{=$Name}]]%0a[[#defaultend]]%0a(:ifend:)%0a%0a(:pagelist group={$Group} fmt=#default count=6:)%0a(:markupend:)%0a%0a%0a!!fmt=#bygroup%0a%0aDisplay pages by group/name.%0a%0a(:markup class="horiz":)%0a(:if false:)%0a[[#bygroup]]%0a(:template first {=$Group}:)%0a%0a:[[{=$Group}/]] /:%0a(:template each:)%0a: :[[{=$Group}/{=$Name}]]%0a[[#bygroupend]]%0a(:ifend:)%0a%0a(:pagelist group={$Group} fmt=#bygroup count=6:)%0a(:markupend:)%0a%0a%0a!!fmt=#simple%0a%0aA simple bullet list of page names.%0a%0a(:markup class="horiz":)%0a(:if false:)%0a[[#simple]]%0a* [[{=$FullName}]]%0a[[#simpleend]]%0a(:ifend:)%0a%0a(:pagelist group={$Group} fmt=#simple count=5:)%0a(:markupend:)%0a%0a%0a!!fmt=#title%0a%0aA simple bullet list of page titles. %0a%0a(:markup class="horiz":)%0a(:if false:)%0a[[#title]]%0a(:template defaults order=title:)%0a* [[{=$FullName}|+]]%0a[[#titleend]]%0a(:ifend:)%0a%0a(:pagelist group={$Group} fmt=#title count=5:)%0a(:markupend:)%0a%0a%0a!!fmt=#titlespaced%0a%0aOutputs wiki page titles with spaces between the words in the title.%0a%0a(:markup class="horiz":)%0a(:if false:)%0a[[#titlespaced]]%0a(:template defaults order=title:)%0a* [[{=$FullName}|{=$Titlespaced}]]%0a[[#titlespacedend]]%0a(:ifend:)%0a%0a(:pagelist group={$Group} fmt=#titlespaced count=5:)%0a(:markupend:)%0a%0a%0a!!fmt=#group%0a%0aA bullet list of groups.%0a%0a[@%0a[[#group]]%0a(:template first {=$Group}:)%0a* [[{=$Group}/]]%0a[[#groupend]]%0a@]%0a%0a%0a!!fmt=#include%0a%0aConcatenate the text of pages in the list. (Note, this can be an expensive operation!)%0a%0a[@%0a[[#include]]%0a(:include {=$FullName} self=0:)%0a[[#includeend]]%0a@]%0a%0a%0a!!fmt=#includefaq%0a%0aInclude just the #faq sections from pages in the list. (This can also be expensive,%0aespecially if the list includes pages that don't have the [@[[#faq]]@] anchor!)%0a%0a[@%0a[[#includefaq]]%0a!![[{=$FullName}|+]]%0a>>faq%3c%3c%0a(:include {=$FullName}#faq#faqend self=0:)%0a>>%3c%3c%0a[[#includefaqend]]%0a@]%0a%0a%0a!!fmt=#description%0a%0aList pages and append the page's description if it exists. Creates dash by all names, but adding a nested loop to get rid of it causes markup problems (nested loops are not allowed).%0a%0a(:markup class="horiz":)%0a(:if false:)%0a[[#description]]%0a* [[{=$FullName}|+]]%0a - {=$Description}%0a[[#descriptionend]]%0a(:ifend:)%0a%0a(:pagelist group={$Group} fmt=#description count=7:)%0a(:markupend:)%0a%0a%0a!!fmt=#simplename%0a%0aSimple bullet list of page names, without the Group name. %0a%0a(:markup class="horiz":)%0a(:if false:)%0a[[#simplename]]%0a* [[({=$Group}/){=$Name}]]%0a[[#simplenameend]]%0a(:ifend:)%0a%0a(:pagelist group={$Group} fmt=#simplename count=5:)%0a(:markupend:)%0a%0a%0a!!fmt=#simplenamespaced%0a%0aSimple bullet list of spaced page names, without the Group name. %0a%0a(:markup class="horiz":)%0a(:if false:)%0a[[#simplenamespaced]]%0a* [[({=$Group}/){=$Namespaced}]]%0a[[#simplenamespacedend]]%0a(:ifend:)%0a%0a(:pagelist group={$Group} fmt=#simplenamespaced count=5:)%0a(:markupend:)%0a%0a%0a!! fmt=#titlesummary%0a%0aA simple bullet list of page title and summary. %0a%0a(:markup class=horiz:)%0a>>comment%3c%3c%0a[[#titlesummary]]%0a* [[{=$FullName} | {=$Titlespaced}]] [-{=$:Summary}-]%0a[[#titlesummaryend]]%0a>>font-size:smaller%3c%3c%0a%0a(:pagelist group=Site fmt=#titlesummary list=normal count=8:)%0a(:markupend:)%0a%0a!!fmt=#count%0a%0aNumber of pages in pagelist %0a%0a(:markup class="horiz":)%0a(:if false:)%0a[[#count]]%0a(:template defaults wrap=inline list=normal :)%0a(:template last:)%0a{$$PageCount}%0a[[#countend]]%0a(:ifend:)%0a%0aNumber of pages in the {$Group} group: (:pagelist group={$Group} fmt=#count :).%0a%0aNumber of pages in the {$Group} group: (:pagelist group={$Group} fmt=count :).%0a%0aThere are (:pagelist group=PmWiki fmt=#count wrap=html :) pages in the PmWiki group.%0a(:markupend:)%0a%0a
+time=1251046581
diff --git a/wikilib.d/Site.PageNotFound b/wikilib.d/Site.PageNotFound
new file mode 100644
index 0000000..2e9816b
--- /dev/null
+++ b/wikilib.d/Site.PageNotFound
@@ -0,0 +1,11 @@
+version=pmwiki-2.2.0 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.19) Gecko/20081216 Ubuntu/8.04 (hardy) Firefox/2.0.0.19
+author=Petko
+charset=ISO-8859-1
+csum=
+host=81.65.14.164
+name=Site.PageNotFound
+rev=45
+targets=Site.PageNotFound
+text=(:Summary: Page displayed when PmWiki can't find the requested page:)%0a(:nolinkwikiwords:)%0a(:if name {$SiteGroup}.PageNotFound:)%0a-> %25green font-style:italic%25 This page contains the text to be displayed when PmWiki is unable to locate a requested page. Administrators can edit this page to change the message.%0a(:ifend:)%0a%0a(:if !group Category:)%0aThe page "{$RequestedPage}" doesn't exist. %0a(:ifend:)%0a(:if auth edit:)%0a%25rel=nofollow%25 ([[{*$FullName}?action=edit | Create {*$FullName}]]). %0a(:ifend:)%0a%0a
+time=1237082832
diff --git a/wikilib.d/Site.Preferences b/wikilib.d/Site.Preferences
new file mode 100644
index 0000000..3e3b4dc
--- /dev/null
+++ b/wikilib.d/Site.Preferences
@@ -0,0 +1,11 @@
+version=pmwiki-2.2.0 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.9.0.5) Gecko/2008120122 Firefox/3.0.5
+author=OliverBetz
+charset=ISO-8859-1
+csum=added more actions, commented unused entries
+host=87.163.109.22
+name=Site.Preferences
+rev=30
+targets=PmWiki.AccessKeys,Site.Preferences
+text=(:Summary: Preferences for access keys and edit form:)%0aPreferences for [[PmWiki/access keys]] and edit form%0a%0aThis page can be used as template for (personal) preferences, or set as default site preference (see below).%0a%0a->[@%0a # Access keys - hold Alt (Windows IE), Shift + Alt (Firefox)%0a # or Control (Mac) and tap the indicated key on your keyboard%0a # to trigger the corresponding action.%0a# 'ak_view' => '' , # view page%0a 'ak_edit' => 'e', # edit page%0a 'ak_history' => 'h', # page history%0a# 'ak_print' => '', # print view of page%0a 'ak_recentchanges' => 'c', # Recent Changes%0a 'ak_save' => 's', # save page%0a 'ak_saveedit' => 'u', # save and keep editing%0a 'ak_savedraft' => 'd', # save as draft%0a 'ak_preview' => 'p', # preview page%0a 'ak_em' => 'i', # emphasized text (italic)%0a 'ak_strong' => 'b', # strong text (bold)%0a%0a# 'ak_attach' => '', # attach a file%0a# 'ak_backlinks' => '', # show backlinks%0a# 'ak_logout' => '', # log out%0a%0a # Editing components%0a 'e_rows' => '20', # rows in edit textarea%0a 'e_cols' => '70', # columns in edit textarea%0a 'Site.EditForm' => 'Site.EditForm' # location of EditForm%0a @]%0a%0aTo create personal user (browser) preferences,%0a* make a copy of [[{$FullName}?action=source | this page]] somewhere, preferably as @@Profiles.''%25green%25insert_your_name_here%25%25''-Preferences@@%0a* edit that page with your new preferred settings,%0a* select [[{$FullName}?setprefs={$FullName} | Set Preferences of this Page]] on the page containing your newly created settings. %0a-> This sets a preference cookie on your browser which tells PmWiki where to find your personal preference settings.%0a%0aTo revert to the PmWiki default preferences%0a* select [[{$Name}?setprefs=| Revert to PmWiki Default Preferences]] to unset the preference cookie%0a%0aSee also [[Cookbook:UserConfigurations]] about how to customise the edit form for personal use.%0a%0a%0aNote that by default, parsing of {$FullName} is disabled. To make it the default site preference, add%0a XLPage('prefs', "Site.Preferences");%0ato a config file (e.g. local/config.php).%0a
+time=1234195765
diff --git a/wikilib.d/Site.Search b/wikilib.d/Site.Search
new file mode 100644
index 0000000..dbf81dd
--- /dev/null
+++ b/wikilib.d/Site.Search
@@ -0,0 +1,11 @@
+version=pmwiki-2.2.0-beta68 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.0.1) Gecko/2008070208 Firefox/3.0.1
+author=simon
+charset=ISO-8859-1
+csum=search is case insensitive
+host=203.97.214.12
+name=Site.Search
+rev=19
+targets=PmWiki.PageLists
+text=(:Summary:Search wiki:)%0a(:searchbox:)%0a%0a(:searchresults:)%0a%0a[[#searchinfostart]]%0aA search for more than one word will find pages that contain all of the words.%0aUse quotation marks to search for a phrase. %0aAlso use quotes for text with punctuation or special characters.%0aSearches are case insensitive.%0a%0aTo limit your search to a single group, enter the group name followed by a slash at the beginning of the search string (e.g., "[=PmWiki/=]" or "{$SiteGroup}/"). %0aTo list all pages, enter a slash for the search. %0a%0a!![-Search examples-]%0a %0a||border='0' cellspacing='0' width='100%25' cellpadding='0'%0a||!Enter ||!To find pages containing ||%0a||apple pie ||both 'apple' and 'pie' ||%0a||"apple pie" ||the phrase 'apple pie' ||%0a||pmwiki/apple ||'apple' in the [=PmWiki=] group of pages ||%0a||"pmwiki/apple" ||the phrase 'pmwiki/apple' in all groups of pages ||%0a||apple -pie ||'apple', omitting those containing 'pie' ||%0a||food -"apple pie" ||'food', omitting those containing 'apple pie' ||%0a||apple "-pie" ||the words 'apple' and '-pie' ||%0a||apple - pie ||'apple', '-', and 'pie' ||%0a||"pie:" ||the word 'pie' with a colon ||%0a||"pie=tasty" ||the phrase 'pie=tasty' ||%0a||name=*crumble* ||page names containing 'crumble' ||%0a%0aSome ''special characters'' need to be enclosed in quotes, including the colon (:), equals sign (=), less than (<), single quote (') and double quote(").%0a%0aFor ''advanced searches'', [[PmWiki/page list(s)]] parameters (count, name, group, fmt, link, list, order, and trail) can be entered together with the search string. %0a-%3c''Wild card characters'': asterisk (*) represent zero or more characters and question mark (?) represent exactly one character.%0a[[#searchinfoend]]%0a
+time=1219138857
diff --git a/wikilib.d/Site.SideBar b/wikilib.d/Site.SideBar
new file mode 100644
index 0000000..1af4f93
--- /dev/null
+++ b/wikilib.d/Site.SideBar
@@ -0,0 +1,5 @@
+version=pmwiki-2.0.beta55 ordered=1 urlencoded=1
+name=Site.SideBar
+passwdedit=@_site_edit
+text=* [[Main/HomePage]]%0a* [[Main/WikiSandbox]]%0a%0a%25sidehead%25 [[PmWiki/PmWiki]]%0a* [[PmWiki/Initial Setup Tasks]] %0a* [[PmWiki/Basic Editing]]%0a* [[PmWiki/Documentation Index]]%0a* [[PmWiki/FAQ | PmWiki FAQ ]]%0a* [[PmWiki/PmWikiPhilosophy]]%0a* [[PmWiki/Release Notes]]%0a* [[PmWiki/ChangeLog]]%0a%0a%25sidehead%25 [[http://www.pmwiki.org | pmwiki.org ]]%0a* [[Cookbook:CookbookBasics | Cookbook (addons) ]]%0a* [[Cookbook:Skins | Skins (themes) ]]%0a* [[PITS:PITS | PITS (issue tracking) ]]%0a* [[PmWiki/Mailing Lists]]%0a%0a%25right%25 [-[[Site.SideBar?action=edit | edit SideBar]]-]
+time=1125550800
diff --git a/wikilib.d/Site.Site b/wikilib.d/Site.Site
new file mode 100644
index 0000000..1fa0ec4
--- /dev/null
+++ b/wikilib.d/Site.Site
@@ -0,0 +1,12 @@
+version=pmwiki-2.2.5 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.2) Gecko/20090729 Firefox/3.5.2 GTB5
+author=TeganDowling
+charset=ISO-8859-1
+csum=list=all to over-ride display constraints; fix typo
+host=69.131.21.195
+name=Site.Site
+rev=32
+targets=PmWiki.Skins,Site.Site,SiteAdmin.SiteAdmin,Site.SideBar,PmWiki.PasswordsAdmin,Site.AllRecentChanges,PmWiki.GroupHeaders,PmWiki.Forms
+text=(:title Site Configuration:)(:Summary: Site Configuration:)%0aHere you find some links to Site configuration and administration pages. Add links to other pages you may need for your site's configuration here, as necessary. %0aSome links may only apply to certain configurations or [[PmWiki/skins]].%0a%0aThe [[{$SiteGroup}/]] group contains configuration pages, and the [[SiteAdmin/]] group contains administrative pages.%0a%0a'''Note to new administrators''':%0a* All pages in the 'Site' group (except [[Site.Side Bar]]) are locked for editing as the default. [[{$SiteGroup}.SideBar]] is locked with the site-wide edit password, if one is set. %0a* All pages in the 'SiteAdmin' group are locked for reading and editing as the default.%0a* In order to edit any locked page you need to create in @@local/config.php@@ a site wide '''admin''' password (see [[PmWiki/Passwords Admin]]). Then you can edit pages and change the access protection of individual pages by changing the page attributes with [@?action=attr@].%0a(:table border=0 width=100%25:)%0a(:cellnr:)%0a!! Configuration and Menu Pages%0a(:pagelist group={$SiteGroup} list=all name=PageActions,InterMap,Search,Preferences,PageNotFound fmt=#titlesummary:)%0a* [[{$SiteGroup}/All recent changes]] - changes made to all pages in all groups%0a%0a!! SideBar, header, and footer pages%0aSidebar, [[PmWiki/GroupHeaders | headers]] and footers are used to display common content across a group or entire website.%0a(:pagelist group={$SiteGroup} list=all name=*bar*,*head*,*foot* fmt=#titlesummary:)%0a%0a!! Form pages%0a[[PmWiki/Forms]] are used for display and entry of information.%0a(:pagelist group={$SiteGroup} list=all name=*form* fmt=#titlesummary:)%0a%0a!! Quick reference pages%0aQuick reference pages are included in other pages to assist in the use of those pages.%0a(:pagelist group={$SiteGroup} list=all name=*quick* fmt=#titlesummary:)%0a%0a!! Template pages%0aTemplates are used by page and form directives to control the output displayed.%0a(:pagelist group={$SiteGroup} list=all name=*template* fmt=#titlesummary:)%0a(:cell:)%0a!! Site Administration%0aHere is the list of the pages in the [[SiteAdmin/]] group. Some links may only apply to certain configurations.%0a(:pagelist group=SiteAdmin list=all fmt=#titlesummary:)%0a(:tableend:)%0a%0a%0a
+time=1251688706
+title=Site Configuration
diff --git a/wikilib.d/Site.UploadQuickReference b/wikilib.d/Site.UploadQuickReference
new file mode 100644
index 0000000..52951d6
--- /dev/null
+++ b/wikilib.d/Site.UploadQuickReference
@@ -0,0 +1,11 @@
+version=pmwiki-2.2.0-beta64 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.9) Gecko/20071025 Firefox/2.0.0.9
+author=simon
+charset=ISO-8859-1
+csum=summary
+host=203.97.214.12
+name=Site.UploadQuickReference
+rev=22
+targets=PmWiki.Uploads,Site.UploadQuickReference
+text=(:Summary:quick reference for [[PmWiki/uploads|uploading]] pages:)%0a[[#quickreference]]%0a>>color:#000000 bgcolor:#f9f9f9 font-family:'Arial,sans-serif' font-size:12px padding:2px border:'1px solid #cccccc' class='quickref'%3c%3c%0a'''%25newwin%25[[PmWiki/Uploads]]'''%0a%0a# Use the "Browse" button above to find the "File to upload" on your local computer.%0a%0a# For the "Name attachment as:" field, enter the name you prefer the file to have once it has been uploaded to the site. [[%3c%3c]]This can be the same as its filename on your source disk ''or it can be different'', but %25bgcolor:yellow%25'''make sure it has the correct file extension'''%25%25.%0a%0a# Press "$[Upload]" to upload the file.%0a%0a# To refer to an attachment within a wiki page in this {$Group} `WikiGroup, simply enter @@[=Attach:=]''filename.ext''@@ in the page text.%0a%0a# After uploading, you can %0a** %25item rel=nofollow class=browse accesskey=$[ak_view]%25 [[{*$FullName}?action=browse | $[View] the {*$Name} page]] or%0a** %25item rel=nofollow class=edit accesskey=$[ak_edit]%25 [[{*$FullName}?action=edit | $[Edit] the {*$Name} page]] or%0a** Scroll down to view the list of files that have been uploaded to the {*$Group} wiki group.%0a>>%3c%3c%0a[[#quickreferenceend]]%0a%0a----%0a%0a!! Existing uploads%0a>>font-size:smaller%3c%3c%0a(:attachlist:)%0a>>%3c%3c
+time=1195339548
diff --git a/wikilib.d/SiteAdmin.AuthList b/wikilib.d/SiteAdmin.AuthList
new file mode 100644
index 0000000..b9c0e23
--- /dev/null
+++ b/wikilib.d/SiteAdmin.AuthList
@@ -0,0 +1,12 @@
+version=pmwiki-2.2.0-beta64 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.8) Gecko/20071022 Ubuntu/7.10 (gutsy) Firefox/2.0.0.8
+author=Pm
+charset=ISO-8859-1
+csum=
+ctime=1180200570
+host=76.183.97.54
+name=SiteAdmin.AuthList
+rev=28
+targets=SiteAdmin.AuthList
+text=This page displays the permissions settings for pages that have permissions set. Fields that say "(protected)" mean that you may need to [[{*$FullName}?action=login | log in]] (e.g., with an administrative password) in order to view them.%0a%0a(:pagelist fmt=#authlist request=1:)%0a%0a(:if false:)%0a[@%0a[[#authlist]]%0a(:template defaults passwd=?* list=all:)%0a(:template first:)%0a|| class='indent authlist' cellspacing=0 cellpadding=0%0a(:template first {=$Group}:)%0a%0a'''{=$Group}:'''%0a%0a(:if exists {=$Group}.GroupAttributes:)%0a{=$Group}.GroupAttributes %0a[- [[{=$Group}.GroupAttributes | (view)]] -]%0a[- [[{=$Group}.GroupAttributes?action=attr | (attr)]] -] :%0a||read ||{{=$Group}.GroupAttributes$PasswdRead} ||%0a||edit ||{{=$Group}.GroupAttributes$PasswdEdit} ||%0a||attr ||{{=$Group}.GroupAttributes$PasswdAttr} ||%0a||upload ||{{=$Group}.GroupAttributes$PasswdUpload} ||%0a(:if:)%0a(:template each:)%0a%0a(:if ! equal {=$Name} GroupAttributes :)%0a{=$FullName}%0a[- [[{=$FullName} | (view) ]] -]%0a[- [[{=$FullName}?action=attr | (attr) ]] -] :%0a||read ||{=$PasswdRead} ||%0a||edit ||{=$PasswdEdit} ||%0a||attr ||{=$PasswdAttr} ||%0a||upload ||{=$PasswdUpload} ||%0a(:if:)%0a(:template last:)%0a%0aDisplayed {$$PageCount} pages.%0a[[#authlistend]]%0a%0a@]
+time=1195064732
diff --git a/wikilib.d/SiteAdmin.AuthUser b/wikilib.d/SiteAdmin.AuthUser
new file mode 100644
index 0000000..6d1844a
--- /dev/null
+++ b/wikilib.d/SiteAdmin.AuthUser
@@ -0,0 +1,11 @@
+version=pmwiki-2.2.0-beta63 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.8.1.6) Gecko/20070725 Firefox/2.0.0.6
+author=simon
+charset=ISO-8859-1
+csum=summary
+host=202.37.32.2
+name=SiteAdmin.AuthUser
+rev=1
+targets=PmWiki.AuthUser,PmWiki.LocalCustomizations,PmWiki.Passwords
+text=(:Summary: Configuration of identity based authorisations:)%0a(:nolinkwikiwords:)%0aThis is the default configuration page for PmWiki's identity-based authorizations (aka "authuser.php"). See [[PmWiki.AuthUser]] for instructions.%0a%0a(:if enabled EnableAuthUser:)%0aThis site appears to have the authuser extensions enabled.%0a(:if !enabled EnableAuthUser:)%0aAt present this site doesn't appear to have the authuser extensions enabled. To enable them, add the line [@include_once("$FarmD/scripts/authuser.php");@] to your ''local/config.php'' file. (See [[PmWiki.LocalCustomizations]].)%0a(:ifend:)%0a%0a!! Login accounts%0a%0aSpecify login accounts in the form "@@[=username: (:=]encrypt ''password'':)@@":%0a%0a-> # Examples:%0a-> # alice: [=(:=]encrypt wonderland:)%0a-> # bob: [=(:=]encrypt builder:)%0a%0aNote that the passwords will be encrypted when the page is saved, so that the result will look something like:%0a%0a-> # alice: $1$0gcdAN1a$HTdEAXyYYo8Hc9/Xv30Yz1%0a-> # bob: $1$wSP2R80i$sJ593ERCmTtjm3Fk26HCV1%0a%0aTo authorize specific login accounts for pages and groups, use "[@id:username@]" as a password in [@?action=attr@] or $DefaultPasswords (see [[PmWiki.Passwords]]). Use "[@id:*@]" to mean "any logged-in user".%0a%0a!! Authorization groups%0a%0aAuthorization groups are specified with a leading "@" sign. Define either the login accounts belonging to a group or the groups for a login account:%0a%0a-> # @writers: alice, bob %0a-> # carol: @editors, @writers%0a-> # @admins: alice, dave%0a%0aThen use "[@@group@]" as a password in [@?action=attr@] or $DefaultPasswords.%0a%0a!! Login accounts from external sources%0a%0aObtaining login accounts from external sources (uncomment out appropriate line(s)):%0a%0a-> # htpasswd: /filesystem/path/to/.htpasswd%0a-> # ldap: ldap://ldap.example.com/ou=People,o=example?uid?sub%0a-> # mysql: mysql://[username:password]@localhost/db/table?user,passwd%0a%0a
+time=1188505097
diff --git a/wikilib.d/SiteAdmin.GroupAttributes b/wikilib.d/SiteAdmin.GroupAttributes
new file mode 100644
index 0000000..d9dfa5b
--- /dev/null
+++ b/wikilib.d/SiteAdmin.GroupAttributes
@@ -0,0 +1,4 @@
+name=Site.GroupAttributes
+passwdread=@lock
+passwdedit=@lock
+passwdattr=@lock
diff --git a/wikilib.d/SiteAdmin.SiteAdmin b/wikilib.d/SiteAdmin.SiteAdmin
new file mode 100644
index 0000000..5249c2d
--- /dev/null
+++ b/wikilib.d/SiteAdmin.SiteAdmin
@@ -0,0 +1,13 @@
+version=pmwiki-2.2.2 ordered=1 urlencoded=1
+agent=Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.19) Gecko/20081216 Ubuntu/8.04 (hardy) Firefox/2.0.0.19
+author=Petko
+charset=ISO-8859-1
+csum=include Site.Site
+ctime=1182106004
+host=81.65.14.164
+name=SiteAdmin.SiteAdmin
+rev=6
+targets=
+text=(:include Site.Site:)%0a(:title Site Administration:)(:Summary: Site Administration:)%0a
+time=1247701015
+title=Site Administration
diff --git a/wikilib.d/SiteAdmin.Status b/wikilib.d/SiteAdmin.Status
new file mode 100644
index 0000000..bfcaf14
--- /dev/null
+++ b/wikilib.d/SiteAdmin.Status
@@ -0,0 +1,12 @@
+version=pmwiki-2.2.0 ordered=1 urlencoded=1
+agent=NetSprint -- 3.0
+author=simon
+charset=ISO-8859-1
+csum=Add summary, see how long a summary lasts?!
+host=212.77.100.47
+name=SiteAdmin.Status
+rev=22
+targets=
+text=(:Summary: PmWiki version {$Version} (VersionNum={$VersionNum}):)%0a(:comment Any local edits to this page may be lost!:)%0a%0aThis site is running {$Version} (VersionNum={$VersionNum}).%0a
+time=1232344608
+updatedto=2002000