#!/usr/bin/perl # PASSarola TEST generator v1.0 use utf8::all; use strict; use warnings; use Getopt::Long qw(:config no_auto_abbrev ); use Pod::Usage; use Exercise::Proc::Parse; use Parse::DSLUtils; skimport(); use Data::Dumper; use Exercise::Gen::Verify; use Cwd; my %S=(id=>""); GetOptions( \%S, qw{help|? man l s=i o=s n=i passdir=s pdf pdf2 nosol nores test showrand nohead no h dl dm test pdf pdf2 store tit=s aut=s outdir=s catalog=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}; my $catal = ($S{catalog} ? "-catalog $S{catalog}" : ""); my %store_exs = (); 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}; if($S{h}){print TESTEXE(); exit 0} ### Test example skeleton my $f=shift or die("usage: $0 [options] file\n"); my $basename=$f; $basename =~ s/\.test$//; my $basepath=$f; $basepath =~ s/[^\/]*\..*$//; Exercise::Proc::Parse::parseFile($f); my $t = \%Exercise::Proc::Parse::sem; my @secs = map { ( q_item2tex(@{$_}) ) } @{ $t->{q} }; if($S{store}){ set_pass_basedir($S{passdir}) if $S{passdir}; my $exid = pass_newid(); set_exercise_test($exid, \%store_exs); print "New test is id: $exid \n"; } else{ open(F,">",$basename."-enun.tex") or die("pass-test: Can't create ".$basename."-enun.tex"); # open(F,">","$basename-enun.tex") or die("cant create $basename-enun.tex"); print F TEX( ### tex_title=> "\\exametitle{$t->{title}}{$t->{subtitle}}{}", {title => $t->{title}, subtitle => $t->{subtitle}, usepackage => ($t->{usepackage}|| ""), date => $t->{date}, tex_body => [ map {$_->[0]} @secs] }); close F; open(F,">",$basename."-sol.tex") or die("pass-test: Can't create ".$basename."-sol.tex"); # open(F,">","$basename-sol.tex") or die("cant create $basename-sol.tex"); print F TEX( ### tex_title=> "\\exametitle{$t->{title}}{$t->{subtitle}}{}", {title => $t->{title}, subtitle => $t->{subtitle}, usepackage => ($t->{usepackage}|| ""), date => $t->{date}, tex_body => [ map {$_->[1]} @secs] }); close F; } if($S{pdf} or $S{pdf2}){ __system("/usr/local/bin/ppdflatex -Q $basename-sol.tex") or die("Error in ppdflatex\n"); __system("/usr/local/bin/ppdflatex -Q $basename-enun.tex") or die("Error in ppdflatex\n"); if($S{pdf}){ showpdf($basename.'-enun.pdf'); # __system("jpdf $basename-enun.pdf") # or __system("evince $basename-enun.pdf") # # or __system("xpdf $basename-enun.pdf") # or __system("open $basename-enun.pdf") # or die("Error no PDF found\n"); } } sub __system { my $cmd = shift; print STDERR "$cmd\n" if $S{dl} ; if(system ($cmd) == 0){ return 1} else { warn "** ERROR ****** system $cmd failed: $!$?\n"; return 0 } } sub q_item2tex{ my $f=shift ; ## translate question item -> LaTeX x LaTeX if($f eq "q" ){ if(ref($_[0]) eq "ARRAY"){ my ($func,@a) = @{$_[0]}; if($func eq "inline"){ return [question({q => $a[0]}), question({q => $a[1]})];} if($func eq "choice"){ my ($aux,$l1) ; ($aux,$l1) = _choice(@a); my $option = $S{passdir} ? "-passdir=$S{passdir}" : ""; if($S{store}){ db_untie(); my $new_id = `pass-exer $catal $option -store -d -test '$aux'`; db_tie(); $store_exs{$new_id} = "stored"; ##__system("pass-exer -store -d -test '$aux'"); } else{ __system("pass-exer $catal -no '$aux'"); } my $file="OUT/$aux"; $file=~ s/\.(txt|mex|pex)$/.tex/ or $file .= '.tex'; return( [question({q=> slurp8($file)}), question({q=> slurp8("$file-sol") })]); } return([question({q => "Error Unexpected: $func"}),666]); } else{ return([ question({q => "Error Unexpected2: $_[0]"}),666]); } } if($f eq "tex"){ return [$_[0],$_[0] ] } if($f eq "q*" ){ my @out = (); my ($card,$vals) = @_; my ($func,@a) = @{$vals}; if($func eq "choice"){ for my $i(1..$card){ my ($aux,$l1) ; ($aux,$l1) = _choice(@a); print("Processing $aux\n"); #print "file and q* $aux\n"; if($S{store}){ #push(@store_exs, `pass-exer -store -d -passdir=$S{passdir} -test $aux`);; } else{ __system("pass-exer $catal -no '$aux'"); } my $file="OUT/$aux"; $file=~ s/\.(txt|mex|pex)$/.tex/; push( @out , [ question({ q => slurp8($file) }), question({ q => slurp8("$file-sol")})]); } return @out; } return([ question({q => "Error Unexpected3: $func"}),666]); } return([ question({q => "Error Unexpected5: $f"}),666]); } sub slurp8{ open(F,"<:utf8",$_[0]) or die("pass-test.slurp8: Can't read '$_[0]'.\n"); # open(F,"<:utf8",$_[0]) or die("cant read $_[0]\n"); my $a=join("",); return $a; } sub _choice{ my @a=@_; ## choose a (value,index) pair from a list warn("choice in an empty list\n") unless (@a); return (undef) unless @a; my $i = int(rand(scalar @a)); ($a[$i], $i) } sub showpdf{ my $p=shift(@_); my $shh = ' > /dev/null 2>&1'; # para manter os comandos calados ($S{d1} and system("acroread $p".$shh) == 0) or system("jpdf $p".$shh) == 0 or #system("xpdf $p".$shh) == 0 or system("evince $p".$shh) == 0 or system("gnome-open $p".$shh) == 0 or system("open $p".$shh) == 0 or die("pass-exer.showpdf: Unable to find pdf (".$p.")\n"); } __END__ if($dl){Exercise::Gen::Let::lexdebug($f); exit 0} __DATA__ # jjaulas; # TESTEXE; # question({q => '__',}); # TEX({usepackage=>, tex_body=>, tex_title=>, data=>, suptitle=>, title =>,}); __jjaulas__ \RequirePackage[a4paper,top=2cm,left=2cm,right=2cm,bottom=2cm,nohead]{geometry} \parindent 0pt \parskip 3pt \usepackage{fancyvrb} \fvset{fontsize=\small, numbers=left, frame=leftline, numberblanklines=false} \newcounter{quest} \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 \\ \mbox{}\large #3\\} \end{center}\end{minipage}} \mbox{}\\} __TESTEXE__ title: Test of subtitle: ... date:\today usepackage:{\usepackage{...} ... } \section{Introduction} #q{file1.txt} #q[5]{file1.txt} \section{Part 2} #q{file1, file2, file3} #q{inline{9*sqrt(9)=?}{=9*3=27}{27}} __question__ \begin{questao}{} [% q %] \end{questao} __TEX__ [%default:{ usepackage=>'', tex_title => sub{ my %a=@_; my $d= $a{date} || '\today'; my $s= $a{subtitle} || '\mbox{}'; qq{\\exametitle{$a{title}}{$s}{$d}}} }%] \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} __END__ =pod =encoding utf8 =head1 NAME pass-test - Passarola Test (Exercise Set) Generator =head1 SYNOPSIS pass-test [I