+sub getopt () { #{{{
+ eval q{use Getopt::Long};
+ error($@) if $@;
+ Getopt::Long::Configure('pass_through');
+ GetOptions("tagbase=s" => \$config{tagbase});
+} #}}}
+
+sub getsetup () { #{{{
+ return
+ plugin => {
+ safe => 1,
+ rebuild => undef,
+ },
+ tagbase => {
+ type => "string",
+ example => "tag",
+ description => "parent page tags are located under",
+ safe => 1,
+ rebuild => 1,
+ },
+} #}}}
+
+sub tagpage ($) { #{{{
+ my $tag=shift;
+
+ if ($tag !~ m{^\.?/} &&
+ defined $config{tagbase}) {
+ $tag=$config{tagbase}."/".$tag;
+ }
+
+ return $tag;
+} #}}}
+
+sub taglink ($$$;@) { #{{{
+ my $page=shift;
+ my $destpage=shift;
+ my $tag=shift;
+ my %opts=@_;
+
+ my $link=tagpage($tag);
+
+ # Force tag creation links to create the tag under /tagbase,
+ # if there is a tagbase and this tag used it.
+ $link="/".$link if $tag ne $link;
+
+ return htmllink($page, $destpage, $link, %opts);
+} #}}}
+
+sub preprocess_tag (@) { #{{{