Compare commits

...

32 Commits
2.2 ... 2.2.2

Author SHA1 Message Date
Alex Schroeder
4fc84fa623 Make sure fix encoding doesn't save if nothing has changed 2012-11-21 21:39:13 +01:00
Alex Schroeder
33aa81d9c9 Fix encoding issues with translation links. 2012-11-21 21:29:41 +01:00
Alex Schroeder
58690662df Private pages no longer accessible using revision parameter 2012-11-21 21:11:49 +01:00
Alex Schroeder
b2194ebdac Added some tests for translation links. 2012-11-21 21:01:06 +01:00
Alex Schroeder
d584c4dc68 Merge branch 'master' of git.sv.gnu.org:/srv/git/oddmuse 2012-11-20 19:46:45 +01:00
Alex Schroeder
105ccdf323 Add header back to bulgarian-utf8.pl and chinese-utf8.pl 2012-11-20 15:47:03 +01:00
Alex Schröder
cb6d1cc17d Merge branch 'master' of git.sv.gnu.org:/srv/git/oddmuse 2012-11-20 15:38:51 +01:00
Alex Schroeder
be4bddab30 No longer recreate -utf8 files. 2012-11-16 21:49:56 +01:00
Alex Schroeder
465b278303 Fix a loophole where using <include "..."> allowed you to see hidden pages. 2012-11-16 18:38:27 +01:00
Alex Schroeder
a52bebdcd2 Fix docstring. 2012-11-16 17:56:25 +01:00
Alex Schroeder
1caa4c55c0 Private pages! 2012-11-16 17:12:12 +01:00
Alex Schroeder
9c77e56568 Whitespace. 2012-11-16 15:51:56 +01:00
Alex Schroeder
f5e86f4ddc Prevent double "Showing revision X" by passing QUIET to GetTextRevision. 2012-11-16 15:51:19 +01:00
Alex Schroeder
f10dde33c8 No bullet point before div.refer a elements. 2012-11-14 17:35:52 +01:00
Alex Schröder
ff64a0ed82 Update by Hervé Robin 2012-11-05 13:56:03 +01:00
Alex Schroeder
a046436a50 Deutsche Übersetzung auf Vordermann gebracht. 2012-10-27 13:56:40 +02:00
Alex Schroeder
bcb9721499 New extension. 2012-10-27 13:28:13 +02:00
Alex Schroeder
609f037345 Added link to documentation online. 2012-10-27 12:55:30 +02:00
Alex Schroeder
4ed8c4fb25 Fixed whitespace when setting %Tex.
Made %Tex public so it can be used in a test.
2012-10-26 23:59:54 +02:00
Alex Schroeder
45ebd07cf4 testing encoding of the cookie 2012-10-26 16:46:18 +02:00
Alex Schroeder
51223c6297 Merge branch 'master' of git.sv.gnu.org:/srv/git/oddmuse 2012-10-26 16:39:37 +02:00
Alex Schroeder
08b7674ab4 Use decoded_content for HTTP::Response 2012-10-26 16:38:22 +02:00
Alex Schroeder
a8780e75f5 Also handles other parameter per feed, eg. ignore_in_feed = updated 2012-10-26 16:20:30 +02:00
Alex Schröder
dc43759ebd Many additions by Aurélien Desbrières. 2012-10-25 10:21:01 +02:00
Alex Schroeder
e8ba28bffe Merge branch 'master' of git.sv.gnu.org:/srv/git/oddmuse 2012-10-25 08:55:10 +02:00
Alex Schroeder
f3266288e1 Add module description. 2012-10-25 08:54:53 +02:00
Alex Schroeder
8482c47383 user tables without 4em margin 2012-10-23 19:30:30 -04:00
Alex Schroeder
1e4268597d no longer need to encode UTF-8 strings: it's the default 2012-10-22 11:28:26 -04:00
Alex Schroeder
dd05f824a8 Switch tex.pl to rules instead of macros. 2012-10-18 23:36:44 +02:00
Alex Schroeder
6b2d119481 Commented utf8::encode in DoTagsReindex
This was recommended by Erik on the wiki because he found Latin-1
encoded page names in the Tag DB.
2012-09-30 09:39:37 +02:00
Alex Schroeder
37bdb62db8 Added svg to $ImageExtensions.
Apparently this now works; I tested it on an up to date Firefox.
2012-08-18 12:03:29 +02:00
Alex Schroeder
30c5c3798f Use xpath to extract oldtime parameter.
The last change to GetHiddenValue changed the HTML output. Using XPath
will find the right parameter even if the order of the parameters
changed.
2012-08-15 19:32:10 +02:00
22 changed files with 915 additions and 355 deletions

View File

@@ -1,6 +1,6 @@
#!/usr/bin/perl
# Copyright (C) 2010 Alex Schroeder <alex@gnu.org>
# Copyright (C) 2010, 2012 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
@@ -17,6 +17,7 @@
package OddMuse;
use URI;
use LWP::UserAgent;
use utf8;
# load Oddmuse core
$RunCGI = 0;
@@ -61,16 +62,16 @@ sub parse_blogs {
return %cached_blogs if %cached_blogs;
my @data = split(/\n/, GetRaw($src));
my $url;
my $name;
my $paramref;
foreach $_ (@data) {
if (/^\[(.+)\]/) {
$url = $1;
$name = undef;
} elsif (/^name *= *(.+)/) {
$name = $1;
$paramref = {};
} elsif (/^([a-z_]+) *= *(.+)/) {
$paramref->{$1} = $2;
}
if ($url && $name) {
$cached_blogs{$url} = $name;
if ($url && $paramref->{name}) {
$cached_blogs{$url} = $paramref;
}
}
return %cached_blogs;
@@ -84,8 +85,16 @@ sub host_exists {
}
}
sub debug_url {
my $url = $q->url(-path_info=>1) . "?debug=1;";
$url .= join(";", map { $_ . "=" . GetParam($_) }
qw(username confirmed candidate url));
return $url;
}
sub check_url {
my $url = shift;
print $q->p("Debug: url=$url") if GetParam("debug");
my $frown = $q->img({-src=>"http://emacswiki.org/pics/smiles/sad.png",
-alt=>":("});
my $smile = $q->img({-src=>"http://emacswiki.org/pics/smiles/smile.png",
@@ -97,26 +106,24 @@ sub check_url {
$u = URI->new($url);
eval {$u->host };
}
# - not an url
# - it's campaign wiki site
# - no username
# or read Feeds page and
# - it's a duplicate
# - it's a partial match: continue with confirmed=1
# or read the list of alternatives from the url
# - one of the feeds listed is known: continue with confirmed=2
# - no feeds were listed: url is a feed or report it
# - one feed was listed: try it
# - some feeds were listed: pick one
if ($@) {
# the prefixing of http:// above should make it really hard to reach this code
print $q->p($q->a({-href=>$url}, $url) . qq{
seems to be <strong>invalid</strong>. $frown Make sure you use something
like the following: <tt>http://grognardia.blogspot.com/</tt>});
} elsif (not GetParam('username', '')) {
print $q->p(qq{As an anti-spam measure I'd really like you to <strong>provide a name</strong> for the log file. Sorry about that. $frown});
} else {
my %blogs = parse_blogs();
my $duplicate = host_exists($u->host, %blogs);
if ($duplicate
&& !$blogs{$url}
&& !GetParam('confirmed')) {
print $q->p("We have a partial match: ",
$q->a({-href=>$duplicate}, $duplicate));
print GetFormStart();
print $q->hidden('confirmed', 1);
print $q->hidden('url', $url);
print $q->submit('go', 'Proceed anyway!');
print $q->end_form();
} elsif ($url =~ /campaignwiki\.org/i) {
print $q->p(qq{
This looks <strong>familiar</strong>!
@@ -124,17 +131,35 @@ I do not think that adding any of the wikis on this site is the right
thing to do, though.});
print $q->p(qq{Thanks for testing it. }
. $q->img({-src=>"http://www.emacswiki.org/pics/grin.png"}));
} elsif (not GetParam('username', '')) {
print $q->p(qq{As an anti-spam measure I'd really like you to
<strong>provide a name</strong> for the log file. Sorry about that. $frown});
} else {
my %blogs = parse_blogs();
my $duplicate = host_exists($u->host, %blogs);
if ($blogs{$url}) {
print $q->p("We already list ",
$q->a({-href=>$duplicate}, $duplicate));
} elsif ($duplicate && !GetParam('confirmed')) {
print $q->p("We have a partial match: ",
$q->a({-href=>$duplicate}, $duplicate));
print GetFormStart();
print $q->hidden('confirmed', 1);
print $q->hidden('url', $url);
print $q->submit('go', 'Proceed anyway!');
print $q->end_form();
} else {
my @alternatives = get_feeds($url, keys %blogs);
if ($#alternatives > 0 && !GetParam('candidate')) {
my ($status, @alternatives) = get_feeds($url, %blogs);
if ($status eq 'known' && GetParam('confirmed') < 2) {
print $q->p($q->a({-href=>$url},
"The page you submitted")
. " lists "
. $q->a({-href=>$alternatives[0]},
"a known feed") . ".");
print GetFormStart();
print $q->hidden('confirmed', 1);
print $q->hidden('confirmed', 2);
print $q->hidden('url', $url);
print $q->p("You need to pick one of the candidates:");
print $q->p(join($q->br(), map {
$q->input({-type=>"radio", -name=>"candidate", -value=>$_},
$q->a({-href=>$_}, QuoteHtml($_))) } @alternatives));
print $q->submit('go', 'Submit');
print $q->submit('go', 'Proceed anyway!');
print $q->end_form();
} elsif ($#alternatives < 0) {
if (is_feed($url)) {
@@ -143,20 +168,31 @@ thing to do, though.});
print $q->p("Apparently " . $q->a({-href=>$url}, QuoteHtml($url))
. " is not a feed and doesn't link to any feed. "
. "There is nothing for me to add. " . $frown);
print $q->p("If you feel like it, you could try to "
. $q->a({-href=>debug_url()}, "debug")
. " this.");
}
} elsif ($#alternatives == 0) {
print $q->p($q->a({-href=>$url}, "The page you submitted")
. " lists "
. $q->a({-href=>$alternatives[0]},
"one new feed")
. ".");
print GetFormStart();
print $q->hidden('url', $alternatives[0]);
print $q->submit('go', 'Take it!');
print $q->end_form();
print $q->p("If you feel like it, you could try to "
. $q->a({-href=>debug_url()}, "debug")
. " this.");
} else {
my $candidate = GetParam('candidate');
$candidate = $alternatives[0] unless $candidate;
if (is_feed($candidate)) {
post_addition($candidate);
} else {
print $q->p($q->a({-href=>$candidate}, "The page you submitted")
. " listed "
. $q->a({-href=>$candidate}, QuoteHtml($candidate))
. " as one of its feeds. "
. "But it turns out that this is not a valid feed! "
. "I can't add an invalid feed. " . $frown);
}
print GetFormStart();
print $q->p("You need to pick one of the candidates:");
print $q->p(join($q->br(), map {
$q->input({-type=>"radio", -name=>"url", -value=>$_},
$q->a({-href=>$_}, QuoteHtml($_))) } @alternatives));
print $q->submit('go', 'Submit');
print $q->end_form();
}
}
}
@@ -172,23 +208,73 @@ sub is_feed {
sub get_feeds {
my $url = shift;
my %others = map { $_ => 1 } @_;
my @links = GetRaw($url) =~ /<link\b *(.*?)>/g;
my %others = @_;
my $html = GetRaw($url);
my @links = $html =~ /<link\b *(.*?)>/g;
print $q->p("Debug: " . scalar(@links) . " links found") if GetParam("debug");
print $q->pre($html) unless scalar(@links);
print $q->p("Debug: no content returned") if GetParam("debug") and not $html;
my @feeds;
foreach my $link (@links) {
my %link;
foreach (split(/ /, lc($link))) {
my ($attr, $val) = split(/=/, $_, 2);
# strip quotes and garbage: "foo"/ -> foo
my $to = index($val, substr($val, 0, 1), 1);
$val = substr($val, 1, $to -1) if $to >= 0;
$link{$attr} = $val;
print $q->p("Debug: $link")
if GetParam("debug");
if ($link !~ /\brel=(['"])alternate\1/i) {
print $q->p("Debug: missing rel='alternate'")
if GetParam("debug");
next;
}
next unless $link{rel} eq 'alternate';
next unless $valid_content_type{$link{type}};
push(@feeds, $link{href}) unless $others{$link{href}};
$link =~ /\btype=(['"])(.*?)\1/i;
my $type = $2;
if (not $valid_content_type{$type}) {
print $q->p("Debug: type parameter is invalid ($type)")
if GetParam("debug");
next;
}
$link =~ /\bhref=(['"])(.*?)\1/i;
my $href = $2;
# clean up blogspot urls and prefer atom format
$href =~ s/\?alt=rss$//i if $href =~ /blogspot/i;
if (not $href) {
print $q->p("Debug: href missing")
if GetParam("debug");
next;
}
if ($others{$href}) {
print $q->p("Debug: feed already known ($href)")
if GetParam("debug");
if ($q->param('confirmed') >= 2) {
next;
} else {
# don't look for other alternatives!
return 'known', $href;
}
}
push(@feeds, $href);
}
return @feeds;
print $q->p("Debug: returning " . scalar(@feeds) . " links found")
if GetParam("debug");
return 'ok', @feeds;
}
sub config {
my %blogs = @_;
my $result = qq{#! config file for the RPG Planet
# format:
# Feed URL in square brackets, followed by name = and the name of the feed
};
foreach my $url (sort {lc($blogs{$a}->{name}) cmp lc($blogs{$b}->{name})} keys %blogs) {
$result .= "[$url]\n";
$paramref = $blogs{$url};
foreach my $key (sort keys %{$paramref}) {
$result .= $key . " = " . $paramref->{$key} . "\n";
}
}
return $result;
}
sub post_addition {
@@ -206,14 +292,9 @@ sub post_addition {
$title = $final_url unless $title;
print $q->p("Adding ",
$q->a({-href=>$final_url}, $title));
$blogs{$url} = $title;
my $result = qq{#! config file for the RPG Planet
# format:
# Feed URL in square brackets, followed by name = and the name of the feed
};
foreach $url (sort {lc($blogs{$a}) cmp lc($blogs{$b})} keys %blogs) {
$result .= "[$url]\nname = " . $blogs{$url} . "\n";
}
my %param = (name => $title);
$blogs{$url} = \%param;
my $result = config(%blogs);
my $ua = LWP::UserAgent->new;
my %params = (text => $result,
title => $page,
@@ -250,16 +331,18 @@ sub main {
if ($q->path_info eq '/source') {
seek DATA, 0, 0;
print "Content-type: text/plain; charset=UTF-8\r\n\r\n", <DATA>;
} elsif ($q->path_info eq '/test') {
print "Content-type: text/plain; charset=UTF-8\r\n\r\n";
print config(parse_blogs());
} else {
$UserGotoBar .= $q->a({-href=>$q->url . '/source'}, 'Source');
print GetHeader('', 'Submit a new blog');
print $q->start_div({-class=>'content index'});
if (not GetParam('url')
or not GetParam($HoneyPotOk)) {
if (not GetParam('url')) {
print $q->p("Debug: no url parameter provided.") if GetParam("debug");
default();
} else {
SetParam('title', 'Feeds'); # required to trigger HoneyPotInspection()
HoneyPotInspection();
check_url(GetParam('url'));
}
print $q->p('Questions? Send mail to Alex Schröder <'

View File

@@ -149,9 +149,6 @@ div.refer {
line-height: 13pt;
}
div.refer a:first-child:before { content: "" }
div.refer a:before { content: "• " }
div.message {
background-color:#fee;
color:#000;

View File

@@ -179,7 +179,7 @@ div.rc hr { display: none; }
/* Tables */
table.user {
margin: 1em 4em;
margin: 1em 0;
padding: 0 1em;
border-top: 1px solid black;
border-bottom: 1px solid black;

View File

@@ -18,6 +18,8 @@
$ModulesDescription .= '<p><a href="http://git.savannah.gnu.org/cgit/oddmuse.git/tree/modules/canonical.pl">canonical.pl</a>, see <a href="http://www.oddmuse.org/cgi-bin/oddmuse/Canonical_Names">Canonical Names</a></p>';
use utf8;
*OldCanonicalResolveId = *ResolveId;
*ResolveId = *NewCanonicalResolveId;
@@ -39,14 +41,9 @@ sub NewCanonicalResolveId {
# If the page AlexSchröder exists, [[alexschroder]] will link to it.
use utf8;
use Encode;
sub CanonicalName {
my $str = shift;
$DebugInfo .= ' ' . $str;
$str = decode('utf-8', $str);
$str =~ tr/äáàâëéèêïíìîöóòôüúùû/aaaaeeeeiiiioooouuuu/;
$str = lc($str);
$DebugInfo .= '->' . $str;
return $str;
}

40
modules/fix-encoding.pl Normal file
View File

@@ -0,0 +1,40 @@
# Copyright (C) 2012 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/>.
$ModulesDescription .= '<p><a href="http://git.savannah.gnu.org/cgit/oddmuse.git/tree/modules/fix-encoding.pl">fix-encoding.pl</a>, see <a href="http://www.oddmuse.org/cgi-bin/oddmuse/Fix_Encoding">Fix Encoding</a></p>';
$Action{'fix-encoding'} = \&FixEncoding;
sub FixEncoding {
my $id = shift;
ValidIdOrDie($id);
RequestLockOrError();
OpenPage($id);
my $text = $Page{text};
utf8::decode($text);
Save($id, $text, 'fix encoding', 1) if $text ne $Page{text};
ReleaseLock();
ReBrowsePage($id);
}
push(@MyAdminCode, \&FixEncodingMenu);
sub FixEncodingMenu {
my ($id, $menuref, $restref) = @_;
if ($id) {
push(@$menuref,
ScriptLink('action=fix-encoding;id=' . UrlEncode($id), T('Fix page encoding')));
}
}

View File

@@ -376,7 +376,7 @@ sub NewNamespaceBrowsePage {
#REDIRECT into different namespaces
my ($id, $raw, $comment, $status) = @_;
OpenPage($id);
my ($text, $revision) = GetTextRevision(GetParam('revision', ''));
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)/)

139
modules/private-pages.pl Normal file
View File

@@ -0,0 +1,139 @@
# Copyright (C) 2012 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/>.
=head1 Private Pages Extension
This module allows you to hide the content of particular pages in Oddmuse.
Unlike the I<Hidden Pages Extension>, this is not based on the user's role of
editor or administrator. Instead, every page can have a different password by
beginning it with #PASSWORD XYZZY where XYZZY is the password required to read
it. Multiple passwords can be supplied, separated by spaces.
Note that all the meta information of the private page remains public: The
I<name> of the page, the fact that is has been edited, the author, the
revision, the content of past revisions that have not been protected by a
password all remain visible to other users.
Notes:
=over
=item * This extension might not work in a mod_perl environment because it
sets C<$NewText> without ever resetting it.
=item * If you're protecting a comment page, people can still leave comments
-- they just can't read the resulting page.
=back
=cut
$ModulesDescription .= '<p><a href="http://git.savannah.gnu.org/cgit/oddmuse.git/tree/modules/private-pages.pl">private-pages.pl</a>, see <a href="http://www.oddmuse.org/cgi-bin/oddmuse/Private_Pages_Extension">Private Pages Extension</a></p>';
sub PrivatePageLocked {
my $text = shift;
my ($line) = split(/\n/, $text, 1);
my @token = split(/\s+/, $line);
my $lock = 0;
if (shift(@token) eq '#PASSWORD') {
my $pwd = GetParam('pwd', '');
$lock = 1;
foreach (@token) {
if ($pwd eq $_) {
$lock = 0;
break;
}
}
}
return $lock;
}
*OldPrivatePagesUserCanEdit = *UserCanEdit;
*UserCanEdit = *NewPrivatePagesUserCanEdit;
sub NewPrivatePagesUserCanEdit {
my ($id, $editing, @rest) = @_;
my $result = OldPrivatePagesUserCanEdit($id, $editing, @rest);
# bypass OpenPage and GetPageContent (these are redefined below)
if ($result > 0 and $editing and $IndexHash{$id}) {
my %data = ParseData(ReadFileOrDie(GetPageFile($id)));
if (PrivatePageLocked($data{text})) {
return 0;
}
}
return $result;
}
sub PrivatePageMessage {
return Ts('This page is password protected. If you know the password, you can %s. Once you have done that, return and reload this page.',
'[' . ScriptUrl('action=password') . ' '
. T('supply the password now') . ']');
}
*OldPrivatePagesOpenPage = *OpenPage;
*OpenPage = *NewPrivatePagesOpenPage;
sub NewPrivatePagesOpenPage {
OldPrivatePagesOpenPage(@_);
if (PrivatePageLocked($Page{text})) {
%Page = (); # reset everything
$NewText = PrivatePageMessage();
}
return $OpenPageName;
}
*OldPrivatePagesGetPageContent = *GetPageContent;
*GetPageContent = *NewPrivatePagesGetPageContent;
sub NewPrivatePagesGetPageContent {
my $text = OldPrivatePagesGetPageContent(@_);
if (PrivatePageLocked($text)) {
return PrivatePageMessage();
}
return $text;
}
*OldPrivatePagesGetTextRevision = *GetTextRevision;
*GetTextRevision = *NewPrivatePagesGetTextRevision;
sub NewPrivatePagesGetTextRevision {
my ($text, $revision) = OldPrivatePagesGetTextRevision(@_);
if (PrivatePageLocked($text)) {
return (PrivatePageMessage(), $revision);
}
return ($text, $revision);
}
push(@MyRules, \&PrivatePageRule);
sub PrivatePageRule {
if (pos == 0 && m/\G#PASSWORD.*\n/gc) {
return '';
}
return undef;
}
*OldPrivatePagesGetSummary = *GetSummary;
*GetSummary = *NewPrivatePagesGetSummary;
sub NewPrivatePagesGetSummary {
my $text = GetParam('text', '');
if ($text and $text =~ /^#PASSWORD\b/
# no text means aftertext is set (leaving a comment)
or $Page{text} =~ /^#PASSWORD\b/) {
# if no summary was set, set something in order to avoid the default
return '';
}
return OldPrivatePagesGetSummary();
}

View File

@@ -178,8 +178,8 @@ sub UpdateReferers {
}
my $ua = LWP::UserAgent->new;
my $response = $ua->get($referer);
return unless $response->is_success and $response->content =~ /$self/;
my $title = PageContentToTitle($response->content);
return unless $response->is_success and $response->decoded_content =~ /$self/;
my $title = PageContentToTitle($response->decoded_content);
# starting with a timestamp makes sure that numerical comparisons still work!
$Referers{$referer} = "$Now $title";
return 1;

View File

@@ -352,7 +352,8 @@ sub DoTagsReindex {
$Page{text} =~ m/\[\[tag:$FreeLinkPattern\|([^]|]+)\]\]/g);
next unless %tag;
utf8::encode($id); # back to bytes for the following installation:
# utf8::encode($id);
# back to bytes for the following installation:
# This is perl, v5.10.1 (*) built for i486-linux-gnu-thread-multi
# (with 56 registered patches, see perl -V for more detail)
# (FIXME: get rid of this call, or explain why no UTF-8 can be stored in %h)

View File

@@ -1,8 +1,8 @@
# Copyright (C) 2006 Alex Schroeder <alex@emacswiki.org>
# Copyright (C) 2006, 2012 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 2 of the License, or
# 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,
@@ -11,17 +11,14 @@
# 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
# along with this program. If not, see <http://www.gnu.org/licenses/>.
$ModulesDescription .= '<p><a href="http://git.savannah.gnu.org/cgit/oddmuse.git/tree/modules/tex.pl">tex.pl</a></p>';
$ModulesDescription .= '<p><a href="http://git.savannah.gnu.org/cgit/oddmuse.git/tree/modules/tex.pl">tex.pl</a>, see <a href="http://www.oddmuse.org/cgi-bin/oddmuse/TeX_Extension">TeX Extension</a></p>';
use vars qw($TeXInit);
use vars qw($TeXInit %Tex);
use utf8;
my %h = qw( !` ¡ {\pounds} £ \pounds £ {\S} § \S § \"{} ¨ {\copyright} ©
%Tex = qw( !` ¡ {\pounds} £ \pounds £ {\S} § \S § \"{} ¨ {\copyright} ©
\copyright © $^a$ ª \={} ¯ $\pm$ ± \pm ± $^2$ ² $^3$ ³ \'{} ´ {\P} ¶
\P ¶ $\cdot$ · \cdot · \c{} ¸ $^1$ ¹ $^o$ º ?` ¿ \`{A} À \`A À \'{A} Á
\'A Á \^{A} Â \^A Â \~{A} Ã \~A Ã \"{A} Ä \"A Ä \k{A} Ą {\AA} Å \AA Å
@@ -155,17 +152,27 @@ _0 ₀ _1 ₁ _2 ₂ _3 ₃ _4 ₄ _5 ₅ _6 ₆ _7 ₇ _8 ₈ _9 ₉ _= ₌ \~
\varpropto ∝ \varrho ϱ \varsigma ς \vartheta ϑ \vartriangleleft ⊲
\vartriangleright ⊳ \vdash ⊢ \vdots ⋮ \vee \veebar ⊻ \vert | \wedge
∧ \wp ℘ \wr ≀ \xi ξ \zeta ζ \Bbb{N} \Bbb{P} \Bbb{R} \Bbb{Z} --
--- — ~ \mu μ \rho ρ \mathscr{I} \Smiley ☺ \blacksmiley ☻
--- — \mu μ \rho ρ \mathscr{I} \Smiley ☺ \blacksmiley ☻
\Frowny ☹ \Letter ✉ \permil ‰ \registered ® \currency ¤ \dh ð \DH Ð
\th þ \TH Þ \micro µ \lnot ¬ \ordfeminine ª \ordmasculine º \lambdabar
ƛ \celsius ℃ \ldq “ \rdq ” \minus \defs ≙ \llbracket 〚 \rrbracket 〛
\ldata 《\rdata 》\glq \grq \glqq „ \"` „ \grqq “ \"' “ \flq
\ldata 《 \rdata 》 \glq \grq \glqq „ \"` „ \grqq “ \"' “ \flq
\frq \flqq « \"< « \frqq » \"> » \- ­ \textmu µ \textfractionsolidus
\textbigcircle ⃝ \textmusicalnote ♪ \textdied ✝ \textcolonmonetary ₡
\textwon ₩ \textnaira ₦ \textpeso ₱ \textlira ₤ \textrecipe ℞
\textinterrobang ‽ \textpertenthousand ‱ \textbaht ฿ \textnumero №
\textdiscount ⁒ \textestimated \textopenbullet ◦ \textlquill ⁅
\textrquill ⁆ \textcircledP ℗ \textreferencemark ※ );
$Tex{'~'} = ' ';
my $re = '(' . join('|', map {quotemeta} keys %h) . ')(\s|\b)';
push(@MyMacros, sub {s/$re/$h{$1}/go});
my $TexRe = '(' . join('|', map {quotemeta} sort { $b cmp $a } keys %Tex) . ')';
$TexRe = qr{$TexRe};
push(@MyRules, \&TexRule);
sub TexRule {
if (m/\G$TexRe/goc) {
return $Tex{$1};
}
return undef;
}

View File

@@ -13,6 +13,8 @@
# You should have received a copy of the GNU General Public License along with
# this program. If not, see <http://www.gnu.org/licenses/>.
$ModulesDescription .= '<p><a href="http://git.savannah.gnu.org/cgit/oddmuse.git/tree/modules/translation-links.pl">translation-links.pl</a>, see <a href="http://www.oddmuse.org/cgi-bin/oddmuse/Translation_Links">Translation Links</a></p>';
=head1 Translation Links
This package allows Oddmuse to support translation links.
@@ -198,9 +200,13 @@ sub DoTranslationLink {
}
print $q->p($q->label({-for=>'target'}, T('Translated page: ')),
$q->textfield('target', '', 40),
$q->hidden('action', 'translate'),
$q->hidden('id', $source),
$q->hidden('missing', GetParam('missing', '')),
# don't use $q->hidden or you'll get encoding errors
$q->input({-type=>'hidden', -name=>'id',
-value=>$source}),
$q->input({-type=>'hidden', -name=>'action',
-value=>'translate'}),
$q->input({-type=>'hidden', -name=>'missing',
-value=>GetParam('missing', '')}),
$q->submit('dotranslate', T('Go!')));
print $q->endform, $q->end_div();
PrintFooter();

View File

@@ -1,3 +1,25 @@
# UTF-8 encoded Bulgarian translation file for use with Oddmuse
#
# Copyright (c) 2004 Stanislav Traykov <stanislav@tortoises.org>
# Copyright (c) 2003, 2004 Alex Schröder <alex@emacswiki.org>
#
# Permission is granted to copy, distribute and/or modify this
# document under the terms of the GNU Free Documentation License,
# Version 1.2 or any later version published by the Free Software
# Foundation; with no Invariant Sections, no Front-Cover Texts, and no
# Back-Cover Texts. A copy of the license could be found at:
# http://www.gnu.org/licenses/fdl.txt .
#
# Installation:
# =============
#
# Create a modules subdirectory in your data directory, and put the
# file in there. It will be loaded automatically.
#
# This translation was updated for Oddmuse 1.354.
#
use utf8;
$ModulesDescription .= '<p><a href="http://git.savannah.gnu.org/cgit/oddmuse.git/tree/modules/translations/bulgarian-utf8.pl">bulgarian-utf8.pl</a>, see <a href="http://www.oddmuse.org/cgi-bin/oddmuse/Bulgarian">Bulgarian</a></p>';
%Translate = split(/\n/,<<END_OF_TRANSLATION);
Include normal pages

View File

@@ -1,3 +1,25 @@
# UTF-8 encoded Traditional Chinese language file for use with Oddmuse
#
# Copyright (c) 2003, 2004 wctang <wctang@csie.nctu.edu.tw>
# Copyright (c) 2007 Wei Ren Wang <weithenn@gmail.com>
#
# Permission is granted to copy, distribute and/or modify this
# document under the terms of the GNU Free Documentation License,
# Version 1.2 or any later version published by the Free Software
# Foundation; with no Invariant Sections, no Front-Cover Texts, and no
# Back-Cover Texts. A copy of the license could be found at:
# http://www.gnu.org/licenses/fdl.txt.
#
# Installation:
# =============
#
# Create a modules subdirectory in your data directory, and put the
# file in there. It will be loaded automatically.
#
# This translation was last checked for Oddmuse version 1.504.
#
use utf8;
$ModulesDescription .= '<p><a href="http://git.savannah.gnu.org/cgit/oddmuse.git/tree/modules/translations/chinese-utf8.pl">chinese-utf8.pl</a>, see <a href="http://www.oddmuse.org/cgi-bin/oddmuse/Chinese">Chinese</a></p>';
%Translate = split(/\n/,<<END_OF_TRANSLATION);
Include normal pages
包含正常頁面

View File

@@ -3,6 +3,8 @@
# Copyright (c) 2003, 2005 Pierre Gaston
# Copyright (c) 2004, 2005 Christophe Ducamp
# Copyright (c) 2010 Alex Schroeder
# Copyright (c) 2012 Aurélien Desbrières
# Copyright (c) 2012 Hervé Robin
#
# Permission is granted to copy, distribute and/or modify this
# document under the terms of the GNU Free Documentation License,
@@ -17,10 +19,12 @@
# Create a modules subdirectory in your data directory, and put the
# file in there. It will be loaded automatically.
#
# This translation was last checked for Oddmuse version 1.296.
#
# This translation was last checked for Oddmuse 2.2.
use utf8;
$ModulesDescription .= '<p><a href="http://git.savannah.gnu.org/cgit/oddmuse.git/tree/modules/translations/french-utf8.pl">french-utf8.pl</a>, see <a href="http://www.oddmuse.org/cgi-bin/oddmuse/French">French</a></p>';
%Translate = split(/\n/,<<END_OF_TRANSLATION);
Include normal pages
Comprend les pages normales
@@ -31,9 +35,9 @@ Se connecter
Error
Erreur
%s calls
%s appel
Could not create %s
Création impossible de %s
Création de %s impossible
Invalid UserName %s: not saved.
Nom dutilisateur non valide %s : non sauvegardé.
UserName must be 50 characters or less: not saved
@@ -87,13 +91,13 @@ Page non valide %s
Too many redirections
Trop de redirections
No redirection for old revisions
Pas de redirection pour les versions ancienne
Pas de redirection pour les versions anciennes
Invalid link pattern for #REDIRECT
Mise en forme invalide pour le lien de redirection (#REDIRECT)
Syntaxe invalide pour le lien de redirection (#REDIRECT)
Please go on to %s.
SVP aller a %s.
SVP allez à %s.
Updates since %s
Mises à hour depuis %s
Mises à jour depuis %s
up to %s
jusquà
Updates in the last %s days
@@ -109,7 +113,7 @@ Lister toutes les modifications
Skip rollbacks
Sans les retours en arrière
Include rollbacks
Incluant les retours en arrière
Inclure les retours en arrière
List only major changes
Lister seulement les modifications majeures
Include minor changes
@@ -117,7 +121,7 @@ Inclure les modifications mineures
%s days
%s jours
List later changes
Lister les modifications les plus récentes
Lister les modifications plus récentes
RSS
RSS
RSS with pages
@@ -151,15 +155,15 @@ Tous les changements pour %s
from %s
depuis %s
This page is too big to send over RSS.
Cette page est trop grosse pour être envoyée sur RSS
Cette page est trop grande pour être envoyée sur RSS
History of %s
Historique de %s
Compare
Comparer
Deleted
Suprimé
Supprimé(e)
Mark this page for deletion
Marquer cette page à suprimer
Marquer cette page comme étant à supprimer
No other revisions available
Il ny a pas dautre version
current
@@ -173,15 +177,15 @@ Cible manquante pour le retour en arrière.
Target for rollback is too far back.
La cible du retour en arrière est trop ancienne.
A username is required for ordinary users.
Un nom dutilisateur est nécessaire pour les utilisateurs communs
Un nom dutilisateur est nécessaire pour les utilisateurs normaux
Rolling back changes
Réinitialisation en cours
The two revisions are the same.
Les deux révisions sont les mêmes.
Les deux versions sont identiques.
Editing not allowed for %s.
Edition non autorisée pour %s.
Modification non autorisée pour %s.
Rollback of %s would restore banned content.
Un retour à %s restaurara du texte interdit.
Un retour à %s restaurera du contenu interdit.
Rollback to %s
Retour à %s
%s rolled back
@@ -193,13 +197,13 @@ Index de toutes les pages
Wiki Version
Affiche la version du wiki
Unlock Wiki
Supression du verrou
Suppression du verrou
Password
Mot de passe
Run maintenance
Lancer la maintenance
Unlock site
Déverouiller le site
Déverrouiller le site
Lock site
Verouiller le site
Install CSS
@@ -215,11 +219,11 @@ Actions :
Important pages:
Pages importantes :
To mark a page for deletion, put <strong>%s</strong> on the first line.
Pour marquer une page devant être supprimée, ajoutez <strong>%s</strong> à la première ligne
Pour marquer une page comme étant à supprimer, ajoutez <strong>%s</strong> à la première ligne
[Home]
[Accueil]
redirected from %s
redirigée à partir de %s
redirigé(e) à partir de %s
%s:
%s :
Click to search for references to this page
@@ -241,7 +245,7 @@ La base de données est stockée dans le répertoire temporaire %s
Last edited
Dernière modification
Edited
Modifié
Modifié(e)
by %s
par %s
(diff)
@@ -259,9 +263,9 @@ Voir la version actuelle
View all changes
Voir toutes les modifications
View contributors
Vour les contributeurs
Voir les contributeurs
Homepage URL:
Adresse(URL) du site perso
Adresse(URL) du site personnel
s
s
Save
@@ -277,7 +281,7 @@ f
Replace:
Remplacer :
Delete
Suprimer
Supprimer
Validate HTML
Valider HTML
Validate CSS
@@ -285,11 +289,11 @@ Valider CSS
Last edit
Dernière modification
Difference between revision %1 and %2
Différence (de la révision %1 à %2)
Différence entre les versions %1 et %2
revision %s
révision %s
version %s
current revision
révision actuelle
version actuelle
Last major edit (%s)
Dernière modification majeure (%s)
later minor edits
@@ -299,17 +303,17 @@ Pas de diff disponible.
Old revision:
Ancienne révision :
Changed:
Modifiée :
Modifié(e) :
Deleted:
Suprimé :
Supprimé(e) :
Added:
Ajoutée :
Ajouté(e) :
to
à
Revision %s not available
La version %s nest pas disponible
showing current revision instead
présentation à la place de la version en cours.
présentation à la place de la version en cours
Showing revision %s
Présentation de la version %s
Cannot save a nameless page.
@@ -327,11 +331,11 @@ Ne peut obtenir un verrouillage %s
The lock was created %s.
Le verrouillage a été créé %s.
Maybe the user running this script is no longer allowed to remove the lock directory?
Peut-être lutilisateur éxecutant le logiciel nest plus autorisé à effacer le répertoire utilisé pour le verrouillage ?
Peut-être lutilisateur exécutant le logiciel nest-il plus autorisé à effacer le répertoire utilisé pour le verrouillage ?
This operation may take several seconds...
Cette opération peut prendre quelques secondes...
Forced unlock of %s lock.
Supression forcée du verrou %s.
Suppression forcée du verrou %s.
No unlock required.
La suppression du verrou nest pas nécessaire.
%s hours ago
@@ -351,11 +355,11 @@ just now
Edit Denied
Modification interdite
Editing not allowed: user, ip, or network is blocked.
Modification interdite : lutilisateur, ladresse ip, ou le reseau est bloqué.
Modification interdite : lutilisateur, ladresse ip, ou le réseau est bloqué.
Contact the wiki administrator for more information.
Contactez ladministrateur du wiki pour plus dinformation.
The rule %s matched for you.
La règle %s a fonctionné pour vous.
La règle %s a été appliquée pour vous.
See %s for more information.
Voir %s pour plus dinformation.
Editing not allowed: %s is read-only.
@@ -375,7 +379,7 @@ Résumé :
This change is a minor edit.
Cette modification est une édition mineure.
Cancel
Anuler
Annuler
Replace this file with text
Remplacer ce fichier par un texte
Replace this text with a file
@@ -393,7 +397,7 @@ Vous êtes actuellement éditeur de ce site.
You are a normal user on this site.
Vous êtes un utilisateur normal de ce site.
Your password does not match any of the administrator or editor passwords.
Vote mot de passe ne corespond à aucun de ceux des mots de passe administrateurs ou éditeurs.
Vote mot de passe ne correspond ni au mot de passe administrateur ni au mot de passe éditeur.
Password:
Mot de passe :
This site does not use admin or editor passwords.
@@ -411,7 +415,7 @@ La règle "%1" correspondait à "%2" sur cette page.
Reason: %s.
Raison : %s.
Reason unknown.
Raison inconnu.
Raison inconnue.
Filter:
Filtre :
(for %s)
@@ -419,9 +423,9 @@ Filtre :
%s pages found.
%s pages trouvées.
Malformed regular expression in %s
Expression régulière malformé dans %s
Expression rationnelle mal formulée dans %s
Replaced: %s
Remplacé : %s
Remplacé(e) : %s
Search for: %s
Rechercher : %s
View changes for these pages
@@ -433,9 +437,9 @@ par
Transfer Error: %s
Erreur de Transfert : %s
Browser reports no file info.
Le navigateur signale pas dinformation sur le fichier.
Le navigateur ne signale pas dinformation sur le fichier.
Browser reports no file type.
Le navigateur signale pas de format de fichier.
Le navigateur ne signale pas de type de fichier.
The page contains banned text.
Cette page contient un texte interdit.
No changes to be saved.
@@ -449,7 +453,7 @@ SVP vérifiez si vous avez écrasé ces modifications.
Anonymous
Anonyme
Cannot delete the index file %s.
Impossible de supprimer le fichier index %s.
Impossible de supprimer le fichier index %s.
Please check the directory permissions.
Veuillez vérifier les permissions des répertoires.
Your changes were not saved.
@@ -473,11 +477,11 @@ Enlevez le fichier "maintain" ou patientez.
Expiring keep files and deleting pages marked for deletion
Expiration des fichiers de cache et suppression des pages marquées pour la suppression
not deleted:
non supprimée :
non supprimé(e) :
deleted
supprimé
supprimé(e)
Moving part of the %s log file.
Deplace une partie du fichier de log %s.
Déplace une partie du fichier de log %s.
Could not open %s log file
Impossible douvrir le fichier de log %
Error was
@@ -507,15 +511,15 @@ Trop de connexions par %s
Please do not fetch more than %1 pages in %2 seconds.
Veuillez ne pas télécharger plus de %1 pages toutes les %2 secondes
Check whether the web server can create the directory %s and whether it can create files in it.
Verifiez si le serveur web peut créer le répertoire %s et sil peut créer des fichiers dedans.
Vérifiez si le serveur web peut créer le répertoire %s et sil peut créer des fichiers dedans.
Copy one of the following stylesheets to %s:
Copier une des feuilles de style suivantes sur %s.
Deleting %s
Supression de %s
Suppression de %s
Deleted %s
%s supprimée
%s supprimé(e)
Renaming %1 to %2.
Change %1 en %2.
Renomme %1 en %2.
The page %s does not exist
La page %s n'existe pas
The page %s already exists
@@ -523,15 +527,15 @@ La page %s existe déjà
Cannot rename %1 to %2
Impossible de renommer %1 en %2
Renamed to %s
Renommé en %s
Renommé(e) en %s
Renamed from %s
Renommé à partir de %s
Renommé(e) à partir de %s
Renamed %1 to %2.
%1 a été renommée en %2.
%1 a été renommé(e) en %2.
Immediately delete %s
Supprimer immédiatement %s
Rename %s to:
Renommer %s en :
Renommer %s en :
Learn more...
En savoir plus...
Complete Content
@@ -539,17 +543,17 @@ Contenu Complet
The main page is %s.
La page principale est %s.
Archive:
Archive :
Rebuild BackLink database
Rebâtir les liens de la base de données
Internal Page:
Page Interne :
Pages that link to this page
Pages liées à cette page
The search parameter is missing.
Le paramètre de recherche est manquant
Pages link to %s
Pages liées à %s
Cannot highlight the language %s.
Impossible de surligner la langue %s.
Recent Visitors
@@ -587,33 +591,33 @@ Ve
Sa
Sa
January
Janvier
janvier
February
Février
février
March
Mars
mars
April
Avril
avril
May
Mai
mai
June
Juin
juin
July
Juillet
juillet
August
Août
août
September
Septembre
septembre
October
Octobre
octobre
November
Novembre
novembre
December
Décembre
décembre
set %s
paramétrer %s
unset %s
dé-paramétrer %s
Clustermap
Carte du Faisceau
Pages without a Cluster
@@ -627,85 +631,85 @@ Compilation pour %s
Compilation tag is missing a regular expression.
Une expression régulière manque au tag de compilation.
Extract all dates from the database
Extraire toutes les dates depuis la base de données
Dates
Dates
No dates found.
Aucune date trouvée
Inter links:
InterLiens :
InterLiens :
List spammed pages
Lister les pages spammées
Despamming pages
Suppression des textes indésirables sur les pages.
Spammed pages
Pages spammées
Cannot find revision %s.
Impossible de trouver la version %s.
Revert to revision %1: %2
Retour à la version %1 : %2
Retour à la version %1 : %2
Marked as %s.
Marqué comme %s.
Marqué(e) comme %s.
Cannot find unspammed revision.
Impossible de trouver une version sans texte indésirable.
Recover Draft
Récupérer le brouillon
No text to save
Aucun texte à sauvegarder
Draft saved
Brouillon sauvegardé
Draft recovered
Brouillon récupéré
No draft available to recover
Aucun brouillon à récupérer
Save Draft
Sauvegarder le Brouillon
Draft Cleanup
Nettoyer le Brouillon
%1 was last modified %2 and was kept
%1 a été modifié(e) en dernier et %2 a été conservé(e)
%1 was last modified %2 and was deleted
%1 a été modifié(e) en dernier et %2 a été effacé(e)
Unable to delete draft %s
Impossible d'effacer le brouillon %s
Add Comment
Ajouter Commentaire
Ajouter un commentaire
ordinary changes
modifications ordinaires
Matching page names:
Pages correspondant aux noms :
Email:
Email :
E-mail :
Could not find %1.html template in %2
Impossible de trouver le modèle %1.html dans %2
Only Editors are allowed to see this hidden page.
Seuls les Editeurs ont l'autorisation de voir cette page cachée.
Seuls les Éditeurs ont l'autorisation de voir cette page cachée.
Only Admins are allowed to see this hidden page.
Seuls les Administrateurs ont l'autorisation de voir cette page cachée.
Index
Index
Languages:
Langues :
Langues :
Show!
Voir !
Voir !
Define
Définir
Full Link List
Liste Complète des Liens
List of locked pages
Liste des pages verrouillées
Pages tagged with %s
Pages taguées avec %s
Template without parameters
Gabarit sans paramètres
Modèle sans paramètres
The template %s is either empty or does not exist.
Le gabarit %s est soit vide soit n'existe pas.
Le modèle %s est soit vide soit n'existe pas.
-- defined on %s
-- défini sur %s
-- défini(e) sur %s
Local names defined on %1: %2
Noms locaux définis sur %1 : %2
Locked Pages
Pages Verrouillées
Register for %s
Enregistrer pour %s
Please choose a username of the form "FirstLast" using your real name.
@@ -723,7 +727,7 @@ Votre enregistrement pour %s a été soumis.
Please allow time for the webmaster to approve your request.
SVP accordez un peu de temps au webmestre pour valider votre demande.
An email has been sent to "%s" with further instructions.
Un email a été envoyé à "%s" pour de plus amples instructions.
Un e-mail a été envoyé à "%s" pour de plus amples instructions.
There was an error saving your registration.
Il y a eu une erreur au moment de sauvegarder votre enregistrement.
An account was created for %s.
@@ -733,23 +737,23 @@ Se connecter sur %s
Username and/or password are incorrect.
Le nom d'utilisateur et/ou le mot de passe sont incorrects.
Logged in as %s.
Connecté sous %s.
Connecté(e) sous %s.
Logout of %s
Déconnexion de %s
Logout of %s?
Déconnexion de %s ?
Déconnexion de %s ?
Logged out of %s
Déconnecté de %s
Déconnecté(e) de %s
You are now logged out.
Vous êtes maintenant déconnecté.
Vous êtes maintenant déconnecté(e).
Register a new account
Enregistrer un nouveau compte.
Logout
Se déconnecter
Who am I?
Qui suis-je ?
Qui suis-je ?
Forgot your password?
Mot de passe oublié ?
Mot de passe oublié ?
Change your password
Changer votre mot de passe
Approve pending registrations
@@ -759,17 +763,17 @@ Confirmation d'Enregistrement pour %s
%s, your registration has been approved. You can now use your password to login and edit this wiki.
%s, votre enregistrement a été accepté. Vous pouvez désormais utiliser votre mot de passe pour vous connecter et éditer ce wiki.
Confirmation failed. Please email %s for help.
Echec sur la confirmation. SVP envoyez un email à %s pour de l'aide.
Échec sur la confirmation. SVP envoyez un e-mail à %s pour obtenir de l'aide.
Who Am I?
Qui suis-je ?
Qui suis-je ?
You are logged in as %s.
Vous êtes connecté en tant que %s.
Vous êtes connecté(e) en tant que %s.
You are not logged in.
Vous n'êtes pas connecté.
Vous n'êtes pas connecté(e).
Reset Password
Réinitialiser le mot de passe.
The password for %s was reset. It has been emailed to the address on file.
Le mot de passe pour %s a été réinitialisé. Il a été envoyé à l'adresse sur le fichier.
Le mot de passe pour %s a été réinitialisé. Il a été envoyé à l'adresse spécifiée sur le fichier.
There was an error resetting the password for %s.
Il y a eu une erreur de réinitialisation du mot de passe pour %s.
The username "%s" does not exist.
@@ -777,11 +781,11 @@ Le nom d'utilisateur "%s" n'existe pas.
Reset Password for %s
Réinitialiser le mot de passe pour %s
Reset Password?
Réinitialisation Mot de Passe ?
Réinitialisation du Mot de Passe ?
Change Password for %s
Modification Mot de Passe pour %s
Modification du Mot de Passe pour %s
Change Password?
Modification Mot de Passe ?
Modification du Mot de Passe ?
Your current password is incorrect.
Votre Mot de Passe est incorrect.
Your password has been changed.
@@ -789,9 +793,9 @@ Votre mot de passe a été modifié.
Approve Pending Registrations for %s
Accepter les Enregistrements en Attente pour %s
%s has been approved.
%s a été accepté.
%s a été accepté(e).
There was an error approving %s.
Il y a eu une erreur à accepter %s.
Il y a eu une erreur en acceptant %s.
<ul>
<ul>
<li>%1 - %2</li>
@@ -803,15 +807,15 @@ Il n'y a pas d'enregistrements en attente.
Invalid Mail %s: not saved.
Ladresse e-mail %s nest pas valide
unsubscribe
désabonner
se désabonner
subscribe
abonner
s'abonner
%s appears to be an invalid mail address
Ladresse e-mail %s nest pas valide
Your mail subscriptions
Vôtre abonnements
Votre abonnements
All mail subscriptions
Tous les abonnements
Tous les abonnements e-mail
Subscriptions
Abonnements
Show
@@ -819,7 +823,7 @@ Voir
Subscriptions for %s:
Abonnements pour %s :
Unsubscribe
Désabonner
Se désabonner
There are no subscriptions for %s.
Il ny a pas dabonnements pour %s.
Change email address
@@ -827,45 +831,45 @@ Changer ladresse e-mail
Mail addresses are linked to unsubscription links.
Les adresses e-mail sont liées au désabonnement.
Subscribe to %s.
Abonner %s.
S'abonner %s.
Subscribe
Abonner
S'abonner
Subscribed %s to the following pages:
%s est abonné aux pages suivantes :
The remaining pages do not exist.
Les pages restantes nexistent pas (ou plus).
Unsubscribed %s from the following pages:
%s a désabonné les pages suivantes :
%s est désabonné aux pages suivantes :
You linked more than %s times to the same domain. It would seem that only a spammer would do this. Your edit is refused.
Vous avez créé plus de %s liens vers le même domaine. Il semble que seuls les spammeurs font cela. Votre édition est donc refusée.
%s is not a legal name for a namespace
%s nest pas un nom valide pour un espace de noms
Namespaces
Espace de noms
Espaces de noms
Getting page index file for %s.
Récupération du fichier d'index de %s.
Near links:
Liens de proximité :
Liens de proximité :
Search sites on the %s as well
Rechercher aussi les sites présents sur %s
Fetching results from %s:
Récupération des résultats à partir de %s :
Récupération des résultats à partir de %s :
Near pages:
Pages à proximité :
Pages à proximité :
Include near pages
Inclure les pages de proximité
EditNearLinks
EditerLiensDeProximité
ÉditerLiensDeProximité
The same page on other sites:
La même page sur d'autres sites :
La même page sur d'autres sites :
(create locally)
(créer localement)
image
image
download
télécharger
Backlinks
Liens en retour
Clearing Cache
Nettoyage du cache.
Done.
@@ -881,7 +885,7 @@ Aucune page id pour actionner la carte locale
Requested page %s does not exist
La page demandée %s n'existe pas
Local Map for %s
CarteLocale pour %s
Carte Locale pour %s
view
voir
Self-ban by %s
@@ -889,23 +893,23 @@ Auto-bannissement par %s
You have banned your own IP.
Vous avez banni votre propre IP.
OpenID Login
Identification OpenID
Your identity is saved in a cookie, if you have cookies enabled. Cookies may get lost if you connect from another machine, from another account, or using another software.
Votre identité est sauvegardée dans un cookie, si vous avez activé les cookies. Vos cookies seront perdus si vous vous connectez depuis une autre machine, sur un autre compte ou si vous utilisez un autre navigateur.
Your homepage is set to %s.
Votre page d'accueil est établie sur %s.
You have no homepage set.
Votre page d'acceuil n'est pas établie.
Homepage:
Page d'accueil :
Homepage is missing
La page d'accueil est manquante
OpenID error %s
Erreur OpenID %s
Orphan List
Liste Orpheline
Trail:
Trace :
Trace :
None
Aucune
Type
@@ -915,9 +919,9 @@ Lien permanent vers "%s"
anchor first defined here: %s
première ancre définie ici : %s
the page %s also exists
la page %s existe aussi
la page %s existe également
There was an error generating the pdf for %s. Please report this to webmaster, but do not try to download again as it will not work.
Il y a eu une erreur en générant le pdf pour %s. SVP, rendez-compte de cela au webmestre, mais n'essayez pas de télécharger à nouveau, car cela ne fonctionnera pas.
Il y a eu une erreur en générant le pdf pour %s. SVP, rendez compte de cela au webmestre, mais n'essayez pas de télécharger à nouveau, car cela ne fonctionnera pas.
Someone else is generating a pdf for %s. Please wait a minute and then try again.
Quelqu'un d'autre est en train de générer un pdf pour %S. SVP, attendez une minute puis essayez de nouveau.
Download this page as PDF
@@ -931,23 +935,23 @@ Portrait
Publish %s
Publier %s
No target wiki was specified in the config file.
La cible du wiki n'est pas spécifiée dans le fichier de configuration.
The target wiki was misconfigured.
La cible du wiki a été mal configurée.
Upload is limited to %s bytes
Le téléversement est limité à %s bytes
You did not answer correctly.
Vous navez pas répondu correctement.
To save this page you must answer this question:
Il faut réponder a cette question pour sauvegarder la page :
Vous devez répondre à cette question pour sauvegarder la page :
Please type the following two words:
Tapez s'il vous plaît les deux mots suivants :
Please answer this captcha:
Répondez à ce captcha s'il vous plaît :
Referrers
Introducteurs
Référants
All Referrers
Tous les Introducteurs
Tous les Référants
Tag
Tag
Rebuild index for searching
@@ -957,55 +961,55 @@ Nuage de Tags
Search::FreeText is not available on this system.
Search::FreeText n'est pas disponible sur ce système.
Rebuilding index not done.
Reconstruction index non effectuée.
Reconstruction de l'index non effectuée.
(Rebuilding the index can only be done once every 12 hours.)
(La reconstruction de l'index ne peut être faite qu'une fois toutes les 12 heures.)
(La reconstruction de l'index ne peut être effectuée qu'une fois toutes les 12 heures.)
New Pages for Indexed Search
Nouvelle pages pour indexer la recherche
List changes since %s
Changement depuis %s
Changements dans la liste depuis %s
...
...
Search term missing.
Terme de la recherche manquant.
Result pages:
Pages de résultats :
Pages de résultats :
(%s results)
(%s résultats)
Tags:
Tags :
Tags: %s.
Tags : %s
No tags
Pas de tags
Page list for %s
Liste des pages pour %s
Slideshow:%s
Diaporama : %s
Diaporama : %s
Index of all small pages
Index de toutes les pages de petite taille
Static Copy
Copie Statique
Back to %s
Retour à %s
Edit image in the browser
Éditer l'image dans le navigateur
Summary of your changes:
Résumé de tous vos changements :
Copy to %1 succeeded: %2.
Copie vers %1 réussie : %2.
Copie vers %1 réussie : %2.
Copy to %1 failed: %2.
Copie vers %1 échouée : %2.
Copie vers %1 échouée : %2.
Feed for this tag
Flux pour ce tag
Rebuild tag index
Rebâtir votre index de tags
list tags
liste de tags
tag cloud
nuage de tags
Alternatively, use one of the following templates:
Alternativement, utilisez un des modèles suivants :
Alternativement, utilisez un des modèles suivants :
Thread: %s
Fil: %s
ID parameter is missing.
@@ -1013,7 +1017,7 @@ Le paramètre ID est manquant.
Thread %s does not exist.
Le fil %s n'existe pas.
Page %s does not contain a thread.
La page %s ne contient pas de fil.
La page %s ne contient aucun fil.
Add
Ajouter
URL parameter is missing.
@@ -1021,53 +1025,53 @@ Le paramètre URL est manquant.
Add to %s thread
Ajouter %s au fil
Below:
En-dessous :
En-dessous :
URL:
URL :
URL :
Name:
Nom :
Nom :
Too many instances. Only %s allowed.
Trop d'instances. %s seulement est autorisée
Please try again later. Perhaps somebody is running maintenance or doing a long search. Unfortunately the site has limited resources, and so we must ask you for a bit of patience.
Essayez plus tard s'il vous plaît. Peut-être que quelqu'un effectue une maintenance ou une recherche volumineuse. Malheureusement le site a des ressources limitées, nous vous demandons de faire preuve d'un peu de patience.
Timezone
Fuseau horaire
Pick your timezone:
Sélectionnez votre fuseau horaire
Set
Ajusté
Contents
Contenus
Create a new page for today
Ajouter une page nouvelle pour aujourdhui
Add Translation
Àjouter une traduction
Ajouter une traduction
Please provide a different page name for the translation.
Donnez s'il vous plait un nom différent à votre traduction
Added translation: %1 (%2)
Traduction ajoutée : %1 (%2)
Translate %s
Traduire %s
Thank you for writing a translation of %s.
Merci pour traduir %s.
Merci pour la traduction de %s.
Please indicate what language you will be using.
Merci d'indiquer quelle langue vous allez utiliser.
Language is missing
La langue est manquante
Suggested languages:
Langues suggérées
Please indicate a page name for the translation of %s.
Indiquez s'il vous plaît un nom de page pour la traduction de %s.
More help may be available here: %s.
Plus d'aide disponible ici : %s.
Translated page:
Page traduite :
This page is a translation of %s.
Cette page est une traduction de %s.
The translation is up to date.
La traduction est à jour.
The translation is outdated.
La traduction n'est pas à jour.
La traduction n'est plus à jour.
The page does not exist.
La page n'existe pas.
http://search.barnesandnoble.com/booksearch/isbninquiry.asp?ISBN=%s
@@ -1081,23 +1085,23 @@ http://www.pricescan.com/books/BookDetail.asp?isbn=%s
search
chercher
Wanted Pages
Pages recherchées
%s pages
%s pages
%s, referenced from:
%s, référencé(e) depuis :
Upload of %s file
Téléversement du fichier %s
Blog
Blog
Matching pages:
Pages correspondantes :
Pages correspondantes :
New
Nouveau
Nouveau
Edit %s.
Editer %s.
Éditer %s.
Title:
Titre :
Tags:
Tags :
END_OF_TRANSLATION

View File

@@ -1,7 +1,7 @@
# UTF-8 encoded German translation file for use with Oddmuse
#
# Copyright (c) 2003 Karl Loncarek <karl@loncarek.de>
# Copyright (c) 2003, 2004, 2005, 2006, 2007, 2009, 2010 Alex Schröder <alex@gnu.org>
# Copyright (c) 2003-2012 Alex Schröder <alex@gnu.org>
#
# Permission is granted to copy, distribute and/or modify this document under
# the terms of the GNU Free Documentation License, Version 1.2 or any later
@@ -16,7 +16,9 @@
# there. It will be loaded automatically.
#
use utf8;
$ModulesDescription .= '<p><a href="http://git.savannah.gnu.org/cgit/oddmuse.git/tree/modules/translations/german-utf8.pl">german-utf8.pl</a>, see <a href="http://www.oddmuse.org/cgi-bin/oddmuse/German">German</a></p>';
%Translate = split(/\n/,<<END_OF_TRANSLATION);
Include normal pages
Mit normalen Seiten
@@ -28,8 +30,8 @@ Error
Fehler
%s calls
%s Aufrufe
Could not create %s
Konnte %s nicht erzeugen
Cannot create %s
%s kann nicht erstellt werden
Invalid UserName %s: not saved.
Ungültiger Benutzername %s: nicht gespeichert.
UserName must be 50 characters or less: not saved
@@ -198,8 +200,6 @@ Unlock site
Wiki entsperren
Lock site
Wiki sperren
Install CSS
CSS installieren
Unlock %s
%s entsperren
Lock %s
@@ -316,8 +316,6 @@ Cannot open %s
%s kann nicht geöffnet werden
Cannot write %s
%s kann nicht geschrieben werden
Cannot create %s
%s kann nicht erstellt werden
Could not get %s lock
Die %s Sperre konnte nicht gesetzt werden
The lock was created %s.
@@ -504,8 +502,6 @@ Please do not fetch more than %1 pages in %2 seconds.
Bitte rufen sie nicht mehr als %1 Seiten in %2 Sekunden auf.
Check whether the web server can create the directory %s and whether it can create files in it.
Vielleicht kann der Webserver das Verzeichnis %s nicht anlegen oder es wurde schon angelegt, aber der Webserver kann darin keine neuen Dateien anlegen.
Copy one of the following stylesheets to %s:
Eines der folgenden Style Sheets kann auf die %s Seite kopiert werden:
Deleting %s
%s löschen
Deleted %s
@@ -622,6 +618,12 @@ Compilation for %s
Zusammenstellung für %s
Compilation tag is missing a regular expression.
Der tag für die Zusammenstellung benötigt noch ein Suchmuster.
Install CSS
CSS installieren
Copy one of the following stylesheets to %s:
Eines der folgenden Style Sheets kann auf die %s Seite kopiert werden:
Reset
Zurück setzen
Extract all dates from the database
Alle Daten aus der Datenbank extrahieren
Dates
@@ -670,6 +672,14 @@ ordinary changes
normale Änderungen
Matching page names:
Übereinstimmende Seitennamen:
Fix page encoding
Zeichenkodierung korrigieren
no summary available
keine Zusammenfassug vorhanden
page was marked for deletion
die Seite war zum Löschen freigegeben
Oddmuse
Oddmuse
Email:
Email:
Could not find %1.html template in %2
@@ -684,6 +694,22 @@ Languages:
Sprachen:
Show!
Zeigen!
LaTeX export
LaTeX Export
An uploaded file cannot be rendered as LaTeX.
Ein hochgeladene Datei kann nicht mit LaTeX dargestellt werden.
Exporting of journal pages to LaTeX is not supported.
Journalseiten können nicht für LaTeX exportiert werden.
Exporting of RSS feeds to LaTeX is not supported.
RSS Feeds können nicht für LaTeX exportiert werden.
Exporting of search results to LaTeX is not supported.
Suchresultate können nicht für LaTeX exportiert werden.
Exporting of redirections to LaTeX is not supported.
Umleitungen können nicht für LaTeX exportiert werden.
Exporting of named entity reference to LaTeX is not supported.
Benannte Zeichen können nicht für LaTeX exportiert werden.
Exporting of images to LaTeX is not supported.
Bilder können nicht für LaTeX exportiert werden.
Define
Definieren
Full Link List
@@ -700,6 +726,14 @@ Die %s Vorlage ist entweder leer oder existiert gar nicht.
-- definiert auf der Seite %s
Local names defined on %1: %2
Der lokale Namen %2 wurde auf der Seite %1 definiert
Name:
Name:
URL:
URL:
Define Local Names
Lokalen Namen definieren
Define external redirect:
Umleitung auf eine externe Seite definieren:
Locked Pages
Gesperrte Seiten
Register for %s
@@ -870,6 +904,12 @@ Generating Link Database
Verweis Datenbank wird angelegt
The 404 handler extension requires the link data extension (links.pl).
Die 404 handler Erweiterung benötigt die Link Data Erweiterung (links.pl).
Make available offline
Offline zur Verfügung stellen
Offline
Offline
You are currently offline and what you requested is not part of the offline application. You need to be online to do this.
Sie sind im Moment offline und was sie verlangt haben, ist nicht Teil der Offline Applikation. Hierfür müssen sie online sein.
LocalMap
LocalMap
No page id for action localmap
@@ -884,20 +924,6 @@ Self-ban by %s
%s hat sich selber verbannt.
You have banned your own IP.
Sie haben ihre eigene IP Nummer verbannt.
OpenID Login
OpenID Login
Your identity is saved in a cookie, if you have cookies enabled. Cookies may get lost if you connect from another machine, from another account, or using another software.
Die Identität wird in einem Cookie gespeichert, falls diese erlaubt sind. Cookies gehen verloren, wenn ein anderer Rechner, eine anderes Konto, oder ein anderer Browser verwendet wird.
Your homepage is set to %s.
Homepage wurde auf %s gesetzt.
You have no homepage set.
Keine Homepage gesetzt.
Homepage:
Homepage:
Homepage is missing
Homepage fehlt
OpenID error %s
OpenID Fehler %s
Orphan List
Liste der Waisen
Trail:
@@ -1026,6 +1052,26 @@ Too many instances. Only %s allowed.
Es laufen schon %s Wiki Prozesse gleichzeitig auf diesem Server. Mehr sind leider nicht erlaubt.
Please try again later. Perhaps somebody is running maintenance or doing a long search. Unfortunately the site has limited resources, and so we must ask you for a bit of patience.
Versuchen Sie es später nocheinmal. Vielleicht werden gerade Wartungsarbeiten durchgeführt, oder ein Suchbefehl nimmt gerade viel Zeit in Anspruch. Leider sind die Resourcen des Rechners limitiert; wir bitten Sie deshalb um etwas Geduld.
thumb
Error creating thumbnail from non existant page %s.
Can not create thumbnail for file type %s.
Can not create thumbnail for a text document
Could not open %s for writing whilst trying to save image before creating thumbnail. Check write permissions.
Can not create path for thumbnail - %s
Failed to run %1 to create thumbnail: %2
%s ran into an error
%s hat einen Fehler festgestellt
%s produced no output
%s hat nichts ausgegeben
Failed to parse %s.
Die Ausgabe von %s wurde nicht verstanden
Timezone
Zeitzone
Pick your timezone:
@@ -1082,6 +1128,8 @@ Gewünschte Seiten
%s Seiten
%s, referenced from:
%s, referenziert von:
Web application for offline browsing
Offline Webapplikation
Upload of %s file
Hochladen der %s Datei
Blog

View File

@@ -18,7 +18,7 @@
require 't/test.pl';
package OddMuse;
use Test::More tests => 16;
use Test::More tests => 19;
clear_pages();
@@ -49,6 +49,7 @@ The two are the same,
But after they are produced,
they have different names.
};
my $lao_file_2 = q{The Way that can be told of is not the eternal Way;
The name that can be named is not the eternal name.
The Nameless is the origin of Heaven and Earth;
@@ -118,9 +119,8 @@ sleep(2);
update_page('ConflictTest', $lao_file);
$_ = `perl wiki.pl action=edit id=ConflictTest`;
/name="oldtime" value="([0-9]+)"/;
my $oldtime = $1;
my $oldtime = xpath_test(get_page('action=edit id=ConflictTest'),
'//input[@name="oldtime"]/attribute::value');
sleep(2);
@@ -143,9 +143,8 @@ sleep(2);
update_page('ConflictTest', $tzu_file);
$_ = `perl wiki.pl action=edit id=ConflictTest`;
/name="oldtime" value="([0-9]+)"/;
$oldtime = $1;
$oldtime = xpath_test(get_page('action=edit id=ConflictTest'),
'//input[@name="oldtime"]/attribute::value');
sleep(2);
@@ -192,9 +191,8 @@ sleep(2);
update_page('ConflictTest', $lao_file);
$_ = `perl wiki.pl action=edit id=ConflictTest`;
/name="oldtime" value="([0-9]+)"/;
$oldtime = $1;
$oldtime = xpath_test(get_page('action=edit id=ConflictTest'),
'//input[@name="oldtime"]/attribute::value');
sleep(2);

View File

@@ -1,4 +1,4 @@
# Copyright (C) 2009 Alex Schroeder <alex@gnu.org>
# Copyright (C) 2009, 2012 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
@@ -15,7 +15,8 @@
require 't/test.pl';
package OddMuse;
use Test::More tests => 16;
use Test::More tests => 18;
use utf8;
clear_pages();
@@ -78,4 +79,10 @@ SKIP: {
$response = $ua->get("$wiki?action=debug;pwd=");
test_page($ua->cookie_jar->as_string, 'Set-Cookie.*: Wiki=""');
# Encoding issues
$response = $ua->get("$wiki?action=rc;username=Alex\%20Schr\%C3\%B6der");
test_page($ua->cookie_jar->as_string,
'Set-Cookie.*: Wiki=username%251eAlex%20Schr%C3%B6der');
test_page($response->decoded_content,
'Cookie: Wiki, username=Alex Schröder');
};

47
t/fix-encoding.t Normal file
View File

@@ -0,0 +1,47 @@
# Copyright (C) 2012 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/>.
require 't/test.pl';
package OddMuse;
use Test::More tests => 8;
use utf8; # tests contain UTF-8 characters and it matters
clear_pages();
add_module('fix-encoding.pl');
# make sure the menu only shows up if it applies to a page
test_page_negative(get_page('action=admin'), 'action=fix-encoding');
test_page(get_page('action=admin id=foo'), 'action=fix-encoding;id=foo');
# make sure nothing is saved if there is no change
test_page(update_page('Example', 'Pilgerstätte für die Göttin'),
'Pilgerstätte für die Göttin');
test_page(get_page('action=fix-encoding id=Example'),
'Location: http://localhost/wiki.pl/Example');
test_page_negative(get_page('action=rc showedit=1'), 'fix encoding');
# here is an actual page you need to fix
test_page(update_page('Example', 'Pilgerstätte für die Göttin', 'borked encoding'),
'Pilgerstätte für die Göttin');
test_page(get_page('action=fix-encoding id=Example'),
'Location: http://localhost/wiki.pl/Example');
test_page(get_page('Example'),
'Pilgerstätte für die Göttin');

97
t/private-pages.t Normal file
View File

@@ -0,0 +1,97 @@
# Copyright (C) 2012 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/>.
require 't/test.pl';
package OddMuse;
use Test::More tests => 28;
clear_pages();
add_module('private-pages.pl');
# create password protected page: can't read it without password!
test_page(update_page('Privat', "#PASSWORD foo\nSo many secrets remain untold.\n"),
'This page is password protected');
# can't update password protected page
update_page('Privat', "#PASSWORD foo\nCats have secrets.\n");
test_page($redirect, 'Status: 403');
# use password foo to update protected page: can't read it without password!
test_page_negative(update_page('Privat', "#PASSWORD foo\nCats have secrets.\n", undef, undef, 1),
'Cats have secrets');
test_page($redirect, 'Status: 302');
# read it with password
my $page = get_page('action=browse id=Privat pwd=foo');
test_page_negative($page, 'This page is password protected');
test_page($page, 'Cats have secrets');
# a keep file was created as well
ok(-f GetKeepFile('Privat', 1), 'Keep file exists');
# can't read old revisions without a password
test_page_negative(get_page('action=browse id=Privat revision=1'),
'Cats have secrets');
# read old revisions with password
test_page(get_page('action=browse id=Privat revision=1 pwd=foo'),
'So many secrets remain untold');
# can't read old revisions without password
test_page(get_page('action=browse id=Privat revision=1'),
'This page is password protected');
# can't see secrets when printing raw pages
my $page = get_page('action=browse raw=1 id=Privat pwd=foo');
test_page_negative($page, 'This page is password protected');
test_page($page, 'Cats have secrets');
# can't see summaries with secrets
my $page = get_page('action=rc raw=1 all=1');
test_page($page, 'Privat');
test_page_negative($page, 'secret');
# can't search for secrets without a password
my $page = get_page('search=cats');
test_page($page, '0 pages found');
test_page_negative($page, "Privat");
# search finds secrets with password
my $page = get_page('search=cats pwd=foo');
test_page($page, '1 pages? found',
'Privat', '<strong>Cats</strong> have secrets');
# can't edit a private page without a password
my $page = get_page('action=edit id=Privat');
test_page($page, 'Editing not allowed');
test_page_negative($page, 'Cats have secrets');
# can edit a private page with a password
my $page = get_page('action=edit id=Privat pwd=foo');
test_page_negative($page, 'This page is password protected');
test_page($page, 'Cats have secrets');
# can't edit an old revision of a private page without a password
my $page = get_page('action=edit id=Privat revision=1');
test_page($page, 'Editing not allowed');
test_page_negative($page, 'secret');
# can't just post changes to a private page without a password
my $page = get_page('title=Privat text=YaddaYadda revision=1');
test_page($page, 'Editing not allowed');
test_page_negative($page, 'secret');
# can't include them
test_page_negative(update_page('Publik', '<include "Privat">'),
'Cats have secrets');

34
t/tex.t
View File

@@ -1,8 +1,8 @@
# Copyright (C) 2006 Alex Schroeder <alex@emacswiki.org>
# Copyright (C) 2012 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 2 of the License, or
# 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,
@@ -11,24 +11,28 @@
# 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
# along with this program. If not, see <http://www.gnu.org/licenses/>.
require 't/test.pl';
package OddMuse;
use Test::More tests => 3;
use Test::More tests => 4;
use utf8; # tests contain UTF-8 characters and it matters
clear_pages();
add_module('tex.pl');
run_macro_tests(split('\n',<<'EOT'));
4\times 7
4×7
right\copyright
right©
a\infty b
ab
EOT
test_page(update_page('Example', '4\times7 right\copyright a\inftyb'),
qw(4×7 right© a∞b));
ok($Tex{'\textreferencemark'}, "TeX patterns ok");
# Create the table of documentation:
# binmode(STDOUT, ':utf8');
# my $i = 1;
# foreach (sort keys %Tex) {
# printf "||%s || %s ", $_, $Tex{$_};
# if ($i % 5 == 0) {
# print "||\n";
# }
# $i++;
# }

View File

@@ -15,7 +15,7 @@
require 't/test.pl';
package OddMuse;
use Test::More tests => 20;
use Test::More tests => 33;
use utf8; # tests contain UTF-8 characters and it matters
clear_pages();
@@ -76,3 +76,43 @@ test_page(get_page('action=translate id=HomePage target=abc'),
test_page(get_page('action=translate id=HomePage target=abc translation=fr'),
'Editing abc');
# encoding issues
# first check the from ASCII to something that can be encoded in Latin-1
test_page(update_page('SiteMap', 'Hello'), 'Hello');
test_page(get_page('action=translate id=SiteMap target=Übersicht translation=de'),
'Editing Übersicht');
xpath_test(get_page('SiteMap'),
'//a[@class="translation de"][text()="Deutsch"]');
xpath_test(get_page('action=rc showedit=1'),
'//li/a[@class="local"][text()="SiteMap"]/following-sibling::strong[text()="Added translation: Übersicht (Deutsch)"]');
# now check the other way around
test_page(get_page('action=translate id=Übersicht target=SiteMap translation=en'),
'Editing SiteMap');
xpath_test(get_page('Übersicht'),
'//a[@class="translation en"][text()="English"]');
xpath_test(get_page('action=rc showedit=1'),
'//li/a[@class="local"][text()="Übersicht"]/following-sibling::strong[text()="Added translation: SiteMap (English)"]');
AppendStringToFile($ConfigFile, q{
$Languages{ja} = '(ま|す|ん|し|ょ|う|の|は)';
$Translate{ja} = '日本語';
});
# Repeat it with Unicode!
test_page(get_page('action=translate id=SiteMap target=サイトマップ translation=ja'),
'Editing サイトマップ');
xpath_test(get_page('SiteMap'),
'//a[@class="translation ja"][text()="日本語"]');
xpath_test(get_page('action=rc showedit=1'),
'//li/a[@class="local"][text()="SiteMap"]/following-sibling::strong[text()="Added translation: サイトマップ (日本語)"]');
# and again, check the other way around
test_page(get_page('action=translate id=サイトマップ target=SiteMap translation=en'),
'Editing SiteMap');
xpath_test(get_page('サイトマップ'),
'//a[@class="translation en"][text()="English"]');
xpath_test(get_page('action=rc showedit=1'),
'//li/a[@class="local"][text()="サイトマップ"]/following-sibling::strong[text()="Added translation: SiteMap (English)"]');

View File

@@ -388,7 +388,7 @@ sub InitLinkPatterns {
my $EndChars = '[-a-zA-Z0-9/@=+$_~*]'; # no punctuation at the end of the url.
$UrlPattern = "((?:$UrlProtocols):$UrlChars+$EndChars)";
$FullUrlPattern="((?:$UrlProtocols):$UrlChars+)"; # when used in square brackets
$ImageExtensions = '(gif|jpg|png|bmp|jpeg)';
$ImageExtensions = '(gif|jpg|png|bmp|jpeg|svg)';
}
sub Clean {
@@ -666,7 +666,8 @@ sub OpenHtmlEnvironment { # close the previous $html_tag and open a new one
unshift(@HtmlStack, $html_tag);
unshift(@HtmlAttrStack, $html_tag_attr);
$html .= $html_tag_attr ? "<$html_tag $html_tag_attr>" : "<$html_tag>";
} return $html;
}
return $html;
}
sub CloseHtmlEnvironments { # close all -- remember to use AddHtmlEnvironment('p') if required!
@@ -2494,7 +2495,7 @@ sub PrintHtmlDiff {
if ($type == 1) {
$old = $Page{lastmajor} - 1;
($text, $new) = GetTextRevision($Page{lastmajor}, 1)
unless $new or $Page{lastmajor} == $Page{revision};
unless $new or $Page{lastmajor} == $Page{revision};
} elsif ($new) {
$old = $new - 1;
} else {