Add new gavinc plugins to MANIFEST.medium.
[matthijs/upstream/blosxom-plugins.git] / gavinc / metamail
1 # Blosxom Plugin: metamail
2 # Author(s): Gavin Carr <gavin@openfusion.com.au>
3 # Version: 0.001000
4 # Documentation: 'perldoc metamail'
5 # Requires: metaclear
6 # Follows: metaclear
7
8 package metamail;
9
10 use strict;
11
12 #use Blosxom::Debug debug_level => 1;
13
14 # --- Configurable variables -----
15
16 # Headers to consider titles
17 my @title_headers = qw(Title Subject);
18
19 # Headers to keep in the body (required by later plugins, for instance)
20 my @keep_in_body_headers = qw(Tags);
21
22 # Whether to unfold (join) multi-line headers
23 my $unfold_headers = 1;
24
25 # --------------------------------
26
27 sub start { 1 };
28
29 sub story {
30   my($pkg, $path, $filename, $story_ref, $title_ref, $body_ref) = @_;
31
32   my %header = ();
33   my ($headers, $body) = split /\n\s*\n/, $$title_ref . "\n" . $$body_ref, 2;
34
35   my $meta = \%blosxom::meta;
36
37   # Walk the headers
38   for my $header ( split /\n(?=\S)/, $headers ) {
39     # Split header into key/value
40     my ($key, $key2, $value);
41     if ($header =~ m/:/) {
42       ($key, $value) = split /:\s*/, $header, 2;  
43     }
44     # For backwards compatibility, assume a header without a : is a title
45     else {
46       $key = @title_headers[0] || 'Title';
47       $value = $header;
48     }
49     chomp $value;
50     
51     # Unfold
52     $value =~ s/\n //g if $unfold_headers;
53
54     # Cache header
55     $header{$key} = $value;
56
57     # Insert into meta namespace
58     $meta->{$key} = $value;
59     # debug(1, "metamail: $key: " . $meta->{$key} . "\n");
60     # Insert lowercase/underscored version as well
61     ($key2 = lc $key) =~ s/-/_/g;
62     if ($key ne $key2) {
63       $meta->{$key2} = $value;
64       # debug(1, "metamail: $key2: " . $meta->{$key2} . "\n");
65     }
66   }
67
68   # Update $$title_ref to the first title_header we can find
69   $$title_ref = '';
70   for (@title_headers) {
71     $$title_ref = $header{$_} and last if $header{$_};
72   }
73
74   # Update body_ref
75   if (my @keep_headers = grep { defined $header{$_} } @keep_in_body_headers) {
76     $$body_ref = join("\n", map { "$_: $header{$_}" } @keep_headers) . "\n" . $body;
77   }
78   else {
79     $$body_ref = $body;
80   }
81
82   return 1;
83 }
84
85 1;
86
87 __END__
88
89 =head1 NAME
90
91 metamail - an alternative to Rael's original L<meta> plugin, supporting
92 mail/RFC822-style headers in posts
93
94 =head1 DESCRIPTION
95
96 metamail is a plugin for loading metadata from the 'headers' in a 
97 blosxom post. Metadata is loaded into a %blosxom::meta hash (instead of
98 into package variables like L<meta>). metamail expects posts to look like 
99 RFC822-style mails i.e. a bunch of headers, where a header is a key (no 
100 whitespace) followed by a colon followed by a value; then an empty line 
101 as a separator; and then the post body.
102
103 metamail loads all headers it finds as variables into the %blosxom::meta
104 hash. It typically creates two entries for each header: the first is named 
105 exactly as the key is given in the header, and the second is the key 
106 converted to lowercase, and with dashes converted to underscores.
107
108 So given the following headers:
109
110     Title: Test Post 1
111     Tags: test, ignore
112     URL: http://www.openfusion.net/
113
114 metamail will create the following %blosxom::meta entries:
115    
116     $blosxom::meta{Title} = 'Test Post 1';
117     $blosxom::meta{title} = 'Test Post 1';
118     $blosxom::meta{Tags} = 'test, ignore';
119     $blosxom::meta{tags} = 'test, ignore';
120     $blosxom::meta{URL} = 'http://www.openfusion.net/';
121     $blosxom::meta{url} = 'http://www.openfusion.net/';
122
123 For backwards compatibility purposes, L<metamail> will treat any header
124 not containing a colon (which is typically the first line title) as the 
125 'Title' of the post, and store it with the first key in @title_headers
126 (default is 'Title'). L<metamail> supports the title being anywhere in 
127 the headers, and will report it properly to blosxom, but any plugins 
128 that look directly at the post file may still expect the title 
129 (without a key) to be there in the first line, so that is currently
130 still the recommended convention.
131
132 =head1 USAGE
133
134 This plugin requires the L<metaclear> plugin to reset the %blosxom::meta
135 hash for each story, and should be loaded early, after L<metaclear>, but
136 typically before all other story plugins e.g. as 05metamail. 
137
138 This is an *alternative* to the L<meta> plugin, so should usually be used 
139 _instead_ of L<meta>, not as well.
140
141 =head1 SEE ALSO
142
143 L<metaclear>, L<metadir>, L<metafile>.
144
145 L<meta>, Rael Dornfest's original metadata plugin
146
147 Blosxom: http://blosxom.sourceforge.net/
148
149 =head1 AUTHOR
150
151 Gavin Carr <gavin@openfusion.com.au>, http://www.openfusion.net/
152
153 =head1 LICENSE
154
155 Copyright 2007, Gavin Carr.
156
157 This plugin is licensed under the same terms as blosxom itself i.e.
158
159 Permission is hereby granted, free of charge, to any person obtaining a
160 copy of this software and associated documentation files (the "Software"),
161 to deal in the Software without restriction, including without limitation
162 the rights to use, copy, modify, merge, publish, distribute, sublicense,
163 and/or sell copies of the Software, and to permit persons to whom the
164 Software is furnished to do so, subject to the following conditions:
165
166 The above copyright notice and this permission notice shall be included
167 in all copies or substantial portions of the Software.
168
169 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
170 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
171 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
172 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
173 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
174 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
175 OTHER DEALINGS IN THE SOFTWARE.
176
177 =cut
178
179 # vim:ft=perl