[system] / trunk / webwork-modperl / lib / WeBWorK / ContentGenerator / Hardcopy.pm Repository:
ViewVC logotype

Annotation of /trunk/webwork-modperl/lib/WeBWorK/ContentGenerator/Hardcopy.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 614 - (view) (download) (as text)

1 : sh002i 478 ################################################################################
2 : sh002i 494 # WeBWorK mod_perl (c) 2000-2002 WeBWorK Project
3 : sh002i 478 # $Id$
4 :     ################################################################################
5 :    
6 :     package WeBWorK::ContentGenerator::Hardcopy;
7 :    
8 :     =head1 NAME
9 :    
10 :     WeBWorK::ContentGenerator::Test - generate a PDF version of one or more
11 :     problem sets.
12 :    
13 :     =cut
14 :    
15 :     use strict;
16 :     use warnings;
17 :     use base qw(WeBWorK::ContentGenerator);
18 :     use Apache::Constants qw(:common);
19 :     use CGI qw();
20 : sh002i 502 use File::Path qw(rmtree);
21 :     use File::Temp qw(tempdir);
22 :     use WeBWorK::DB::Classlist;
23 :     use WeBWorK::DB::WW;
24 : sh002i 478 use WeBWorK::Form;
25 :     use WeBWorK::Utils qw(readFile);
26 :    
27 : sh002i 492 sub texBlockComment { return "\n".("%"x80)."\n%% ".join("", @_)."\n".("%"x80)."\n\n"; }
28 :    
29 : sh002i 502 sub initialize {
30 :     my $self = shift;
31 :     my $ce = $self->{courseEnvironment};
32 :     $self->{cldb} = WeBWorK::DB::Classlist->new($ce);
33 :     $self->{wwdb} = WeBWorK::DB::WW->new($ce);
34 :     }
35 :    
36 :     sub path {
37 :     my ($self, undef, $args) = @_;
38 :    
39 :     my $ce = $self->{courseEnvironment};
40 :     my $root = $ce->{webworkURLs}->{root};
41 :     my $courseName = $ce->{courseName};
42 :     return $self->pathMacro($args,
43 :     "Home" => "$root",
44 :     $courseName => "$root/$courseName",
45 :     "Hardcopy Generator" => "",
46 :     );
47 :     }
48 :    
49 :     sub title {
50 : sh002i 547 return "Hardcopy Generator";
51 : sh002i 502 }
52 :    
53 :     sub body {
54 : sh002i 478 my ($self, $singleSet) = @_;
55 :     $singleSet =~ s/^set//;
56 :     my $r = $self->{r};
57 :     my $ce = $self->{courseEnvironment};
58 :     $self->{wwdb} = WeBWorK::DB::WW->new($ce);
59 :    
60 :     my @sets = $r->param("set");
61 :     unshift @sets, $singleSet;
62 : sh002i 502 unless (@sets) {
63 :     print CGI::p("No problem sets were specified.");
64 :     return OK;
65 :     }
66 : sh002i 478
67 : sh002i 562 #print CGI::pre($self->getMultiSetTeX(@sets));
68 :     #return "";
69 :    
70 : sh002i 502 print CGI::p("Generating your hardcopy...");
71 :     my $url = $self->makeHardcopy(@sets);
72 :     if ($url) {
73 :     print CGI::p("Ok, your hardcopy is ready. Click the following link to download it.");
74 :     print CGI::p({-align=>"center"},
75 :     CGI::big(CGI::a({-href=>$url}, "Download PDF Hardcopy"))
76 :     );
77 :     } else {
78 :     print CGI::p("Hmm, looks like I was unable to generate the hardcopy you requested. I'm really sorry... :(");
79 :     }
80 : sh002i 478
81 : sh002i 502 return "";
82 : sh002i 478 }
83 :    
84 : sh002i 502 # -----
85 :    
86 :     sub makeHardcopy {
87 : sh002i 492 my ($self, @sets) = @_;
88 : sh002i 502 my $courseName = $self->{courseEnvironment}->{courseName};
89 :     my $userName = $self->{r}->param("user");
90 :     my $tempDir = $self->{courseEnvironment}->{courseDirs}->{html_temp}
91 :     . "/hardcopy";
92 :     my $tempURL = $self->{courseEnvironment}->{courseURLs}->{html_temp}
93 :     . "/hardcopy";
94 :    
95 :     # determine name of PDF file
96 :     my $fileName;
97 :     if (@sets > 1) {
98 :     # multiset output
99 :     $fileName = "$courseName.$userName.multiset.pdf"
100 :     } elsif (@sets == 1) {
101 :     # only one set
102 :     my $setName = $sets[0];
103 :     $fileName = "$courseName.$userName.$setName.pdf";
104 :     } else {
105 :     $fileName = "$courseName.$userName.pdf";
106 :     }
107 :     my $tex = $self->getMultiSetTeX(@sets);
108 :     $self->latex2pdf($tex, $tempDir, $fileName) or return;
109 :    
110 :     return "$tempURL/$fileName";
111 :     }
112 :    
113 :     sub latex2pdf {
114 :     # this is a little ad-hoc function which I will replace with a LaTeX
115 :     # module at some point (or put it in Utils).
116 :     my ($self, $tex, $fileBase, $fileName) = @_;
117 :     my $finalFile = "$fileBase/$fileName";
118 : sh002i 492 my $ce = $self->{courseEnvironment};
119 : sh002i 502
120 :     # create a temporary directory for tex to shit in
121 :     my $wd = tempdir("webwork-hardcopy-XXXXXXXX", TMPDIR => 1);
122 :     my $texFile = "$wd/hardcopy.tex";
123 :     my $pdfFile = "$wd/hardcopy.pdf";
124 : sh002i 562 my $logFile = "$wd/hardcopy.log";
125 : sh002i 502
126 :     # write the tex file
127 :     local *TEX;
128 :     open TEX, ">", $texFile;
129 :     print TEX $tex;
130 :     close TEX;
131 :    
132 :     # call pdflatex - we don't want to chdir in the mod_perl process, as
133 :     # that might step on the feet of other things (esp. in Apache 2.0)
134 : sh002i 492 my $pdflatex = $ce->{externalPrograms}->{pdflatex};
135 : sh002i 502 system "cd $wd && $pdflatex $texFile";
136 : sh002i 478
137 : sh002i 502 if (-e $pdfFile) {
138 :     # move resulting PDF file to appropriate location
139 :     my $mv = $ce->{externalPrograms}->{mv};
140 :     system $mv, $pdfFile, $finalFile and die "Failed to mv: $!\n";
141 :     }
142 :    
143 :     # remove temporary directory
144 : sh002i 607 #rmtree($wd, 0, 1);
145 : sh002i 502
146 :     return -e $finalFile;
147 : sh002i 478 }
148 :    
149 : sh002i 502 # -----
150 :    
151 :     sub getMultiSetTeX {
152 : sh002i 492 my ($self, @sets) = @_;
153 :     my $ce = $self->{courseEnvironment};
154 : sh002i 502 my $tex = "";
155 : sh002i 492
156 : sh002i 502 # the document preamble
157 :     $tex .= $self->texInclude($ce->{webworkFiles}->{hardcopySnippets}->{preamble});
158 : sh002i 492
159 :     while (my $set = shift @sets) {
160 : sh002i 502 $tex .= $self->getSetTeX($set);
161 : sh002i 492 if (@sets) {
162 :     # divide sets, but not after the last set
163 : sh002i 502 $tex .= $self->texInclude($ce->{webworkFiles}->{hardcopySnippets}->{setDivider});
164 : sh002i 492 }
165 :     }
166 :    
167 : sh002i 502 # the document postamble
168 :     $tex .= $self->texInclude($ce->{webworkFiles}->{hardcopySnippets}->{postamble});
169 :    
170 :     return $tex;
171 : sh002i 492 }
172 :    
173 : sh002i 478 sub getSetTeX {
174 :     my ($self, $setName) = @_;
175 :     my $ce = $self->{courseEnvironment};
176 :     my $wwdb = $self->{wwdb};
177 :     my $user = $self->{r}->param("user");
178 : sh002i 492 my @problemNumbers = sort { $a <=> $b } $wwdb->getProblems($user, $setName);
179 : sh002i 478
180 : sh002i 492 # get header and footer
181 :     my $setHeader = $wwdb->getSet($user, $setName)->set_header
182 :     || $ce->{webworkFiles}->{hardcopySnippets}->{setHeader};
183 :     # database doesn't support the following yet :(
184 :     #my $setFooter = $wwdb->getSet($user, $setName)->set_footer
185 :     # || $ce->{webworkFiles}->{hardcopySnippets}->{setFooter};
186 : sh002i 502 # so we don't allow per-set customization, which is probably okay :)
187 :     my $setFooter = $ce->{webworkFiles}->{hardcopySnippets}->{setFooter};
188 : sh002i 478
189 : sh002i 502 my $tex = "";
190 :    
191 : sh002i 492 # render header
192 : sh002i 502 $tex .= texBlockComment("BEGIN $setName : $setHeader");
193 : sh002i 547 $tex .= $self->getProblemTeX($setName, 0, $setHeader);
194 : sh002i 478
195 :     # render each problem
196 : sh002i 492 while (my $problemNumber = shift @problemNumbers) {
197 : sh002i 502 $tex .= texBlockComment("BEGIN $setName : $problemNumber");
198 :     $tex .= $self->getProblemTeX($setName, $problemNumber);
199 : sh002i 492 if (@problemNumbers) {
200 :     # divide problems, but not after the last problem
201 : sh002i 502 $tex .= $self->texInclude($ce->{webworkFiles}->{hardcopySnippets}->{problemDivider});
202 : sh002i 492 }
203 : sh002i 478 }
204 :    
205 : sh002i 492 # render footer
206 : sh002i 502 $tex .= texBlockComment("BEGIN $setName : $setFooter");
207 :     $tex .= $self->getProblemTeX($setName, 0, $setFooter);
208 :    
209 :     return $tex;
210 : sh002i 478 }
211 :    
212 :     sub getProblemTeX {
213 : sh002i 502 my ($self, $setName, $problemNumber, $pgFile) = @_;
214 : sh002i 478 my $r = $self->{r};
215 :     my $ce = $self->{courseEnvironment};
216 :    
217 : sh002i 502 my $wwdb = $self->{wwdb};
218 :     my $cldb = $self->{cldb};
219 :     my $user = $cldb->getUser($r->param("user"));
220 :     my $set = $wwdb->getSet($user->id, $setName);
221 :     my $psvn = $wwdb->getPSVN($user->id, $setName);
222 :    
223 :     # decide what to do about problem number
224 :     my $problem;
225 :     if ($problemNumber) {
226 :     $problem = $wwdb->getProblem($user->id, $setName, $problemNumber);
227 :     } elsif ($pgFile) {
228 :     $problem = WeBWorK::Problem->new(
229 :     id => 0,
230 :     set_id => $set->id,
231 :     login_id => $user->id,
232 :     source_file => $pgFile,
233 :     # the rest of Problem's fields are not needed, i think
234 :     );
235 :     }
236 :    
237 : sh002i 478 my $pg = WeBWorK::PG->new(
238 :     $ce,
239 : sh002i 502 $user,
240 : sh002i 478 $r->param('key'),
241 : sh002i 502 $set,
242 :     $problem,
243 :     $psvn,
244 :     {}, # no form fields!
245 : sh002i 478 { # translation options
246 :     displayMode => "tex",
247 :     showHints => 0,
248 :     showSolutions => 0,
249 :     processAnswers => 0,
250 :     },
251 :     );
252 :    
253 : sh002i 607 warn "***GET READY FOR PG WARNINGS!!!!!\n***SET=$setName PROBLEM=$problemNumber\n",
254 :     $pg->{warnings}, "***OK NO MORE PG WARNINGS!!!!\n" if $pg->{warnings};
255 :    
256 : sh002i 478 return $pg->{body_text};
257 :     }
258 :    
259 : sh002i 492 sub texInclude {
260 :     my ($self, $texFile) = @_;
261 : sh002i 502 my $tex = "";
262 : sh002i 492
263 : sh002i 502 $tex .= texBlockComment("BEGIN: $texFile");
264 : sh002i 492 eval {
265 : sh002i 502 $tex .= readFile($texFile)
266 : sh002i 492 };
267 :     if ($@) {
268 : sh002i 502 $tex .= texBlockComment($@);
269 : sh002i 492 }
270 : sh002i 502
271 :     return $tex;
272 : sh002i 478 }
273 :    
274 :     1;

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9