d30ce8c4e50dfc7788d93cc05cf3a161d663cb14
[muse-el.git] / contrib / ikiwiki / IkiWiki / Plugin / muse.pm
blobd30ce8c4e50dfc7788d93cc05cf3a161d663cb14
1 #!/usr/bin/perl
2 # Ikiwiki plugin for Emacs Muse.
3 # Author: Michael Olson
4 # License: GPLv2 or later
6 # In your ikiwiki.setup file, set the muse_init option to the location
7 # of the init file for Muse. Some examples provided in the
8 # examples/ikiwiki directory are muse-init-simple.el and
9 # muse-init-project.el.
11 package IkiWiki::Plugin::muse;
13 use warnings;
14 use strict;
15 use IkiWiki 2.00;
16 use Date::Format qw();
17 use Encode qw();
18 use File::Temp qw();
20 sub import {
21 hook(type => "getsetup", id => "muse", call => \&getsetup);
22 hook(type => "scan", id => "muse", call => \&scan);
23 hook(type => "filter", id => "muse", call => \&filter);
24 hook(type => "htmlize", id => "muse", call => \&htmlize);
27 sub getsetup () {
28 return (
29 plugin => {
30 safe => 1,
31 rebuild => 1, # format plugin
33 muse_init => {
34 type => "string",
35 example => "~/ikiwiki/muse-init.el",
36 description => "the location of your Muse init file",
37 safe => 1,
38 rebuild => 1,
43 # Handle Muse directives
44 sub scan (@) {
45 my %params=@_;
46 return unless pagetype($pagesources{$params{page}}) eq 'muse';
47 my $canmeta = IkiWiki::Plugin::meta->can("preprocess");
48 my $cantag = IkiWiki::Plugin::tag->can("preprocess_tag");
49 return unless $canmeta || $cantag;
50 my $fun;
52 $_ = $params{content};
53 pos = undef;
54 while ( m/ \G \# ([a-zA-Z-]+) \s+ (.+?) \n+ /sgx ) {
55 my ($key, $val) = ($1, $2);
56 if ( $key =~ m/^(tags?|category)$/s ) {
57 next unless $cantag;
58 $fun = sub {
59 IkiWiki::Plugin::tag::preprocess_tag(
60 (map { $_ => '' } (split /\s+/, $val)),
61 page => $params{page},
62 destpage => $params{page},
63 preview => 1,
67 else {
68 next unless $canmeta;
69 if ( $key eq 'date' ) {
70 # Support pyblosxom-style dates (YYYY-MM-DD(-hh-mm)?)
71 my $re = qr/ ^ ([0-9]{4}) - ([0-1][0-9]) - ([0-3][0-9])
72 (?: - ([0-2][0-9]) - ([0-5][0-9]) )? $ /sx;
73 if ( $val =~ m/$re/ ) {
74 my @array = (0, $5 || 0, $4 || 0, $3, $2, $1 - 1900);
75 $val = Date::Format::strftime("%a, %e %b %Y %T", @array);
78 $fun = sub {
79 IkiWiki::Plugin::meta::preprocess(
80 $key, $val,
81 page => $params{page},
82 destpage => $params{page},
83 preview => 1,
87 if ( $params{muse_filter} ) {
88 # Make "wantarray" work in the meta plugin
89 my $ret = $fun->();
91 else {
92 $fun->();
97 # Pass the content of the page to Muse for publishing
98 sub filter (@) {
99 my %params=@_;
100 return $params{content}
101 unless pagetype($pagesources{$params{page}}) eq 'muse';
103 # Force detection of the Muse #date directive
104 scan(
105 content => $params{content},
106 page => $params{page},
107 muse_filter => 1,
110 my $content = Encode::encode_utf8($params{content});
111 my $qname = $params{page};
112 $qname =~ s/"/\\"/g;
114 my ($fh, $filename) = File::Temp::tempfile();
115 print $fh $content;
116 close $fh;
117 my $qfile = $filename;
118 $qfile =~ s/"/\\"/g;
119 eval {
120 system qw( emacs -q --no-site-file -batch -l ),
121 $config{muse_init}, '--eval',
122 qq{(muse-ikiwiki-publish-file "$qfile" "$qname")};
124 open my $ifh, '<', $filename;
125 local $/;
126 $content = <$ifh>;
127 close $ifh;
129 unlink $filename;
131 if ($@) {
132 unlink $filename;
133 die $@;
135 return Encode::decode_utf8($content);
138 # Fake handler to make publishing work
139 sub htmlize (@) {
140 my %params=@_;
141 return $params{content};