#!/usr/bin/perl BEGIN{ print "This script is deprecated, use pass-exeg.\n"; exit 0;} use strict; use utf8::all; use Getopt::Long qw(:config no_auto_abbrev ); use Pod::Usage; use Cwd; use MLDBM qw(DB_File); use DB_File; use Fcntl; my %S=(n=>1); GetOptions( \%S, qw{help|h|? man l s=i o=s n=i srand=i pdf pdf2 nosol nores test showrand nohead no cgi db h h1 dl d dm test catalog=s tit=s aut=s outdir=s } ) or die "Specify the --help (or -?) option for usage information.\n"; pod2usage(2) if $S{help}; pod2usage(-exitstatus => 0, -verbose => 2) if $S{man}; die "-cgi is outdated, please dont use it.\n" if $S{cgi}; if($S{no}){$S{nosol} = $S{nores} = $S{nohead} = 1 } if($S{srand}){srand($S{srand})} use Data::Dumper; use Exercise::Gen::Let; ## use Skel::Data; skimport(); use Parse::DSLUtils; skimport(); my $cwd=cwd(); $S{outdir} //="OUT"; $S{outdir} = "$cwd/$S{outdir}" unless $S{outdir} =~ m!^[./~]!; $S{outdir} =~ s!^\.!$cwd/! if $S{outdir} =~ m!^[.][^.]!; mkdir $S{outdir}; my @catlist = (); push( @catlist, (split(/:/,$S{catalog})) ) if $S{catalog}; push( @catlist, "$ENV{HOME}/.mex_catalogue") if -f "$ENV{HOME}/.mex_catalogue"; my $state = {}; if($S{h}) {print EXE(); exit 0} ### Mex skeleton if($S{h1}){print GEXER(); exit 0} ### Test skeleton my $f1 = shift or die("usage: $0 [options] file\n"); my ($f,$nam1,$nam2)=($f1,".",""); ($f,$nam1,$nam2)=get_mex_filename($f1,@catlist); die("File $f1 does not exist!\n") unless $f && -e $f; # print "### f1=$f1,F=$f,dir=$nam1,file=$nam2\n"; my $base = $nam2; $base =~ s!\.(.{1,5}$)!!; ## print STDERR "Debug: $nam1/=/$nam2; dir=$S{outdir}\n"; if($S{d}) { Exercise::Gen::Let::parseFile($f); print Dumper(\%Exercise::Gen::Let::sem ); exit 0} if($S{dl}){ Exercise::Gen::Let::lexdebug($f); exit 0} if($f =~ m/(.*)\.test$/){$S{test}=1; $S{o} ||="$S{outdir}/$1.tex"; } else { $S{o} ||="$S{outdir}/$base.tex"; } for my $id( ($S{n} ==1 ? ("") : (map {".$_" } 1 .. $S{n}))){ if($S{dm}){ debugmex ($f,$S{o})} else { mex2tex ({ ($S{nosol}? (nosol=>$S{nosol}) :()), ($S{nores}? (nores=>$S{nores}) :()), ($S{nohead}? (nohead=>$S{nohead}) :()), ($S{s} ? (s=>$S{s}) :()), ($S{tit} ? (title=>$S{tit}) :()), ($S{aut} ? (author=>$S{aut}) :()), },[$f],"$S{o}$id")} } if($S{pdf}){ tex2pdf("$S{outdir}/$base.tex"); system("jpdf $S{outdir}/$base.pdf") == 0 or system("xpdf $S{outdir}/$base.pdf") == 0 or system("open $S{outdir}/$base.pdf") == 0 or die("Error no PDF found\n"); } if($S{pdf2}){ tex2pdf("$S{outdir}/$base.tex"); } sub tex2pdf{ my $file=shift; my $pp = undef; if( -x "/usr/local/bin/ppdflatex" ){ $pp ||='/usr/local/bin/ppdflatex';} if( -x "/usr/bin/ppdflatex" ){ $pp ||='/usr/bin/ppdflatex';} if( -x "/bin/ppdflatex" ){ $pp ||='/bin/ppdflatex';} if( -x "/opt/bin/ppdflatex" ){ $pp ||='/opt/bin/ppdflatex';} if( -x "/opt/local/bin/ppdflatex" ){ $pp ||='/opt/local/bin/ppdflatex';} if($pp){ system("$pp -Q $file")== 0 or die("Error in ppdflatex\n");} else { my $op = ""; if( $file =~ m!(.+)/(.*)!) {$op="--output-directory $1"} system("pdflatex -interaction nonstopmode $op $file")== 0 or die("Error in ppdflatex\n");} } sub debugmex{ ## debug multi-exercise : generates a exe+solu+... tex file my ($f,$o)= @_; Exercise::Gen::Let::parseFile($f); Exercise::Gen::Let::calcsem(); my $t= $Exercise::Gen::Let::sem{texblocks}; my $v= $Exercise::Gen::Let::sem{ts}; my $tab=""; if($S{showrand}){ for (keys %$v ){ $tab.= sprintf("%5s | %20s | %s\n", $_, $v->{$_}{fv}, $v->{$_}{v1})}; } open (F,">:utf8",$o) or die("cant create output file $o\n");; ## for some reason, rand is being printed twice! my $rand; if ($S{showrand}){ $rand = RAND(tab => $tab); } print F LATDEBUG({showrand => $rand, map {("_$_"=>$t->{$_}{v1} )} qw(sugestion result author title usepackage resolution obs question) }); close F; if($S{cgi} or $S{db}){ my $verify = $Exercise::Gen::Let::sem{verify}; #my $vindex = $Exercise::Gen::Let::vindex; my $verify_fun = $Exercise::Gen::Let::sem{verify_fun}; if($S{db}){ mex2db($verify, $base, $S{outdir}, $verify_fun); } #else{ # mex2cgi($verify, $base, $S{outdir}, $vindex); #} } } sub mex2db{ my ($verify, $base, $outdir, $verify_fun) = @_; my %EXER; my $x= tie %EXER, 'MLDBM' , "MEX/mex.db", O_CREAT|O_RDWR, 0644 or die $! ; my $topid = $EXER{topid}; $EXER{topid} = $topid+1; my $tmp = $EXER{$topid}; $tmp->{enun} = scalar(`ppdflatex -p -Q $outdir/$base.tex | tth -a -e1 -u -r 2>/dev/null`); my $tmp2 = $tmp->{answer}; for(@{$verify}){ my $h = {answer => $_->{v1}, type => $_->{type}, func => $_->{func}}; push(@{$tmp2},$h); } $tmp->{answer} = $tmp2; $tmp->{perl} = $verify_fun; $EXER{$topid} = $tmp; print "New exercise is id: $topid \n"; } sub mex2cgi{ #deprecated my ($verify, $base, $outdir, $vindex) = @_; open (F,">:utf8", "$outdir/$base.cgi") or die("cant create output file $outdir/$base.cgi\n"); print F CGIHEAD({base => $base, enunciado => scalar( `tth -a -e1 -u -r < $S{outdir}/$base.tex`)}); for (0..$vindex-1){ print F CGIQUESTIF({answer => $verify->[$_]{v1}, number => $_+1}); } print F CGIFOOT1({}); for (0.. $vindex-1){ print F CGIQUESTELSE({number => $_+1}); } print F CGIFOOT2({}); close F; } sub get_mex_filename{ my ($f,$cata)=@_; my $a = `mex_catalogue -meta -cata "$cata" "$f"`; warn("Error $!\n") if $!; my $b = eval $a; warn("Error $@\n") if $@; # print "#####", Dumper($b); return ("","","") unless $b->[0]{file}; return ("$b->[0]{dir}/$b->[0]{file}",$b->[0]{dir},$b->[0]{file}); } sub mex2tex{ ## multi-exercise : generates a exe.tex file my %opt =(n => 1,nores=>0, nosol => 0, s => 0,nohead=>0); if(ref($_[0]) eq "HASH") {%opt = (%opt , %{shift(@_)}) } ; my ($f,$o)= @_; my @files = ref($f)? @$f : ($f); my @q = (); my @r = (); my $rule = "\n\n....................\n\n"; my @resol = (); my ($enu,$sol,$res,$t); for my $f1 (@files){ Exercise::Gen::Let::parseFile($f1); Exercise::Gen::Let::calcsem(); ## Exercise::Gen::Let::calcnewchoice(); $t= $Exercise::Gen::Let::sem{texblocks}; $opt{title} //= $t->{title}{v1}; $opt{subtitle} //= $t->{author}{v1}; $opt{data} //= $t->{data}{v1}; push(@q ,{q=> $t->{question}{v1} }); push(@r ,{q=> $t->{question}{v1} . $rule . $t->{result}{v1} }); push(@resol ,{q=> $t->{question}{v1} . $rule . $t->{resolution}{v1} }); } my %meta = ( title => $opt{title}, subtitle => $opt{author} || '\mbox{}' , data => $opt{data} || '\today' ); if ($opt{s}==0){ $enu= join("\n\n\\hrule\n\n",map {$_->{q}} @q); $sol= join("\n\n\\hrule\n\n",map {$_->{q}} @r); $res= join("\n\n\\hrule\n\n",map {$_->{q}} @resol); } elsif($opt{s}==1){ $enu= question( @q); $sol= question( @r); $res= question( @resol); } elsif($opt{s}==2){ $enu = ENUN({ questions => question( @q), %meta }); $sol = ENUN({ questions => question( @r), %meta }); $res = ENUN({ questions => question( @resol), %meta }); } my $body= join('\newpage ', ( $enu, ($opt{nosol} ? () : ($sol)), ($opt{nores} ? () : ($res)), )); if($opt{nohead}){ open (F,">:utf8",$o) or die("cant create output file $o\n"); print F $enu; close F; open (F,">:utf8","$o-sol") or die("cant create output file $o\n"); print F $res; close F; } else { open (F,">:utf8",$o) or die("cant create output file $o\n"); print F TEX( { _usepackage => $t->{usepackage}{v1}, tex_body => $body, }); close F; } } __DATA__ =encoding utf8 __jjaulas__ \RequirePackage[a4paper,top=2cm,left=2cm,right=2cm,bottom=1.5cm,nohead,nofoot]{geometry} \parindent 0pt \parskip 3pt \fvset{fontsize=\small, numbers=left, frame=leftline, numberblanklines=false} \newcounter{quest} %\def\theenumi{\alpha{enumi}} \newenvironment{questao}[2][]{ \def\theenumi{\alph{enumi})} \addtocounter{quest}{1}{\bf Quest\~ao \thequest\ (#2)} \marginpar{#1} }{ \addvspace{2mm}\mbox{}\hrule\mbox{} } \newenvironment{exame}[3]{\noindent\fbox{\begin{minipage}{\textwidth}\begin{center} {\Huge #1 \\ \huge #2 \\ \large #3\\} \end{center}\end{minipage}} \mbox{}\\}{} \newcommand{\exametitle}[3]{\noindent\fbox{\begin{minipage}{\textwidth}\begin{center} {\Huge #1 \\ \huge #2 \\ \large #3\\} \end{center}\end{minipage}} \mbox{}\\} \newif\iftth __LATDEBUG__ [%default:{ _usepackage=>'%no #usepackage provided', _sugestion =>'... no sugestion provided', _resolution=>'... no resolution provided', _author=>'', data=>'\today', _obs=>'', sugestion => 'sugestion', resolution => 'resolution', result => 'result', showrand => '', }%] \documentclass[portuges,a4paper]{article} \usepackage{babel} \usepackage[mathletters]{ucs} \usepackage[utf8x]{inputenc} \usepackage[T1]{fontenc} \usepackage{fancyvrb} %\usepackage{t1enc} %\usepackage{jjaulas} \usepackage{graphicx} [% _usepackage %] [%!jjaulas %] \begin{document} \exametitle{[% _title %]}{[% _author %]\mbox{}}{[%data%]} \iftth \begin{html}
\end{html} \fi \subsection*{Question} [% _question %] \iftth \begin{html}
\end{html} \fi [% sugestion*VISTOGGLE1 %] \subsection*{Sugestion} [% sugestion*VISTOGGLE2 %] [% _sugestion %] [%!VISTOGGLE3 %] [% resolution*VISTOGGLE1 %] \subsection*{Resolution} [% resolution*VISTOGGLE2 %] [% _resolution %] [%!VISTOGGLE3 %] [% result*VISTOGGLE1 %] \subsection*{Result} [% result*VISTOGGLE2 %] [% _result %] [%!VISTOGGLE3 %] \subsection*{Obs} [% _obs %] [% showrand %] \iftth \begin{html}



\end{html} \fi \end{document} __RAND__ \subsection*{Random choices} {\small \begin{verbatim} [% tab %] \end{verbatim} } __VISTOGGLE1__ \iftth \begin{html}\end{html} \fi __VISTOGGLE2__ \iftth \begin{html}\end{html} \fi __EXE__ #title: #author: #date: (def=\today) #let: n a =[ ]; a ~ b; #question: \begin{enumerate} \item \end{enumerate} #sugestion: #resolution: #result: #Verify: #usepackage % \usepackage{...} latex preambula __GEXER__ template: ~/svn/gexer/Exercise-Gen/example/jj.tskel problems: ~/svn/gexer/ versions: 4 title: Teste Matemática Jun 2011 subtitle: exemplo inocente =*Introdução Este teste destina-se a preparar os alunos para o prémio nobel (pedir não custa). #q{EqQua2.txt} #q{DerivadaDoProduto.txt} #q[2]{Estatica.txt} #q{DerivadaDaFuncaoComposta.txt} #q{inline{Quanto é $3 \times 9$?}{$9+9+9=27$}{27} } __ENUN__ \exametitle{[% title %]}{[% subtitle %]}{[%data%]} [% questions %] __TEX__ [%default:{_usepackage=>'', tex_title => '', }%] \documentclass[portuges,a4paper]{article} \usepackage{babel} \usepackage[mathletters]{ucs} \usepackage[utf8x]{inputenc} \usepackage[T1]{fontenc} \usepackage{fancyvrb} %\usepackage{t1enc} %\usepackage{jjaulas} \usepackage{graphicx} [% _usepackage %] [%!jjaulas %] \begin{document} %\fvset{fontsize=\small, frame=single, numberblanklines=false} [% tex_title %] [% tex_body %] \end{document} __CGIHEAD__ #!/usr/bin/perl use CGI q(:all); print header(-charset=>'utf-8'); print start_html("[% base %]"); ###system("cat [% base %].html"); print q{[% enunciado %]}; print start_form; ## gerado pelo verify block if(param()) { __CGIQUESTIF__ ## pergunta [% number %] $answer = param('p[% number %]'); print "Pergunta 1: ", textfield('p[% number %]'); if ($answer eq [% answer %]) { print 'Correcto!'; } else{ print 'Errado!'; } print "
\n"; __CGIFOOT1__ } else { __CGIQUESTELSE__ print "Pergunta [% number %]: ", textfield('p[% number %]'), "
\n"; __CGIFOOT2__ } print submit, end_form, end_html; __END__ =head1 NAME mex2t - MEX-based Exercise Generator =head1 SYNOPSIS To obtain templates/example: mex2t -h -- print multi-exercise template mex2t -h1 -- print multi-test template To print all sections of a mex-file mex2t -dm problem.txt -- debug the mex-file mex2t -dm -pdf problem.txt -- makes pdf and shows it mex2t -dm -pdf2 problem.txt -- makes pdf mex2t -srand 45 ... -- forces random seed (for testing purposes) -nosol -- skip solution section -nores -- skip resolution section -showrand -- show the random choices done -outdir dir -- output direcctory (def=OUT) -o file -tit="Title of the test" default: title from first mex -aut="author name" default: author of the first mex Debug the lex-level of the mex-file (FIXME) mex2t -dl -- debug the lexer stage mex2t -pdf math.test =head1 DESCRIPTION =head2 Mex Format =head1 AUTHOR J.Joao Almeida, jj@di.uminho.pt =head1 SEE ALSO perl(1). =cut