| 1 | #!/usr/local/bin/webwork-perl |
1 | |
| 2 | |
2 | |
| 3 | #################################################################### |
3 | #################################################################### |
| 4 | # Copyright @ 1995-1998 University of Rochester |
4 | # Copyright @ 1995-1998 University of Rochester |
| 5 | # All Rights Reserved |
5 | # All Rights Reserved |
| 6 | #################################################################### |
6 | #################################################################### |
| … | |
… | |
| 45 | $SOLUTION, |
45 | $SOLUTION, |
| 46 | $HINT, |
46 | $HINT, |
| 47 | $US, |
47 | $US, |
| 48 | $SPACE, |
48 | $SPACE, |
| 49 | $BBOLD, |
49 | $BBOLD, |
| 50 | $EBOLD, |
50 | $EBOLD, |
| 51 | $BITALIC, |
51 | $BITALIC, |
| 52 | $EITALIC, |
52 | $EITALIC, |
| 53 | $BCENTER, |
53 | $BCENTER, |
| 54 | $ECENTER, |
54 | $ECENTER, |
| 55 | $HR, |
55 | $HR, |
| … | |
… | |
| 85 | $main::SOLUTION = SOLUTION_HEADING(); |
85 | $main::SOLUTION = SOLUTION_HEADING(); |
| 86 | $main::HINT = HINT_HEADING(); |
86 | $main::HINT = HINT_HEADING(); |
| 87 | $main::US = US(); |
87 | $main::US = US(); |
| 88 | $main::SPACE = SPACE(); |
88 | $main::SPACE = SPACE(); |
| 89 | $main::BBOLD = BBOLD(); |
89 | $main::BBOLD = BBOLD(); |
| 90 | $main::EBOLD = EBOLD(); |
90 | $main::EBOLD = EBOLD(); |
| 91 | $main::BITALIC = BITALIC(); |
91 | $main::BITALIC = BITALIC(); |
| 92 | $main::EITALIC = EITALIC(); |
92 | $main::EITALIC = EITALIC(); |
| 93 | $main::BCENTER = BCENTER(); |
93 | $main::BCENTER = BCENTER(); |
| 94 | $main::ECENTER = ECENTER(); |
94 | $main::ECENTER = ECENTER(); |
| 95 | $main::HR = HR(); |
95 | $main::HR = HR(); |
| … | |
… | |
| 101 | $main::PERCENT = PERCENT(); |
101 | $main::PERCENT = PERCENT(); |
| 102 | $main::CARET = CARET(); |
102 | $main::CARET = CARET(); |
| 103 | $main::PI = PI(); |
103 | $main::PI = PI(); |
| 104 | $main::E = E(); |
104 | $main::E = E(); |
| 105 | @main::ALPHABET = ('A'..'ZZ'); |
105 | @main::ALPHABET = ('A'..'ZZ'); |
| 106 | |
106 | |
| 107 | $PAR = PAR(); |
107 | $PAR = PAR(); |
| 108 | $BR = BR(); |
108 | $BR = BR(); |
| 109 | $LQ = LQ(); |
109 | $LQ = LQ(); |
| 110 | $RQ = RQ(); |
110 | $RQ = RQ(); |
| 111 | $BM = BM(); |
111 | $BM = BM(); |
| … | |
… | |
| 134 | $PERCENT = PERCENT(); |
134 | $PERCENT = PERCENT(); |
| 135 | $CARET = CARET(); |
135 | $CARET = CARET(); |
| 136 | $PI = PI(); |
136 | $PI = PI(); |
| 137 | $E = E(); |
137 | $E = E(); |
| 138 | @ALPHABET = ('A'..'ZZ'); |
138 | @ALPHABET = ('A'..'ZZ'); |
| 139 | |
139 | |
| 140 | |
140 | |
| 141 | |
141 | |
| 142 | } |
142 | } |
| 143 | |
143 | |
| 144 | =head2 Answer blank macros: |
144 | =head2 Answer blank macros: |
| 145 | |
145 | |
| … | |
… | |
| 241 | } elsif (ref($answer_value) eq 'ARRAY') { |
241 | } elsif (ref($answer_value) eq 'ARRAY') { |
| 242 | my @answers = @{ $answer_value}; |
242 | my @answers = @{ $answer_value}; |
| 243 | $answer_value = shift(@answers); # use up the first answer |
243 | $answer_value = shift(@answers); # use up the first answer |
| 244 | $main::rh_sticky_answers{$name}=\@answers; # store the rest |
244 | $main::rh_sticky_answers{$name}=\@answers; # store the rest |
| 245 | $answer_value= '' unless defined($answer_value); |
245 | $answer_value= '' unless defined($answer_value); |
| 246 | } |
246 | } |
| 247 | |
247 | |
| 248 | $answer_value =~ tr/$@`//d; ## make sure student answers can not be interpolated by e.g. EV3 |
248 | $answer_value =~ tr/$@`//d; ## make sure student answers can not be interpolated by e.g. EV3 |
| 249 | $name = RECORD_ANS_NAME($name); |
249 | $name = RECORD_ANS_NAME($name); |
| 250 | MODES( |
250 | MODES( |
| 251 | TeX => "\\mbox{\\parbox[t]{10pt}{\\hrulefill}}\\hrulefill\\quad ", |
251 | TeX => "\\mbox{\\parbox[t]{10pt}{\\hrulefill}}\\hrulefill\\quad ", |
| 252 | Latex2HTML => qq!\\begin{rawhtml}\n<INPUT TYPE=TEXT SIZE=$col NAME=\"$name\" VALUE = \"\">\n\\end{rawhtml}\n!, |
252 | Latex2HTML => qq!\\begin{rawhtml}\n<INPUT TYPE=TEXT SIZE=$col NAME=\"$name\" VALUE = \"\">\n\\end{rawhtml}\n!, |
| … | |
… | |
| 578 | 'Latex2HTML' => '\\fbox{Answer boxes cannot be placed inside typeset equations}', |
578 | 'Latex2HTML' => '\\fbox{Answer boxes cannot be placed inside typeset equations}', |
| 579 | 'HTML_tth' => '\\begin{rawhtml} '. $answer_rule.'\\end{rawhtml}', |
579 | 'HTML_tth' => '\\begin{rawhtml} '. $answer_rule.'\\end{rawhtml}', |
| 580 | 'HTML_dpng' => '\\fbox{Answer boxes cannot be placed inside typeset equations}', |
580 | 'HTML_dpng' => '\\fbox{Answer boxes cannot be placed inside typeset equations}', |
| 581 | 'HTML' => $answer_rule |
581 | 'HTML' => $answer_rule |
| 582 | ); |
582 | ); |
| 583 | |
583 | |
| 584 | $out; |
584 | $out; |
| 585 | } |
585 | } |
| 586 | sub tex_ans_rule_extension { |
586 | sub tex_ans_rule_extension { |
| 587 | my $len = shift; |
587 | my $len = shift; |
| 588 | $len = 20 unless $len ; |
588 | $len = 20 unless $len ; |
| … | |
… | |
| 593 | 'Latex2HTML' => '\fbox{Answer boxes cannot be placed inside typeset equations}', |
593 | 'Latex2HTML' => '\fbox{Answer boxes cannot be placed inside typeset equations}', |
| 594 | 'HTML_tth' => '\\begin{rawhtml} '. $answer_rule.'\\end{rawhtml}', |
594 | 'HTML_tth' => '\\begin{rawhtml} '. $answer_rule.'\\end{rawhtml}', |
| 595 | 'HTML_dpng' => '\fbox{Answer boxes cannot be placed inside typeset equations}', |
595 | 'HTML_dpng' => '\fbox{Answer boxes cannot be placed inside typeset equations}', |
| 596 | 'HTML' => $answer_rule |
596 | 'HTML' => $answer_rule |
| 597 | ); |
597 | ); |
| 598 | |
598 | |
| 599 | $out; |
599 | $out; |
| 600 | } |
600 | } |
| 601 | # still needs some cleanup. |
601 | # still needs some cleanup. |
| 602 | sub NAMED_TEX_ANS_RULE { |
602 | sub NAMED_TEX_ANS_RULE { |
| 603 | my $name = shift; |
603 | my $name = shift; |
| … | |
… | |
| 609 | 'Latex2HTML' => '\\fbox{Answer boxes cannot be placed inside typeset equations}', |
609 | 'Latex2HTML' => '\\fbox{Answer boxes cannot be placed inside typeset equations}', |
| 610 | 'HTML_tth' => '\\begin{rawhtml} '. $answer_rule.'\\end{rawhtml}', |
610 | 'HTML_tth' => '\\begin{rawhtml} '. $answer_rule.'\\end{rawhtml}', |
| 611 | 'HTML_dpng' => '\\fbox{Answer boxes cannot be placed inside typeset equations}', |
611 | 'HTML_dpng' => '\\fbox{Answer boxes cannot be placed inside typeset equations}', |
| 612 | 'HTML' => $answer_rule |
612 | 'HTML' => $answer_rule |
| 613 | ); |
613 | ); |
| 614 | |
614 | |
| 615 | $out; |
615 | $out; |
| 616 | } |
616 | } |
| 617 | sub NAMED_TEX_ANS_RULE_EXTENSION { |
617 | sub NAMED_TEX_ANS_RULE_EXTENSION { |
| 618 | my $name = shift; |
618 | my $name = shift; |
| 619 | my $len = shift; |
619 | my $len = shift; |
| … | |
… | |
| 624 | 'Latex2HTML' => '\fbox{Answer boxes cannot be placed inside typeset equations}', |
624 | 'Latex2HTML' => '\fbox{Answer boxes cannot be placed inside typeset equations}', |
| 625 | 'HTML_tth' => '\\begin{rawhtml} '. $answer_rule.'\\end{rawhtml}', |
625 | 'HTML_tth' => '\\begin{rawhtml} '. $answer_rule.'\\end{rawhtml}', |
| 626 | 'HTML_dpng' => '\fbox{Answer boxes cannot be placed inside typeset equations}', |
626 | 'HTML_dpng' => '\fbox{Answer boxes cannot be placed inside typeset equations}', |
| 627 | 'HTML' => $answer_rule |
627 | 'HTML' => $answer_rule |
| 628 | ); |
628 | ); |
| 629 | |
629 | |
| 630 | $out; |
630 | $out; |
| 631 | } |
631 | } |
| 632 | sub ans_box { |
632 | sub ans_box { |
| 633 | my $row = shift; |
633 | my $row = shift; |
| 634 | my $col =shift; |
634 | my $col =shift; |
| … | |
… | |
| 731 | |
731 | |
| 732 | |
732 | |
| 733 | sub hint { |
733 | sub hint { |
| 734 | my @in = @_; |
734 | my @in = @_; |
| 735 | my $out = ''; |
735 | my $out = ''; |
| 736 | |
736 | |
| 737 | $main::hintExists =1; |
737 | $main::hintExists =1; |
| 738 | $main::numOfAttempts = 0 unless defined($main::numOfAttempts); |
738 | $main::numOfAttempts = 0 unless defined($main::numOfAttempts); |
| 739 | |
739 | |
| 740 | if ($main::displayMode eq 'TeX') { |
740 | if ($main::displayMode eq 'TeX') { |
| 741 | $out = ''; # do nothing since hints are not available for download |
741 | $out = ''; # do nothing since hints are not available for download |
| 742 | } elsif (($envir{'displayHintsQ'}) and ($main::numOfAttempts >= $main::showHint)) |
742 | } elsif (($envir{'displayHintsQ'}) and ($main::numOfAttempts >= $main::showHint)) |
| 743 | |
743 | |
| 744 | ## the second test above prevents a hint being shown if a doctored form is submitted |
744 | ## the second test above prevents a hint being shown if a doctored form is submitted |
| 745 | |
745 | |
| 746 | {$out = join(' ',@in);} # show hint |
746 | {$out = join(' ',@in);} # show hint |
| 747 | |
747 | |
| 748 | $out ; |
748 | $out ; |
| 749 | } |
749 | } |
| 750 | |
750 | |
| 751 | |
751 | |
| 752 | sub HINT { |
752 | sub HINT { |
| … | |
… | |
| 863 | return $options{HTML} |
863 | return $options{HTML} |
| 864 | if defined( $options{HTML} ); |
864 | if defined( $options{HTML} ); |
| 865 | die " ERROR in using MODES: 'HTML' option not defined for HTML_tth"; |
865 | die " ERROR in using MODES: 'HTML' option not defined for HTML_tth"; |
| 866 | |
866 | |
| 867 | } |
867 | } |
| 868 | |
868 | |
| 869 | if ($displayMode eq "HTML_img") { |
869 | if ($displayMode eq "HTML_img") { |
| 870 | return $options{HTML_dpng} if defined $options{HTML_dpng}; |
870 | return $options{HTML_dpng} if defined $options{HTML_dpng}; |
| 871 | return $options{HTML_tth} if defined $options{HTML_tth}; |
871 | return $options{HTML_tth} if defined $options{HTML_tth}; |
| 872 | return $options{HTML} if defined $options{HTML}; |
872 | return $options{HTML} if defined $options{HTML}; |
| 873 | die " ERROR in using MODES: 'HTML' option not defined for HTML_img"; |
873 | die " ERROR in using MODES: 'HTML' option not defined for HTML_img"; |
| 874 | } |
874 | } |
| 875 | |
875 | |
| 876 | if ($displayMode eq "HTML_dpng") { |
876 | if ($displayMode eq "HTML_dpng") { |
| 877 | return $options{HTML_tth} |
877 | return $options{HTML_tth} |
| 878 | if defined( $options{HTML_tth} ); |
878 | if defined( $options{HTML_tth} ); |
| 879 | return $options{HTML} |
879 | return $options{HTML} |
| 880 | if defined( $options{HTML} ); |
880 | if defined( $options{HTML} ); |
| … | |
… | |
| 882 | |
882 | |
| 883 | } |
883 | } |
| 884 | |
884 | |
| 885 | # trap undefined errors |
885 | # trap undefined errors |
| 886 | die "ERROR in defining MODES: Can't find |$displayMode| among |
886 | die "ERROR in defining MODES: Can't find |$displayMode| among |
| 887 | available options:" . join(" ", keys(%options) ) |
887 | available options:" . join(" ", keys(%options) ) |
| 888 | . " file " . __FILE__ ." line " . __LINE__."\n\n"; |
888 | . " file " . __FILE__ ." line " . __LINE__."\n\n"; |
| 889 | |
889 | |
| 890 | } |
890 | } |
| 891 | |
891 | |
| 892 | |
892 | |
| … | |
… | |
| 918 | $BBOLD BBOLD() begin bold typeface |
918 | $BBOLD BBOLD() begin bold typeface |
| 919 | $EBOLD EBOLD() end bold typeface |
919 | $EBOLD EBOLD() end bold typeface |
| 920 | $BITALIC BITALIC() begin italic typeface |
920 | $BITALIC BITALIC() begin italic typeface |
| 921 | $EITALIC EITALIC() end italic typeface |
921 | $EITALIC EITALIC() end italic typeface |
| 922 | $BCENTER BCENTER() begin centered environment |
922 | $BCENTER BCENTER() begin centered environment |
| 923 | $ECENTER ECENTER() end centered environment |
923 | $ECENTER ECENTER() end centered environment |
| 924 | $HR HR() horizontal rule |
924 | $HR HR() horizontal rule |
| 925 | $LBRACE LBRACE() left brace |
925 | $LBRACE LBRACE() left brace |
| 926 | $LB LB () left brace |
926 | $LB LB () left brace |
| 927 | $RBRACE RBRACE() right brace |
927 | $RBRACE RBRACE() right brace |
| 928 | $RB RB () right brace |
928 | $RB RB () right brace |
| … | |
… | |
| 1224 | } |
1224 | } |
| 1225 | |
1225 | |
| 1226 | sub general_math_ev3 { |
1226 | sub general_math_ev3 { |
| 1227 | my $in = shift; |
1227 | my $in = shift; |
| 1228 | my $mode = shift || "inline"; |
1228 | my $mode = shift || "inline"; |
| 1229 | |
1229 | |
| 1230 | $in = FEQ($in); |
1230 | $in = FEQ($in); |
| 1231 | $in =~ s/%/\\%/g; |
1231 | $in =~ s/%/\\%/g; |
| 1232 | my $in_delim; |
1232 | my $in_delim; |
| 1233 | |
1233 | |
| 1234 | if($mode eq "inline") { |
1234 | if($mode eq "inline") { |
| … | |
… | |
| 1432 | my @out = keys %temp; # sort is causing trouble with Safe.?? |
1432 | my @out = keys %temp; # sort is causing trouble with Safe.?? |
| 1433 | @out; |
1433 | @out; |
| 1434 | } |
1434 | } |
| 1435 | |
1435 | |
| 1436 | sub lex_sort { |
1436 | sub lex_sort { |
| 1437 | PGsort sub {$_[0] cmp $_[1]}, @_; |
1437 | PGsort sub {$_[0] cmp $_[1]}, @_; |
| 1438 | } |
1438 | } |
| 1439 | sub num_sort { |
1439 | sub num_sort { |
| 1440 | PGsort sub {$_[0] <=> $_[1]}, @_; |
1440 | PGsort sub {$_[0] <=> $_[1]}, @_; |
| 1441 | } |
1441 | } |
| 1442 | |
1442 | |
| … | |
… | |
| 1479 | $out .= "\n\\begin{rawhtml} <TABLE , BORDER=1>\n\\end{rawhtml}"; |
1479 | $out .= "\n\\begin{rawhtml} <TABLE , BORDER=1>\n\\end{rawhtml}"; |
| 1480 | } |
1480 | } |
| 1481 | elsif ($displayMode eq 'HTML' || $displayMode eq 'HTML_tth' || $displayMode eq 'HTML_dpng' || $displayMode eq 'HTML_img') { |
1481 | elsif ($displayMode eq 'HTML' || $displayMode eq 'HTML_tth' || $displayMode eq 'HTML_dpng' || $displayMode eq 'HTML_img') { |
| 1482 | $out .= "<TABLE BORDER=1>\n" |
1482 | $out .= "<TABLE BORDER=1>\n" |
| 1483 | } |
1483 | } |
| 1484 | else { |
1484 | else { |
| 1485 | $out = "Error: PGchoicemacros: begintable: Unknown displayMode: $displayMode.\n"; |
1485 | $out = "Error: PGchoicemacros: begintable: Unknown displayMode: $displayMode.\n"; |
| 1486 | } |
1486 | } |
| 1487 | $out; |
1487 | $out; |
| 1488 | } |
1488 | } |
| 1489 | |
1489 | |
| … | |
… | |
| 1580 | if (ref($image_ref) =~ /ARRAY/ ) { |
1580 | if (ref($image_ref) =~ /ARRAY/ ) { |
| 1581 | @image_list = @{$image_ref}; |
1581 | @image_list = @{$image_ref}; |
| 1582 | } else { |
1582 | } else { |
| 1583 | push(@image_list,$image_ref); |
1583 | push(@image_list,$image_ref); |
| 1584 | } |
1584 | } |
| 1585 | |
1585 | |
| 1586 | my @output_list = (); |
1586 | my @output_list = (); |
| 1587 | while(@image_list) { |
1587 | while(@image_list) { |
| 1588 | my $imageURL = alias(shift @image_list); |
1588 | my $imageURL = alias(shift @image_list); |
| 1589 | my $out=""; |
1589 | my $out=""; |
| 1590 | |
1590 | |
| 1591 | if ($main::displayMode eq 'TeX') { |
1591 | if ($main::displayMode eq 'TeX') { |
| 1592 | my $imagePath = $imageURL; # in TeX mode, alias gives us a path, not a URL |
1592 | my $imagePath = $imageURL; # in TeX mode, alias gives us a path, not a URL |
| 1593 | if ($envir{texDisposition} eq "pdf") { |
1593 | if ($envir{texDisposition} eq "pdf") { |
| 1594 | # We're going to create PDF files with our TeX (using pdflatex), so |
1594 | # We're going to create PDF files with our TeX (using pdflatex), so |
| 1595 | # alias should have given us the path to a PNG image. What we need |
1595 | # alias should have given us the path to a PNG image. What we need |
| 1596 | # to do is find out the dimmensions of this image, since pdflatex |
1596 | # to do is find out the dimmensions of this image, since pdflatex |
| 1597 | # is too dumb to live. |
1597 | # is too dumb to live. |
| 1598 | |
1598 | |
| 1599 | #my ($height, $width) = getImageDimmensions($imagePath); |
1599 | #my ($height, $width) = getImageDimmensions($imagePath); |
| 1600 | ##warn "&image: $imagePath $height $width\n"; |
1600 | ##warn "&image: $imagePath $height $width\n"; |
| 1601 | #unless ($height and $width) { |
1601 | #unless ($height and $width) { |
| 1602 | # warn "Couldn't get the dimmensions of image $imagePath.\n" |
1602 | # warn "Couldn't get the dimmensions of image $imagePath.\n" |
| 1603 | #} |
1603 | #} |
| 1604 | #$out = "\\includegraphics[bb=0 0 $height $width,width=$width_ratio\\linewidth]{$imagePath}\n"; |
1604 | #$out = "\\includegraphics[bb=0 0 $height $width,width=$width_ratio\\linewidth]{$imagePath}\n"; |
| 1605 | $out = "\\includegraphics[width=$width_ratio\\linewidth]{$imagePath}\n"; |
1605 | $out = "\\includegraphics[width=$width_ratio\\linewidth]{$imagePath}\n"; |
| 1606 | } else { |
1606 | } else { |
| 1607 | # Since we're not creating PDF files, alias should have given us the |
1607 | # Since we're not creating PDF files, alias should have given us the |
| 1608 | # path to an EPS file. latex can get its dimmensions no problem! |
1608 | # path to an EPS file. latex can get its dimmensions no problem! |
| 1609 | |
1609 | |
| 1610 | $out = "\\includegraphics[width=$width_ratio\\linewidth]{$imagePath}\n"; |
1610 | $out = "\\includegraphics[width=$width_ratio\\linewidth]{$imagePath}\n"; |
| 1611 | } |
1611 | } |
| 1612 | } elsif ($main::displayMode eq 'Latex2HTML') { |
1612 | } elsif ($main::displayMode eq 'Latex2HTML') { |
| 1613 | $out = qq!\\begin{rawhtml}\n<A HREF= "$imageURL" TARGET="ZOOM"><IMG SRC="$imageURL" WIDTH="$width" HEIGHT="$height"></A>\n |
1613 | $out = qq!\\begin{rawhtml}\n<A HREF= "$imageURL" TARGET="ZOOM"><IMG SRC="$imageURL" WIDTH="$width" HEIGHT="$height"></A>\n |
| 1614 | \\end{rawhtml}\n ! |
1614 | \\end{rawhtml}\n ! |