Ikiwiki plugin: Make location of emacs configurable.
[muse-el.git] / contrib / ikiwiki / IkiWiki / Plugin / muse.pm
blob1d5257f92a02fb4f9efadaacfa794cc34451a6a7
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 3.00;
17 use Date::Format ();
18 use Encode ();
19 use File::Temp ();
21 sub import {
22 hook(type => "getsetup", id => "muse", call => \&getsetup);
23 hook(type => "scan", id => "muse", call => \&scan);
24 hook(type => "filter", id => "muse", call => \&filter);
25 hook(type => "htmlize", id => "muse", call => \&htmlize);
28 sub getsetup () {
29 return (
30 plugin => {
31 safe => 1,
32 rebuild => 1, # format plugin
34 muse_emacs => {
35 type => "string",
36 example => "/usr/bin/emacs",
37 description => "the location of Emacs",
38 safe => 1,
39 rebuild => 1,
41 muse_init => {
42 type => "string",
43 example => "~/ikiwiki/muse-init.el",
44 description => "the location of your Muse init file",
45 safe => 1,
46 rebuild => 1,
51 # Handle Muse directives
52 sub scan (@) {
53 my %params=@_;
54 return unless pagetype($pagesources{$params{page}}) eq 'muse';
55 my $canmeta = UNIVERSAL::can('IkiWiki::Plugin::meta', 'preprocess');
56 my $cantag = UNIVERSAL::can('IkiWiki::Plugin::tag', 'preprocess_tag');
57 return unless $canmeta || $cantag;
58 my $fun;
60 $_ = $params{content};
61 pos = undef;
62 while ( m/ \G \# ([a-zA-Z-]+) \s+ (.+?) \n+ /sgx ) {
63 my ($key, $val) = ($1, $2);
64 if ( $key =~ m/^(tags?|category)$/s ) {
65 next unless $cantag;
66 $fun = sub {
67 IkiWiki::Plugin::tag::preprocess_tag(
68 (map { $_ => '' } (split /\s+/, $val)),
69 page => $params{page},
70 destpage => $params{page},
71 preview => 1,
75 else {
76 next unless $canmeta;
77 if ( $key eq 'date' ) {
78 # Support pyblosxom-style dates (YYYY-MM-DD(-hh-mm)?)
79 my $re = qr/ ^ ([0-9]{4}) - ([0-1][0-9]) - ([0-3][0-9])
80 (?: - ([0-2][0-9]) - ([0-5][0-9]) )? $ /sx;
81 if ( $val =~ m/$re/ ) {
82 my @array = (0, $5 || 0, $4 || 0, $3, $2, $1 - 1900);
83 $val = Date::Format::strftime("%a, %e %b %Y %T", @array);
86 $fun = sub {
87 IkiWiki::Plugin::meta::preprocess(
88 $key, $val,
89 page => $params{page},
90 destpage => $params{page},
91 preview => 1,
95 if ( $params{muse_filter} ) {
96 # Make "wantarray" work in the meta plugin
97 my $ret = $fun->();
99 else {
100 $fun->();
105 # Determine the emacs binary to use
106 sub locate_emacs {
107 my $err = sub {
108 die "Unable to find your emacs binary.\n",
109 " Set muse_emacs config to the right value.\n";
111 if ( $config{muse_emacs} ) {
112 ( -x $config{muse_emacs} ) ? return $config{muse_emacs} : $err->();
114 else {
115 my $emacs = `which emacs`;
116 chomp $emacs;
117 ( $emacs ) ? return $emacs : $err->();
121 # Pass the content of the page to Muse for publishing
122 sub filter (@) {
123 my %params=@_;
124 return $params{content}
125 unless pagetype($pagesources{$params{page}}) eq 'muse';
127 # Force detection of the Muse #date directive
128 scan(
129 content => $params{content},
130 page => $params{page},
131 muse_filter => 1,
134 my $content = Encode::encode_utf8($params{content});
135 my $qname = $params{page};
136 $qname =~ s/"/\\"/g;
138 my ($fh, $filename) = File::Temp::tempfile();
139 print $fh $content;
140 close $fh;
141 my $qfile = $filename;
142 $qfile =~ s/"/\\"/g;
143 eval {
144 system locate_emacs(),
145 qw( -q --no-site-file -batch -l ), $config{muse_init},
146 '--eval', qq{(muse-ikiwiki-publish-file "$qfile" "$qname")};
148 open my $ifh, '<', $filename;
149 local $/; $content = <$ifh>;
150 close $ifh;
152 unlink $filename;
154 if ($@) {
155 my $ret = $@;
156 unlink $filename;
157 die $ret;
159 return Encode::decode_utf8($content);
162 # Fake handler to make publishing work
163 sub htmlize (@) {
164 my %params=@_;
165 return $params{content};