aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoey Hess <joey@kitenet.net>2013-03-04 18:29:58 -0400
committerJoey Hess <joey@kitenet.net>2013-03-04 18:29:58 -0400
commitb1a721942de0556cfd78d67f5c8822611b13fa6e (patch)
tree4f01430ee53324c6084a49b30287b9e422b2a01c
parentd72e5fd58c121582b2a2a1feca39596c29a1feb0 (diff)
parent766a2c7ab1c48e1fe3acabaaf7b40bcd60e15688 (diff)
downloadikiwiki-b1a721942de0556cfd78d67f5c8822611b13fa6e.tar
ikiwiki-b1a721942de0556cfd78d67f5c8822611b13fa6e.tar.gz
Merge remote-tracking branch 'smcv/ready/map'
-rw-r--r--IkiWiki/Plugin/map.pm50
-rwxr-xr-xt/map.t235
-rwxr-xr-xt/permalink.t1
3 files changed, 264 insertions, 22 deletions
diff --git a/IkiWiki/Plugin/map.pm b/IkiWiki/Plugin/map.pm
index 38f090ff7..4a9bf58db 100644
--- a/IkiWiki/Plugin/map.pm
+++ b/IkiWiki/Plugin/map.pm
@@ -72,6 +72,9 @@ sub preprocess (@) {
$common_prefix=IkiWiki::dirname($common_prefix);
}
+ # Set this to 1 or more spaces to pretty-print maps for debugging
+ my $spaces = "";
+
# Create the map.
my $parent="";
my $indent=0;
@@ -94,33 +97,37 @@ sub preprocess (@) {
if defined $common_prefix && length $common_prefix;
my $depth = ($item =~ tr/\//\//) + 1;
my $baseitem=IkiWiki::dirname($item);
- my $parentbase=IkiWiki::dirname($parent);
- while (length $parentbase && length $baseitem && $baseitem !~ /^\Q$parentbase\E(\/|$)/) {
- $parentbase=IkiWiki::dirname($parentbase);
+ while (length $parent && length $baseitem && $baseitem !~ /^\Q$parent\E(\/|$)/) {
+ $parent=IkiWiki::dirname($parent);
last if length $addparent && $baseitem =~ /^\Q$addparent\E(\/|$)/;
$addparent="";
- $indent--;
- $map .= "</li>\n";
- if ($indent > 0) {
- $map .= "</ul>\n";
+ $map .= ($spaces x $indent) . "</li>\n";
+ if ($indent > 1) {
+ $map .= ($spaces x $indent) . "</ul><map:collapse>\n";
}
+ $indent--;
}
while ($depth < $indent) {
- $indent--;
- $map .= "</li>\n";
- if ($indent > 0) {
- $map .= "</ul>\n";
+ $map .= ($spaces x $indent) . "</li>\n";
+ if ($indent > 1) {
+ $map .= ($spaces x $indent) . "</ul>\n";
}
+ $indent--;
}
my @bits=split("/", $item);
my $p="";
- $indent++ unless length $parent;
$p.="/".shift(@bits) for 1..$indent;
while ($depth > $indent) {
- if (@bits && !(length $parent && "/$parent" eq $p)) {
+ $indent++;
+ if ($indent > 1) {
+ $map .= ($spaces x $indent) . "<ul><map:collapse>\n";
+ }
+ if ($depth > $indent) {
+ $p.="/".shift(@bits);
$addparent=$p;
$addparent=~s/^\///;
- $map .= "<li>"
+ $map .= ($spaces x $indent) . "<li>\n";
+ $map .= ($spaces x $indent)
.htmllink($params{page}, $params{destpage},
"/".$common_prefix.$p, class => "mapparent",
noimageinline => 1)
@@ -130,14 +137,10 @@ sub preprocess (@) {
else {
$openli=0;
}
- $indent++;
- $p.="/".shift(@bits) if @bits;
- if ($indent > 1) {
- $map .= "<ul>\n";
- }
}
- $map .= "</li>\n" if $openli;
- $map .= "<li>"
+ $map .= ($spaces x $indent) . "</li>\n" if $openli;
+ $map .= ($spaces x $indent) . "<li>\n";
+ $map .= ($spaces x $indent)
.htmllink($params{page}, $params{destpage},
"/".$common_prefix."/".$item,
@linktext,
@@ -147,9 +150,12 @@ sub preprocess (@) {
$parent=$item;
}
while ($indent > 0) {
+ $map .= ($spaces x $indent) . "</li>\n";
$indent--;
- $map .= "</li>\n</ul>\n";
+ $map .= ($spaces x $indent) . "</ul>\n";
}
+ $map =~ s{\n *</ul><map:collapse>\n *<ul><map:collapse>\n}{\n}gs;
+ $map =~ s{<map:collapse>}{}g;
$map .= "</div>\n";
return $map;
}
diff --git a/t/map.t b/t/map.t
new file mode 100755
index 000000000..7f3df61f7
--- /dev/null
+++ b/t/map.t
@@ -0,0 +1,235 @@
+#!/usr/bin/perl
+package IkiWiki;
+
+use warnings;
+use strict;
+use XML::Twig;
+use Test::More;
+
+BEGIN { use_ok("IkiWiki"); }
+BEGIN { use_ok("IkiWiki::Render"); }
+BEGIN { use_ok("IkiWiki::Plugin::map"); }
+BEGIN { use_ok("IkiWiki::Plugin::mdwn"); }
+
+ok(! system("rm -rf t/tmp; mkdir t/tmp"));
+
+$config{verbose} = 1;
+$config{srcdir} = 't/tmp';
+$config{underlaydir} = 't/tmp';
+$config{underlaydirbase} = '.';
+$config{templatedir} = 'templates';
+$config{usedirs} = 1;
+$config{htmlext} = 'html';
+$config{wiki_file_chars} = "-[:alnum:]+/.:_";
+$config{userdir} = "users";
+$config{tagbase} = "tags";
+$config{default_pageext} = "mdwn";
+$config{wiki_file_prune_regexps} = [qr/^\./];
+$config{autoindex_commit} = 0;
+
+is(checkconfig(), 1);
+
+%oldrenderedfiles=%pagectime=();
+%pagesources=%pagemtime=%oldlinks=%links=%depends=%typedlinks=%oldtypedlinks=
+%destsources=%renderedfiles=%pagecase=%pagestate=();
+
+my @pages = qw(
+alpha
+alpha/1
+alpha/1/i
+alpha/1/ii
+alpha/1/iii
+alpha/1/iv
+alpha/2
+alpha/2/a
+alpha/2/b
+alpha/3
+beta
+);
+
+foreach my $page (@pages) {
+ # we use a non-default extension for these, so they're distinguishable
+ # from programmatically-created pages
+ $pagesources{$page} = "$page.mdwn";
+ $destsources{$page} = "$page.mdwn";
+ $pagemtime{$page} = $pagectime{$page} = 1000000;
+ writefile("$page.mdwn", "t/tmp", "your ad here");
+}
+
+sub comment {
+ my $str = shift;
+ $str =~ s/^/# /gm;
+ print $str;
+}
+
+sub node {
+ my $name = shift;
+ my $kids = shift;
+ my %stuff = @_;
+
+ return { %stuff, name => $name, kids => $kids };
+}
+
+sub check_nodes {
+ my $ul = shift;
+ my $expected = shift;
+
+ is($ul->tag, 'ul');
+
+ # expected is a list of hashes
+ # ul is a list of li
+ foreach my $li ($ul->children) {
+ my @kids = $li->children;
+
+ is($li->tag, 'li');
+
+ my $expectation = shift @$expected;
+
+ is($kids[0]->tag, 'a');
+ my $a = $kids[0];
+
+ if ($expectation->{parent}) {
+ is($a->att('class'), 'mapparent');
+ }
+ else {
+ is($a->att('class'), 'mapitem');
+ }
+
+ is_deeply([$a->text], [$expectation->{name}]);
+
+ if (@{$expectation->{kids}}) {
+ is(scalar @kids, 2);
+
+ check_nodes($kids[1], $expectation->{kids});
+ }
+ else {
+ is_deeply([@kids], [$a]);
+ }
+ }
+}
+
+sub check {
+ my $pagespec = shift;
+ my $expected = shift;
+ comment("*** $pagespec ***\n");
+
+ my $html = IkiWiki::Plugin::map::preprocess(pages => $pagespec,
+ page => 'map',
+ destpage => 'map');
+ comment($html);
+ my $tree = XML::Twig->new(pretty_print => 'indented');
+ eval {
+ $tree->parse($html);
+ };
+ if ($@) {
+ print "malformed XML: $@\n$html\n";
+ ok(0);
+ }
+ my $fragment = $tree->root;
+
+ is($fragment->tag, 'div');
+ is($fragment->att('class'), 'map');
+
+ if (@$expected) {
+ check_nodes(($fragment->children)[0], $expected);
+ }
+ else {
+ ok(! $fragment->children);
+ }
+
+ $tree->dispose;
+}
+
+check('doesnotexist', []);
+
+check('alpha', [node('alpha', [])]);
+
+check('alpha/*',
+ [
+ node('1', [
+ node('i', []),
+ node('ii', []),
+ node('iii', []),
+ node('iv', []),
+ ]),
+ node('2', [
+ node('a', []),
+ node('b', []),
+ ]),
+ node('3', []),
+ ]);
+
+check('alpha or alpha/*',
+ [
+ node('alpha', [
+ node('1', [
+ node('i', []),
+ node('ii', []),
+ node('iii', []),
+ node('iv', []),
+ ]),
+ node('2', [
+ node('a', []),
+ node('b', []),
+ ]),
+ node('3', []),
+ ]),
+ ]);
+
+check('alpha or alpha/1 or beta',
+ [
+ node('alpha', [
+ node('1', []),
+ ]),
+ node('beta', []),
+ ]);
+
+check('alpha/1 or beta',
+ [
+ node('alpha', [
+ node('1', []),
+ ], parent => 1),
+ node('beta', []),
+ ]);
+
+check('alpha/1/i* or alpha/2/a or beta',
+ [
+ node('alpha', [
+ node('1', [
+ node('i', []),
+ node('ii', []),
+ node('iii', []),
+ node('iv', []),
+ ], parent => 1),
+ node('2', [
+ node('a', []),
+ ], parent => 1),
+ ], parent => 1),
+ node('beta', []),
+ ]);
+
+check('alpha/1/i* or alpha/2/a',
+ [
+ node('1', [
+ node('i', []),
+ node('ii', []),
+ node('iii', []),
+ node('iv', []),
+ ], parent => 1),
+ node('2', [
+ node('a', []),
+ ], parent => 1),
+ ]);
+
+check('alpha/1/i*',
+ [
+ node('i', []),
+ node('ii', []),
+ node('iii', []),
+ node('iv', []),
+ ]);
+
+ok(! system("rm -rf t/tmp"));
+done_testing;
+
+1;
diff --git a/t/permalink.t b/t/permalink.t
index 81d4d1820..36be984c5 100755
--- a/t/permalink.t
+++ b/t/permalink.t
@@ -3,6 +3,7 @@ use warnings;
use strict;
use Test::More 'no_plan';
+ok(! system("rm -rf t/tmp"));
ok(! system("mkdir t/tmp"));
ok(! system("make -s ikiwiki.out"));
ok(! system("perl -I. ./ikiwiki.out -plugin inline -url=http://example.com -cgiurl=http://example.com/ikiwiki.cgi -rss -atom -underlaydir=underlays/basewiki -set underlaydirbase=underlays -templatedir=templates t/tinyblog t/tmp/out"));