1#!/usr/local/bin/perl -w
2
3# generate a .typ file and call gtypist to run this file
4#
5# Yuusuke Mita <neiklotrrj@yahoo.com>, Felix Natter <fnatter@gmx.net>
6# Some fixes by Stefan Troeger <stefan@troeger.st>
7#
8# This program is free software; you can redistribute it and/or
9# modify it under the terms of the GNU General Public License
10# as published by the Free Software Foundation, either version 3
11# of the License, or (at your option) any later version.
12#
13# This program is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16# GNU General Public License for more details.
17#
18# You should have received a copy of the GNU General Public License
19# along with this program; if not, write to the Free Software
20# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21
22use strict qw (subs vars refs);
23use Carp;
24use File::Temp qw (tempfile);
25use Getopt::Std;
26
27# subroutines
28
29# this creates a B:-command (centered on 66 columns because
30# "gtypist <version>" is in the right corner)
31sub getBanner($)
32{
33    my $banner = $_[0];
34    # remove whitespace at the beginning ...
35    $banner =~ s/^\s*//;
36    # ... and at the end
37    $banner =~ s/\s*$//;
38    return "B:" . " " x (33 - int((length($banner) / 2))) . $banner . "\n";
39}
40
41my %opts;
42if (!getopts ("dslhn:o:", \%opts) || $opts{h}) {
43    print "SYNTAX: typefortune [-dslh] [-n count] [-o gtypist_opts]\n";
44    print "-d: use D: (instead of S:)\n";
45    print "-s: use fortune -s\n";
46    print "-l: use fortune -l\n";
47    print "-n <count>: practice <count> fortunes (default=1)\n";
48    print "-o <gtypist_options>: pass options to gtypist\n";
49    print "See the gtypist manual (info gtypist or info '(gtypist)') " .
50	"for details.\n";
51    if ($opts{h}) {
52	exit 0;
53    } else {
54	exit 1;
55    }
56}
57
58# operate on command-line arguments
59my $exercise_type = "S:";
60if ($opts{d}) { $exercise_type = "D:"; }
61my $max_lines = 22;
62if ($exercise_type eq "D:" || $exercise_type eq "d:") { $max_lines = 11; }
63if ($opts{s} && $opts{l}) { die "-s and -l cannot be used together"; }
64my $fortune_options = "";
65if ($opts{s}) { $fortune_options .= " -s"; }
66if ($opts{l}) { $fortune_options .= " -l"; }
67my $count = 1;
68if (defined ($opts{n})) { $count = $opts{n}; }
69
70# create option-list for gtypist
71my $gtypist_options = "";
72if (!defined ($opts{o})) {
73    # avoid warning
74    $opts{o} = "";
75}
76foreach my $opt (split (/\s+/, $opts{o}))
77{
78    my $sepidx = index ($opt, ",");
79    if ($sepidx == -1) {
80	# boolean option
81	if (length ($opt) == 1) { # short option
82	    $gtypist_options .= "-" . $opt;
83	} else { # long option
84	    $gtypist_options .= "--" . $opt;
85	}
86    } else {
87	# option with value
88	if ($sepidx == 1) { # short option
89	    $gtypist_options .= "-" . substr ($opt, 0, 1);
90	} else { # long option
91	    $gtypist_options .= "--" . substr ($opt, 0, $sepidx - 1);
92	}
93	$gtypist_options .= " " . substr ($opt, $sepidx + 1);
94    }
95    $gtypist_options .= " ";
96}
97
98my $i;
99my $j;
100my @lines;
101my ($typfile, $typfilename);
102
103eval {
104  ($typfile, $typfilename) =
105      tempfile("typefortune.XXXXXX", DIR => "/tmp", UNLINK => 1);
106};
107if ($@) {
108  croak "Couldn't create temporary file in /tmp";
109}
110
111# note: $#lines is the index of the last line (and not the length of @lines)
112print $typfile "# temporary file created by typefortune\n";
113print $typfile "K:12:END\n";
114for ($i = 0; $i < $count; $i++)
115{
116    {
117        local $^W = 0;
118        do {
119            @lines = split (/\n/, `fortune$fortune_options`);
120            die "Couldn't find fortune" unless $? == 0;
121        } while ($#lines >= $max_lines);
122    }
123
124    # maybe insert banner
125    if ($#lines > 0 && $lines[$#lines] =~ /^\s*-- (.+)\s*/) {
126	print $typfile getBanner($1);
127	pop @lines;
128    } else {
129	# clear any existing banner
130	print $typfile "B:\n";
131    }
132
133    print $typfile "I:fortune ". ($i + 1) . "/" . $count . "\n";
134
135    # print lines
136    for ($j = 0; $j <= $#lines; $j++)
137    {
138	if ($j == 0) {
139	    print $typfile "$exercise_type";
140	} else {
141	    print $typfile " :";
142	}
143	print $typfile $lines[$j];
144	print $typfile "\n";
145    }
146}
147
148print $typfile getBanner("Practice complete");
149print $typfile "T:\n :\n :\n : Congratulations: " .
150    "you successfully completed the $count " .
151    "fortune lessons !\n";
152print $typfile "*:END\nX:\n";
153close($typfile) || die "Couldn't close $typfilename: $!";
154
155# call gtypist
156system("gtypist $gtypist_options $typfilename");
157