Merge branch 'master' of ssh://git.ikiwiki.info/srv/git/ikiwiki.info
[ikiwiki] / IkiWiki / Plugin / otl.pm
1 #!/usr/bin/perl
2 # outline markup
3 package IkiWiki::Plugin::otl;
4
5 use warnings;
6 use strict;
7 use IkiWiki 3.00;
8 use open qw{:utf8 :std};
9
10 sub import {
11         hook(type => "getsetup", id => "otl", call => \&getsetup);
12         hook(type => "htmlize", id => "otl", call => \&htmlize);
13 }
14
15 sub getsetup () {
16         return 
17                 plugin => {
18                         safe => 1,
19                         rebuild => 1, # format plugin
20                         section => "format",
21                 },
22 }
23
24 sub htmlize (@) {
25         my %params=@_;
26         
27         # Munge up check boxes to look a little bit better.
28         my $checked=htmllink($params{page}, $params{page},
29                 "smileys/star_on.png", linktext => "[X]");
30         my $unchecked=htmllink($params{page}, $params{page},
31                 "smileys/star_off.png", linktext => "[_]");
32         $params{content}=~s/^(\s*)\[X\]\s/${1}$checked /mg;
33         $params{content}=~s/^(\s*)\[_\]\s/${1}$unchecked /mg;
34
35         # Can't use open2 since otl2html doesn't play nice with buffering.
36         # Instead, fork off a child process that will run otl2html and feed
37         # it the content. Then read otl2html's response.
38
39         my $tries=10;
40         my $pid;
41         do {
42                 $pid = open(KID_TO_READ, "-|");
43                 unless (defined $pid) {
44                         $tries--;
45                         if ($tries < 1) {
46                                 debug("failed to fork: $@");
47                                 return $params{content};
48                         }
49                 }
50         } until defined $pid;
51
52         if (! $pid) {
53                 $tries=10;
54                 $pid=undef;
55
56                 do {
57                         $pid = open(KID_TO_WRITE, "|-");
58                         unless (defined $pid) {
59                                 $tries--;
60                                 if ($tries < 1) {
61                                         debug("failed to fork: $@");
62                                         print $params{content};
63                                         exit;
64                                 }
65                         }
66                 } until defined $pid;
67
68                 if (! $pid) {
69                         if (! exec 'otl2html', '-S', '/dev/null', '-T', '/dev/stdin') {
70                                 debug("failed to run otl2html: $@");
71                                 print $params{content};
72                                 exit;
73                         }
74                 }
75
76                 print KID_TO_WRITE $params{content};
77                 close KID_TO_WRITE;
78                 waitpid $pid, 0;
79                 exit;
80         }
81         
82         local $/ = undef;
83         my $ret=<KID_TO_READ>;
84         close KID_TO_READ;
85         waitpid $pid, 0;
86
87         $ret=~s/.*<body>//s;
88         $ret=~s/<body>.*//s;
89         $ret=~s/<div class="Footer">.*//s;
90         return $ret;
91 }
92
93 1