initial, fully functional build complete
@@ -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 .
|
||||
@@ -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'>",
|
||||
"/&(.*?);/" => "&\\1;",
|
||||
);
|
||||
|
||||
$text = str_replace(array_keys($astr), $astr, $text);
|
||||
$text = Markdown($text);
|
||||
$text = preg_replace(array_keys($pstr), $pstr, $text);
|
||||
|
||||
return $text;
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -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.
|
||||
@@ -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 .
|
||||
|
||||
@@ -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!
|
||||
@@ -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
|
||||
@@ -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ü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:)';
|
||||
@@ -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.
|
||||
|
After Width: | Height: | Size: 772 B |
|
After Width: | Height: | Size: 724 B |
|
After Width: | Height: | Size: 663 B |
|
After Width: | Height: | Size: 651 B |
|
After Width: | Height: | Size: 710 B |
|
After Width: | Height: | Size: 716 B |
@@ -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;
|
||||
}
|
||||
|
After Width: | Height: | Size: 691 B |
|
After Width: | Height: | Size: 696 B |
|
After Width: | Height: | Size: 699 B |
|
After Width: | Height: | Size: 700 B |
|
After Width: | Height: | Size: 664 B |
|
After Width: | Height: | Size: 662 B |
|
After Width: | Height: | Size: 649 B |
|
After Width: | Height: | Size: 741 B |
|
After Width: | Height: | Size: 677 B |
|
After Width: | Height: | Size: 657 B |
|
After Width: | Height: | Size: 707 B |
|
After Width: | Height: | Size: 722 B |
|
After Width: | Height: | Size: 648 B |
|
After Width: | Height: | Size: 643 B |
|
After Width: | Height: | Size: 703 B |
|
After Width: | Height: | Size: 752 B |
|
After Width: | Height: | Size: 712 B |
|
After Width: | Height: | Size: 716 B |
|
After Width: | Height: | Size: 719 B |
|
After Width: | Height: | Size: 654 B |
|
After Width: | Height: | Size: 668 B |
|
After Width: | Height: | Size: 712 B |
@@ -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}
|
||||
|
After Width: | Height: | Size: 327 B |
@@ -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');
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -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; }
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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
|
||||
@@ -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; }
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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>
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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]"'),
|
||||
|
||||
));
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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"
|
||||
' ' => ' ',
|
||||
'¡' => '¡',
|
||||
'¢' => '¢',
|
||||
'£' => '£',
|
||||
'¤' => '¤',
|
||||
'¥' => '¥',
|
||||
'¦' => '¦',
|
||||
'§' => '§',
|
||||
'¨' => '¨',
|
||||
'©' => '©',
|
||||
'ª' => 'ª',
|
||||
'«' => '«',
|
||||
'¬' => '¬',
|
||||
'­' => '­',
|
||||
'®' => '®',
|
||||
'¯' => '¯',
|
||||
'°' => '°',
|
||||
'±' => '±',
|
||||
'²' => '²',
|
||||
'³' => '³',
|
||||
'´' => '´',
|
||||
'µ' => 'µ',
|
||||
'¶' => '¶',
|
||||
'·' => '·',
|
||||
'¸' => '¸',
|
||||
'¹' => '¹',
|
||||
'º' => 'º',
|
||||
'»' => '»',
|
||||
'¼' => '¼',
|
||||
'½' => '½',
|
||||
'¾' => '¾',
|
||||
'¿' => '¿',
|
||||
'À' => 'À',
|
||||
'Á' => 'Á',
|
||||
'Â' => 'Â',
|
||||
'Ã' => 'Ã',
|
||||
'Ä' => 'Ä',
|
||||
'Å' => 'Å',
|
||||
'Æ' => 'Æ',
|
||||
'Ç' => 'Ç',
|
||||
'È' => 'È',
|
||||
'É' => 'É',
|
||||
'Ê' => 'Ê',
|
||||
'Ë' => 'Ë',
|
||||
'Ì' => 'Ì',
|
||||
'Í' => 'Í',
|
||||
'Î' => 'Î',
|
||||
'Ï' => 'Ï',
|
||||
'Ð' => 'Ð',
|
||||
'Ñ' => 'Ñ',
|
||||
'Ò' => 'Ò',
|
||||
'Ó' => 'Ó',
|
||||
'Ô' => 'Ô',
|
||||
'Õ' => 'Õ',
|
||||
'Ö' => 'Ö',
|
||||
'×' => '×',
|
||||
'Ø' => 'Ø',
|
||||
'Ù' => 'Ù',
|
||||
'Ú' => 'Ú',
|
||||
'Û' => 'Û',
|
||||
'Ü' => 'Ü',
|
||||
'Ý' => 'Ý',
|
||||
'Þ' => 'Þ',
|
||||
'ß' => 'ß',
|
||||
'à' => 'à',
|
||||
'á' => 'á',
|
||||
'â' => 'â',
|
||||
'ã' => 'ã',
|
||||
'ä' => 'ä',
|
||||
'å' => 'å',
|
||||
'æ' => 'æ',
|
||||
'ç' => 'ç',
|
||||
'è' => 'è',
|
||||
'é' => 'é',
|
||||
'ê' => 'ê',
|
||||
'ë' => 'ë',
|
||||
'ì' => 'ì',
|
||||
'í' => 'í',
|
||||
'î' => 'î',
|
||||
'ï' => 'ï',
|
||||
'ð' => 'ð',
|
||||
'ñ' => 'ñ',
|
||||
'ò' => 'ò',
|
||||
'ó' => 'ó',
|
||||
'ô' => 'ô',
|
||||
'õ' => 'õ',
|
||||
'ö' => 'ö',
|
||||
'÷' => '÷',
|
||||
'ø' => 'ø',
|
||||
'ù' => 'ù',
|
||||
'ú' => 'ú',
|
||||
'û' => 'û',
|
||||
'ü' => 'ü',
|
||||
'ý' => 'ý',
|
||||
'þ' => 'þ',
|
||||
'ÿ' => 'ÿ',
|
||||
# entities defined in "http://www.w3.org/TR/xhtml1/DTD/xhtml-special.ent"
|
||||
'"' => '"',
|
||||
#'&' => '&#38;',
|
||||
#'<' => '&#60;',
|
||||
#'>' => '>',
|
||||
''' => ''',
|
||||
'Œ' => 'Œ',
|
||||
'œ' => 'œ',
|
||||
'Š' => 'Š',
|
||||
'š' => 'š',
|
||||
'Ÿ' => 'Ÿ',
|
||||
'ˆ' => 'ˆ',
|
||||
'˜' => '˜',
|
||||
' ' => ' ',
|
||||
' ' => ' ',
|
||||
' ' => ' ',
|
||||
'‌' => '‌',
|
||||
'‍' => '‍',
|
||||
'‎' => '‎',
|
||||
'‏' => '‏',
|
||||
'–' => '–',
|
||||
'—' => '—',
|
||||
'‘' => '‘',
|
||||
'’' => '’',
|
||||
'‚' => '‚',
|
||||
'“' => '“',
|
||||
'”' => '”',
|
||||
'„' => '„',
|
||||
'†' => '†',
|
||||
'‡' => '‡',
|
||||
'‰' => '‰',
|
||||
'‹' => '‹',
|
||||
'›' => '›',
|
||||
'€' => '€',
|
||||
# entities defined in "http://www.w3.org/TR/xhtml1/DTD/xhtml-symbol.ent"
|
||||
'ƒ' => 'ƒ',
|
||||
'Α' => 'Α',
|
||||
'Β' => 'Β',
|
||||
'Γ' => 'Γ',
|
||||
'Δ' => 'Δ',
|
||||
'Ε' => 'Ε',
|
||||
'Ζ' => 'Ζ',
|
||||
'Η' => 'Η',
|
||||
'Θ' => 'Θ',
|
||||
'Ι' => 'Ι',
|
||||
'Κ' => 'Κ',
|
||||
'Λ' => 'Λ',
|
||||
'Μ' => 'Μ',
|
||||
'Ν' => 'Ν',
|
||||
'Ξ' => 'Ξ',
|
||||
'Ο' => 'Ο',
|
||||
'Π' => 'Π',
|
||||
'Ρ' => 'Ρ',
|
||||
'Σ' => 'Σ',
|
||||
'Τ' => 'Τ',
|
||||
'Υ' => 'Υ',
|
||||
'Φ' => 'Φ',
|
||||
'Χ' => 'Χ',
|
||||
'Ψ' => 'Ψ',
|
||||
'Ω' => 'Ω',
|
||||
'α' => 'α',
|
||||
'β' => 'β',
|
||||
'γ' => 'γ',
|
||||
'δ' => 'δ',
|
||||
'ε' => 'ε',
|
||||
'ζ' => 'ζ',
|
||||
'η' => 'η',
|
||||
'θ' => 'θ',
|
||||
'ι' => 'ι',
|
||||
'κ' => 'κ',
|
||||
'λ' => 'λ',
|
||||
'μ' => 'μ',
|
||||
'ν' => 'ν',
|
||||
'ξ' => 'ξ',
|
||||
'ο' => 'ο',
|
||||
'π' => 'π',
|
||||
'ρ' => 'ρ',
|
||||
'ς' => 'ς',
|
||||
'σ' => 'σ',
|
||||
'τ' => 'τ',
|
||||
'υ' => 'υ',
|
||||
'φ' => 'φ',
|
||||
'χ' => 'χ',
|
||||
'ψ' => 'ψ',
|
||||
'ω' => 'ω',
|
||||
'ϑ' => 'ϑ',
|
||||
'ϒ' => 'ϒ',
|
||||
'ϖ' => 'ϖ',
|
||||
'•' => '•',
|
||||
'…' => '…',
|
||||
'′' => '′',
|
||||
'″' => '″',
|
||||
'‾' => '‾',
|
||||
'⁄' => '⁄',
|
||||
'℘' => '℘',
|
||||
'ℑ' => 'ℑ',
|
||||
'ℜ' => 'ℜ',
|
||||
'™' => '™',
|
||||
'ℵ' => 'ℵ',
|
||||
'←' => '←',
|
||||
'↑' => '↑',
|
||||
'→' => '→',
|
||||
'↓' => '↓',
|
||||
'↔' => '↔',
|
||||
'↵' => '↵',
|
||||
'⇐' => '⇐',
|
||||
'⇑' => '⇑',
|
||||
'⇒' => '⇒',
|
||||
'⇓' => '⇓',
|
||||
'⇔' => '⇔',
|
||||
'∀' => '∀',
|
||||
'∂' => '∂',
|
||||
'∃' => '∃',
|
||||
'∅' => '∅',
|
||||
'∇' => '∇',
|
||||
'∈' => '∈',
|
||||
'∉' => '∉',
|
||||
'∋' => '∋',
|
||||
'∏' => '∏',
|
||||
'∑' => '∑',
|
||||
'−' => '−',
|
||||
'∗' => '∗',
|
||||
'√' => '√',
|
||||
'∝' => '∝',
|
||||
'∞' => '∞',
|
||||
'∠' => '∠',
|
||||
'∧' => '∧',
|
||||
'∨' => '∨',
|
||||
'∩' => '∩',
|
||||
'∪' => '∪',
|
||||
'∫' => '∫',
|
||||
'∴' => '∴',
|
||||
'∼' => '∼',
|
||||
'≅' => '≅',
|
||||
'≈' => '≈',
|
||||
'≠' => '≠',
|
||||
'≡' => '≡',
|
||||
'≤' => '≤',
|
||||
'≥' => '≥',
|
||||
'⊂' => '⊂',
|
||||
'⊃' => '⊃',
|
||||
'⊄' => '⊄',
|
||||
'⊆' => '⊆',
|
||||
'⊇' => '⊇',
|
||||
'⊕' => '⊕',
|
||||
'⊗' => '⊗',
|
||||
'⊥' => '⊥',
|
||||
'⋅' => '⋅',
|
||||
'⌈' => '⌈',
|
||||
'⌉' => '⌉',
|
||||
'⌊' => '⌊',
|
||||
'⌋' => '⌋',
|
||||
'⟨' => '〈',
|
||||
'⟩' => '〉',
|
||||
'◊' => '◊',
|
||||
'♠' => '♠',
|
||||
'♣' => '♣',
|
||||
'♥' => '♥',
|
||||
'♦' => '♦'));
|
||||
|
||||
@@ -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("'", ''', MarkupRestore($opt[$a]) ));
|
||||
$attr[] = "$a='".str_replace("'", ''', $opt[$a])."'";
|
||||
}
|
||||
$FmtV['$InputFormArgs'] = implode(' ', $attr);
|
||||
return FmtPageName($opt[':html'], $pagename);
|
||||
}
|
||||
|
||||
|
||||
## InputMarkup handles the (:input ...:) directive. It either
|
||||
## calls any function given by the :fn element of the corresponding
|
||||
## tag, or else just returns the result of InputToHTML().
|
||||
function InputMarkup($pagename, $type, $args) {
|
||||
global $InputTags;
|
||||
$fn = @$InputTags[$type][':fn'];
|
||||
if ($fn) return $fn($pagename, $type, $args);
|
||||
return Keep(InputToHTML($pagename, $type, $args, $opt));
|
||||
}
|
||||
|
||||
|
||||
## (:input default:) directive.
|
||||
function InputDefault($pagename, $type, $args) {
|
||||
global $InputValues, $PageTextVarPatterns, $PCache;
|
||||
$args = ParseArgs($args);
|
||||
$args[''] = (array)@$args[''];
|
||||
$name = (isset($args['name'])) ? $args['name'] : array_shift($args['']);
|
||||
$name = preg_replace('/^\\$:/', 'ptv_', $name);
|
||||
$value = (isset($args['value'])) ? $args['value'] : array_shift($args['']);
|
||||
if (!isset($InputValues[$name])) $InputValues[$name] = $value;
|
||||
if (@$args['request']) {
|
||||
$req = array_merge($_GET, $_POST);
|
||||
foreach($req as $k => $v)
|
||||
if (!isset($InputValues[$k]))
|
||||
$InputValues[$k] = htmlspecialchars(stripmagic($v), ENT_NOQUOTES);
|
||||
}
|
||||
$source = @$args['source'];
|
||||
if ($source) {
|
||||
$source = MakePageName($pagename, $source);
|
||||
$page = RetrieveAuthPage($source, 'read', false, READPAGE_CURRENT);
|
||||
if ($page) {
|
||||
foreach((array)$PageTextVarPatterns as $pat)
|
||||
if (preg_match_all($pat, IsEnabled($PCache[$source]['=preview'], $page['text']),
|
||||
$match, PREG_SET_ORDER))
|
||||
foreach($match as $m)
|
||||
if (!isset($InputValues['ptv_'.$m[2]]))
|
||||
$InputValues['ptv_'.$m[2]] =
|
||||
htmlspecialchars(Qualify($source, $m[3]), ENT_NOQUOTES);
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
|
||||
## (:input select ...:) is special, because we need to process a bunch of
|
||||
## them as a single unit.
|
||||
function InputSelect($pagename, $type, $markup) {
|
||||
global $InputTags, $InputAttrs, $FmtV;
|
||||
preg_match_all('/\\(:input\\s+\\S+\\s+(.*?):\\)/', $markup, $match);
|
||||
$selectopt = (array)$InputTags[$type];
|
||||
$opt = $selectopt;
|
||||
$optionshtml = '';
|
||||
$optiontype = isset($InputTags["$type-option"])
|
||||
? "$type-option" : "select-option";
|
||||
foreach($match[1] as $args) {
|
||||
$optionshtml .= InputToHTML($pagename, $optiontype, $args, $oo);
|
||||
$opt = array_merge($opt, $oo);
|
||||
}
|
||||
$attrlist = array_diff($InputAttrs, array('value'));
|
||||
$attr = array();
|
||||
foreach($attrlist as $a) {
|
||||
if (!isset($opt[$a]) || $opt[$a]===false) continue;
|
||||
$attr[] = "$a='".str_replace("'", ''', $opt[$a])."'";
|
||||
}
|
||||
$FmtV['$InputSelectArgs'] = implode(' ', $attr);
|
||||
$FmtV['$InputSelectOptions'] = $optionshtml;
|
||||
return Keep(FmtPageName($selectopt[':html'], $pagename));
|
||||
}
|
||||
|
||||
|
||||
function InputActionForm($pagename, $type, $args) {
|
||||
global $InputAttrs;
|
||||
$args = ParseArgs($args);
|
||||
if (@$args['pagename']) $pagename = $args['pagename'];
|
||||
$opt = NULL;
|
||||
$html = InputToHTML($pagename, $type, $args, $opt);
|
||||
foreach(preg_grep('/^[\\w$]/', array_keys($args)) as $k) {
|
||||
if (is_array($args[$k]) || in_array($k, $InputAttrs)) continue;
|
||||
if ($k == 'n' || $k == 'pagename') continue;
|
||||
$html .= "<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').' '));
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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('$', '$',
|
||||
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("'", "'", $SearchQuery)));
|
||||
$opt = array_merge((array)$SearchBoxOpt, @$_GET, (array)$opt);
|
||||
$opt['action'] = 'search';
|
||||
$target = (@$opt['target'])
|
||||
? MakePageName($pagename, $opt['target']) : $pagename;
|
||||
$opt['n'] = IsEnabled($EnablePathInfo, 0) ? '' : $target;
|
||||
$out = FmtPageName(" class='wikisearch' action='\$PageUrl' method='get'>",
|
||||
$target);
|
||||
foreach($opt as $k => $v) {
|
||||
if ($v == '' || is_array($v)) continue;
|
||||
$v = str_replace("'", "'", $v);
|
||||
$opt[$k] = $v;
|
||||
if ($k == 'q' || $k == 'label' || $k == 'value' || $k == 'size') continue;
|
||||
$k = str_replace("'", "'", $k);
|
||||
$out .= "<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['<'] = (string)@$matches[$i-1];
|
||||
$Cursor['='] = $pn;
|
||||
$Cursor['>'] = $Cursor['>'] = (string)@$matches[$i+1];
|
||||
$curr = str_replace($vk, $vv, $control);
|
||||
$curr = preg_replace('/\\{(=|&[lg]t;)(\\$:?\\w+)\\}/e',
|
||||
"PageVar(\$pn, '$2', '$1')", $curr);
|
||||
if ($when == 'first' && $i > 0 && $last[$t] == $curr) continue;
|
||||
$last[$t] = $curr;
|
||||
}
|
||||
if ($when == 'last') {
|
||||
$Cursor['<'] = $Cursor['<'] = $pn;
|
||||
$Cursor['='] = (string)@$matches[$i+1];
|
||||
$Cursor['>'] = $Cursor['>'] = (string)@$matches[$i+2];
|
||||
$next = str_replace($vk, $vv, $control);
|
||||
$next = preg_replace('/\\{(=|&[lg]t;)(\\$:?\\w+)\\}/e',
|
||||
"PageVar(\$pn, '$2', '$1')", $next);
|
||||
if ($next == $last[$t] && $i != count($matches) - 1) continue;
|
||||
$last[$t] = $next;
|
||||
}
|
||||
}
|
||||
}
|
||||
$Cursor['<'] = $Cursor['<'] = (string)@$matches[$i-1];
|
||||
$Cursor['='] = $pn;
|
||||
$Cursor['>'] = $Cursor['>'] = (string)@$matches[$i+1];
|
||||
$item = str_replace($vk, $vv, $item);
|
||||
$item = preg_replace('/\\{(=|&[lg]t;)(\\$:?\\w+)\\}/e',
|
||||
"PVSE(PageVar(\$pn, '$2', '$1'))", $item);
|
||||
$out .= MarkupRestore($item);
|
||||
}
|
||||
}
|
||||
|
||||
$class = preg_replace('/[^-a-zA-Z0-9\\x80-\\xff]/', ' ', @$opt['class']);
|
||||
if ($class) $class = " class='$class'";
|
||||
$wrap = @$opt['wrap'];
|
||||
if ($wrap != 'inline') {
|
||||
$out = $FPLTemplateMarkupFunction($pagename, $out, array('escape' => 0, 'redirect'=>1));
|
||||
if ($wrap != 'none') $out = "<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);
|
||||
}
|
||||
@@ -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&source=".$DiffShow['source']."&minor=n'>$[Hide minor edits]</a>" :
|
||||
"<a href='{\$PageUrl}?action=diff&source=".$DiffShow['source']."&minor=y'>$[Show minor edits]</a>" );
|
||||
SDV($DiffSourceFmt, ($DiffShow['source']=='y') ?
|
||||
"<a href='{\$PageUrl}?action=diff&source=n&minor=".$DiffShow['minor']."'>$[Show changes to output]</a>" :
|
||||
"<a href='{\$PageUrl}?action=diff&source=y&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&restore=\$DiffId&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");
|
||||
@@ -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*-+>\\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,'§');
|
||||
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,'↑ Contents');
|
||||
Markup('tocback','directives','/\(:toc-back(?:\s+(.*?))?:\)/e',
|
||||
"'[[#toc | '.TocLinkText(PSS('$1')).']]'");
|
||||
Markup('tocpage','directives','/\(:toc-page\s+(.*?)(?:\s+self=([01]))?:\)/e',
|
||||
"RemoteTableOfContents(\$pagename,'$1','$2')");
|
||||
|
||||
function RemoteTableOfContents($pagename,$ref,$self=0) {
|
||||
global $TocHeaderFmt,$RemoteTocFmt;
|
||||
$oTocHeader = $TocHeaderFmt;
|
||||
$TocHeaderFmt = str_replace('$Toc',$ref,$RemoteTocFmt);
|
||||
$tocname = MakePageName($pagename,$ref);
|
||||
if ($tocname==$pagename && $self==0) return '';
|
||||
$tocpage=RetrieveAuthPage($tocname,'read',false);
|
||||
$toctext=@$tocpage['text'];
|
||||
if (preg_match('/\(:([#\*])?toc(?:-(float|hide))?(?:\s+anchors=(v)isible)?(?:\s+(.*?))?(?:\s+(Q))?:\)(.*)$/se',$toctext,$m))
|
||||
$toc = str_replace('[[#',"[[$ref#",
|
||||
TableOfContents($tocname,$m[1],'page','',$m[5],PSS($m[6])));
|
||||
$TocHeaderFmt = $oTocHeader;
|
||||
return $toc;
|
||||
}
|
||||
|
||||
function TocLinkText($text) {
|
||||
global $TocBackFmt;
|
||||
if ($text) $TocBackFmt = $text;
|
||||
return $TocBackFmt;
|
||||
}
|
||||
|
||||
function TocEntryAnchors($visible,$text) {
|
||||
global $IdPattern;
|
||||
return preg_replace("/\n(!+|Q:)((\[\[#+$IdPattern\]\])|##?)?/e",
|
||||
'"\n$1".InsertAnchor($visible,"$1","$2")',$text);
|
||||
}
|
||||
|
||||
function InsertAnchor($visible,$h,$mark) {
|
||||
global $OmitQMarkup, $NumberToc, $L1TocChar;
|
||||
static $l1,$l2,$toc1,$toc2;
|
||||
if ($h=='Q:' && $OmitQMarkup) return $mark;
|
||||
if ($mark=='') $visibility = ($visible=='') ? '#' : '##';
|
||||
else $visibility = $mark;
|
||||
if ($h=='Q:') return $visibility;
|
||||
$r = '';
|
||||
$len = strlen($h);
|
||||
if ($l1==0) { $l1 = $len; }
|
||||
else if ($len!=$l1 && $l2==0) { $l2 = $len; }
|
||||
# if ($l1==$len || $l2==$len) $r = $visibility;
|
||||
if ($l1==$len) {
|
||||
$toc1++; $toc2 = 0; $r = $visibility;
|
||||
if ($NumberToc) $r .= "$toc1$L1TocChar ";
|
||||
} elseif ($l2==$len) {
|
||||
$toc2++; $r = $visibility;
|
||||
if ($NumberToc) $r .= "$toc1.$toc2 ";
|
||||
}
|
||||
return $r;
|
||||
}
|
||||
|
||||
function TableOfContents($pagename,$number,$float,$title,$includeq,$text) {
|
||||
global $DefaultTocTitle,$TocHeaderFmt,$IdPattern,$NumberToc,$OmitQMarkup,
|
||||
$format,$L1TocChar,$DefaultTocAnchor,$TocFloat,$HTMLHeaderFmt,
|
||||
$ToggleText;
|
||||
if ($includeq) $OmitQMarkup = (!$OmitQMarkup);
|
||||
if ($float=='float') $TocFloat = (!$TocFloat);
|
||||
$l1 = 0; $l2 = 0; $l3 = 0;
|
||||
$q = 0; $prelen = 1; $counter = 0;
|
||||
$r = ''; $toc1 = 0;
|
||||
if (!$title) $title = $DefaultTocTitle;
|
||||
$toc = str_replace('$TocTitle',$title,$TocHeaderFmt);
|
||||
if ($number=='*') $NumberToc = false;
|
||||
elseif ($number=='#') $NumberToc = true;
|
||||
$closel = 0;
|
||||
if ($format=='pdf') {
|
||||
$l = 'tbook:item';
|
||||
$s = ($NumberToc) ? 'tbook:enumerate' : 'tbook:itemize'; $sc = $s;
|
||||
$toc = "<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 " : '';
|
||||
} else {
|
||||
$toc2++;
|
||||
$tocout = ($NumberToc) ? "$toc1.$toc2 " : '';
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -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");
|
||||
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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' => '',
|
||||
));
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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';
|
||||
}
|
||||
@@ -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 <<<<<<< and
|
||||
>>>>>>>.",
|
||||
'EditWarning' => "The page you are editing has been modified
|
||||
since you started editing it. If you continue, your
|
||||
changes will overwrite any changes that others have made."));
|
||||
$MessagesFmt[] = "<p class='editconflict'>$ec
|
||||
(<a target='_blank' href='\$PageUrl?action=diff'>$[View changes]</a>)
|
||||
</p>\n";
|
||||
}
|
||||
|
||||
@@ -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 <!--HTMLHeader-->", 'htmlheader');
|
||||
if (!preg_match('/<!--(No)?(HT|X)MLFooter-->/i', $k))
|
||||
Abort("Skin template missing <!--HTMLFooter-->", 'htmlheader');
|
||||
}
|
||||
|
||||
$sect = preg_split(
|
||||
'#[[<]!--(/?(?:Page[A-Za-z]+Fmt|(?:HT|X)ML(?:Head|Foot)er|HeaderText|PageText).*?)--[]>]#',
|
||||
$k, 0, PREG_SPLIT_DELIM_CAPTURE);
|
||||
$TmplFmt['Start'] = array_merge(array('headers:'),
|
||||
preg_split("/$SkinDirectivesPattern/s",
|
||||
array_shift($sect),0,PREG_SPLIT_DELIM_CAPTURE));
|
||||
$TmplFmt['End'] = array($PageTextEndFmt);
|
||||
$ps = 'Start';
|
||||
while (count($sect)>0) {
|
||||
$k = array_shift($sect);
|
||||
$v = preg_split("/$SkinDirectivesPattern/s",
|
||||
array_shift($sect),0,PREG_SPLIT_DELIM_CAPTURE);
|
||||
$TmplFmt[$ps][] = "<!--$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);
|
||||
}
|
||||
|
||||
@@ -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"); }
|
||||
}
|
||||
@@ -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','/&(?>([A-Za-z0-9]+|#\\d+|#[xX][A-Fa-f0-9]+));/',
|
||||
'&$1;');
|
||||
Markup('&amp;', '<&', '/&amp;/', Keep('&'));
|
||||
|
||||
|
||||
## (:if:)/(:elseif:)/(:else:)
|
||||
SDV($CondTextPattern,
|
||||
"/ \\(:if (\d*) (?:end)? \\b[^\n]*?:\\)
|
||||
.*?
|
||||
(?: \\(: (?:if\\1|if\\1end) \\s* :\\)
|
||||
| (?=\\(:(?:if\\1|if\\1end)\\b[^\n]*?:\\) | $)
|
||||
)
|
||||
/seix");
|
||||
SDV($CondTextReplacement, "CondText2(\$pagename, PSS('$0'), '$1')");
|
||||
Markup('if', 'fulltext', $CondTextPattern, $CondTextReplacement);
|
||||
|
||||
function CondText2($pagename, $text, $code = '') {
|
||||
global $Conditions, $CondTextPattern, $CondTextReplacement;
|
||||
$if = "if$code";
|
||||
|
||||
$parts = preg_split("/\\(:(?:{$if}end|$if|else *$if|else$code)\\b\\s*(.*?)\\s*:\\)/",
|
||||
$text, -1, PREG_SPLIT_DELIM_CAPTURE);
|
||||
$x = array_shift($parts);
|
||||
while ($parts) {
|
||||
list($condspec, $condtext) = array_splice($parts, 0, 2);
|
||||
if (!preg_match("/^\\s*(!?)\\s*(\\S*)\\s*(.*?)\\s*$/", $condspec, $match)) continue;
|
||||
list($x, $not, $condname, $condparm) = $match;
|
||||
if (!isset($Conditions[$condname]))
|
||||
return preg_replace($CondTextPattern, $CondTextReplacement, $condtext);
|
||||
$tf = @eval("return ({$Conditions[$condname]});");
|
||||
if ($tf xor $not)
|
||||
return preg_replace($CondTextPattern, $CondTextReplacement, $condtext);
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
|
||||
## (:include:)
|
||||
Markup('include', '>if',
|
||||
'/\\(:include\\s+(\\S.*?):\\)/ei',
|
||||
"PRR(IncludeText(\$pagename, PSS('$1')))");
|
||||
|
||||
## (:redirect:)
|
||||
Markup('redirect', '<include',
|
||||
'/\\(: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("'", ''', $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','/\\[\\[<<\\]\\]/',"<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*-+>\\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','/^(?>(-+))>\\s?(\\s*)/','<:indent,$1,$1 $2>$2');
|
||||
Markup('^-<','block','/^(?>(-+))<\\s?(\\s*)/','<:outdent,$1,$1 $2>$2');
|
||||
|
||||
## definition lists
|
||||
Markup('^::','block','/^(:+)(\s*)([^:]+):/','<:dl,$1,$1$2><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',
|
||||
'/^>>(.+?)<<(.*)$/',
|
||||
'(:div:)%div $1 apply=div%$2 ');
|
||||
Markup('^>><<', '<^>>',
|
||||
'/^>><</',
|
||||
'(: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("'", ''',
|
||||
"<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'))");
|
||||
|
||||
@@ -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','/<<\\|([^|]+|\\[\\[(.+?)\\]\\])\\|>>/e',
|
||||
"MakeTrailStop(\$pagename,'$1')");
|
||||
Markup('<|','><<|','/<\\|([^|]+|\\[\\[(.+?)\\]\\])\\|>/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('/^\\[\\[(.+?)(->|\\|)(.+?)\\]\\]$/', $trailname, $m))
|
||||
$trailname = ($m[2] == '|') ? $m[1] : $m[3];
|
||||
$trailtext = RetrieveAuthSection($pagename, $trailname);
|
||||
$trailname = $RASPageName;
|
||||
$trailtext = Qualify($trailname, $trailtext);
|
||||
$t = array();
|
||||
$n = 0;
|
||||
foreach(explode("\n", htmlspecialchars(@$trailtext, ENT_NOQUOTES))
|
||||
as $x) {
|
||||
$x = preg_replace("/\\[\\[([^\\]]*)->([^\\]]*)\\]\\]/",'[[$2|$1]]',$x);
|
||||
if (!preg_match("/^([#*:]+) \\s*
|
||||
(\\[\\[([^:#!|][^|:]*?)(\\|.*?)?\\]\\]($SuffixPattern)
|
||||
| (($GroupPattern([\\/.]))?$WikiWordPattern)) (.*)/x",$x,$match))
|
||||
continue;
|
||||
if (@$match[6]) {
|
||||
if (!$LinkWikiWords) continue;
|
||||
$tgt = MakePageName($trailname, $match[6]);
|
||||
} else $tgt = MakePageName($trailname,
|
||||
preg_replace('/[#?].+/', '', $match[3]));
|
||||
$t[$n]['depth'] = $depth = strlen($match[1]);
|
||||
$t[$n]['pagename'] = $tgt;
|
||||
$t[$n]['markup'] = $match[2];
|
||||
$t[$n]['detail'] = $match[9];
|
||||
for($i=$depth;$i<10;$i++) $d[$i]=$n;
|
||||
if ($depth>1) $t[$n]['parent']=@$d[$depth-1];
|
||||
$n++;
|
||||
}
|
||||
return $t;
|
||||
}
|
||||
|
||||
function MakeTrailStop($pagename,$trailname) {
|
||||
$t = ReadTrail($pagename,$trailname);
|
||||
$prev=''; $next='';
|
||||
for($i=0;$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'><< $prev | $trailname | $next >></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 = '< '.$t[$i-1]['markup'].' | ';
|
||||
if ($i+1<count($t)) $next = ' | '.$t[$i+1]['markup'].' >';
|
||||
}
|
||||
}
|
||||
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>";
|
||||
}
|
||||
|
||||
@@ -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'),
|
||||
));
|
||||
}
|
||||
|
||||
@@ -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 -> $n1</li>";
|
||||
}
|
||||
|
||||
if ($message) {
|
||||
$migrateurl = "$ScriptUrl?action=upgrade&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);
|
||||
}
|
||||
@@ -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'> Δ</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&upname=$upname", $pagename);
|
||||
$FmtV['$LinkText'] = $txt;
|
||||
if (!file_exists($filepath))
|
||||
return FmtPageName($LinkUploadCreateFmt, $pagename);
|
||||
$path = PUE(FmtPageName(IsEnabled($EnableDirectDownload, 1)
|
||||
? "$UploadUrlFmt$UploadPrefixFmt/$upname"
|
||||
: "{\$PageUrl}?action=download&upname=$upname",
|
||||
$pagename));
|
||||
return LinkIMap($pagename, $imap, $path, $alt, $txt, $fmt);
|
||||
}
|
||||
|
||||
# Authenticate group downloads with the group password
|
||||
function UploadAuth($pagename, $auth, $cache=0){
|
||||
global $GroupAttributesFmt, $EnableUploadGroupAuth;
|
||||
if (IsEnabled($EnableUploadGroupAuth,0)){
|
||||
SDV($GroupAttributesFmt,'$Group/GroupAttributes');
|
||||
$pn_upload = FmtPageName($GroupAttributesFmt, $pagename);
|
||||
} else $pn_upload = $pagename;
|
||||
$page = RetrieveAuthPage($pn_upload, $auth, true, READPAGE_CURRENT);
|
||||
if(!$page) Abort("?No '$auth' permissions for $pagename");
|
||||
if($cache) PCache($pn_upload,$page);
|
||||
return true;
|
||||
}
|
||||
|
||||
function HandleUpload($pagename, $auth = 'upload') {
|
||||
global $FmtV,$UploadExtMax,
|
||||
$HandleUploadFmt,$PageStartFmt,$PageEndFmt,$PageUploadFmt;
|
||||
UploadAuth($pagename, $auth, 1);
|
||||
$FmtV['$UploadName'] = MakeUploadName($pagename,@$_REQUEST['upname']);
|
||||
$upresult = htmlspecialchars(@$_REQUEST['upresult']);
|
||||
$uprname = htmlspecialchars(@$_REQUEST['uprname']);
|
||||
$FmtV['$upext'] = htmlspecialchars(@$_REQUEST['upext']);
|
||||
$FmtV['$upmax'] = htmlspecialchars(@$_REQUEST['upmax']);
|
||||
$FmtV['$UploadResult'] = ($upresult) ?
|
||||
FmtPageName("<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&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&upname=$file'> Δ</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;
|
||||
}
|
||||
@@ -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('"','''),$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;
|
||||
}
|
||||
|
||||
@@ -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('$', '$', $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>$$v</code></a></td><td><a
|
||||
href='{\$PageUrl}'>{\$Name}</a></td></tr>\n",$a['pagename']);
|
||||
$out .= "</table>";
|
||||
return $out;
|
||||
}
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
<?php $Version="pmwiki-2.2.13"; $VersionNum=2002013;
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;";
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;";
|
||||
|
||||
@@ -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"
|
||||
));
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||