Ikiwiki plugin: Support IkiWiki 3.00.
[muse-el.git] / contrib / ikiwiki / IkiWiki / Plugin / muse.pm
blob45673774596eadb0b29884d6880a3eb97298d0d4
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_init => {
35 type => "string",
36 example => "~/ikiwiki/muse-init.el",
37 description => "the location of your Muse init file",
38 safe => 1,
39 rebuild => 1,
44 # Handle Muse directives
45 sub scan (@) {
46 my %params=@_;
47 return unless pagetype($pagesources{$params{page}}) eq 'muse';
48 my $canmeta = UNIVERSAL::can('IkiWiki::Plugin::meta', 'preprocess');
49 my $cantag = UNIVERSAL::can('IkiWiki::Plugin::tag', 'preprocess_tag');
50 return unless $canmeta || $cantag;
51 my $fun;
53 $_ = $params{content};
54 pos = undef;
55 while ( m/ \G \# ([a-zA-Z-]+) \s+ (.+?) \n+ /sgx ) {
56 my ($key, $val) = ($1, $2);
57 if ( $key =~ m/^(tags?|category)$/s ) {
58 next unless $cantag;
59 $fun = sub {
60 IkiWiki::Plugin::tag::preprocess_tag(
61 (map { $_ => '' } (split /\s+/, $val)),
62 page => $params{page},
63 destpage => $params{page},
64 preview => 1,
68 else {
69 next unless $canmeta;
70 if ( $key eq 'date' ) {
71 # Support pyblosxom-style dates (YYYY-MM-DD(-hh-mm)?)
72 my $re = qr/ ^ ([0-9]{4}) - ([0-1][0-9]) - ([0-3][0-9])
73 (?: - ([0-2][0-9]) - ([0-5][0-9]) )? $ /sx;
74 if ( $val =~ m/$re/ ) {
75 my @array = (0, $5 || 0, $4 || 0, $3, $2, $1 - 1900);
76 $val = Date::Format::strftime("%a, %e %b %Y %T", @array);
79 $fun = sub {
80 IkiWiki::Plugin::meta::preprocess(
81 $key, $val,
82 page => $params{page},
83 destpage => $params{page},
84 preview => 1,
88 if ( $params{muse_filter} ) {
89 # Make "wantarray" work in the meta plugin
90 my $ret = $fun->();
92 else {
93 $fun->();
98 # Pass the content of the page to Muse for publishing
99 sub filter (@) {
100 my %params=@_;
101 return $params{content}
102 unless pagetype($pagesources{$params{page}}) eq 'muse';
104 # Force detection of the Muse #date directive
105 scan(
106 content => $params{content},
107 page => $params{page},
108 muse_filter => 1,
111 my $content = Encode::encode_utf8($params{content});
112 my $qname = $params{page};
113 $qname =~ s/"/\\"/g;
115 my ($fh, $filename) = File::Temp::tempfile();
116 print $fh $content;
117 close $fh;
118 my $qfile = $filename;
119 $qfile =~ s/"/\\"/g;
120 eval {
121 system qw( emacs -q --no-site-file -batch -l ),
122 $config{muse_init}, '--eval',
123 qq{(muse-ikiwiki-publish-file "$qfile" "$qname")};
125 open my $ifh, '<', $filename;
126 local $/;
127 $content = <$ifh>;
128 close $ifh;
130 unlink $filename;
132 if ($@) {
133 my $ret = $@;
134 unlink $filename;
135 die $ret;
137 return Encode::decode_utf8($content);
140 # Fake handler to make publishing work
141 sub htmlize (@) {
142 my %params=@_;
143 return $params{content};