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