#!/usr/bin/perl use strict; use Getopt::Std; use File::Slurp qw/slurp/; use File::Spec::Functions; use Config::AutoConf; use Digest::MD5 'md5_hex'; use Memoize; memoize("check_tools_for"); our $VERSION = '0.02'; my $n = 0; my @temporary_files; my $DEBUG = 0; my %opts; getopts('nsQDho:', \%opts) or die "Use -h to see usage information.\n"; help() if $opts{h}; $DEBUG = 1 if $opts{D}; ## Possivelmente podemos passar a usar o RegExp::Common, nao? :) ##jj talvez tenhas raz�o ##ambs agora temos as expressoes regulares recursivas O:-) our $cam2tex_counter = 0; my $TMPDIR = 'tex-cache'; mkdir $TMPDIR unless -d $TMPDIR; my $bl0 = qr([^{}]*); my $bl1 = qr(\{$bl0\}); my $bl2 = qr(\{$bl0($bl1*$bl0)*\}); my $bl3 = qr(\{$bl0($bl2*$bl0)*\}); my $bl4 = qr(\{$bl0($bl3*$bl0)*\}); # Called for # \import_x{file} --> proc_file sub syst{ my $a = shift; print LOG "...system($a)\n"; system $a; } sub systopen { my $a = shift; print LOG "...open($a|)\n"; open X, "-|", $a or die $!; 1 while (<X>); close X; } my %importer_types = ( ### type -> function ; ### function = filename * options * md5 -> latexStr pass2 => sub { my ($f, $op, $md5) = @_; my $id=$op->{id} || 33; my $r; my $o = catfile $TMPDIR, "$md5-$id"; if (! -f "$o-sol") { syst "pass-exer -nohead -srand=$id -o=$o $f"; } $r = slurp("$o-sol"); my($enun,$sol)= ($r =~ m/(.*?)\.{20}\n*(.*)/s); $r=""; if($op->{enun}) { $r .= $enun;} if($op->{sol}) { $r .= '\solname '.$sol;} if($op->{result}){ $r .= $sol;} return $r; }, pass => sub { my ($f, $op, $md5) = @_; my $id=$op->{id} || 33; my $r; my $o = catfile $TMPDIR, "$md5-$id"; if (! -f "$o-sol") { syst "pass-exer -d -nohead -srand=$id -o=$o-sol $f"; } $r = slurp("$o-sol"); my($question,$suggestion,$result,$resolution); ($question) = ($r =~ m/%%%QUESTION\n.*?\n(.*?)%%%/s); ($suggestion) = ($r =~ m/%%%SUGG?ESTION\n.*?\n(.*?)%%%/s); ($result) = ($r =~ m/%%%RESULT\n.*?\n(.*?)%%%/s); ($resolution) = ($r =~ m/%%%RESOLUTION\n.*?\n(.*?)%%%/s); my($r1,$r2,$sopt)=("","",""); $r1 .= $question; if($op->{endresolution}){ $r2.= $resolution || $result;} elsif($op->{endresult}){ $r2.= $result || $resolution;} else { $r2.= $resolution || $result; $sopt = '[print]'} return "\\begin{question}$r1\\end{question} \\begin{solution}$sopt$r2\\end{solution}"; }, pass1 => sub { my ($f, $op, $md5) = @_; my $id=$op->{id} || 33; my $r; my $o = catfile $TMPDIR, "$md5-$id"; my $options =''; $options .= " -res" if $op->{res}; $options .= " -solved" if $op->{solved}; if (! -f "$o") { { syst "pass-exsheets $options -srand=$id -o=$o $f";} } # print STDERR "DEBUG: pass-exsheet -res -srand=$id -o=$o $f\n"; return slurp("$o"); }, html => sub { my ($f, $op, $md5) = @_; my $o = catfile $TMPDIR, $md5; if (! -f "$o.pdf") { $f =~ m/html?$/ or die "Invalid extension for HTML inclusion [$f]\n"; syst "htmldoc --textfont times --footer ... --header ... --webpage -f $o.pdf $f"; } temp($o); return "\\includepdf[pagecommand={},pages=-]{$o}"; }, pod => sub { my ($f, $op, $md5) = @_; my $o = catfile $TMPDIR, $md5; my $def = { "h1level" => 2, (%{$op}) }; if (! -f "$o.tex") { syst "pod2latex -h1level $def->{h1level} -out $o $f"; } my $r = slurp("$o.tex"); $r =~ s/section\{(.*?)\}/"section{". ucfirst(lc($1)) ."}"/ge; return $r; }, makefileg => sub { my ($f, $op, $md5) = @_; $op = {scale => 0.7, (%{$op}) }; my $tmpfile = catfile $TMPDIR, "_${md5}_"; if (!-f "$tmpfile.pdf") { gvmake($op, $f, temp("$tmpfile.pdf")); } delete $op->{root}; delete $op->{trim_mode}; delete $op->{rankdir}; return "\\includegraphics[".hash2texargs($op)."]{$tmpfile.pdf}"; }, dot => sub { my ($f, $op, $md5) = @_; my $o= catfile $TMPDIR, $md5; my $def={scale => "0.9", pagecommand => "", frame => "true", nup => "1x2", pages => "-", delta => "0.5cm 0.5cm", (%{$op})}; if (! -f "$o.pdf") { ## \begin{import_dot}[neato,width=\textwidth] if (defined($op->{neato})) { syst "neato -Tpdf $f > ${f}_.pdf"; } elsif (defined($op->{twopi})) { syst "twopi -Tpdf $f > ${f}_.pdf"; } elsif (defined($op->{circo})) { syst "circo -Tpdf $f > ${f}_.pdf"; } else { syst "dot -Tpdf $f > ${f}_.pdf"; } systopen("pdfcrop --xetex ${f}_.pdf $o.pdf"); unlink "${f}_.pdf"; } temp("$o.pdf"); delete($op->{twopi}); delete($op->{circo}); delete($op->{neato}); return "\\includegraphics[".hash2texargs($op)."]{$o.pdf}"; }, slides => sub { my ($f, $op,$md5) = @_; my $def = { scale => "0.9", pagecommand => "", frame => "true", nup => "1x2", pages => "-", delta => "0.5cm 0.5cm", (%{$op})}; return "\\includepdf[".hash2texargs($def)."]{$f}"; }, ); # Called for # \inline_x{...} e \begin{import_x}....\end{import_x} --> proc_str ### type -> function ### function = str * options * md5 -> latexStr my %environment_types = ( abcl => sub{ my ($f, $op, $md5) = @_; my $abcop ="-c -q "; $abcop .= "-a $op->{a}" if $op->{a}; my $midiop = ""; $midiop = "-Q $op->{t}" if $op->{t}; my $pin = '\fbox{\textmusicalnote}'; $pin = '$\odot$' if $op->{pin}eq "odot"; $pin = '\fbox{\textmusicalnote}' if $op->{pin}eq "note"; my $incipit=""; $n++; print LOG "abcl $n - $TMPDIR/_${md5}_.abc\n"; my $tmpfile = catfile $TMPDIR, "_${md5}_"; $incipit = "\\incipit{$tmpfile}" if $op->{incipit}; my $sound= ""; my $image= ""; if (!-f "$tmpfile.pdf") { open (F, ">$tmpfile.abcl") or die "Cant create temporary file($tmpfile.abcl)\n"; print F $f,"\n"; close F; # syst "abcm2ps $abcop $tmpfile.abc -O ${tmpfile}_.ps"; # syst "ps2pdf ${tmpfile}_.ps ${tmpfile}_.pdf"; # if($op->{incipit}){ # my $incipitop =""; # $incipitop="-M" if $op->{incipit} eq "nolyrics"; # syst "abc2incipit $incipitop $tmpfile.abc"; # } # systopen("pdfcrop --xetex ${tmpfile}_.pdf $tmpfile.pdf"); syst "abcl $tmpfile.abcl > $tmpfile.abc"; syst "abcm2ps $abcop $tmpfile.abc -O ${tmpfile} -E"; syst "epstopdf ${tmpfile}001.eps -o=$tmpfile.pdf"; } if($op->{mp3}){ if (!-f "$tmpfile.mp3") { syst "abc2midi $tmpfile.abc $midiop -o ${tmpfile}_.mid > _.log"; syst "timidity --quiet -Ow ${tmpfile}_.mid -o ${tmpfile}_.wav > _.log"; syst "lame --quiet ${tmpfile}_.wav $tmpfile.mp3 > _.log"; unlink "${tmpfile}_.wav"; } # $displayPin="\\def\\displayPin#1{\\marginpar[]{#1}\\\\}" # $sound="\\displayPin{\\attachfile[color=1 1 1]{$tmpfile.mp3}}"; $sound="\\displayPin{\\textattachfile[color=1 0 0]{$tmpfile.mp3}{$pin}}"; } elsif($op->{wav}){ if (!-f "$tmpfile.wav") { syst "abc2midi $tmpfile.abc $midiop -o ${tmpfile}_.mid > _.log"; syst "timidity --quiet -Ow ${tmpfile}_.mid -o $tmpfile.wav > _.log"; } # $sound="\\displayPin{\\attachfile[color=1 1 1]{$tmpfile.wav}}"; $sound="\\displayPin{\\textattachfile[color=1 0 0]{$tmpfile.wav}{$pin}}"; } elsif($op->{midi}){ if (!-f "$tmpfile.mid") { syst "abc2midi $tmpfile.abc $midiop -o $tmpfile.mid > _.log"; } $sound="\\displayPin{\\textattachfile[color=1 0 0]{$tmpfile.mid}{$pin}}"; } unlink "${tmpfile}_.pdf", "${tmpfile}_.ps"; ## unlink "$tmpfile.abc"; my $ign=$op->{noscore}; delete $op->{mp3}; delete $op->{noscore}; delete $op->{wav}; delete $op->{midi}; delete $op->{t}; delete $op->{pin}; delete $op->{a}; temp("$tmpfile.pdf"); $image="\\includegraphics[".hash2texargs($op)."]{$tmpfile}" if not $ign; return $image.$sound; }, abc => sub { my ($f, $op, $md5) = @_; my $abcop ="-c -q "; $abcop .= "-a $op->{a}" if $op->{a}; my $midiop = ""; $midiop = "-Q $op->{t}" if $op->{t}; my $pin = '\fbox{\textmusicalnote}'; $pin = '$\odot$' if $op->{pin}eq "odot"; $pin = '\fbox{\textmusicalnote}' if $op->{pin}eq "note"; my $incipit=""; $n++; print LOG "abc $n - $TMPDIR/_${md5}_.abc\n"; my $tmpfile = catfile $TMPDIR, "_${md5}_"; $incipit = "\\incipit{$tmpfile}" if $op->{incipit}; my $sound= ""; my $image= ""; if (!-f "$tmpfile.pdf") { open (F, ">$tmpfile.abc") or die "Cant create temporary file($tmpfile.abc)\n"; print F $f,"\n"; close F; # syst "abcm2ps $abcop $tmpfile.abc -O ${tmpfile}_.ps"; # syst "ps2pdf ${tmpfile}_.ps ${tmpfile}_.pdf"; # if($op->{incipit}){ # my $incipitop =""; # $incipitop="-M" if $op->{incipit} eq "nolyrics"; # syst "abc2incipit $incipitop $tmpfile.abc"; # } # systopen("pdfcrop --xetex ${tmpfile}_.pdf $tmpfile.pdf"); syst "abcm2ps $abcop $tmpfile.abc -O ${tmpfile} -E"; syst "epstopdf ${tmpfile}001.eps -o=$tmpfile.pdf"; if($op->{incipit}){ my $incipitop =""; $incipitop="-M" if $op->{incipit} eq "nolyrics"; syst "abc2incipit $incipitop $tmpfile.abc"; systopen("pdfcrop --xetex ${tmpfile}_.pdf $tmpfile.pdf"); } } if($op->{mp3}){ if (!-f "$tmpfile.mp3") { syst "abc2midi $tmpfile.abc $midiop -o ${tmpfile}_.mid > _.log"; syst "timidity --quiet -Ow ${tmpfile}_.mid -o ${tmpfile}_.wav > _.log"; syst "lame --quiet ${tmpfile}_.wav $tmpfile.mp3 > _.log"; unlink "${tmpfile}_.wav"; } # $displayPin="\\def\\displayPin#1{\\marginpar[]{#1}\\\\}" # $sound="\\displayPin{\\attachfile[color=1 1 1]{$tmpfile.mp3}}"; $sound="\\displayPin{\\textattachfile[color=1 0 0]{$tmpfile.mp3}{$pin}}"; } elsif($op->{wav}){ if (!-f "$tmpfile.wav") { syst "abc2midi $tmpfile.abc $midiop -o ${tmpfile}_.mid > _.log"; syst "timidity --quiet -Ow ${tmpfile}_.mid -o $tmpfile.wav > _.log"; } # $sound="\\displayPin{\\attachfile[color=1 1 1]{$tmpfile.wav}}"; $sound="\\displayPin{\\textattachfile[color=1 0 0]{$tmpfile.wav}{$pin}}"; } elsif($op->{midi}){ if (!-f "$tmpfile.mid") { syst "abc2midi $tmpfile.abc $midiop -o $tmpfile.mid > _.log"; } $sound="\\displayPin{\\textattachfile[color=1 0 0]{$tmpfile.mid}{$pin}}"; } unlink "${tmpfile}_.pdf", "${tmpfile}_.ps"; ## unlink "$tmpfile.abc"; my $ign=$op->{noscore}; delete $op->{mp3}; delete $op->{noscore}; delete $op->{wav}; delete $op->{midi}; delete $op->{t}; delete $op->{pin}; delete $op->{incipit}; delete $op->{a}; temp("$tmpfile.pdf"); $image="\\includegraphics[".hash2texargs($op)."]{$tmpfile}" if not $ign; return $incipit.$image.$sound; }, dot => sub { my ($f, $op, $md5) = @_; my $t = 'dot'; $n++; print LOG "dot $n - $TMPDIR/_${md5}_.dot\n"; my $tmpfile = catfile $TMPDIR, "_${md5}_"; if (! -f "$tmpfile.pdf") { open (F, ">$tmpfile.$t") or die "Cant create temporary file($tmpfile.$t)\n"; print F $f; close F; if (defined($op->{neato})) { syst "neato -Tpdf $tmpfile.$t > ${tmpfile}_.pdf"; } elsif (defined($op->{twopi})) { syst "twopi -Tpdf $tmpfile.$t > ${tmpfile}_.pdf"; } elsif (defined($op->{circo})) { syst "circo -Tpdf $tmpfile.$t > ${tmpfile}_.pdf"; } else { syst "dot -Tpdf $tmpfile.$t > ${tmpfile}_.pdf"; } systopen("pdfcrop --xetex ${tmpfile}_.pdf $tmpfile.pdf"); unlink "${tmpfile}_.pdf"; unlink "$tmpfile.$t"; } delete $op->{neato}; delete $op->{circo}; delete $op->{twopi}; temp("$tmpfile.pdf"); return "\\includegraphics[".hash2texargs($op)."]{$tmpfile}"; }, makefileg => sub { my ($f, $op, $md5) = @_; $op = {scale => 0.7, (%{$op}) }; $n++; print LOG "makefileg $n - $TMPDIR/_${md5}_.make\n"; my $tmpfile = catfile $TMPDIR, "_${md5}_"; if (!-f "$tmpfile.pdf") { open (F, ">$tmpfile") or die "Cant create temporary file($tmpfile)\n"; print F $f; close F; gvmake($op, $tmpfile, temp("$tmpfile.pdf")); unlink $tmpfile; } delete $op->{root}; delete $op->{trim_mode}; delete $op->{rankdir}; return "\\includegraphics[".hash2texargs($op)."]{$tmpfile.pdf}"; }, csv => sub { my ($f,$op) = @_; $op = {fs => "\t", head => 1, lhead => 0, %$op}; $n++; print LOG "csv $n\n"; my @l = split(/\n/,$f) ; shift(@l) while(not $l[0] =~ /\S/); my @fl =""; @fl = (split( $op->{fs}, shift(@l))); my $cols= join("",(map {"|l"} @fl ))."|"; my $final="\\begin{tabular}{$cols}\\hline\n"; $final .= join("&",@fl)."\\\\"; $final .= '\hline' if $op->{head}; for(@l){ if(/^[-_]+$/) { $final .= "\n\\hline";} else { $final .= "\n". join(" & ",split( $op->{fs}, $_,-1)). '\\\\';} } $final.='\hline\end{tabular}'; return $final; }, gnuplot => sub { my ($f, $op, $md5) = @_; $n++; print LOG "gnuplot $n - $TMPDIR/_${md5}_\n"; my $tmpfile = catfile $TMPDIR, "_${md5}_"; if (!-f "$tmpfile.tex") { open (F, ">$tmpfile.gnuplot") or die "Cant create temporary file($tmpfile.gnuplot)\n"; print F "set terminal cairolatex\nset output '$tmpfile.tex'\n"; print F $f; close F; syst "gnuplot $tmpfile.gnuplot"; unlink "$tmpfile.gnuplot"; } temp("$tmpfile.tex"); return "\\input{$tmpfile.tex}"; }, camila => sub { my ($f, $op, $md5) = @_; $n++; print LOG "camila $n - $TMPDIR/_${md5}_\n"; my $tmpfile = catfile $TMPDIR, "_${md5}_"; if (! -f "$tmpfile.tex") { # -- ver bichomp -- $f = substr($f, 1, length($f)-2); $f =~ s/;?(\s*)$/;$1/; $f =~ s/ENDTYPE;?(\s*)$/ENDTYPE$1/; open F, "| tee $tmpfile.camila | cam2tex > $tmpfile.tex" or die "can't cam2tex\n"; print F $f; close F; } my $res = slurp("$tmpfile.tex"); $res =~ s/\\\\\s*$//; # isto ate' ja' parece java!!! if ($op->{framed}) { my $length = ($op->{framed} =~ /(\d+)/)?$1:0; my $save_fs = ""; if (!$cam2tex_counter) { $save_fs = "\\newlength{\\camtmp}\\setlength\\camtmp{\\FrameSep}\n"; $cam2tex_counter = 1; } my $set_fs = "\\setlength\\FrameSep{${length}mm}\n"; my $restore_fs = "\\setlength\\FrameSep{\\camtmp}\n"; $res = "$save_fs$set_fs\n\\begin{framed} \n $res \n \\end{framed} \n$restore_fs\n\n"; } return $res; }, html => sub { my ($f, $op, $md5) = @_; # my $o=$f; # $o =~ s/html?$/pdf/ or die("invalid extension\n"); # system("htmldoc --textfont times --footer ... --header ... --webpage -f $o $f"); # return "\\includepdf[pagecommand={},pages=-]{$o}" }, pod => sub { my ($f, $op, $md5) = @_; # my $o=$$; # my $def={"h1level" => 2, # (%{$op})}; # system("pod2latex -h1level $def->{h1level} -out $o $f"); # my $r = slurp("$o.tex"); # $r =~ s/section\{(.*?)\}/"section{". ucfirst(lc($1)) ."}"/ge; # unlink("$o.tex"); # return $r; }, ); open LOG, ">", "teximporter$$.log" or die "Cannot open teximporter$$.log logfile.\n"; undef $/; while(<>) { my %save = (); my $n1 = 0; s{( \\begin\{[Vv]erbatim\} .*? \\end\{[Vv]erbatim\})} { $save{++$n1}=$1;"__SSAVE${n1}__"}xges; ## save verbatim s{([^\\]) (\%.*)} { $save{++$n1}=$2;"$1__SSAVE${n1}__"}xge; ## save comm s{ \\input \{ ([^\}]+) \} } { $a = $1; if (-f $a) { system("teximporter $a > __$a")==0 or die $?; } if (-f "$a.tex") { system("teximporter $a.tex > __$a.tex")==0 or die $?; } "\\input{__$a}" }gex unless $opts{n}; s{ (\\begin\{import_(\w+)\} (?: \[ (.*?) \] )? ((?:.|\n)*?) \\end\{import_\2\}) } { my ($a1,$a2,$a3,$a4)=($1,$2,$3,$4); my $md5 = md5_hex($a1); $a1 =~ s{__SSAVE(\d+)__}{$save{$1}}g; $a4 =~ s{__SSAVE(\d+)__}{$save{$1}}g; proc_str($md5, $a2, $a4, args2hash($a3)) }xge; s{ (\\begin\{_(\w+)\} (?: \[ (.*?) \] )? ((?:.|\n)*?) \\end\{_\2\}) } { my ($a1,$a2,$a3,$a4)=($1,$2,$3,$4); if ($environment_types{$a2}){ my $md5 = md5_hex($a1); $a1 =~ s{__SSAVE(\d+)__}{$save{$1}}g; $a4 =~ s{__SSAVE(\d+)__}{$save{$1}}g; proc_str($md5, $a2, $a4, args2hash($a3)); } else { $a1 } }xge unless $opts{s}; s{ (\\_(\w+) (?: \[ (.*?) \] )? ($bl4)) } { my ($a1,$a2,$a3,$a4)=($1,$2,$3,$4); if ($environment_types{$a2}) { $a1 =~ s{__SSAVE(\d+)__}{$save{$1}}g; $a4 =~ s{__SSAVE(\d+)__}{$save{$1}}g; my $md5 = md5_hex($a1); proc_str($md5, $a2, bichomp($a4), args2hash($a3)); } else { $a1 } }xge unless $opts{s}; s{ (\\inline_(\w+) (?: \[ (.*?) \] )? ($bl4)) } { my ($a1,$a2,$a3,$a4)=($1,$2,$3,$4); $a1 =~ s{__SSAVE(\d+)__}{$save{$1}}g; $a4 =~ s{__SSAVE(\d+)__}{$save{$1}}g; my $md5 = md5_hex($a1); proc_str($md5, $a2, bichomp($a4), args2hash($a3)) }xge; s{ \\import_(\w+) (?: \[ (.*?) \] )? \{ (.*?) \} } { proc_file($1, $3, args2hash($2)) }xge; s{__SSAVE(\d+)__}{$save{$1}}g; if($opts{o}){ open(my $Fo, ">", $opts{o}) or die ("cant create $opts{o}"); print $Fo $_; close $Fo; } else { print; } } print STDERR "Temporary files: @temporary_files\n" if $DEBUG; close LOG; # Save a file on temporary_files array sub temp { push @temporary_files, @_; return $_[0]; } sub bichomp{ my $a=shift; $a =~ s/^{//; $a =~ s/}$//; $a; } sub args2hash { my %save = (); my $n = 0; my $a1 = shift; $a1 =~ s/(\{.*?\})/$save{++$n}=$1;"__SAVE${n}__"/ge; $a1 =~ s/,/=,=/g; $a1 =~ s/__SAVE(\d+)__/$save{$1}/g; return { map { (m/(\w+)=(.*)/) ? ($1=>$2) : ($_=>"true") } split(/\s*=,=\s*/,$a1) }; } sub hash2texargs { my $a = shift; die "invalid hash ref $a\n" unless ref($a) eq "HASH"; return join(",", (map { "$_=$a->{$_}" } keys %$a)); } sub proc_file { my ($t,$f,$op) = @_; $op ||= {}; my $sl=slurp($f); my $md5 = -f $f ? md5_hex($sl) : md5_hex(localtime); warn(" Processing a $t primitive...\n") unless $opts{Q}; if (exists($importer_types{$t})) { check_tools_for($t); return $importer_types{$t}->($f, $op, $md5); } elsif (exists($environment_types{$t})) { # check_tools_for($t); # return $environment_types{$t}->(slurp($f), $op, $md5); return proc_str($md5,$t,$sl,$op); } else { warn ("unknown import file type: '$t'\n"); } } sub proc_str { my ($md5, $t, $f,$op)=@_; $op ||= {}; warn(" Processing a $t primitive...\n") unless $opts{Q}; if (exists($environment_types{$t})) { check_tools_for($t); return $environment_types{$t}->($f, $op, $md5); } else { warn "unknown inline/environment type: '$t'\n"; } } sub gvmake { local $/ = "\n"; my %opt = ( trim_mode => 0 , rankdir => 1); if (ref($_[0]) eq "HASH") { %opt = (%opt , %{shift(@_)}); } my ($makefile, $outfile) = @_; my $parser = Makefile::GraphViz->new; $parser->parse($makefile) or die $parser->error; my $gv = $parser->plot( ($opt{root} || $parser->target) , init_args => { rankdir => $opt{rankdir}, # width => undef, height => undef, }, trim_mode => $opt{trim_mode}, ); ## $gv->as_canon("$outfile-1.dot"); $gv->as_ps("$outfile-1.ps"); syst "ps2pdf -sPAPERSIZE=a2 $outfile-1.ps $outfile-1.pdf"; systopen("pdfcrop --xetex $outfile-1.pdf $outfile"); unlink "$outfile-1.pdf"; unlink "$outfile-1.ps"; } sub help { print <<"_EOC_"; Usage: $0 file.tex > processed_file.tex Options: ... _EOC_ exit 1; } sub check_tools_for { my $format = shift; if($format eq "makefileg"){ require Makefile::GraphViz } my %formats = ( html => [qw.htmldoc.], dot => [qw.dot pdfcrop neato twopi.], gnuplot => [qw.ps2pdf gnuplot.], makefileg => [qw.dot ps2pdf pdfcrop.], pod => [qw.pod2latex.], abcl => [qw.abcl abcm2ps epstopdf ps2pdf pdfcrop abc2midi.], abc => [qw.abcm2ps epstopdf ps2pdf pdfcrop abc2midi.], camila => [qw.cam2tex.], csv => [], ); my %tools = ( htmldoc => "http://www.easysw.com/htmldoc/", ps2pdf => "http://www.ghostscript.com/", pod2latex => "http://www.cpan.org/", dot => "http://www.graphviz.org/", twopi => "http://www.graphviz.org/", neato => "http://www.graphviz.org/", gnuplot => "http://www.gnuplot.info/", cam2tex => "http://natura.di.uminho.pt/download/sources/cam2tex", pdfcrop => "check texlive or other TeX distribution", abcm2ps => "http://abcplus.sourceforge.net/", abc2midi => "package abcMIDI", ); return 1 unless exists $formats{$format}; for my $tool (@{$formats{$format}}) { Config::AutoConf->check_prog($tool) or die "$tool is needed to use $format\nPlease install from $tools{$tool}"; } return 1; } __END__ =head1 NAME teximporter - a preprocessor to use HTML, GnuPlot, GraphViz and other tools directly from LaTeX =head1 SYNOPSIS teximporter [options] a.tex > b.tex teximporter -s a.tex > b.tex (ignore \_fmt{...} commands) =head1 DESCRIPTION C<teximporter> command was design to help in the task of include external file formats into \LaTeX{}. You can: =over 4 =item * Import a foreign file \import_fmt{file} =item * Using a foreign format \inline_fmt{extract of language fmt} or \_fmt{extract of language fmt} or \begin{import_fmt} extract of language fmt \end{import_fmt} =back Supported formats (fmt in the examples above) are: HTML POD (Perl documentation format) slides (PDF slides) camila (specification language ) gnuplot dot (graphViz) makefileg (import makefile as a graph) abcl (abcl music format) abc (abc music format) csv (csv table) For instance, you can import an HTML file with \import_html{file.html} or you can draw a Graphviz graph with \begin{import_dot} digraph "Makefile" { f -> o; o -> o; } \end{import_dot} =head1 Options -h help -s ignore \_fmt{...} notation -D keep temporary files to help debuging (not yet avail) -Q quiet mode -n don't proccess \input{file} -o=file.pdf =head1 Specific formats documentation Some commands support additional configuration options, that are described here. =head2 Import slides The C<import_slides> command supports the following options: nup=2x3 (def nup=1x2) pages={3,4,9-12} (def all pages) and also do pdfpages atributes: scale= (def "0.9") pagecommand= (def "") frame= (def "true") delta= (def "0.5cm 0.5cm") =head2 Import makefiles The C<import_makefileg> supports the following options: root=symbol scale=0.4 (def: 0.7) trim_mode=1 ignore makefile commands (def: 0) =head2 Import Abc music notation The C<import_abc> supports the following options: mp3 to generate attatched MP3 midi to generate attatched MIDI wav to generate attatched Wav incipit to generate incipit entry in the index incipit=nolyrics to generate incipit entry in the index noscore skip score t=120 (define quarter time for acustic music) a=0.90 to make notes more compact ( [0,1] see abcm2ps) + options form includegraphics ex: scale=0.6 =head2 Import POD documentation The C<import_pod> supports the following options: h1level=3 (def h1level=2) =head2 Import CSV fs=":" (default \t) head=1 to use first line as an header lhead=1 to use first column as an header (FIXME: not yet) -- to head a \hline =head2 Example Some command examples: \import_html{usos_corpora.html} \import_slides[nup=2x3]{/home/jj/docvs/escolaDeVerao/ta.pdf} \import_slides[pages={3,4,9-12}]{/home/jj/docvs/escolaDeVerao/ta.pdf} \import_pod[h1level=3]{teximporter} \begin{import_gnuplot} ... \end{import_gnuplot} \begin{import_makefileg} ... \end{import_makefileg} =head2 External Tools Requirements =over 4 =item * htmldoc -- to translate HTML to PDF =item * Makefile::GraphViz -- to import Makefiles; =item * pod2latex -- to import POD =item * pdfcrop -- to import Makefiles =item * ps2pdf -- to import Makefiles =item * graphViz -- to import Makefiles and Dot =item * gnuplot =back =head1 AUTHOR J.Joao Almeida, jj@di.uminho.pt Alberto Simoes, ambs@cpan.org =head1 SEE ALSO perl(1). LaTeX ABC, abcm2ps abc2midi ppdeflatex LaTeX::Importer sudo tlmgr install epstopdf =cut