summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/exceltex
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /macros/latex/contrib/exceltex
Initial commit
Diffstat (limited to 'macros/latex/contrib/exceltex')
-rw-r--r--macros/latex/contrib/exceltex/CHANGES15
-rw-r--r--macros/latex/contrib/exceltex/INSTALL10
-rw-r--r--macros/latex/contrib/exceltex/README164
-rw-r--r--macros/latex/contrib/exceltex/exceltex824
-rw-r--r--macros/latex/contrib/exceltex/exceltex.sty60
-rw-r--r--macros/latex/contrib/exceltex/manpage.pdfbin0 -> 7406 bytes
6 files changed, 1073 insertions, 0 deletions
diff --git a/macros/latex/contrib/exceltex/CHANGES b/macros/latex/contrib/exceltex/CHANGES
new file mode 100644
index 0000000000..489e347570
--- /dev/null
+++ b/macros/latex/contrib/exceltex/CHANGES
@@ -0,0 +1,15 @@
+* 0.5.1
+ - documentation updates
+ - minor bugfixes
+
+* 0.5.0
+ - new commandline interface
+ - support for global and project-specific configuration files
+ - support for some character encodings, currently supported are latin1,
+ latin9 and utf8
+ - experiemntal support for the EURO currency symbol
+ - fixed lots of bugs and surely introduced some new ones :)
+
+* 0.4.0
+ - simple formatting is supported now
+ - data is written to a separate directory
diff --git a/macros/latex/contrib/exceltex/INSTALL b/macros/latex/contrib/exceltex/INSTALL
new file mode 100644
index 0000000000..3b62f18106
--- /dev/null
+++ b/macros/latex/contrib/exceltex/INSTALL
@@ -0,0 +1,10 @@
+For installation just copy the exceltex helper script somewhere in your
+PATH for example $HOME/bin or /usr/local/bin, and make sure it is
+executable.
+
+The readimg.sty file should be copied somewhere LaTeX can find it, usually
+$HOME/texmf/tex/latex/misc or /usr/local/lib/texmf/tex/latex/misc. Dont
+forget to run 'texconfig rehash' afterwards.
+
+Thats it.
+
diff --git a/macros/latex/contrib/exceltex/README b/macros/latex/contrib/exceltex/README
new file mode 100644
index 0000000000..7b4ce95034
--- /dev/null
+++ b/macros/latex/contrib/exceltex/README
@@ -0,0 +1,164 @@
+ ABOUT
+
+Exceltex is a LaTeX package combined with a helper program written in
+Perl. It provides a easy to use yet powerfull and flexible way to get
+data from Spreadsheets into LaTeX.
+
+In difference to other existing solutions, exceltex does not seek for
+making the creation of tables in LaTeX easier, but to get data from
+Spreadsheets in into LaTeX as easy as possible.
+
+The excel fileformat acts as an interface between the spreadsheet
+application and exceltex beacause it is easily accessible via the
+Spreadsheet::ParseExcel Perl module and because most spreadsheet
+applications are able to read and write excel files.
+
+
+
+
+ REQIREMENTS
+
+Exceltex depends on the perl module Spreadsheet::ParseExcel and the
+LaTeX Packages ulem and color.
+
+Currently a Unix like operating system is required, cygwin on windows
+should work also.
+
+
+
+
+
+ LATEX COMMANDS
+
+Exceltex provides two commands to include single cells and cell-ranges
+for tabulars. Load the exceltex LaTeX package via
+\usepackage{exceltex}.
+
+ \inccell{foo.xls!results!B9}
+ includes cell B9 from sheet results in file foo.xls
+
+ \inctab{foo.xls!results!B2!C15}
+ includes the 14 rows between B2 and F15 from sheet results
+ in file foo.xls in LaTeX' tabular format ('&' separated rows
+ ended by \\)
+
+For both commands you may omit specifying the file (foo.xls) if it has
+the same basename (foo) as the LaTeX file (foo.tex).
+
+
+
+
+ USAGE
+
+Mark cells and tabulars for inclusion with the \incell and \inctab
+commands. Then run latex, exceltex and latex again.
+
+The following Example demonstrates the usage of exceltex:
+
+--- snip ---
+\documentclass{article}
+\usepackage[options]{exceltex}
+
+\begin{document}
+
+\title{a brief introduction to exceltex}
+\maketitle
+
+\section{including single cells}
+
+You can include contents of cells with the \\inccell command. Example:
+Cell A1 on sheet 'Sheet1' of file foo.xls is:
+\inccell{foo.xls!Sheet1!A1}
+
+
+\section{including tabulars}
+
+this is as easy as including single cells.
+
+\begin{tabular}{lll}
+ \hline
+ column 1 & colum 2 & colum 3 \\
+ \hline
+ \inctab{foo.xls!Sheet1!A1!C5}
+ \hline
+\end{tabular}
+
+\end{document}
+--- snap ---
+
+now, run latex, then exceltex and latex again.
+
+The \inctab command does nothing else than provide the requested cells
+in LaTeX' tabular format - colums are separated with a '&', each line
+is endet with a line break (\\). This gives you a maximum of
+flexibility and the freedom to use whatever tabular package you want.
+
+
+Currently one package option is supported.
+\usepackage[cellrefs]{exceltex} will write cell data to files named by
+filename, workbook and cell instead of sequentially numbered files.
+
+
+
+
+ PROBLEMS
+
+* Exceltex cannot read Excel files created by Spreadsheet::WriteExcel
+ (see Spreadsheet::ParseExcel documentatin for details).
+
+* Workbook names must not include problematic characters (LaTeX
+ control Characters) (^,_,$,%,&,!). Just use Letters, Numbers and a
+ Minus as spearator.
+
+* when using the cellrefs package option, whitespaces are also
+ forbidden in workbook names and filenames. These are LaTeX
+ limitations, i think.
+
+
+
+
+
+ HOW IT WORKS
+
+The first LaTeX run writes an entry for each \inctab, \inccell command
+to a spearate index file (\jobname.exltx). This index is then read by
+the exceltex helper script, which actually extracts the ordered data
+and writes it to sequentially numbered files in the directory
+\jobname-exltx. The \inctab and \inccell are then simply including
+these files via a \InputIfExists{} command on the following latex runs.
+
+
+
+
+ TODO
+
+Support for other formats than excels would be appreciating. There is
+maybe a chance to get OpenOffice Calc working. There is now a module
+OpenOffice::Parse::SXC on cpan which could to the job for Openoffice,
+but it seems quite new and is not includeded in Ubuntu yet. On the
+other hand, support for different fileformats would yield a naming
+problem, at the time i started with exceltex (in 2004) there was only
+Spreadsheet::ParseExcel, so the name exceltex ....
+
+
+The newest version of Exceltex is available at the following url:
+http://www.physik.uni-freiburg.de/~doerr/exceltex
+
+
+
+
+ COPYING
+
+exceltex is Copyright 2004-2006 by Hans-Peter Doerr
+<doerr@cip.physik.uni-freiburg.de>
+
+This is free software; see the source for copying conditions. There
+is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
+PARTICULAR PURPOSE.
+
+exceltex is distributed under the terms of the Gnu General Public
+License (GPL) Version 2. See COPYING for details.
+
+
+
+README for exceltex version 0.5.1, Apr 30, 2006
diff --git a/macros/latex/contrib/exceltex/exceltex b/macros/latex/contrib/exceltex/exceltex
new file mode 100644
index 0000000000..919a0918f6
--- /dev/null
+++ b/macros/latex/contrib/exceltex/exceltex
@@ -0,0 +1,824 @@
+#!/usr/bin/perl -w
+# $Id: exceltex 155 2006-04-30 11:25:16Z pez $
+#
+# helper script for the exceltex latex package. reads contents of
+# M$ Excel files using the Spreadsheet::ParseExcel perl module.
+#
+# (c) 2004-2006 by Hans-Peter Doerr <doerr@cip.physik.uni-freiburg.de>
+#
+# exceltex is free software. you can redistribute or modify it under
+# the terms of the GNU GENERAL PUBLIC LICENSE Version 2. See COPYING for
+# details.
+
+use strict;
+
+my $VERSION = "0.5.1";
+my $DEBUG = 0;
+
+# this is the default encoding for all files written by exceltex
+my $ENCODING = "latin1";
+
+# some lookup tables
+my %L2N;
+{ my $i = 1; for ('A' .. 'Z') { $L2N{$_} = $i; ++$i } }
+
+my @N2L;
+{ for ('A' .. 'Z') { push(@N2L, $_) } }
+
+
+#XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+#XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+package util;
+
+#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+sub DEBUG
+{
+ my ($msg) = @_;
+
+ if ($DEBUG)
+ {
+ chomp($msg);
+ print STDERR "DEBUG: $msg\n";
+ }
+}
+
+
+#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+sub cell2xy
+{
+ my ($cell) = @_;
+
+ $cell = uc($cell);
+ return undef if (! ($cell =~ m/^([A-Z]+)([0-9]+)$/));
+
+ # return (column, row)
+ return (col2x($1), $2-1);
+}
+
+
+#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+sub xy2cell
+{
+ my ($x, $y) = @_;
+
+ # is is likely to be slow as hell
+ return undef if (! ($x =~ m/^[0-9]+$/g && $y =~ m/^[0-9]+$/g));
+
+ ++$y;
+ return x2col($x) . "$y";
+}
+
+
+#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+sub col2x
+{
+ my ($l) = @_;
+
+ my $len = length($l);
+ my @S = split //, $l;
+
+ my $n = 0;
+
+ if ($len == 1) { $n = $L2N{$l} - 1 }
+ if ($len == 2) { $n = 26 * $L2N{$S[0]} + $L2N{$S[1]} - 1 }
+
+ return $n;
+}
+
+
+#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+sub x2col
+{
+ my ($n) = @_;
+
+ return undef if (! $n =~ m/[0-9]+/);
+ my $l;
+ if ($n > 25) { $l = $N2L[int($n/26)-1] . $N2L[$n % 26] }
+ else { $l = $N2L[$n] }
+
+ return $l;
+}
+
+
+
+
+
+#XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+#XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+package main;
+
+use strict;
+use Getopt::Long;
+use Encode;
+
+my $Workbooks = {}; # workbook cache
+my $nItems = 0; # number of processed items
+my $nCells = 0; # number of processed cells
+my $nTabs = 0; # number of processed tabs
+my $Warnings = 0; # number of warnings
+
+my $Jobname = ""; # jobname of .tex file
+my $inputDir = ""; # data goes here
+my $indexFile = "";
+
+
+my $optFormat = 1; # use formatting?
+my $optColor = 1; # use colors?
+my $optComma = 0; # use comma for decimals
+my $optFmtSci = 0; # reformat scientific numbers?
+my $ignWarn = 0; # ignore warnings?
+my $euroSymbol = "EUR"; # use this for the EUR currency symbol
+
+my $cleanup = 0; # cleanup inputDir
+
+my $EXTNS = "excltx";
+
+# read global and local config files
+# will be overwritten by commandline options
+readConfigFile("$ENV{HOME}/.exceltexrc") if (-f "$ENV{HOME}/.exceltexrc");
+readConfigFile(".exceltexrc") if (-f ".exceltexrc");
+
+# handle commandline switches
+GetOptions('format!' => \$optFormat,
+ 'color!' => \$optColor,
+ 'comma!' => \$optComma,
+ 'reformat-sn!' => \$optFmtSci,
+ 'p|plain' => sub{$optFormat=0; $optColor=0; $optFmtSci=0;},
+ 'd|debug' => \$DEBUG,
+ 'c|cleanup' => \$cleanup,
+ 'e|encoding=s' => \$ENCODING,
+ 'o|euro-symbol=s' => \$euroSymbol,
+ 'h|help' => sub{ usage(); exit 0;},
+ 'v|version' => sub{ print "exceltex, version $VERSION\n"; exit 0},
+ 'w|ignore-warnings' => \$ignWarn,
+ ) || exit 2;
+
+if (@ARGV == 0) {
+ usage();
+ exit 2;
+}
+
+
+
+# encoding of output files
+$ENCODING = lc($ENCODING);
+if (! ($ENCODING eq "latin1" ||
+ $ENCODING eq "iso-8859-1" ||
+ $ENCODING eq "latin9" ||
+ $ENCODING eq "iso-8859-15" ||
+ $ENCODING eq "utf8"))
+{
+ print STDERR "Unsupported encoding: $ENCODING\n";
+ print STDERR "currently supported: iso-8859-1 (latin1), iso-8859-15 "
+ . "(latin9), utf8\n";
+ exit_error();
+}
+
+print "exceltex helper script, version $VERSION\n";
+
+
+# get jobname from first argument
+if ($ARGV[0] =~ m/(\w+)\.tex/g) {
+ $Jobname = $1;
+}
+else { $Jobname = $ARGV[0]; }
+
+if (! defined($Jobname))
+{
+ print STDERR "can't determine jobname.\n";
+ exit_error();
+}
+
+util::DEBUG("jobname is: $Jobname\n");
+
+
+# data from spreadsheet goes here
+$inputDir = $Jobname . '-' . $EXTNS;
+$indexFile = $Jobname . '.' . $EXTNS;
+
+# cleanup?
+if ($cleanup)
+{
+ cleanup();
+ exit 0;
+}
+
+if (! -f $indexFile)
+{
+ print STDERR "can't read index '$indexFile: $!.\n";
+ print STDERR "run latex first to create the index.\n";
+ exit_error();
+}
+
+# create data dir
+if (! -d $inputDir)
+{
+ if (! mkdir $inputDir)
+ {
+ print STDERR "can't create data directory '$inputDir': $!\n";
+ exit_error();
+ }
+}
+
+
+# rock'n'roll
+processIndex($indexFile);
+
+
+# exiting message
+if ($Warnings)
+{
+ print STDERR "exceltex finished with $nItems items ($nCells cells "
+ . "and $nTabs tabulars)\n";
+ print STDERR "*** not all items proccessed fine, there were "
+ . "$Warnings Warnings\n";
+ exit 0 if ($ignWarn);
+ exit 1;
+}
+else
+{
+ print "exceltex successfully finished with $nItems items ($nCells cells "
+ . "and $nTabs tabulars)\n";
+}
+
+exit 0;
+
+
+
+#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+sub exit_error
+{
+ print STDERR "aborting.\n";
+ exit 2;
+}
+
+#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+sub usage
+{
+ print <<__EOF;
+exceltex version $VERSION
+usage: exceltex [options] file[.tex]
+options:
+ -h|--help show this help
+ -v|--version show program version and exit
+ -c|--cleanup remove temporary files created by previous runs
+ -w|--ignore-warnings exit with status zero, even on warnings
+ -o|--euro-symbol=sym use sym for displaying the euro currency symbol [EUR]
+ -e|--encoding=enc set encoding to enc. Currently supported
+ encodings are: latin1, latin9, utf8 [latin1]
+ --[no]reformat-sn (dont) reformat scientific numbers to A X 10^B notation
+ --[no]comma (dont) use comma for decimal numbers
+ --[no]format (dont) use formatting
+ --[no]nocolor (dont) use colors
+ -p|--plain shorthand for --noformat --nocolor --noreformat-sn
+__EOF
+}
+
+
+#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+sub readConfigFile
+{
+ my ($file) = @_;
+
+ open(I, "<$file") || return;
+ while(<I>)
+ {
+ chomp();
+ my ($key, $val) = split('=', $_);
+
+ if ($key eq "encoding") { $ENCODING = $val }
+ elsif ($key eq "reformat-sn") { $optFmtSci = $val }
+ elsif ($key eq "color") { $optColor = $val }
+ elsif ($key eq "format") { $optFormat = $val }
+ elsif ($key eq "comma") { $optComma = $val }
+ elsif ($key eq "euro-symbol") { $euroSymbol = $val }
+ elsif ($key eq "plain") { $optColor=0; $optFormat=0}
+ else { print STDERR "unsupported config option in '$file': "
+ . "$key, ignoring\n" }
+ }
+ close(I);
+}
+
+
+
+#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+sub cleanup
+{
+ if (-f $indexFile)
+ {
+ print "removing $indexFile\n";
+ unlink($indexFile);
+ }
+ return if (! defined($inputDir));
+ return if (! -d $inputDir);
+
+ print "cleaning up $inputDir/\n";
+ unlink <$inputDir/c-*>;
+ unlink <$inputDir/t-*>;
+}
+
+
+
+# read index file, extract data, write to files
+#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+sub processIndex
+{
+ my ($index) = @_;
+
+ if (! open(I, "< $index"))
+ {
+ print STDERR "can't read index '$index': $!. Run latex first?\n";
+ exit_error();
+ }
+
+ my $cellrefs = 0;
+ while(<I>)
+ {
+ chomp($_);
+
+ # if cellrefs is switched on, we store data in files with name
+ # inputDir/[c,t]-file!sheet!cell
+ if ($. == 1 && $_ eq ";cellrefs")
+ {
+ print "using cell referencing by name\n";
+ $cellrefs = 1;
+ }
+
+ # ignore lines beginning with ;
+ next if ($_ =~ m/^;/);
+
+ my $type;
+ my $idx = undef;
+ my $source;
+ my @flags;
+
+ if ($cellrefs == 1) {($type, $source, @flags) = split(':', $_)}
+ else {($type, $idx, $source, @flags) = split(':', $_)}
+
+ # parse flags
+ # not used yet
+ if (@flags != 0)
+ {
+ my $ok = 0;
+ foreach (@flags)
+ {
+ $ok = 1 if ($_ eq 'plain');
+ }
+ print STDERR "Index '$indexFile' corrupt at line $.: bad flag\n";
+ exit_error();
+ }
+
+ if (! defined($source))
+ {
+ print STDERR "Index '$indexFile' corrupt at line $.\n";
+ exit_error();
+ }
+
+ my ($f, $s, $c1, $c2) = parseSource($source, $type);
+ if (! $s)
+ {
+ print STDERR "Index '$indexFile' corrupt at line $.\n";
+ exit_error();
+ }
+
+ my $string = "";
+ if ($type eq 't')
+ {
+ $string = getTabString($f, $s, $c1, $c2);
+ }
+ elsif ($type eq 'c')
+ {
+ $string = getCellString($f, $s, $c1);
+ }
+ else
+ {
+ print STDERR "Index '$indexFile' corrupt at line $.: "
+ . "unknown $type '$type'\n";
+ exit_error();
+ }
+
+ # no need to write empty data
+ next if (! defined($string));
+
+ $string = decode_utf8($string, 0);
+ $string = encode($ENCODING, $string, 0);
+
+ if (! writeBuf($type, $idx, $string, $source))
+ {
+ print STDERR "can't write cell data: $!.\n";
+ exit_error();
+ }
+ }
+ close(I);
+
+ return 1;
+}
+
+
+#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+sub getFile
+{
+ my $file = $Jobname . ".xls";
+ return $file if (-f $file);
+ return undef;
+}
+
+#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+sub parseSource
+{
+ my ($string, $type) = @_;
+
+ my @tokens = split('!', $string);
+
+ my $file;
+ my $sheet;
+ my $cel1;
+ my $cel2;
+
+ if ($type eq 'c')
+ {
+ if (@tokens == 2)
+ {
+ $file = getFile();
+ $sheet = $tokens[0];
+ $cel1 = $tokens[1];
+ }
+ elsif (@tokens == 3)
+ {
+ $file = $tokens[0];
+ $sheet = $tokens[1];
+ $cel1 = $tokens[2];
+ }
+ else { return undef; }
+ }
+ elsif ($type eq 't')
+ {
+ if (@tokens == 3)
+ {
+ $file = getFile();
+ $sheet = $tokens[0];
+ $cel1 = $tokens[1];
+ $cel2 = $tokens[2];
+ }
+ elsif (@tokens == 4)
+ {
+ $file = $tokens[0];
+ $sheet = $tokens[1];
+ $cel1 = $tokens[2];
+ $cel2 = $tokens[3];
+ }
+ else { return undef; }
+ }
+ else { return (undef, undef, undef, undef); }
+
+ return ($file, $sheet, $cel1, $cel2);
+}
+
+
+#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+sub writeBuf
+{
+ my ($type, $idx, $string, $source) = @_;
+ return 1 if ($string eq "");
+
+ my $wfile;
+
+ if (! defined($idx)) { $wfile = $inputDir . "/" . $type . "-" . $source }
+ else { $wfile = $inputDir . "/" . $type . "-" . $idx }
+
+ return 0 if (! open (O, ">$wfile"));
+ return 0 if (! print O $string);
+ return 0 if (! close(O));
+ return 1;
+}
+
+
+#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+sub getWorkbook
+{
+ my ($file) = @_;
+
+ if (! -f $file) {
+ print STDERR "can't read '$file': it does not exists.\n";
+ exit_error();
+ }
+
+ if (! defined($Workbooks->{$file}))
+ {
+ my $type = "xls";
+ if ($file =~ m/^\w+\.(\w+)$/g) { $type = $1 };
+
+ if ($type eq "xls")
+ {
+ print("reading '$file'\n");
+ # readExcel->new() will exit, if anything bad happens
+ $Workbooks->{$file} = readExcel->new($file);
+ }
+ }
+
+ return $Workbooks->{$file};
+}
+
+
+#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+sub texifyCell
+{
+ my ($cel) = @_;
+
+ my $MATH = 0; # wether to enclose string in $$ for math mode
+ my $string = $cel->{value};
+
+ return "" if (! defined($string) || $string eq "");
+
+ # escape latex control characters
+ $string =~ s/\{/\\\{/g;
+ $string =~ s/\}/\\\}/g;
+ # escape backslash if not followed by { or }
+ $string =~ s/\\(?!({|}))/\\ensuremath\{\\backslash\}/g;
+ $string =~ s/#/\\#/g;
+ $string =~ s/\$/\\\$/g;
+ $string =~ s/%/\\%/g;
+ $string =~ s/&/\\&/g;
+ $string =~ s/~/\\~/g;
+ $string =~ s/_/\\_/g;
+ $string =~ s/\^/\{\\verb ^ \}/g;
+
+ # FIXME: needs more testing!
+ # hack for EUR sign, works for me but is definetly ugly :(
+ # will need some information on how exactly this
+ # user-entered formatting stuff works (in excel)
+ $string =~ s/\[.+\xac-{0,1}\d{1,3}\]/$euroSymbol/g; # EUR in currency cells
+ $string =~ s/\[.+EUR\]/$euroSymbol/g; # "
+ $string =~ s/.{1,1}\xac/$euroSymbol/g; # single EUR sign
+
+
+ # use decimal comma if requested
+ $string =~ s/(\d)\.(\d)/$1,$2/g if ($optComma == 1);
+
+ # reformat scientific numbers if requested
+ if ($optFmtSci == 1)
+ {
+ $MATH = 1 if ($string =~ s/([0-9]+)[eE]([+-][0-9]+)/
+ simplifyScientificNumber($1, $2)/ge);
+ }
+
+ # apply cell formatting and colors if not requested otherweise
+ $string = applyFormatting($string, $cel, $MATH) if($optFormat == 1);
+
+ # same goes for colors
+ $string = applyColor($string, $cel) if ($optColor == 1);
+
+ util::DEBUG " texified => '$string'";
+
+ return "\$$string\$" if ($MATH);
+ return $string;
+}
+
+
+#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+sub applyFormatting
+{
+ my ($s, $c, $m) = @_;
+
+ # font bold?
+ if ($c->{bold} && $m) { $s = "\\mathbf{$s}"; }
+ elsif ($c->{bold}) { $s = "\\textbf{$s}"; }
+
+ # font italic?
+ if ($c->{italic} && $m) { $s = "\\mathit{$s}"; }
+ elsif ($c->{italic}) { $s = "\\textit{$s}"; }
+
+ # underlined? striked out?
+ $s = "\\uline{$s}" if ($c->{underline});
+ $s = "\\sout{$s}" if ($c->{strikeout});
+
+ return $s;
+}
+
+
+#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+sub applyColor
+{
+ my ($s, $c) = @_;
+
+ # only evaluate color if it is not black anyway
+ if ($c->{color} != 8)
+ {
+ # convert rrggbb hex color triplet to float rgb
+ $s = "\\textcolor[rgb]{" . colormap($c->{color}) . "}{$s}";
+ }
+
+ return $s;
+}
+
+#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+sub colormap
+{
+ my ($color) = @_;
+
+ util::DEBUG(" color => $color\n");
+
+ # get rgb triplet as floats
+ return join(', ', map {hex($_)/255.0}
+ unpack('a2a2a2', Spreadsheet::ParseExcel->ColorIdxToRGB($color)));
+}
+
+
+
+#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+sub simplifyScientificNumber
+{
+ my ($f, $e) = @_;
+
+ # extract signum
+ my $s = substr($e, 0, 1);
+ $s = '' if ($s eq "+");
+
+ # remove signum & trailing zeros
+ $e =~ s/^[+-]*//;
+ $e =~ s/^0*(\d+)/$1/;
+
+ return $f if ($e == 0);
+ return sprintf("%s \\times 10^{%s%s}", $f, $s, $e);
+}
+
+
+#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+sub warning
+{
+ my ($msg) = @_;
+
+ chomp($msg);
+ print STDERR "warning: " . $msg . "\n";
+ ++$Warnings;
+}
+
+
+#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+sub getCellString
+{
+ my ($file, $sheet, $cell) = @_;
+
+ util::DEBUG("get $file -> $sheet -> $cell\n");
+
+ my $w = getWorkbook($file);
+ return undef if (! defined($w));
+
+ my ($x, $y) = util::cell2xy($cell);
+ if (! defined($x) || ! defined($y)) {
+ warning("cell '$cell' is invalid\n");
+ return undef;
+ }
+
+ my $c = $w->getCell($sheet, $x, $y);
+ warning($w->error()) if (! defined($c->{value}));
+
+ ++$nItems;
+ ++$nCells;
+ return texifyCell($c);
+}
+
+
+#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+sub getTabString
+{
+ my ($file, $sheet, $cell1, $cell2) = @_;
+
+ # cell1 is upper-left and cell2 is lower-right corner
+ # of the selected cell-range
+ my ($lfx, $upy) = util::cell2xy($cell1);
+ my ($rtx, $loy) = util::cell2xy($cell2);
+
+ if (! defined($lfx))
+ {
+ warning "cell '$cell1' is invalid\n";
+ return undef;
+ }
+ if (! defined($rtx))
+ {
+ warning "cell '$cell2' is invlaid\n";
+ return undef;
+ }
+
+ my $book = getWorkbook($file);
+ my $buf;
+
+ my $empty = 1;
+
+ for (my $y = $upy; $y <= $loy; ++$y)
+ {
+ for (my $x = $lfx; $x <= $rtx; ++$x)
+ {
+ my $c = $book->getCell($sheet, $x, $y);
+
+ warning($book->error()) if (! defined($c));
+ $empty = 0 if(defined($c->{value}));
+ $buf .= texifyCell($c);
+ $buf .= " & " if ($x < $rtx);
+ }
+ $buf .= " \\\\\n";
+ }
+
+ warning("table $cell1!$cell2 is empty\n") if ($empty);
+
+ ++$nItems;
+ ++$nTabs;
+ return $buf;
+}
+
+
+
+
+
+#XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+#XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+package readExcel;
+
+use strict;
+use Spreadsheet::ParseExcel;
+use Encode;
+
+#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+sub new
+{
+ my ($class, $file) = @_;
+
+ my $self = {};
+ $self->{ERROR} = "";
+
+ if (! -f $file)
+ {
+ print STDERR "can't read '$file', it does not exists.\n";
+ exit_error();
+ }
+
+ $self->{book} =
+ Spreadsheet::ParseExcel::Workbook->Parse($file);
+
+ if (! defined($self->{book}))
+ {
+ print STDERR "SpreadSheet::ParseExcel Error: "
+ . "can't parse '$file' : $!\n";
+ exit_error();
+ }
+
+ $self->{file} = $file;
+ bless $self, $class;
+
+ return $self;
+}
+
+
+#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+sub getCell
+{
+ my ($self, $sheet, $x, $y) = @_;
+
+ my $ws = $self->{book}->Worksheet($sheet);
+ if (! defined($ws))
+ {
+ $self->_setError("sheet '$sheet' does not exist");
+ return undef;
+ }
+
+ my $cell = $ws->Cell($y, $x);
+
+ if(! $cell)
+ {
+ $self->_setError("cell '$sheet!" . util::xy2cell($x, $y) . "' is emtpy "
+ . "or out of range");
+
+ return { value => undef }
+ }
+
+ # we're internally operating with utf8, for now
+ my $value = encode_utf8($cell->Value());
+ util::DEBUG " value => '$value'";
+
+ # return hash containing value and formatting
+ return { value => $value,
+ bold => $cell->{Format}->{Font}->{Bold},
+ italic => $cell->{Format}->{Font}->{Italic},
+ color => $cell->{Format}->{Font}->{Color},
+ underline => $cell->{Format}->{Font}->{Underline},
+ strikeout => $cell->{Format}->{Font}->{Strikeout}
+ };
+}
+
+
+#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+sub _setError
+{
+ my ($self, $err) = @_;
+ $self->{ERROR} = $err;
+}
+
+
+#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+sub error
+{
+ my $self = shift;
+ my $err = $self->{ERROR};
+ $self->{ERROR} = undef;
+ return $err;
+}
diff --git a/macros/latex/contrib/exceltex/exceltex.sty b/macros/latex/contrib/exceltex/exceltex.sty
new file mode 100644
index 0000000000..1b2dadeaac
--- /dev/null
+++ b/macros/latex/contrib/exceltex/exceltex.sty
@@ -0,0 +1,60 @@
+% $Id: exceltex.sty 155 2006-04-30 11:25:16Z pez $
+%
+% get data from excel files into LaTeX
+%
+% (c) 2004-2006 by Hans-Peter Doerr <doerr@cip.physik.uni-freiburg.de>
+%
+% exceltex is free software. you can redistribute or modify it under
+% the terms of the GNU GENERAL PUBLIC LICENSE Version 2. See COPYING for
+% details.
+%
+\def\exceltexVersion{0.5.1}
+%
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{exceltex}[2006/04/30 v.\exceltexVersion]
+\DeclareOption{cellrefs}{\def\cellrefs{1}}
+\ProcessOptions
+%
+\typeout{This is exceltex v\exceltexVersion}
+% ulem needs option normalem for not breaking \em and \emph
+\RequirePackage[normalem]{ulem}
+\RequirePackage{color}
+%\RequirePackage{eurosym}
+%
+\newcounter{exceltexCounterC}\setcounter{exceltexCounterC}{0}
+\newcounter{exceltexCounterT}\setcounter{exceltexCounterT}{0}
+%
+\immediate\openout 10=\jobname.excltx
+%
+%
+% write index header
+\ifx\cellrefs\undefined
+%
+\else
+\immediate\write 10{;cellrefs}
+\fi
+\immediate\write 10{;created by exceltex v. \exceltexVersion}
+%
+\newcommand{\inccell}[1]{%
+ \stepcounter{exceltexCounterC}%
+ \ifx\cellrefs\undefined%
+ \immediate\write 10{c:\theexceltexCounterC:#1}%
+ \InputIfFileExists{\jobname-excltx/c-\theexceltexCounterC}{}{}%
+ \else
+ \immediate\write 10{c:#1}%
+ \InputIfFileExists{\jobname-excltx/c-#1}{}{}%
+ \fi
+}%
+%
+%
+\newcommand{\inctab}[1]{%
+ \stepcounter{exceltexCounterT}%
+ \ifx\cellrefs\undefined%
+ \immediate\write 10{t:\theexceltexCounterT:#1}%
+ \InputIfFileExists{\jobname-excltx/t-\theexceltexCounterT}{}{\\}%
+ \else
+ \immediate\write 10{t:#1}%
+ \InputIfFileExists{\jobname-excltx/t-#1}{}{\\}%
+ \fi
+}%
+\endinput
diff --git a/macros/latex/contrib/exceltex/manpage.pdf b/macros/latex/contrib/exceltex/manpage.pdf
new file mode 100644
index 0000000000..a58df1a4d5
--- /dev/null
+++ b/macros/latex/contrib/exceltex/manpage.pdf
Binary files differ