From 55000fd779816fa059e51e9fd01c7e6772b8efc7 Mon Sep 17 00:00:00 2001
From: intrigeri <intrigeri@boum.org>
Date: Tue, 15 Jul 2008 12:35:12 +0200
Subject: [PATCH] pedigree: rewrote with different design

(and updated testsuite + docs accordingly)

Signed-off-by: intrigeri <intrigeri@boum.org>
---
 IkiWiki/Plugin/pedigree.pm         |  57 +++------------
 doc/plugins/pedigree.mdwn          | 112 +++++++++++------------------
 t/pedigree.t                       | 109 +++++-----------------------
 t/pedigree/templates/pedigree.tmpl |   6 --
 4 files changed, 69 insertions(+), 215 deletions(-)

diff --git a/IkiWiki/Plugin/pedigree.pm b/IkiWiki/Plugin/pedigree.pm
index f91ea94b4..eb8bfa83b 100644
--- a/IkiWiki/Plugin/pedigree.pm
+++ b/IkiWiki/Plugin/pedigree.pm
@@ -18,20 +18,22 @@ sub pedigree ($) { #{{{
 	my $path="";
 	my $title=$config{wikiname};
 	my $i=0;
+	my $depth=0;
+	my $height=0;
 
 	my @pagepath=(split("/", $page));
 	my $pagedepth=@pagepath;
 	foreach my $dir (@pagepath) {
 		next if $dir eq 'index';
+		$depth=$i;
+		$height=($pagedepth - $depth);
 		push @ret, {
 			    url => urlto($path, $page),
 			    page => $title,
-			    absdepth => $i,
-			    distance => ($pagedepth - $i),
-			    is_root => ($i eq 0),
-			    is_second_ancestor => ($i eq 1),
-			    is_grand_mother => ($i eq ($pagedepth - 2)),
-			    is_mother => ($i eq ($pagedepth - 1)),
+			    depth => $depth,
+			    height => $height,
+			    "depth_$depth" => 1,
+			    "height_$height" => 1,
 			   };
 		$path.="/".$dir;
 		$title=IkiWiki::pagetitle($dir);
@@ -40,51 +42,14 @@ sub pedigree ($) { #{{{
 	return @ret;
 } #}}}
 
-sub forget_oldest ($@) { #{{{
-	my $offset=shift;
-	my @pedigree=@_;
-	my @ret;
-	my $parent;
-	unless ($offset ge scalar(@pedigree)) {
-		for (my $i=0; $i < $offset; $i++) {
-			shift @pedigree;
-		}
-		while (@pedigree) {
-			# Doing so does not modify the original @pedigree, we've
-			# got our own copy of its "content" (i.e. a pile of
-			# references to hashes)...
-			$parent=shift @pedigree;
-			# ... but we have no copy of the referenced hashes, so we
-			# actually are modifying them in-place, which
-			# means the second (and following) calls to
-			# this function overwrite the previous one's
-			# reldepth values => known bug if PEDIGREE_BUT_ROOT and
-			# PEDIGREE_BUT_TWO_OLDEST are used in the same template
-			$parent->{reldepth}=($parent->{absdepth} - $offset);
-			push @ret, $parent;
-		}
-	}
-	return @ret;
-} #}}}
-
 sub pagetemplate (@) { #{{{
 	my %params=@_;
         my $page=$params{page};
         my $template=$params{template};
 
-	my @pedigree=pedigree($page)
-	  if ($template->query(name => "pedigree")
-	      or $template->query(name => "pedigree_but_root")
-	      or $template->query(name => "pedigree_but_two_oldest")
-	     );
-
-	$template->param(pedigree => \@pedigree)
-	  if ($template->query(name => "pedigree"));
-	$template->param(pedigree_but_root => [forget_oldest(1, @pedigree)])
-	  if ($template->query(name => "pedigree_but_root"));
-	$template->param(pedigree_but_two_oldest => [forget_oldest(2, @pedigree)])
-	  if ($template->query(name => "pedigree_but_two_oldest"));
-
+	if ($template->query(name => "pedigree")) {
+		$template->param(pedigree => [pedigree($page)]);
+	}
 } # }}}
 
 1
diff --git a/doc/plugins/pedigree.mdwn b/doc/plugins/pedigree.mdwn
index 41f70745c..15c032838 100644
--- a/doc/plugins/pedigree.mdwn
+++ b/doc/plugins/pedigree.mdwn
@@ -1,98 +1,74 @@
 [[!template id=plugin name=pedigree author="intrigeri"]]
 [[!tag type/useful]]
 
-This plugin provides a bunch of loops that one can use in his/her
-`HTML::Template`'s to iterate over all or a subset of a page's
-parents. One can think of pedigree as "`PARENTLINKS` on steroids".
+This plugin offers a `HTML::Template` loop that iterates over all or
+a subset of a page's parents, providing a few bonus possibilities,
+such as styling the parent links depending on their place in the path.
+One can think of pedigree as "`PARENTLINKS` on steroids".
 
 [[!toc ]]
 
 Content
 =======
 
-Loop variables
---------------
+This plugin provides one template loop, called `PEDIGREE`, that
+returns the same parents list as `PARENTLINKS` would; as a bonus,
+every path element returned by the `PEDIGREE` loop has the following
+variables set:
 
-Inside any loop provided by the pedigree plugin, every path element
-has not only the `URL` and `PAGE` variables, as with `PARENTLINKS`,
-but also the following ones:
-
-* `ABSDEPTH` (positive integer): depth of the path leading to the
+* `URL` (string): url to the current path element
+* `PAGE` (string): title of the current path element
+* `DEPTH` (positive integer): depth of the path leading to the
   current path element, counting from the wiki's root, which has
-  `ABSDEPTH=0`
-* `DISTANCE` (positive integer): distance, expressed in path elements,
+  `DEPTH=0`
+* `HEIGHT` (positive integer): distance, expressed in path elements,
   from the current page to the current path element; e.g. this is
   1 for the current page's mother, 2 for its grand-mother, etc.
-* `IS_ROOT` (boolean): true if, and only if, this path element is the
-  wiki's root
-* `IS_SECOND_ANCESTOR` (boolean): true if, and only if, this path
-  element is the first one after the wiki's root, on the path leading
-  to the current page
-* `IS_GRAND_MOTHER` (boolean): true if, and only if, this path element
-  is the current page's grand-mother
-* `IS_MOTHER` (boolean): true if, and only if, this path element
-  is the current page's mother
-
-Loops
------
-
-### `PEDIGREE`
-
-Returns the same parents list as `PARENTLINKS` would, along with
-additional loop variables as explained above.
-
-### `PEDIGREE_BUT_ROOT`
-
-Returns the same parents list as `PEDIGREE` would, **but** the wiki
-root (i.e. homepage).
-
-In addition to pedigree's common loop variables, `PEDIGREE_BUT_ROOT`
-provides `RELDEPTH` (positive integer), whose value, for a given
-parent, is its relative depth, i.e. the depth of the path leading to
-it, counting from the first element returned by this loop.
-
-### `PEDIGREE_BUT_TWO_OLDEST`
-
-Returns the same parents list as `PEDIGREE` would, **but** the wiki
-root (i.e. homepage) and the next path component.
-
-In addition to pedigree's common loop variables,
-`PEDIGREE_BUT_TWO_OLDEST` provides `RELDEPTH`: depth of the path
-leading to the current parent, relative to the first element returned
-by this loop.
+* `DEPTH_n` (boolean): true if, and only if, `DEPTH==n`
+* `HEIGHT_n` (boolean): true if, and only if, `HEIGHT==n`
 
 Usage
 =====
 
+The `DEPTH_n` and `HEIGHT_n` variables allow the template writer to
+skip arbitrary elements in the parents list: they are arbitrary
+page-range selectors.
+
+The `DEPTH` and `HEIGHT` variables allow the template writer to apply
+general treatment, depending on one of these variables, to *every*
+parent: they are counters.
+
 Styling parents depending on their depth
 ----------------------------------------
 
 Say you want the parent links to be styled depending on their depth in
-the path leading to the current page; just add the following lines in
-`page.tmpl`:
+the path going from the wiki root to the current page; just add the
+following lines in `page.tmpl`:
 
 	<TMPL_LOOP NAME="PEDIGREE">
-	<a href="<TMPL_VAR NAME="URL">" class="parentdepth<TMPL_VAR NAME="ABSDEPTH">">
+	<a href="<TMPL_VAR NAME="URL">" class="depth<TMPL_VAR NAME="DEPTH">">
 	  <TMPL_VAR NAME="PAGE">
 	</a> / 
 	</TMPL_LOOP>
 
-Then write the appropriate CSS bits for `a.parentdepth1`, etc.
+Then write the appropriate CSS bits for `a.depth1`, etc.
 
-Skip some parents, style the others depending on their distance
----------------------------------------------------------------
+Skip some parents, style the others depending on their distance to the current page
+-----------------------------------------------------------------------------------
 
-Say you want to display the parents links, skipping the wiki homepage,
-styled depending on their distance from the current page; just add the
+Say you want to display all the parents links but the wiki homepage,
+styled depending on their distance to the current page; just add the
 following lines in `page.tmpl`:
 
-	<TMPL_LOOP NAME="PEDIGREE_BUT_ROOT">
-	<a href="<TMPL_VAR NAME="URL">" class="parentdistance<TMPL_VAR NAME="DISTANCE">">
+	<TMPL_LOOP NAME="PEDIGREE">
+	<TMPL_IF NAME="DEPTH_0">
+	<TMPL_ELSE>
+	<a href="<TMPL_VAR NAME="URL">" class="height<TMPL_VAR NAME="HEIGHT">">
 	  <TMPL_VAR NAME="PAGE">
 	</a> / 
 	</TMPL_LOOP>
 
-Then write the appropriate CSS bits for `a.parentdistance1`, etc.
+Then write the appropriate CSS bits for `a.height1`, etc.
 
 Full-blown example
 ------------------
@@ -106,9 +82,9 @@ and/or CSS generated for some special path components; e.g.:
 	<div id="oldestparents">
 	<ul>
 	<TMPL_LOOP NAME="PEDIGREE">
-	  <TMPL_IF NAME="IS_GRAND_MOTHER">
+	  <TMPL_IF NAME="HEIGHT_2">
 	  <TMPL_ELSE>
-	    <TMPL_IF NAME="IS_MOTHER">
+	    <TMPL_IF NAME="HEIGHT_1">
 	    <TMPL_ELSE>
 	      <li><a href="<TMPL_VAR NAME="URL">"><TMPL_VAR NAME="PAGE"></a></li>
 	    </TMPL_IF>
@@ -119,12 +95,12 @@ and/or CSS generated for some special path components; e.g.:
 	
 	<!-- dedicated div's for mother and grand'ma -->
 	<TMPL_LOOP NAME="PEDIGREE">
-	  <TMPL_IF NAME="IS_GRAND_MOTHER">
+	  <TMPL_IF NAME="HEIGHT_2">
 	    <div id="grandma">
 	      <a href="<TMPL_VAR NAME="URL">"><TMPL_VAR NAME="PAGE"></a>
 	    </div>
 	  <TMPL_ELSE>
-	    <TMPL_IF NAME="IS_MOTHER">
+	    <TMPL_IF NAME="HEIGHT_1">
 	      <div id="mother">
 		<a href="<TMPL_VAR NAME="URL">"><TMPL_VAR NAME="PAGE"></a>
 	      </div>
@@ -135,11 +111,3 @@ and/or CSS generated for some special path components; e.g.:
 	<!-- eventually, the current page title -->
 	<TMPL_VAR NAME="TITLE">
 	</div>
-
-Known bugs
-==========
-
-If `PEDIGREE_BUT_ROOT` and `PEDIGREE_BUT_TWO_OLDEST` are used in the
-same `HTML::Template`, `RELDEPTH` has wrong values inside the
-`PEDIGREE_BUT_ROOT` loop. This can be fixed if anyone needs this to
-be working.
diff --git a/t/pedigree.t b/t/pedigree.t
index aa78cbe67..74871cfa8 100755
--- a/t/pedigree.t
+++ b/t/pedigree.t
@@ -24,61 +24,15 @@ $expected{'pedigree'} =
   {
    "" => [],
    "ikiwiki" => [],
-   "ikiwiki/pagespec" => [
-			  {absdepth => 0,
-			   distance => 2,
-			   is_root => 1,
-			   is_second_ancestor => '',
-			   is_grand_mother => 1,
-			   is_mother => '',
-			  },
-			  {absdepth => 1,
-			   distance => 1,
-			   is_root => '',
-			   is_second_ancestor => 1,
-			   is_grand_mother => '',
-			   is_mother => 1,
-			  },
-			 ],
-   "ikiwiki/pagespec/attachment" => [
-				     {absdepth => 0,
-				      distance => 3,
-				      is_root => 1,
-				      is_second_ancestor => '',
-				      is_grand_mother => '',
-				      is_mother => '',
-				     },
-				     {absdepth => 1,
-				      distance => 2,
-				      is_root => '',
-				      is_second_ancestor => 1,
-				      is_grand_mother => 1,
-				      is_mother => '',
-				     },
-				     {absdepth => 2,
-				      distance => 1,
-				      is_root => '',
-				      is_second_ancestor => '',
-				      is_grand_mother => '',
-				      is_mother => 1,
-				     },
-				    ],
-  };
-
-$expected{'pedigree_but_root'} =
-  {
-   "" => [],
-   "ikiwiki" => [],
-   "ikiwiki/pagespec" => [],
-   "ikiwiki/pagespec/attachment" => [],
-  };
-
-$expected{'pedigree_but_two_oldest'} =
-  {
-   "" => [],
-   "ikiwiki" => [],
-   "ikiwiki/pagespec" => [],
-   "ikiwiki/pagespec/attachment" => [],
+   "ikiwiki/pagespec" =>
+     [ {depth => 0, height => 2, },
+       {depth => 1, height => 1, },
+     ],
+   "ikiwiki/pagespec/attachment" =>
+     [ {depth => 0, height => 3, depth_0 => 1, height_3 => 1},
+       {depth => 1, height => 2, },
+       {depth => 2, height => 1, },
+     ],
   };
 
 # Test function
@@ -87,15 +41,6 @@ sub test_loop($$) {
 	my $expected=shift;
 	my $template;
 	my %params;
-	my $offset;
-
-	if ($loop eq 'pedigree') {
-		$offset=0;
-	} elsif ($loop eq 'pedigree_but_root') {
-		$offset=1;
-	} elsif ($loop eq 'pedigree_but_two_oldest') {
-		$offset=2;
-	}
 
 	ok($template=template('pedigree.tmpl'), "template created");
 	ok($params{template}=$template, "params populated");
@@ -103,12 +48,6 @@ sub test_loop($$) {
 	while ((my $page, my $exp) = each %{$expected}) {
 		my @path=(split("/", $page));
 		my $pagedepth=@path;
-		my $expdepth;
-		if (($pagedepth - $offset) >= 0) {
-			$expdepth=$pagedepth - $offset;
-		} else {
-			$expdepth=0;
-		}
 		my $msgprefix="$page $loop";
 
 		# manually run the plugin hook
@@ -117,28 +56,18 @@ sub test_loop($$) {
 		IkiWiki::Plugin::pedigree::pagetemplate(%params);
 		my $res=$template->param($loop);
 
-		is(scalar(@$res), $expdepth, "$msgprefix: path length");
+		is(scalar(@$res), $pagedepth, "$msgprefix: path length");
 		# logic & arithmetic validation tests
-		for (my $i=0; $i<$expdepth; $i++) {
+		for (my $i=0; $i<$pagedepth; $i++) {
 			my $r=$res->[$i];
-			is($r->{distance}, $pagedepth - $r->{absdepth},
-			   "$msgprefix\[$i\]: distance = pagedepth - absdepth");
-			ok($r->{absdepth} ge 0, "$msgprefix\[$i\]: absdepth>=0");
-			ok($r->{distance} ge 0, "$msgprefix\[$i\]: distance>=0");
-			unless ($loop eq 'pedigree') {
-				ok($r->{reldepth} ge 0, "$msgprefix\[$i\]: reldepth>=0");
-			      TODO: {
-					local $TODO = "Known bug" if 
-					  (($loop eq 'pedigree_but_root')
-					   && ($i >= $offset));
-					is($r->{reldepth} + $offset, $r->{absdepth},
-					   "$msgprefix\[$i\]: reldepth+offset=absdepth");
-				}
-			}
+			is($r->{height}, $pagedepth - $r->{depth},
+			   "$msgprefix\[$i\]: height = pagedepth - depth");
+			ok($r->{depth} ge 0, "$msgprefix\[$i\]: depth>=0");
+			ok($r->{height} ge 0, "$msgprefix\[$i\]: height>=0");
 		}
 		# comparison tests, iff the test-suite has been written
-		if (scalar(@$exp) eq $expdepth) {
-			for (my $i=0; $i<$expdepth; $i++) {
+		if (scalar(@$exp) eq $pagedepth) {
+			for (my $i=0; $i<$pagedepth; $i++) {
 				my $e=$exp->[$i];
 				my $r=$res->[$i];
 				map { is($r->{$_}, $e->{$_}, "$msgprefix\[$i\]: $_"); } keys %$e;
@@ -151,6 +80,4 @@ sub test_loop($$) {
 }
 
 # Main
-map {
-	test_loop($_, $expected{$_});
-} ('pedigree', 'pedigree_but_root', 'pedigree_but_two_oldest');
+test_loop('pedigree', $expected{'pedigree'});
diff --git a/t/pedigree/templates/pedigree.tmpl b/t/pedigree/templates/pedigree.tmpl
index 3590244ee..5fa25733a 100644
--- a/t/pedigree/templates/pedigree.tmpl
+++ b/t/pedigree/templates/pedigree.tmpl
@@ -2,9 +2,3 @@
 
 <TMPL_LOOP NAME="PEDIGREE">
 </TMPL_LOOP>
-
-<TMPL_LOOP NAME="PEDIGREE_BUT_ROOT">
-</TMPL_LOOP>
-
-<TMPL_LOOP NAME="PEDIGREE_BUT_TWO_OLDEST">
-</TMPL_LOOP>
-- 
2.39.5