forked from github/kensanata.oddmuse
Compare commits
2 Commits
as/encode_
...
cleaning-l
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
73d04103c4 | ||
|
|
b58f83351d |
4
.gitignore
vendored
4
.gitignore
vendored
@@ -1,10 +1,8 @@
|
||||
*~
|
||||
/build/
|
||||
\#*\#
|
||||
/test-data*
|
||||
/test-data
|
||||
/Mac/pkg/
|
||||
*.dmg
|
||||
*.pkg
|
||||
.DS_Store
|
||||
wiki.log
|
||||
.prove
|
||||
|
||||
22
Makefile
22
Makefile
@@ -3,7 +3,7 @@
|
||||
# subdirectory.
|
||||
|
||||
VERSION_NO=$(shell git describe --tags)
|
||||
TRANSLATIONS=$(wildcard modules/translations/[a-z]*-utf8.pl$)
|
||||
TRANSLATIONS=$(wildcard modules/translations/[a-z]*.pl$)
|
||||
MODULES=$(wildcard modules/*.pl)
|
||||
BUILD=build/wiki.pl $(foreach file, $(notdir $(MODULES)) $(notdir $(TRANSLATIONS)), build/$(file))
|
||||
|
||||
@@ -19,13 +19,9 @@ build:
|
||||
|
||||
clean:
|
||||
rm -rf build
|
||||
prove t/setup.pl
|
||||
|
||||
release:
|
||||
perl stuff/release ~/oddmuse.org
|
||||
|
||||
build/wiki.pl: wiki.pl
|
||||
perl -lne "s/(\\\$$q->a\(\{-href=>'http:\/\/www.oddmuse.org\/'\}, 'Oddmuse'\))/\\\$$q->a({-href=>'http:\/\/git.savannah.gnu.org\/cgit\/oddmuse.git\/tag\/?id=$(VERSION_NO)'}, 'wiki.pl') . ' ($(VERSION_NO)), see ' . \$$1/; print" < $< > $@
|
||||
perl -lne "s/(\\\$$q->a\({-href=>'http:\/\/www.oddmuse.org\/'}, 'Oddmuse'\))/\\\$$q->a({-href=>'http:\/\/git.savannah.gnu.org\/cgit\/oddmuse.git\/tag\/?id=$(VERSION_NO)'}, 'wiki.pl') . ' ($(VERSION_NO)), see ' . \$$1/; print" < $< > $@
|
||||
|
||||
build/%-utf8.pl: modules/translations/%-utf8.pl
|
||||
perl -lne "s/(AddModuleDescription\('[^']+', '[^']+')\)/\$$1, 'translations\/', '$(VERSION_NO)')/; print" < $< > $@
|
||||
@@ -42,21 +38,11 @@ build/month-names-%.pl: modules/translations/month-names-%.pl
|
||||
build/%.pl: modules/%.pl
|
||||
perl -lne "s/(AddModuleDescription\('[^']+', '[^']+')\)/\$$1, undef, '$(VERSION_NO)')/; print" < $< > $@
|
||||
|
||||
modules/translations/new-utf8.pl: wiki.pl $(MODULES)
|
||||
cp $@ $@-old
|
||||
perl stuff/oddtrans -l $@-old wiki.pl $(MODULES) > $@
|
||||
rm -f $@-old
|
||||
|
||||
translations: $(TRANSLATIONS)
|
||||
for f in $^; do \
|
||||
echo updating $$f...; \
|
||||
perl stuff/oddtrans -l $$f wiki.pl $(MODULES) > $$f-new && mv $$f-new $$f; \
|
||||
perl oddtrans -l $$f wiki.pl $(MODULES) > $$f-new && mv $$f-new $$f; \
|
||||
done
|
||||
|
||||
# Running four jobs in parallel, but clean up data directories without
|
||||
# race conditions!
|
||||
|
||||
jobs ?= 4
|
||||
test:
|
||||
prove t/setup.pl
|
||||
prove --jobs=$(jobs) --state=slow,save t
|
||||
prove t
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
This is the README file distributed together with the
|
||||
[[https://oddmuse.org/|Oddmuse]] script.
|
||||
[[http://oddmuse.org/|Oddmuse]] script.
|
||||
|
||||
== Installing Oddmuse on a Debian System running Apache
|
||||
|
||||
@@ -82,7 +82,7 @@ putting their names in {{{[[double square brackets]]}}}.
|
||||
|
||||
Enjoy your wiki experience.
|
||||
|
||||
Visit https://www.oddmuse.org/ to learn more about the translation
|
||||
Visit http://www.oddmuse.org/ to learn more about the translation
|
||||
files and modules that are part of this package.
|
||||
|
||||
== Apache
|
||||
@@ -136,7 +136,7 @@ simply restart it all:
|
||||
sudo service apache2 graceful
|
||||
}}}
|
||||
|
||||
== License
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Permission is granted to copy, distribute and/or modify this document
|
||||
under the terms of the GNU Free Documentation License, Version 1.1 or
|
||||
@@ -153,7 +153,5 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
Both the GNU Free Documentation License, and the GNU General Public
|
||||
License are distributed together with this script. See the files
|
||||
[[https://github.com/kensanata/oddmuse/blob/master/FDL|FDL]] and
|
||||
[[https://github.com/kensanata/oddmuse/blob/master/GPL|GPL]],
|
||||
respectively.
|
||||
License are distributed together with this script. See the files FDL
|
||||
and GPL, respectively.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
The files in this directory are used to run https://campaignwiki.org/
|
||||
The files in this directory are used to run http://campaignwiki.org/
|
||||
|
||||
add-link.pl
|
||||
===========
|
||||
@@ -8,7 +8,7 @@ bookmark site: A few pages make up a big unordered list of links in
|
||||
wiki format. add-link is a tool to help users contribute new links to
|
||||
the list.
|
||||
|
||||
https://campaignwiki.org/wiki/LinksToWisdom/HomePage
|
||||
http://campaignwiki.org/wiki/LinksToWisdom/HomePage
|
||||
|
||||
copy.pl
|
||||
=======
|
||||
@@ -17,7 +17,7 @@ This is used to copy the text from a web page to a wiki page. The idea
|
||||
was to keep archive copies of cool pages somewhere. The Blog Archive
|
||||
never got used, though.
|
||||
|
||||
https://campaignwiki.org/wiki/BlogArchive/HomePage
|
||||
http://campaignwiki.org/wiki/BlogArchive/HomePage
|
||||
|
||||
monster-tag.pl
|
||||
==============
|
||||
@@ -25,7 +25,7 @@ monster-tag.pl
|
||||
This is used to quickly tag many pages in the Monsters wiki. The
|
||||
Monsters wiki hasn't been used in a long time, though.
|
||||
|
||||
https://campaignwiki.org/wiki/Monsters/HomePage
|
||||
http://campaignwiki.org/wiki/Monsters/HomePage
|
||||
|
||||
submit.pl
|
||||
=========
|
||||
@@ -34,4 +34,4 @@ This used to be used to add sites to the Old School RPG Planet. The
|
||||
aggregator was configured via a wiki page on the Planet wiki. It's now
|
||||
abandoned.
|
||||
|
||||
https://campaignwiki.org/wiki/Planet/HomePage
|
||||
http://campaignwiki.org/wiki/Planet/HomePage
|
||||
|
||||
@@ -292,7 +292,6 @@ sub main {
|
||||
Init(); # read config file (no modules!)
|
||||
$ScriptName = $site; # undo setting in the config file
|
||||
$FullUrl = $site; #
|
||||
InitPageVariables(); # call again: $ScriptName was wrong
|
||||
binmode(STDOUT,':utf8');
|
||||
$q->charset('utf8');
|
||||
if ($q->path_info eq '/source') {
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
#!/bin/bash
|
||||
if test -z "$2" -o ! -z "$3"; then
|
||||
echo "Usage: delete.sh USERNAME WIKI"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
username=$1
|
||||
wiki=$2
|
||||
|
||||
for p in $(curl "https://campaignwiki.org/wiki/$wiki?action=index;raw=1"); do
|
||||
echo "Deleting: $p"
|
||||
curl -F frodo=1 -F "title=$p" -F text=DeletedPage -F summary=Deleted -F username="$username" "https://campaignwiki.org/wiki/$wiki"
|
||||
sleep 5
|
||||
done
|
||||
@@ -1,131 +0,0 @@
|
||||
#! /usr/bin/perl -w
|
||||
|
||||
# Copyright (C) 2005-2016 Alex Schroeder <alex@gnu.org>
|
||||
#
|
||||
# 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use Modern::Perl;
|
||||
use LWP::UserAgent;
|
||||
use utf8;
|
||||
binmode(STDOUT, ":utf8");
|
||||
|
||||
my $ua = LWP::UserAgent->new;
|
||||
|
||||
sub url_encode {
|
||||
my $str = shift;
|
||||
return '' unless $str;
|
||||
utf8::encode($str); # turn to byte string
|
||||
my @letters = split(//, $str);
|
||||
my %safe = map {$_ => 1} ('a' .. 'z', 'A' .. 'Z', '0' .. '9', '-', '_', '.', '!', '~', '*', "'", '(', ')', '#');
|
||||
foreach my $letter (@letters) {
|
||||
$letter = sprintf("%%%02x", ord($letter)) unless $safe{$letter};
|
||||
}
|
||||
return join('', @letters);
|
||||
}
|
||||
|
||||
sub get_raw {
|
||||
my $uri = shift;
|
||||
my $response = $ua->get($uri);
|
||||
return $response->content if $response->is_success;
|
||||
}
|
||||
|
||||
sub get_wiki_page {
|
||||
my ($wiki, $id, $password) = @_;
|
||||
my $parameters = [
|
||||
pwd => $password,
|
||||
action => 'browse',
|
||||
id => $id,
|
||||
raw => 1,
|
||||
];
|
||||
my $response = $ua->post($wiki, $parameters);
|
||||
return $response->decoded_content if $response->is_success;
|
||||
die "Getting $id returned " . $response->status_line;
|
||||
}
|
||||
|
||||
sub get_wiki_index {
|
||||
my $wiki = shift;
|
||||
my $parameters = [
|
||||
search => "flickr.com",
|
||||
context => 0,
|
||||
raw => 1,
|
||||
];
|
||||
my $response = $ua->post($wiki, $parameters);
|
||||
return $response->decoded_content if $response->is_success;
|
||||
die "Getting the index returned " . $response->status_line;
|
||||
}
|
||||
|
||||
sub post_wiki_page {
|
||||
my ($wiki, $id, $username, $password, $text) = @_;
|
||||
my $parameters = [
|
||||
username => $username,
|
||||
pwd => $password,
|
||||
recent_edit => 'on',
|
||||
text => $text,
|
||||
title => $id,
|
||||
];
|
||||
my $response = $ua->post($wiki, $parameters);
|
||||
die "Posting to $id returned " . $response->status_line unless $response->code == 302;
|
||||
}
|
||||
|
||||
my %seen = ();
|
||||
|
||||
sub write_flickr {
|
||||
my ($id, $flickr, $dir, $file) = @_;
|
||||
say "Found $flickr";
|
||||
warn "$file was seen before: " . $seen{$file} if $seen{$file};
|
||||
die "$file contains unknown characters" if $file =~ /[^a-z0-9_.]/;
|
||||
$seen{$file} = "$id used $flickr";
|
||||
my $bytes = get_raw($flickr) or die("No data for $id");
|
||||
open(my $fh, '>', "$dir/$file") or die "Cannot write $dir/$file";
|
||||
binmode($fh);
|
||||
print $fh $bytes;
|
||||
close($fh);
|
||||
}
|
||||
|
||||
sub convert_page {
|
||||
my ($wiki, $pics, $dir, $username, $password, $id) = @_;
|
||||
say $id;
|
||||
my $text = get_wiki_page($wiki, $id, $password);
|
||||
my $is_changed = 0;
|
||||
while ($text =~ m!(https://[a-z0-9.]+.flickr.com/(?:[a-z0-9.]+/)?([a-z0-9_]+\.(?:jpg|png)))!) {
|
||||
my $flickr = $1;
|
||||
my $file = $2;
|
||||
write_flickr($id, $flickr, $dir, $file);
|
||||
$is_changed = 1;
|
||||
my $re = quotemeta($flickr);
|
||||
$text =~ s!$flickr!$pics/$file!g;
|
||||
}
|
||||
if ($is_changed) {
|
||||
post_wiki_page($wiki, $id, $username, $password, $text);
|
||||
} else {
|
||||
# die "$id has no flickr matches?\n$text";
|
||||
}
|
||||
sleep(5);
|
||||
}
|
||||
|
||||
sub convert_site {
|
||||
my ($wiki, $pics, $dir, $username, $password) = @_;
|
||||
my @ids = split(/\n/, get_wiki_index($wiki));
|
||||
for my $id (@ids) {
|
||||
convert_page($wiki, $pics, $dir, $username, $password, $id);
|
||||
}
|
||||
}
|
||||
|
||||
our $AdminPass;
|
||||
do "/home/alex/password.pl";
|
||||
convert_site('https://alexschroeder.ch/wiki',
|
||||
'https://alexschroeder.ch/pics',
|
||||
'/home/alex/alexschroeder.ch/pics',
|
||||
'Alex Schroeder',
|
||||
$AdminPass);
|
||||
@@ -38,10 +38,9 @@
|
||||
;;; Code:
|
||||
|
||||
(eval-when-compile
|
||||
'(progn
|
||||
(require 'cl)
|
||||
(require 'sgml-mode)
|
||||
(require 'skeleton)))
|
||||
(require 'cl)
|
||||
(require 'sgml-mode)
|
||||
(require 'skeleton))
|
||||
|
||||
(require 'goto-addr); URL regexp
|
||||
(require 'info); link face
|
||||
@@ -258,6 +257,24 @@ Example:
|
||||
(defvar oddmuse-revision nil
|
||||
"A variable to bind dynamically when calling `oddmuse-format-command'.")
|
||||
|
||||
(defun oddmuse-revision-put (wiki page rev)
|
||||
"Store REV for WIKI and PAGE in `oddmuse-revisions'."
|
||||
(let ((w (assoc wiki oddmuse-revisions)))
|
||||
(unless w
|
||||
(setq w (list wiki)
|
||||
oddmuse-revisions (cons w oddmuse-revisions)))
|
||||
(let ((p (assoc page w)))
|
||||
(unless p
|
||||
(setq p (list page))
|
||||
(setcdr w (cons p (cdr w))))
|
||||
(setcdr p rev))))
|
||||
|
||||
(defun oddmuse-revision-get (wiki page)
|
||||
"Get revision for WIKI and PAGE in `oddmuse-revisions'."
|
||||
(let ((w (assoc wiki oddmuse-revisions)))
|
||||
(when w
|
||||
(cdr (assoc page w)))))
|
||||
|
||||
;;; Helpers
|
||||
|
||||
(defsubst oddmuse-page-name (file)
|
||||
@@ -283,7 +300,7 @@ Example:
|
||||
(defun oddmuse-url (wiki pagename)
|
||||
"Get the URL of oddmuse wiki."
|
||||
(condition-case v
|
||||
(concat (or (cadr (assoc wiki oddmuse-wikis)) (error "Wiki not found in `oddmuse-wikis'")) "/"
|
||||
(concat (or (cadr (assoc wiki oddmuse-wikis)) (error)) "/"
|
||||
(url-hexify-string pagename))
|
||||
(error nil)))
|
||||
|
||||
@@ -517,7 +534,7 @@ as well."
|
||||
((string-match "<title>Error</title>" status)
|
||||
(if (string-match "<h1>\\(.*\\)</h1>" status)
|
||||
(error "Error %s: %s" mesg (match-string 1 status))
|
||||
(error "Error %s: Cause unknown" status)))
|
||||
(error "Error %s: Cause unknown")))
|
||||
(t
|
||||
(message "%s...done" mesg))))))
|
||||
|
||||
@@ -719,7 +736,7 @@ Font-locking is controlled by `oddmuse-markup-functions'.
|
||||
(set (make-local-variable 'sgml-tag-alist)
|
||||
`(("b") ("code") ("em") ("i") ("strong") ("nowiki")
|
||||
("pre" \n) ("tt") ("u")))
|
||||
(set (make-local-variable 'skeleton-transformation-function) 'identity)
|
||||
(set (make-local-variable 'skeleton-transformation) 'identity)
|
||||
|
||||
(make-local-variable 'oddmuse-wiki)
|
||||
(make-local-variable 'oddmuse-page-name)
|
||||
@@ -837,8 +854,11 @@ people have been editing the wiki in the mean time."
|
||||
(set-buffer (get-buffer-create name))
|
||||
(erase-buffer); in case of current-prefix-arg
|
||||
(oddmuse-run "Loading" oddmuse-get-command wiki pagename)
|
||||
(oddmuse-revision-put wiki pagename (oddmuse-get-latest-revision wiki pagename))
|
||||
;; fix mode-line for VC in the new buffer because this is not a vc-checkout
|
||||
(setq buffer-file-name (concat oddmuse-directory "/" wiki "/" pagename))
|
||||
(vc-working-revision buffer-file-name 'oddmuse)
|
||||
(vc-mode-line buffer-file-name 'oddmuse)
|
||||
(pop-to-buffer (current-buffer))
|
||||
;; check for a diff (this ends with display-buffer) and bury the
|
||||
;; buffer if there are no hunks
|
||||
(when (file-exists-p buffer-file-name)
|
||||
@@ -849,9 +869,7 @@ people have been editing the wiki in the mean time."
|
||||
;; this also changes the buffer name
|
||||
(basic-save-buffer)
|
||||
;; this makes sure that the buffer name is set correctly
|
||||
(oddmuse-mode)
|
||||
;; fix mode-line for VC in the new buffer because this is not a vc-checkout
|
||||
(vc-mode-line buffer-file-name 'oddmuse))))
|
||||
(oddmuse-mode))))
|
||||
|
||||
(defalias 'oddmuse-go 'oddmuse-edit)
|
||||
|
||||
@@ -891,11 +909,8 @@ Use a prefix argument to override this."
|
||||
(and buffer-file-name (basic-save-buffer))
|
||||
(oddmuse-run "Posting" oddmuse-post-command nil nil
|
||||
(get-buffer-create " *oddmuse-response*") t 302)
|
||||
;; force reload
|
||||
(vc-file-setprop buffer-file-name 'vc-working-revision
|
||||
(oddmuse-get-latest-revision oddmuse-wiki oddmuse-page-name))
|
||||
;; fix mode-line for VC in the new buffer because this is not a vc-checkout
|
||||
(vc-mode-line buffer-file-name 'oddmuse))
|
||||
(oddmuse-revision-put oddmuse-wiki oddmuse-page-name
|
||||
(oddmuse-get-latest-revision oddmuse-wiki oddmuse-page-name)))
|
||||
|
||||
;;;###autoload
|
||||
(defun oddmuse-preview (&optional arg)
|
||||
|
||||
@@ -47,8 +47,7 @@ For a list of possible values, see `vc-state'."
|
||||
|
||||
(defun vc-oddmuse-working-revision (file)
|
||||
"The current revision based on `oddmuse-revisions'."
|
||||
(with-oddmuse-file
|
||||
(oddmuse-get-latest-revision wiki pagename)))
|
||||
(oddmuse-revision-get oddmuse-wiki oddmuse-page-name))
|
||||
|
||||
(defun vc-oddmuse-checkout-model (files)
|
||||
"No locking."
|
||||
@@ -60,6 +59,10 @@ For a list of possible values, see `vc-state'."
|
||||
(defun vc-oddmuse-register (files &optional rev comment)
|
||||
"This always works.")
|
||||
|
||||
(defun vc-oddmuse-revert (file &optional contents-done)
|
||||
"No idea"
|
||||
nil)
|
||||
|
||||
(defvar vc-oddmuse-log-command
|
||||
(concat "curl --silent %w"
|
||||
" --form action=rc"
|
||||
@@ -146,7 +149,7 @@ a version backup."
|
||||
(with-oddmuse-file file
|
||||
(let ((command (oddmuse-format-command vc-oddmuse-get-revision-command)))
|
||||
(with-temp-buffer
|
||||
(oddmuse-run "Loading" command wiki pagename)
|
||||
(oddmuse-run "Loading" command)
|
||||
(write-file file))))))
|
||||
|
||||
(defun vc-oddmuse-checkin (files rev comment)
|
||||
|
||||
@@ -1,7 +1,110 @@
|
||||
/* This file is in the public domain. */
|
||||
|
||||
/* @import url(https://fonts.googleapis.com/css?family=Noticia+Text:400,400italic,700italic,700&subset=latin,latin-ext); */
|
||||
|
||||
/* vietnamese */
|
||||
@font-face {
|
||||
font-family: 'Noticia Text';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: local('Noticia Text'), local('NoticiaText-Regular)'), url('/fonts/NoticiaText-Regular.woff') format('woff');
|
||||
unicode-range: U+0102-0103, U+1EA0-1EF1, U+20AB;
|
||||
}
|
||||
/* latin-ext */
|
||||
@font-face {
|
||||
font-family: 'Noticia Text';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: local('Noticia Text'), local('NoticiaText-Regular)'), url('/fonts/NoticiaText-Regular.woff') format('woff');
|
||||
unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;
|
||||
}
|
||||
/* latin */
|
||||
@font-face {
|
||||
font-family: 'Noticia Text';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: local('Noticia Text'), local('NoticiaText-Regular)'), url('/fonts/NoticiaText-Regular.woff') format('woff');
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
|
||||
}
|
||||
/* vietnamese */
|
||||
@font-face {
|
||||
font-family: 'Noticia Text';
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
src: local('Noticia Text Bold'), local('NoticiaText-Bold)'), url('/fonts/NoticiaText-Bold.woff') format('woff');
|
||||
unicode-range: U+0102-0103, U+1EA0-1EF1, U+20AB;
|
||||
}
|
||||
/* latin-ext */
|
||||
@font-face {
|
||||
font-family: 'Noticia Text';
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
src: local('Noticia Text Bold'), local('NoticiaText-Bold)'), url('/fonts/NoticiaText-Bold.woff') format('woff');
|
||||
unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;
|
||||
}
|
||||
/* latin */
|
||||
@font-face {
|
||||
font-family: 'Noticia Text';
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
src: local('Noticia Text Bold'), local('NoticiaText-Bold)'), url('/fonts/NoticiaText-Bold.woff') format('woff');
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
|
||||
}
|
||||
/* vietnamese */
|
||||
@font-face {
|
||||
font-family: 'Noticia Text';
|
||||
font-style: italic;
|
||||
font-weight: 400;
|
||||
src: local('Noticia Text Italic'), local('NoticiaText-Italic)'), url('/fonts/NoticiaText-Italic.woff') format('woff');
|
||||
unicode-range: U+0102-0103, U+1EA0-1EF1, U+20AB;
|
||||
}
|
||||
/* latin-ext */
|
||||
@font-face {
|
||||
font-family: 'Noticia Text';
|
||||
font-style: italic;
|
||||
font-weight: 400;
|
||||
src: local('Noticia Text Italic'), local('NoticiaText-Italic)'), url('/fonts/NoticiaText-Italic.woff') format('woff');
|
||||
unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;
|
||||
}
|
||||
/* latin */
|
||||
@font-face {
|
||||
font-family: 'Noticia Text';
|
||||
font-style: italic;
|
||||
font-weight: 400;
|
||||
src: local('Noticia Text Italic'), local('NoticiaText-Italic)'), url('/fonts/NoticiaText-Italic.woff') format('woff');
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
|
||||
}
|
||||
/* vietnamese */
|
||||
@font-face {
|
||||
font-family: 'Noticia Text';
|
||||
font-style: italic;
|
||||
font-weight: 700;
|
||||
src: local('Noticia Text Bold Italic'), local('NoticiaText-BoldItalic)'), url('/fonts/NoticiaText-BoldItalic.woff') format('woff');
|
||||
unicode-range: U+0102-0103, U+1EA0-1EF1, U+20AB;
|
||||
}
|
||||
/* latin-ext */
|
||||
@font-face {
|
||||
font-family: 'Noticia Text';
|
||||
font-style: italic;
|
||||
font-weight: 700;
|
||||
src: local('Noticia Text Bold Italic'), local('NoticiaText-BoldItalic)'), url('/fonts/NoticiaText-BoldItalic.woff') format('woff');
|
||||
unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;
|
||||
}
|
||||
/* latin */
|
||||
@font-face {
|
||||
font-family: 'Noticia Text';
|
||||
font-style: italic;
|
||||
font-weight: 700;
|
||||
src: local('Noticia Text Bold Italic'), local('NoticiaText-BoldItalic)'), url('/fonts/NoticiaText-BoldItalic.woff') format('woff');
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Symbola';
|
||||
src: local('Symbola'), url('/fonts/Symbola.woff') format('woff'), url('/fonts/Symbola.ttf') format('truetype');
|
||||
}
|
||||
|
||||
body, rss {
|
||||
font-family: "Palatino Linotype", "Book Antiqua", Palatino, serif;
|
||||
font-family: "Noticia Text", Symbola, serif;
|
||||
font-style: normal;
|
||||
font-size: 14pt;
|
||||
margin: 1em 3em;
|
||||
|
||||
@@ -1,536 +0,0 @@
|
||||
/* This file is in the public domain. */
|
||||
html{ text-align: center; }
|
||||
|
||||
body, rss {
|
||||
font-family: "Palatino Linotype", "Book Antiqua", Palatino, serif;
|
||||
font-style: normal;
|
||||
font-size: 14pt;
|
||||
padding: 1em 3em;
|
||||
max-width: 72ex;
|
||||
display: inline-block;
|
||||
text-align: left;
|
||||
color: #000;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
@media print {
|
||||
body {
|
||||
font-size: 12pt;
|
||||
}
|
||||
|
||||
/* hide all the crap */
|
||||
div.diff, div.diff+hr, div.refer, div.near, div.definition, div.sister,
|
||||
div.cal, div.footer, span.specialdays, span.gotobar, a.edit, a.number span,
|
||||
div.rc form, form.tiny, p.comment, p#plus1, div.g-plusone, div.content a.feed {
|
||||
display:none;
|
||||
}
|
||||
div.content a.book,
|
||||
div.content a.movie {
|
||||
text-decoration: none;
|
||||
}
|
||||
a cite {
|
||||
font-style: italic;
|
||||
}
|
||||
img[alt="RSS"] { display: none }
|
||||
a.rss { font-size: 8pt }
|
||||
}
|
||||
|
||||
/* headings: we can use larger sizes if we use a lighter color.
|
||||
we cannot inherit the font-family because header and footer use a narrow font. */
|
||||
|
||||
h1, h2, h3, title {
|
||||
font-family: inherit;
|
||||
font-weight: normal;
|
||||
}
|
||||
h1, channel title {
|
||||
font-size: 32pt;
|
||||
margin: 1em 0 0.5em 0;
|
||||
padding: 0.4em 0;
|
||||
}
|
||||
h2 {
|
||||
font-size: 18pt;
|
||||
margin: 2em 0 0 0;
|
||||
padding: 0;
|
||||
}
|
||||
h3 {
|
||||
font-size: inherit;
|
||||
font-weight: bold;
|
||||
padding: 0;
|
||||
margin: 1em 0 0 0;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
/* headers in the journal are smaller */
|
||||
|
||||
div.journal h1, item title {
|
||||
font-size: inherit;
|
||||
padding: 0;
|
||||
clear: both;
|
||||
border-bottom: 1px solid #000;
|
||||
}
|
||||
div.journal h2 {
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
}
|
||||
div.journal h3 {
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
font-weight: inherit;
|
||||
font-style: italic;
|
||||
}
|
||||
div.journal hr {
|
||||
visibility: hidden;
|
||||
}
|
||||
p.more {
|
||||
margin-top: 3em;
|
||||
}
|
||||
/* Links in headings appear on journal pages. */
|
||||
|
||||
h1 a, h2 a, h3 a {
|
||||
color:inherit;
|
||||
text-decoration:none;
|
||||
font-weight: normal;
|
||||
}
|
||||
h1 a:visited, h2 a:visited, h3 a:visited {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
/* for download buttons and the like */
|
||||
|
||||
.button {
|
||||
display: inline-block;
|
||||
font-size: 120%;
|
||||
cursor: pointer;
|
||||
padding: 0.4em 0.6em;
|
||||
text-shadow: 0px -1px 0px #ccc;
|
||||
background-color: #cfa;
|
||||
border: 1px solid #9d8;
|
||||
border-radius: 5px;
|
||||
box-shadow: 0px 1px 3px white inset, 0px 1px 3px black;
|
||||
}
|
||||
|
||||
.button .icon {
|
||||
color: #363;
|
||||
text-shadow: 0px -1px 1px white, 0px 1px 3px #666;
|
||||
}
|
||||
|
||||
.button a {
|
||||
text-decoration: none;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
/* links */
|
||||
|
||||
a.pencil {
|
||||
padding-left: 1ex;
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
visibility: hidden;
|
||||
transition: visibility 0s 1s, opacity 1s linear;
|
||||
opacity: 0;
|
||||
}
|
||||
*:hover > a.pencil {
|
||||
visibility: visible;
|
||||
transition: opacity .5s linear;
|
||||
opacity: 1;
|
||||
}
|
||||
@media print {
|
||||
a.pencil {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
a.number {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/* stop floating content from flowing over the footer */
|
||||
|
||||
hr {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
/* the distance between links in the navigation bars */
|
||||
|
||||
span.bar a {
|
||||
margin-right: 1ex;
|
||||
}
|
||||
|
||||
a img {
|
||||
border: none;
|
||||
}
|
||||
|
||||
/* search box in the top bar */
|
||||
|
||||
.header form, .header p {
|
||||
display: inline;
|
||||
white-space: nowrap;
|
||||
}
|
||||
label[for="searchlang"], #searchlang, .header input[type="submit"] {
|
||||
/* don't use display: none! http://stackoverflow.com/questions/5665203/getting-iphone-go-button-to-submit-form */
|
||||
visibility: hidden; position: absolute;
|
||||
}
|
||||
/* wrap on the iphone */
|
||||
@media only screen and (max-device-width: 480px) {
|
||||
}
|
||||
|
||||
.header input {
|
||||
width: 10ex;
|
||||
}
|
||||
|
||||
/* other form fields */
|
||||
|
||||
input[type="text"] {
|
||||
padding: 0;
|
||||
font-size: 80%;
|
||||
line-height: 125%;
|
||||
}
|
||||
|
||||
/* code */
|
||||
|
||||
textarea, pre, code, tt {
|
||||
font-family: "Andale Mono", Monaco, "Courier New", Courier, monospace, "Symbola";
|
||||
font-size: 80%;
|
||||
}
|
||||
|
||||
pre {
|
||||
overflow:hidden;
|
||||
white-space: pre-wrap; /* CSS 3 */
|
||||
white-space: -moz-pre-wrap; /* Mozilla, since 1999 */
|
||||
white-space: -pre-wrap; /* Opera 4-6 */
|
||||
white-space: -o-pre-wrap; /* Opera 7 */
|
||||
word-wrap: break-word; /* Internet Explorer 5.5+ */
|
||||
}
|
||||
|
||||
/* styling for divs that will be invisible when printing
|
||||
when printing. */
|
||||
|
||||
div.header, div.footer, div.near, div.definition, p.comment, a.tag {
|
||||
|
||||
font-size: 14pt;
|
||||
}
|
||||
@media print {
|
||||
div.header, div.footer, div.near, div.definition, p.comment, a.tag {
|
||||
font-size: 8pt;
|
||||
}
|
||||
}
|
||||
|
||||
div.footer form.search {
|
||||
display: none;
|
||||
}
|
||||
div.rc li + li {
|
||||
margin-top: 1em;
|
||||
}
|
||||
div.rc li strong, table.history strong, strong.description {
|
||||
font-family: inherit;
|
||||
font-weight: inherit;
|
||||
}
|
||||
div.diff {
|
||||
padding-left: 5%;
|
||||
padding-right: 5%;
|
||||
font-size: 12pt;
|
||||
color: #000;
|
||||
|
||||
}
|
||||
div.old {
|
||||
background-color: #ffffaf;
|
||||
}
|
||||
div.new {
|
||||
background-color: #cfffcf;
|
||||
}
|
||||
|
||||
div.refer {
|
||||
padding-left: 5%;
|
||||
padding-right: 5%;
|
||||
font-size: 12pt;
|
||||
}
|
||||
|
||||
div.message {
|
||||
background-color:#fee;
|
||||
color:#000;
|
||||
}
|
||||
|
||||
img.xml {
|
||||
border:none;
|
||||
padding:1px;
|
||||
}
|
||||
a.small img {
|
||||
max-width:300px;
|
||||
}
|
||||
a.large img {
|
||||
max-width:600px;
|
||||
}
|
||||
div.sister {
|
||||
margin-right:1ex;
|
||||
background-color:inherit;
|
||||
}
|
||||
div.sister p {
|
||||
margin-top:0;
|
||||
}
|
||||
div.sister hr {
|
||||
display:none;
|
||||
}
|
||||
div.sister img {
|
||||
border:none;
|
||||
}
|
||||
|
||||
div.near, div.definition {
|
||||
background-color:#efe;
|
||||
}
|
||||
|
||||
div.sidebar {
|
||||
float:right;
|
||||
border:1px dotted #000;
|
||||
padding:0 1em;
|
||||
}
|
||||
div.sidebar ul {
|
||||
padding-left:1em;
|
||||
}
|
||||
|
||||
/* replacements, features */
|
||||
|
||||
ins {
|
||||
font-style: italic;
|
||||
text-decoration: none;
|
||||
}
|
||||
acronym, abbr {
|
||||
letter-spacing:0.1em;
|
||||
font-variant:small-caps;
|
||||
}
|
||||
|
||||
/* Interlink prefix not shown */
|
||||
a .site, a .separator {
|
||||
display: none;
|
||||
}
|
||||
a cite { font:inherit; }
|
||||
/* browser borkage */
|
||||
textarea[name="text"] { width:97%; height:80%; }
|
||||
textarea[name="summary"] { width:97%; height:3em; }
|
||||
/* comments */
|
||||
textarea[name="aftertext"] { width:97%; height:10em; }
|
||||
div.commentshown {
|
||||
font-size: 12pt;
|
||||
padding: 2em 0;
|
||||
}
|
||||
div.commenthidden {
|
||||
display:none;
|
||||
}
|
||||
div.commentshown {
|
||||
display:block;
|
||||
}
|
||||
p.comment {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
div.comment {
|
||||
font-size: 14pt;
|
||||
}
|
||||
div.comment h2 {
|
||||
margin-top: 5em;
|
||||
}
|
||||
/* comment pages with username, homepage, and email subscription */
|
||||
.comment form span { display: block; }
|
||||
.comment form span label { display: inline-block; width: 10em; }
|
||||
/* IE sucks */
|
||||
.comment input#username,
|
||||
.comment input#homepage,
|
||||
.comment input#mail { width: 20em; }
|
||||
|
||||
/* cal */
|
||||
div.month { padding:0; margin:0 2ex; }
|
||||
body > div.month {
|
||||
float:right;
|
||||
background-color: inherit;
|
||||
border:solid thin;
|
||||
padding:0 1ex;
|
||||
}
|
||||
.year > .month {
|
||||
float:left;
|
||||
}
|
||||
.footer {
|
||||
clear:both;
|
||||
}
|
||||
.month .title a.local {
|
||||
background-color: inherit;
|
||||
}
|
||||
.month a.local {
|
||||
background-color: #ddf;
|
||||
}
|
||||
.month a.today {
|
||||
background-color: #fdd;
|
||||
}
|
||||
.month a {
|
||||
color:inherit;
|
||||
font-weight:inherit;
|
||||
text-decoration: none;
|
||||
background-color: #eee;
|
||||
}
|
||||
/* history tables and other tables */
|
||||
table.history {
|
||||
border: none;
|
||||
}
|
||||
td.history {
|
||||
border: none;
|
||||
}
|
||||
|
||||
table.user {
|
||||
border: none;
|
||||
border-top: 1px solid #ccc;
|
||||
border-bottom: 1px solid #ccc;
|
||||
padding: 1em;
|
||||
margin: 1em 2em;
|
||||
}
|
||||
table.user tr td, table.user tr th {
|
||||
border: none;
|
||||
padding: 0.2em 0.5em;
|
||||
vertical-align: top;
|
||||
}
|
||||
table.arab tr th {
|
||||
font-weight:normal;
|
||||
text-align:left;
|
||||
vertical-align:top;
|
||||
}
|
||||
table.arab, table.arab tr th, table.arab tr td {
|
||||
border:none;
|
||||
}
|
||||
th.nobreak {
|
||||
white-space:nowrap;
|
||||
}
|
||||
table.full { width:99%; margin-left:1px; }
|
||||
table.j td, table.j th, table tr td.j, table tr th.j, .j { text-align:justify; }
|
||||
table.l td, table.l th, table tr td.l, table tr th.l, .l { text-align:left; }
|
||||
table.r td, table.r th, table tr td.r, table tr th.r, .r { text-align:right; }
|
||||
table.c td, table.c th, table tr td.c, table tr th.c, .c { text-align:center; }
|
||||
table.t td { vertical-align: top; }
|
||||
td.half { width:50%; }
|
||||
td.third { width:33%; }
|
||||
|
||||
form table td { padding:5px; }
|
||||
|
||||
/* lists */
|
||||
dd { padding-bottom:0.5ex; }
|
||||
dl.inside dt { float:left; }
|
||||
/* search */
|
||||
div.search span.result { font-size:larger; }
|
||||
div.search span.info { font-size:smaller; font-style:italic; }
|
||||
div.search p.result { display:none; }
|
||||
|
||||
img.logo {
|
||||
float: right;
|
||||
margin: 0 0 0 1ex;
|
||||
padding: 0;
|
||||
border: 1px solid #000;
|
||||
opacity: 0.3;
|
||||
background-color:#ffe;
|
||||
}
|
||||
|
||||
/* images */
|
||||
|
||||
div.content a.feed img, div.journal a.feed img,
|
||||
div.content a img.smiley, div.journal a img.smiley, img.smiley,
|
||||
div.content a.inline img, div.journal a.inline img,
|
||||
div.content li a.image img, div.journal li a.image img {
|
||||
margin: 0; padding: 0; border: none;
|
||||
}
|
||||
div.image a img {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
div.image span.caption {
|
||||
margin: 0 1em;
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.left { float:left; margin-right: 1em; }
|
||||
.right { float:right; margin-left: 1em; }
|
||||
.half img { height: 50%; width: 50%; }
|
||||
.face img { width: 200px; }
|
||||
div.left .left, div.right .right {
|
||||
float:none;
|
||||
}
|
||||
.center { text-align:center; }
|
||||
table.aside {
|
||||
float:right;
|
||||
width:40%;
|
||||
margin-left: 1em;
|
||||
padding: 1ex;
|
||||
border: 1px dotted #666;
|
||||
}
|
||||
table.aside td {
|
||||
text-align:left;
|
||||
}
|
||||
div.sidebar {
|
||||
float:right; width: 250px;
|
||||
text-align: right;
|
||||
border: none;
|
||||
margin: 1ex;
|
||||
}
|
||||
|
||||
.bigsidebar {
|
||||
float:right;
|
||||
width: 500px;
|
||||
border: none;
|
||||
margin-left: 1ex;
|
||||
font-size: 80%;
|
||||
}
|
||||
|
||||
dl.irc dt { width:20ex; float:left; text-align:right; clear:left; }
|
||||
dl.irc dt span.time { float:left; }
|
||||
dl.irc dd { margin-left:22ex; }
|
||||
|
||||
/* portrait */
|
||||
|
||||
div.footer, div.comment, hr { clear: both; }
|
||||
.portrait { float: left; font-size: small; margin-right: 1em; }
|
||||
.portrait a { color: #999; }
|
||||
|
||||
div.left { float:left; margin:1em; padding: 0.5em; }
|
||||
div.left p { display:table-cell; }
|
||||
div.left p + p { display:table-caption; caption-side:bottom; }
|
||||
|
||||
p.table a { float:left; width:20ex; }
|
||||
p.table + p { clear:both; }
|
||||
|
||||
/* rss */
|
||||
|
||||
channel * { display: block; }
|
||||
|
||||
channel title {
|
||||
margin-top: 30pt;
|
||||
}
|
||||
copyright {
|
||||
font-size: 14pt;
|
||||
margin-top: 1em;
|
||||
}
|
||||
channel > link:before {
|
||||
font-size: 18pt;
|
||||
display: block;
|
||||
margin: 1em;
|
||||
padding: 0.5em;
|
||||
content: "This is an RSS feed, designed to be read in a feed reader.";
|
||||
color: red;
|
||||
border: 1px solid red;
|
||||
}
|
||||
link, license {
|
||||
font-size: 11pt;
|
||||
margin-bottom: 9pt;
|
||||
}
|
||||
username:before { content: "Last edited by "; }
|
||||
username:after { content: "."; }
|
||||
generator:before { content: "Feed generated by "; }
|
||||
generator:after { content: "."; }
|
||||
channel description {
|
||||
font-weight: bold;
|
||||
}
|
||||
item description {
|
||||
font-style: italic;
|
||||
font-weight: normal;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
docs, language,
|
||||
pubDate, lastBuildDate, ttl, guid, category, comments,
|
||||
docs, image title, image link,
|
||||
status, version, diff, history, importance {
|
||||
display: none;
|
||||
}
|
||||
@@ -321,6 +321,7 @@ div.sister {
|
||||
float:left;
|
||||
margin-right:1ex;
|
||||
padding-right:1ex;
|
||||
border-right:1px dashed;
|
||||
}
|
||||
div.sister p { padding:1ex; margin:0; }
|
||||
div.sister hr { display:none; }
|
||||
|
||||
158
css/light.css
158
css/light.css
@@ -8,8 +8,110 @@
|
||||
|
||||
@import url(https://fonts.googleapis.com/css?family=Noticia+Text:400,400italic,700italic,700&subset=latin,latin-ext); */
|
||||
|
||||
/* vietnamese */
|
||||
@font-face {
|
||||
font-family: 'Noticia Text';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: local('Noticia Text'), local('NoticiaText-Regular)'), url('/fonts/NoticiaText-Regular.woff') format('woff');
|
||||
unicode-range: U+0102-0103, U+1EA0-1EF1, U+20AB;
|
||||
}
|
||||
/* latin-ext */
|
||||
@font-face {
|
||||
font-family: 'Noticia Text';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: local('Noticia Text'), local('NoticiaText-Regular)'), url('/fonts/NoticiaText-Regular.woff') format('woff');
|
||||
unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;
|
||||
}
|
||||
/* latin */
|
||||
@font-face {
|
||||
font-family: 'Noticia Text';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: local('Noticia Text'), local('NoticiaText-Regular)'), url('/fonts/NoticiaText-Regular.woff') format('woff');
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
|
||||
}
|
||||
/* vietnamese */
|
||||
@font-face {
|
||||
font-family: 'Noticia Text';
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
src: local('Noticia Text Bold'), local('NoticiaText-Bold)'), url('/fonts/NoticiaText-Bold.woff') format('woff');
|
||||
unicode-range: U+0102-0103, U+1EA0-1EF1, U+20AB;
|
||||
}
|
||||
/* latin-ext */
|
||||
@font-face {
|
||||
font-family: 'Noticia Text';
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
src: local('Noticia Text Bold'), local('NoticiaText-Bold)'), url('/fonts/NoticiaText-Bold.woff') format('woff');
|
||||
unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;
|
||||
}
|
||||
/* latin */
|
||||
@font-face {
|
||||
font-family: 'Noticia Text';
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
src: local('Noticia Text Bold'), local('NoticiaText-Bold)'), url('/fonts/NoticiaText-Bold.woff') format('woff');
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
|
||||
}
|
||||
/* vietnamese */
|
||||
@font-face {
|
||||
font-family: 'Noticia Text';
|
||||
font-style: italic;
|
||||
font-weight: 400;
|
||||
src: local('Noticia Text Italic'), local('NoticiaText-Italic)'), url('/fonts/NoticiaText-Italic.woff') format('woff');
|
||||
unicode-range: U+0102-0103, U+1EA0-1EF1, U+20AB;
|
||||
}
|
||||
/* latin-ext */
|
||||
@font-face {
|
||||
font-family: 'Noticia Text';
|
||||
font-style: italic;
|
||||
font-weight: 400;
|
||||
src: local('Noticia Text Italic'), local('NoticiaText-Italic)'), url('/fonts/NoticiaText-Italic.woff') format('woff');
|
||||
unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;
|
||||
}
|
||||
/* latin */
|
||||
@font-face {
|
||||
font-family: 'Noticia Text';
|
||||
font-style: italic;
|
||||
font-weight: 400;
|
||||
src: local('Noticia Text Italic'), local('NoticiaText-Italic)'), url('/fonts/NoticiaText-Italic.woff') format('woff');
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
|
||||
}
|
||||
/* vietnamese */
|
||||
@font-face {
|
||||
font-family: 'Noticia Text';
|
||||
font-style: italic;
|
||||
font-weight: 700;
|
||||
src: local('Noticia Text Bold Italic'), local('NoticiaText-BoldItalic)'), url('/fonts/NoticiaText-BoldItalic.woff') format('woff');
|
||||
unicode-range: U+0102-0103, U+1EA0-1EF1, U+20AB;
|
||||
}
|
||||
/* latin-ext */
|
||||
@font-face {
|
||||
font-family: 'Noticia Text';
|
||||
font-style: italic;
|
||||
font-weight: 700;
|
||||
src: local('Noticia Text Bold Italic'), local('NoticiaText-BoldItalic)'), url('/fonts/NoticiaText-BoldItalic.woff') format('woff');
|
||||
unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;
|
||||
}
|
||||
/* latin */
|
||||
@font-face {
|
||||
font-family: 'Noticia Text';
|
||||
font-style: italic;
|
||||
font-weight: 700;
|
||||
src: local('Noticia Text Bold Italic'), local('NoticiaText-BoldItalic)'), url('/fonts/NoticiaText-BoldItalic.woff') format('woff');
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Symbola';
|
||||
src: local('Symbola'), url('/fonts/Symbola.woff') format('woff');
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: "Palatino Linotype", "Book Antiqua", Palatino, serif;
|
||||
font-family: "Noticia Text", Symbola, serif;
|
||||
font-size: 14pt;
|
||||
color: #000;
|
||||
background-color: #eed;
|
||||
@@ -17,13 +119,13 @@ body {
|
||||
}
|
||||
|
||||
textarea, pre, code, tt {
|
||||
font-family: "Andale Mono", Monaco, "Courier New", Courier, monospace, Symbola;
|
||||
font-size: 80%;
|
||||
font-family: "Andale Mono", Monaco, "Courier New", Courier, monospace, Symbola;
|
||||
font-size: 80%;
|
||||
}
|
||||
|
||||
@media print {
|
||||
body {
|
||||
background-color: white;
|
||||
background-color: white;
|
||||
font-family: Times, serif;
|
||||
font-size:10pt;
|
||||
}
|
||||
@@ -47,8 +149,8 @@ textarea, pre, code, tt {
|
||||
.browse { min-height: 3em; }
|
||||
.header form, .header p { margin: 0; }
|
||||
/* hide the buttons but don't use display:none because of
|
||||
http://stackoverflow.com/questions/5665203/getting-iphone-go-button-to-submit-form
|
||||
.header input[type="submit"] { position: absolute; visibility: hidden; } */
|
||||
http://stackoverflow.com/questions/5665203/getting-iphone-go-button-to-submit-form */
|
||||
.header input[type="submit"] { position: absolute; visibility: hidden; }
|
||||
.header input { width: 5em; font-size: 80%; }
|
||||
.footer { clear:both; font-size: 90%; }
|
||||
.content input { font-size: 80%; line-height: 125%; }
|
||||
@@ -73,9 +175,9 @@ input#mail, input#homepage, input#username {
|
||||
|
||||
/* titles */
|
||||
h1 {
|
||||
font-weight: bold;
|
||||
font-size: 150%;
|
||||
padding: 1em 0;
|
||||
font-weight: bold;
|
||||
font-size: 150%;
|
||||
padding: 1em 0;
|
||||
}
|
||||
h1 a:link, h1 a:visited {
|
||||
color: inherit;
|
||||
@@ -115,7 +217,7 @@ a:active {
|
||||
border: 1px solid #9d8;
|
||||
border-radius: 5px;
|
||||
box-shadow: 0px 1px 3px white inset,
|
||||
0px 1px 3px black;
|
||||
0px 1px 3px black;
|
||||
}
|
||||
.button a {
|
||||
text-decoration: none;
|
||||
@@ -129,6 +231,10 @@ a:active {
|
||||
font-weight: normal;
|
||||
}
|
||||
a.edit, div.footer, form, span.gotobar, a.number span { display:none; }
|
||||
a[class="url number"]:after, a[class="inter number"]:after {
|
||||
content:"[" attr(href) "]";
|
||||
}
|
||||
a[class="local number"]:after { content:"[" attr(title) "]"; }
|
||||
img[smiley] { line-height: inherit; }
|
||||
}
|
||||
|
||||
@@ -137,15 +243,15 @@ a.pencil { display: none; }
|
||||
|
||||
/* table of contents */
|
||||
.toc {
|
||||
font-size: smaller;
|
||||
border-left: 1em solid #886;
|
||||
font-size: smaller;
|
||||
border-left: 1em solid #886;
|
||||
}
|
||||
.toc ol {
|
||||
list-style-type: none;
|
||||
padding-left: 1em;
|
||||
list-style-type: none;
|
||||
padding-left: 1em;
|
||||
}
|
||||
.toc a {
|
||||
font-weight: normal;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
/* images with links, captions, etc */
|
||||
@@ -201,28 +307,26 @@ div.message {
|
||||
}
|
||||
table.history { border-style:none; }
|
||||
td.history { border-style:none; }
|
||||
div.history span.dash + strong { font-weight: normal; }
|
||||
span.result { font-size:larger; }
|
||||
span.info { font-size:smaller; font-style:italic; }
|
||||
div.rc hr { display: none; }
|
||||
div.rc li { padding-bottom: 0.5em; }
|
||||
div.rc li strong { font-weight: normal; }
|
||||
|
||||
/* Tables */
|
||||
table.user {
|
||||
margin: 1em 0;
|
||||
padding: 0 1em;
|
||||
border-top: 1px solid black;
|
||||
border-bottom: 1px solid black;
|
||||
margin: 1em 0;
|
||||
padding: 0 1em;
|
||||
border-top: 1px solid black;
|
||||
border-bottom: 1px solid black;
|
||||
}
|
||||
div.aside table.user {
|
||||
margin: 1em 0;
|
||||
padding: 0;
|
||||
margin: 1em 0;
|
||||
padding: 0;
|
||||
}
|
||||
table.user td, table.user th {
|
||||
border-style: none;
|
||||
padding:5px 10px;
|
||||
vertical-align: top;
|
||||
border-style: none;
|
||||
padding:5px 10px;
|
||||
vertical-align: top;
|
||||
}
|
||||
table.user th { font-weight:bold; }
|
||||
table.user td.r { text-align:right; }
|
||||
@@ -233,7 +337,7 @@ table.user td.mark { background-color:yellow; }
|
||||
tr:empty { display: block; height: 0.5em; }
|
||||
@media print {
|
||||
table {
|
||||
font-size: 9pt;
|
||||
font-size: 9pt;
|
||||
margin: 0;
|
||||
}
|
||||
table.user td, table.user th {
|
||||
|
||||
47
css/wiki.css
47
css/wiki.css
@@ -219,3 +219,50 @@ code {
|
||||
background: #eee;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Gentium Basic';
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
src: local('Gentium Basic Bold'), local('GentiumBasic-Bold'), url(/fonts/GenBasB.woff) format('woff');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Gentium Basic';
|
||||
font-style: italic;
|
||||
font-weight: 400;
|
||||
src: local('Gentium Basic Italic'), local('GentiumBasic-Italic'), url(/fonts/GenBasI.woff) format('woff');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Gentium Basic';
|
||||
font-style: italic;
|
||||
font-weight: 700;
|
||||
src: local('Gentium Basic Bold Italic'), local('GentiumBasic-BoldItalic'), url(/fonts/GenBasBI.woff) format('woff');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Gentium Basic';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: local('Gentium Basic'), local('GentiumBasic'), url(/fonts/GenBasR.woff) format('woff');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Gentium Plus';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: local('Gentium Plus'), local('GentiumPlus'), url(/fonts/GentiumPlus-R.woff) format('woff');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Gentium Plus';
|
||||
font-style: italic;
|
||||
font-weight: 400;
|
||||
src: local('Gentium Plus Italic'), local('GentiumPlus-Italic'), url(/fonts/GentiumPlus-I.woff) format('woff');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Symbola';
|
||||
src: local('Symbola'), url('/fonts/Symbola.woff') format('woff') url('/fonts/Symbola.ttf') format('truetype');
|
||||
}
|
||||
|
||||
43
modules/aawrapperdiv.pl
Normal file
43
modules/aawrapperdiv.pl
Normal file
@@ -0,0 +1,43 @@
|
||||
# Copyright (C) 2004, 2005 Fletcher T. Penney <fletcher@freeshell.org>
|
||||
#
|
||||
# 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
|
||||
|
||||
use strict;
|
||||
use v5.10;
|
||||
|
||||
AddModuleDescription('aawrapperdiv.pl', 'WrapperDiv Module');
|
||||
|
||||
our ($q);
|
||||
|
||||
*OldGetHeader = \&GetHeader;
|
||||
*GetHeader = \&WrapperGetHeader;
|
||||
|
||||
sub WrapperGetHeader {
|
||||
my ($id, $title, $oldId, $nocache, $status) = @_;
|
||||
my $result = OldGetHeader ($id, $title, $oldId, $nocache, $status);
|
||||
$result .= $q->start_div({-class=>'wrapper'});
|
||||
}
|
||||
|
||||
*OldPrintFooter = \&PrintFooter;
|
||||
*PrintFooter = \&WrapperPrintFooter;
|
||||
|
||||
sub WrapperPrintFooter {
|
||||
my ($id, $rev, $comment) = @_;
|
||||
print $q->start_div({-class=>'wrapper close'});
|
||||
print $q->end_div(), $q->end_div();
|
||||
OldPrintFooter($id, $rev, $comment);
|
||||
}
|
||||
@@ -22,7 +22,7 @@ our (@MyRules, $FreeLinkPattern);
|
||||
|
||||
push(@MyRules, \&LinksWithAccessKeys);
|
||||
sub LinksWithAccessKeys {
|
||||
if (m/\G(\[\[$FreeLinkPattern\{(.)\}\]\])/cg) {
|
||||
if (m/\G(\[\[$FreeLinkPattern\{(.)\}\]\])/cog) {
|
||||
my ($id, $key) = ($2, $3);
|
||||
Dirty($1);
|
||||
$id = FreeToNormal($id);
|
||||
|
||||
@@ -36,7 +36,7 @@ sub AdminPowerDelete {
|
||||
OpenPage($id);
|
||||
my $status = DeletePage($id);
|
||||
if ($status) {
|
||||
print $q->p(GetPageLink($id) . ' ' . T('not deleted:') . ' ' . $status);
|
||||
print $q->p(GetPageLink($id) . ' ' . T('not deleted: ')) . $status;
|
||||
} else {
|
||||
print $q->p(GetPageLink($id) . ' ' . T('deleted'));
|
||||
WriteRcLog($id, Ts('Deleted %s', $id), 0, $Page{revision},
|
||||
@@ -44,7 +44,7 @@ sub AdminPowerDelete {
|
||||
GetCluster($Page{text}));
|
||||
}
|
||||
# Regenerate index on next request
|
||||
Unlink($IndexFile);
|
||||
unlink($IndexFile);
|
||||
ReleaseLock();
|
||||
print $q->p(T('Main lock released.'));
|
||||
PrintFooter();
|
||||
@@ -61,30 +61,30 @@ sub AdminPowerRename {
|
||||
print $q->p(T('Main lock obtained.'));
|
||||
# page file -- only check for existing or missing pages here
|
||||
my $fname = GetPageFile($id);
|
||||
ReportError(Ts('The page %s does not exist', $id), '400 BAD REQUEST') unless IsFile($fname);
|
||||
ReportError(Ts('The page %s does not exist', $id), '400 BAD REQUEST') unless -f $fname;
|
||||
my $newfname = GetPageFile($new);
|
||||
ReportError(Ts('The page %s already exists', $new), '400 BAD REQUEST') if IsFile($newfname);
|
||||
ReportError(Ts('The page %s already exists', $new), '400 BAD REQUEST') if -f $newfname;
|
||||
# Regenerate index on next request -- remove this before errors can occur!
|
||||
Unlink($IndexFile);
|
||||
unlink($IndexFile);
|
||||
# page file
|
||||
CreateDir($PageDir); # It might not exist yet
|
||||
Rename($fname, $newfname)
|
||||
rename($fname, $newfname)
|
||||
or ReportError(Tss('Cannot rename %1 to %2', $fname, $newfname) . ": $!", '500 INTERNAL SERVER ERROR');
|
||||
# keep directory
|
||||
my $kdir = GetKeepDir($id);
|
||||
my $newkdir = GetKeepDir($new);
|
||||
CreateDir($KeepDir); # It might not exist yet (only the parent directory!)
|
||||
Rename($kdir, $newkdir)
|
||||
rename($kdir, $newkdir)
|
||||
or ReportError(Tss('Cannot rename %1 to %2', $kdir, $newkdir) . ": $!", '500 INTERNAL SERVER ERROR')
|
||||
if IsDir($kdir);
|
||||
if -d $kdir;
|
||||
# refer file
|
||||
if (defined(&GetRefererFile)) {
|
||||
my $rdir = GetRefererFile($id);
|
||||
my $newrdir = GetRefererFile($new);
|
||||
CreateDir($RefererDir); # It might not exist yet
|
||||
Rename($rdir, $newrdir)
|
||||
rename($rdir, $newrdir)
|
||||
or ReportError(Tss('Cannot rename %1 to %2', $rdir, $newrdir) . ": $!", '500 INTERNAL SERVER ERROR')
|
||||
if IsDir($rdir);
|
||||
if -d $rdir;
|
||||
}
|
||||
# RecentChanges
|
||||
OpenPage($new);
|
||||
|
||||
@@ -26,7 +26,7 @@ our ($q, $bol, %Action, %Page, $OpenPageName, $UseDiff, $UsePathInfo, $RssStyleS
|
||||
push(@MyRules, \&AggregateRule);
|
||||
|
||||
sub AggregateRule {
|
||||
if ($bol && m/\G(<aggregate\s+((("[^\"&]+",?\s*)+)|(sort\s+)?search\s+(.+?))>)/cg) {
|
||||
if ($bol && m/\G(<aggregate\s+((("[^\"&]+",?\s*)+)|(sort\s+)?search\s+(.+?))>)/gc) {
|
||||
Clean(CloseHtmlEnvironments());
|
||||
Dirty($1);
|
||||
my ($oldpos, $old_, $str, $sort, $search) = ((pos), $_, $3, $5, $6);
|
||||
@@ -126,8 +126,8 @@ sub DoAggregate {
|
||||
}
|
||||
}
|
||||
foreach my $id (@pages) {
|
||||
my $data = ParseData(ReadFileOrDie(GetPageFile(FreeToNormal($id))));
|
||||
my $page = $data->{text};
|
||||
my %data = ParseData(ReadFileOrDie(GetPageFile(FreeToNormal($id))));
|
||||
my $page = $data{text};
|
||||
my $size = length($page);
|
||||
my $i = index($page, "\n=");
|
||||
my $j = index($page, "\n----");
|
||||
@@ -136,13 +136,13 @@ sub DoAggregate {
|
||||
$page =~ s/^=.*\n//; # if it starts with a header
|
||||
my $name = $id;
|
||||
$name =~ s/_/ /g;
|
||||
my $date = TimeToRFC822($data->{ts});
|
||||
my $host = $data->{host};
|
||||
my $username = $data->{username};
|
||||
my $date = TimeToRFC822($data{ts});
|
||||
my $host = $data{host};
|
||||
my $username = $data{username};
|
||||
$username = QuoteHtml($username);
|
||||
$username = $host unless $username;
|
||||
my $minor = $data->{minor};
|
||||
my $revision = $data->{revision};
|
||||
my $minor = $data{minor};
|
||||
my $revision = $data{revision};
|
||||
my $cluster = GetCluster($page);
|
||||
my $description = ToString(sub { ApplyRules(QuoteHtml($page), 1, 0, undef, 'p') });
|
||||
$description .= $q->p(GetPageLink($id, T('Learn more...')))
|
||||
|
||||
@@ -26,11 +26,11 @@ AddModuleDescription('agree-disagree.pl', 'AgreeDisagreePlugin');
|
||||
push(@MyRules, \&AgreeDisagreeSupportRule);
|
||||
|
||||
push(@MyMacros, sub{ s/\[\+\]/"[+:" . GetParam('username', T('Anonymous'))
|
||||
. ':' . TimeToText($Now) . "]"/eg });
|
||||
push(@MyMacros, sub{ s/\[\+(:[^]:]+)\]/"[+$1:" . TimeToText($Now) . "]"/eg });
|
||||
. ':' . TimeToText($Now) . "]"/ge });
|
||||
push(@MyMacros, sub{ s/\[\+(:[^]:]+)\]/"[+$1:" . TimeToText($Now) . "]"/ge });
|
||||
push(@MyMacros, sub{ s/\[\-\]/"[-:" . GetParam('username', T('Anonymous'))
|
||||
. ':' . TimeToText($Now) . "]"/eg });
|
||||
push(@MyMacros, sub{ s/\[\-(:[^]:]+)\]/"[-$1:" . TimeToText($Now) . "]"/eg });
|
||||
. ':' . TimeToText($Now) . "]"/ge });
|
||||
push(@MyMacros, sub{ s/\[\-(:[^]:]+)\]/"[-$1:" . TimeToText($Now) . "]"/ge });
|
||||
|
||||
|
||||
$DefaultStyleSheet .= <<'EOT' unless $DefaultStyleSheet =~ /div\.agree/; # mod_perl?
|
||||
@@ -78,17 +78,17 @@ EOT
|
||||
|
||||
sub AgreeDisagreeSupportRule {
|
||||
if ($bol) {
|
||||
if ($bol && m/(\G(\s*\[\+(.*?)\]|\s*\[-(.*?)\])+)/cgs) {
|
||||
if ($bol && m/(\G(\s*\[\+(.*?)\]|\s*\[-(.*?)\])+)/gcs) {
|
||||
|
||||
my $votes = $1;
|
||||
my @ayes = ();
|
||||
my @nayes = ();
|
||||
while ($votes =~ m/\G.*?\[\+(.*?)\]/cgs) {
|
||||
while ($votes =~ m/\G.*?\[\+(.*?)\]/gcs) {
|
||||
my ($ignore, $name, $time) = split(/:/, $1, 3);
|
||||
push(@ayes, $name);
|
||||
}
|
||||
my $votes2 = $votes;
|
||||
while ($votes2 =~ m/\G.*?\[-(.*?)\]/cgs) {
|
||||
while ($votes2 =~ m/\G.*?\[-(.*?)\]/gcs) {
|
||||
my ($ignore, $name, $time) = split(/:/, $1, 3);
|
||||
push(@nayes, $name);
|
||||
}
|
||||
|
||||
@@ -21,13 +21,13 @@ our ($q, %Page, $FootnoteNumber, $FreeLinkPattern, @MyRules, $BracketWiki);
|
||||
push(@MyRules, \&AnchorsRule);
|
||||
|
||||
sub AnchorsRule {
|
||||
if (m/\G\[\[\#$FreeLinkPattern\]\]/cg) {
|
||||
if (m/\G\[\[\#$FreeLinkPattern\]\]/gc) {
|
||||
return $q->a({-href=>'#' . FreeToNormal($1), -class=>'local anchor'}, $1);
|
||||
} elsif ($BracketWiki && m/\G\[\[\#$FreeLinkPattern\|([^\]]+)\]\]/cg) {
|
||||
} elsif ($BracketWiki && m/\G\[\[\#$FreeLinkPattern\|([^\]]+)\]\]/gc) {
|
||||
return $q->a({-href=>'#' . FreeToNormal($1), -class=>'local anchor'}, $2);
|
||||
} elsif ($BracketWiki && m/\G(\[\[$FreeLinkPattern\#$FreeLinkPattern\|([^\]]+)\]\])/cg
|
||||
or m/\G(\[\[\[$FreeLinkPattern\#$FreeLinkPattern\]\]\])/cg
|
||||
or m/\G(\[\[$FreeLinkPattern\#$FreeLinkPattern\]\])/cg) {
|
||||
} elsif ($BracketWiki && m/\G(\[\[$FreeLinkPattern\#$FreeLinkPattern\|([^\]]+)\]\])/cog
|
||||
or m/\G(\[\[\[$FreeLinkPattern\#$FreeLinkPattern\]\]\])/cog
|
||||
or m/\G(\[\[$FreeLinkPattern\#$FreeLinkPattern\]\])/cog) {
|
||||
# This one is not a dirty rule because the output is always a page
|
||||
# link, never an edit link (unlike normal free links).
|
||||
my $bracket = (substr($1, 0, 3) eq '[[[');
|
||||
@@ -47,7 +47,7 @@ sub AnchorsRule {
|
||||
$text = $id unless $text;
|
||||
$text =~ s/_/ /g;
|
||||
return ScriptLink(UrlEncode($id), $text, $class, undef, $title);
|
||||
} elsif (m/\G\[\:$FreeLinkPattern\]/cg) {
|
||||
} elsif (m/\G\[\:$FreeLinkPattern\]/gc) {
|
||||
return $q->a({-name=>FreeToNormal($1), -class=>'anchor'}, '');
|
||||
}
|
||||
return;
|
||||
|
||||
@@ -34,7 +34,7 @@ push(@MyRules, \&MaskEmailRule);
|
||||
|
||||
sub MaskEmailRule {
|
||||
# Allow [email@foo.bar Email Me] links
|
||||
if (m/\G\[($EmailRegExp(\s\w+)*\s*)\]/cgi) {
|
||||
if (m/\G\[($EmailRegExp(\s\w+)*\s*)\]/igc) {
|
||||
my $chunk = $1;
|
||||
$chunk =~ s/($EmailRegExp)//i;
|
||||
my $email = $1;
|
||||
@@ -51,7 +51,7 @@ sub MaskEmailRule {
|
||||
return "<a href=\"mailto:$email\">$chunk</a>";
|
||||
}
|
||||
|
||||
if (m/\G($EmailRegExp)/cgi) {
|
||||
if (m/\G($EmailRegExp)/igc) {
|
||||
my $email = $1;
|
||||
if ($DoMaskEmail) {
|
||||
my $masked="";
|
||||
|
||||
@@ -20,7 +20,7 @@ AddModuleDescription('askpage.pl', 'Ask Page Extension');
|
||||
|
||||
use Fcntl qw(:DEFAULT :flock);
|
||||
|
||||
our ($DataDir, %Translate, @MyFooters);
|
||||
our ($DataDir);
|
||||
our ($AskPage, $QuestionPage, $NewQuestion);
|
||||
# Don't forget to set your $CommentsPattern to include both $AskPage and $QuestionPage
|
||||
$AskPage = 'Ask';
|
||||
@@ -29,7 +29,7 @@ $NewQuestion = 'Write your question here:';
|
||||
|
||||
sub IncrementInFile {
|
||||
my $filename = shift;
|
||||
sysopen my $fh, encode_utf8($filename), O_RDWR|O_CREAT or die "can't open $filename: $!";
|
||||
sysopen my $fh, $filename, O_RDWR|O_CREAT or die "can't open $filename: $!";
|
||||
flock $fh, LOCK_EX or die "can't flock $filename: $!";
|
||||
my $num = <$fh> || 1;
|
||||
seek $fh, 0, 0 or die "can't rewind $filename: $!";
|
||||
@@ -39,8 +39,8 @@ sub IncrementInFile {
|
||||
return $num;
|
||||
}
|
||||
|
||||
*OldAskPageDoPost = \&DoPost;
|
||||
*DoPost = \&NewAskPageDoPost;
|
||||
*OldAskPageDoPost=\&DoPost;
|
||||
*DoPost=\&NewAskPageDoPost;
|
||||
sub NewAskPageDoPost {
|
||||
my $id = FreeToNormal(shift);
|
||||
if ($id eq $AskPage and not GetParam('text', undef)) { # comment, not a regular edit
|
||||
@@ -51,18 +51,18 @@ sub NewAskPageDoPost {
|
||||
OldAskPageDoPost($id, @_); # keep original functionality for regular edits
|
||||
}
|
||||
|
||||
*OldAskPageGetCommentForm = \&GetCommentForm;
|
||||
*GetCommentForm = \&NewAskPageGetCommentForm;
|
||||
@MyFooters = map { $_ == \&OldAskPageGetCommentForm ? \&NewAskPageGetCommentForm : $_ } @MyFooters;
|
||||
|
||||
sub NewAskPageGetCommentForm {
|
||||
my ($id) = @_;
|
||||
$Translate{'Add your comment here:'} = $NewQuestion if $id eq $AskPage;
|
||||
OldAskPageGetCommentForm(@_);
|
||||
*OldAskPageGetTextArea=\&GetTextArea;
|
||||
*GetTextArea=\&NewAskPageGetTextArea;
|
||||
sub NewAskPageGetTextArea {
|
||||
my ($name, $text, @rest) = @_;
|
||||
if ($name eq 'aftertext' and not $text and GetId() eq $AskPage) {
|
||||
$text = $NewQuestion;
|
||||
}
|
||||
OldAskPageGetTextArea($name, $text, @rest);
|
||||
}
|
||||
|
||||
*OldAskPageJournalSort = \&JournalSort;
|
||||
*JournalSort = \&NewAskPageJournalSort;
|
||||
*OldAskPageJournalSort=\&JournalSort;
|
||||
*JournalSort=\&NewAskPageJournalSort;
|
||||
sub NewAskPageJournalSort {
|
||||
return OldAskPageJournalSort() unless $a =~ m/^$QuestionPage\d+$/ and $b =~ m/^$QuestionPage\d+$/;
|
||||
($b =~ m/$QuestionPage(\d+)/)[0] <=> ($a =~ m/$QuestionPage(\d+)/)[0];
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
use strict;
|
||||
use v5.10;
|
||||
|
||||
use XML::Atom;
|
||||
use XML::Atom::Entry;
|
||||
use XML::Atom::Link;
|
||||
use XML::Atom::Person;
|
||||
@@ -150,7 +149,7 @@ sub GetRcAtom {
|
||||
# Based on DoPost
|
||||
sub DoAtomSave {
|
||||
my ($type, $oldid) = @_;
|
||||
my $entry = AtomEntry($type);
|
||||
my $entry = AtomEntry();
|
||||
my $title = $entry->title();
|
||||
my $author = $entry->author();
|
||||
SetParam('username', $author->name) if $author; # Used in Save()
|
||||
@@ -231,8 +230,15 @@ sub DoAtomGet {
|
||||
}
|
||||
|
||||
sub AtomEntry {
|
||||
my $type = shift || 'POST';
|
||||
my $data = $q->param($type . 'DATA'); # PUTDATA or POSTDATA
|
||||
my $data = $q->param('POSTDATA');
|
||||
if (not $data) {
|
||||
# CGI provides POSTDATA for POST requests, not for PUT requests.
|
||||
# The following code is based on the CGI->init code.
|
||||
my $content_length = defined($ENV{'CONTENT_LENGTH'}) ? $ENV{'CONTENT_LENGTH'} : 0;
|
||||
if ($content_length > 0 and $content_length < $MaxPost) {
|
||||
$q->read_from_client(\$data, $content_length, 0);
|
||||
}
|
||||
}
|
||||
my $entry = XML::Atom::Entry->new(\$data);
|
||||
return $entry;
|
||||
}
|
||||
|
||||
@@ -171,11 +171,11 @@ sub UserCanEditAutoLockFix {
|
||||
return 0 if $id eq 'SampleUndefinedPage' or $id eq T('SampleUndefinedPage')
|
||||
or $id eq 'Sample_Undefined_Page' or $id eq T('Sample_Undefined_Page');
|
||||
return 1 if UserIsAdmin() || UserIsEditor();
|
||||
return 0 if $id ne '' and IsFile(GetLockedPageFile($id));
|
||||
return 0 if $LockOnCreation{$id} and not IsFile(GetPageFile($id)); # new page
|
||||
return 0 if !$EditAllowed or IsFile($NoEditFile);
|
||||
return 0 if $id ne '' and -f GetLockedPageFile($id);
|
||||
return 0 if $LockOnCreation{$id} and not -f GetPageFile($id); # new page
|
||||
return 0 if !$EditAllowed or -f $NoEditFile;
|
||||
return 0 if $editing and UserIsBanned(); # this call is more expensive
|
||||
return 0 if $EditAllowed >= 2 and (not $CommentsPrefix or $id !~ /^$CommentsPrefix/);
|
||||
return 0 if $EditAllowed >= 2 and (not $CommentsPrefix or $id !~ /^$CommentsPrefix/o);
|
||||
return 1 if $EditAllowed >= 3 and ($comment or (GetParam('aftertext', '') and not GetParam('text', '')));
|
||||
return 0 if $EditAllowed >= 3;
|
||||
return 1;
|
||||
|
||||
@@ -44,8 +44,8 @@ sub BacklinksMenu {
|
||||
$Action{buildback} = \&BuildBacklinkDatabase;
|
||||
sub BuildBacklinkDatabase {
|
||||
print GetHttpHeader('text/plain');
|
||||
Unlink($backfile); # Remove old database
|
||||
tie my %backhash, 'MLDBM', encode_utf8($backfile) or die "Cannot open file $backfile $!\n";
|
||||
unlink $backfile; # Remove old database
|
||||
tie my %backhash, 'MLDBM', $backfile or die "Cannot open file $backfile $!\n";
|
||||
log1("Starting Database Store Process ... please wait\n\n");
|
||||
|
||||
foreach my $name (AllPagesList()) {
|
||||
@@ -101,7 +101,7 @@ sub GetBackLink {
|
||||
|
||||
our ($BacklinkBanned);
|
||||
$BacklinkBanned = "HomePage|ScratchPad" if !$BacklinkBanned;
|
||||
tie my %backhash, 'MLDBM', encode_utf8($backfile), O_CREAT|O_RDWR, oct(644) or die "Cannot open file $backfile $!\n";
|
||||
tie my %backhash, 'MLDBM', $backfile, O_CREAT|O_RDWR, oct(644) or die "Cannot open file $backfile $!\n";
|
||||
|
||||
# Search database for matches
|
||||
while ( my ($source, $hashes) = each %backhash ) {
|
||||
@@ -117,7 +117,7 @@ sub GetBackLink {
|
||||
foreach my $backlink (@backlinks) {
|
||||
my ($class, $resolved, $title, $exists) = ResolveId($backlink);
|
||||
if (($resolved ne $id) && ($resolved !~ /^($BacklinkBanned)$/)) {
|
||||
push(@unpopped, ScriptLink(UrlEncode($resolved), $resolved, $class . ' backlink', undef, Ts('Internal Page: %s', $resolved)));
|
||||
push(@unpopped, ScriptLink(UrlEncode($resolved), $resolved, $class . ' backlink', undef, T('Internal Page: ' . $resolved)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -124,10 +124,10 @@ sub NewBanContributorsWriteRcLog {
|
||||
and $OpenPageName eq $id and UserIsAdmin()) {
|
||||
# we currently have the clean page loaded, so we need to reload
|
||||
# the spammed revision (there is a possible race condition here)
|
||||
my $old = GetTextRevision($Page{revision} - 1, 1)->{text};
|
||||
my %urls = map {$_ => 1 } $old =~ /$UrlPattern/g;
|
||||
my ($old) = GetTextRevision($Page{revision}-1, 1);
|
||||
my %urls = map {$_ => 1 } $old =~ /$UrlPattern/og;
|
||||
# we open the file again to force a load of the despammed page
|
||||
foreach my $url ($Page{text} =~ /$UrlPattern/g) {
|
||||
foreach my $url ($Page{text} =~ /$UrlPattern/og) {
|
||||
delete($urls{$url});
|
||||
}
|
||||
# we also remove any candidates that are already banned
|
||||
@@ -153,7 +153,7 @@ sub NewBanContributorsWriteRcLog {
|
||||
$q->submit(T('Ban!'))),
|
||||
$q->end_form();
|
||||
};
|
||||
print $q->p(T("Consider banning the IP number as well:"), ' ',
|
||||
print $q->p(T("Consider banning the IP number as well: "),
|
||||
ScriptLink('action=ban;id=' . UrlEncode($id), T('Ban contributors')));
|
||||
};
|
||||
return OldBanContributorsWriteRcLog(@_);
|
||||
|
||||
@@ -61,12 +61,12 @@ sub bbCodeRule {
|
||||
return AddHtmlEnvironment('strong', qq{class="highlight"}); }
|
||||
elsif ($tag eq 'url') {
|
||||
if ($option) {
|
||||
$option =~ /^($UrlProtocols)/;
|
||||
$option =~ /^($UrlProtocols)/o;
|
||||
my $class = "url $1";
|
||||
return AddHtmlEnvironment('a', qq{href="$option" class="$class"}); }
|
||||
elsif (/\G$FullUrlPattern\s*\[\/url\]/cgi) {
|
||||
elsif (/\G$FullUrlPattern\s*\[\/url\]/cogi) {
|
||||
return GetUrl($1); }}
|
||||
elsif ($tag eq 'img' and /\G$FullUrlPattern\s*\[\/img\]/cgi) {
|
||||
elsif ($tag eq 'img' and /\G$FullUrlPattern\s*\[\/img\]/cogi) {
|
||||
return GetUrl($1, undef, undef, 1); } # force image
|
||||
elsif ($tag eq 'quote') {
|
||||
my $html = CloseHtmlEnvironments();
|
||||
|
||||
@@ -60,6 +60,7 @@ sub AddRecentVisitor {
|
||||
my $url = ScriptUrl(join(';', "action=$action;id=" . UrlEncode($id),
|
||||
map { $_ . '=' . UrlEncode(GetParam($_)) }
|
||||
keys %params));
|
||||
my $url = $q->url(-path_info=>1,-query=>1);
|
||||
my $download = GetParam('action', 'browse') eq 'download'
|
||||
|| GetParam('download', 0)
|
||||
|| $q->path_info() =~ m/\/download\//;
|
||||
|
||||
@@ -28,10 +28,10 @@ push(@MyRules, \&BlockQuoteRule);
|
||||
sub BlockQuoteRule {
|
||||
# indented text using : with the option of spanning multiple text
|
||||
# paragraphs (but not lists etc).
|
||||
if (InElement('blockquote') && m/\G(\s*\n)+:[ \t]*/cg) {
|
||||
if (InElement('blockquote') && m/\G(\s*\n)+:[ \t]*/cog) {
|
||||
return CloseHtmlEnvironmentUntil('blockquote')
|
||||
. AddHtmlEnvironment('p');
|
||||
} elsif ($bol && m/\G(\s*\n)*:[ \t]*/cg) {
|
||||
} elsif ($bol && m/\G(\s*\n)*:[ \t]*/cog) {
|
||||
return CloseHtmlEnvironments()
|
||||
. AddHtmlEnvironment('blockquote')
|
||||
. AddHtmlEnvironment('p');
|
||||
|
||||
@@ -74,7 +74,7 @@ sub Cal {
|
||||
$link .= ScriptLink('action=collect;match=' . UrlEncode($re), $day, 'local collection' . $class);
|
||||
}
|
||||
$link;
|
||||
}}eg;
|
||||
}}ge;
|
||||
$cal =~ s{(\S+) (\d\d\d\d)}{{
|
||||
my ($month_text, $year_text) = ($1, $2);
|
||||
my $date = sprintf("%d-%02d", $year, $mon);
|
||||
@@ -118,22 +118,22 @@ sub DoCollect {
|
||||
push(@MyRules, \&CalendarRule);
|
||||
|
||||
sub CalendarRule {
|
||||
if (/\G(calendar:(\d\d\d\d))/cg) {
|
||||
if (/\G(calendar:(\d\d\d\d))/gc) {
|
||||
my $oldpos = pos;
|
||||
Clean(CloseHtmlEnvironments());
|
||||
Dirty($1);
|
||||
PrintYearCalendar($2);
|
||||
pos = $oldpos;
|
||||
return AddHtmlEnvironment('p');
|
||||
} elsif (/\G(month:(\d\d\d\d)-(\d\d))/cg) {
|
||||
} elsif (/\G(month:(\d\d\d\d)-(\d\d))/gc) {
|
||||
my $oldpos = pos;
|
||||
Clean(CloseHtmlEnvironments());
|
||||
Dirty($1);
|
||||
print Cal($2, $3);
|
||||
pos = $oldpos;
|
||||
return AddHtmlEnvironment('p');
|
||||
} elsif (/\G(month:([+-]\d\d?))/cg
|
||||
or /\G(\[\[month:([+-]\d\d?) $FreeLinkPattern\]\])/cg) {
|
||||
} elsif (/\G(month:([+-]\d\d?))/gc
|
||||
or /\G(\[\[month:([+-]\d\d?) $FreeLinkPattern\]\])/gc) {
|
||||
my $oldpos = pos;
|
||||
Clean(CloseHtmlEnvironments());
|
||||
Dirty($1);
|
||||
|
||||
@@ -77,7 +77,7 @@ sub DoCheckBox{
|
||||
$summary{$3} = 0 if $2 eq 'x' or $2 eq 'X';
|
||||
"${1}[[ :${3}]]";
|
||||
}
|
||||
}egi;
|
||||
}eig;
|
||||
SetParam('text', $text);
|
||||
SetParam('summary', join(', ', map {
|
||||
if ($summary{$_}) {
|
||||
|
||||
@@ -62,7 +62,7 @@ foreach (@ClusterMapAdminPages){
|
||||
}
|
||||
|
||||
sub ClusterMapRule {
|
||||
if (/\G^([\n\r]*\<\s*clustermap\s*\>\s*)$/cgm) {
|
||||
if (/\G^([\n\r]*\<\s*clustermap\s*\>\s*)$/mgc) {
|
||||
Dirty($1);
|
||||
my $oldpos = pos;
|
||||
my $oldstr = $_;
|
||||
|
||||
@@ -30,7 +30,7 @@ sub CommentDivWrapper {
|
||||
return $q->start_div({-class=>'userComment'});
|
||||
}
|
||||
}
|
||||
if ($OpenPageName =~ /$CommentsPattern/) {
|
||||
if ($OpenPageName =~ /$CommentsPattern/o) {
|
||||
if ($bol and m/\G(\s*\n)*----+[ \t]*\n?/cg) {
|
||||
my $html = CloseHtmlEnvironments()
|
||||
. ($CommentDiv++ > 0 ? $q->end_div() : $q->h2({-class=>'commentsHeading'}, T('Comments:'))) . $q->start_div({-class=>'userComment'})
|
||||
|
||||
@@ -52,15 +52,15 @@ sub NewCommentcountScriptLink {
|
||||
if ($CommentsPrefix && $action =~ /^$CommentsPrefix(.*)/) { # TODO use $CommentsPattern ?
|
||||
# Add the number of comments here
|
||||
my $id = $action;
|
||||
$id =~ s/%([0-9a-f][0-9a-f])/chr(hex($1))/eg; # undo urlencode
|
||||
$id =~ s/%([0-9a-f][0-9a-f])/chr(hex($1))/ge; # undo urlencode
|
||||
my $comments = GetPageContent($id);
|
||||
my $num = 0;
|
||||
if($comments =~ /=== (\d+) Comments?\. ===/) {
|
||||
$num = $1;
|
||||
}
|
||||
# Fix plurals
|
||||
my $plural = T('Comments on');
|
||||
my $singular = T('Comment on');
|
||||
my $plural = T('Comments on ');
|
||||
my $singular = T('Comment on ');
|
||||
$text =~ s/$plural/$singular/ if($num == 1);
|
||||
$text = $num . ' ' . $text;
|
||||
}
|
||||
|
||||
@@ -218,7 +218,7 @@ sub CreoleRule {
|
||||
}
|
||||
# escape next char (and prevent // in URLs from enabling italics)
|
||||
# ~
|
||||
elsif (m/\G(~($FullUrlPattern|\S))/cg) {
|
||||
elsif (m/\G(~($FullUrlPattern|\S))/cgo) {
|
||||
return
|
||||
($CreoleTildeAlternative and
|
||||
index( 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
|
||||
@@ -234,12 +234,12 @@ sub CreoleRule {
|
||||
# {{{preformatted code}}}
|
||||
elsif (m/\G\{\{\{(.*?}*)\}\}\}/cg) { return $q->code($1); }
|
||||
# download: {{pic}} and {{pic|text}}
|
||||
elsif (m/\G(\{\{$FreeLinkPattern$CreoleLinkTextPattern\}\})/cgs) {
|
||||
elsif (m/\G(\{\{$FreeLinkPattern$CreoleLinkTextPattern\}\})/cgos) {
|
||||
my $text = $4 || $2;
|
||||
return GetCreoleLinkHtml($1, GetDownloadLink(FreeToNormal($2), 1, undef, $text), $text);
|
||||
}
|
||||
# image link: {{url}} and {{url|text}}
|
||||
elsif (m/\G\{\{$FullUrlPattern$CreoleLinkTextPattern\}\}/cgs) {
|
||||
elsif (m/\G\{\{$FullUrlPattern$CreoleLinkTextPattern\}\}/cgos) {
|
||||
return GetCreoleImageHtml(
|
||||
$q->a({-href=> UnquoteHtml($1),
|
||||
-class=> 'image outside'},
|
||||
@@ -250,7 +250,7 @@ sub CreoleRule {
|
||||
}
|
||||
# image link: [[link|{{pic}}]] and [[link|{{pic|text}}]]
|
||||
elsif (m/\G(\[\[$FreeLinkPattern$CreoleLinkPipePattern
|
||||
\{\{$FreeLinkPattern$CreoleLinkTextPattern\}\}\]\])/cgsx) {
|
||||
\{\{$FreeLinkPattern$CreoleLinkTextPattern\}\}\]\])/cgosx) {
|
||||
my $text = $5 || $2;
|
||||
return GetCreoleLinkHtml($1, GetCreoleImageHtml(
|
||||
ScriptLink(UrlEncode(FreeToNormal($2)),
|
||||
@@ -261,7 +261,7 @@ sub CreoleRule {
|
||||
}
|
||||
# image link: [[link|{{url}}]] and [[link|{{url|text}}]]
|
||||
elsif (m/\G(\[\[$FreeLinkPattern$CreoleLinkPipePattern
|
||||
\{\{$FullUrlPattern$CreoleLinkTextPattern\}\}\]\])/cgsx) {
|
||||
\{\{$FullUrlPattern$CreoleLinkTextPattern\}\}\]\])/cgosx) {
|
||||
my $text = $5 || $2;
|
||||
return GetCreoleLinkHtml($1, GetCreoleImageHtml(
|
||||
ScriptLink(UrlEncode(FreeToNormal($2)),
|
||||
@@ -272,7 +272,7 @@ sub CreoleRule {
|
||||
}
|
||||
# image link: [[url|{{pic}}]] and [[url|{{pic|text}}]]
|
||||
elsif (m/\G(\[\[$FullUrlPattern$CreoleLinkPipePattern
|
||||
\{\{$FreeLinkPattern$CreoleLinkTextPattern\}\}\]\])/cgsx) {
|
||||
\{\{$FreeLinkPattern$CreoleLinkTextPattern\}\}\]\])/cgosx) {
|
||||
my $text = $5 || $2;
|
||||
return GetCreoleLinkHtml($1, GetCreoleImageHtml(
|
||||
$q->a({-href=> UnquoteHtml($2), -class=> 'image outside'},
|
||||
@@ -283,7 +283,7 @@ sub CreoleRule {
|
||||
}
|
||||
# image link: [[url|{{url}}]] and [[url|{{url|text}}]]
|
||||
elsif (m/\G\[\[$FullUrlPattern$CreoleLinkPipePattern
|
||||
\{\{$FullUrlPattern$CreoleLinkTextPattern\}\}\]\]/cgsx) {
|
||||
\{\{$FullUrlPattern$CreoleLinkTextPattern\}\}\]\]/cgosx) {
|
||||
return GetCreoleImageHtml(
|
||||
$q->a({-href=> UnquoteHtml($1), -class=> 'image outside'},
|
||||
$q->img({-src=> UnquoteHtml($2),
|
||||
@@ -292,7 +292,7 @@ sub CreoleRule {
|
||||
-class=> 'url outside'})));
|
||||
}
|
||||
# link: [[url]] and [[url|text]]
|
||||
elsif (m/\G\[\[$FullUrlPattern$CreoleLinkTextPattern\]\]/cgs) {
|
||||
elsif (m/\G\[\[$FullUrlPattern$CreoleLinkTextPattern\]\]/cgos) {
|
||||
# Permit embedding of Creole syntax within link text. (Rather complicated,
|
||||
# but it does the job remarkably.)
|
||||
my $link_url = $1;
|
||||
@@ -305,7 +305,7 @@ sub CreoleRule {
|
||||
return GetUrl($link_url, $link_text, 1);
|
||||
}
|
||||
# link: [[page]] and [[page|text]]
|
||||
elsif (m/\G(\[\[$FreeLinkPattern$CreoleLinkTextPattern\]\])/cgs) {
|
||||
elsif (m/\G(\[\[$FreeLinkPattern$CreoleLinkTextPattern\]\])/cgos) {
|
||||
my $markup = $1;
|
||||
my $page_name = $2;
|
||||
my $link_text = $4 ? CreoleRuleRecursive($4, @_) : $page_name;
|
||||
@@ -315,7 +315,7 @@ sub CreoleRule {
|
||||
}
|
||||
# interlink: [[Wiki:page]] and [[Wiki:page|text]]
|
||||
elsif ($is_interlinking and
|
||||
m/\G(\[\[$FreeInterLinkPattern$CreoleLinkTextPattern\]\])/cgs) {
|
||||
m/\G(\[\[$FreeInterLinkPattern$CreoleLinkTextPattern\]\])/cgos) {
|
||||
my $markup = $1;
|
||||
my $interlink = $2;
|
||||
my $interlink_text = $4;
|
||||
|
||||
@@ -28,8 +28,8 @@ $RuleOrder{\&CrumbsRule} = -10; # run before default rules!
|
||||
|
||||
sub CrumbsRule {
|
||||
if (not (pos) # first!
|
||||
and (($WikiLinks && /\G($LinkPattern\n)/cg)
|
||||
or ($FreeLinks && /\G(\[\[$FreeLinkPattern\]\]\n)/cg))) {
|
||||
and (($WikiLinks && /\G($LinkPattern\n)/cgo)
|
||||
or ($FreeLinks && /\G(\[\[$FreeLinkPattern\]\]\n)/cgo))) {
|
||||
my $oldpos = pos; # will be trashed below
|
||||
my $cluster = FreeToNormal($2);
|
||||
my %seen = ($cluster => 1);
|
||||
|
||||
@@ -133,14 +133,14 @@ sub DespamPage {
|
||||
# from DoHistory()
|
||||
my @revisions = sort {$b <=> $a} map { m|/([0-9]+).kp$|; $1; } GetKeepFiles($OpenPageName);
|
||||
foreach my $revision (@revisions) {
|
||||
my ($revisionPage, $rev) = GetTextRevision($revision, 1); # quiet
|
||||
my ($text, $rev) = GetTextRevision($revision, 1); # quiet
|
||||
if (not $rev) {
|
||||
print ': ' . Ts('Cannot find revision %s.', $revision);
|
||||
return;
|
||||
} elsif (not DespamBannedContent($revisionPage->{text})) {
|
||||
} elsif (not DespamBannedContent($text)) {
|
||||
my $summary = Tss('Revert to revision %1: %2', $revision, $rule);
|
||||
print ': ' . $summary;
|
||||
Save($OpenPageName, $revisionPage->{text}, $summary) unless GetParam('debug', 0);
|
||||
Save($OpenPageName, $text, $summary) unless GetParam('debug', 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,7 +77,8 @@ sub DoUnifiedDiff { # copied from DoDiff
|
||||
RequestLockDir('diff') or return '';
|
||||
WriteStringToFile($oldName, $_[0]);
|
||||
WriteStringToFile($newName, $_[1]);
|
||||
my $diff_out = decode_utf8(`diff -U 99999 -- \Q$oldName\E \Q$newName\E | tail -n +7`); # should be +4, but we always add extra line # TODO that workaround is ugly, fix it!
|
||||
my $diff_out = `diff -U 99999 -- \Q$oldName\E \Q$newName\E | tail -n +7`; # should be +4, but we always add extra line # TODO that workaround is ugly, fix it!
|
||||
utf8::decode($diff_out); # needs decoding
|
||||
$diff_out =~ s/\n\K\\ No newline.*\n//g; # Get rid of common complaint.
|
||||
ReleaseLockDir('diff');
|
||||
# No need to unlink temp files--next diff will just overwrite.
|
||||
|
||||
@@ -30,7 +30,7 @@ $DojoTheme = 'tundra';
|
||||
push (@MyRules, \&WysiwygRule);
|
||||
|
||||
sub WysiwygRule {
|
||||
if (m/\G(<.*?>)/cg) {
|
||||
if (m/\G(<.*?>)/gc) {
|
||||
return $1 if substr($1,5,6) eq 'script'
|
||||
or substr($1,4,6) eq 'script';
|
||||
return UnquoteHtml($1);
|
||||
|
||||
@@ -28,8 +28,8 @@ push( @MyRules, \&DownloadSupportRule );
|
||||
# [[download:page name|alternate title]]
|
||||
|
||||
sub DownloadSupportRule {
|
||||
if (m/\G(\[\[download:$FreeLinkPattern\|([^\]]+)\]\])/cg
|
||||
or m!\G(\[\[download:$FreeLinkPattern\]\])!cg) {
|
||||
if (m/\G(\[\[download:$FreeLinkPattern\|([^\]]+)\]\])/cog
|
||||
or m!\G(\[\[download:$FreeLinkPattern\]\])!cog) {
|
||||
Dirty($1);
|
||||
print GetDownloadLink($2, undef, undef, $3);
|
||||
return '';
|
||||
|
||||
@@ -29,7 +29,7 @@ push(@MyInitVariables, \&DraftInit);
|
||||
sub DraftInit {
|
||||
if (GetParam('Draft', '')) {
|
||||
SetParam('action', 'draft') ; # Draft button used
|
||||
} elsif (IsFile("$DraftDir/" . GetParam('username', $q->remote_addr())) # draft exists
|
||||
} elsif (-f "$DraftDir/" . GetParam('username', $q->remote_addr()) # draft exists
|
||||
and $FooterNote !~ /action=draft/) { # take care of mod_perl persistence
|
||||
$FooterNote = $q->p(ScriptLink('action=draft', T('Recover Draft'))) . $FooterNote;
|
||||
}
|
||||
@@ -47,11 +47,11 @@ sub DoDraft {
|
||||
WriteStringToFile($draft, EncodePage(text=>$text, id=>$id));
|
||||
SetParam('msg', T('Draft saved')); # invalidate cache
|
||||
print GetHttpHeader('', T('Draft saved'), '204 NO CONTENT');
|
||||
} elsif (IsFile($draft)) {
|
||||
my $data = ParseData(ReadFileOrDie($draft));
|
||||
Unlink($draft);
|
||||
} elsif (-f $draft) {
|
||||
my %data = ParseData(ReadFileOrDie($draft));
|
||||
unlink ($draft);
|
||||
$Message .= $q->p(T('Draft recovered'));
|
||||
DoEdit($data->{id}, $data->{text}, 1);
|
||||
DoEdit($data{id}, $data{text}, 1);
|
||||
} else {
|
||||
ReportError(T('No draft available to recover'), '404 NOT FOUND');
|
||||
}
|
||||
@@ -76,19 +76,22 @@ push(@MyMaintenance, \&DraftCleanup);
|
||||
|
||||
sub DraftFiles {
|
||||
return map {
|
||||
substr($_, length($DraftDir) + 1);
|
||||
} Glob("$DraftDir/*"), Glob("$DraftDir/.*");
|
||||
my $x = $_;
|
||||
$x = substr($x, length($DraftDir) + 1);
|
||||
utf8::decode($x);
|
||||
$x;
|
||||
} bsd_glob("$DraftDir/*"), bsd_glob("$DraftDir/.*");
|
||||
}
|
||||
|
||||
sub DraftCleanup {
|
||||
print '<p>' . T('Draft Cleanup');
|
||||
foreach my $draft (DraftFiles()) {
|
||||
next if $draft eq '.' or $draft eq '..';
|
||||
my $ts = Modified("$DraftDir/$draft");
|
||||
my $ts = (stat("$DraftDir/$draft"))[9];
|
||||
if ($Now - $ts < 1209600) { # 14*24*60*60
|
||||
print $q->br(), Tss("%1 was last modified %2 and was kept",
|
||||
$draft, CalcTimeSince($Now - $ts));
|
||||
} elsif (Unlink("$DraftDir/$draft")) {
|
||||
} elsif (unlink("$DraftDir/$draft")) {
|
||||
print $q->br(), Tss("%1 was last modified %2 and was deleted",
|
||||
$draft, CalcTimeSince($Now - $ts));
|
||||
} else {
|
||||
|
||||
@@ -18,7 +18,7 @@ use v5.10;
|
||||
|
||||
AddModuleDescription('edit-cluster.pl', 'Edit Cluster Extension');
|
||||
|
||||
our ($q, $FS, $RcDefault, @RcDays, $RecentTop, $LastUpdate, $ShowAll);
|
||||
our ($q, $FS, $RcDefault, @RcDays, $RecentTop, $LastUpdate);
|
||||
|
||||
our $EditCluster = 'EditCluster';
|
||||
|
||||
@@ -34,7 +34,7 @@ sub GetRc {
|
||||
$changetime{$pagename} = $ts;
|
||||
}
|
||||
my $date = '';
|
||||
my $all = GetParam('all', $ShowAll);
|
||||
my $all = GetParam('all', 0);
|
||||
my ($idOnly, $userOnly, $hostOnly, $clusterOnly, $filterOnly, $match, $lang) =
|
||||
map { GetParam($_, ''); }
|
||||
('rcidonly', 'rcuseronly', 'rchostonly', 'rcclusteronly',
|
||||
@@ -128,7 +128,7 @@ sub EditClusterNewRcHeader {
|
||||
$action = "action=rc$action";
|
||||
}
|
||||
my $days = GetParam('days', $RcDefault);
|
||||
my $all = GetParam('all', $ShowAll);
|
||||
my $all = GetParam('all', 0);
|
||||
my @menu;
|
||||
if ($all) {
|
||||
push(@menu, ScriptLink("$action;days=$days;all=0",
|
||||
|
||||
@@ -21,14 +21,14 @@ push(@MyRules, \&EmailQuoteRule);
|
||||
|
||||
sub EmailQuoteRule {
|
||||
# > on a line of its own should work
|
||||
if ($bol && m/\G(\s*\n)*((\>))+\n/cg) {
|
||||
if ($bol && m/\G(\s*\n)*((\>))+\n/cog) {
|
||||
return $q->p();
|
||||
}
|
||||
# > hi, you mentioned that:
|
||||
# >> I don't like Oddmuse.
|
||||
# > in last letter.
|
||||
elsif ($bol && m/\G(\s*\n)*((\>)+)[ \t]/cg
|
||||
or InElement('dd') && m/\G(\s*\n)+((\>)+)[ \t]/cg) {
|
||||
elsif ($bol && m/\G(\s*\n)*((\>)+)[ \t]/cog
|
||||
or InElement('dd') && m/\G(\s*\n)+((\>)+)[ \t]/cog) {
|
||||
my $leng = length($2) / 4;
|
||||
return CloseHtmlEnvironmentUntil('dd') . OpenHtmlEnvironment('dl',$leng, 'quote')
|
||||
. $q->dt() . AddHtmlEnvironment('dd');
|
||||
|
||||
@@ -28,7 +28,7 @@ push(@MyRules, \&EnclosureRule);
|
||||
# [[enclosure:url|size in bytes|mime type]]
|
||||
|
||||
sub EnclosureRule {
|
||||
if (m!\G\[\[enclosure:\s*$FreeLinkPattern(\|([^\]]+))?\]\]!cgi) {
|
||||
if (m!\G\[\[enclosure:\s*$FreeLinkPattern(\|([^\]]+))?\]\]!ogci) {
|
||||
my $id = FreeToNormal($1);
|
||||
# Make sure we don't add duplicates; we will add non-existing
|
||||
# enclosures as well. We test for existence only when the RSS feed
|
||||
@@ -56,8 +56,8 @@ sub NewEnclosureRssItem {
|
||||
my $id = shift;
|
||||
my $rss = OldEnclosureRssItem($id, @_);
|
||||
require MIME::Base64;
|
||||
my $data = ParseData(ReadFileOrDie(GetPageFile($id)));
|
||||
my @enclosures = split(' ', $data->{enclosures});
|
||||
my %data = ParseData(ReadFileOrDie(GetPageFile($id)));
|
||||
my @enclosures = split(' ', $data{enclosures});
|
||||
my $enclosures = '';
|
||||
foreach my $enclosure (@enclosures) {
|
||||
# Don't add the enclosure if the page has been deleted in the mean
|
||||
|
||||
@@ -38,10 +38,10 @@ $FaqAnswerText = "Answer: " unless $FaqAnswerText;
|
||||
push(@MyRules, \&FaqRule);
|
||||
|
||||
sub FaqRule {
|
||||
if ($bol && m/\GQ: (.+)/cg) {
|
||||
if ($bol && m/\GQ: (.+)/gc) {
|
||||
return $q->a({name=>'FAQ_' . UrlEncode($1)},'')
|
||||
. $q->div({class=>'question'}, $FaqQuestionText . $1);
|
||||
} elsif ($bol && m/\GA:[ \t]*/cg) {
|
||||
} elsif ($bol && m/\GA:[ \t]*/gc) {
|
||||
return CloseHtmlEnvironments()
|
||||
. AddHtmlEnvironment('div', "class='answer'") . $FaqAnswerText;
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ $FCKeditorHeight = 400; # Pixel
|
||||
push (@MyRules, \&WysiwygRule);
|
||||
|
||||
sub WysiwygRule {
|
||||
if (m/\G(<.*?>)/cg) {
|
||||
if (m/\G(<.*?>)/gc) {
|
||||
return $1 if substr($1,5,6) eq 'script'
|
||||
or substr($1,4,6) eq 'script';
|
||||
return UnquoteHtml($1);
|
||||
|
||||
@@ -27,7 +27,8 @@ sub FixEncoding {
|
||||
ValidIdOrDie($id);
|
||||
RequestLockOrError();
|
||||
OpenPage($id);
|
||||
my $text = decode_utf8($Page{text});
|
||||
my $text = $Page{text};
|
||||
utf8::decode($text);
|
||||
Save($id, $text, T('Fix character encoding'), 1) if $text ne $Page{text};
|
||||
ReleaseLock();
|
||||
ReBrowsePage($id);
|
||||
|
||||
@@ -66,7 +66,7 @@ $RuleOrder{\&FlickrGalleryRule} = -10;
|
||||
|
||||
sub FlickrGalleryRule {
|
||||
# This code is used when Markdown is not available
|
||||
if (/\G^([\n\r]*\<\s*FlickrSet:\s*(\d+)\s*\>\s*)$/cgim) {
|
||||
if (/\G^([\n\r]*\<\s*FlickrSet:\s*(\d+)\s*\>\s*)$/mgci) {
|
||||
my $oldpos = pos;
|
||||
my $oldstr = $_;
|
||||
|
||||
@@ -79,7 +79,7 @@ sub FlickrGalleryRule {
|
||||
return '';
|
||||
}
|
||||
|
||||
if (/\G^([\n\r]*\<\s*FlickrPhoto:\s*(\d+)\s*([a-z0-9]*?)\s*($size)?\s*\>\s*)$/cgim) {
|
||||
if (/\G^([\n\r]*\<\s*FlickrPhoto:\s*(\d+)\s*([a-z0-9]*?)\s*($size)?\s*\>\s*)$/mgci) {
|
||||
my $oldpos = pos;
|
||||
my $oldstr = $_;
|
||||
|
||||
@@ -103,13 +103,13 @@ sub MarkdownFlickrGalleryRule {
|
||||
^<FlickrSet:\s*(\d+)\s*\>
|
||||
}{
|
||||
FlickrGallery($1);
|
||||
}egimx;
|
||||
}xmgei;
|
||||
|
||||
$text =~ s{
|
||||
^<FlickrPhoto:\s*(\d+)\s*([a-z0-9]*?)\s*($size)?\s*\>
|
||||
}{
|
||||
GetFlickrPhoto($1,$2,$3);
|
||||
}egimx;
|
||||
}xmgei;
|
||||
|
||||
return $text
|
||||
}
|
||||
@@ -135,7 +135,7 @@ sub FlickrGallery {
|
||||
|
||||
$result = $FlickrHeaderTemplate;
|
||||
|
||||
$result =~ s/(\$[a-zA-Z\d]+)/"defined $1 ? $1 : ''"/eeg;
|
||||
$result =~ s/(\$[a-zA-Z\d]+)/"defined $1 ? $1 : ''"/gee;
|
||||
|
||||
# Get list of photos and process them
|
||||
$url = $FlickrBaseUrl . "?method=flickr.photosets.getPhotos&api_key=" .
|
||||
@@ -153,7 +153,7 @@ sub FlickrGallery {
|
||||
|
||||
my $footer = $FlickrFooterTemplate;
|
||||
|
||||
$footer =~ s/(\$[a-zA-Z\d]+)/"defined $1 ? $1 : ''"/eeg;
|
||||
$footer =~ s/(\$[a-zA-Z\d]+)/"defined $1 ? $1 : ''"/gee;
|
||||
$result .= $footer;
|
||||
|
||||
return $result;
|
||||
@@ -192,7 +192,7 @@ sub FlickrPhoto {
|
||||
|
||||
|
||||
my $output = $FlickrImageTemplate;
|
||||
$output =~ s/(\$[a-zA-Z\d]+)/"defined $1 ? $1 : ''"/eeg;
|
||||
$output =~ s/(\$[a-zA-Z\d]+)/"defined $1 ? $1 : ''"/gee;
|
||||
|
||||
return $output
|
||||
}
|
||||
|
||||
@@ -242,13 +242,13 @@ sub FootnotesRule {
|
||||
# Footnotes and the set of all footnotes must be marked so as to ensure their
|
||||
# reevaluation, as each of the footnotes might contain Wiki markup requiring
|
||||
# reevaluation (like, say, free links).
|
||||
if (m/\G($FootnotePattern)(?=([ \t]*$FootnotePattern)?)/cgs) {
|
||||
if (m/\G($FootnotePattern)(?=([ \t]*$FootnotePattern)?)/gcos) {
|
||||
Dirty($1); # do not cache the prefixing "\G"
|
||||
my $footnote_text = $2;
|
||||
my $is_adjacent_footnote = defined $3;
|
||||
|
||||
# A number range (e.g., "2-5") of references to other footnotes.
|
||||
if ($footnote_text =~ m/^(\d+)-(\d+)$/) {
|
||||
if ($footnote_text =~ m/^(\d+)-(\d+)$/o) {
|
||||
my ($footnote_number_first, $footnote_number_last) = ($1, $2);
|
||||
# '–', below, is the HTML entity for a Unicode en-dash.
|
||||
print $q->a({-href=> '#footnotes' .$footnote_number_first,
|
||||
@@ -261,7 +261,7 @@ sub FootnotesRule {
|
||||
}, $footnote_number_last.($is_adjacent_footnote ? ', ' : ''));
|
||||
}
|
||||
# A number (e.g., "5") implying reference to another footnote.
|
||||
elsif ($footnote_text =~ m/^(\d+)$/) {
|
||||
elsif ($footnote_text =~ m/^(\d+)$/o) {
|
||||
my $footnote_number = $1;
|
||||
print $q->a({-href=> '#footnotes' .$footnote_number,
|
||||
-title=> 'Footnote #'.$footnote_number,
|
||||
@@ -285,7 +285,7 @@ sub FootnotesRule {
|
||||
return '';
|
||||
}
|
||||
# The "<footnotes>" list of all footnotes at the foot of a page.
|
||||
elsif ($bol && m/\G($FootnotesPattern)/cgis) {
|
||||
elsif ($bol && m/\G($FootnotesPattern)/gcios) {
|
||||
Clean(CloseHtmlEnvironments());
|
||||
Dirty($1); # do not cache the prefixing "\G"
|
||||
|
||||
|
||||
@@ -12,16 +12,16 @@ our ($q, $OpenPageName, @MyRules, $CrossbarPageName);
|
||||
push(@MyRules, \&FormsRule);
|
||||
|
||||
sub FormsRule {
|
||||
if (IsFile(GetLockedPageFile($OpenPageName)) or (InElement('div', '^class="crossbar"$') and
|
||||
IsFile(GetLockedPageFile($CrossbarPageName)))) {
|
||||
if (-f GetLockedPageFile($OpenPageName) or (InElement('div', '^class="crossbar"$') and
|
||||
-f GetLockedPageFile($CrossbarPageName))) {
|
||||
if (/\G(\<form.*?\<\/form\>)/cgs) {
|
||||
my $form = $1;
|
||||
my $oldpos = pos;
|
||||
Clean(CloseHtmlEnvironments());
|
||||
Dirty($form);
|
||||
$form =~ s/\%([a-z]+)\%/GetParam($1)/eg;
|
||||
$form =~ s/\%([a-z]+)\%/GetParam($1)/ge;
|
||||
$form =~ s/\$([a-z]+)\$/$q->span({-class=>'param'}, GetParam($1))
|
||||
.$q->input({-type=>'hidden', -name=>$1, -value=>GetParam($1)})/eg;
|
||||
.$q->input({-type=>'hidden', -name=>$1, -value=>GetParam($1)})/ge;
|
||||
print UnquoteHtml($form);
|
||||
pos = $oldpos;
|
||||
return AddHtmlEnvironment('p');
|
||||
|
||||
@@ -163,7 +163,8 @@ sub GdSecurityImageGenerate {
|
||||
my ($imgData) = $img->out(force => 'png');
|
||||
my $ticketId = Digest::MD5::md5_hex(rand());
|
||||
CreateDir($GdSecurityImageDir);
|
||||
open my $fh, ">:raw", encode_utf8(GdSecurityImageGetImageFile($ticketId))
|
||||
my $file = GdSecurityImageGetImageFile($ticketId);
|
||||
open my $fh, ">:raw", $file
|
||||
or ReportError(Ts('Image storing failed. (%s)', $!), '500 INTERNAL SERVER ERROR');
|
||||
print $fh $imgData;
|
||||
#print $fh $png; ### experimental ###
|
||||
@@ -186,7 +187,9 @@ sub GdSecurityImageIsValidId {
|
||||
}
|
||||
|
||||
sub GdSecurityImageReadImageFile {
|
||||
if (open(my $IN, '<:raw', encode_utf8(shift))) {
|
||||
my $file = shift;
|
||||
utf8::encode($file); # filenames are bytes!
|
||||
if (open(my $IN, '<:raw', $file)) {
|
||||
local $/ = undef; # Read complete files
|
||||
my $data=<$IN>;
|
||||
close $IN;
|
||||
@@ -208,7 +211,7 @@ sub GdSecurityImageDoImage {
|
||||
print $q->header(-type=>'image/png');
|
||||
print $data;
|
||||
|
||||
Unlink(GdSecurityImageGetImageFile($id));
|
||||
unlink(GdSecurityImageGetImageFile($id));
|
||||
}
|
||||
|
||||
sub GdSecurityImageCleanup {
|
||||
@@ -216,10 +219,10 @@ sub GdSecurityImageCleanup {
|
||||
if (!GdSecurityImageIsValidId($id)) {
|
||||
return;
|
||||
}
|
||||
my @files = (Glob("$GdSecurityImageDir/*.png"), Glob("$GdSecurityImageDir/*.ticket"));
|
||||
my @files = (bsd_glob("$GdSecurityImageDir/*.png"), bsd_glob("$GdSecurityImageDir/*.ticket"));
|
||||
foreach my $file (@files) {
|
||||
if ($Now - Modified($file) > $GdSecurityImageDuration) {
|
||||
Unlink($file);
|
||||
if ($Now - (stat $file)[9] > $GdSecurityImageDuration) {
|
||||
unlink($file);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -237,9 +240,9 @@ sub GdSecurityImageCheck {
|
||||
if ($answer ne '' && GdSecurityImageIsValidId($id)) {
|
||||
my ($status, $data) = ReadFile(GdSecurityImageGetTicketFile($id));
|
||||
if ($status) {
|
||||
my $page = ParseData($data);
|
||||
if ($page->{generation_time} + $GdSecurityImageDuration > $Now) {
|
||||
if ($answer eq $page->{string}) {
|
||||
my %page = ParseData($data);
|
||||
if ($page{generation_time} + $GdSecurityImageDuration > $Now) {
|
||||
if ($answer eq $page{string}) {
|
||||
$GdSecurityImageId = '';
|
||||
if (!$GdSecurityImageRememberAnswer) {
|
||||
SetParam('gd_security_image_id', '');
|
||||
@@ -252,7 +255,7 @@ sub GdSecurityImageCheck {
|
||||
}
|
||||
|
||||
if (GdSecurityImageIsValidId($id)) {
|
||||
Unlink(GdSecurityImageGetTicketFile($id));
|
||||
unlink(GdSecurityImageGetTicketFile($id));
|
||||
}
|
||||
|
||||
$GdSecurityImageId = GdSecurityImageGenerate();
|
||||
|
||||
@@ -30,12 +30,12 @@ $GitMail = 'unknown@oddmuse.org';
|
||||
sub GitCommit {
|
||||
my ($message, $author) = @_;
|
||||
my $oldDir = cwd;
|
||||
ChangeDir("$DataDir/page");
|
||||
chdir("$DataDir/page");
|
||||
capture {
|
||||
system($GitBinary, qw(add -A));
|
||||
system($GitBinary, qw(commit -q -m), $message, "--author=$author <$GitMail>");
|
||||
};
|
||||
ChangeDir($oldDir);
|
||||
chdir($oldDir);
|
||||
}
|
||||
|
||||
sub GitInitRepository {
|
||||
|
||||
@@ -80,7 +80,7 @@ sub GitRun {
|
||||
my $exitStatus;
|
||||
# warn join(' ', $GitBinary, @_) . "\n";
|
||||
|
||||
ChangeDir($GitRepo);
|
||||
chdir($GitRepo);
|
||||
if ($GitDebug) {
|
||||
# TODO use ToString here
|
||||
# capture the output of the git comand in a temporary file
|
||||
@@ -99,7 +99,7 @@ sub GitRun {
|
||||
} else {
|
||||
$exitStatus = system($GitBinary, @_);
|
||||
}
|
||||
ChangeDir($oldDir);
|
||||
chdir($oldDir);
|
||||
return $exitStatus;
|
||||
}
|
||||
|
||||
@@ -108,7 +108,7 @@ sub GitInitVariables {
|
||||
}
|
||||
|
||||
sub GitInitRepository {
|
||||
return if IsDir("$GitRepo/.git");
|
||||
return if -d "$GitRepo/.git";
|
||||
my $exception = shift;
|
||||
CreateDir($GitRepo);
|
||||
GitRun(qw(init --quiet));
|
||||
@@ -187,16 +187,17 @@ sub DoGitCleanup {
|
||||
}
|
||||
|
||||
sub GitCleanup {
|
||||
if (IsDir($GitRepo)) {
|
||||
if (-d $GitRepo) {
|
||||
print $q->p('Git cleanup starting');
|
||||
AllPagesList();
|
||||
# delete all the files including all the files starting with a dot
|
||||
opendir(DIR, encode_utf8($GitRepo)) or ReportError("cannot open directory $GitRepo: $!");
|
||||
opendir(DIR, $GitRepo) or ReportError("cannot open directory $GitRepo: $!");
|
||||
foreach my $file (readdir(DIR)) {
|
||||
my $name = decode_utf8($file);
|
||||
my $name = $file;
|
||||
utf8::decode($name); # filenames are bytes
|
||||
next if $file eq '.git' or $file eq '.' or $file eq '..' or $IndexHash{$name};
|
||||
print $q->p("Deleting left over file $name");
|
||||
Unlink("$GitRepo/$file") or ReportError("cannot delete $GitRepo/$name: $!");
|
||||
unlink "$GitRepo/$file" or ReportError("cannot delete $GitRepo/$name: $!");
|
||||
}
|
||||
closedir DIR;
|
||||
# write all the files again, just to be sure
|
||||
|
||||
@@ -56,7 +56,7 @@ sub GooglePlusPrintFooter {
|
||||
return q{
|
||||
<!-- start of Google+ -->
|
||||
<script type="text/javascript">
|
||||
function loadScript(jssource) {
|
||||
function loadScript(jssource,link_id) {
|
||||
// add javascript
|
||||
var jsnode = document.createElement('script');
|
||||
jsnode.setAttribute('type','text/javascript');
|
||||
@@ -66,24 +66,15 @@ function loadScript(jssource) {
|
||||
var butn = document.createElement('div');
|
||||
butn.setAttribute('class', 'g-plusone');
|
||||
butn.setAttribute('id', 'my_plusone');
|
||||
var link = document.getElementById('plus1');
|
||||
var link = document.getElementById(link_id);
|
||||
link.parentNode.insertBefore(butn, link);
|
||||
// hide the link
|
||||
link.innerHTML = "";
|
||||
// when looking at action=plusone
|
||||
var ul = document.getElementById('plus1s');
|
||||
var children = ul.children;
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
var li = children[i];
|
||||
butn = document.createElement('g:plusone');
|
||||
butn.setAttribute('href', li.firstElementChild.getAttribute('href'));
|
||||
butn.setAttribute('id', 'my_plusone' + i);
|
||||
li.appendChild(butn);
|
||||
}
|
||||
}
|
||||
var plus1source = "https://apis.google.com/js/plusone.js";
|
||||
</script>
|
||||
<p id="plus1">
|
||||
<a href="javascript:loadScript('https://apis.google.com/js/plusone.js')">
|
||||
<a href="javascript:loadScript(plus1source,'plus1')">
|
||||
<img src="/pics/plusone-h24.png" alt="Show Google +1" />
|
||||
</a>
|
||||
</p>
|
||||
@@ -112,9 +103,11 @@ sub DoPlusOne {
|
||||
push(@pages, $id) if $id =~ /^\d\d\d\d-\d\d-\d\d/;
|
||||
}
|
||||
splice(@pages, 0, $#pages - 19); # last 20 items
|
||||
print '<ul id="plus1s">';
|
||||
print "<ul>";
|
||||
foreach my $id (@pages) {
|
||||
print $q->li(GetPageLink($id), ' ');
|
||||
my $url = ScriptUrl(UrlEncode($id));
|
||||
print $q->li(GetPageLink($id),
|
||||
qq{ <g:plusone href="$url"></g:plusone>});
|
||||
}
|
||||
print "</ul>";
|
||||
print $q->end_div();
|
||||
|
||||
@@ -39,7 +39,7 @@ sub GotobarInit {
|
||||
@UserGotoBarPages = ();
|
||||
$UserGotoBar = '';
|
||||
my $count = 0;
|
||||
while ($Page{text} =~ m/($LinkPattern|\[\[$FreeLinkPattern\]\]|\[\[$FreeLinkPattern\|([^\]]+)\]\]|\[$InterLinkPattern\s+([^\]]+?)\]|\[$FullUrlPattern[|[:space:]]([^\]]+?)\])/g) {
|
||||
while ($Page{text} =~ m/($LinkPattern|\[\[$FreeLinkPattern\]\]|\[\[$FreeLinkPattern\|([^\]]+)\]\]|\[$InterLinkPattern\s+([^\]]+?)\]|\[$FullUrlPattern[|[:space:]]([^\]]+?)\])/og) {
|
||||
my $page = $2||$3||$4||$6||$8;
|
||||
my $text = $5||$7||$9;
|
||||
$UserGotoBar .= ' ' if $UserGotoBar;
|
||||
|
||||
@@ -29,7 +29,7 @@ my $gravatar_regexp = "\\[\\[gravatar:(?:$FullUrlPattern )?([^\n:]+):([0-9a-f]+)
|
||||
push(@MyRules, \&GravatarRule);
|
||||
|
||||
sub GravatarRule {
|
||||
if ($bol && m!\G$gravatar_regexp!cg) {
|
||||
if ($bol && m!\G$gravatar_regexp!cog) {
|
||||
my $url = $1;
|
||||
my $gravatar = "https://secure.gravatar.com/avatar/$3";
|
||||
my $name = FreeToNormal($2);
|
||||
@@ -53,7 +53,7 @@ sub GravatarFormAddition {
|
||||
return $html unless $type eq 'comment';
|
||||
|
||||
my $addition = $q->span({-class=>'mail'},
|
||||
$q->label({-for=>'mail'}, T('Email:') . ' ')
|
||||
$q->label({-for=>'mail'}, T('Email: '))
|
||||
. ' ' . $q->textfield(-name=>'mail', -id=>'mail',
|
||||
-default=>GetParam('mail', '')));
|
||||
$html =~ s!(name="homepage".*?)</p>!$1 $addition</p>!i;
|
||||
@@ -90,6 +90,6 @@ sub AddGravatar {
|
||||
|
||||
sub GravatarNewGetSummary {
|
||||
my $summary = GravatarOldGetSummary(@_);
|
||||
$summary =~ s/^$gravatar_regexp *//;
|
||||
$summary =~ s/^$gravatar_regexp *//o;
|
||||
return $summary;
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ sub PrintGrep {
|
||||
foreach my $id (AllPagesList()) {
|
||||
my $text = GetPageContent($id);
|
||||
next if (TextIsFile($text)); # skip files
|
||||
while ($text =~ m{($regexp)}gi) {
|
||||
while ($text =~ m{($regexp)}ig) {
|
||||
print $q->li(GetPageLink($id) . ': ' . $1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ $RuleOrder{\&HeadersRule} = 95;
|
||||
|
||||
sub HeadersRule {
|
||||
my $oldpos = pos;
|
||||
if ($bol && (m/\G((.+?)[ \t]*\n(---+|===+)[ \t]*\n)/cg)) {
|
||||
if ($bol && (m/\G((.+?)[ \t]*\n(---+|===+)[ \t]*\n)/gc)) {
|
||||
my $html = CloseHtmlEnvironments() . ($PortraitSupportColorDiv ? '</div>' : '');
|
||||
if (substr($3,0,1) eq '=') {
|
||||
$html .= $q->h2($2);
|
||||
|
||||
@@ -32,7 +32,7 @@ push(@MyRules, \&HeadlinesRule);
|
||||
$HeadlineNumber = 20;
|
||||
|
||||
sub HeadlinesRule {
|
||||
if (m/\G(\<headlines(:(\d+))?\>)/cgi) {
|
||||
if (m/\G(\<headlines(:(\d+))?\>)/gci) {
|
||||
if (($3) and ($3>0)) {$HeadlineNumber = $3;};
|
||||
Clean(CloseHtmlEnvironments());
|
||||
Dirty($1);
|
||||
|
||||
@@ -1212,7 +1212,7 @@ sub GetHibernalArchiveMonth {
|
||||
~e;
|
||||
$html_month =~ s~( {1,2})(\d{1,2})\b~
|
||||
$1.GetHibernalArchiveMonthDay($post_name_regexp, $year, $month, $2)
|
||||
~eg;
|
||||
~ge;
|
||||
|
||||
# Float the HTML for each month horizontally past the month preceding it;
|
||||
# failure to float months in this manner causes these months to stack
|
||||
|
||||
@@ -31,7 +31,7 @@ push(@MyRules, \&HtmlLinksRule);
|
||||
$RuleOrder{\&HtmlLinksRule} = 105;
|
||||
|
||||
sub HtmlLinksRule {
|
||||
if (IsFile(GetLockedPageFile($OpenPageName))) {
|
||||
if (-f GetLockedPageFile($OpenPageName)) {
|
||||
$HtmlLinks = 1;
|
||||
} else {
|
||||
$HtmlLinks = 0;
|
||||
|
||||
@@ -32,7 +32,7 @@ push(@MyRules, \&ImageSupportRule);
|
||||
|
||||
sub ImageSupportRule {
|
||||
my $result = undef;
|
||||
if (m!\G\[\[image((/[a-z]+)*)( external)?:\s*([^]|]+?)\s*(\|[^]|]+?)?\s*(\|[^]|]*?)?\s*(\|[^]|]*?)?\s*(\|[^]|]*?)?\s*\]\](\{([^}]+)\})?!cg) {
|
||||
if (m!\G\[\[image((/[a-z]+)*)( external)?:\s*([^]|]+?)\s*(\|[^]|]+?)?\s*(\|[^]|]*?)?\s*(\|[^]|]*?)?\s*(\|[^]|]*?)?\s*\]\](\{([^}]+)\})?!gc) {
|
||||
my $oldpos = pos;
|
||||
my $class = 'image' . $1;
|
||||
my $external = $3;
|
||||
|
||||
@@ -32,7 +32,7 @@ sub DivFooRule {
|
||||
my $str = $1;
|
||||
CreateDir($ImagifyDir);
|
||||
my $fileName = sha256_hex($str) . '.' . $ImagifyFormat;
|
||||
system('convert', %ImagifyParams, "caption:$str", "$ImagifyDir/$fileName") unless IsFile("$ImagifyDir/$fileName");
|
||||
system('convert', %ImagifyParams, "caption:$str", "$ImagifyDir/$fileName") unless -e "$ImagifyDir/$fileName";
|
||||
my $src = $ScriptName . "/imagify/" . UrlEncode($fileName);
|
||||
return CloseHtmlEnvironments() . $q->img({-class => 'imagify', -src => $src, -alt => '(rendered text)'}) . AddHtmlEnvironment('p');
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ $IrcLinkNick = 0;
|
||||
# This adds an extra <br> at the beginning. Alternatively, add it to
|
||||
# the last line, or only add it when required.
|
||||
sub IrcRule {
|
||||
if ($bol && m/\G(?:\[?(\d\d?:\d\d(?:am|pm)?)\]?)?\s*<($IrcNickRegexp)> ?/cg) {
|
||||
if ($bol && m/\G(?:\[?(\d\d?:\d\d(?:am|pm)?)\]?)?\s*<($IrcNickRegexp)> ?/gc) {
|
||||
my ($time, $nick) = ($1, $2);
|
||||
my ($error) = ValidId($nick);
|
||||
# if we're in a dl, close the open dd but not the dl. (if we're
|
||||
|
||||
@@ -149,7 +149,7 @@ sub JoinerGetPasswordHash {
|
||||
sub JoinerRequestLockOrError {
|
||||
my ($name) = @_;
|
||||
# 10 tries, 3 second wait, die on error
|
||||
return RequestLockDir($name, 10, 3, 1);
|
||||
return RequestLockDir($name, 0, 10, 3, 1);
|
||||
}
|
||||
|
||||
sub JoinerGetEmailFile {
|
||||
@@ -174,17 +174,18 @@ sub JoinerCreateAccount {
|
||||
}
|
||||
|
||||
my ($email_status, $email_data) = ReadFile(JoinerGetEmailFile($email));
|
||||
my %email_page = ();
|
||||
if ($email_status) {
|
||||
my $email_page = ParseData($email_data);
|
||||
if ($email_page->{confirmed}) {
|
||||
%email_page = ParseData($email_data);
|
||||
if ($email_page{confirmed}) {
|
||||
return Ts('The email address %s has already been used.', $email);
|
||||
}
|
||||
if ($email_page->{registration_time} + $JoinerWait > $Now) {
|
||||
my $min = 1 + int(($email_page->{registration_time} + $JoinerWait - $Now) / 60);
|
||||
if ($email_page{registration_time} + $JoinerWait > $Now) {
|
||||
my $min = 1 + int(($email_page{registration_time} + $JoinerWait - $Now) / 60);
|
||||
return Ts('Wait %s minutes before try again.', $min);
|
||||
}
|
||||
}
|
||||
my %email_page = ();
|
||||
%email_page = ();
|
||||
$email_page{username} = $username;
|
||||
$email_page{email} = $email;
|
||||
$email_page{confirmed} = 0;
|
||||
@@ -214,7 +215,7 @@ sub JoinerSendRegistrationConfirmationEmail {
|
||||
print $EMAIL "From: $JoinerEmailSenderAddress\n";
|
||||
print $EMAIL "Subject: $SiteName " . T('Registration Confirmation') . "\n";
|
||||
print $EMAIL "\n";
|
||||
print $EMAIL T('Visit the link below to confirm registration.') . "\n";
|
||||
print $EMAIL T('Visit the link blow to confirm registration.') . "\n";
|
||||
print $EMAIL "\n";
|
||||
print $EMAIL "$link\n";
|
||||
print $EMAIL "\n";
|
||||
@@ -467,37 +468,37 @@ sub JoinerDoConfirmRegistration {
|
||||
JoinerShowRegistrationConfirmationFailed();
|
||||
return;
|
||||
}
|
||||
my $page = ParseData($data);
|
||||
my %page = ParseData($data);
|
||||
|
||||
if ($key ne $page->{key}) {
|
||||
if ($key ne $page{key}) {
|
||||
$JoinerMessage = T('Invalid key.');
|
||||
JoinerShowRegistrationConfirmationFailed();
|
||||
return;
|
||||
}
|
||||
|
||||
if ($page->{registration_time} + $JoinerWait < $Now) {
|
||||
if ($page{registration_time} + $JoinerWait < $Now) {
|
||||
$JoinerMessage = T('The key expired.');
|
||||
JoinerShowRegistrationConfirmationFailed();
|
||||
return;
|
||||
}
|
||||
|
||||
$page->{key} = '';
|
||||
$page->{confirmed} = 1;
|
||||
$page{key} = '';
|
||||
$page{confirmed} = 1;
|
||||
JoinerRequestLockOrError('joiner');
|
||||
CreateDir($JoinerDir);
|
||||
WriteStringToFile(JoinerGetAccountFile($username), EncodePage(%$page));
|
||||
WriteStringToFile(JoinerGetAccountFile($username), EncodePage(%page));
|
||||
ReleaseLockDir('joiner');
|
||||
|
||||
my $email = $page->{email};
|
||||
my $email = $page{email};
|
||||
JoinerRequestLockOrError('joiner');
|
||||
my ($email_status, $email_data) = ReadFile(JoinerGetEmailFile($email));
|
||||
ReleaseLockDir('joiner');
|
||||
if ($email_status) {
|
||||
my $email_page = ParseData($email_data);
|
||||
$email_page->{confirmed} = 1;
|
||||
my %email_page = ParseData($email_data);
|
||||
$email_page{confirmed} = 1;
|
||||
JoinerRequestLockOrError('joiner');
|
||||
CreateDir($JoinerEmailDir);
|
||||
WriteStringToFile(JoinerGetEmailFile($email), EncodePage(%$email_page));
|
||||
WriteStringToFile(JoinerGetEmailFile($email), EncodePage(%email_page));
|
||||
ReleaseLockDir('joiner');
|
||||
}
|
||||
|
||||
@@ -569,41 +570,41 @@ sub JoinerDoProcessLogin {
|
||||
JoinerDoLogin();
|
||||
return;
|
||||
}
|
||||
my $page = ParseData($data);
|
||||
my %page = ParseData($data);
|
||||
my $hash = JoinerGetPasswordHash($password);
|
||||
if ($hash eq $page->{password}) {
|
||||
$page->{recover} = 0;
|
||||
if ($hash eq $page{password}) {
|
||||
$page{recover} = 0;
|
||||
SetParam('joiner_recover', 0);
|
||||
} elsif ($key ne '' && $key eq $page->{recover_key}) {
|
||||
if ($page->{recover_time} + $JoinerWait < $Now) {
|
||||
} elsif ($key ne '' && $key eq $page{recover_key}) {
|
||||
if ($page{recover_time} + $JoinerWait < $Now) {
|
||||
$JoinerMessage = T('The key expired.');
|
||||
JoinerDoLogin();
|
||||
return;
|
||||
}
|
||||
$page->{recover} = 1;
|
||||
$page{recover} = 1;
|
||||
SetParam('joiner_recover', 1);
|
||||
} else {
|
||||
$JoinerMessage = T('Login failed.');
|
||||
JoinerDoLogin();
|
||||
return;
|
||||
}
|
||||
if ($page->{banned}) {
|
||||
if ($page{banned}) {
|
||||
$JoinerMessage = T('You are banned.');
|
||||
JoinerDoLogin();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!$page->{confirmed}) {
|
||||
if (!$page{confirmed}) {
|
||||
$JoinerMessage = T('You must confirm email address.');
|
||||
JoinerDoLogin();
|
||||
return;
|
||||
}
|
||||
|
||||
my $session = Digest::MD5::md5_hex(rand());
|
||||
$page->{session} = $session;
|
||||
$page{session} = $session;
|
||||
JoinerRequestLockOrError('joiner');
|
||||
CreateDir($JoinerDir);
|
||||
WriteStringToFile(JoinerGetAccountFile($username), EncodePage(%$page));
|
||||
WriteStringToFile(JoinerGetAccountFile($username), EncodePage(%page));
|
||||
ReleaseLockDir('joiner');
|
||||
|
||||
SetParam('username', $username);
|
||||
@@ -616,7 +617,7 @@ sub JoinerDoProcessLogin {
|
||||
print Ts('%s has logged in.', $username);
|
||||
print $q->end_p();
|
||||
|
||||
if ($page->{recover}) {
|
||||
if ($page{recover}) {
|
||||
print $q->start_p();
|
||||
print T('You should set new password immediately.');
|
||||
print $q->end_p();
|
||||
@@ -734,9 +735,9 @@ sub JoinerDoProcessChangePassword {
|
||||
JoinerDoChangePassword();
|
||||
return;
|
||||
}
|
||||
my $page = ParseData($data);
|
||||
my %page = ParseData($data);
|
||||
my $hash = JoinerGetPasswordHash($current_password);
|
||||
if (!$page->{recover} && $hash ne $page->{password}) {
|
||||
if (!$page{recover} && $hash ne $page{password}) {
|
||||
$JoinerMessage = T('Current Password:') . ' ' . T('Password is wrong.');
|
||||
JoinerDoChangePassword();
|
||||
return;
|
||||
@@ -753,12 +754,12 @@ sub JoinerDoProcessChangePassword {
|
||||
return;
|
||||
}
|
||||
|
||||
$page->{password} = JoinerGetPasswordHash($new_password);
|
||||
$page->{key} = '';
|
||||
$page->{recover} = '';
|
||||
$page{password} = JoinerGetPasswordHash($new_password);
|
||||
$page{key} = '';
|
||||
$page{recover} = '';
|
||||
JoinerRequestLockOrError('joiner');
|
||||
CreateDir($JoinerDir);
|
||||
WriteStringToFile(JoinerGetAccountFile($username), EncodePage(%$page));
|
||||
WriteStringToFile(JoinerGetAccountFile($username), EncodePage(%page));
|
||||
ReleaseLockDir('joiner');
|
||||
|
||||
SetParam('joiner_recover', 0);
|
||||
@@ -822,9 +823,9 @@ sub JoinerDoProcessForgotPassword {
|
||||
JoinerDoForgotPassword();
|
||||
return;
|
||||
}
|
||||
my $email_page = ParseData($email_data);
|
||||
my %email_page = ParseData($email_data);
|
||||
|
||||
my $username = $email_page->{username};
|
||||
my $username = $email_page{username};
|
||||
JoinerRequestLockOrError('joiner');
|
||||
my ($status, $data) = ReadFile(JoinerGetAccountFile($username));
|
||||
ReleaseLockDir('joiner');
|
||||
@@ -833,27 +834,27 @@ sub JoinerDoProcessForgotPassword {
|
||||
JoinerDoForgotPassword();
|
||||
return;
|
||||
}
|
||||
my $page = ParseData($data);
|
||||
my %page = ParseData($data);
|
||||
|
||||
if ($email ne $page->{email}) {
|
||||
if ($email ne $page{email}) {
|
||||
$JoinerMessage = T('The mail address is not valid anymore.');
|
||||
JoinerDoForgotPassword();
|
||||
return;
|
||||
}
|
||||
|
||||
if ($page->{recover_time} + $JoinerWait > $Now) {
|
||||
my $min = 1 + int(($page->{recover_time} + $JoinerWait - $Now) / 60);
|
||||
if ($page{recover_time} + $JoinerWait > $Now) {
|
||||
my $min = 1 + int(($page{recover_time} + $JoinerWait - $Now) / 60);
|
||||
$JoinerMessage = Ts('Wait %s minutes before try again.', $min);
|
||||
JoinerDoForgotPassword();
|
||||
return;
|
||||
}
|
||||
|
||||
my $key = Digest::MD5::md5_hex($JoinerGeneratorSalt . rand());
|
||||
$page->{recover_time} = $Now;
|
||||
$page->{recover_key} = $key;
|
||||
$page{recover_time} = $Now;
|
||||
$page{recover_key} = $key;
|
||||
JoinerRequestLockOrError('joiner');
|
||||
CreateDir($JoinerDir);
|
||||
WriteStringToFile(JoinerGetAccountFile($username), EncodePage(%$page));
|
||||
WriteStringToFile(JoinerGetAccountFile($username), EncodePage(%page));
|
||||
ReleaseLockDir('joiner');
|
||||
|
||||
JoinerSendRecoverAccountEmail($email, $username, $key);
|
||||
@@ -921,8 +922,8 @@ sub JoinerDoProcessChangeEmail {
|
||||
my ($email_status, $email_data) = ReadFile(JoinerGetEmailFile($email));
|
||||
ReleaseLockDir('joiner');
|
||||
if ($email_status) {
|
||||
my $email_page = ParseData($email_data);
|
||||
if ($email_page->{confirmed} && $email_page->{username} ne $username) {
|
||||
my %email_page = ParseData($email_data);
|
||||
if ($email_page{confirmed} && $email_page{username} ne $username) {
|
||||
$JoinerMessage = T('Email:') . ' ' .
|
||||
Ts('The email address %s has already been used.', $email);
|
||||
JoinerDoChangeEmail();
|
||||
@@ -938,29 +939,29 @@ sub JoinerDoProcessChangeEmail {
|
||||
JoinerDoChangeEmail();
|
||||
return;
|
||||
}
|
||||
my $page = ParseData($data);
|
||||
my %page = ParseData($data);
|
||||
|
||||
if ($page->{change_email_time} + $JoinerWait > $Now) {
|
||||
my $min = 1 + int(($page->{change_email_time} + $JoinerWait - $Now) / 60);
|
||||
if ($page{change_email_time} + $JoinerWait > $Now) {
|
||||
my $min = 1 + int(($page{change_email_time} + $JoinerWait - $Now) / 60);
|
||||
$JoinerMessage = Ts('Wait %s minutes before try again.', $min);
|
||||
JoinerDoChangeEmail();
|
||||
return;
|
||||
}
|
||||
|
||||
my $hash = JoinerGetPasswordHash($password);
|
||||
if ($hash ne $page->{password}) {
|
||||
if ($hash ne $page{password}) {
|
||||
$JoinerMessage = T('Password:') . ' ' . T('Password is wrong.');
|
||||
JoinerDoChangeEmail();
|
||||
return;
|
||||
}
|
||||
|
||||
my $key = Digest::MD5::md5_hex(rand());
|
||||
$page->{change_email} = $email;
|
||||
$page->{change_email_key} = $key;
|
||||
$page->{change_email_time} = $Now;
|
||||
$page{change_email} = $email;
|
||||
$page{change_email_key} = $key;
|
||||
$page{change_email_time} = $Now;
|
||||
JoinerRequestLockOrError('joiner');
|
||||
CreateDir($JoinerDir);
|
||||
WriteStringToFile(JoinerGetAccountFile($username), EncodePage(%$page));
|
||||
WriteStringToFile(JoinerGetAccountFile($username), EncodePage(%page));
|
||||
ReleaseLockDir('joiner');
|
||||
|
||||
JoinerSendChangeEmailEmail($email, $username, $key);
|
||||
@@ -1011,22 +1012,22 @@ sub JoinerDoConfirmEmail {
|
||||
JoinerShowConfirmEmailFailed();
|
||||
return;
|
||||
}
|
||||
my $page = ParseData($data);
|
||||
my %page = ParseData($data);
|
||||
|
||||
if ($key ne $page->{change_email_key}) {
|
||||
if ($key ne $page{change_email_key}) {
|
||||
$JoinerMessage = T('Invalid key.');
|
||||
JoinerShowConfirmEmailFailed();
|
||||
return;
|
||||
}
|
||||
|
||||
my $new_email = $page->{change_email};
|
||||
$page->{email} = $new_email;
|
||||
$page->{change_email} = '';
|
||||
$page->{change_email_key} = '';
|
||||
$page->{change_email_time} = '';
|
||||
my $new_email = $page{change_email};
|
||||
$page{email} = $new_email;
|
||||
$page{change_email} = '';
|
||||
$page{change_email_key} = '';
|
||||
$page{change_email_time} = '';
|
||||
JoinerRequestLockOrError('joiner');
|
||||
CreateDir($JoinerDir);
|
||||
WriteStringToFile(JoinerGetAccountFile($username), EncodePage(%$page));
|
||||
WriteStringToFile(JoinerGetAccountFile($username), EncodePage(%page));
|
||||
ReleaseLockDir('joiner');
|
||||
|
||||
my %email_page = ();
|
||||
@@ -1127,30 +1128,30 @@ sub JoinerDoProcessBan {
|
||||
JoinerDoBan();
|
||||
return;
|
||||
}
|
||||
my $page = ParseData($data);
|
||||
my %page = ParseData($data);
|
||||
|
||||
if ($ban) {
|
||||
if ($page->{banned}) {
|
||||
if ($page{banned}) {
|
||||
$JoinerMessage = Ts('%s is already banned.', $username);
|
||||
JoinerDoBan();
|
||||
return;
|
||||
}
|
||||
$page->{banned} = 1;
|
||||
$page->{session} = '';
|
||||
$page{banned} = 1;
|
||||
$page{session} = '';
|
||||
$JoinerMessage = Ts('%s has been banned.', $username);
|
||||
} else {
|
||||
if (!$page->{banned}) {
|
||||
if (!$page{banned}) {
|
||||
$JoinerMessage = Ts('%s is not banned.', $username);
|
||||
JoinerDoBan();
|
||||
return;
|
||||
}
|
||||
$page->{banned} = 0;
|
||||
$page{banned} = 0;
|
||||
$JoinerMessage = Ts('%s has been unbanned.', $username);
|
||||
}
|
||||
|
||||
JoinerRequestLockOrError('joiner');
|
||||
CreateDir($JoinerDir);
|
||||
WriteStringToFile(JoinerGetAccountFile($username), EncodePage(%$page));
|
||||
WriteStringToFile(JoinerGetAccountFile($username), EncodePage(%page));
|
||||
ReleaseLockDir('joiner');
|
||||
|
||||
JoinerDoBan();
|
||||
@@ -1177,16 +1178,16 @@ sub JoinerIsLoggedIn {
|
||||
$JoinerLoggedIn = 0;
|
||||
return $JoinerLoggedIn;
|
||||
}
|
||||
my $page = ParseData($data);
|
||||
if (!$page->{confirmed}) {
|
||||
my %page = ParseData($data);
|
||||
if (!$page{confirmed}) {
|
||||
$JoinerLoggedIn = 0;
|
||||
return $JoinerLoggedIn;
|
||||
}
|
||||
if ($session ne $page->{session}) {
|
||||
if ($session ne $page{session}) {
|
||||
$JoinerLoggedIn = 0;
|
||||
return $JoinerLoggedIn;
|
||||
}
|
||||
if ($page->{banned}) {
|
||||
if ($page{banned}) {
|
||||
$JoinerLoggedIn = 0;
|
||||
return $JoinerLoggedIn;
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ our ($q, @HtmlStack, @MyRules, $FullUrl);
|
||||
push(@MyRules, \&LangRule);
|
||||
|
||||
sub LangRule {
|
||||
if (m/\G\[([a-z][a-z])\]/cg) {
|
||||
if (m/\G\[([a-z][a-z])\]/gc) {
|
||||
my $html;
|
||||
$html .= "</" . shift(@HtmlStack) . ">" if $HtmlStack[0] eq 'span';
|
||||
return $html . AddHtmlEnvironment('span', "lang=\"$1\"") . "[$1]";
|
||||
|
||||
@@ -98,7 +98,7 @@ EOT
|
||||
push(@MyRules, \&LatexRule);
|
||||
|
||||
sub LatexRule {
|
||||
if (m/\G\\\[(\(.*?\))?((.*\n)*?.*?)\\\]/cg) {
|
||||
if (m/\G\\\[(\(.*?\))?((.*\n)*?.*?)\\\]/gc) {
|
||||
my $label = $1;
|
||||
my $latex = $2;
|
||||
$label =~ s#\(?\)?##g;# Remove the ()'s from the label and convert case
|
||||
@@ -106,13 +106,13 @@ sub LatexRule {
|
||||
$eqCounter++;
|
||||
$eqHash{$label} = $eqCounter;
|
||||
return &MakeLaTeX("\\begin{displaymath} $latex \\end{displaymath}", "display math",$label);
|
||||
} elsif (m/\G\$\$((.*\n)*?.*?)\$\$/cg) {
|
||||
} elsif (m/\G\$\$((.*\n)*?.*?)\$\$/gc) {
|
||||
return &MakeLaTeX("\$\$ $1 \$\$", $LatexSingleDollars ? "display math" : "inline math");
|
||||
} elsif ($LatexSingleDollars and m/\G\$((.*\n)*?.*?)\$/cg) {
|
||||
} elsif ($LatexSingleDollars and m/\G\$((.*\n)*?.*?)\$/gc) {
|
||||
return &MakeLaTeX("\$ $1 \$", "inline math");
|
||||
} elsif ($allowPlainLaTeX && m/\G\$\[((.*\n)*?.*?)\]\$/cg) { #Pick up plain LaTeX commands
|
||||
} elsif ($allowPlainLaTeX && m/\G\$\[((.*\n)*?.*?)\]\$/gc) { #Pick up plain LaTeX commands
|
||||
return &MakeLaTeX(" $1 ", "LaTeX");
|
||||
} elsif (m/\GEQ\((.*?)\)/cg) { # Handle references to equations
|
||||
} elsif (m/\GEQ\((.*?)\)/gc) { # Handle references to equations
|
||||
my $label = $1;
|
||||
$label =~ tr/A-Z/a-z/;
|
||||
if ($eqHash{$label}) {
|
||||
@@ -131,8 +131,8 @@ sub MakeLaTeX {
|
||||
|
||||
# Select which binary to use for conversion of dvi to images
|
||||
my $useConvert = 0;
|
||||
if (not IsFile($dvipngPath)) {
|
||||
if (not IsFile($convertPath)) {
|
||||
if (not -e $dvipngPath) {
|
||||
if (not -e $convertPath) {
|
||||
return "[Error: dvipng binary and convert binary not found at $dvipngPath or $convertPath ]";
|
||||
}
|
||||
else {
|
||||
@@ -155,26 +155,26 @@ sub MakeLaTeX {
|
||||
}
|
||||
|
||||
# check cache
|
||||
if (not IsFile("$LatexDir/$hash.png") or ZeroSize("$LatexDir/$hash.png")) {
|
||||
if (not -f "$LatexDir/$hash.png" or -z "$LatexDir/$hash.png") { #If file doesn't exist or is zero bytes
|
||||
# Then create the image
|
||||
|
||||
# read template and replace <math>
|
||||
CreateDir($LatexDir);
|
||||
if (not IsFile($LatexDefaultTemplateName)) {
|
||||
open (my $F, '>', encode_utf8($LatexDefaultTemplateName)) or return '[Unable to write template]';
|
||||
mkdir($LatexDir) unless -d $LatexDir;
|
||||
if (not -f $LatexDefaultTemplateName) {
|
||||
open (my $F, '>', $LatexDefaultTemplateName) or return '[Unable to write template]';
|
||||
print $F $LatexDefaultTemplate;
|
||||
close $F;
|
||||
}
|
||||
my $template = ReadFileOrDie($LatexDefaultTemplateName);
|
||||
$template =~ s/<math>/$latex/gi;
|
||||
$template =~ s/<math>/$latex/ig;
|
||||
#setup rendering directory
|
||||
my $dir = "$LatexDir/$hash";
|
||||
if (IsDir($dir)) {
|
||||
Unlink((Glob("$dir/*")));
|
||||
if (-d $dir) {
|
||||
unlink (bsd_glob('$dir/*'));
|
||||
} else {
|
||||
CreateDir($dir);
|
||||
mkdir($dir) or return "[Unable to create $dir]";
|
||||
}
|
||||
ChangeDir($dir) or return "[Unable to switch to $dir]";
|
||||
chdir ($dir) or return "[Unable to switch to $dir]";
|
||||
WriteStringToFile ("srender.tex", $template);
|
||||
my $errorText = qx(latex srender.tex);
|
||||
|
||||
@@ -197,16 +197,16 @@ sub MakeLaTeX {
|
||||
$error = "[dvipng error $? ($output)]" if $?;
|
||||
}
|
||||
|
||||
if (not $error and IsFile('srender1.png') and not ZeroSize('srender1.png')) {
|
||||
if (not $error and -f 'srender1.png' and not -z 'srender1.png') {
|
||||
my $png = ReadFileOrDie("srender1.png");
|
||||
WriteStringToFile ("$LatexDir/$hash.png", $png);
|
||||
} else {
|
||||
$error = "[Error retrieving image for $latex]";
|
||||
}
|
||||
}
|
||||
Unlink(glob('*'));
|
||||
ChangeDir($LatexDir);
|
||||
RemoveDir($dir);
|
||||
unlink (glob('*'));
|
||||
chdir ($LatexDir);
|
||||
rmdir ($dir);
|
||||
|
||||
return $error if $error;
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ push(@MyRules, \&LinkAllRule);
|
||||
$RuleOrder{\&LinkAllRule} = 1000;
|
||||
|
||||
sub LinkAllRule {
|
||||
if (/\G([A-Za-z\x{0080}-\x{fffd}]+)/cg) {
|
||||
if (/\G([A-Za-z\x{0080}-\x{fffd}]+)/gc) {
|
||||
my $oldpos = pos;
|
||||
Dirty($1);
|
||||
# print the word, or the link to the word
|
||||
|
||||
@@ -71,31 +71,31 @@ sub GetLinkList { # for the currently open page
|
||||
my %links;
|
||||
foreach my $block (@blocks) {
|
||||
if (shift(@flags)) { # dirty block and interlinks or normal links
|
||||
if ($inter and ($BracketText && $block =~ m/^(\[$InterLinkPattern\s+([^\]]+?)\])$/
|
||||
or $BracketText && $block =~ m/^(\[\[$FreeInterLinkPattern\|([^\]]+?)\]\])$/
|
||||
or $block =~ m/^(\[$InterLinkPattern\])$/
|
||||
or $block =~ m/^(\[\[\[$FreeInterLinkPattern\]\]\])$/
|
||||
or $block =~ m/^($InterLinkPattern)$/
|
||||
or $block =~ m/^(\[\[$FreeInterLinkPattern\]\])$/)) {
|
||||
if ($inter and ($BracketText && $block =~ m/^(\[$InterLinkPattern\s+([^\]]+?)\])$/o
|
||||
or $BracketText && $block =~ m/^(\[\[$FreeInterLinkPattern\|([^\]]+?)\]\])$/o
|
||||
or $block =~ m/^(\[$InterLinkPattern\])$/o
|
||||
or $block =~ m/^(\[\[\[$FreeInterLinkPattern\]\]\])$/o
|
||||
or $block =~ m/^($InterLinkPattern)$/o
|
||||
or $block =~ m/^(\[\[$FreeInterLinkPattern\]\])$/o)) {
|
||||
$links{$raw ? $2 : GetInterLink($2, $3)} = 1 if $InterSite{substr($2,0,index($2, ':'))};
|
||||
} elsif ($link
|
||||
and (($WikiLinks and $block !~ m/!$LinkPattern/
|
||||
and ($BracketWiki && $block =~ m/^(\[$LinkPattern\s+([^\]]+?)\])$/
|
||||
or $block =~ m/^(\[$LinkPattern\])$/
|
||||
or $block =~ m/^($LinkPattern)$/))
|
||||
and (($WikiLinks and $block !~ m/!$LinkPattern/o
|
||||
and ($BracketWiki && $block =~ m/^(\[$LinkPattern\s+([^\]]+?)\])$/o
|
||||
or $block =~ m/^(\[$LinkPattern\])$/o
|
||||
or $block =~ m/^($LinkPattern)$/o))
|
||||
or ($FreeLinks
|
||||
and ($BracketWiki && $block =~ m/^(\[\[$FreeLinkPattern\|([^\]]+)\]\])$/
|
||||
or $block =~ m/^(\[\[\[$FreeLinkPattern\]\]\])$/
|
||||
or $block =~ m/^(\[\[$FreeLinkPattern\]\])$/)))) {
|
||||
and ($BracketWiki && $block =~ m/^(\[\[$FreeLinkPattern\|([^\]]+)\]\])$/o
|
||||
or $block =~ m/^(\[\[\[$FreeLinkPattern\]\]\])$/o
|
||||
or $block =~ m/^(\[\[$FreeLinkPattern\]\])$/o)))) {
|
||||
$links{$raw ? FreeToNormal($2) : GetPageOrEditLink($2, $3)} = 1;
|
||||
} elsif ($url and $block =~ m/^\[$FullUrlPattern\]$/g) {
|
||||
} elsif ($url and $block =~ m/^\[$FullUrlPattern\]$/og) {
|
||||
$links{$raw ? $1 : GetUrl($1)} = 1;
|
||||
}
|
||||
} elsif ($url) { # clean block and url
|
||||
while ($block =~ m/$UrlPattern/g) {
|
||||
while ($block =~ m/$UrlPattern/og) {
|
||||
$links{$raw ? $1 : GetUrl($1)} = 1;
|
||||
}
|
||||
while ($block =~ m/\[$FullUrlPattern\s+[^\]]+?\]/g) {
|
||||
while ($block =~ m/\[$FullUrlPattern\s+[^\]]+?\]/og) {
|
||||
$links{$raw ? $1 : GetUrl($1)} = 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ push (@MyRules, \&LinkTagRule, \&LinkDescriptionRule);
|
||||
|
||||
sub LinkTagRule { # Process link tags on a page
|
||||
|
||||
if ( m/\G$LinkTagMark(.*?)$LinkTagMark/cg) { # find tags
|
||||
if ( m/\G$LinkTagMark(.*?)$LinkTagMark/gc) { # find tags
|
||||
my @linktags = split /,\s*/, $1; # push them in array
|
||||
@linktags = map { # and generate html output:
|
||||
qq{<a href="$ScriptName?action=linktagsearch;linktag=$_">$_</a>}; # each tag is a link to search all links with that tag
|
||||
@@ -66,7 +66,7 @@ sub LinkTagRule { # Process link tags on a page
|
||||
|
||||
sub LinkDescriptionRule { # Process link descriptions on a page
|
||||
|
||||
if ( m/\G$LinkDescMark(.*?)$LinkDescMark/cg) { # find description
|
||||
if ( m/\G$LinkDescMark(.*?)$LinkDescMark/gc) { # find description
|
||||
return qq{<span class="$LinkDescClass">$1</span>}; # put it in SPAN block
|
||||
}
|
||||
return;
|
||||
@@ -184,7 +184,7 @@ sub PrintLinkTagMap {
|
||||
my $tag = $1;
|
||||
|
||||
"<li id=\"$tag\">$tag</li>\n<ul>";
|
||||
}egsx;
|
||||
}xsge;
|
||||
|
||||
$result =~ s/\<\/tag\>/<\/ul>/g;
|
||||
$result =~ s{
|
||||
@@ -194,7 +194,7 @@ sub PrintLinkTagMap {
|
||||
my $name = $2; if ( length $name == 0 ) { $name = $url; } # name (if not present use url instead)
|
||||
my $description = $3; # and description
|
||||
"<li><a href=\"$url\">$name</a> <span class=\"$LinkDescClass\">$description</span></li>";
|
||||
}egsx;
|
||||
}xsge;
|
||||
print $result;
|
||||
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ sub DoListBannedContent {
|
||||
print $BannedRegexps . ': ' . scalar(keys(%text_regexps)) . $q->br() . "\n";
|
||||
PAGE: foreach my $id (@pages) {
|
||||
OpenPage($id);
|
||||
my @urls = $Page{text} =~ /$FullUrlPattern/g;
|
||||
my @urls = $Page{text} =~ /$FullUrlPattern/go;
|
||||
foreach my $url (@urls) {
|
||||
foreach my $re (keys %url_regexps) {
|
||||
if ($url =~ $re) {
|
||||
|
||||
@@ -38,7 +38,7 @@ sub DoListLocked {
|
||||
print $q->start_div({-class=>'content list locked'}), $q->start_p();
|
||||
}
|
||||
foreach my $id (AllPagesList()) {
|
||||
PrintPage($id) if IsFile(GetLockedPageFile($id));
|
||||
PrintPage($id) if -f GetLockedPageFile($id);
|
||||
}
|
||||
if (not $raw) {
|
||||
print $q->end_p(), $q->end_div();
|
||||
|
||||
@@ -31,7 +31,7 @@ $TagListLabel = "tag:";
|
||||
push(@MyRules, \&ListTagRule);
|
||||
|
||||
sub ListTagRule {
|
||||
if ($bol && /\G(\[\[\!tag\s*(.+)\]\])/cg) {
|
||||
if ($bol && /\G(\[\[\!tag\s*(.+)\]\])/gc) {
|
||||
my $tag_text = $2;
|
||||
my @tags = split /,\s*/, $tag_text;
|
||||
@tags = map {
|
||||
|
||||
@@ -26,7 +26,7 @@ our ($q, $bol, @MyRules, $FreeLinkPattern);
|
||||
push(@MyRules, \&LiveTemplateRule);
|
||||
|
||||
sub LiveTemplateRule {
|
||||
if ($bol and /\G(<<$FreeLinkPattern\n)/cg) {
|
||||
if ($bol and /\G(<<$FreeLinkPattern\n)/cog) {
|
||||
Clean(CloseHtmlEnvironments());
|
||||
my $str = $1;
|
||||
my $template = FreeToNormal($2);
|
||||
@@ -35,12 +35,12 @@ sub LiveTemplateRule {
|
||||
Dirty($str);
|
||||
my $oldpos = pos;
|
||||
my $old_ = $_;
|
||||
my $hash = ParseData($2);
|
||||
my %hash = ParseData($2);
|
||||
my $text = GetPageContent($template);
|
||||
return $q->p($q->strong(Ts('The template %s is either empty or does not exist.',
|
||||
$template))) . AddHtmlEnvironment('p') unless $text;
|
||||
foreach my $key (keys %$hash) {
|
||||
$text =~ s/\$$key\$/$hash->{$key}/g;
|
||||
foreach my $key (keys %hash) {
|
||||
$text =~ s/\$$key\$/$hash{$key}/g;
|
||||
}
|
||||
print "<div class=\"template $template\">";
|
||||
ApplyRules(QuoteHtml($text), 1, 1, undef, 'p');
|
||||
|
||||
@@ -18,39 +18,32 @@ use v5.10;
|
||||
|
||||
AddModuleDescription('load-lang.pl', 'Language Browser Preferences');
|
||||
|
||||
our ($q, %CookieParameters, $ConfigFile, $DataDir, $ModuleDir, $NamespaceCurrent, @MyInitVariables);
|
||||
our $CurrentLanguage;
|
||||
|
||||
our $LoadLanguageDir = "$ModuleDir/translations"; # by default same as in git
|
||||
our ($q, %CookieParameters, $ConfigFile, $DataDir, $NamespaceCurrent, @MyInitVariables);
|
||||
our ($CurrentLanguage, $LoadLanguageDir);
|
||||
|
||||
$CookieParameters{interface} = '';
|
||||
|
||||
our %TranslationsLibrary = (
|
||||
'bg' => 'bulgarian-utf8.pl',
|
||||
'ca' => 'catalan-utf8.pl',
|
||||
'de' => 'german-utf8.pl',
|
||||
'et' => 'estonian-utf8.pl',
|
||||
'es' => 'spanish-utf8.pl',
|
||||
'fi' => 'finnish-utf8.pl',
|
||||
'fr' => 'french-utf8.pl',
|
||||
'gr' => 'greek-utf8.pl',
|
||||
'he' => 'hebrew-utf8.pl',
|
||||
'it' => 'italian-utf8.pl',
|
||||
'ja' => 'japanese-utf8.pl',
|
||||
'ko' => 'korean-utf8.pl',
|
||||
'nl' => 'dutch-utf8.pl',
|
||||
'pl' => 'polish-utf8.pl',
|
||||
'pt' => 'portuguese-utf8.pl',
|
||||
'pt-br' => 'brazilian-portuguese-utf8.pl',
|
||||
'ro' => 'romanian-utf8.pl',
|
||||
'ru' => 'russian-utf8.pl',
|
||||
'se' => 'swedish-utf8.pl',
|
||||
'sr' => 'serbian-utf8.pl',
|
||||
'uk' => 'ukrainian-utf8.pl',
|
||||
'zh' => 'chinese-utf8.pl',
|
||||
'zh-cn' => 'chinese_cn-utf8.pl',
|
||||
'zh-tw' => 'chinese-utf8.pl',
|
||||
);
|
||||
my %library= ('bg' => 'bulgarian-utf8.pl',
|
||||
'de' => 'german-utf8.pl',
|
||||
'es' => 'spanish-utf8.pl',
|
||||
'fr' => 'french-utf8.pl',
|
||||
'fi' => 'finnish-utf8.pl',
|
||||
'gr' => 'greek-utf8.pl',
|
||||
'he' => 'hebrew-utf8.pl',
|
||||
'it' => 'italian-utf8.pl',
|
||||
'ja' => 'japanese-utf8.pl',
|
||||
'ko' => 'korean-utf8.pl',
|
||||
'nl' => 'dutch-utf8.pl',
|
||||
'pl' => 'polish-utf8.pl',
|
||||
'pt' => 'portuguese-utf8.pl',
|
||||
'ro' => 'romanian-utf8.pl',
|
||||
'ru' => 'russian-utf8.pl',
|
||||
'se' => 'swedish-utf8.pl',
|
||||
'sr' => 'serbian-utf8.pl',
|
||||
'zh' => 'chinese-utf8.pl',
|
||||
'zh-cn' => 'chinese_cn-utf8.pl',
|
||||
'zh-tw' => 'chinese-utf8.pl',
|
||||
);
|
||||
|
||||
sub LoadLanguage {
|
||||
# my $requested_language = "da, en-gb;q=0.8, en;q=0.7";
|
||||
@@ -72,8 +65,7 @@ sub LoadLanguage {
|
||||
# . $q->end_html) && exit if GetParam('debug', '');
|
||||
foreach (@prefs) {
|
||||
last if $Lang{$_} eq 'en'; # the default
|
||||
my $file = $TranslationsLibrary{$Lang{$_}};
|
||||
next unless $file; # file is not listed, eg. there is no file for "de-ch"
|
||||
my $file = $library{$Lang{$_}};
|
||||
$file = "$LoadLanguageDir/$file" if defined $LoadLanguageDir;
|
||||
if (-r $file) {
|
||||
do $file;
|
||||
|
||||
@@ -64,9 +64,9 @@ You can change this expiry time by setting C<$LnCacheHours>.
|
||||
push (@MyMaintenance, \&LnMaintenance);
|
||||
|
||||
sub LnMaintenance {
|
||||
if (opendir(DIR, encode_utf8($RssDir))) { # cleanup if they should expire anyway
|
||||
foreach my $file (readdir(DIR)) {
|
||||
unlink("$RssDir/$file") if -M $file > $LnCacheHours * 3600;
|
||||
if (opendir(DIR, $RssDir)) { # cleanup if they should expire anyway
|
||||
foreach (readdir(DIR)) {
|
||||
unlink "$RssDir/$_" if $Now - (stat($_))[9] > $LnCacheHours * 3600;
|
||||
}
|
||||
closedir DIR;
|
||||
}
|
||||
@@ -103,7 +103,7 @@ L<http://ln.taoriver.net/>.
|
||||
push(@MyRules, \&LocalNamesRule);
|
||||
|
||||
sub LocalNamesRule {
|
||||
if (m/\G\[\[ln:$FullUrlPattern\s*([^\]]*)\]\]/cg) {
|
||||
if (m/\G\[\[ln:$FullUrlPattern\s*([^\]]*)\]\]/cog) {
|
||||
# [[ln:url text]], [[ln:url]]
|
||||
return $q->a({-class=>'url outside ln', -href=>$1}, $2||$1);
|
||||
}
|
||||
@@ -144,7 +144,7 @@ sub LocalNamesInit {
|
||||
$LocalNamesPage = FreeToNormal($LocalNamesPage); # spaces to underscores
|
||||
$AdminPages{$LocalNamesPage} = 1;
|
||||
my $data = GetPageContent($LocalNamesPage);
|
||||
while ($data =~ m/\[$FullUrlPattern\s+([^\]]+?)\]/g) {
|
||||
while ($data =~ m/\[$FullUrlPattern\s+([^\]]+?)\]/go) {
|
||||
my ($page, $url) = ($2, $1);
|
||||
my $id = FreeToNormal($page);
|
||||
$LocalNames{$id} = $url;
|
||||
@@ -152,12 +152,12 @@ sub LocalNamesInit {
|
||||
# Now read data from ln links, checking cache if possible. For all
|
||||
# URLs not in the cache or with invalid cache, fetch the file again,
|
||||
# and save it in the cache.
|
||||
my @ln = $data =~ m/\[\[ln:$FullUrlPattern[^\]]*?\]\]/g;
|
||||
my @ln = $data =~ m/\[\[ln:$FullUrlPattern[^\]]*?\]\]/go;
|
||||
my %todo = map {$_, GetLnFile($_)} @ln;
|
||||
my %data = ();
|
||||
if (GetParam('cache', $UseCache) > 0) {
|
||||
foreach my $uri (keys %todo) { # read cached rss files if possible
|
||||
if ($Now - Modified($todo{$uri}) < $LnCacheHours * 3600) {
|
||||
if ($Now - (stat($todo{$uri}))[9] < $LnCacheHours * 3600) {
|
||||
$data{$uri} = ReadFile($todo{$uri});
|
||||
delete($todo{$uri}); # no need to fetch them below
|
||||
}
|
||||
@@ -347,13 +347,13 @@ sub DoLocalNames {
|
||||
if (GetParam('expand', 0)) {
|
||||
print "# Local names defined on $LocalNamesPage:\n";
|
||||
my $data = GetPageContent($LocalNamesPage);
|
||||
while ($data =~ m/\[$FullUrlPattern\s+([^\]]+?)\]/g) {
|
||||
while ($data =~ m/\[$FullUrlPattern\s+([^\]]+?)\]/go) {
|
||||
my ($title, $url) = ($2, $1);
|
||||
my $id = FreeToNormal($title);
|
||||
print qq{LN "$title" "$url"\n};
|
||||
}
|
||||
print "# Namespace delegations defined on $LocalNamesPage:\n";
|
||||
while ($data =~ m/\[\[ln:$FullUrlPattern([^\]]*)?\]\]/g) {
|
||||
while ($data =~ m/\[\[ln:$FullUrlPattern([^\]]*)?\]\]/go) {
|
||||
my ($title, $url) = ($2, $1);
|
||||
my $id = FreeToNormal($title);
|
||||
print qq{NS "$title" "$url"\n};
|
||||
@@ -396,10 +396,10 @@ sub DoDefine {
|
||||
$q->start_div({-class=>'content define'}),
|
||||
GetFormStart(undef, 'get', 'def');
|
||||
my $go = T('Go!');
|
||||
print $q->p($q->label({-for=>"defined"}, T('Name:') . ' '),
|
||||
print $q->p($q->label({-for=>"defined"}, T('Name: ')),
|
||||
$q->textfield(-name=>"name", -id=>"defined",
|
||||
-tabindex=>"1", -size=>20));
|
||||
print $q->p($q->label({-for=>"definition"}, T('URL:') . ' '),
|
||||
print $q->p($q->label({-for=>"definition"}, T('URL: ')),
|
||||
$q->textfield(-name=>"link", -id=>"definition",
|
||||
-tabindex=>"2", -size=>20));
|
||||
print $q->p($q->submit(-label=>$go, -tabindex=>"3"),
|
||||
@@ -430,7 +430,7 @@ sub GetWantedPages {
|
||||
# skip comment pages
|
||||
if ($CommentsPrefix) {
|
||||
foreach my $id (keys %WantedPages) {
|
||||
delete $WantedPages{$id} if $id =~ /^$CommentsPrefix/; # TODO use $CommentsPattern ?
|
||||
delete $WantedPages{$id} if $id =~ /^$CommentsPrefix/o; # TODO use $CommentsPattern ?
|
||||
}
|
||||
}
|
||||
# now something more complicated: if near-links.pl was loaded, then
|
||||
@@ -446,7 +446,7 @@ sub GetWantedPages {
|
||||
# if any wanted pages remain, print them
|
||||
if (@wanted) {
|
||||
return $q->div({-class=>'definition'},
|
||||
$q->p(T('Define external redirect:'), ' ',
|
||||
$q->p(T('Define external redirect: '),
|
||||
map { my $page = NormalToFree($_);
|
||||
ScriptLink('action=define;name='
|
||||
. UrlEncode($page),
|
||||
|
||||
@@ -22,7 +22,7 @@ use v5.10;
|
||||
AddModuleDescription('login.pl', 'Login Module');
|
||||
|
||||
our ($q, %Action, $SiteName, @MyAdminCode, $IndexFile, $DataDir, $FullUrl);
|
||||
our ($RegistrationForm, $MinimumPasswordLength, $RegistrationsMustBeApproved, $LoginForm, $PasswordFile, $PasswordFileToUse, $PendingPasswordFile, $RequireLoginToEdit, $ConfirmEmailAddress, $UnconfirmedPasswordFile, $EmailSenderAddress, $EmailCommand, $EmailRegExp, $NotifyPendingRegistrations, $EmailConfirmationMessage, $ResetPasswordMessage, $LogoutForm, $ResetForm, $ChangePassForm, $RequireCamelUserName, $UsernameRegExp);
|
||||
our ($RegistrationForm, $MinimumPasswordLength, $RegistrationsMustBeApproved, $LoginForm, $PasswordFile, $PasswordFileToUse, $PendingPasswordFile, $RequireLoginToEdit, $ConfirmEmailAddress, $UncomfirmedPasswordFile, $EmailSenderAddress, $EmailCommand, $EmailRegExp, $NotifyPendingRegistrations, $EmailConfirmationMessage, $ResetPasswordMessage, $LogoutForm, $ResetForm, $ChangePassForm, $RequireCamelUserName, $UsernameRegExp);
|
||||
|
||||
my $EncryptedPassword = "";
|
||||
|
||||
@@ -40,7 +40,7 @@ $RegistrationsMustBeApproved = 1 unless defined $RegistrationsMustBeApproved;
|
||||
$PendingPasswordFile = "$DataDir/pending" unless defined $PendingPasswordFile;
|
||||
|
||||
$ConfirmEmailAddress = 1 unless defined $ConfirmEmailAddress;
|
||||
$UnconfirmedPasswordFile = "$DataDir/uncomfirmed" unless defined $UnconfirmedPasswordFile;
|
||||
$UncomfirmedPasswordFile = "$DataDir/uncomfirmed" unless defined $UncomfirmedPasswordFile;
|
||||
|
||||
$EmailSenderAddress = "fletcher\@freeshell.org" unless defined $EmailSenderAddress;
|
||||
$EmailCommand = "/usr/sbin/sendmail -oi -t" unless defined $EmailCommand;
|
||||
@@ -71,7 +71,7 @@ $PasswordFileToUse = $RegistrationsMustBeApproved
|
||||
? $PendingPasswordFile : $PasswordFile;
|
||||
|
||||
$PasswordFileToUse = $ConfirmEmailAddress
|
||||
? $UnconfirmedPasswordFile : $PasswordFileToUse;
|
||||
? $UncomfirmedPasswordFile : $PasswordFileToUse;
|
||||
|
||||
$RegistrationForm = <<'EOT' unless defined $RegistrationForm;
|
||||
<p>Your Username should be a CamelCase form of your real name, e.g. JohnDoe.</p>
|
||||
@@ -199,9 +199,9 @@ sub DoRegister {
|
||||
my $id = shift;
|
||||
print GetHeader('', Ts('Register for %s', $SiteName), '');
|
||||
print '<div class="content">';
|
||||
$RegistrationForm =~ s/\%([a-z]+)\%/GetParam($1)/egi;
|
||||
$RegistrationForm =~ s/\%([a-z]+)\%/GetParam($1)/ige;
|
||||
$RegistrationForm =~ s/\$([a-z]+)\$/$q->span({-class=>'param'}, GetParam($1))
|
||||
. $q->input({-type=>'hidden', -name=>$1, -value=>GetParam($1)})/eg;
|
||||
. $q->input({-type=>'hidden', -name=>$1, -value=>GetParam($1)})/ge;
|
||||
print $RegistrationForm;
|
||||
print '</div>';
|
||||
PrintFooter();
|
||||
@@ -271,9 +271,9 @@ sub DoLogin {
|
||||
my $id = shift;
|
||||
print GetHeader('', Ts('Login to %s', $SiteName), '');
|
||||
print '<div class="content">';
|
||||
$LoginForm =~ s/\%([a-z]+)\%/GetParam($1)/eg;
|
||||
$LoginForm =~ s/\%([a-z]+)\%/GetParam($1)/ge;
|
||||
$LoginForm =~ s/\$([a-z]+)\$/$q->span({-class=>'param'}, GetParam($1))
|
||||
. $q->input({-type=>'hidden', -name=>$1, -value=>GetParam($1)})/eg;
|
||||
. $q->input({-type=>'hidden', -name=>$1, -value=>GetParam($1)})/ge;
|
||||
print $LoginForm;
|
||||
print '</div>';
|
||||
PrintFooter();
|
||||
@@ -290,7 +290,7 @@ sub DoProcessLogin {
|
||||
ReportError(T('Username and/or password are incorrect.'))
|
||||
unless (AuthenticateUser($username,$pwd));
|
||||
|
||||
Unlink($IndexFile);
|
||||
unlink($IndexFile);
|
||||
print GetHeader('', Ts('Register for %s', $SiteName), '');
|
||||
print '<div class="content">';
|
||||
print Ts('Logged in as %s.', $username);
|
||||
@@ -305,9 +305,9 @@ sub DoLogout {
|
||||
print GetHeader('', Ts('Logout of %s', $SiteName), '');
|
||||
print '<div class="content">';
|
||||
print '<p>' . Ts('Logout of %s?',$SiteName) . '</p>';
|
||||
$LogoutForm =~ s/\%([a-z]+)\%/GetParam($1)/eg;
|
||||
$LogoutForm =~ s/\%([a-z]+)\%/GetParam($1)/ge;
|
||||
$LogoutForm =~ s/\$([a-z]+)\$/$q->span({-class=>'param'}, GetParam($1))
|
||||
. $q->input({-type=>'hidden', -name=>$1, -value=>GetParam($1)})/eg;
|
||||
. $q->input({-type=>'hidden', -name=>$1, -value=>GetParam($1)})/ge;
|
||||
print $LogoutForm;
|
||||
print '</div>';
|
||||
PrintFooter();
|
||||
@@ -318,7 +318,7 @@ $Action{process_logout} = \&DoProcessLogout;
|
||||
sub DoProcessLogout {
|
||||
SetParam('pwd','');
|
||||
SetParam('username','');
|
||||
Unlink($IndexFile); # I shouldn't have to do this...
|
||||
unlink($IndexFile); # I shouldn't have to do this...
|
||||
print GetHeader('', Ts('Logged out of %s', $SiteName), '');
|
||||
print '<div class="content">';
|
||||
print T('You are now logged out.');
|
||||
@@ -328,7 +328,7 @@ sub DoProcessLogout {
|
||||
|
||||
sub UserExists {
|
||||
my $username = shift;
|
||||
if (open (my $PASSWD, '<', encode_utf8($PasswordFile))) {
|
||||
if (open (my $PASSWD, '<', $PasswordFile)) {
|
||||
while ( <$PASSWD> ) {
|
||||
if ($_ =~ /^$username:/) {
|
||||
return 1;
|
||||
@@ -338,7 +338,7 @@ sub UserExists {
|
||||
}
|
||||
|
||||
if ($RegistrationsMustBeApproved) {
|
||||
if (open (my $PASSWD, '<', encode_utf8($PendingPasswordFile))) {
|
||||
if (open (my $PASSWD, '<', $PendingPasswordFile)) {
|
||||
while ( <$PASSWD> ) {
|
||||
if ($_ =~ /^$username:/) {
|
||||
return 1;
|
||||
@@ -349,7 +349,7 @@ sub UserExists {
|
||||
}
|
||||
|
||||
if ($ConfirmEmailAddress) {
|
||||
if (open (my $PASSWD, '<', encode_utf8($UnconfirmedPasswordFile))) {
|
||||
if (open (my $PASSWD, '<', $UncomfirmedPasswordFile)) {
|
||||
while ( <$PASSWD> ) {
|
||||
if ($_ =~ /^$username:/) {
|
||||
return 1;
|
||||
@@ -490,13 +490,14 @@ sub ConfirmUser {
|
||||
my ($username, $key) = @_;
|
||||
my $FileToUse = $RegistrationsMustBeApproved
|
||||
? $PendingPasswordFile : $PasswordFileToUse;
|
||||
if (open(my $PASSWD, '<', encode_utf8($UnconfirmedPasswordFile))) {
|
||||
|
||||
if (open(my $PASSWD, '<', $UncomfirmedPasswordFile)) {
|
||||
while (<$PASSWD>) {
|
||||
if ($_ =~ /^$username:(.*):(.*)/) {
|
||||
if (crypt($1,$key) eq $key) {
|
||||
AddUser($username,$1,$2,$FileToUse);
|
||||
close $PASSWD;
|
||||
RemoveUser($username,$UnconfirmedPasswordFile);
|
||||
RemoveUser($username,$UncomfirmedPasswordFile);
|
||||
if ($RegistrationsMustBeApproved) {
|
||||
SendNotification($username);
|
||||
}
|
||||
@@ -514,7 +515,8 @@ sub RemoveUser {
|
||||
|
||||
my %passwords = ();
|
||||
my %emails = ();
|
||||
if (open (my $PASSWD, '<', encode_utf8($FileToUse))) {
|
||||
|
||||
if (open (my $PASSWD, '<', $FileToUse)) {
|
||||
while ( <$PASSWD> ) {
|
||||
if ($_ =~ /^(.*):(.*):(.*)$/) {
|
||||
next if ($1 eq $username);
|
||||
@@ -597,7 +599,8 @@ sub ChangePassword {
|
||||
|
||||
my %passwords = ();
|
||||
my %emails = ();
|
||||
if (open (my $PASSWD, '<', encode_utf8($PasswordFile))) {
|
||||
|
||||
if (open (my $PASSWD, '<', $PasswordFile)) {
|
||||
while ( <$PASSWD> ) {
|
||||
if ($_ =~ /^(.*):(.*):(.*)$/) {
|
||||
$passwords{$1}=$2;
|
||||
@@ -609,7 +612,7 @@ sub ChangePassword {
|
||||
|
||||
$passwords{$user} = $hash;
|
||||
|
||||
open (my $PASSWD, '>', encode_utf8($PasswordFile));
|
||||
open (my $PASSWD, '>', $PasswordFile);
|
||||
foreach my $key ( sort keys(%passwords)) {
|
||||
print $PASSWD "$key:$passwords{$key}:$emails{$key}\n";
|
||||
}
|
||||
@@ -625,9 +628,9 @@ sub DoReset {
|
||||
print GetHeader('', Ts('Reset Password for %s', $SiteName), '');
|
||||
print '<div class="content">';
|
||||
print '<p>' . T('Reset Password?') . '</p>';
|
||||
$ResetForm =~ s/\%([a-z]+)\%/GetParam($1)/eg;
|
||||
$ResetForm =~ s/\%([a-z]+)\%/GetParam($1)/ge;
|
||||
$ResetForm =~ s/\$([a-z]+)\$/$q->span({-class=>'param'}, GetParam($1))
|
||||
. $q->input({-type=>'hidden', -name=>$1, -value=>GetParam($1)})/eg;
|
||||
. $q->input({-type=>'hidden', -name=>$1, -value=>GetParam($1)})/ge;
|
||||
print $ResetForm;
|
||||
print '</div>';
|
||||
PrintFooter();
|
||||
@@ -649,9 +652,9 @@ sub DoChangePassword {
|
||||
print GetHeader('', Ts('Change Password for %s', $SiteName), '');
|
||||
print '<div class="content">';
|
||||
print '<p>' . T('Change Password?') . '</p>';
|
||||
$ChangePassForm =~ s/\%([a-z]+)\%/GetParam($1)/eg;
|
||||
$ChangePassForm =~ s/\%([a-z]+)\%/GetParam($1)/ge;
|
||||
$ChangePassForm =~ s/\$([a-z]+)\$/$q->span({-class=>'param'}, GetParam($1))
|
||||
. $q->input({-type=>'hidden', -name=>$1, -value=>GetParam($1)})/eg;
|
||||
. $q->input({-type=>'hidden', -name=>$1, -value=>GetParam($1)})/ge;
|
||||
print $ChangePassForm;
|
||||
print '</div>';
|
||||
PrintFooter();
|
||||
@@ -716,7 +719,7 @@ sub DoApprovePending {
|
||||
}
|
||||
} else {
|
||||
print '<ul>';
|
||||
if (open(my $PASSWD, '<', encode_utf8($PendingPasswordFile))) {
|
||||
if (open(my $PASSWD, '<', $PendingPasswordFile)) {
|
||||
while (<$PASSWD>) {
|
||||
if ($_ =~ /^(.*):(.*):(.*)$/) {
|
||||
print '<li>' . ScriptLink("action=approve_pending;user=$1;",$1) . ' - ' . $3 . '</li>';
|
||||
@@ -737,7 +740,8 @@ sub DoApprovePending {
|
||||
|
||||
sub ApproveUser {
|
||||
my ($username) = @_;
|
||||
if (open(my $PASSWD, '<', encode_utf8($PendingPasswordFile))) {
|
||||
|
||||
if (open(my $PASSWD, '<', $PendingPasswordFile)) {
|
||||
while (<$PASSWD>) {
|
||||
if ($_ =~ /^$username:(.*):(.*)/) {
|
||||
AddUser($username,$1,$2,$PasswordFile);
|
||||
|
||||
@@ -118,7 +118,7 @@ sub DoLogout {
|
||||
|
||||
print
|
||||
GetHeader('', Ts('Logged out of %s', $SiteName), '') .
|
||||
$q->div({-class=> 'content'}, $q->p(T('You are now logged out.'), $id ? $q->p(ScriptLink('action=browse;id=' . UrlEncode($id) . '&time=' . time, Ts('Return to %s', NormalToFree($id)))) : ''));
|
||||
$q->div({-class=> 'content'}, $q->p(T('You are now logged out.'), $id ? $q->p(ScriptLink('action=browse;id=' . UrlEncode($id) . '&time=' . time, T('Return to ' . NormalToFree($id)))) : ''));
|
||||
PrintFooter();
|
||||
}
|
||||
|
||||
@@ -201,10 +201,10 @@ sub CookieUsernameFix {
|
||||
# Only valid usernames get stored in the new cookie.
|
||||
my $name = GetParam('username', '');
|
||||
if (!$name) { }
|
||||
elsif (!$FreeLinks && !($name =~ /^$LinkPattern$/)) {
|
||||
elsif (!$FreeLinks && !($name =~ /^$LinkPattern$/o)) {
|
||||
CookieUsernameFixDelete(Ts('Invalid UserName %s: not saved.', $name));
|
||||
}
|
||||
elsif ($FreeLinks && (!($name =~ /^$FreeLinkPattern$/))) {
|
||||
elsif ($FreeLinks && (!($name =~ /^$FreeLinkPattern$/o))) {
|
||||
CookieUsernameFixDelete(Ts('Invalid UserName %s: not saved.', $name));
|
||||
}
|
||||
elsif (length($name) > 50) { # Too long
|
||||
|
||||
@@ -56,12 +56,14 @@ sub MacFixEncoding {
|
||||
return unless %Namespaces;
|
||||
my %hash = ();
|
||||
for my $key (keys %Namespaces) {
|
||||
utf8::decode($key);
|
||||
$key = NFC($key);
|
||||
$hash{$key} = $NamespaceRoot . '/' . $key . '/';
|
||||
}
|
||||
%Namespaces = %hash;
|
||||
%hash = ();
|
||||
for my $key (keys %InterSite) {
|
||||
utf8::decode($key);
|
||||
$key = NFC($key);
|
||||
$hash{$key} = $Namespaces{$key} if $Namespaces{$key};
|
||||
}
|
||||
|
||||
@@ -84,7 +84,7 @@ sub MailNewInitCookie {
|
||||
$q->delete('mail');
|
||||
if (!$mail) {
|
||||
# do nothing
|
||||
} elsif (!($mail =~ /$MailPattern/)) {
|
||||
} elsif (!($mail =~ /$MailPattern/o)) {
|
||||
$Message .= $q->p(Ts('Invalid Mail %s: not saved.', $mail));
|
||||
} else {
|
||||
SetParam('mail', $mail);
|
||||
@@ -106,7 +106,7 @@ sub MailFormAddition {
|
||||
. ScriptLink("action=subscribe;pages=$id", T('subscribe'), 'subscribe');
|
||||
}
|
||||
$addition = $q->span({-class=>'mail'},
|
||||
$q->label({-for=>'mail'}, T('Email:') . ' ')
|
||||
$q->label({-for=>'mail'}, T('Email: '))
|
||||
. ' ' . $q->textfield(-name=>'mail', -id=>'mail',
|
||||
-default=>GetParam('mail', ''))
|
||||
. $addition);
|
||||
@@ -120,7 +120,7 @@ sub MailIsSubscribed {
|
||||
return 0 unless $mail;
|
||||
# open the DB file
|
||||
require DB_File;
|
||||
tie my %h, "DB_File", encode_utf8($MailFile);
|
||||
tie my %h, "DB_File", $MailFile;
|
||||
my %subscribers = map {$_=>1} split(/$FS/, UrlDecode($h{UrlEncode($id)}));
|
||||
untie %h;
|
||||
return $subscribers{$mail};
|
||||
@@ -197,7 +197,7 @@ sub NewMailDeletePage {
|
||||
sub MailDeletePage {
|
||||
my $id = shift;
|
||||
require DB_File;
|
||||
tie my %h, "DB_File", encode_utf8($MailFile);
|
||||
tie my %h, "DB_File", $MailFile;
|
||||
foreach my $mail (split(/$FS/, UrlDecode(delete $h{UrlEncode($id)}))) {
|
||||
my %subscriptions = map {$_=>1} split(/$FS/, UrlDecode($h{UrlEncode($mail)}));
|
||||
delete $subscriptions{$id};
|
||||
@@ -274,7 +274,7 @@ sub MailSubscription {
|
||||
my $mail = shift;
|
||||
return unless $mail;
|
||||
require DB_File;
|
||||
tie my %h, "DB_File", encode_utf8($MailFile);
|
||||
tie my %h, "DB_File", $MailFile;
|
||||
my @result = split(/$FS/, UrlDecode($h{UrlEncode($mail)}));
|
||||
untie %h;
|
||||
@result = sort @result;
|
||||
@@ -303,15 +303,16 @@ sub DoMailSubscriptionList {
|
||||
'<ul>';
|
||||
}
|
||||
require DB_File;
|
||||
tie my %h, "DB_File", encode_utf8($MailFile);
|
||||
|
||||
tie my %h, "DB_File", $MailFile;
|
||||
foreach my $encodedkey (sort keys %h) {
|
||||
my @values = sort split(/$FS/, UrlDecode($h{$encodedkey}));
|
||||
my $key = UrlDecode($encodedkey);
|
||||
if ($raw) {
|
||||
print join(' ', $key, @values) . "\n";
|
||||
} else {
|
||||
print $q->li(Ts('%s:', MailLink($key, @values)) . ' '
|
||||
. join(' ', map { MailLink($_, $key) } @values));
|
||||
print $q->li(Ts('%s: ', MailLink($key, @values)),
|
||||
join(' ', map { MailLink($_, $key) } @values));
|
||||
}
|
||||
}
|
||||
print '</ul></div>' unless $raw;
|
||||
@@ -382,7 +383,7 @@ sub MailSubscribe {
|
||||
return unless $mail and @pages;
|
||||
# open the DB file
|
||||
require DB_File;
|
||||
tie my %h, "DB_File", encode_utf8($MailFile);
|
||||
tie my %h, "DB_File", $MailFile;
|
||||
# add to the mail entry
|
||||
my %subscriptions = map {$_=>1} split(/$FS/, UrlDecode($h{UrlEncode($mail)}));
|
||||
for my $id (@pages) {
|
||||
@@ -441,7 +442,7 @@ sub MailUnsubscribe {
|
||||
my ($mail, @pages) = @_;
|
||||
return unless $mail and @pages;
|
||||
require DB_File;
|
||||
tie my %h, "DB_File", encode_utf8($MailFile);
|
||||
tie my %h, "DB_File", $MailFile;
|
||||
my %subscriptions = map {$_=>1} split(/$FS/, UrlDecode($h{UrlEncode($mail)}));
|
||||
foreach my $id (@pages) {
|
||||
delete $subscriptions{$id};
|
||||
@@ -480,7 +481,8 @@ sub DoMailMigration {
|
||||
$q->start_div({-class=>'content mailmigrate'});
|
||||
|
||||
require DB_File;
|
||||
tie my %h, "DB_File", encode_utf8($MailFile);
|
||||
|
||||
tie my %h, "DB_File", $MailFile;
|
||||
my $found = 0;
|
||||
foreach my $key (keys %h) {
|
||||
if (index($key, '@') != -1) {
|
||||
|
||||
@@ -45,14 +45,14 @@ sub MarkdownRule {
|
||||
. AddHtmlEnvironment("p");
|
||||
}
|
||||
# setext headers
|
||||
elsif ($bol and m/\G((\s*\n)*(.+?)[ \t]*\n(-+|=+)[ \t]*\n)/cg) {
|
||||
elsif ($bol and m/\G((\s*\n)*(.+?)[ \t]*\n(-+|=+)[ \t]*\n)/gc) {
|
||||
return CloseHtmlEnvironments()
|
||||
. (substr($4,0,1) eq '=' ? $q->h2($3) : $q->h3($3))
|
||||
. AddHtmlEnvironment('p');
|
||||
}
|
||||
# > blockquote
|
||||
# with continuation
|
||||
elsif ($bol and m/\G>/cg) {
|
||||
elsif ($bol and m/\G>/gc) {
|
||||
return CloseHtmlEnvironments()
|
||||
. AddHtmlEnvironment('blockquote');
|
||||
}
|
||||
@@ -117,20 +117,20 @@ sub MarkdownRule {
|
||||
. AddHtmlEnvironment('td');
|
||||
}
|
||||
# whitespace indentation = code
|
||||
elsif ($bol and m/\G(\s*\n)*( .+)\n?/cg) {
|
||||
elsif ($bol and m/\G(\s*\n)*( .+)\n?/gc) {
|
||||
my $str = substr($2, 4);
|
||||
while (m/\G( .*)\n?/cg) {
|
||||
while (m/\G( .*)\n?/gc) {
|
||||
$str .= "\n" . substr($1, 4);
|
||||
}
|
||||
return OpenHtmlEnvironment('pre',1) . $str; # always level 1
|
||||
}
|
||||
# ``` = code
|
||||
elsif ($bol and m/\G```[ \t]*\n(.*?)\n```[ \t]*(\n|$)/cgs) {
|
||||
elsif ($bol and m/\G```[ \t]*\n(.*?)\n```[ \t]*(\n|$)/gcs) {
|
||||
return CloseHtmlEnvironments() . $q->pre($1)
|
||||
. AddHtmlEnvironment("p");
|
||||
}
|
||||
# [an example](http://example.com/ "Title")
|
||||
elsif (m/\G\[(.+?)\]\($FullUrlPattern(\s+"(.+?)")?\)/cg) {
|
||||
elsif (m/\G\[(.+?)\]\($FullUrlPattern(\s+"(.+?)")?\)/goc) {
|
||||
my ($text, $url, $title) = ($1, $2, $4);
|
||||
$url =~ /^($UrlProtocols)/;
|
||||
my %params;
|
||||
|
||||
@@ -142,18 +142,18 @@ sub MarkupTag {
|
||||
}
|
||||
|
||||
sub MarkupRule {
|
||||
if ($bol and %MarkupLines and m/$markup_lines_re/cg) {
|
||||
if ($bol and %MarkupLines and m/$markup_lines_re/gc) {
|
||||
my ($tag, $str) = ($1, $2);
|
||||
$str = $q->span($tag) . $str;
|
||||
while (m/$markup_lines_re/cg) {
|
||||
while (m/$markup_lines_re/gc) {
|
||||
$str .= $q->span($1) . $2;
|
||||
}
|
||||
return CloseHtmlEnvironments()
|
||||
. MarkupTag($MarkupLines{UnquoteHtml($tag)}, $str)
|
||||
. AddHtmlEnvironment('p');
|
||||
} elsif (%MarkupSingles and m/$markup_singles_re/cg) {
|
||||
} elsif (%MarkupSingles and m/$markup_singles_re/gc) {
|
||||
return $MarkupSingles{UnquoteHtml($1)};
|
||||
} elsif (%MarkupForcedPairs and m/$markup_forced_pairs_re/cg) {
|
||||
} elsif (%MarkupForcedPairs and m/$markup_forced_pairs_re/gc) {
|
||||
my $tag = $1;
|
||||
my $start = $tag;
|
||||
my $end = $tag;
|
||||
@@ -168,20 +168,20 @@ sub MarkupRule {
|
||||
$endre .= '[ \t]*\n?' if $block_element{$start}; # skip trailing whitespace if block
|
||||
# may match the empty string, or multiple lines, but may not span
|
||||
# paragraphs.
|
||||
if ($endre and m/\G$endre/cg) {
|
||||
if ($endre and m/\G$endre/gc) {
|
||||
return $tag . $end;
|
||||
} elsif ($tag eq $end && m/\G((:?.+?\n)*?.+?)$endre/cg) { # may not span paragraphs
|
||||
} elsif ($tag eq $end && m/\G((:?.+?\n)*?.+?)$endre/gc) { # may not span paragraphs
|
||||
return MarkupTag($data, $1);
|
||||
} elsif ($tag ne $end && m/\G((:?.|\n)+?)$endre/cg) {
|
||||
} elsif ($tag ne $end && m/\G((:?.|\n)+?)$endre/gc) {
|
||||
return MarkupTag($data, $1);
|
||||
} else {
|
||||
return $tag;
|
||||
}
|
||||
} elsif (%MarkupPairs and m/$markup_pairs_re/cg) {
|
||||
} elsif (%MarkupPairs and m/$markup_pairs_re/gc) {
|
||||
return MarkupTag($MarkupPairs{UnquoteHtml($1)}, $2);
|
||||
} elsif ($MarkupPairs{'/'} and m|\G~/|cg) {
|
||||
} elsif ($MarkupPairs{'/'} and m|\G~/|gc) {
|
||||
return '~/'; # fix ~/elisp/ example
|
||||
} elsif ($MarkupPairs{'/'} and m|\G(/[-A-Za-z0-9\x{0080}-\x{fffd}/]+/$words/)|cg) {
|
||||
} elsif ($MarkupPairs{'/'} and m|\G(/[-A-Za-z0-9\x{0080}-\x{fffd}/]+/$words/)|gc) {
|
||||
return $1; # fix /usr/share/lib/! example
|
||||
}
|
||||
# "foo
|
||||
|
||||
@@ -54,10 +54,10 @@ sub BisectAction {
|
||||
sub BisectInitialScreen {
|
||||
print GetFormStart(undef, 'get', 'bisect');
|
||||
print GetHiddenValue('action', 'bisect');
|
||||
my @disabledFiles = Glob("$ModuleDir/*.p[ml].disabled");
|
||||
my @disabledFiles = bsd_glob("$ModuleDir/*.p[ml].disabled");
|
||||
if (@disabledFiles == 0) {
|
||||
print T('Test / Always enabled / Always disabled'), $q->br();
|
||||
my @files = Glob("$ModuleDir/*.p[ml]");
|
||||
my @files = bsd_glob("$ModuleDir/*.p[ml]");
|
||||
for (my $i = 0; $i < @files; $i++) {
|
||||
my $moduleName = fileparse($files[$i]);
|
||||
my @disabled = ($moduleName eq 'module-bisect.pl' ? (-disabled=>'disabled') : ());
|
||||
@@ -68,7 +68,7 @@ sub BisectInitialScreen {
|
||||
}
|
||||
print $q->submit(-name=>'bad', -value=>T('Start'));
|
||||
} else {
|
||||
print T('Bisecting proccess is already active.'), $q->br();
|
||||
print T('Biscecting proccess is already active.'), $q->br();
|
||||
print $q->submit(-name=>'stop', -value=>T('Stop'));
|
||||
}
|
||||
print $q->end_form();
|
||||
@@ -78,7 +78,7 @@ sub BisectProcess {
|
||||
my ($isGood) = @_;
|
||||
my $parameterHandover = '';
|
||||
BisectEnableAll();
|
||||
my @files = Glob("$ModuleDir/*.p[ml]");
|
||||
my @files = bsd_glob("$ModuleDir/*.p[ml]");
|
||||
for (my $i = @files - 1; $i >= 0; $i--) { # handle user choices
|
||||
if (GetParam("m$i") eq 'on') {
|
||||
$parameterHandover .= GetHiddenValue("m$i", GetParam("m$i"));
|
||||
@@ -102,7 +102,7 @@ sub BisectProcess {
|
||||
print $q->end_form();
|
||||
return;
|
||||
}
|
||||
print T('Module count (only testable modules):'), ' ', $q->strong(scalar @files), $q->br();
|
||||
print T('Module count (only testable modules): '), $q->strong(scalar @files), $q->br();
|
||||
print $q->br(), T('Current module statuses:'), $q->br();
|
||||
my $halfsize = ($end - $start + 1) / 2.0; # + 1 because it is count
|
||||
$end -= int($halfsize) unless $isGood;
|
||||
@@ -131,7 +131,7 @@ sub BisectProcess {
|
||||
}
|
||||
|
||||
sub BisectEnableAll {
|
||||
for (Glob("$ModuleDir/*.p[ml].disabled")) { # reenable all modules
|
||||
for (bsd_glob("$ModuleDir/*.p[ml].disabled")) { # reenable all modules
|
||||
my $oldName = $_;
|
||||
s/\.disabled$//;
|
||||
print Ts('Enabling %s', (fileparse($_))[0]), '...', $q->br() if $_[0];
|
||||
|
||||
@@ -40,8 +40,8 @@ sub ModuleUpdaterAction {
|
||||
if (GetParam('ok')) {
|
||||
ModuleUpdaterApply();
|
||||
} else {
|
||||
Unlink(Glob("$TempDir/*.p[ml]")); # XXX is it correct to use $TempDir for such stuff? What if something else puts .pm files there?
|
||||
for (Glob("$ModuleDir/*.p[ml]")) {
|
||||
unlink bsd_glob("$TempDir/*.p[ml]"); # XXX is it correct to use $TempDir for such stuff? What if something else puts .pm files there?
|
||||
for (bsd_glob("$ModuleDir/*.p[ml]")) {
|
||||
my $curModule = fileparse($_);
|
||||
ProcessModule($curModule);
|
||||
}
|
||||
@@ -58,7 +58,7 @@ sub ModuleUpdaterAction {
|
||||
}
|
||||
|
||||
sub ModuleUpdaterApply {
|
||||
for (Glob("$TempDir/*.p[ml]")) {
|
||||
for (bsd_glob("$TempDir/*.p[ml]")) {
|
||||
my $moduleName = fileparse($_);
|
||||
if (move($_, "$ModuleDir/$moduleName")) {
|
||||
print $q->strong("Module $moduleName updated successfully!"), $q->br();
|
||||
@@ -66,7 +66,7 @@ sub ModuleUpdaterApply {
|
||||
print $q->strong("Unable to replace module $moduleName: $!"), $q->br();
|
||||
}
|
||||
}
|
||||
Unlink(Glob("$TempDir/*.p[ml]")); # XXX same as above
|
||||
unlink bsd_glob("$TempDir/*.p[ml]"); # XXX same as above
|
||||
print $q->br(), $q->strong('Done!');
|
||||
}
|
||||
|
||||
@@ -81,15 +81,15 @@ sub ProcessModule {
|
||||
. ' If this is your own module, please contribute it to Oddmuse!'), $q->br();
|
||||
return;
|
||||
}
|
||||
my $file = "$TempDir/$module";
|
||||
open my $fh, ">:utf8", encode_utf8($file) or die("Could not open file $TempDir/$module: $!");
|
||||
open my $fh, ">", "$TempDir/$module" or die("Could not open file. $!");
|
||||
utf8::encode($moduleData);
|
||||
print $fh $moduleData;
|
||||
close $fh;
|
||||
|
||||
my $diff = DoModuleDiff("$ModuleDir/$module", "$TempDir/$module");
|
||||
if (not $diff) {
|
||||
print $q->strong('This module is up to date, there is no need to update it.'), $q->br();
|
||||
Unlink("$TempDir/$module");
|
||||
unlink "$TempDir/$module";
|
||||
return;
|
||||
}
|
||||
print $q->strong('There is a newer version of this module. Here is a diff:'), $q->br();
|
||||
@@ -109,6 +109,7 @@ sub ProcessModule {
|
||||
}
|
||||
|
||||
sub DoModuleDiff {
|
||||
my $diff = decode_utf8(`diff -U 3 -- \Q$_[0]\E \Q$_[1]\E`);
|
||||
my $diff = `diff -U 3 -- \Q$_[0]\E \Q$_[1]\E`;
|
||||
utf8::decode($diff); # needs decoding
|
||||
return $diff;
|
||||
}
|
||||
|
||||
@@ -64,13 +64,13 @@ sub MoinListLevel {
|
||||
|
||||
sub MoinRule {
|
||||
# ["free link"]
|
||||
if (m/\G(\["(.*?)"\])/cgs) {
|
||||
if (m/\G(\["(.*?)"\])/gcs) {
|
||||
Dirty($1);
|
||||
print GetPageOrEditLink($2);
|
||||
return '';
|
||||
}
|
||||
# [[BR]]
|
||||
elsif (m/\G\[\[BR\]\]/cg) {
|
||||
elsif (m/\G\[\[BR\]\]/gc) {
|
||||
return $q->br();
|
||||
}
|
||||
# {{{
|
||||
|
||||
@@ -46,13 +46,13 @@ sub NewMultiUrlBannedContent {
|
||||
|
||||
sub MultiUrlBannedContent {
|
||||
my $str = shift;
|
||||
my @urls = $str =~ /$FullUrlPattern/g;
|
||||
my @urls = $str =~ /$FullUrlPattern/go;
|
||||
my %domains;
|
||||
my %whitelist;
|
||||
my $max = 0;
|
||||
my $label = '[a-z]([a-z0-9-]*[a-z0-9])?'; # RFC 1034
|
||||
foreach (split(/\n/, GetPageContent($MultiUrlWhiteList))) {
|
||||
next unless m/^\s*($label\.$label)/i;
|
||||
next unless m/^\s*($label\.$label)/io;
|
||||
$whitelist{$1} = 1;
|
||||
}
|
||||
foreach my $url (@urls) {
|
||||
|
||||
@@ -85,8 +85,9 @@ sub NamespacesInitVariables {
|
||||
# Do this before changing the $DataDir and $ScriptName
|
||||
if ($UsePathInfo) {
|
||||
$Namespaces{$NamespacesMain} = $ScriptName . '/';
|
||||
foreach my $name (Glob("$DataDir/*")) {
|
||||
if (IsDir($name)
|
||||
foreach my $name (bsd_glob("$DataDir/*")) {
|
||||
utf8::decode($name);
|
||||
if (-d $name
|
||||
and $name =~ m|/($InterSitePattern)$|
|
||||
and $name ne $NamespacesMain
|
||||
and $name ne $NamespacesSelf) {
|
||||
@@ -96,9 +97,10 @@ sub NamespacesInitVariables {
|
||||
}
|
||||
$NamespaceRoot = $ScriptName; # $ScriptName may be changed below
|
||||
$NamespaceCurrent = '';
|
||||
my $ns = decode_utf8(GetParam('ns', ''));
|
||||
my $ns = GetParam('ns', '');
|
||||
if (not $ns and $UsePathInfo) {
|
||||
my $path_info = decode_utf8($q->path_info());
|
||||
my $path_info = $q->path_info();
|
||||
utf8::decode($path_info);
|
||||
# make sure ordinary page names are not matched!
|
||||
if ($path_info =~ m|^/($InterSitePattern)(/.*)?|
|
||||
and ($2 or $q->keywords or NamespaceRequiredByParameter())) {
|
||||
@@ -135,8 +137,13 @@ sub NamespacesInitVariables {
|
||||
$StaticUrl .= UrlEncode($NamespaceCurrent) . '/'
|
||||
if substr($StaticUrl,-1) eq '/'; # from static-copy.pl
|
||||
$WikiDescription .= "<p>Current namespace: $NamespaceCurrent</p>";
|
||||
$LastUpdate = Modified($IndexFile);
|
||||
CreateDir($DataDir);
|
||||
# override LastUpdate
|
||||
my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size, $atime,$mtime,$ctime,$blksize,$blocks)
|
||||
= stat($IndexFile);
|
||||
$LastUpdate = $mtime;
|
||||
CreateDir($DataDir); # Create directory if it doesn't exist
|
||||
ReportError(Ts('Cannot create %s', $DataDir) . ": $!", '500 INTERNAL SERVER ERROR')
|
||||
unless -d $DataDir;
|
||||
}
|
||||
$Namespaces{$NamespacesSelf} = $ScriptName . '?';
|
||||
# reinitialize
|
||||
@@ -217,19 +224,19 @@ sub NewNamespaceGetRcLines { # starttime, hash of seen pages to use as a second
|
||||
# opening a rcfile, compare the first timestamp with the
|
||||
# starttime. If any rcfile exists with no timestamp before the
|
||||
# starttime, we need to open its rcoldfile.
|
||||
foreach my $rcfile (@rcfiles) {
|
||||
open(my $F, '<:encoding(UTF-8)', encode_utf8($rcfile));
|
||||
foreach my $file (@rcfiles) {
|
||||
open(my $F, '<:encoding(UTF-8)', $file);
|
||||
my $line = <$F>;
|
||||
my ($ts) = split(/$FS/, $line); # the first timestamp in the regular rc file
|
||||
my ($ts) = split(/$FS/o, $line); # the first timestamp in the regular rc file
|
||||
my @new;
|
||||
if (not $ts or $ts > $starttime) { # we need to read the old rc file, too
|
||||
push(@new, GetRcLinesFor($rcoldfiles{$rcfile}, $starttime,\%match, \%following));
|
||||
push(@new, GetRcLinesFor($rcoldfiles{$file}, $starttime,\%match, \%following));
|
||||
}
|
||||
push(@new, GetRcLinesFor($rcfile, $starttime, \%match, \%following));
|
||||
push(@new, GetRcLinesFor($file, $starttime, \%match, \%following));
|
||||
# strip rollbacks in each namespace separately
|
||||
@new = StripRollbacks(@new);
|
||||
# prepend the namespace to both pagename and author
|
||||
my $ns = $namespaces{$rcfile};
|
||||
my $ns = $namespaces{$file};
|
||||
if ($ns) {
|
||||
for (my $i = $#new; $i >= 0; $i--) {
|
||||
# page id
|
||||
@@ -374,8 +381,7 @@ sub NewNamespaceBrowsePage {
|
||||
#REDIRECT into different namespaces
|
||||
my ($id, $raw, $comment, $status) = @_;
|
||||
OpenPage($id);
|
||||
my ($revisionPage, $revision) = GetTextRevision(GetParam('revision', ''), 1);
|
||||
my $text = $revisionPage->{text};
|
||||
my ($text, $revision) = GetTextRevision(GetParam('revision', ''), 1);
|
||||
my $oldId = GetParam('oldid', '');
|
||||
if (not $oldId and not $revision and (substr($text, 0, 10) eq '#REDIRECT ')
|
||||
and (($WikiLinks and $text =~ /^\#REDIRECT\s+(($InterSitePattern:)?$InterLinkPattern)/)
|
||||
@@ -434,6 +440,8 @@ sub NamespacesNewGetId {
|
||||
# In this case GetId() will have set the parameter Test to 1.
|
||||
# http://example.org/cgi-bin/wiki.pl/Test?rollback-1234=foo
|
||||
# This doesn't set the Test parameter.
|
||||
return if $id and $UsePathInfo and $id eq $NamespaceCurrent and not GetParam($id) and not GetParam('ns');
|
||||
if ($UsePathInfo and $id eq $NamespaceCurrent and not GetParam($id) and not GetParam('ns')) {
|
||||
$id = undef;
|
||||
}
|
||||
return $id;
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ use v5.10;
|
||||
|
||||
AddModuleDescription('near-links.pl', 'Near Links');
|
||||
|
||||
our ($q, $Now, %AdminPages, %InterSite, $CommentsPrefix, $DataDir, $UseCache, @MyFooters, @MyMaintenance, @MyInitVariables, @Debugging, $InterSitePattern, @UserGotoBarPages, @IndexOptions);
|
||||
our ($q, %AdminPages, %InterSite, $CommentsPrefix, $DataDir, $UseCache, @MyFooters, @MyMaintenance, @MyInitVariables, @Debugging, $InterSitePattern, @UserGotoBarPages, @IndexOptions);
|
||||
|
||||
=head1 Near Links
|
||||
|
||||
@@ -128,8 +128,7 @@ sub NearLinksMaintenance {
|
||||
# skip if less than 12h old and caching allowed (the default)
|
||||
foreach my $site (keys %NearSite) {
|
||||
next if GetParam('cache', $UseCache) > 0
|
||||
and IsFile("$NearDir/$site")
|
||||
and $Now - Modified("$NearDir/$site") < 0.5;
|
||||
and -f "$NearDir/$site" and -M "$NearDir/$site" < 0.5;
|
||||
print $q->p(Ts('Getting page index file for %s.', $site));
|
||||
my $data = GetRaw($NearSite{$site});
|
||||
print $q->p($q->strong(Ts('%s returned no data, or LWP::UserAgent is not available.',
|
||||
@@ -186,7 +185,7 @@ sub NewNearLinksResolveId {
|
||||
my $id = shift;
|
||||
my @result = OldNearLinksResolveId($id, @_);
|
||||
my %forbidden = map { $_ => 1 } @UserGotoBarPages, %AdminPages;
|
||||
$forbidden{$id} = 1 if $CommentsPrefix and $id =~ /^$CommentsPrefix/;
|
||||
$forbidden{$id} = 1 if $CommentsPrefix and $id =~ /^$CommentsPrefix/o;
|
||||
if (not $result[1] and $NearSource{$id} and not $forbidden{$id}) {
|
||||
$NearLinksUsed{$id} = 1;
|
||||
my $site = $NearSource{$id}[0];
|
||||
@@ -265,18 +264,18 @@ sub SearchNearPages {
|
||||
if (%NearSearch and GetParam('near', 1) > 1 and GetParam('context',1)) {
|
||||
foreach my $site (keys %NearSearch) {
|
||||
my $url = $NearSearch{$site};
|
||||
$url =~ s/\%s/UrlEncode($string)/eg or $url .= UrlEncode($string);
|
||||
$url =~ s/\%s/UrlEncode($string)/ge or $url .= UrlEncode($string);
|
||||
print $q->hr(), $q->p(Ts('Fetching results from %s:', $q->a({-href=>$url}, $site)))
|
||||
unless GetParam('raw', 0);
|
||||
my $data = GetRaw($url);
|
||||
my @entries = split(/\n\n+/, $data);
|
||||
shift @entries; # skip head
|
||||
foreach my $entry (@entries) {
|
||||
my $entryPage = ParseData($entry); # need to pass reference
|
||||
my $name = $entryPage->{title};
|
||||
my %entry = ParseData($entry); # need to pass reference
|
||||
my $name = $entry{title};
|
||||
next if $found{$name}; # do not duplicate local pages
|
||||
$found{$name} = 1;
|
||||
PrintSearchResultEntry($entryPage, $regex); # with context and full search!
|
||||
PrintSearchResultEntry(\%entry, $regex); # with context and full search!
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,8 +24,8 @@ our ($q, @MyRules, $FullUrlPattern, $UrlProtocols, $BracketText);
|
||||
push(@MyRules, \&NewWindowLink);
|
||||
sub NewWindowLink {
|
||||
# compare sub LinkRules in oddmuse.pl
|
||||
if ($BracketText && m/\G(\[new:$FullUrlPattern\s+([^\]]+?)\])/cg
|
||||
or m/\G(\[new:$FullUrlPattern\])/cg) {
|
||||
if ($BracketText && m/\G(\[new:$FullUrlPattern\s+([^\]]+?)\])/cog
|
||||
or m/\G(\[new:$FullUrlPattern\])/cog) {
|
||||
my ($url, $text) = ($2, $3);
|
||||
$url =~ /^($UrlProtocols)/;
|
||||
my $class = "url $1"; # get protocol (http, ftp, ...)
|
||||
|
||||
@@ -25,7 +25,7 @@ sub NewGetSearchLink {
|
||||
my ($text, $class, $name, $title) = @_;
|
||||
$name = UrlEncode($name);
|
||||
$text =~ s/_/ /g;
|
||||
return $q->span({-class=>$class}, $text);
|
||||
return $q->span({-class=>$class }, $text);
|
||||
}
|
||||
|
||||
push(@MyAdminCode, \&BacklinksMenu);
|
||||
@@ -34,8 +34,8 @@ sub BacklinksMenu {
|
||||
if ($id) {
|
||||
my $text = T('Backlinks');
|
||||
my $class = 'backlinks';
|
||||
my $name = 'backlinks';
|
||||
my $title = T('Click to search for references to this page');
|
||||
my $name = "backlinks";
|
||||
my $title = T("Click to search for references to this page");
|
||||
my $link = ScriptLink('search=' . $id, $text, $class, $name, $title);
|
||||
push(@$menuref, $link);
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ $Action{clearcache} = \&DoClearCache;
|
||||
|
||||
sub DoClearCache {
|
||||
print GetHeader('', QuoteHtml(T('Clearing Cache')), '');
|
||||
Unlink(Glob("$NotFoundHandlerDir/*"));
|
||||
unlink(bsd_glob("$NotFoundHandlerDir/*"));
|
||||
print $q->p(T('Done.'));
|
||||
PrintFooter();
|
||||
}
|
||||
@@ -45,7 +45,7 @@ sub DoClearCache {
|
||||
sub ReadLinkDb {
|
||||
return if $LinkDbInit;
|
||||
$LinkDbInit = 1;
|
||||
return if not IsFile($LinkFile);
|
||||
return if not -f $LinkFile;
|
||||
my $data = ReadFileOrDie($LinkFile);
|
||||
map { my ($id, @links) = split; $LinkDb{$id} = \@links } split(/\n/, $data);
|
||||
}
|
||||
@@ -101,13 +101,13 @@ sub NewNotFoundHandlerSave {
|
||||
my $id = $args[0];
|
||||
OldNotFoundHandlerSave(@args);
|
||||
RefreshLinkDb(); # for the open page
|
||||
if (not IsDir($NotFoundHandlerDir)) {
|
||||
CreateDir($NotFoundHandlerDir);
|
||||
if (not -d $NotFoundHandlerDir) {
|
||||
mkdir($NotFoundHandlerDir);
|
||||
} elsif ($Page{revision} == 1) {
|
||||
NotFoundHandlerCacheUpdate($id);
|
||||
} else {
|
||||
# unlink PageName, PageName.en, PageName.de, etc.
|
||||
Unlink("$NotFoundHandlerDir/$id", Glob("$NotFoundHandlerDir/$id.[a-z][a-z]"));
|
||||
unlink("$NotFoundHandlerDir/$id", bsd_glob("$NotFoundHandlerDir/$id.[a-z][a-z]"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,7 +132,7 @@ sub NotFoundHandlerCacheUpdate {
|
||||
foreach my $source (keys %LinkDb) {
|
||||
warn "Examining $source\n";
|
||||
if (grep(/$target/, @{$LinkDb{$source}})) {
|
||||
Unlink("$NotFoundHandlerDir/$source", Glob("$NotFoundHandlerDir/$source.[a-z][a-z]"));
|
||||
unlink("$NotFoundHandlerDir/$source", bsd_glob("$NotFoundHandlerDir/$source.[a-z][a-z]"));
|
||||
warn "Unlinking $source\n";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,8 +25,8 @@ push(@MyRules, \&NumberedListRule);
|
||||
sub NumberedListRule {
|
||||
# numbered lists using # copied from usemod.pl but allow leading
|
||||
# whitespace
|
||||
if ($bol && m/\G(\s*\n)*\s*(\#+)[ \t]/cg
|
||||
or InElement('li') && m/\G(\s*\n)+\s*(\#+)[ \t]/cg) {
|
||||
if ($bol && m/\G(\s*\n)*\s*(\#+)[ \t]/cog
|
||||
or InElement('li') && m/\G(\s*\n)+\s*(\#+)[ \t]/cog) {
|
||||
return CloseHtmlEnvironmentUntil('li')
|
||||
. OpenHtmlEnvironment('ol',length($2))
|
||||
. AddHtmlEnvironment('li');
|
||||
|
||||
@@ -78,7 +78,7 @@ sub DoManifest {
|
||||
# print ScriptUrl($id) . "\n" unless $IndexHash{$id};
|
||||
# }
|
||||
# External CSS
|
||||
print ref $StyleSheet ? join("\n", @$StyleSheet) . "\n" : "$StyleSheet\n" if $StyleSheet;
|
||||
print $StyleSheet . "\n" if $StyleSheet;
|
||||
# FIXME: $StyleSheetPage
|
||||
# FIXME: external images, stuff in $HtmlHeaders
|
||||
# Error message all the stuff that's not available offline.
|
||||
|
||||
@@ -99,9 +99,9 @@ sub LocalMapWorkHorse {
|
||||
|
||||
my $retval_children = '';
|
||||
if ($depth > 0) {
|
||||
my $data = ParseData(ReadFileOrDie(GetPageFile($id)));
|
||||
my @flags = split(/$FS/, $data->{'flags'});
|
||||
my @blocks = split(/$FS/, $data->{'blocks'});
|
||||
my %data = ParseData(ReadFileOrDie(GetPageFile($id)));
|
||||
my @flags = split(/$FS/, $data{'flags'});
|
||||
my @blocks = split(/$FS/, $data{'blocks'});
|
||||
my @subpages;
|
||||
|
||||
# Iterate over blocks, operate only on "dirty" ones
|
||||
@@ -111,14 +111,14 @@ sub LocalMapWorkHorse {
|
||||
local $_ = $blocks[$i];
|
||||
|
||||
if ($WikiLinks
|
||||
&& ($BracketWiki && m/\G(\[$LinkPattern\s+([^\]]+?)\])/cg
|
||||
or m/\G(\[$LinkPattern\])/cg or m/\G($LinkPattern)/cg)) {
|
||||
&& ($BracketWiki && m/\G(\[$LinkPattern\s+([^\]]+?)\])/cog
|
||||
or m/\G(\[$LinkPattern\])/cog or m/\G($LinkPattern)/cog)) {
|
||||
$sub_id = $1;
|
||||
} elsif ($FreeLinks
|
||||
&& (($BracketWiki
|
||||
&& m/\G(\[\[($FreeLinkPattern)\|([^\]]+)\]\])/cg)
|
||||
or m/\G(\[\[\[($FreeLinkPattern)\]\]\])/cg
|
||||
or m/\G(\[\[($FreeLinkPattern)\]\])/cg)) {
|
||||
&& m/\G(\[\[($FreeLinkPattern)\|([^\]]+)\]\])/cog)
|
||||
or m/\G(\[\[\[($FreeLinkPattern)\]\]\])/cog
|
||||
or m/\G(\[\[($FreeLinkPattern)\]\])/cog)) {
|
||||
$sub_id = $2;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ my $org_emph_re = qr!\G([ \t('\"])*(([*/_=+])([^ \t\r\n,*/_=+].*?(?:\n.*?){0,1}[
|
||||
my %org_emphasis_alist = qw!* b / i _ u = code + del!;
|
||||
|
||||
sub OrgModeRule {
|
||||
if (/$org_emph_re/cg) {
|
||||
if (/$org_emph_re/cgo) {
|
||||
my $tag = $org_emphasis_alist{$3};
|
||||
return "$1<$tag>$4</$tag>$5";
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ sub UpdatePageTrail {
|
||||
|
||||
sub NewPageTrailGetGotoBar {
|
||||
my $bar = OldPageTrailGetGotoBar(@_);
|
||||
$bar .= $q->span({-class=>'trail'}, $q->br(), T('Trail:') . ' ',
|
||||
$bar .= $q->span({-class=>'trail'}, $q->br(), T('Trail: '),
|
||||
map { GetPageLink($_) } reverse(@PageTrail))
|
||||
if @PageTrail;
|
||||
return $bar;
|
||||
|
||||
@@ -28,7 +28,7 @@ push(@MyRules, \&ParagraphLinkRule);
|
||||
$RuleOrder{\&ParagraphLinkRule} = 100;
|
||||
|
||||
sub ParagraphLinkRule {
|
||||
if ($bol && m/\G(\[(-)?$FreeLinkPattern\])/cg) {
|
||||
if ($bol && m/\G(\[(-)?$FreeLinkPattern\])/cog) {
|
||||
Dirty($1);
|
||||
my $invisible = $2;
|
||||
my $orig = $3;
|
||||
|
||||
@@ -27,7 +27,7 @@ our ($q, %Page, @MyRules, $CommentsPrefix);
|
||||
push(@MyRules, \&PartialCutRule);
|
||||
|
||||
sub PartialCutRule {
|
||||
if (m/\G(?<=\n)\s*--\s*cut\s*--\s*(?=\n)/cg) {
|
||||
if (m/\G(?<=\n)\s*--\s*cut\s*--\s*(?=\n)/gc) {
|
||||
return CloseHtmlEnvironments() . '<hr class="cut" />' . AddHtmlEnvironment('p');
|
||||
}
|
||||
return;
|
||||
|
||||
@@ -78,7 +78,7 @@ push(@MyRules, \&PermanentAnchorsRule);
|
||||
|
||||
sub PermanentAnchorsRule {
|
||||
my ($locallinks, $withanchors) = @_;
|
||||
if (m/\G(\[::$FreeLinkPattern\])/cg) {
|
||||
if (m/\G(\[::$FreeLinkPattern\])/cog) {
|
||||
#[::Free Link] permanent anchor create only $withanchors
|
||||
Dirty($1);
|
||||
if ($withanchors) {
|
||||
@@ -99,7 +99,7 @@ sub GetPermanentAnchor {
|
||||
ScriptLink(UrlEncode($resolved), $text, 'alias')) . ']';
|
||||
} elsif ($PermanentAnchors{$id} ne $OpenPageName
|
||||
# 10 tries, 3 second wait, die on error
|
||||
and RequestLockDir('permanentanchors', 10, 3, 1)) {
|
||||
and RequestLockDir('permanentanchors', 1, 10, 3, 1)) {
|
||||
# Somebody may have added a permanent anchor in the mean time.
|
||||
# Comparing $LastUpdate to the $IndexFile mtime does not work for
|
||||
# subsecond changes and updates are rare, so just reread the file!
|
||||
@@ -190,7 +190,7 @@ sub NewPermanentAnchorsSave {
|
||||
sub DeletePermanentAnchors {
|
||||
my $id = shift;
|
||||
# 10 tries, 3 second wait, die on error
|
||||
RequestLockDir('permanentanchors', 10, 3, 1);
|
||||
RequestLockDir('permanentanchors', 1, 10, 3, 1);
|
||||
foreach (keys %PermanentAnchors) {
|
||||
if ($PermanentAnchors{$_} eq $id and !$PagePermanentAnchors{$_}) {
|
||||
delete($PermanentAnchors{$_}) ;
|
||||
@@ -246,7 +246,7 @@ sub NewPermanentAnchorsGetPageContent {
|
||||
if (not $result and $PermanentAnchors{$id}) {
|
||||
$result = OldPermanentAnchorsGetPageContent($PermanentAnchors{$id});
|
||||
$result =~ s/^(.*\n)*.*\[::$id\]// or return '';
|
||||
$result =~ s/(\n=|\n----|\[::$FreeLinkPattern\])(.*\n)*.*$//;
|
||||
$result =~ s/(\n=|\n----|\[::$FreeLinkPattern\])(.*\n)*.*$//o;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ sub CommentFooterLink {
|
||||
my @elements;
|
||||
if ($id and $rev ne 'history' and $rev ne 'edit') {
|
||||
if ($CommentsPrefix) {
|
||||
if ($OpenPageName =~ /^$CommentsPrefix(.*)/) {
|
||||
if ($OpenPageName =~ /^$CommentsPrefix(.*)/o) {
|
||||
push(@elements, GetPageLink($1, undef, 'original'));
|
||||
} else {
|
||||
push(@elements, GetPageLink($CommentsPrefix . $OpenPageName, undef, 'comment'));
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user