wiki.pl: Port some fixes from upstream
[Orgmuse.git] / modules / olocalmap.pl
blobfa8f01d2312362b1533e93b0717278fa720806ed
1 # Copyright (C) 2005 Flavio Poletti <flavio@polettix.it>
3 # This program is free software; you can redistribute it and/or modify
4 # it under the terms of the GNU General Public License as published by
5 # the Free Software Foundation; either version 2 of the License, or
6 # (at your option) any later version.
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
13 # You should have received a copy of the GNU General Public License
14 # along with this program; if not, write to the
15 # Free Software Foundation, Inc.
16 # 59 Temple Place, Suite 330
17 # Boston, MA 02111-1307 USA
19 # This module adds an action and a link in the UserGotoBar to build
20 # a Local Site Map starting from the current page. The map is a sort
21 # of Table Of Contents in which the current page is considered the
22 # root of the document.
24 # Basic idea got from MoinMoin.
27 ##########################################################################
29 # End-user capabilities
31 ##########################################################################
32 # Actions
33 $Action{'localmap'} = \&DoLocalMap;
35 # Variables
36 use vars qw($LocalMapDefaultDepth);
37 $LocalMapDefaultDepth = 3 unless defined $LocalMapDefaultDepth;
40 ##########################################################################
42 # Implementation
44 ##########################################################################
45 $ModulesDescription .= '<p>$Id $: build a Local Site Map from a page, using references as sub-sections</p>';
47 push(@MyInitVariables, \&InitLocalMap);
49 sub InitLocalMap {
50 my $id = GetCurrentPageName();
51 my $action = lc(GetParam('action', ''));
52 AllPagesList(); # Build %IndexHash
54 # Avoid putting stuff in non-pages (like RecentChanges) and in
55 # the page result of the action
56 return 0 unless (length($id)
57 && $IndexHash{$id}
58 && ($action cmp 'localmap'));
60 # Add a link to the list of parents
61 $UserGotoBar .= ScriptLink("action=localmap;id=$id", T('LocalMap')) . ' ';
64 sub DoLocalMap {
65 my $id = GetParam('id', '');
66 MyReportError(T('No page id for action localmap'), '400 BAD REQUEST',
67 undef, GetParam('raw', 0))
68 unless length($id);
70 AllPagesList(); # Build %IndexHash
71 MyReportError(Ts('Requested page %s does not exist', $id),
72 '503 SERVICE UNAVAILABLE', undef, GetParam('raw', 0))
73 unless ($IndexHash{FreeToNormal($id)});
75 print GetHeader('', QuoteHtml(Ts('Local Map for %s', $id)), '');
77 my $depth = GetParam('depth', $LocalMapDefaultDepth);
78 $id = FreeToNormal($id);
79 my %got; # Tracks already hit pages
80 print($q->ul(LocalMapWorkHorse($id, $depth, \%got)));
81 PrintFooter();
84 sub LocalMapWorkHorse {
85 my ($id, $depth, $GotPagesRef) = @_;
87 $GotPagesRef->{$id} = $depth;
88 return '' unless exists($IndexHash{$id});
89 my $name = $id;
90 $name =~ s/_/ /g;
92 my $retval_me .= ScriptLink("action=localmap;id=" . UrlEncode($id), $name);
93 $retval_me .= ' (' . GetPageLink($id, T('view')) . ')';
94 my $retval_me = $q->li($retval_me);
96 my $retval_children = '';
97 if ($depth > 0) {
98 my %data = ParseData(ReadFileOrDie(GetPageFile($id)));
99 my @flags = split(/$FS/, $data{'flags'});
100 my @blocks = split(/$FS/, $data{'blocks'});
101 my @subpages;
103 # Iterate over blocks, operate only on "dirty" ones
104 for (my $i = 0; $i < @flags; ++$i) {
105 next unless $flags[$i];
106 my $sub_id;
107 local $_ = $blocks[$i];
109 if ($WikiLinks
110 && ($BracketWiki && m/\G(\[$LinkPattern\s+([^\]]+?)\])/cog
111 or m/\G(\[$LinkPattern\])/cog or m/\G($LinkPattern)/cog)) {
112 $sub_id = $1;
113 } elsif ($FreeLinks
114 && (($BracketWiki
115 && m/\G(\[\[($FreeLinkPattern)\|([^\]]+)\]\])/cog)
116 or m/\G(\[\[\[($FreeLinkPattern)\]\]\])/cog
117 or m/\G(\[\[($FreeLinkPattern)\]\])/cog)) {
118 $sub_id = $2;
121 if ($sub_id) {
122 $sub_id = FreeToNormal($sub_id);
123 if (exists $IndexHash{$sub_id}
124 && ! exists $GotPagesRef->{$sub_id}) {
125 push(@subpages, $sub_id);
126 $GotPagesRef->{$sub_id} = $depth - 1;
131 # Recollect. We cannot do it inside the for loop because otherwise
132 # we would spoil the hash pointed by $GotPagesRef
133 foreach my $sub_id (@subpages) {
134 $retval_children .=
135 LocalMapWorkHorse($sub_id, $depth - 1, $GotPagesRef);
138 # Enclose all inside an unnumbered list
139 $retval_children = $q->ul($retval_children) if length($retval_children);
142 # Return the two sections
143 return $retval_me . $retval_children;