2008-09-28 07:00:34 +00:00
|
|
|
|
#!/usr/bin/env perl
|
2015-03-27 03:01:01 +02:00
|
|
|
|
use strict;
|
2015-08-18 10:48:03 +02:00
|
|
|
|
use v5.10;
|
2015-03-27 03:01:01 +02:00
|
|
|
|
|
2008-09-28 07:00:34 +00:00
|
|
|
|
# ====================[ footnotes.pl ]====================
|
|
|
|
|
|
|
2015-07-28 23:02:23 +02:00
|
|
|
|
=encoding utf8
|
|
|
|
|
|
|
2008-09-28 07:00:34 +00:00
|
|
|
|
=head1 NAME
|
|
|
|
|
|
|
|
|
|
|
|
footnotes - An Oddmuse module for adding footnotes to Oddmuse Wiki pages.
|
|
|
|
|
|
|
|
|
|
|
|
=head1 INSTALLATION
|
|
|
|
|
|
|
|
|
|
|
|
footnotes is easily installable; move this file into the B<wiki/modules/>
|
|
|
|
|
|
directory for your Oddmuse Wiki.
|
|
|
|
|
|
|
|
|
|
|
|
=cut
|
2014-08-21 22:23:23 +02:00
|
|
|
|
AddModuleDescription('footnotes.pl', 'Footnotes Extension');
|
2008-09-28 07:00:34 +00:00
|
|
|
|
|
2015-04-10 13:31:28 +03:00
|
|
|
|
our ($q, $bol, @MyRules, @MyInitVariables);
|
2008-09-28 07:00:34 +00:00
|
|
|
|
# ....................{ CONFIGURATION }....................
|
|
|
|
|
|
|
|
|
|
|
|
=head1 CONFIGURATION
|
|
|
|
|
|
|
|
|
|
|
|
footnotes is easily configurable; set these variables in the B<wiki/config.pl>
|
|
|
|
|
|
file for your Oddmuse Wiki.
|
|
|
|
|
|
|
|
|
|
|
|
=cut
|
2015-04-10 13:31:28 +03:00
|
|
|
|
our ($FootnotePattern,
|
|
|
|
|
|
$FootnotesPattern,
|
|
|
|
|
|
$FootnotesHeaderText,
|
2008-09-28 07:00:34 +00:00
|
|
|
|
|
|
|
|
|
|
@FootnoteList);
|
|
|
|
|
|
|
|
|
|
|
|
=head2 $FootnotePattern
|
|
|
|
|
|
|
|
|
|
|
|
A regular expression matching text within an Oddmuse Wiki page, which, when
|
|
|
|
|
|
matched, replaces that text with a footnote reference. In other words, text
|
|
|
|
|
|
matching this regular expression becomes a "footnote."
|
|
|
|
|
|
|
|
|
|
|
|
If left unset, this regular expression takes one of two defaults - depending on
|
|
|
|
|
|
which other Oddmuse markup modules are installed (so as not to conflict with
|
|
|
|
|
|
those other Oddmuse markup modules' markup rules).
|
|
|
|
|
|
|
|
|
|
|
|
=over
|
|
|
|
|
|
|
|
|
|
|
|
=item (($FootnoteText))
|
|
|
|
|
|
|
|
|
|
|
|
=over
|
|
|
|
|
|
|
|
|
|
|
|
=item If the Creole Markup module (B<creole.pl>) is also installed, then this
|
|
|
|
|
|
is the default regular expression for marking a footnote (where
|
|
|
|
|
|
C<$FootnoteText> is the displayed text for that footnote).
|
|
|
|
|
|
|
|
|
|
|
|
=back
|
|
|
|
|
|
|
|
|
|
|
|
=item {{$FootnoteText}}
|
|
|
|
|
|
|
|
|
|
|
|
=over
|
|
|
|
|
|
|
|
|
|
|
|
=item If the Creole Markup module (B<creole.pl>) is not installed, then this
|
|
|
|
|
|
is the default regular expression for marking a footnote (where
|
|
|
|
|
|
C<$FootnoteText> is the displayed text for that footnote). This is, also,
|
|
|
|
|
|
the old default for this module.
|
|
|
|
|
|
|
|
|
|
|
|
=back
|
|
|
|
|
|
|
|
|
|
|
|
=back
|
|
|
|
|
|
|
|
|
|
|
|
=cut
|
|
|
|
|
|
$FootnotePattern = undef;
|
|
|
|
|
|
|
|
|
|
|
|
=head2 $FootnotesPattern
|
|
|
|
|
|
|
|
|
|
|
|
A regular expression matching text within an Oddmuse Wiki page, which, when
|
|
|
|
|
|
matched, replaces that text with the set of all page footnotes.
|
|
|
|
|
|
|
|
|
|
|
|
Any page with footnotes (i.e., any page with at least one string matching the
|
|
|
|
|
|
C<$FootnotePattern>) should collect and show those footnotes somewhere in that
|
|
|
|
|
|
page. Luckily, there are two mechanisms for effecting this - the first via
|
|
|
|
|
|
explicit markup, and the second via implicit fallback; these are:
|
|
|
|
|
|
|
|
|
|
|
|
=over
|
|
|
|
|
|
|
|
|
|
|
|
=item <footnotes>
|
|
|
|
|
|
|
|
|
|
|
|
=over
|
|
|
|
|
|
|
|
|
|
|
|
=item If a page has markup explicitly matched by this regular expression, that
|
|
|
|
|
|
markup is replaced by the set of footnotes for the page.
|
|
|
|
|
|
|
|
|
|
|
|
=back
|
|
|
|
|
|
|
|
|
|
|
|
=item N/A
|
|
|
|
|
|
|
|
|
|
|
|
=over
|
|
|
|
|
|
|
|
|
|
|
|
=item Otherwise, if a page has no such markup but does have at least one
|
|
|
|
|
|
footnote, the set of footnotes for the page is automatically situated
|
|
|
|
|
|
between the content and footer for that page. As this may, or may not, be
|
|
|
|
|
|
the proper place for page footnotes, you're encouraged to explicitly
|
|
|
|
|
|
provide page markup matched by this regular expression.
|
|
|
|
|
|
|
|
|
|
|
|
=back
|
|
|
|
|
|
|
|
|
|
|
|
=back
|
|
|
|
|
|
|
|
|
|
|
|
=cut
|
2009-05-11 02:28:44 +00:00
|
|
|
|
$FootnotesPattern = '\<footnotes\>[ \t]*(\n|$)';
|
2008-09-28 07:00:34 +00:00
|
|
|
|
|
|
|
|
|
|
=head2 $FootnotesHeaderText
|
|
|
|
|
|
|
|
|
|
|
|
The string displayed as the header to the set of all page footnotes.
|
|
|
|
|
|
|
|
|
|
|
|
=cut
|
|
|
|
|
|
$FootnotesHeaderText = 'Footnotes:';
|
|
|
|
|
|
|
|
|
|
|
|
# ....................{ INITIALIZATION }....................
|
|
|
|
|
|
push(@MyInitVariables, \&FootnotesInit);
|
|
|
|
|
|
|
|
|
|
|
|
sub FootnotesInit {
|
|
|
|
|
|
@FootnoteList = ();
|
|
|
|
|
|
|
2008-10-01 06:21:46 +00:00
|
|
|
|
if (not defined $FootnotePattern) {
|
2009-05-11 02:28:44 +00:00
|
|
|
|
$FootnotePattern = defined &CreoleRule ? '\(\((.+?)\)\)' : '\{\{(.+?)\}\}';
|
2008-10-01 06:21:46 +00:00
|
|
|
|
}
|
2008-09-28 07:00:34 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# ....................{ MARKUP }....................
|
|
|
|
|
|
push(@MyRules, \&FootnotesRule);
|
|
|
|
|
|
|
|
|
|
|
|
=head2 MARKUP
|
|
|
|
|
|
|
|
|
|
|
|
=head3 CREATING FOOTNOTES
|
|
|
|
|
|
|
|
|
|
|
|
footnotes handles markup resembling (assuming the Creole Markup module is also
|
|
|
|
|
|
installed):
|
|
|
|
|
|
|
|
|
|
|
|
(($FootnoteText))
|
|
|
|
|
|
|
|
|
|
|
|
C<$FootnoteText> is the text for that footnote. This extension replaces that
|
|
|
|
|
|
text (and enclosing parentheses) with a numbered link to the footnote in the set
|
2009-05-11 02:28:44 +00:00
|
|
|
|
of all footnotes for that page - usually, at the foot of the page. As example of
|
|
|
|
|
|
a citation for Jared Diamond's "Collapse: How Societies Choose to Fail or
|
|
|
|
|
|
Succeed" (2005), you might write:
|
2008-09-28 07:00:34 +00:00
|
|
|
|
|
2009-05-11 02:28:44 +00:00
|
|
|
|
History suggests that societal decline does not result from a single cause,
|
|
|
|
|
|
but rather the confluence of several interwoven causes.((Diamond, Jared. 2005.
|
|
|
|
|
|
**Collapse: How Societies Choose to Fail or Succeed.** %%Viking, New York.%%))
|
|
|
|
|
|
|
|
|
|
|
|
Note that the example above embeds Wiki Creole syntax within the footnote
|
|
|
|
|
|
definition itself. This is perfectly legal and, in fact, encouraged.
|
|
|
|
|
|
|
|
|
|
|
|
=head3 CREATING MULTIPLE FOOTNOTES
|
|
|
|
|
|
|
|
|
|
|
|
footnotes also handles markup resembling:
|
|
|
|
|
|
|
|
|
|
|
|
(($FirstFootnoteText))(($NextFootnoteText))
|
|
|
|
|
|
|
|
|
|
|
|
C<$FirstFootnoteText> and C<$NextFootnoteText> are the text for two adjacent
|
|
|
|
|
|
footnotes. These footnote definitions will be handled and displayed as above,
|
|
|
|
|
|
except that the numbered link for the first footnote will be visually delimited
|
|
|
|
|
|
from the numbered link for the footnote that follows it with a ", ". As example,
|
|
|
|
|
|
you might write:
|
|
|
|
|
|
|
|
|
|
|
|
History suggests that societal decline does not result from a single cause,
|
|
|
|
|
|
but rather the confluence of several interwoven causes.((Diamond, Jared. 2005.
|
|
|
|
|
|
**Collapse: How Societies Choose to Fail or Succeed.** %%Viking, New York.%%))
|
|
|
|
|
|
((Tainter, Joseph. 1988. **The Collapse of Complex Societies.** %%Cambridge
|
|
|
|
|
|
Univ Press, Cambridge, UK.%%))
|
|
|
|
|
|
|
|
|
|
|
|
=head3 REFERENCING ANOTHER FOOTNOTE
|
|
|
|
|
|
|
|
|
|
|
|
footnotes also handles marking resembling:
|
|
|
|
|
|
|
|
|
|
|
|
(($FootnoteNumber))
|
|
|
|
|
|
|
|
|
|
|
|
C<$FootnoteNumber> is the number for another footnote. This module assigns each
|
|
|
|
|
|
footnote definition a unique number, beginning at "1". Thus, this markup allows
|
|
|
|
|
|
you to reference one footnote definition in multiple places throughout a page.
|
|
|
|
|
|
As example, you might write:
|
2015-04-17 01:43:19 +03:00
|
|
|
|
|
2009-05-11 02:28:44 +00:00
|
|
|
|
History suggests that societal decline does not result from a single cause,
|
|
|
|
|
|
but rather the confluence of several interwoven causes.((Diamond, Jared. 2005.
|
|
|
|
|
|
**Collapse: How Societies Choose to Fail or Succeed.** %%Viking, New York.%%))
|
|
|
|
|
|
|
|
|
|
|
|
Such causes include a human-dominated ecosystem moving to a brittle, non-
|
|
|
|
|
|
resilient state due to climatological changes.((Weiss H, Bradley RS. 2001.
|
2015-07-28 22:44:53 +02:00
|
|
|
|
**What drives societal collapse?** %%Science 291:609–610.%%))
|
2009-05-11 02:28:44 +00:00
|
|
|
|
|
|
|
|
|
|
Societal decline only occurs, however, when socio-ecological systems become
|
|
|
|
|
|
brittle and incapable of adaptation.((1))
|
|
|
|
|
|
|
|
|
|
|
|
The final footnote, above, is a reference to the first footnote definition
|
|
|
|
|
|
rather than a new footnote definition.
|
2015-04-17 01:43:19 +03:00
|
|
|
|
|
2009-05-11 02:28:44 +00:00
|
|
|
|
=head3 REFERENCING A RANGE OF OTHER FOOTNOTES
|
|
|
|
|
|
|
|
|
|
|
|
footnotes also handles marking resembling:
|
|
|
|
|
|
|
|
|
|
|
|
(($FirstFootnoteNumber-$LastFootnoteNumber))
|
|
|
|
|
|
|
|
|
|
|
|
C<$FirstFootnoteNumber> and C<$LastFootnoteNumber> are the numbers for two
|
|
|
|
|
|
other footnotes. Thus, this markup allows you to reference a range of footnote
|
|
|
|
|
|
definitions in multiple places throughout a page. As example, you might write:
|
|
|
|
|
|
|
|
|
|
|
|
History suggests that societal decline does not result from a single cause,
|
|
|
|
|
|
but rather the confluence of several interwoven causes.((Diamond, Jared. 2005.
|
|
|
|
|
|
**Collapse: How Societies Choose to Fail or Succeed.** %%Viking, New York.%%))
|
|
|
|
|
|
|
|
|
|
|
|
Such causes include a human-dominated ecosystem moving to a brittle, non-
|
|
|
|
|
|
resilient state due to climatological changes((Weiss H, Bradley RS. 2001.
|
2015-07-28 22:44:53 +02:00
|
|
|
|
**What drives societal collapse?** %%Science 291:609–610.%%)), external
|
2009-05-11 02:28:44 +00:00
|
|
|
|
forcings((Tainter, Jared. 2006. **Social complexity and sustainability.**
|
2015-07-28 22:44:53 +02:00
|
|
|
|
%%Ecol Complex 3:91–103.%%)), or internal pressures((Cullen HM, et al. 2000.
|
2009-05-11 02:28:44 +00:00
|
|
|
|
**Climate change and the collapse of the Akkadian empire: Evidence from the
|
2015-07-28 22:44:53 +02:00
|
|
|
|
deep sea.** %%Geology 28:379–382.%%)).
|
2009-05-11 02:28:44 +00:00
|
|
|
|
|
|
|
|
|
|
Societal decline only occurs, however, when socio-ecological systems become
|
|
|
|
|
|
brittle and incapable of adaptation.((1-2))((4))
|
|
|
|
|
|
|
|
|
|
|
|
The final footnotes, above, are a reference to the first two footnote
|
|
|
|
|
|
definitions followed by a reference to the fourth footnote definition. This
|
|
|
|
|
|
module visually renders this disjoint list like: "1-2, 4".
|
2015-04-17 01:43:19 +03:00
|
|
|
|
|
2008-09-28 07:00:34 +00:00
|
|
|
|
=head3 CREATING THE SET OF FOOTNOTES
|
|
|
|
|
|
|
|
|
|
|
|
footnotes also handles markup resembling:
|
|
|
|
|
|
|
|
|
|
|
|
<footnotes>
|
|
|
|
|
|
|
|
|
|
|
|
This extension replaces that markup with the set of all footnotes for that page.
|
|
|
|
|
|
Note that, if that page has no such markup, this extension automatically places
|
|
|
|
|
|
the set of all footnotes for that page between the content and footer for that
|
2009-05-11 02:28:44 +00:00
|
|
|
|
page. (This may or not be what you want, of course.)
|
2008-09-28 07:00:34 +00:00
|
|
|
|
|
|
|
|
|
|
=cut
|
|
|
|
|
|
sub FootnotesRule {
|
2009-05-11 02:28:44 +00:00
|
|
|
|
# A "((...))" footnote anywhere in a page.
|
|
|
|
|
|
#
|
|
|
|
|
|
# Footnotes and the set of all footnotes must be marked so as to ensure their
|
|
|
|
|
|
# reevaluation, as each of the footnotes might contain Wiki markup requiring
|
|
|
|
|
|
# reevaluation (like, say, free links).
|
2015-08-23 21:22:12 +03:00
|
|
|
|
if (m/\G($FootnotePattern)(?=([ \t]*$FootnotePattern)?)/cgs) {
|
2008-09-28 07:00:34 +00:00
|
|
|
|
Dirty($1); # do not cache the prefixing "\G"
|
2009-05-11 02:28:44 +00:00
|
|
|
|
my $footnote_text = $2;
|
2008-10-01 06:20:48 +00:00
|
|
|
|
my $is_adjacent_footnote = defined $3;
|
|
|
|
|
|
|
2009-05-11 02:28:44 +00:00
|
|
|
|
# A number range (e.g., "2-5") of references to other footnotes.
|
2015-08-23 21:22:12 +03:00
|
|
|
|
if ($footnote_text =~ m/^(\d+)-(\d+)$/) {
|
2009-05-11 02:28:44 +00:00
|
|
|
|
my ($footnote_number_first, $footnote_number_last) = ($1, $2);
|
|
|
|
|
|
# '–', below, is the HTML entity for a Unicode en-dash.
|
|
|
|
|
|
print $q->a({-href=> '#footnotes' .$footnote_number_first,
|
|
|
|
|
|
-title=> 'Footnote #'.$footnote_number_first,
|
|
|
|
|
|
-class=> 'footnote'
|
|
|
|
|
|
}, $footnote_number_first.'–')
|
|
|
|
|
|
.$q->a({-href=> '#footnotes' .$footnote_number_last,
|
|
|
|
|
|
-title=> 'Footnote #'.$footnote_number_last,
|
|
|
|
|
|
-class=> 'footnote'
|
|
|
|
|
|
}, $footnote_number_last.($is_adjacent_footnote ? ', ' : ''));
|
|
|
|
|
|
}
|
|
|
|
|
|
# A number (e.g., "5") implying reference to another footnote.
|
2015-08-23 21:22:12 +03:00
|
|
|
|
elsif ($footnote_text =~ m/^(\d+)$/) {
|
2009-05-11 02:28:44 +00:00
|
|
|
|
my $footnote_number = $1;
|
|
|
|
|
|
print $q->a({-href=> '#footnotes' .$footnote_number,
|
|
|
|
|
|
-title=> 'Footnote #'.$footnote_number,
|
|
|
|
|
|
-class=> 'footnote'
|
|
|
|
|
|
}, $footnote_number.($is_adjacent_footnote ? ', ' : ''));
|
|
|
|
|
|
}
|
|
|
|
|
|
# Otherwise, a new footnote definition.
|
|
|
|
|
|
else {
|
|
|
|
|
|
push(@FootnoteList, $footnote_text);
|
|
|
|
|
|
my $footnote_number = @FootnoteList;
|
|
|
|
|
|
print $q->a({-href=> '#footnotes'.$footnote_number,
|
|
|
|
|
|
-name=> 'footnote' .$footnote_number,
|
|
|
|
|
|
-title=> 'Footnote: '. # Truncate link titles to one line.
|
|
|
|
|
|
( length($footnote_text) > 48
|
|
|
|
|
|
? substr($footnote_text, 0, 44).'...'
|
|
|
|
|
|
: $footnote_text),
|
|
|
|
|
|
-class=> 'footnote'
|
|
|
|
|
|
}, $footnote_number.($is_adjacent_footnote ? ', ' : ''));
|
|
|
|
|
|
}
|
2008-09-28 07:00:34 +00:00
|
|
|
|
|
|
|
|
|
|
return '';
|
|
|
|
|
|
}
|
2009-05-11 02:28:44 +00:00
|
|
|
|
# The "<footnotes>" list of all footnotes at the foot of a page.
|
2015-08-23 21:22:12 +03:00
|
|
|
|
elsif ($bol && m/\G($FootnotesPattern)/cgis) {
|
2008-09-28 07:00:34 +00:00
|
|
|
|
Clean(CloseHtmlEnvironments());
|
|
|
|
|
|
Dirty($1); # do not cache the prefixing "\G"
|
|
|
|
|
|
|
|
|
|
|
|
if (@FootnoteList) {
|
|
|
|
|
|
my ($oldpos, $old_) = (pos, $_);
|
|
|
|
|
|
PrintFootnotes();
|
|
|
|
|
|
Clean(AddHtmlEnvironment('p')); # if dirty block is looked at later, this will disappear
|
|
|
|
|
|
($_, pos) = ($old_, $oldpos); # restore \G (assignment order matters!)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2004-06-17 01:13:18 +00:00
|
|
|
|
return '';
|
2004-01-30 11:53:18 +00:00
|
|
|
|
}
|
2008-09-28 07:00:34 +00:00
|
|
|
|
|
2015-02-27 12:10:18 +02:00
|
|
|
|
return;
|
2004-01-30 11:53:18 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2008-09-28 07:00:34 +00:00
|
|
|
|
# ....................{ HTML OUTPUT }....................
|
2015-04-11 23:41:33 +03:00
|
|
|
|
*PrintFooterFootnotesOld = \&PrintFooter;
|
|
|
|
|
|
*PrintFooter = \&PrintFooterFootnotes;
|
2008-09-28 07:00:34 +00:00
|
|
|
|
|
|
|
|
|
|
=head2 PrintFooterFootnotes
|
2004-01-30 11:53:18 +00:00
|
|
|
|
|
2008-09-28 07:00:34 +00:00
|
|
|
|
Appends the list of footnotes to the footer of the page, if and only if the
|
|
|
|
|
|
user-provided content for that page had no content matching C<$FootersPattern>.
|
|
|
|
|
|
Thus, this function is an eleventh-hour fallback; ideally, pages providing
|
|
|
|
|
|
footnotes also provide an explicit place to list those footnotes.
|
|
|
|
|
|
|
|
|
|
|
|
=cut
|
|
|
|
|
|
sub PrintFooterFootnotes {
|
2004-01-30 11:53:18 +00:00
|
|
|
|
my @params = @_;
|
2008-09-28 07:00:34 +00:00
|
|
|
|
if (@FootnoteList) { PrintFootnotes(); }
|
|
|
|
|
|
PrintFooterFootnotesOld(@params);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
=head2 PrintFootnotes
|
|
|
|
|
|
|
|
|
|
|
|
Prints the list of footnotes.
|
|
|
|
|
|
|
|
|
|
|
|
=cut
|
2015-04-28 00:03:11 +03:00
|
|
|
|
sub PrintFootnotes {
|
2009-05-11 02:28:44 +00:00
|
|
|
|
print
|
|
|
|
|
|
$q->start_div({-class=> 'footnotes'})
|
|
|
|
|
|
.$q->h2(T($FootnotesHeaderText));
|
2008-09-28 07:00:34 +00:00
|
|
|
|
|
|
|
|
|
|
# Don't use <ol>, because we want to link from the number back to
|
|
|
|
|
|
# its page location.
|
2008-10-01 06:20:48 +00:00
|
|
|
|
my $footnote_number = 1;
|
|
|
|
|
|
foreach my $footnote (@FootnoteList) {
|
2009-05-11 02:28:44 +00:00
|
|
|
|
print
|
|
|
|
|
|
$q->start_div({-class=> 'footnote'})
|
|
|
|
|
|
.$q->a({-class=> 'footnote_backlink',
|
|
|
|
|
|
-name=> 'footnotes'.$footnote_number,
|
|
|
|
|
|
-href=> '#footnote' .$footnote_number}, $footnote_number.'.')
|
2008-09-28 07:00:34 +00:00
|
|
|
|
.' ';
|
2008-10-01 06:20:48 +00:00
|
|
|
|
ApplyRules($footnote, 1);
|
2009-05-11 02:28:44 +00:00
|
|
|
|
print $q->end_div();
|
2008-09-28 07:00:34 +00:00
|
|
|
|
|
2008-10-01 06:20:48 +00:00
|
|
|
|
$footnote_number++;
|
2004-01-30 11:53:18 +00:00
|
|
|
|
}
|
2008-09-28 07:00:34 +00:00
|
|
|
|
|
2009-05-11 02:28:44 +00:00
|
|
|
|
print $q->end_div();
|
|
|
|
|
|
|
|
|
|
|
|
# Empty the footnotes, now; this prevents our calling the fallback, later.
|
|
|
|
|
|
@FootnoteList = ();
|
2004-01-30 11:53:18 +00:00
|
|
|
|
}
|
2008-09-28 07:00:34 +00:00
|
|
|
|
|
|
|
|
|
|
=head1 COPYRIGHT AND LICENSE
|
|
|
|
|
|
|
|
|
|
|
|
The information below applies to everything in this distribution,
|
|
|
|
|
|
except where noted.
|
|
|
|
|
|
|
|
|
|
|
|
Copyleft 2008 by B.w.Curry <http://www.raiazome.com>.
|
|
|
|
|
|
Copyright 2004 by Alex Schroeder <alex@emacswiki.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 L<http://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
|
|
|
|
=cut
|