initial, fully functional build complete

This commit is contained in:
Kenneth Reitz
2010-02-26 12:23:45 -05:00
commit 8fa9d953b0
229 changed files with 14895 additions and 0 deletions
+48
View File
@@ -0,0 +1,48 @@
This is the README.txt file for PmWiki, a wiki-based system for
collaborative creation and maintenance of websites.
PmWiki is distributed with the following directories:
docs/ Brief documentation, sample configuration scripts
local/ Configuration scripts
cookbook/ Recipes (add-ons) from the PmWiki Cookbook
pub/skins/ Layout templates ("skins" for custom look and feel)
pub/css/ Extra CSS stylesheet files
pub/guiedit/ Files for the Edit Form's GUIEdit module
scripts/ Scripts that are part of PmWiki
wikilib.d/ Bundled wiki pages, including
* a default Home Page
* PmWiki documentation pages
* some Site-oriented pages
After PmWiki is installed the following directories may also exist:
wiki.d/ Wiki pages
uploads/ Uploaded files (page attachments)
For quick installation advice, see docs/INSTALL.txt.
For more extensive information about installing PmWiki, visit
http://pmwiki.org/wiki/PmWiki/Installation
For information about running PmWiki in standalone mode without
requiring a webserver, visit
http://pmwiki.org/wiki/Cookbook/Standalone
PmWiki is Copyright 2001-2006 Patrick R. Michaud
pmichaud@pobox.com
http://www.pmichaud.com/
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.
The GNU General Public License is distributed with this program
(see docs/COPYING.txt) and it is also available online at
http://www.fsf.org/licensing/licenses/gpl.txt .
File diff suppressed because it is too large Load Diff
+43
View File
@@ -0,0 +1,43 @@
<?php
/**
* Use Markdown Markup in PmWiki
*
* @author Sebastian Siedentopf <schlaefer@macnews.de>
* @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", '<include', "/\(:markdown:\)(.*?)[\n]?\(:markdownend:\)/se",
"Keep(MarkupPmWikiConversion(PSS('$1')))");
function MarkupPmWikiConversion($text){
$astr = array (
"<:vspace>" => "\n\n",
"(:nl:)" => "\n",
);
$pstr = array(
"/<p>/" => "<p class='vspace'>",
"/&amp;(.*?);/" => "&\\1;",
);
$text = str_replace(array_keys($astr), $astr, $text);
$text = Markdown($text);
$text = preg_replace(array_keys($pstr), $pstr, $text);
return $text;
}
?>
+340
View File
@@ -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.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
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.
<signature of Ty Coon>, 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.
+10
View File
@@ -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 .
+39
View File
@@ -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 "?>":
<?php include('pmwiki.php');
5) Sitewide configuration settings will go in a "local configuration
file" named local/config.php. Copy the well-commented sample
configuration file from docs/sample-config.php to the local/
subdirectory, then rename the copy to config.php. Edit your
new local/config.php file to suit your preferences.
That's it. Next you'll probably want to browse your new site and
read the bundled documentation. A good place to start is the
PmWiki.InitialSetupTasks page.
Enjoy!
+50
View File
@@ -0,0 +1,50 @@
This UPGRADE.txt file is a command-line syntax reminder for
experienced PmWiki administrators. For full documentation on
upgrading Pmwiki, see the bundled PmWiki.Upgrades page or visit
http://www.pmwiki.org/wiki/PmWiki/Upgrades
See also these related pages:
http://www.pmwiki.org/wiki/PmWiki/BackupAndRestore
http://www.pmwiki.org/wiki/PmWiki/Subversion
The examples assume your PmWiki site is in a ./pmwiki/
directory (a directory named "pmwiki" immediately below the
working directory).
Backing up (always a good idea!):
tar -zcvf ~/pmwiki-backup.tar.gz pmwiki
zip -9r ~/pmwiki-backup.zip pmwiki
Or, to keep backups organized by date:
tar -zcvf ~/pmwiki-site-`date +%Y%m%d%M`.tar.gz pmwiki
zip -9r ~/pmwiki-site-`date +%Y%m%d%M`.zip pmwiki
The latest release is available here:
http://www.pmichaud.com/pub/pmwiki/pmwiki-latest.tgz
http://www.pmichaud.com/pub/pmwiki/pmwiki-latest.zip
Example download commands:
wget http://www.pmichaud.com/pub/pmwiki/pmwiki-latest.tgz
lftpget http://www.pmichaud.com/pub/pmwiki/pmwiki-latest.tgz
links http://www.pmichaud.com/pub/pmwiki/pmwiki-latest.tgz
lynx http://www.pmichaud.com/pub/pmwiki/pmwiki-latest.tgz
Expanding the archive:
tar -zxvf pmwiki-latest.tgz # for the gzipped tarball
unzip pmwiki-latest.zip # for the .zip archive
Copying the files (two ways to do it):
cp -av pmwiki-2.1.x/. pmwiki
cp -Rpv pmwiki-2.1.x/. pmwiki
Subversion upgrade:
svn export svn://pmwiki.org/pmwiki/tags/latest pmwiki --force
+2094
View File
File diff suppressed because it is too large Load Diff
+172
View File
@@ -0,0 +1,172 @@
<?php if (!defined('PmWiki')) exit();
## This is a sample config.php file. To use this file, copy it to
## local/config.php, then edit it for whatever customizations you want.
## Also, be sure to take a look at http://www.pmwiki.org/wiki/Cookbook
## for more details on the types of customizations that can be added
## to PmWiki.
## $WikiTitle is the name that appears in the browser's title bar.
$WikiTitle = 'Z&uuml;m Hosting';
$PageLogoUrl="";
$EnableMarkdown = 1;
## $ScriptUrl is your preferred URL for accessing wiki pages
## $PubDirUrl is the URL for the pub directory.
# $ScriptUrl = 'http://www.mydomain.com/path/to/pmwiki.php';
# $PubDirUrl = 'http://www.mydomain.com/path/to/pub';
## If you want to use URLs of the form .../pmwiki.php/Group/PageName
## instead of .../pmwiki.php?p=Group.PageName, try setting
## $EnablePathInfo below. Note that this doesn't work in all environments,
## it depends on your webserver and PHP configuration. You might also
## want to check http://www.pmwiki.org/wiki/Cookbook/CleanUrls more
## details about this setting and other ways to create nicer-looking urls.
# $EnablePathInfo = 1;
## $PageLogoUrl is the URL for a logo image -- you can change this
## to your own logo if you wish.
# $PageLogoUrl = "$PubDirUrl/skins/pmwiki/pmwiki-32.gif";
## If you want to have a custom skin, then set $Skin to the name
## of the directory (in pub/skins/) that contains your skin files.
## See PmWiki.Skins and Cookbook.Skins.
$Skin = 'equilibrium';
## You'll probably want to set an administrative password that you
## can use to get into password-protected pages. Also, by default
## the "attr" passwords for the PmWiki and Main groups are locked, so
## an admin password is a good way to unlock those. See PmWiki.Passwords
## and PmWiki.PasswordsAdmin.
$DefaultPasswords['admin'] = crypt('drummer42');
## Unicode (UTF-8) allows the display of all languages and all alphabets.
# include_once("scripts/xlpage-utf-8.php");
## If you're running a publicly available site and allow anyone to
## edit without requiring a password, you probably want to put some
## blocklists in place to avoid wikispam. See PmWiki.Blocklist.
# $EnableBlocklist = 1; # enable manual blocklists
# $EnableBlocklist = 10; # enable automatic blocklists
## PmWiki comes with graphical user interface buttons for editing;
## to enable these buttons, set $EnableGUIButtons to 1.
# $EnableGUIButtons = 1;
## To enable markup syntax from the Creole common wiki markup language
## (http://www.wikicreole.org/), include it here:
# include_once("scripts/creole.php");
## Some sites may want leading spaces on markup lines to indicate
## "preformatted text blocks", set $EnableWSPre=1 if you want to do
## this. Setting it to a higher number increases the number of
## space characters required on a line to count as "preformatted text".
# $EnableWSPre = 1; # lines beginning with space are preformatted (default)
# $EnableWSPre = 4; # lines with 4 or more spaces are preformatted
# $EnableWSPre = 0; # disabled
## If you want uploads enabled on your system, set $EnableUpload=1.
## You'll also need to set a default upload password, or else set
## passwords on individual groups and pages. For more information
## see PmWiki.UploadsAdmin.
# $EnableUpload = 1;
# $DefaultPasswords['upload'] = crypt('secret');
## Setting $EnableDiag turns on the ?action=diag and ?action=phpinfo
## actions, which often helps others to remotely troubleshoot
## various configuration and execution problems.
# $EnableDiag = 1; # enable remote diagnostics
## By default, PmWiki doesn't allow browsers to cache pages. Setting
## $EnableIMSCaching=1; will re-enable browser caches in a somewhat
## smart manner. Note that you may want to have caching disabled while
## adjusting configuration files or layout templates.
# $EnableIMSCaching = 1; # allow browser caching
## Set $SpaceWikiWords if you want WikiWords to automatically
## have spaces before each sequence of capital letters.
# $SpaceWikiWords = 1; # turn on WikiWord spacing
## Set $EnableWikiWords if you want to allow WikiWord links.
## For more options with WikiWords, see scripts/wikiwords.php .
# $EnableWikiWords = 1; # enable WikiWord links
## $DiffKeepDays specifies the minimum number of days to keep a page's
## revision history. The default is 3650 (approximately 10 years).
# $DiffKeepDays=30; # keep page history at least 30 days
## By default, viewers are prevented from seeing the existence
## of read-protected pages in search results and page listings,
## but this can be slow as PmWiki has to check the permissions
## of each page. Setting $EnablePageListProtect to zero will
## speed things up considerably, but it will also mean that
## viewers may learn of the existence of read-protected pages.
## (It does not enable them to access the contents of the
## pages.)
# $EnablePageListProtect = 0;
## The refcount.php script enables ?action=refcount, which helps to
## find missing and orphaned pages. See PmWiki.RefCount.
# if ($action == 'refcount') include_once("scripts/refcount.php");
## The feeds.php script enables ?action=rss, ?action=atom, ?action=rdf,
## and ?action=dc, for generation of syndication feeds in various formats.
# if ($action == 'rss') include_once("scripts/feeds.php"); # RSS 2.0
# if ($action == 'atom') include_once("scripts/feeds.php"); # Atom 1.0
# if ($action == 'dc') include_once("scripts/feeds.php"); # Dublin Core
# if ($action == 'rdf') include_once("scripts/feeds.php"); # RSS 1.0
## In the 2.2.0-beta series, {$var} page variables were absolute, but now
## relative page variables provide greater flexibility and are recommended.
## (If you're starting a new site, it's best to leave this setting alone.)
# $EnableRelativePageVars = 1; # 1=relative; 0=absolute
## By default, pages in the Category group are manually created.
## Uncomment the following line to have blank category pages
## automatically created whenever a link to a non-existent
## category page is saved. (The page is created only if
## the author has edit permissions to the Category group.)
# $AutoCreate['/^Category\\./'] = array('ctime' => $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", "/'~(.*?)~'/", "<i>$1</i>"); # '~italic~'
# Markup("'*", "inline", "/'\\*(.*?)\\*'/", "<b>$1</b>"); # '*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:)';
+6
View File
@@ -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.
Binary file not shown.

After

Width:  |  Height:  |  Size: 772 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 724 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 663 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 651 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 710 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 716 B

+62
View File
@@ -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("<a tabindex='-1' " + mkey + "onclick=\"insMarkup('"
+ mopen + "','"
+ mclose + "','"
+ mtext + "');\">"
+ mlabel + "</a>");
}
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;
}
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 691 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 696 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 699 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 700 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 664 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 662 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 649 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 741 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 677 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 657 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 707 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 722 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 648 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 643 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 703 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 752 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 712 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 716 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 719 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 654 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 668 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 712 B

+8
View File
@@ -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}
Binary file not shown.

After

Width:  |  Height:  |  Size: 327 B

+129
View File
@@ -0,0 +1,129 @@
<?php if (!defined('PmWiki')) exit();
/* PmWiki Equilibrium skin
*
* Examples at: http://pmwiki.com/Cookbook/Equilibrium and http://solidgone.org/Skins/
* Copyright (c) 2009 David Gilbert
* This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.
* Please retain the links in the footer.
* http://creativecommons.org/licenses/by-sa/3.0/us/
*/
global $FmtPV,$HTMLStylesFmt,$MarkupExpr;
$FmtPV['$SkinName'] = '"Equilibrium"';
$FmtPV['$SkinVersion'] = '"1.1.1"';
$FmtPV['$SkinDate'] = '"20091019"';
$MarkupExpr['mod'] = '($args[0] % $args[1])';
# Default color scheme
global $SkinColor, $ValidSkinColors;
$UserSkinColors = (is_array($ValidSkinColors) ?$ValidSkinColors :array());
$ValidSkinColors['black'] = array('block-highlight-back'=>'#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', "<fieldset>");
Markup('fieldsetend', 'inline', '/\\(:fieldsetend:\\)/i', "</fieldset>");
# 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 ('<a href="http://pmwiki.com/'.($GLOBALS['bi_BlogIt_Enabled']?'Cookbook/BlogIt">BlogIt':'">PmWiki').'</a>');
}
# 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');
}
}
+74
View File
@@ -0,0 +1,74 @@
<!DOCTYPE html PUBLIC
"-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>$WikiTitle {$Group}/{$Titlespaced}</title>
<meta name="generator" content="PmWiki" />
<link rel="stylesheet" type="text/css" href="$SkinDirUrl/style.css" media="screen" />
<!--[if lte IE 7]><link rel="stylesheet" type="text/css" href="$SkinDirUrl/ie7.css" media="screen" /><![endif]-->
<!--HTMLHeader-->
</head>
<body>
<div id="page-wrap" class="force_contain">
<div id="top">
<!--PageHeaderFmt-->
<div id="siteheader">
<!--wiki:{$Group}.SiteHeader {$SiteGroup}.SiteHeader-->
</div>
<!--/PageHeaderFmt-->
<!--PageTabsFmt-->
<!--wiki:{$Group}.SiteNav {$SiteGroup}.SiteNav -->
<!--/PageTabsFmt-->
<!--PageActionFmt-->
<div class="pageactions">
<!--wiki:{$Group}.PageActions {$SiteGroup}.PageActions-->
</div>
<!--/PageActionFmt-->
</div>
<div class="content">
<!--PageTitleGroupFmt-->
<a href='{$ScriptUrl}/{$Group}' class="pagegroup">{$Group}</a>
<!--/PageTitleGroupFmt-->
<!--PageTitleFmt-->
<h3 class='page-head'><a href='{$PageUrl}'>{$Titlespaced}</a></h3>
<!--/PageTitleFmt-->
<!--PageText-->
</div>
<div id="sidebar">
<!--PageSearchFmt-->
<h2>$[Search]</h2>
<form id="searchform" action='$ScriptUrl' method="get"><fieldset>
<input type='hidden' name='n' value='{$FullName}' />
<input type='hidden' name='action' value='search' />
<input class='searchBox' type='text' id='s' name='q' value="" />
<input id="searchsubmit" class='searchButton' type='submit' value='$[Go]' />
</fieldset></form>
<div class="clear"></div>
<!--/PageSearchFmt-->
<!--PageRightFmt-->
<!--wiki:{$Group}.SideBar {$SiteGroup}.SideBar-->
<!--/PageRightFmt-->
</div>
</div>
<div id="footer">
<!--PageFooterFmt-->
<div class="footer"><!--wiki:{$Group}.SiteFooter {$SiteGroup}.SiteFooter--></div>
<!--/PageFooterFmt-->
<div class="credits">
Brought to you by <a href="http://kennethreitz.com">Kenneth Reits</a>. This wiki+skin+markdown available on <a href="http://github.com/kennethreitz/mdWiki">GitHub</a>.
</div>
</div>
<!--HTMLFooter-->
</body>
</html>
+366
View File
@@ -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 */
@@ -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@]
@@ -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}]
@@ -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:)
@@ -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
@@ -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
+22
View File
@@ -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.
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

+102
View File
@@ -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; }
}
+52
View File
@@ -0,0 +1,52 @@
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>$WikiTitle | {$Group} / {$Title} $ActionTitle</title>
<meta http-equiv='Content-Style-Type' content='text/css' />
<link rel='stylesheet' href='$SkinDirUrl/pmwiki.css' type='text/css' />
<!--HTMLHeader-->
</head>
<body>
<!--PageHeaderFmt-->
<div id='wikilogo'><a href='{$ScriptUrl}'><img src='$PageLogoUrl'
alt='$WikiTitle' border='0' /></a></div>
<div id='wikihead'>
<form action='{$ScriptUrl}'>
<span class='headnav'><a href='{$ScriptUrl}/$[{$Group}/RecentChanges]'
accesskey='$[ak_recentchanges]'>$[Recent Changes]</a> -</span>
<input type='hidden' name='n' value='{$FullName}' />
<input type='hidden' name='action' value='search' />
<a href='{$ScriptUrl}/$[{$SiteGroup}/Search]'>$[Search]</a>:
<input type='text' name='q' value='' class='inputbox searchbox' />
<input type='submit' class='inputbutton searchbutton'
value='$[Go]' /></form></div>
<!--/PageHeaderFmt-->
<table id='wikimid' width='100%' cellspacing='0' cellpadding='0'><tr>
<!--PageLeftFmt-->
<td id='wikileft' valign='top'>
<!--wiki:{$Group}.SideBar {$SiteGroup}.SideBar--></td>
<!--/PageLeftFmt-->
<td id='wikibody' valign='top'>
<!--PageActionFmt-->
<div id='wikicmds'><!--wiki:{$Group}.PageActions {$SiteGroup}.PageActions--></div>
<!--PageTitleFmt-->
<div id='wikititle'>
<div class='pagegroup'><a href='{$ScriptUrl}/{$Group}'>{$Group}</a> /</div>
<h1 class='pagetitle'>{$Title}</h1></div>
<!--PageText-->
</td>
</tr></table>
<!--PageFooterFmt-->
<div id='wikifoot'>
<div class='footnav'>
<a rel="nofollow" href='{$PageUrl}?action=edit'>$[Edit]</a> -
<a rel="nofollow" href='{$PageUrl}?action=diff'>$[History]</a> -
<a rel="nofollow" href='{$PageUrl}?action=print' target='_blank'>$[Print]</a> -
<a href='{$ScriptUrl}/$[{$Group}/RecentChanges]'>$[Recent Changes]</a> -
<a href='{$ScriptUrl}/$[{$SiteGroup}/Search]'>$[Search]</a></div>
<div class='lastmod'>$[Page last modified on {$LastModified}]</div></div>
<!--HTMLFooter-->
</body>
</html>
+20
View File
@@ -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
+50
View File
@@ -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; }
+29
View File
@@ -0,0 +1,29 @@
<?php if (!defined('PmWiki')) exit();
/* 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 script defines additional settings needed when the 'print'
skin is loaded (usually in response to ?action=print, as controlled
by the $ActionSkin['print'] setting. See scripts/skins.php for
more details.
The changes made are:
- Redefines the standard layout to a format suitable for printing
- Redefines internal links to keep ?action=print
- Changes the display of URL and mailto: links
- Uses GroupPrintHeader and GroupPrintFooter pages instead
of GroupHeader and GroupFooter
*/
global $LinkPageExistsFmt, $GroupPrintHeaderFmt,
$GroupPrintFooterFmt, $GroupHeaderFmt, $GroupFooterFmt;
$LinkPageExistsFmt = "<a class='wikilink' href='\$PageUrl?action=print'>\$LinkText</a>";
SDV($GroupPrintHeaderFmt,'(:include $Group.GroupPrintHeader basepage={*$FullName}:)(:nl:)');
SDV($GroupPrintFooterFmt,'(:nl:)(:include $Group.GroupPrintFooter basepage={*$FullName}:)');
$GroupHeaderFmt = $GroupPrintHeaderFmt;
$GroupFooterFmt = $GroupPrintFooterFmt;
+20
View File
@@ -0,0 +1,20 @@
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html><head>
<title>$WikiTitle | {$Group} / {$Title}</title>
<link rel='stylesheet' href='$SkinDirUrl/print.css' type='text/css' />
<!--HTMLHeader-->
</head>
<body>
<div id='printhead'>
<h3>$[From $WikiTitle]</h3>
<h1 class='pagename'><a href='$ScriptUrl/{$Group}'>{$Group}: {$Title}</a></h1>
</div>
<!--PageText-->
<div id='printfoot'>
<div class='from'>$[Retrieved from {$PageUrl}]</div>
<div class='lastmod'>$[Page last modified on {$LastModified}]</div></div>
<!--HTMLFooter-->
</body>
</html>
+55
View File
@@ -0,0 +1,55 @@
<?php if (!defined('PmWiki')) exit();
/* Copyright 2004-2009 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 script handles author tracking.
*/
SDV($AuthorNameChars, "- '\\w\\x80-\\xff");
SDV($AuthorCookie, $CookiePrefix.'author');
SDV($AuthorCookieExpires,$Now+60*60*24*30);
SDV($AuthorCookieDir,'/');
SDV($AuthorGroup,'Profiles');
SDV($AuthorRequiredFmt,
"<h3 class='wikimessage'>$[An author name is required.]</h3>");
Markup('[[~','<links','/\\[\\[~(.*?)\\]\\]/',"[[$AuthorGroup/$1]]");
$LogoutCookies[] = $AuthorCookie;
if (!isset($Author)) {
if (isset($_POST['author'])) {
$x = stripmagic($_POST['author']);
setcookie($AuthorCookie, $x, $AuthorCookieExpires, $AuthorCookieDir);
} elseif (@$_COOKIE[$AuthorCookie]) {
$x = stripmagic(@$_COOKIE[$AuthorCookie]);
} else $x = @$AuthId;
$Author = htmlspecialchars(preg_replace("/[^$AuthorNameChars]/", '', $x),
ENT_COMPAT);
}
if (!isset($AuthorPage)) $AuthorPage =
FmtPageName('$AuthorGroup/$Name', MakePageName($pagename, $Author));
SDV($AuthorLink,($Author) ? "[[~$Author]]" : '?');
if (IsEnabled($EnableAuthorSignature,1)) {
SDVA($ROSPatterns, array(
'/(?<!~)~~~~(?!~)/e'
=> "FmtPageName('[[~\$Author]] \$CurrentTime', \$pagename)",
'/(?<!~)~~~(?!~)/e'
=> "FmtPageName('[[~\$Author]]', \$pagename)"));
Markup('~~~~','<[[~','/(?<!~)~~~~(?!~)/',"[[~$Author]] $CurrentTime");
Markup('~~~','>~~~~','/(?<!~)~~~(?!~)/',"[[~$Author]]");
}
if (IsEnabled($EnablePostAuthorRequired,0))
array_unshift($EditFunctions,'RequireAuthor');
## RequireAuthor forces an author to enter a name before posting.
function RequireAuthor($pagename, &$page, &$new) {
global $Author, $MessagesFmt, $AuthorRequiredFmt, $EnablePost;
if (!$Author) {
$MessagesFmt[] = $AuthorRequiredFmt;
$EnablePost = 0;
}
}
+210
View File
@@ -0,0 +1,210 @@
<?php if (!defined('PmWiki')) exit();
/* Copyright 2005-2009 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.
The APR compatible MD5 encryption algorithm in _crypt() below is
based on code Copyright 2005 by D. Faure and the File::Passwd
PEAR library module by Mike Wallner <mike@php.net>.
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);
}
+239
View File
@@ -0,0 +1,239 @@
<?php if (!defined('PmWiki')) exit();
/* Copyright 2006-2007 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 script adds blocklisting capabilities to PmWiki, and can
be enabled by simply setting the following in local/config.php:
$EnableBlocklist = 1;
With $EnableBlocklist set to 1, this module will search through
the SiteAdmin.Blocklist page, as well as any other pages given by
the $Blocklist pages variable, looking for lines of the
form "block:some phrase" or "block:/regex/", with "some phrase"
and "/regex/" indicating things to be excluded from any
posting to the site.
In addition, if a page contains IP addresses of the form
"a.b.c.d" or "a.b.c.*", then any posts coming from hosts
matching the address will be blocked.
There is also an "unblock:..." form, which removes an entry
from the blocklist. This is useful for removing specific
block items in wikifarms and with automatically downloaded
blocklists (below).
The script also has the capability of automatically downloading
blocklists from other sources, such as chongqed.org and
and the MoinMaster blocklist. These are configured using
the $BlocklistDownload array. An $EnableBlocklist value
of at least 10 configures PmWiki to automatically download
these external blocklists and refresh them daily.
More information about blocklists is available in the
PmWiki.Blocklist page.
*/
## Some recipes do page updates outside of the built-in posting
## cycle, so $EnableBlocklistImmediate is used to determine if
## we need to catch these. Currently this defaults to enabled,
## but at some point we may change the default to disabled.
if (IsEnabled($EnableBlocklistImmediate, 1)) {
SDVA($BlocklistActions, array('comment' => 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, "<h3 class='wikimessage'>$[This post has been blocked by the administrator]</h3>");
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('#(?<!\\\\)/#', '\\/', trim($m));
$terms['block'][] = "/$m/";
}
continue;
}
## Treat the page as a pmwiki-format blocklist page, with
## IP addresses and "block:"-style declarations. First, see
## if we need to block the author based on a.b.c.d or a.b.c.*
## IP addresses.
$ip = preg_quote($_SERVER['REMOTE_ADDR']);
$ip = preg_replace('/\\d+$/', '($0\\b|\\*)', $ip);
if (preg_match("/\\b$ip/", @$page['text'], $match)) {
$EnablePost = 0;
$IsBlocked = 1;
$WhyBlockedFmt[] = $BlockedMessagesFmt['ip'] . $match[0];
}
## Now we'll load any "block:" or "unblock:" specifications
## from the page text.
if (preg_match_all('/(un)?(?:block|regex):(.*)/', @$page['text'],
$match, PREG_SET_ORDER))
foreach($match as $m) $terms[$m[1].'block'][] = trim($m[2]);
}
## okay, we've loaded all of the terms, now subtract any 'unblock'
## terms from the block set.
StopWatch("Blocklist: diff unblock");
$blockterms = array_diff((array)@$terms['block'], (array)@$terms['unblock']);
## go through each of the remaining blockterms and see if it matches the
## text -- if so, disable posting and add a message to $WhyBlockedFmt.
StopWatch('Blocklist: blockterms (count='.count($blockterms).')');
$itext = strtolower($text);
foreach($blockterms as $b) {
if ($b{0} == '/') {
if (!preg_match($b, $text)) continue;
} else if (strpos($itext, strtolower($b)) === false) continue;
$EnablePost = 0;
$IsBlocked = 1;
$WhyBlockedFmt[] = $BlockedMessagesFmt['text'] . $b;
}
StopWatch('Blocklist: blockterms done');
## If we came across any reasons to block, let's provide a message
## to the author that it was blocked. If $EnableWhyBlocked is set,
## we'll even tell the author why. :-)
if (@$WhyBlockedFmt) {
$MessagesFmt[] = $BlocklistMessageFmt;
if (IsEnabled($EnableWhyBlocked, 0))
foreach((array)$WhyBlockedFmt as $why)
$MessagesFmt[] = "<pre class='blocklistmessage'>$why</pre>\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);
}
+63
View File
@@ -0,0 +1,63 @@
<?php if (!defined('PmWiki')) exit();
/* Copyright 2006-2009 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.
*/
## Browser cache-control. If this is a cacheable action (e.g., browse,
## diff), then set the Last-Modified header to the time the site was
## last modified. If the browser has provided us with a matching
## If-Modified-Since request header, we can return 304 Not Modified.
SDV($LastModFile,"$WorkDir/.lastmod");
if (!$LastModFile) return;
$LastModTime = @filemtime($LastModFile);
foreach(get_included_files() as $f)
{ $v = @filemtime($f); if ($v > $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);
+66
View File
@@ -0,0 +1,66 @@
<?php if (!defined('PmWiki')) exit();
/* Copyright 2007-2010 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 script adds Creole v0.4 markup (http://www.wikicreole.org/)
to PmWiki. To activate this script, simply add the following into
a local customization file:
include_once('scripts/creole.php');
*/
## **strong**
Markup('**', 'inline',
'/^\\*\\*(?>(.+?)\\*\\*)(?!\\S)|(?<!^)\\*\\*(.+?)\\*\\*/',
'<strong>$1$2</strong>');
## //emphasized//
Markup('//', 'inline',
'/(?<!http:|https:|ftp:)\\/\\/(.*?)\\/\\//',
'<em>$1</em>');
## == Headings ==
Markup('^=', 'block',
'/^(={1,6})\\s?(.*?)(\\s*=*\\s*)$/e',
"'<:block,1><h'.strlen('$1').PSS('>$2</h').strlen('$1').'>'");
## Line breaks
Markup('\\\\', 'inline', '/\\\\\\\\/', '<br />');
## Preformatted
Markup('^{{{', '[=',
"/^\\{\\{\\{\n(.*?\n)\\}\\}\\}[^\\S\n]*\n/sme",
"Keep(PSS('<pre class=\"escaped\">$1</pre>'))");
Markup('{{{', '>{{{',
'/\\{\\{\\{(.*?)\\}\\}\\}/se',
"Keep(PSS('<code class=\"escaped\">$1</code>'))");
## 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]"'),
));
+41
View File
@@ -0,0 +1,41 @@
<?php if (!defined('PmWiki')) exit();
/* Copyright 2002-2009 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 script defines ?action=crypt, providing help for WikiAdministrators
to set up site-wide passwords in the installation.
*/
SDV($HandleActions['crypt'],'HandleCrypt');
SDV($ActionTitleFmt['crypt'],'| $[Password encryption]');
function HandleCrypt($pagename, $auth='read') {
global $ScriptUrl,$HTMLStartFmt,$HTMLEndFmt;
PrintFmt($pagename,$HTMLStartFmt);
$passwd = stripmagic(@$_POST["passwd"]);
echo FmtPageName(
"<form action='{\$ScriptUrl}' method='POST'><p>
Enter password to encrypt:
<input type='text' name='passwd' value='"
. htmlspecialchars($passwd, ENT_QUOTES) ."' />
<input type='submit' />
<input type='hidden' name='n' value='{\$FullName}' />
<input type='hidden' name='action' value='crypt' /></p></form>",
$pagename);
if ($passwd) {
$crypt = crypt($passwd);
echo "<p class='vspace'>Encrypted password = $crypt</p>";
echo "<p class='vspace'>To set a site-wide password, insert the line below
in your <i>config.php</i> file, <br />replacing <tt>'type'</tt> with
one of <tt>'admin'</tt>, <tt>'read'</tt>, <tt>'edit'</tt>,
or <tt>'attr'</tt>. <br />See <a
href='$ScriptUrl?n=PmWiki.PasswordsAdmin'>PasswordsAdmin</a> for more
details.</p>
<pre class='vspace'> \$DefaultPasswords['type']='$crypt';</pre>";
}
PrintFmt($pagename,$HTMLEndFmt);
}
+53
View File
@@ -0,0 +1,53 @@
<?php if (!defined('PmWiki')) exit();
/* Copyright 2003-2005, 2007 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 adds "?action=diag" and "?action=phpinfo" actions to PmWiki.
This produces lots of diagnostic output that may be helpful to the
software authors when debugging PmWiki or other scripts.
*/
@ini_set('display_errors', '1');
@ini_set('track_errors','1');
if ($action=='diag') {
@session_start();
header('Content-type: text/plain');
print_r($GLOBALS);
exit();
}
if ($action=='phpinfo') { phpinfo(); exit(); }
function Ruleset() {
global $MarkupTable;
$out = '';
BuildMarkupRules();
foreach($MarkupTable as $id=>$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 = '<pre>';
foreach((array)$StopWatch as $i => $x)
$out .= sprintf("%{$l}d: %s\n", $i, $x);
$out .= '</pre>';
if (is_array($StopWatch)) array_pop($StopWatch);
if ($print) print $out;
return $out;
}
+63
View File
@@ -0,0 +1,63 @@
<?php if (!defined('PmWiki')) exit();
/* Copyright 2006 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.
*/
SDV($DraftSuffix, '-Draft');
if ($DraftSuffix)
SDV($SearchPatterns['normal']['draft'], "!$DraftSuffix\$!");
## set up a 'publish' authorization level, defaulting to 'edit' authorization
SDV($DefaultPasswords['publish'], '');
SDV($AuthCascade['publish'], 'edit');
SDV($FmtPV['$PasswdPublish'], 'PasswdVar($pn, "publish")');
if ($AuthCascade['attr'] == 'edit') $AuthCascade['attr'] = 'publish';
## Add a 'publish' page attribute if desired
if (IsEnabled($EnablePublishAttr, 0))
SDV($PageAttributes['passwdpublish'], '$[Set new publish password:]');
## with drafts enabled, the 'post' operation requires 'publish' permissions
if ($action == 'edit' && $_POST['post'] && $HandleAuth['edit'] == 'edit')
$HandleAuth['edit'] = 'publish';
$basename = preg_replace("/$DraftSuffix\$/", '', $pagename);
## if no -Draft page, switch to $basename
if (!PageExists($pagename) && PageExists($basename)) $pagename = $basename;
## set edit form button labels to reflect draft prompts
SDVA($InputTags['e_savebutton'], array('value' => ' '.XL('Publish').' '));
SDVA($InputTags['e_saveeditbutton'], array('value' => ' '.XL('Save draft and edit').' '));
SDVA($InputTags['e_savedraftbutton'], array(
':html' => "<input type='submit' \$InputFormArgs />",
'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;
}
+544
View File
@@ -0,0 +1,544 @@
<?php if (!defined('PmWiki')) exit();
/* Copyright 2005-2007 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 script provides a number of syndication feed and xml-based
metadata options to PmWiki, including Atom, RSS 2.0, RSS 1.0 (RDF),
and the Dublin Core Metadata extensions. This module is typically
activated from a local configuration file via a line such as
if ($action == 'atom') include_once("$FarmD/scripts/feeds.php");
if ($action == 'dc') include_once("$FarmD/scripts/feeds.php");
When enabled, ?action=atom, ?action=rss, and ?action=rdf produce
syndication feeds based on any wikitrail contained in the page,
or, for Category pages, on the pages in the category. The feeds
are generated using pagelist, thus one can include parameters such
as count=, list=, order=, etc. in the url to adjust the feed output.
?action=dc will normally generate Dublin Core Metadata for the
current page only, but placing a group=, trail=, or link= argument
in the url causes it to generate metadata for all pages in the
associated group, trail, or backlink.
There are a large number of customizations available, most of which
are controlled by the $FeedFmt array. Elements $FeedFmt look like
$FeedFmt['atom']['feed']['rights'] = 'All Rights Reserved';
where the first index corresponds to the action (?action=atom),
the second index indicates a per-feed or per-item element, and
the third index is the name of the element being generated.
The above setting would therefore generate a
"<rights>All Rights Reserved</rights>" 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 <author> 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 <description> 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 <enclosure> 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' => '<?xml version="1.0" encoding="$Charset"?'.'>
<feed xmlns="http://www.w3.org/2005/Atom">'."\n",
'_end' => "</feed>\n",
'title' => '$WikiTitle',
'link' => '<link rel="self" href="{$PageUrl}?action=atom" />',
'id' => '{$PageUrl}?action=atom',
'updated' => '$FeedISOTime',
'author' => "<author><name>$WikiTitle</name></author>\n",
'generator' => '$Version',
'logo' => '$PageLogoUrl'));
SDVA($FeedFmt['atom']['item'], array(
'_start' => "<entry>\n",
'id' => '{$PageUrl}',
'title' => '{$Title}',
'updated' => '$ItemISOTime',
'link' => "<link rel=\"alternate\" href=\"{\$PageUrl}\" />\n",
'author' => "<author><name>{\$LastModifiedBy}</name></author>\n",
'summary' => '{$Description}',
'category' => "<category term=\"\$Category\" />\n",
'_end' => "</entry>\n"));
## Settings for ?action=dc
SDVA($FeedFmt['dc']['feed'], array(
'_header' => 'Content-type: text/xml; charset="$Charset"',
'_start' => '<?xml version="1.0" encoding="$Charset"?'.'>
<!DOCTYPE rdf:RDF PUBLIC "-//DUBLIN CORE//DCMES DTD 2002/07/31//EN"
"http://dublincore.org/documents/2002/07/31/dcmes-xml/dcmes-xml-dtd.dtd">
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/">'."\n",
'_end' => "</rdf:RDF>\n"));
SDVA($FeedFmt['dc']['item'], array(
'_start' => "<rdf:Description rdf:about=\"{\$PageUrl}\">\n",
'dc:title' => '{$Title}',
'dc:identifier' => '{$PageUrl}',
'dc:date' => '$ItemISOTime',
'dc:type' => 'Text',
'dc:format' => 'text/html',
'dc:description' => '{$Description}',
'dc:subject' => "<dc:subject>\$Category</dc:subject>\n",
'dc:publisher' => '$WikiTitle',
'dc:author' => '{$LastModifiedBy}',
'_end' => "</rdf:Description>\n"));
## RSS 2.0 settings for ?action=rss
SDVA($FeedFmt['rss']['feed'], array(
'_header' => 'Content-type: text/xml; charset="$Charset"',
'_start' => '<?xml version="1.0" encoding="$Charset"?'.'>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
<channel>'."\n",
'_end' => "</channel>\n</rss>\n",
'title' => '$WikiTitle | {$Group} / {$Title}',
'link' => '{$PageUrl}?action=rss',
'description' => '{$Group}.{$Title}',
'lastBuildDate' => '$FeedRSSTime'));
SDVA($FeedFmt['rss']['item'], array(
'_start' => "<item>\n",
'_end' => "</item>\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' => '<?xml version="1.0" encoding="$Charset"?'.'>
<rdf:RDF xmlns="http://purl.org/rss/1.0/"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<channel rdf:about="{$PageUrl}?action=rdf">'."\n",
'title' => '$WikiTitle | {$Group} / {$Title}',
'link' => '{$PageUrl}?action=rdf',
'description' => '{$Group}.{$Title}',
'dc:date' => '$FeedISOTime',
'items' => "<items>\n<rdf:Seq>\n\$FeedRDFSeq</rdf:Seq>\n</items>\n",
'_items' => "</channel>\n",
'_end' => "</rdf:RDF>\n"));
SDVA($FeedFmt['rdf']['item'], array(
'_start' => "<item rdf:about=\"{\$PageUrl}\">\n",
'_end' => "</item>\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("<rdf:li resource=\"{\$PageUrl}\" />\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 <enclosure>
## 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"
'&nbsp;' => '&#160;',
'&iexcl;' => '&#161;',
'&cent;' => '&#162;',
'&pound;' => '&#163;',
'&curren;' => '&#164;',
'&yen;' => '&#165;',
'&brvbar;' => '&#166;',
'&sect;' => '&#167;',
'&uml;' => '&#168;',
'&copy;' => '&#169;',
'&ordf;' => '&#170;',
'&laquo;' => '&#171;',
'&not;' => '&#172;',
'&shy;' => '&#173;',
'&reg;' => '&#174;',
'&macr;' => '&#175;',
'&deg;' => '&#176;',
'&plusmn;' => '&#177;',
'&sup2;' => '&#178;',
'&sup3;' => '&#179;',
'&acute;' => '&#180;',
'&micro;' => '&#181;',
'&para;' => '&#182;',
'&middot;' => '&#183;',
'&cedil;' => '&#184;',
'&sup1;' => '&#185;',
'&ordm;' => '&#186;',
'&raquo;' => '&#187;',
'&frac14;' => '&#188;',
'&frac12;' => '&#189;',
'&frac34;' => '&#190;',
'&iquest;' => '&#191;',
'&Agrave;' => '&#192;',
'&Aacute;' => '&#193;',
'&Acirc;' => '&#194;',
'&Atilde;' => '&#195;',
'&Auml;' => '&#196;',
'&Aring;' => '&#197;',
'&AElig;' => '&#198;',
'&Ccedil;' => '&#199;',
'&Egrave;' => '&#200;',
'&Eacute;' => '&#201;',
'&Ecirc;' => '&#202;',
'&Euml;' => '&#203;',
'&Igrave;' => '&#204;',
'&Iacute;' => '&#205;',
'&Icirc;' => '&#206;',
'&Iuml;' => '&#207;',
'&ETH;' => '&#208;',
'&Ntilde;' => '&#209;',
'&Ograve;' => '&#210;',
'&Oacute;' => '&#211;',
'&Ocirc;' => '&#212;',
'&Otilde;' => '&#213;',
'&Ouml;' => '&#214;',
'&times;' => '&#215;',
'&Oslash;' => '&#216;',
'&Ugrave;' => '&#217;',
'&Uacute;' => '&#218;',
'&Ucirc;' => '&#219;',
'&Uuml;' => '&#220;',
'&Yacute;' => '&#221;',
'&THORN;' => '&#222;',
'&szlig;' => '&#223;',
'&agrave;' => '&#224;',
'&aacute;' => '&#225;',
'&acirc;' => '&#226;',
'&atilde;' => '&#227;',
'&auml;' => '&#228;',
'&aring;' => '&#229;',
'&aelig;' => '&#230;',
'&ccedil;' => '&#231;',
'&egrave;' => '&#232;',
'&eacute;' => '&#233;',
'&ecirc;' => '&#234;',
'&euml;' => '&#235;',
'&igrave;' => '&#236;',
'&iacute;' => '&#237;',
'&icirc;' => '&#238;',
'&iuml;' => '&#239;',
'&eth;' => '&#240;',
'&ntilde;' => '&#241;',
'&ograve;' => '&#242;',
'&oacute;' => '&#243;',
'&ocirc;' => '&#244;',
'&otilde;' => '&#245;',
'&ouml;' => '&#246;',
'&divide;' => '&#247;',
'&oslash;' => '&#248;',
'&ugrave;' => '&#249;',
'&uacute;' => '&#250;',
'&ucirc;' => '&#251;',
'&uuml;' => '&#252;',
'&yacute;' => '&#253;',
'&thorn;' => '&#254;',
'&yuml;' => '&#255;',
# entities defined in "http://www.w3.org/TR/xhtml1/DTD/xhtml-special.ent"
'&quot;' => '&#34;',
#'&amp;' => '&#38;#38;',
#'&lt;' => '&#38;#60;',
#'&gt;' => '&#62;',
'&apos;' => '&#39;',
'&OElig;' => '&#338;',
'&oelig;' => '&#339;',
'&Scaron;' => '&#352;',
'&scaron;' => '&#353;',
'&Yuml;' => '&#376;',
'&circ;' => '&#710;',
'&tilde;' => '&#732;',
'&ensp;' => '&#8194;',
'&emsp;' => '&#8195;',
'&thinsp;' => '&#8201;',
'&zwnj;' => '&#8204;',
'&zwj;' => '&#8205;',
'&lrm;' => '&#8206;',
'&rlm;' => '&#8207;',
'&ndash;' => '&#8211;',
'&mdash;' => '&#8212;',
'&lsquo;' => '&#8216;',
'&rsquo;' => '&#8217;',
'&sbquo;' => '&#8218;',
'&ldquo;' => '&#8220;',
'&rdquo;' => '&#8221;',
'&bdquo;' => '&#8222;',
'&dagger;' => '&#8224;',
'&Dagger;' => '&#8225;',
'&permil;' => '&#8240;',
'&lsaquo;' => '&#8249;',
'&rsaquo;' => '&#8250;',
'&euro;' => '&#8364;',
# entities defined in "http://www.w3.org/TR/xhtml1/DTD/xhtml-symbol.ent"
'&fnof;' => '&#402;',
'&Alpha;' => '&#913;',
'&Beta;' => '&#914;',
'&Gamma;' => '&#915;',
'&Delta;' => '&#916;',
'&Epsilon;' => '&#917;',
'&Zeta;' => '&#918;',
'&Eta;' => '&#919;',
'&Theta;' => '&#920;',
'&Iota;' => '&#921;',
'&Kappa;' => '&#922;',
'&Lambda;' => '&#923;',
'&Mu;' => '&#924;',
'&Nu;' => '&#925;',
'&Xi;' => '&#926;',
'&Omicron;' => '&#927;',
'&Pi;' => '&#928;',
'&Rho;' => '&#929;',
'&Sigma;' => '&#931;',
'&Tau;' => '&#932;',
'&Upsilon;' => '&#933;',
'&Phi;' => '&#934;',
'&Chi;' => '&#935;',
'&Psi;' => '&#936;',
'&Omega;' => '&#937;',
'&alpha;' => '&#945;',
'&beta;' => '&#946;',
'&gamma;' => '&#947;',
'&delta;' => '&#948;',
'&epsilon;' => '&#949;',
'&zeta;' => '&#950;',
'&eta;' => '&#951;',
'&theta;' => '&#952;',
'&iota;' => '&#953;',
'&kappa;' => '&#954;',
'&lambda;' => '&#955;',
'&mu;' => '&#956;',
'&nu;' => '&#957;',
'&xi;' => '&#958;',
'&omicron;' => '&#959;',
'&pi;' => '&#960;',
'&rho;' => '&#961;',
'&sigmaf;' => '&#962;',
'&sigma;' => '&#963;',
'&tau;' => '&#964;',
'&upsilon;' => '&#965;',
'&phi;' => '&#966;',
'&chi;' => '&#967;',
'&psi;' => '&#968;',
'&omega;' => '&#969;',
'&thetasym;' => '&#977;',
'&upsih;' => '&#978;',
'&piv;' => '&#982;',
'&bull;' => '&#8226;',
'&hellip;' => '&#8230;',
'&prime;' => '&#8242;',
'&Prime;' => '&#8243;',
'&oline;' => '&#8254;',
'&frasl;' => '&#8260;',
'&weierp;' => '&#8472;',
'&image;' => '&#8465;',
'&real;' => '&#8476;',
'&trade;' => '&#8482;',
'&alefsym;' => '&#8501;',
'&larr;' => '&#8592;',
'&uarr;' => '&#8593;',
'&rarr;' => '&#8594;',
'&darr;' => '&#8595;',
'&harr;' => '&#8596;',
'&crarr;' => '&#8629;',
'&lArr;' => '&#8656;',
'&uArr;' => '&#8657;',
'&rArr;' => '&#8658;',
'&dArr;' => '&#8659;',
'&hArr;' => '&#8660;',
'&forall;' => '&#8704;',
'&part;' => '&#8706;',
'&exist;' => '&#8707;',
'&empty;' => '&#8709;',
'&nabla;' => '&#8711;',
'&isin;' => '&#8712;',
'&notin;' => '&#8713;',
'&ni;' => '&#8715;',
'&prod;' => '&#8719;',
'&sum;' => '&#8721;',
'&minus;' => '&#8722;',
'&lowast;' => '&#8727;',
'&radic;' => '&#8730;',
'&prop;' => '&#8733;',
'&infin;' => '&#8734;',
'&ang;' => '&#8736;',
'&and;' => '&#8743;',
'&or;' => '&#8744;',
'&cap;' => '&#8745;',
'&cup;' => '&#8746;',
'&int;' => '&#8747;',
'&there4;' => '&#8756;',
'&sim;' => '&#8764;',
'&cong;' => '&#8773;',
'&asymp;' => '&#8776;',
'&ne;' => '&#8800;',
'&equiv;' => '&#8801;',
'&le;' => '&#8804;',
'&ge;' => '&#8805;',
'&sub;' => '&#8834;',
'&sup;' => '&#8835;',
'&nsub;' => '&#8836;',
'&sube;' => '&#8838;',
'&supe;' => '&#8839;',
'&oplus;' => '&#8853;',
'&otimes;' => '&#8855;',
'&perp;' => '&#8869;',
'&sdot;' => '&#8901;',
'&lceil;' => '&#8968;',
'&rceil;' => '&#8969;',
'&lfloor;' => '&#8970;',
'&rfloor;' => '&#8971;',
'&lang;' => '&#9001;',
'&rang;' => '&#9002;',
'&loz;' => '&#9674;',
'&spades;' => '&#9824;',
'&clubs;' => '&#9827;',
'&hearts;' => '&#9829;',
'&diams;' => '&#9830;'));
+332
View File
@@ -0,0 +1,332 @@
<?php if (!defined('PmWiki')) exit();
/* Copyright 2005-2009 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.
*/
# $InputAttrs are the attributes we allow in output tags
SDV($InputAttrs, array('name', 'value', 'id', 'class', 'rows', 'cols',
'size', 'maxlength', 'action', 'method', 'accesskey', 'multiple',
'checked', 'disabled', 'readonly', 'enctype', 'src', 'alt'));
# Set up formatting for text, submit, hidden, radio, etc. types
foreach(array('text', 'submit', 'hidden', 'password', 'radio', 'checkbox',
'reset', 'file', 'image') as $t)
SDV($InputTags[$t][':html'], "<input type='$t' \$InputFormArgs />");
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' => "<form \$InputFormArgs>",
'method' => 'post'));
# (:input end:)
SDV($InputTags['end'][':html'], '</form>');
# (:input textarea:)
SDVA($InputTags['textarea'], array(
':content' => array('value'),
':attr' => array_diff($InputAttrs, array('value')),
':html' => "<textarea \$InputFormArgs>\$InputFormContent</textarea>"));
# (: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' => "<option \$InputFormArgs>\$InputFormContent</option>"));
SDVA($InputTags['select'], array(
'class' => 'inputbox',
':html' => "<select \$InputSelectArgs>\$InputSelectOptions</select>"));
# (: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', '<input',
'/\\(:input\\s+select\\s.*?:\\)(?:\\s*\\(:input\\s+select\\s.*?:\\))*/ei',
"InputSelect(\$pagename, 'select', PSS('$0'))");
## The 'input+sp' rule combines multiple (:input select ... :)
## into a single markup line (to avoid split line effects)
Markup('input+sp', '<split',
'/(\\(:input\\s+select\\s(?>.*?:\\)))\\s+(?=\\(:input\\s)/', '$1');
SDV($InputFocusFmt,
"<script language='javascript' type='text/javascript'><!--
document.getElementById('\$InputFocusId').focus();//--></script>");
## 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("'", '&#39;', MarkupRestore($opt[$a]) ));
$attr[] = "$a='".str_replace("'", '&#39;', $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("'", '&#39;', $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 .= "<input type='hidden' name='$k' value='{$args[$k]}' />";
}
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' => "<form action='$r' method='post'
name='authform'>\$PostVars"));
SDV($AuthPromptFmt, array(&$PageStartFmt, 'page:$SiteGroup.AuthForm',
"<script language='javascript' type='text/javascript'><!--
try { document.authform.authid.focus(); }
catch(e) { document.authform.authpw.focus(); } //--></script>",
&$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' => "<form action='{\$PageUrl}?action=edit' method='post'
\$InputFormArgs><input type='hidden' name='action' value='edit'
/><input type='hidden' name='n' value='{\$FullName}'
/><input type='hidden' name='basetime' value='\$EditBaseTime'
/>"));
SDVA($InputTags['e_textarea'], array(
':html' => "<textarea \$InputFormArgs
onkeydown='if (event.keyCode==27) event.returnValue=false;'
>\$EditText</textarea>",
'name' => 'text', 'id' => 'text', 'accesskey' => XL('ak_textedit'),
'rows' => XL('e_rows'), 'cols' => XL('e_cols')));
SDVA($InputTags['e_author'], array(
':html' => "<input type='text' \$InputFormArgs />",
'name' => 'author', 'value' => $Author));
SDVA($InputTags['e_changesummary'], array(
':html' => "<input type='text' \$InputFormArgs />",
'name' => 'csum', 'size' => '60', 'maxlength' => '100',
'value' => htmlspecialchars(stripmagic(@$_POST['csum']), ENT_QUOTES)));
SDVA($InputTags['e_minorcheckbox'], array(
':html' => "<input type='checkbox' \$InputFormArgs />",
'name' => 'diffclass', 'value' => 'minor'));
if (@$_POST['diffclass']=='minor')
SDV($InputTags['e_minorcheckbox']['checked'], 'checked');
SDVA($InputTags['e_savebutton'], array(
':html' => "<input type='submit' \$InputFormArgs />",
'name' => 'post', 'value' => ' '.XL('Save').' ',
'accesskey' => XL('ak_save')));
SDVA($InputTags['e_saveeditbutton'], array(
':html' => "<input type='submit' \$InputFormArgs />",
'name' => 'postedit', 'value' => ' '.XL('Save and edit').' ',
'accesskey' => XL('ak_saveedit')));
SDVA($InputTags['e_savedraftbutton'], array(':html' => ''));
SDVA($InputTags['e_previewbutton'], array(
':html' => "<input type='submit' \$InputFormArgs />",
'name' => 'preview', 'value' => ' '.XL('Preview').' ',
'accesskey' => XL('ak_preview')));
SDVA($InputTags['e_cancelbutton'], array(
':html' => "<input type='submit' \$InputFormArgs />",
'name' => 'cancel', 'value' => ' '.XL('Cancel').' ' ));
SDVA($InputTags['e_resetbutton'], array(
':html' => "<input type='reset' \$InputFormArgs />",
'value' => ' '.XL('Reset').' '));
+82
View File
@@ -0,0 +1,82 @@
<?php if (!defined('PmWiki')) exit();
/* Copyright 2004-2009 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 script adds a graphical button bar to the edit page form.
The buttons are placed in the $GUIButtons array; each button
is specified by an array of five values:
- the position of the button relative to others (a number)
- the opening markup sequence
- the closing markup sequence
- the default text if none was highlighted
- the text of the button, either (a) HTML markup or (b) the
url of a gif/jpg/png image to be used for the button
(along with optional "title" text in quotes).
The buttons specified in this file are the default buttons
for the standard markups. Some buttons (e.g., the attach/upload
button) are specified in their respective cookbook module.
*/
SDVA($HTMLHeaderFmt, array('guiedit' => "<script type='text/javascript'
src='\$FarmPubDirUrl/guiedit/guiedit.js'></script>\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 = "<script type='text/javascript'><!--\n";
foreach ($GUIButtons as $k => $g) {
if (!$g) continue;
@list($when, $mopen, $mclose, $mtext, $tag, $mkey) = $g;
if ($tag{0} == '<') {
$out .= "document.write(\"$tag\");\n";
continue;
}
if (preg_match('/^(.*\\.(gif|jpg|png))("([^"]+)")?$/', $tag, $m)) {
$title = (@$m[4] > '') ? "title='{$m[4]}'" : '';
$tag = "<img src='{$m[1]}' $title style='border:0px;' />";
}
$mopen = str_replace(array('\\', "'"), array('\\\\', "\\\\'"), $mopen);
$mclose = str_replace(array('\\', "'"), array('\\\\', "\\\\'"), $mclose);
$mtext = str_replace(array('\\', "'"), array('\\\\', "\\\\'"), $mtext);
$out .=
"insButton(\"$mopen\", \"$mclose\", '$mtext', \"$tag\", \"$mkey\");\n";
}
$out .= '//--></script>';
return $out;
}
+46
View File
@@ -0,0 +1,46 @@
<?php if (!defined('PmWiki')) exit();
/* Copyright 2004-2005 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 defines an alternate authentication scheme based on the
HTTP Basic authentication protocol (i.e., the scheme used by default
in PmWiki 1).
*/
## If the webserver has already authenticated someone, then use
## that identifier for our authorization id. We also disable
## the use of the browser's Basic Auth form later, since it tends
## to confuse webservers.
if (IsEnabled($EnableRemoteUserAuth, 1) && @$_SERVER['REMOTE_USER']) {
SDV($EnableHTTPBasicAuth, 0);
SDV($AuthId, $_SERVER['REMOTE_USER']);
}
## If the browser supplied a password, add that password to the
## list of passwords used for authentication
if (@$_SERVER['PHP_AUTH_PW'])
SessionAuth($pagename, array('authpw'=>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;
}
+8
View File
@@ -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:
+123
View File
@@ -0,0 +1,123 @@
<?php if (!defined('PmWiki')) exit();
/* Copyright 2007-2010 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 script implements "markup expressions" -- a method to
do simple computations and manipulations from markup. The
generic form of a markup expression is "{(func arg1 arg2)}",
where the named function (held in the $MarkupExpr array)
is called with arg1 and arg2 as arguments.
Markup expressions can be nested. For example, to strip
off the first five characters and convert the remainder to
lowercase, an author can write:
{(tolower (substr "HELLOWORLD" 5))} # produces "world"
Some "built-in" expressions defined by this recipe include:
substr - extract a portion of a string
ftime - date/time formatting
strlen - length of a string
rand - generate a random number
pagename - build a pagename from a string
toupper - convert string to uppercase
tolower - convert string to lowercase
ucfirst - convert first character to uppercase
ucwords - convert first character of each word to uppercase
asspaced - spaceformatting of wikiwords
Custom expressions may be added by other recipes by adding
entries into the $MarkupExpr array. Each entry's key is
the name of the function, the value is the code to be evaluated
for that function (similar to the way $FmtPV works). By default,
any arguments for the expression are placed into the $args array:
## expressions like {(myfunc foo bar)}
$MarkupExpr['myfunc'] = 'myfunc($args[0], $args[1])';
The expression arguments are parsed using ParseArgs(), and the
result of this parsing is available through the $argp array:
## expressions like {(myfunc fmt=foo output=bar)}
$MarkupExpr['myfunc'] = 'myfunc($argp["fmt"], $argp["output"])';
Finally, if the code in $MarkupExpr contains '$params', then
it is executed directly without any preprocessing into arguments,
and $params contains the entire argument string. Note that $params
may contain escaped values representing quoted arguments and
results of other expressions; these values may be un-escaped
by using "preg_replace($rpat, $rrep, $params)".
*/
Markup('{(', '>{$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);
}
+197
View File
@@ -0,0 +1,197 @@
<?php if (!defined('PmWiki')) exit();
/* Copyright 2006-2009 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 script enables email notifications to be sent when posts
are made. It is included by default from the stdconfig.php
script if $EnableNotify is set to non-zero.
Once enabled, the addresses to receive messages are configured
via the Site.NotifyList page. A simple line in that page
such as
notify=somebody@example.com
will cause messages to be periodically sent to "somebody@example.com"
listing the pages that have changed on the site since the previous
message was sent. Multiple notify lines can be placed in the page,
and there are options to restrict the types of notifications
desired. For more details, see the PmWiki.Notify page in
the documentation.
Several variables set defaults for this script:
$NotifyFrom - return email address to use in message.
$NotifyDelay - number of seconds to wait before sending mail
after the first post.
$NotifySquelch - minimum number of seconds between sending email
messages to each address. Individual "notify=" lines in
Site.NotifyList can override this value via a custom "squelch="
parameter.
$NotifyFile - scratchpad file used to keep track of pending emails.
$NotifyListPageFmt - name of the NotifyList configuration page.
$NotifySubjectFmt - subject line for sent messages.
$NotifyBodyFmt - body of message to be sent. The string '$NotifyItems'
is replaced with the list of posts in the email.
$NotifyItemFmt - the format for each post to be included in a notification.
$NotifyTimeFmt - the format for dates and times ($PostTime)
in notification messages.
$NotifyHeaders - any additional message headers to be sent.
$NotifyParameters - any additional parameters to be passed to PHP's
mail() function.
*/
SDV($NotifyDelay, 0);
SDV($NotifySquelch, 10800);
SDV($NotifyFile, "$WorkDir/.notifylist");
SDV($NotifyListPageFmt, '$SiteAdminGroup.NotifyList');
SDV($NotifySubjectFmt, '[$WikiTitle] recent notify posts');
SDV($NotifyBodyFmt,
"Recent \$WikiTitle posts:\n"
. " \$ScriptUrl/$[{\$SiteGroup}/AllRecentChanges]\n\n\$NotifyItems\n");
SDV($NotifyTimeFmt, $TimeFmt);
SDV($NotifyItemFmt,
' * {$FullName} . . . $PostTime by {$LastModifiedBy}');
SDV($NotifyHeaders, '');
SDV($NotifyParameters, '');
if (@$NotifyFrom)
$NotifyHeaders = "From: $NotifyFrom\r\n$NotifyHeaders";
$EditFunctions[] = 'PostNotify';
## check if we need to do notifications
if ($action != 'edit') NotifyCheck($pagename);
function NotifyCheck($pagename) {
global $NotifyFile, $Now, $LastModTime;
$nfp = @fopen($NotifyFile, 'r');
if (!$nfp) return;
$nextevent = fgets($nfp);
fclose($nfp);
if ($Now < $nextevent && $LastModTime < filemtime($NotifyFile)) return;
register_shutdown_function('NotifyUpdate', $pagename, getcwd());
}
function PostNotify($pagename, &$page, &$new) {
global $IsPagePosted;
if ($IsPagePosted)
register_shutdown_function('NotifyUpdate', $pagename, getcwd());
}
function NotifyUpdate($pagename, $dir='') {
global $NotifyList, $NotifyListPageFmt, $NotifyFile, $IsPagePosted,
$FmtV, $NotifyTimeFmt, $NotifyItemFmt, $SearchPatterns,
$NotifySquelch, $NotifyDelay, $Now, $Charset, $EnableNotifySubjectEncode,
$NotifySubjectFmt, $NotifyBodyFmt, $NotifyHeaders, $NotifyParameters;
$abort = ignore_user_abort(true);
if ($dir) { flush(); chdir($dir); }
$GLOBALS['EnableRedirect'] = 0;
## Read in the current notify configuration
$pn = FmtPageName($NotifyListPageFmt, $pagename);
$npage = ReadPage($pn, READPAGE_CURRENT);
preg_match_all('/^[\s*:#->]*(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); $i++)
if ($trail[$i]['pagename'] == $pagename) break;
if ($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;
}
+844
View File
@@ -0,0 +1,844 @@
<?php if (!defined('PmWiki')) exit();
/* Copyright 2004-2009 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 script implements (:pagelist:) and friends -- it's one
of the nastiest scripts you'll ever encounter. Part of the reason
for this is that page listings are so powerful and flexible, so
that adds complexity. They're also expensive, so we have to
optimize them wherever we can.
The core function is FmtPageList(), which will generate a
listing according to a wide variety of options. FmtPageList takes
care of initial option processing, and then calls a "FPL"
(format page list) function to obtain the formatted output.
The FPL function is chosen by the 'fmt=' option to (:pagelist:).
Each FPL function calls MakePageList() to obtain the list
of pages, formats the list somehow, and returns the results
to FmtPageList. FmtPageList then returns the output to
the caller, and calls Keep() (preserves HTML) or PRR() (re-evaluate
as markup) as appropriate for the output being returned.
*/
## $PageIndexFile is the index file for term searches and link= option
if (IsEnabled($EnablePageIndex, 1)) {
SDV($PageIndexFile, "$WorkDir/.pageindex");
$EditFunctions[] = 'PostPageIndex';
}
SDV($StrFoldFunction, 'strtolower');
## $SearchPatterns holds patterns for list= option
SDV($SearchPatterns['all'], array());
SDVA($SearchPatterns['normal'], array(
'recent' => '!\.(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, "<div class='wikisearch'>\$[SearchFor]
<div class='vspace'></div>\$MatchList
<div class='vspace'></div>\$[SearchFound]</div>");
SDV($SearchQuery, str_replace('$', '&#036;',
htmlspecialchars(stripmagic(@$_REQUEST['q']), ENT_NOQUOTES)));
XLSDV('en', array(
'SearchFor' => 'Results of search for <em>$Needle</em>:',
'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("'", "&#039;", $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("'", "&#039;", $v);
$opt[$k] = $v;
if ($k == 'q' || $k == 'label' || $k == 'value' || $k == 'size') continue;
$k = str_replace("'", "&#039;", $k);
$out .= "<input type='hidden' name='$k' value='$v' />";
}
$out .= "<input type='text' name='q' value='{$opt['value']}'
class='inputbox searchbox' size='{$opt['size']}' /><input type='submit'
class='inputbutton searchbutton' value='{$opt['label']}' />";
return '<form '.Keep($out).'</form>';
}
## 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<count($list); $i++)
$list[$i] = &$PCache[$list[$i]];
StopWatch('MakePageList end');
return $list;
}
function PageListProtect(&$list, &$opt, $pn, &$page) {
global $EnablePageListProtect;
switch ($opt['=phase']) {
case PAGELIST_PRE:
if (!IsEnabled($EnablePageListProtect, 1) && @$opt['readf'] < 1000)
return 0;
StopWatch("PageListProtect enabled");
$opt['=protectexclude'] = array();
$opt['=protectsafe'] = (array)@$opt['=protectsafe'];
return PAGELIST_ITEM|PAGELIST_POST;
case PAGELIST_ITEM:
if (@$opt['=protectsafe'][$pn]) return 1;
$page = RetrieveAuthPage($pn, 'ALWAYS', false, READPAGE_CURRENT);
$opt['=readc']++;
if (!$page['=auth']['read']) $opt['=protectexclude'][$pn] = 1;
if (!$page['=passwd']['read']) $opt['=protectsafe'][$pn] = 1;
else NoCache();
return 1;
case PAGELIST_POST:
$excl = array_keys($opt['=protectexclude']);
$safe = array_keys($opt['=protectsafe']);
StopWatch("PageListProtect excluded=" .count($excl)
. ", safe=" . count($safe));
$list = array_diff($list, $excl);
return 1;
}
}
function PageListSources(&$list, &$opt, $pn, &$page) {
global $SearchPatterns;
StopWatch('PageListSources begin');
## add the list= option to our list of pagename filter patterns
$opt['=pnfilter'] = array_merge((array)@$opt['=pnfilter'],
(array)@$SearchPatterns[$opt['list']]);
if (@$opt['group']) $opt['=pnfilter'][] = FixGlob($opt['group'], '$1$2.*');
if (@$opt['name']) $opt['=pnfilter'][] = FixGlob($opt['name'], '$1*.$2');
if (@$opt['trail']) {
$trail = ReadTrail($pn, $opt['trail']);
$tlist = array();
foreach($trail as $tstop) {
$n = $tstop['pagename'];
$tlist[] = $n;
$tstop['parentnames'] = array();
PCache($n, $tstop);
}
foreach($trail as $tstop)
$PCache[$tstop['pagename']]['parentnames'][] =
@$trail[$tstop['parent']]['pagename'];
if (!@$opt['=cached']) $list = MatchPageNames($tlist, $opt['=pnfilter']);
} else if (!@$opt['=cached']) $list = ListPages($opt['=pnfilter']);
StopWatch("PageListSources end count=".count($list));
return 0;
}
function PageListPasswords(&$list, &$opt, $pn, &$page) {
if ($opt['=phase'] == PAGELIST_PRE)
return (@$opt['passwd'] > '' && !@$opt['=cached']) ? PAGELIST_ITEM : 0;
if (!$page) { $page = ReadPage($pn, READPAGE_CURRENT); $opt['=readc']++; }
if (!$page) return 0;
return (boolean)preg_grep('/^passwd/', array_keys($page));
}
function PageListIf(&$list, &$opt, $pn, &$page) {
global $Conditions, $Cursor;
## See if we have any "if" processing to perform
if ($opt['=phase'] == PAGELIST_PRE)
return (@$opt['if'] > '') ? 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['&lt;'] = (string)@$matches[$i-1];
$Cursor['='] = $pn;
$Cursor['>'] = $Cursor['&gt;'] = (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['&lt;'] = $pn;
$Cursor['='] = (string)@$matches[$i+1];
$Cursor['>'] = $Cursor['&gt;'] = (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['&lt;'] = (string)@$matches[$i-1];
$Cursor['='] = $pn;
$Cursor['>'] = $Cursor['&gt;'] = (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 = "<div$class>$out</div>";
}
$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);
}
+214
View File
@@ -0,0 +1,214 @@
<?php if (!defined('PmWiki')) exit();
/* Copyright 2004-2010 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 script defines routines for displaying page revisions. It
is included by default from the stdconfig.php script.
*/
function LinkSuppress($pagename,$imap,$path,$title,$txt,$fmt=NULL)
{ return $txt; }
SDV($DiffShow['minor'],(@$_REQUEST['minor']!='n')?'y':'n');
SDV($DiffShow['source'],(@$_REQUEST['source']!='n')?'y':'n');
SDV($DiffMinorFmt, ($DiffShow['minor']=='y') ?
"<a href='{\$PageUrl}?action=diff&amp;source=".$DiffShow['source']."&amp;minor=n'>$[Hide minor edits]</a>" :
"<a href='{\$PageUrl}?action=diff&amp;source=".$DiffShow['source']."&amp;minor=y'>$[Show minor edits]</a>" );
SDV($DiffSourceFmt, ($DiffShow['source']=='y') ?
"<a href='{\$PageUrl}?action=diff&amp;source=n&amp;minor=".$DiffShow['minor']."'>$[Show changes to output]</a>" :
"<a href='{\$PageUrl}?action=diff&amp;source=y&amp;minor=".$DiffShow['minor']."'>$[Show changes to markup]</a>");
SDV($PageDiffFmt,"<h2 class='wikiaction'>$[{\$FullName} History]</h2>
<p>$DiffMinorFmt - $DiffSourceFmt</p>
");
SDV($DiffStartFmt,"
<div class='diffbox'><div class='difftime'><a name='diff\$DiffGMT' href='#diff\$DiffGMT'>\$DiffTime</a>
\$[by] <span class='diffauthor' title='\$DiffHost'>\$DiffAuthor</span> - \$DiffChangeSum</div>");
SDV($DiffDelFmt['a'],"
<div class='difftype'>\$[Deleted line \$DiffLines:]</div>
<div class='diffdel'>");
SDV($DiffDelFmt['c'],"
<div class='difftype'>\$[Changed line \$DiffLines from:]</div>
<div class='diffdel'>");
SDV($DiffAddFmt['d'],"
<div class='difftype'>\$[Added line \$DiffLines:]</div>
<div class='diffadd'>");
SDV($DiffAddFmt['c'],"</div>
<div class='difftype'>$[to:]</div>
<div class='diffadd'>");
SDV($DiffEndDelAddFmt,"</div>");
SDV($DiffEndFmt,"</div>");
SDV($DiffRestoreFmt,"
<div class='diffrestore'><a href='{\$PageUrl}?action=edit&amp;restore=\$DiffId&amp;preview=y'>$[Restore]</a></div>");
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 .= "<div class='diffmarkup'>"
.$DiffRenderSourceFunction($in, $out, 0)
."</div>";
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 .= "<div class='diffmarkup'>"
.$DiffRenderSourceFunction($in, $out, 1)
."</div>";
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,"<div id='wikidiff'>", 'function:PrintDiff', '</div>',
&$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","<br />",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] = '<del>'. $z2[$a1];
$z2[$a2] .= '</del>';
}
if ($which && ($m[4]=='c'||$m[4]=='a')) {
$z2[$b1] = '<ins>'.$z2[$b1];
$z2[$b2] .= '</ins>';
}
}
}
$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","<br />",$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");
+286
View File
@@ -0,0 +1,286 @@
<?php if (!defined('PmWiki')) exit();
/*
The pagetoc script adds support for automatically generating
a table of contents for a wiki page.
Version 2.0.29 (development version; works with PmWiki beta 13 or above)
Copyright 2004, 2005 John Rankin (john.rankin@affinity.co.nz)
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.
*/
SDV($TocSize,'smaller');
SDV($TocFloat,false);
$HTMLStylesFmt['toc'] = "
span.anchor {
float: left;
font-size: 10px;
margin-left: -10px;
width: 10px;
position:relative; top:-0.1em;
text-align: center;
}
span.anchor a { text-decoration: none; }
span.anchor a:hover { text-decoration: underline; }
ol.toc { text-indent:-20px; list-style: none; }
ol.toc ol.toc { text-indent:-40px; }";
$HTMLStylesFmt['tocf'] = "
div.tocfloat { font-size: $TocSize; margin-bottom: 10px;
border-top: 1px dotted #555555; border-bottom: 1px dotted #555555;
padding-top: 5px; padding-bottom: 5px;
width: 38%; float: right; margin-left: 10px; clear: right;
margin-right:-13px; padding-right: 13px; padding-left: 13px;
background-color: #eeeeee; }
div.toc { font-size: $TocSize;
padding: 4px; border: 1px dotted #cccccc;
background: #f7f7f7;
margin-bottom: 10px; }";
SDV($ToggleText, array('hide', 'show'));
$HTMLHeaderFmt['toggle'] = "<script type=\"text/javascript\">
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]}\";
}
}
</script>";
## 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*-+&gt;\\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 "<em>$anchor</em> not found";
}
}
## [[##visibleanchor]]
SDV($VisibleAnchor,'&sect;');
SDV($VisibleAnchorLinks,false);
SDV($DefaultTocAnchor,'toc');
$RefOrTitle = ($VisibleAnchorLinks) ? 'href' : 'title';
## autonumber anchors
Markup('^!#','<links','/^(!+|Q?:)#(#?)/e',"'$1'.TocAnchor('$2')");
function TocAnchor($visible) {
global $DefaultTocAnchor;
static $toccounter;
return "[[$visible#$DefaultTocAnchor" . ++$toccounter . "]]";
}
## (:markup:) that excludes heading markup examples
function HMarkupMarkup($pagename, $lead, $texta, $textb) {
return "$lead<:block>" .
Keep("<table class='markup' align='center'><tr><td class='markup1'><pre>" .
wordwrap($texta, 70) . "</pre></td></tr><tr><td class='markup2'>") .
"\n$textb\n(:divend:)</td></tr></table>\n";
}
Markup('`markup','<markup',
"/(^|\\(:nl:\\))\\(:markup:\\)[^\\S\n]*\\[([=@])((?:\n`\\.!+.*?)+)\\2\\]/seim",
"HMarkupMarkup(\$pagename, '$1', PSS(str_replace('`.','','$3')), PSS('$3'))");
#Markup("`.",'>links',"/`\./",''); ## included in extendmarkup.php
## page table of contents
$IdPattern = "[A-Za-z][-.:\w]*";
if ($format=='pdf') {
SDV($DefaultTocTitle,'Contents');
SDV($TocHeaderFmt,
'[[#toc]]<tbook:visual markup="bf">$TocTitle</tbook:visual>');
SDV($RemoteTocFmt,
'<tbook:visual markup="bf">Contents of [[$Toc(#toc)]]</tbook:visual>');
} else {
SDV($DefaultTocTitle,'On this page...');
SDV($TocHeaderFmt,'[[#toc]]<b>$TocTitle</b>');
SDV($RemoteTocFmt,'<b>On page [[$Toc(#toc)]]...</b>');
}
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(\"<span class='anchor'><a name='$1' id='$1' $RefOrTitle='#$1'>$VisibleAnchor</a></span>\",
'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,'&uarr; 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&nbsp;";
} elseif ($l2==$len) {
$toc2++; $r = $visibility;
if ($NumberToc) $r .= "$toc1.$toc2&nbsp;";
}
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 = "<tbook:group class='toc'><tbook:p>$toc</tbook:p>".
"<$sc><$l>\$List</$l></$s></tbook:group>";
} elseif ($float=='hide') { return '';
} else {
$tocid = ($float=='page') ? 'ptocid' : 'tocid'; // remote toc?
$toggle = " (<a id=\"{$tocid}tog\" href=\"javascript:toggle('$tocid');\">{$ToggleText[0]}</a>)";
$l = 'li'; $s = ($NumberToc) ? 'ol' : 'ul';
$sc = "$s class='toc'";
$f = ($TocFloat) ? 'float' : '';
$toc = "<div class='toc$f'><p>$toc$toggle</p>" .
"<$sc id='$tocid'><$l>\$List</$l></$s></div>";
}
preg_match_all("/\n(!+|Q?:)\s*(\[\[#+$IdPattern\]\]|#*)([^\n]*)/",$text, $match);
for ($i=0;$i<count($match[0]);$i++) {
if ($match[1][$i]==':' || ($match[1][$i]=='Q:' && $OmitQMarkup)) {
if ($match[2][$i] && $match[2][$i][0]=='#') $counter++;
continue; }
$len = ($match[1][$i]=='Q:') ? 9 : strlen($match[1][$i]);
if ($len==9) $q = 1;
if ($l1==0) { $l1 = $len; $prelen = $l1; }
if ($len!=$l1 && $l2==0) { $l2 = $len; }
if ($len!=$l1 && $len!=$l2 && $q==1 && $l3==0) { $l3 = $len; }
if ($len==$l2 && $l1==9) { $len = $l1; }
if ($len==$l3) { $len = $l2; }
if ($len!=$prelen) {
if ($len==$l1) { $r .= "</$l></$s>"; }
else if ($len==$l2) { $r .= "<$sc><$l>";
$toc2 = 0;
$closel = 0;
}
}
if ($len==$l1 || $len==$l2) {
$prelen = $len;
if ($len==$l1) {
$toc1++;
$tocout = ($NumberToc) ? "$toc1$L1TocChar&nbsp;" : '';
} else {
$toc2++;
$tocout = ($NumberToc) ? "$toc1.$toc2&nbsp;" : '';
}
if ($format=='pdf') $tocout = '';
$m = preg_replace("/^(\\[\\[#)#/","$1",$match[2][$i]);
$m = preg_replace("/^#+/",'',$m);
$t = $match[3][$i];
if ($closel==1) $r .= "</$l><$l>";
$closel = 1;
if (strpos($m,'[#')==1)
$r .= $tocout.str_replace(']]',' | '.
CrossReference($pagename,"$m$t",
preg_replace("/\[\[#(.*?)\]\]/","$1",$m)).']]',$m);
else {
$counter++;
$r .= $tocout."[[#$DefaultTocAnchor$counter | ".
CrossReference($pagename,"[[#]]$t","").']]';
}
}
}
if ($prelen==$l2) $r .= "</$l></$s>";
if ($r!='') $r = str_replace('$List',$r,$toc);
return $r;
}
?>
+39
View File
@@ -0,0 +1,39 @@
<?php if (!defined('PmWiki')) exit();
/* Copyright 2002-2005 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 script enables per-page and per-group customizations in the
local/ subdirectory (or whatever directory is given by $LocalDir).
For example, to create customizations for the 'Demo' group, place
them in a file called local/Demo.php. To customize a single page,
use the full page name (e.g., local/Demo.MyPage.php).
Per-page/per-group customizations can be handled at any time by adding
include_once("scripts/pgcust.php");
to config.php. It is automatically included by scripts/stdconfig.php
unless $EnablePGCust is set to zero in config.php.
A page's customization is loaded first, followed by any group
customization. If no page or group customizations are loaded,
then 'local/default.php' is loaded.
A per-page configuration file can prevent its group's config from
loading by setting $EnablePGCust=0;. A per-page configuration file
can force group customizations to be loaded first by using include_once
on the group customization file.
*/
$f = 1;
for($p=$pagename;$p;$p=preg_replace('/\\.*[^.]*$/','',$p)) {
if (!IsEnabled($EnablePGCust,1)) return;
if (file_exists("$LocalDir/$p.php"))
{ include_once("$LocalDir/$p.php"); $f=0; }
}
if ($f && IsEnabled($EnablePGCust,1) && file_exists("$LocalDir/default.php"))
include_once("$LocalDir/default.php");
+117
View File
@@ -0,0 +1,117 @@
<?php if (!defined('PmWiki')) exit();
/*
Copyright 2003,2004 Nils Knappmeier (nk@knappi.org)
Copyright 2004-2010 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 implements a diff function in native PHP. It is based
upon the PHPDiffEngine code written by Nils Knappmeier, who in turn
had used Daniel Unterberger's diff
(http://www.holomind.de/phpnet/diff.php) as the basis for his code.
Pm's revision of Nils' code simply attempts to streamline it
for speed (eliminate function calls and unnecessary string ops)
and place everything into a single file.
*/
## PHPDiff returns the differences between $old and $new, formatted
## in the standard diff(1) output format.
function PHPDiff($old, $new)
{
StopWatch("PHPDiff: begin");
# split the source text into arrays of lines
$t1 = explode("\n", $old);
$x = array_pop($t1);
if ($x > '') $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';
+47
View File
@@ -0,0 +1,47 @@
<?php if (!defined('PmWiki')) exit();
/* Copyright 2005-2006 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 script handles per-browser preferences. Preference settings
are stored in wiki pages as XLPage translations, and a cookie on
the browser tells PmWiki where to find the browser's preferred
settings.
This script looks for a ?setprefs= request parameter (e.g., in
a url); when it finds one it sets a 'setprefs' cookie on the browser
identifying the page to be used to load browser preferences,
and loads the associated preferences.
If there is no ?setprefs= request, then the script uses the
'setprefs' cookie from the browser to load the preference settings.
*/
SDV($PrefsCookie, $CookiePrefix.'setprefs');
SDV($PrefsCookieExpires, $Now + 60 * 60 * 24 * 365);
$LogoutCookies[] = $PrefsCookie;
$sp = '';
if (@$_COOKIE[$PrefsCookie]) $sp = $_COOKIE[$PrefsCookie];
if (isset($_GET['setprefs'])) {
$sp = $_GET['setprefs'];
setcookie($PrefsCookie, $sp, $PrefsCookieExpires, '/');
}
if ($sp && PageExists($sp)) XLPage('prefs', $sp);
XLSDV('en', array(
'ak_view' => '',
'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' => '',
));
+121
View File
@@ -0,0 +1,121 @@
<?php if (!defined('PmWiki')) exit();
/* Copyright 2004-2006 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 does simple reference counting on pages in a PmWiki site.
Simply activate this script using
include_once('scripts/refcount.php');
in the config.php file and then use ?action=refcount to bring up
the reference count form. The 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,
the number of RecentChanges pages with links to the page, and the
total number of references in all pages.
*/
SDV($PageRefCountFmt,"<h2 class='wikiaction'>Reference Count Results</h2>");
SDV($RefCountTimeFmt," <small>%Y-%b-%d %H:%M</small>");
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 "<form method='post'><input type='hidden' action='refcount'>
<table cellspacing='10'><tr><td valign='top'>Show
<br><select name='whichrefs'>";
foreach($wlist as $w)
echo "<option ",($whichrefs==$w) ? 'selected' : ''," value='$w'>$w\n";
echo "</select></td><td valign='top'> page names in group<br>
<select name='tlist[]' multiple size='4'>";
foreach($grouplist as $g=>$t)
echo "<option ",in_array($g,$tlist) ? 'selected' : ''," value='$g'>$t\n";
echo "</select></td><td valign='top'> referenced from pages in<br>
<select name='flist[]' multiple size='4'>";
foreach($grouplist as $g=>$t)
echo "<option ",in_array($g,$flist) ? 'selected' : ''," value='$g'>$t\n";
echo "</select></td></tr></table>
<p><input type='checkbox' name='showrefs' value='checked' $showrefs>
Display referencing pages
<p><input type='submit' name='submit' value='Search'></form><p><hr>";
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 "<table >
<tr><th></th><th colspan='2'>Referring pages</th></tr>
<tr><th>Name / Time</th><th>All</th><th>R.C.</th></tr>";
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 "<tr><td valign='top'>",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 "<dd>", LinkPage($pagename, '', $pr, '', $pr);
}
echo "</td>";
echo "<td align='center' valign='top'>",@$tref[$p]['page']+0,"</td>";
echo "<td align='center' valign='top'>",@$tref[$p]['rc']+0,"</td>";
echo "</tr>";
}
echo "</table>";
}
}
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);
}
+76
View File
@@ -0,0 +1,76 @@
<?php if (!defined('PmWiki')) exit();
/* Copyright 2005-2006 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 various features to allow PmWiki to control
what web crawlers (robots) see when they visit the site. Of course
it's still possible to control robots at the webserver level
and via robots.txt, but this page provides some finer level
of control.
The $MetaRobots variable controls generation of the
<meta name='robots' ... /> 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 <meta name='robots' ...> tag.
SDV($MetaRobots,
($action!='browse' || !PageExists($pagename)
|| preg_match('#^PmWiki[./](?!PmWiki$)|^Site(Admin)?[./]#', $pagename))
? 'noindex,nofollow' : 'index,follow');
if ($MetaRobots)
$HTMLHeaderFmt['robots'] =
" <meta name='robots' content='\$MetaRobots' />\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("<h1>Not Found</h1>");
exit();
}
header("HTTP/1.1 403 Forbidden");
print("<h1>Forbidden</h1>");
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';
}
+67
View File
@@ -0,0 +1,67 @@
<?php if (!defined('PmWiki')) exit();
/* Copyright 2004-2006 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 enables merging of concurrent edits, using the "diff3"
program available on most Unix systems to merge the edits. If
diff3 is not available or you'd like to use a different command,
then set $SysMergeCmd accordingly.
*/
array_unshift($EditFunctions,'MergeSimulEdits');
$HTMLStylesFmt['simuledit'] = ".editconflict { color:green;
font-style:italic; margin-top:1.33em; margin-bottom:1.33em; }\n";
function Merge($newtext,$oldtext,$pagetext) {
global $WorkDir,$SysMergeCmd;
SDV($SysMergeCmd,"/usr/bin/diff3 -L '' -L '' -L '' -m -E");
if (substr($newtext,-1,1)!="\n") $newtext.="\n";
if (substr($oldtext,-1,1)!="\n") $oldtext.="\n";
if (substr($pagetext,-1,1)!="\n") $pagetext.="\n";
$tempnew = tempnam($WorkDir,"new");
$tempold = tempnam($WorkDir,"old");
$temppag = tempnam($WorkDir,"page");
if ($newfp=fopen($tempnew,'w')) { fputs($newfp,$newtext); fclose($newfp); }
if ($oldfp=fopen($tempold,'w')) { fputs($oldfp,$oldtext); fclose($oldfp); }
if ($pagfp=fopen($temppag,'w')) { fputs($pagfp,$pagetext); fclose($pagfp); }
$mergetext = '';
$merge_handle = popen("$SysMergeCmd $tempnew $tempold $temppag",'r');
if ($merge_handle) {
while (!feof($merge_handle)) $mergetext .= fread($merge_handle,4096);
pclose($merge_handle);
}
@unlink($tempnew); @unlink($tempold); @unlink($temppag);
return $mergetext;
}
function MergeSimulEdits($pagename,&$page,&$new) {
global $Now, $EnablePost, $MessagesFmt, $WorkDir;
if (@!$_POST['basetime'] || !PageExists($pagename)
|| $page['time'] >= $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 &lt;&lt;&lt;&lt;&lt;&lt;&lt; and
&gt;&gt;&gt;&gt;&gt;&gt;&gt;.",
'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[] = "<p class='editconflict'>$ec
(<a target='_blank' href='\$PageUrl?action=diff'>$[View changes]</a>)
</p>\n";
}
+147
View File
@@ -0,0 +1,147 @@
<?php if (!defined('PmWiki')) exit();
/* Copyright 2004-2007 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 implements the skin selection code for PmWiki. Skin
selection is controlled by the $Skin variable, which can also
be an array (in which case the first skin found is loaded).
In addition, $ActionSkin[$action] specifies other skins to be
searched based on the current action.
*/
SDV($Skin, 'pmwiki');
SDV($ActionSkin['print'], 'print');
SDV($FarmPubDirUrl, $PubDirUrl);
SDV($PageLogoUrl, "$FarmPubDirUrl/skins/pmwiki/pmwiki-32.gif");
SDVA($TmplDisplay, array('PageEditFmt' => 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[] = "<link rel='stylesheet' type='text/css' href='$v' />\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<div id='wikitext'>\n");
SDV($PageTextEndFmt, "</div>\n");
SDV($SkinDirectivesPattern,
"[[<]!--((?:wiki|file|function|markup):.*?)--[]>]");
$sddef = array('PageEditFmt' => 0);
$k = implode('', file(FmtPageName($tfilefmt, $pagename)));
if (IsEnabled($EnableSkinDiag, 0)) {
if (!preg_match('/<!--((No)?(HT|X)MLHeader|HeaderText)-->/i', $k))
Abort("Skin template missing &lt;!--HTMLHeader--&gt;", 'htmlheader');
if (!preg_match('/<!--(No)?(HT|X)MLFooter-->/i', $k))
Abort("Skin template missing &lt;!--HTMLFooter--&gt;", '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][] = "<!--$k-->";
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;
## <!--HeaderText--> 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);
}
+89
View File
@@ -0,0 +1,89 @@
<?php if (!defined('PmWiki')) exit();
/* Copyright 2002-2007 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 allows features to be easily enabled/disabled in config.php.
Simply set variables for the features to be enabled/disabled in config.php
before including this file. For example:
$EnableQAMarkup=0; #disable Q: and A: tags
$EnableWikiStyles=1; #include default wikistyles
Each feature has a default setting, if the corresponding $Enable
variable is not set then you get the default.
To avoid processing any of the features of this file, set
$EnableStdConfig = 0;
in config.php.
*/
$pagename = ResolvePageName($pagename);
if (!IsEnabled($EnableStdConfig,1)) return;
if (!function_exists('session_start') && IsEnabled($EnableRequireSession, 1))
Abort('PHP is lacking session support', 'session');
if (IsEnabled($EnablePGCust,1))
include_once("$FarmD/scripts/pgcust.php");
if (IsEnabled($EnableRobotControl,1))
include_once("$FarmD/scripts/robots.php");
if (IsEnabled($EnableCaches, 1))
include_once("$FarmD/scripts/caches.php");
## Scripts that are part of a standard PmWiki distribution.
if (IsEnabled($EnableAuthorTracking,1))
include_once("$FarmD/scripts/author.php");
if (IsEnabled($EnablePrefs, 1))
include_once("$FarmD/scripts/prefs.php");
if (IsEnabled($EnableSimulEdit, 1))
include_once("$FarmD/scripts/simuledit.php");
if (IsEnabled($EnableDrafts, 0))
include_once("$FarmD/scripts/draft.php"); # after simuledit + prefs
if (IsEnabled($EnableSkinLayout,1))
include_once("$FarmD/scripts/skins.php"); # must come after prefs
if (@$Transition || IsEnabled($EnableTransitions, 0))
include_once("$FarmD/scripts/transition.php"); # must come after skins
if (@$LinkWikiWords || IsEnabled($EnableWikiWords, 0))
include_once("$FarmD/scripts/wikiwords.php"); # must come before stdmarkup
if (IsEnabled($EnableStdMarkup,1))
include_once("$FarmD/scripts/stdmarkup.php"); # must come after transition
if ($action=='diff' && @!$HandleActions['diff'])
include_once("$FarmD/scripts/pagerev.php");
if (IsEnabled($EnableWikiTrails,1))
include_once("$FarmD/scripts/trails.php");
if (IsEnabled($EnableWikiStyles,1))
include_once("$FarmD/scripts/wikistyles.php");
if (IsEnabled($EnableMarkupExpressions, 1)
&& !function_exists('MarkupExpression'))
include_once("$FarmD/scripts/markupexpr.php");
if (IsEnabled($EnablePageList,1))
include_once("$FarmD/scripts/pagelist.php");
if (IsEnabled($EnableVarMarkup,1))
include_once("$FarmD/scripts/vardoc.php");
if (!function_exists(@$DiffFunction))
include_once("$FarmD/scripts/phpdiff.php");
if ($action=='crypt')
include_once("$FarmD/scripts/crypt.php");
if ($action=='edit' && IsEnabled($EnableGUIButtons,0))
include_once("$FarmD/scripts/guiedit.php");
if (IsEnabled($EnableForms,1))
include_once("$FarmD/scripts/forms.php"); # must come after prefs
if (IsEnabled($EnableUpload,0))
include_once("$FarmD/scripts/upload.php"); # must come after forms
if (IsEnabled($EnableBlocklist, 0))
include_once("$FarmD/scripts/blocklist.php");
if (IsEnabled($EnableNotify,0))
include_once("$FarmD/scripts/notify.php");
if (IsEnabled($EnableDiag,0))
include_once("$FarmD/scripts/diag.php");
if (IsEnabled($EnableUpgradeCheck,1)) {
SDV($StatusPageName, "$SiteAdminGroup.Status");
$page = ReadPage($StatusPageName, READPAGE_CURRENT);
if (@$page['updatedto'] != $VersionNum)
{ $action = 'upgrade'; include_once("$FarmD/scripts/upgrades.php"); }
}
+500
View File
@@ -0,0 +1,500 @@
<?php if (!defined('PmWiki')) exit();
/* Copyright 2004-2010 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 script defines PmWiki's standard markup. It is automatically
included from stdconfig.php unless $EnableStdMarkup==0.
Each call to Markup() below adds a new rule to PmWiki's translation
engine (unless a rule with the same name has already been defined).
The form of the call is Markup($id,$where,$pat,$rep);
$id is a unique name for the rule, $where is the position of the rule
relative to another rule, $pat is the pattern to look for, and
$rep is the string to replace it with.
*/
## first we preserve text in [=...=] and [@...@]
function PreserveText($sigil, $text, $lead) {
if ($sigil=='=') return $lead.Keep($text);
if (strpos($text, "\n")===false)
return "$lead<code class='escaped'>".Keep($text)."</code>";
$text = preg_replace("/\n[^\\S\n]+$/", "\n", $text);
if ($lead == "" || $lead == "\n")
return "$lead<pre class='escaped'>".Keep($text)."</pre>";
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('<vspace>', '<restore',
'/<vspace>/',
"<div class='vspace'></div>");
Markup('<vspace><p>', '<<vspace>',
"/<vspace><p\\b(([^>]*)(\\s)class=(['\"])([^>]*?)\\4)?/",
"<p$2 class='vspace$3$5'");
## remove carriage returns before preserving text
Markup('\\r','<[=','/\\r/','');
# $[phrase] substitutions
Markup('$[phrase]', '>[=',
'/\\$\\[(?>([^\\]]+))\\]/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:', '<split',
'/\\(:\\w[-\\w]*:(?!\\)).*?:\\)/s', '');
## handle relative text vars in includes
if (IsEnabled($EnableRelativePageVars, 1))
SDV($QualifyPatterns["/\\{([-\\w\\x80-\\xfe]*)(\\$:?\\w+\\})/e"],
"'{' . ('$1' ? MakePageName(\$pagename, '$1') : \$pagename) . '$2'");
## character entities
Markup('&','<if','/&amp;(?>([A-Za-z0-9]+|#\\d+|#[xX][A-Fa-f0-9]+));/',
'&$1;');
Markup('&amp;amp;', '<&', '/&amp;amp;/', Keep('&amp;'));
## (: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',
'/\\(:redirect\\s+(\\S.*?):\\)/ei',
"RedirectMarkup(\$pagename, PSS('$1'))");
$SaveAttrPatterns['/\\(:(if|include|redirect)(\\s.*?)?:\\)/i'] = ' ';
## GroupHeader/GroupFooter handling
Markup('nogroupheader', '>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','<split',"/([^\n])(?>(?:\\(:nl:\\))+)([^\n])/i","$1\n$2");
Markup('nl1','>nl0',"/\\(:nl:\\)/i",'');
## \\$ (end of line joins)
Markup('\\$','>nl1',"/\\\\(?>(\\\\*))\n/e",
"str_repeat('<br />',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') ? '<br />' : '')");
## (: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) ? '<include' : 'directives';
$tmpkeep = IsEnabled($EnablePageTitlePriority, 0) ? '1' : 'NULL';
Markup('title', $tmpwhen,
'/\\(:title\\s(.*?):\\)/ei',
"PZZ(PCache(\$pagename,
\$zz=array('title' => 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("'", '&#039;', $v);
print "<meta name='$n' content='$v' />\n";
}
}
}
#### inline markups ####
## ''emphasis''
Markup("''",'inline',"/''(.*?)''/",'<em>$1</em>');
## '''strong'''
Markup("'''","<''","/'''(.*?)'''/",'<strong>$1</strong>');
## '''''strong emphasis'''''
Markup("'''''","<'''","/'''''(.*?)'''''/",'<strong><em>$1</em></strong>');
## @@code@@
Markup('@@','inline','/@@(.*?)@@/','<code>$1</code>');
## '+big+', '-small-'
Markup("'+","<'''''","/'\\+(.*?)\\+'/",'<big>$1</big>');
Markup("'-","<'''''","/'\\-(.*?)\\-'/",'<small>$1</small>');
## '^superscript^', '_subscript_'
Markup("'^","<'''''","/'\\^(.*?)\\^'/",'<sup>$1</sup>');
Markup("'_","<'''''","/'_(.*?)_'/",'<sub>$1</sub>');
## [+big+], [-small-]
Markup('[+','inline','/\\[(([-+])+)(.*?)\\1\\]/e',
"'<span style=\'font-size:'.(round(pow(6/5,$2strlen('$1'))*100,0)).'%\'>'.
PSS('$3</span>')");
## {+ins+}, {-del-}
Markup('{+','inline','/\\{\\+(.*?)\\+\\}/','<ins>$1</ins>');
Markup('{-','inline','/\\{-(.*?)-\\}/','<del>$1</del>');
## [[<<]] (break)
Markup('[[<<]]','inline','/\\[\\[&lt;&lt;\\]\\]/',"<br clear='all' />");
###### Links ######
## [[free links]]
Markup('[[','links',"/(?>\\[\\[\\s*(.*?)\\]\\])($SuffixPattern)/e",
"Keep(MakeLink(\$pagename,PSS('$1'),NULL,'$2'),'L')");
## [[!Category]]
SDV($CategoryGroup,'Category');
SDV($LinkCategoryFmt,"<a class='categorylink' href='\$LinkUrl'>\$LinkText</a>");
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*-+&gt;\\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') ? '' : \"<a name='$1' id='$1'></a>\", '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','<urllink',
"/\\bmailto:([^\\s$UrlExcludeChars]*[^\\s.,?!$UrlExcludeChars])/e",
"Keep(MakeLink(\$pagename,'$0','$1'),'L')");
## inline images
Markup('img','<urllink',
"/\\b(?>(\\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', '<wikilink',
"/`(($GroupPattern([\\/.]))?($WikiWordPattern))/e",
"Keep('$1')");
#### Block markups ####
## Completely blank lines don't do anything.
Markup('blank', '<block', '/^\\s+$/', '');
## process any <:...> 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'],'<img')===false) ? '$0' :
'<:block,1><div>$1' . ('$4' ? '<br />' : '') .'$5</div>')");
## 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','/^(?>(-+))&gt;\\s?(\\s*)/','<:indent,$1,$1 $2>$2');
Markup('^-<','block','/^(?>(-+))&lt;\\s?(\\s*)/','<:outdent,$1,$1 $2>$2');
## definition lists
Markup('^::','block','/^(:+)(\s*)([^:]+):/','<:dl,$1,$1$2><dt>$2$3</dt><dd>');
## Q: and A:
Markup('^Q:', 'block', '/^Q:(.*)$/', "<:block,1><p class='question'>$1</p>");
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] = '<table '.PQA(PSS('$1')).'>')
.'<:block,1>'");
## headings
Markup('^!', 'block',
'/^(!{1,6})\\s?(.*)$/e',
"'<:block,1><h'.strlen('$1').PSS('>$2</h').strlen('$1').'>'");
## horiz rule
Markup('^----','>^->','/^----+/','<:block,1><hr />');
#### (: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 .= "<table $tattr><tr><$t $attr>";
$cf['table'] = '</tr></table>';
} else if ( preg_match("/nr$/", $name)) $out .= "</tr><tr><$t $attr>";
else $out .= "<$t $attr>";
$cf['cell'] = "</$t>";
} else {
$out .= "<div $attr>";
$cf[$key] = '</div>';
}
return $out;
}
Markup('table', '<block',
'/^\\(:(table|cell|cellnr|head|headnr|tableend|div\\d*(?:end)?)(\\s.*?)?:\\)/ie',
"Cells('$1',PSS('$2'))");
Markup('^>>', '<table',
'/^&gt;&gt;(.+?)&lt;&lt;(.*)$/',
'(:div:)%div $1 apply=div%$2 ');
Markup('^>><<', '<^>>',
'/^&gt;&gt;&lt;&lt;/',
'(: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("'", '&#039;',
"<caption>{$opt['caption']}</caption>");
$class = preg_replace('/[^-\\s\\w]+/', ' ', @$opt['class']);
if (strpos($class, 'horiz') !== false)
{ $sep = ''; $pretext = $MarkupWordwrapFunction($text, 40); }
else
{ $sep = '</tr><tr>'; $pretext = $MarkupWordwrapFunction($text, 75); }
return Keep(@"<table class='markup $class' align='center'>$caption
<tr><td class='markup1' valign='top'><pre>$pretext</pre></td>$sep<td
class='markup2' valign='top'>$html</td></tr></table>");
}
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 <phrase>:) markup/replace-on-save
# pattern.
SDV($ROSPatterns['/\\(:encrypt\\s+([^\\s:=]+).*?:\\)/e'], "crypt(PSS('$1'))");
+127
View File
@@ -0,0 +1,127 @@
<?php if (!defined('PmWiki')) exit();
/* Copyright 2002-2009 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 script enables markup of the form <<|TrailPage|>> 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('<<|','<links','/&lt;&lt;\\|([^|]+|\\[\\[(.+?)\\]\\])\\|&gt;&gt;/e',
"MakeTrailStop(\$pagename,'$1')");
Markup('<|','><<|','/&lt;\\|([^|]+|\\[\\[(.+?)\\]\\])\\|&gt;/e',
"MakeTrailStopB(\$pagename,'$1')");
Markup('^|','<links','/\\^\\|([^|]+|\\[\\[(.+?)\\]\\])\\|\\^/e',
"MakeTrailPath(\$pagename,'$1')");
SDVA($SaveAttrPatterns, array(
'/<<\\|([^|]+|\\[\\[(.+?)\\]\\])\\|>>/' => '$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('/^\\[\\[(.+?)(-&gt;|\\|)(.+?)\\]\\]$/', $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("/\\[\\[([^\\]]*)-&gt;([^\\]]*)\\]\\]/",'[[$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;$i<count($t);$i++) {
if ($t[$i]['pagename']==$pagename) {
if ($i>0) $prev = $t[$i-1]['markup'];
if ($i+1<count($t)) $next = $t[$i+1]['markup'];
}
}
return "<span class='wikitrail'>&lt;&lt; $prev | $trailname | $next &gt;&gt;</span>";
}
function MakeTrailStopB($pagename,$trailname) {
$t = ReadTrail($pagename,$trailname);
$prev = ''; $next = '';
for($i=0;$i<count($t);$i++) {
if ($t[$i]['pagename']==$pagename) {
if ($i>0) $prev = '&lt; '.$t[$i-1]['markup'].' | ';
if ($i+1<count($t)) $next = ' | '.$t[$i+1]['markup'].' &gt;';
}
}
return "<span class='wikitrail'>$prev$trailname$next</span>";
}
function MakeTrailPath($pagename,$trailname) {
global $TrailPathSep;
SDV($TrailPathSep,' | ');
$t = ReadTrail($pagename,$trailname);
$crumbs = '';
for($i=0;$i<count($t);$i++) {
if ($t[$i]['pagename']==$pagename) {
while (@$t[$i]['depth']>0) {
$crumbs = $TrailPathSep.$t[$i]['markup'].$crumbs;
$i = @$t[$i]['parent'];
}
return "<span class='wikitrail'>$trailname$crumbs</span>";
}
}
return "<span class='wikitrail'>$trailname</span>";
}
+277
View File
@@ -0,0 +1,277 @@
<?php if (!defined('PmWiki')) exit();
/* Copyright 2005-2007 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 script handles various "fixup transitions" that might need to
occur to help existing sites smoothly upgrade to newer releases of
PmWiki. Rather than put the workarounds in the main code files, we
try to centralize them here so we can see what's deprecated and a
simple switch (?trans=0 in the url) can tell the admin if his site
is relying on an outdated feature or way of doing things.
Transitions defined in this script:
$Transition['nosessionencode'] - turn off session encoding
$Transition['version'] < 2001967 - all transitions listed above
$Transition['wspre'] - leading spaces are pre text
$Transition['version'] < 2001941 - all transitions listed above
$Transition['wikiwords'] - 2.1-style WikiWord processing
$Transition['version'] < 2001924 - all transitions listed above
$Transition['abslinks'] - absolute links/page vars
$Transition['version'] < 2001901 - all transitions listed above
$Transition['vspace'] - restore <p class='vspace'></p>
$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
## <span class='wikiword'>...</span> 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'] = "</div>";
$out .= "<div $attr>";
}
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'] = "</td></tr></table>";
$out .= "<table $tattr><tr><td $attr>";
} else if ($name == 'cellnr') $out .= "</td></tr><tr><td $attr>";
else $out .= "</td><td $attr>";
}
return $out;
}
Markup('table', '<block',
'/^\\(:(table|cell|cellnr|tableend|div|divend)(\\s.*?)?:\\)/ie',
"TCells('$1',PSS('$2'))");
}
## Transitions from 2.1.7
if (@$Transition['version'] < 2001007)
SDVA($Transition, array('vspace' => 1));
## vspace:
## This restores PmWiki's use of <p class='vspace'></p> to mark
## vertical space in the output.
if (@$Transition['vspace']) $HTMLVSpace = "<p class='vspace'></p>";
## 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,"<dl class='fplbygroup'>");
SDV($FPLByGroupEndFmt,'</dl>');
SDV($FPLByGroupGFmt,"<dt><a href='\$ScriptUrl/\$Group'>\$Group</a> /</dt>\n");
SDV($FPLByGroupIFmt,"<dd><a href='\$PageUrl'>\$Name</a></dd>\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, "<div id='wikiedit'>
<a id='top' name='top'></a>
<h1 class='wikiaction'>$[Editing \$FullName]</h1>
<form method='post' action='\$PageUrl?action=edit'>
<input type='hidden' name='action' value='edit' />
<input type='hidden' name='n' value='\$FullName' />
<input type='hidden' name='basetime' value='\$EditBaseTime' />
\$EditMessageFmt
<textarea id='text' name='text' rows='25' cols='60'
onkeydown='if (event.keyCode==27) event.returnValue=false;'
>\$EditText</textarea><br />
$[Author]: <input type='text' name='author' value='\$Author' />
<input type='checkbox' name='diffclass' value='minor' \$DiffClassMinor />
$[This is a minor edit]<br />
<input type='submit' name='post' value=' $[Save] ' />
<input type='submit' name='preview' value=' $[Preview] ' />
<input type='reset' value=' $[Reset] ' /></form></div>");
if (@$_POST['preview'])
SDV($PagePreviewFmt, "<div id='wikipreview'>
<h2 class='wikiaction'>$[Preview \$FullName]</h2>
<p><b>$[Page is unsaved]</b></p>
\$PreviewText
<hr /><p><b>$[End of preview -- remember to save]</b><br />
<a href='#top'>$[Top]</a></p></div>");
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'),
));
}
+98
View File
@@ -0,0 +1,98 @@
<?php if (!defined('PmWiki')) exit();
/* Copyright 2007 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.
*/
$HandleActions['upgrade'] = 'HandleUpgrade';
$HandleAuth['upgrade'] = 'read';
function HandleUpgrade($pagename, $auth = 'ALWAYS') {
global $SiteGroup, $SiteAdminGroup, $StatusPageName, $ScriptUrl,
$AuthUserPageFmt, $VersionNum, $Version;
StopWatch('HandleUpgrade: begin');
$message = '';
$done = '';
## check for Site.* --> 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 .= "<li>Copied $n0 to $n1</li>";
continue;
}
}
$message .= "<li>$n0 -&gt; $n1</li>";
}
if ($message) {
$migrateurl = "$ScriptUrl?action=upgrade&amp;migrate=yes";
$infourl = 'http://www.pmwiki.org/wiki/PmWiki/UpgradeToSiteAdmin';
$message =
"<h2>Upgrade notice -- SiteAdmin group</h2>
<p>This version of PmWiki expects several administrative pages
from the <em>Site</em> group to be found in a new <em>SiteAdmin</em> group.
On this site, the following pages appear to need to be relocated:</p>
<ul>$message</ul>
<p>For more information about this change, including the various
options for proceeding, see</p>
<blockquote><a target='_blank' href='$infourl'>$infourl</a></blockquote>
<form action='$ScriptUrl' method='post'>
<p>If you would like PmWiki to attempt to automatically copy
these pages into their new <br /> locations for you, try
<input type='hidden' name='action' value='upgrade' />
<input type='hidden' name='migrate' value='yes' />
<input type='submit' value='Relocate pages listed above' />
(admin password required) </p>
</form>
<p>If you want to configure PmWiki so that it continues to
look for the above pages in <em>$SiteGroup</em>, add the
following line near the top of <em>local/config.php</em>:</p>
<blockquote><pre>\$SiteAdminGroup = \$SiteGroup;</pre></blockquote>
$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 .= "<li>Updated $StatusPageName</li>";
echo "<h2>Upgrade to $Version ... ok</h2><ul>$done</ul>";
$GLOBALS['EnableRedirect'] = 0;
}
Redirect($pagename);
}
+327
View File
@@ -0,0 +1,327 @@
<?php if (!defined('PmWiki')) exit();
/* Copyright 2004-2009 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 script adds upload capabilities to PmWiki. Uploads can be
enabled by setting
$EnableUpload = 1;
in config.php. In addition, an upload password must be set, as
the default is to lock uploads. In some configurations it may also
be necessary to set values for $UploadDir and $UploadUrlFmt,
especially if any form of URL rewriting is being performed.
See the PmWiki.UploadsAdmin page for more information.
*/
## $EnableUploadOverwrite determines if we allow previously uploaded
## files to be overwritten.
SDV($EnableUploadOverwrite,1);
## $UploadExts contains the list of file extensions we're willing to
## accept, along with the Content-Type: value appropriate for each.
SDVA($UploadExts,array(
'gif' => '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, "<a rel='nofollow' class='createlinktext' href='\$LinkUpload'>\$LinkText</a><a rel='nofollow' class='createlink' href='\$LinkUpload'>&nbsp;&Delta;</a>");
SDVA($ActionTitleFmt, array('upload' => '| $[Attach]'));
SDV($PageUploadFmt,array("
<div id='wikiupload'>
<h2 class='wikiaction'>$[Attachments for] {\$FullName}</h2>
<h3>\$UploadResult</h3>
<form enctype='multipart/form-data' action='{\$PageUrl}' method='post'>
<input type='hidden' name='n' value='{\$FullName}' />
<input type='hidden' name='action' value='postupload' />
<table border='0'>
<tr><td align='right'>$[File to upload:]</td><td><input
name='uploadfile' type='file' /></td></tr>
<tr><td align='right'>$[Name attachment as:]</td>
<td><input type='text' name='upname' value='\$UploadName' /><input
type='submit' value=' $[Upload] ' /><br />
</td></tr></table></form></div>",
'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('<ul>'.FmtUploadList('$pagename',PSS('$1')).'</ul>')");
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&amp;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&amp;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("<i>$uprname</i>: $[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&amp;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("<a rel='nofollow' class='createlink'
href='\$PageUrl?action=upload&amp;upname=$file'>&nbsp;&Delta;</a>",
$pagename);
$out[] = "<li> <a href='$name'>$file</a>$overwrite ... ".
number_format($stat['size']) . " bytes ... " .
strftime($TimeFmt, $stat['mtime']) . "</li>";
}
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;
}
+125
View File
@@ -0,0 +1,125 @@
<?php if (!defined('PmWiki')) exit();
/* Copyright 2004-2006 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 script provides a URL-approval capability. To enable this
script, add the following line to a configuration file:
include_once('scripts/urlapprove.php');
The URL prefixes to be allowed are stored as patterns in
$WhiteUrlPatterns. This array can be loaded from config.php, or
from the wiki pages given by the $ApprovedUrlPagesFmt[] array.
Any http: or https: URL that isn't in $WhiteUrlPatterns is rendered
using $UnapprovedLinkFmt.
The script also provides ?action=approveurls and ?action=approvesites,
which scan the current page for any new URLs to be automatically added
the first page of $UrlApprovalPagesFmt.
Finally, the script will block any post containing more than
$UnapprovedLinkCountMax unapproved urls in it. By default this
is set to a very large number, leaving the posting of unapproved
urls wide open, but by setting $UnapprovedLinkCountMax to a smaller
number you can limit the number of unapproved urls that make it into
a page. (Wikispammers seem to like to post long lists of urls, while
more "normal" authors tend to only post a few.)
*/
$LinkFunctions['http:'] = 'LinkHTTP';
$LinkFunctions['https:'] = 'LinkHTTP';
SDV($ApprovedUrlPagesFmt, array('$SiteAdminGroup.ApprovedUrls'));
SDV($UnapprovedLinkFmt,
"\$LinkText<a class='apprlink' href='{\$PageUrl}?action=approvesites'>$[(approve sites)]</a>");
$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('&#34;','&#39;'),$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;
}
+78
View File
@@ -0,0 +1,78 @@
<?php if (!defined('PmWiki')) exit();
/* Copyright 2002-2005 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 script provides special handling for WikiWords that are
preceded by a $, treating them as PmWiki variables to be looked up
in the variable documentation pages if such documentation exists.
The $VarPagesFmt variable contains a list of pages to be searched
to build an index of the variable documentation. This index is
generated only once per browse request, and then only when needed.
*/
SDV($VarPagesFmt,array('$[PmWiki.Variables]'));
Markup('varlink','<wikilink',"/\\$($WikiWordPattern)\\b/e",
"Keep(VarLink(\$pagename,'$1','$$1'))");
Markup('vardef','<links',"/^:\\$($WikiWordPattern):/",
':[[#$1]]$$1:');
Markup('varindex', 'directives',
'/\\(:varindex:\\)/ei',
"Keep(VarIndexList(\$pagename))");
$HTMLStylesFmt['vardoc'] = "a.varlink { text-decoration:none; }\n";
function VarLink($pagename,$tgt,$txt) {
global $VarIndex,$FmtV,$VarLinkMissingFmt,$VarLinkExistsFmt;
SDV($VarLinkMissingFmt,'$LinkText');
SDV($VarLinkExistsFmt,"<a class='varlink' href='\$LinkUrl'><code class='varlink'>\$LinkText</code></a>");
VarIndexLoad($pagename);
$FmtV['$LinkText'] = str_replace('$', '&#36;', $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;$i<count($t);$i++)
if (@!$loaded[$t[$i]['pagename']]) $vlist[]=$t[$i]['pagename'];
foreach($vlist as $vname) {
$vpage = ReadPage($vname, READPAGE_CURRENT); @$loaded[$vname]++;
if (!$vpage) continue;
if (!preg_match_all("/\n:\\$([[:upper:]]\\w+):/",@$vpage['text'],$match))
continue;
foreach($match[1] as $n) {
$VarIndex[$n]['pagename'] = $vname;
$VarIndex[$n]['url'] = FmtPageName("{\$PageUrl}#$n",$vname);
}
}
}
}
# VarIndexList() generates a table of all indexed variables.
function VarIndexList($pagename) {
global $VarIndex;
if (!isset($VarIndex)) VarIndexLoad($pagename);
ksort($VarIndex);
$out = "<table><tr><th>Variable</th><th>Documented in</th></tr>\n";
foreach($VarIndex as $v=>$a)
$out .= FmtPageName("<tr><td><a class='varlink'
href='{$a['url']}'><code>&#036;$v</code></a></td><td><a
href='{\$PageUrl}'>{\$Name}</a></td></tr>\n",$a['pagename']);
$out .= "</table>";
return $out;
}
+1
View File
@@ -0,0 +1 @@
<?php $Version="pmwiki-2.2.13"; $VersionNum=2002013;
+186
View File
@@ -0,0 +1,186 @@
<?php if (!defined('PmWiki')) exit();
/* Copyright 2004-2009 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.
*/
SDV($WikiStylePattern,'%%|%[A-Za-z][-,=:#\\w\\s\'"().]*%');
## %% markup
Markup('%%','style','%','return ApplyStyles($x);');
## %define=...% markup on a line by itself
Markup('%define=', '>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;
}
+69
View File
@@ -0,0 +1,69 @@
<?php if (!defined('PmWiki')) exit();
/* Copyright 2001-2007 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 script adds WikiWord (CamelCase) processing to PmWiki.
Originally WikiWords were part of the default configuration,
but their usage has died out over time and so it's now optional.
To enable WikiWord links, simply add the following to
a local customization file:
$EnableWikiWords = 1;
To have PmWiki recognize and process WikiWords but not link
them (i.e., the default behavior in PmWiki 2.1), also add
$LinkWikiWords = 0;
If you want only the first occurrence of a WikiWord to be converted
to a link, set $WikiWordCountMax=1.
$WikiWordCountMax = 1; # converts only first WikiWord
$WikiWordCountMax = 0; # another way to disable WikiWord links
The $WikiWordCount array can be used to control the number of times
a WikiWord is converted to a link. This is useful for disabling
or limiting specific WikiWords.
$WikiWordCount['PhD'] = 0; # disables 'PhD'
$WikiWordCount['PmWiki'] = 1; # convert only first 'PmWiki'
$WikiWordCount['WikiWord'] = -1; # ignore $SpaceWikiWord setting
By default, PmWiki is configured such that only the first occurrence
of 'PmWiki' in a page is treated as a WikiWord. If you want to
restore 'PmWiki' to be treated like other WikiWords, uncomment the
line below.
unset($WikiWordCount['PmWiki']);
If you want to disable WikiWords matching a pattern, you can use
something like the following. Note that the first argument has to
be different for each call to Markup(). The example below disables
WikiWord links like COM1, COM2, COM1234, etc.
Markup('COM\d+', '<wikilink', '/\\bCOM\\d+/', "Keep('$0')");
*/
SDV($LinkWikiWords, 1);
## bare wikilinks
Markup('wikilink', '>urllink',
"/\\b(?<![#&])($GroupPattern([\\/.]))?($WikiWordPattern)/e",
"Keep('<span class=\\'wikiword\\'>'.WikiLink(\$pagename,'$0').'</span>',
'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);
}
+12
View File
@@ -0,0 +1,12 @@
<?php if (!defined('PmWiki')) exit();
/* Copyright 2005 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.
*/
global $HTTPHeaders;
$HTTPHeaders[] = "Content-type: text/html; charset=iso-8859-13;";
+63
View File
@@ -0,0 +1,63 @@
<?php
/* 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 is used to enable the iso-8859-2 character set in PmWiki.
The first part converts the charset to iso-8859-2 and removes
conflicts for newline and keep tokens; the second part
handles the conversion of pagenames from utf-8 (sent by browsers)
into iso-8859-2 if needed.
*/
global $HTTPHeaders, $pagename, $KeepToken;
$HTTPHeaders[] = "Content-Type: text/html; charset=iso-8859-2;";
$KeepToken = "\263\263\263";
$pagename = $_REQUEST['n'];
if (!$pagename) $pagename = @$_GET['pagename'];
if ($pagename=='' && $EnablePathInfo)
$pagename = @substr($_SERVER['PATH_INFO'],1);
if (!$pagename &&
preg_match('!^'.preg_quote($_SERVER['SCRIPT_NAME'],'!').'/?([^?]*)!',
$_SERVER['REQUEST_URI'],$match))
$pagename = urldecode($match[1]);
$pagename = preg_replace('!/+$!','',$pagename);
if (!preg_match('/[\\x80-\\x9f]/', $pagename)) return;
if (function_exists('iconv'))
$pagename = iconv('UTF-8','ISO-8859-2',$pagename);
else {
$conv = array(
' '=>' ', 'Ä„'=>'¡', '˘'=>'¢', '=>'£',
'¤'=>'¤', 'Ľ'=>'¥', 'Åš'=>'¦', '§'=>'§',
'¨'=>'¨', 'Å '=>'©', 'Åž'=>'ª', 'Ť'=>'«',
'Ź'=>'¬', '­'=>'­', 'Ž'=>'®', 'Å»'=>'¯',
'°'=>'°', 'Ä…'=>'±', 'Ë›'=>'²', 'Å‚'=>'³',
'´'=>'´', 'ľ'=>'µ', 'Å›'=>'¶', 'ˇ'=>'·',
'¸'=>'¸', 'Å¡'=>'¹', 'ÅŸ'=>'º', 'Å¥'=>'»',
'ź'=>'¼', '=>'½', 'ž'=>'¾', 'ż'=>'¿',
'Å”'=>'À', '=>'Á', 'Â'=>'Â', 'Ä‚'=>'Ã',
'Ä'=>'Ä', 'Ĺ'=>'Å', 'Ć'=>'Æ', 'Ç'=>'Ç',
'ÄŒ'=>'È', 'É'=>'É', 'Ę'=>'Ê', 'Ë'=>'Ë',
'Äš'=>'Ì', '=>'Í', 'ÃŽ'=>'Î', 'ÄŽ'=>'Ï',
'=>'Ð', 'Ń'=>'Ñ', 'Ň'=>'Ò', 'Ó'=>'Ó',
'Ô'=>'Ô', '=>'Õ', 'Ö'=>'Ö', '×'=>'×',
'Ř'=>'Ø', 'Å®'=>'Ù', 'Ú'=>'Ú', 'Ű'=>'Û',
'Ü'=>'Ü', '=>'Ý', 'Å¢'=>'Þ', 'ß'=>'ß',
'Å•'=>'à', 'á'=>'á', 'â'=>'â', 'ă'=>'ã',
'ä'=>'ä', 'ĺ'=>'å', 'ć'=>'æ', 'ç'=>'ç',
'=>'è', 'é'=>'é', 'Ä™'=>'ê', 'ë'=>'ë',
'Ä›'=>'ì', 'í'=>'í', 'î'=>'î', '=>'ï',
'Ä‘'=>'ð', 'Å„'=>'ñ', 'ň'=>'ò', 'ó'=>'ó',
'ô'=>'ô', 'Å‘'=>'õ', 'ö'=>'ö', '÷'=>'÷',
'Å™'=>'ø', 'ů'=>'ù', 'ú'=>'ú', 'ű'=>'û',
'ü'=>'ü', 'ý'=>'ý', 'Å£'=>'þ', 'Ë™'=>'ÿ',
);
$pagename = str_replace(array_keys($conv),array_values($conv),$pagename);
}
+12
View File
@@ -0,0 +1,12 @@
<?php if (!defined('PmWiki')) exit();
/* Copyright 2005 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.
*/
global $HTTPHeaders;
$HTTPHeaders[] = "Content-type: text/html; charset=iso-8859-9;";
+602
View File
@@ -0,0 +1,602 @@
<?php if (!defined('PmWiki')) exit();
/* Copyright 2004-2010 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 script configures PmWiki to use utf-8 in page content and
pagenames. There are some unfortunate side effects about PHP's
utf-8 implementation, however. First, since PHP doesn't have a
way to do pattern matching on upper/lowercase UTF-8 characters,
WikiWords are limited to the ASCII-7 set, and all links to page
names with UTF-8 characters have to be in double brackets.
Second, we have to assume that all non-ASCII characters are valid
in pagenames, since there's no way to determine which UTF-8
characters are "letters" and which are punctuation.
*/
global $HTTPHeaders, $KeepToken, $pagename,
$GroupPattern, $NamePattern, $WikiWordPattern, $SuffixPattern,
$PageNameChars, $MakePageNamePatterns, $CaseConversions, $StringFolding,
$Charset, $HTMLHeaderFmt, $StrFoldFunction, $AsSpacedFunction;
$Charset = 'UTF-8';
$HTTPHeaders['utf-8'] = 'Content-type: text/html; charset=UTF-8';
$HTMLHeaderFmt['utf-8'] =
"<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />";
$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"
));
+50
View File
@@ -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
+8
View File
@@ -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
+8
View File
@@ -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

Some files were not shown because too many files have changed in this diff Show More