| … | |
… | |
| 92 | |
92 | |
| 93 | =cut |
93 | =cut |
| 94 | |
94 | |
| 95 | BEGIN { |
95 | BEGIN { |
| 96 | be_strict(); # an alias for use strict. This means that all global variable must contain main:: as a prefix. |
96 | be_strict(); # an alias for use strict. This means that all global variable must contain main:: as a prefix. |
|
|
97 | |
| 97 | } |
98 | } |
|
|
99 | |
|
|
100 | |
| 98 | sub _dangerousMacros_init { |
101 | sub _dangerousMacros_init { |
| 99 | } |
102 | } |
| 100 | |
103 | |
| 101 | sub _dangerousMacros_export { |
104 | sub _dangerousMacros_export { |
| 102 | my @EXPORT= ( |
105 | my @EXPORT= ( |
| … | |
… | |
| 179 | |
182 | |
| 180 | $macroDirectory = eval('$main::macroDirectory') unless defined($macroDirectory); |
183 | $macroDirectory = eval('$main::macroDirectory') unless defined($macroDirectory); |
| 181 | $courseScriptsDirectory = eval('$main::courseScriptsDirectory') unless defined($courseScriptsDirectory); |
184 | $courseScriptsDirectory = eval('$main::courseScriptsDirectory') unless defined($courseScriptsDirectory); |
| 182 | $templateDirectory = eval('$main::courseScriptsDirectory') unless defined($templateDirectory); |
185 | $templateDirectory = eval('$main::courseScriptsDirectory') unless defined($templateDirectory); |
| 183 | $scriptDirectory = eval('$main::scriptDirectory') unless defined($scriptDirectory); |
186 | $scriptDirectory = eval('$main::scriptDirectory') unless defined($scriptDirectory); |
| 184 | |
187 | |
| 185 | # Hack to handle those problems where DOCUMENT() comes after loadMacros. |
|
|
| 186 | unless (defined( $main::externalTTHPath) and $main::externalTTHPath) { |
188 | unless (defined( $main::externalTTHPath) and $main::externalTTHPath) { |
| 187 | warn "WARNING::Please make sure that the DOCUMENT() statement comes before<BR>\n" . |
189 | warn "WARNING::Please make sure that the DOCUMENT() statement comes before<BR>\n" . |
| 188 | " the loadMacros() statement in the problem template.<p>" . |
190 | " the loadMacros() statement in the problem template.<p>" . |
| 189 | " The externalTTHPath variable |$main::externalTTHPath| was\n". |
191 | " The externalTTHPath variable |$main::externalTTHPath| was\n". |
| 190 | " not defined which usually indicates the problem above.<br>\n"; |
192 | " not defined which usually indicates the problem above.<br>\n"; |
| … | |
… | |
| 400 | # $tthpath is now taken from $Global::externalTTHPath via %envir. |
402 | # $tthpath is now taken from $Global::externalTTHPath via %envir. |
| 401 | my $tthpath = $envir{externalTTHPath}; |
403 | my $tthpath = $envir{externalTTHPath}; |
| 402 | my $out; |
404 | my $out; |
| 403 | |
405 | |
| 404 | if (-x $tthpath ) { |
406 | if (-x $tthpath ) { |
| 405 | my $tthcmd = "$tthpath -L -f5 -r 2>/dev/null " . $inputString; |
407 | my $tthcmd = "$tthpath -L -f5 -u -r 2>/dev/null " . $inputString; |
| 406 | if (open(TTH, "$tthcmd |")) { |
408 | if (open(TTH, "$tthcmd |")) { |
| 407 | local($/); |
409 | local($/); |
| 408 | $/ = undef; |
410 | $/ = undef; |
| 409 | $out = <TTH>; |
411 | $out = <TTH>; |
| 410 | $/ = "\n"; |
412 | $/ = "\n"; |
| … | |
… | |
| 417 | } |
419 | } |
| 418 | |
420 | |
| 419 | $out; |
421 | $out; |
| 420 | } |
422 | } |
| 421 | |
423 | |
|
|
424 | # possible solution to the tth font problem? Works only for iCab. |
|
|
425 | sub symbolConvert { |
|
|
426 | my $string = shift; |
|
|
427 | $string =~ s/\x5C/\\/g; #\ 92 \ |
|
|
428 | $string =~ s/\x7B/\{/g; #{ 123 { |
|
|
429 | $string =~ s/\x7D/\}/g; #} 125 } |
|
|
430 | $string =~ s/\xE7/\Á/g; #ç 231 Á |
|
|
431 | $string =~ s/\xE6/\Ê/g; #æ 230 Ê |
|
|
432 | $string =~ s/\xE8/\Ë/g; #è 232 Ë |
|
|
433 | $string =~ s/\xF3/\Û/g; #ó 243 Û |
|
|
434 | $string =~ s/\xA5/\•/g; #¥ 165 • |
|
|
435 | $string =~ s/\xB2/\≤/g; #² 178 ≤ |
|
|
436 | $string =~ s/\xB3/\≥/g; #³ 179 ≥ |
|
|
437 | $string =~ s/\xB6/\∂/g; #¶ 182 ∂ |
|
|
438 | $string =~ s/\xCE/\Œ/g; #Î 206 Œ |
|
|
439 | $string =~ s/\xD6/\˜/g; #Ö 214 ˜ |
|
|
440 | $string =~ s/\xD9/\Ÿ/g; #Ù 217 Ÿ |
|
|
441 | $string =~ s/\xDA/\⁄/g; #Ú 218 ⁄ |
|
|
442 | $string =~ s/\xF5/\ı/g; #õ 245 ı |
|
|
443 | $string =~ s/\xF6/\ˆ/g; #ö 246 ˆ |
|
|
444 | $string =~ s/\xF7/\Á/g; #÷ 247 Á |
|
|
445 | $string =~ s/\xF8/\¯/g; #ø 248 ¯ |
|
|
446 | $string =~ s/\xF9/\˘/g; #ù 249 ˘ |
|
|
447 | $string =~ s/\xFA/\˙/g; #ú 250 ˙ |
|
|
448 | $string =~ s/\xFB/\˚;/g; #û 251 ˚ |
|
|
449 | $string; |
|
|
450 | } |
|
|
451 | |
| 422 | # ----- ----- ----- ----- |
452 | # ----- ----- ----- ----- |
| 423 | |
453 | |
| 424 | =head2 math2img |
454 | =head2 math2img |
| 425 | |
455 | |
| 426 | math2img(texString) - returns an IMG tag pointing to an image version of the supplied TeX |
456 | math2img(texString) - returns an IMG tag pointing to an image version of the supplied TeX |
| … | |
… | |
| 436 | my $sourcePath = $envir{templateDirectory} . "/" . $envir{fileName}; |
466 | my $sourcePath = $envir{templateDirectory} . "/" . $envir{fileName}; |
| 437 | my $tempFile = "m2i/$envir{studentLogin}.$envir{setNumber}.$envir{probNum}." |
467 | my $tempFile = "m2i/$envir{studentLogin}.$envir{setNumber}.$envir{probNum}." |
| 438 | . $math2imgCount++ . ".png"; |
468 | . $math2imgCount++ . ".png"; |
| 439 | my $tempPath = surePathToTmpFile($tempFile); #my $tempPath = "$envir{tempDirectory}$tempFile"; |
469 | my $tempPath = surePathToTmpFile($tempFile); #my $tempPath = "$envir{tempDirectory}$tempFile"; |
| 440 | my $tempURL = "$envir{tempURL}/$tempFile"; |
470 | my $tempURL = "$envir{tempURL}/$tempFile"; |
| 441 | |
|
|
| 442 | my $forceRefresh = $envir{refreshMath2img}; |
471 | my $forceRefresh = $envir{refreshMath2img}; |
| 443 | my $imageMissing = not -e $tempPath; |
472 | my $imageMissing = not -e $tempPath; |
| 444 | my $imageStale = (stat $sourcePath)[9] > (stat $tempPath)[9]; |
473 | my $imageStale = (stat $sourcePath)[9] > (stat $tempPath)[9] if -e $tempPath; |
| 445 | if ($forceRefresh or $imageMissing or $imageStale) { |
474 | if ($forceRefresh or $imageMissing or $imageStale) { |
| 446 | # image file doesn't exist, or source file is newer then image file |
475 | # image file doesn't exist, or source file is newer then image file |
| 447 | #warn "math2img: refreshMath2img forcing image generation for $tempFile\n" if $forceRefresh; |
476 | #warn "math2img: refreshMath2img forcing image generation for $tempFile\n" if $forceRefresh; |
| 448 | #warn "math2img: $tempFile doesn't exist, so generating it\n" if $imageMissing; |
477 | #warn "math2img: $tempFile doesn't exist, so generating it\n" if $imageMissing; |
| 449 | #warn "math2img: source file (", (stat $sourcePath)[9], ") is newer than image file (", |
478 | #warn "math2img: source file (", (stat $sourcePath)[9], ") is newer than image file (", |
| 450 | # (stat $tempPath)[9], ") so re-generating image\n" if $imageStale; |
479 | # (stat $tempPath)[9], ") so re-generating image\n" if $imageStale; |
| 451 | if (-e tempPath) { |
480 | if (-e $tempPath) { |
| 452 | unlink $tempPath or die "Failed to delete stale math2img file $tempPath: $!"; |
481 | unlink $tempPath or die "Failed to delete stale math2img file $tempPath: $!"; |
| 453 | } |
482 | } |
| 454 | dvipng( |
483 | dvipng( |
| 455 | $envir{dvipngTempDir}, $envir{externalLaTeXPath}, |
484 | $envir{dvipngTempDir}, $envir{externalLaTeXPath}, |
| 456 | $envir{externalDvipngPath}, $tex, $tempPath |
485 | $envir{externalDvipngPath}, $tex, $tempPath |
| … | |
… | |
| 465 | # it might be nice to call tth here as a fallback instead: |
494 | # it might be nice to call tth here as a fallback instead: |
| 466 | #return tth($tex); |
495 | #return tth($tex); |
| 467 | } |
496 | } |
| 468 | }; |
497 | }; |
| 469 | |
498 | |
| 470 | ## dvipngTempDir externalLaTeXPath, externalDvipngPath |
499 | |
|
|
500 | # copied from IO.pm for backward compatibility with WeBWorK1.8; |
| 471 | #sub dvipng { |
501 | sub dvipng($$$$$) { |
| 472 | # my ($tex, $targetPath) = @_; |
502 | my ( |
| 473 | # |
503 | $wd, # working directory, for latex and dvipng garbage |
| 474 | # # create a temporary directory for tex to shit in |
504 | # (must already exist!) |
| 475 | # my $wd = $envir{dvipngTempDir}; |
505 | $latex, # path to latex binary |
|
|
506 | $dvipng, # path to dvipng binary |
|
|
507 | $tex, # tex string representing equation |
|
|
508 | $targetPath # location of resulting image file |
|
|
509 | ) = @_; |
|
|
510 | |
|
|
511 | my $dvipngBroken = 0; |
|
|
512 | |
| 476 | # my $texFile = "$wd/equation.tex"; |
513 | my $texFile = "$wd/equation.tex"; |
| 477 | # my $dviFile = "$wd/equation.dvi"; |
514 | my $dviFile = "$wd/equation.dvi"; |
| 478 | # my $dviFile2 = "$wd/equationequation.dvi"; |
515 | my $dviFile2 = "$wd/equationequation.dvi"; |
| 479 | # my $dviCall = "equation"; |
516 | my $dviCall = "equation"; |
| 480 | # my $pngFile = "$wd/equation1.png"; |
517 | my $pngFile = "$wd/equation1.png"; |
| 481 | # |
518 | |
|
|
519 | unless (-e $wd) { |
| 482 | # die "dvipng working directory $wd doesn't exist -- caller should have created it for us!\n" |
520 | die "dvipng working directory $wd doesn't exist -- caller should have created it for us!\n"; |
| 483 | # unless -e $wd; |
521 | return 0; |
| 484 | # |
522 | } |
|
|
523 | |
| 485 | # # write the tex file |
524 | # write the tex file |
| 486 | # local *TEX; |
525 | local *TEX; |
| 487 | # open TEX, ">", $texFile; |
526 | open TEX, ">", $texFile or warn "Failed to create $texFile: $!"; |
| 488 | # print TEX <<'EOF'; |
527 | print TEX <<'EOF'; |
| 489 | #% BEGIN HEADER |
528 | % BEGIN HEADER |
| 490 | #\batchmode |
529 | \batchmode |
| 491 | #\documentclass[12pt]{article} |
530 | \documentclass[12pt]{article} |
| 492 | #\usepackage{amsmath,amsfonts,amssymb} |
531 | \usepackage{amsmath,amsfonts,amssymb} |
| 493 | #\def\gt{>} |
532 | \def\gt{>} |
| 494 | #\def\lt{<} |
533 | \def\lt{<} |
| 495 | #\usepackage[active,textmath,displaymath]{preview} |
534 | \usepackage[active,textmath,displaymath]{preview} |
| 496 | #\begin{document} |
535 | \begin{document} |
| 497 | #% END HEADER |
536 | % END HEADER |
| 498 | #EOF |
537 | EOF |
| 499 | # print TEX "\\( \\displaystyle{$tex} \\)\n"; |
538 | print TEX "\\( \\displaystyle{$tex} \\)\n"; |
| 500 | # print TEX <<'EOF'; |
539 | print TEX <<'EOF'; |
| 501 | #% BEGIN FOOTER |
540 | % BEGIN FOOTER |
| 502 | #\end{document} |
541 | \end{document} |
| 503 | #% END FOOTER |
542 | % END FOOTER |
| 504 | #EOF |
543 | EOF |
| 505 | # close TEX; |
544 | close TEX; |
| 506 | # |
545 | |
| 507 | # # call latex |
546 | # call latex |
| 508 | # my $latex = $envir{externalLaTeXPath}; |
|
|
| 509 | # system "cd $wd && $latex $texFile"; |
547 | system "cd $wd && $latex $texFile" |
| 510 | # |
548 | and warn "Failed to call $latex with $texFile: $!"; |
| 511 | # return 0 unless -e $dviFile; |
549 | |
| 512 | # |
550 | unless (-e $dviFile) { |
|
|
551 | warn "Failed to generate DVI file $dviFile"; |
|
|
552 | return 0; |
|
|
553 | } |
|
|
554 | |
|
|
555 | if ($dvipngBroken) { |
| 513 | # # change the name of the DVI file to get around dvipng's crackheadedness |
556 | # change the name of the DVI file to get around dvipng's |
|
|
557 | # crackheadedness. This is no longer needed with the newest |
|
|
558 | # version of dvipng (10 something) |
| 514 | # system "/bin/mv", $dviFile, $dviFile2; |
559 | system "/bin/mv", $dviFile, $dviFile2; |
| 515 | # |
560 | } |
| 516 | # # call dvipng |
561 | |
| 517 | # my $dvipng = $envir{externalDvipngPath}; |
562 | # call dvipng -- using warn instead of die passes some extra information |
| 518 | # system "cd $wd && $dvipng $dviCall" and die "dvipng:dvipng failed: $!"; |
563 | # back to the user the complete warning is still printed in the apache |
| 519 | # |
564 | # error log and a simple message (math2img failed) is returned to the |
| 520 | # return 0 unless -e $pngFile; |
565 | # webpage. |
| 521 | # |
566 | my $cmdout; |
| 522 | # system "/bin/mv", $pngFile, $targetPath and die "Failed to mv: $!\n"; |
567 | $cmdout = system "cd $wd && $dvipng $dviCall" |
| 523 | #} |
568 | and warn "Failed to call$dvipng with $dviCall: $! with signal $cmdout"; |
|
|
569 | |
|
|
570 | unless (-e $pngFile) { |
|
|
571 | warn "Failed to create PNG file $pngFile"; |
|
|
572 | return 0; |
|
|
573 | } |
|
|
574 | |
|
|
575 | $cmdout = system "/bin/mv", $pngFile, $targetPath and warn "Failed to mv: /bin/mv $pngFile $targetPath $!. Call returned $cmdout. \n"; |
|
|
576 | } |
|
|
577 | |
| 524 | |
578 | |
| 525 | # ----- ----- ----- ----- |
579 | # ----- ----- ----- ----- |
| 526 | |
580 | |
| 527 | =head2 alias |
581 | =head2 alias |
| 528 | |
582 | |