From ecfa68b833c60a169220cae2b89dbc9d1e4067ad Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Fri, 30 Mar 2012 22:52:33 +0000 Subject: restore exceltex.sty, ooo can write the files it reads, so good git-svn-id: svn://tug.org/texlive/trunk@25787 c570f23f-e606-0410-a88d-b1316a301751 --- Master/texmf-dist/doc/latex/exceltex/CHANGES | 15 + Master/texmf-dist/doc/latex/exceltex/INSTALL | 10 + Master/texmf-dist/doc/latex/exceltex/README | 164 ++++ .../texmf-dist/doc/latex/exceltex/README.TEXLIVE | 7 + Master/texmf-dist/doc/latex/exceltex/exceltex | 824 +++++++++++++++++++++ 5 files changed, 1020 insertions(+) create mode 100644 Master/texmf-dist/doc/latex/exceltex/CHANGES create mode 100644 Master/texmf-dist/doc/latex/exceltex/INSTALL create mode 100644 Master/texmf-dist/doc/latex/exceltex/README create mode 100644 Master/texmf-dist/doc/latex/exceltex/README.TEXLIVE create mode 100644 Master/texmf-dist/doc/latex/exceltex/exceltex (limited to 'Master/texmf-dist/doc/latex/exceltex') diff --git a/Master/texmf-dist/doc/latex/exceltex/CHANGES b/Master/texmf-dist/doc/latex/exceltex/CHANGES new file mode 100644 index 00000000000..489e3475706 --- /dev/null +++ b/Master/texmf-dist/doc/latex/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/Master/texmf-dist/doc/latex/exceltex/INSTALL b/Master/texmf-dist/doc/latex/exceltex/INSTALL new file mode 100644 index 00000000000..3b62f181066 --- /dev/null +++ b/Master/texmf-dist/doc/latex/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/Master/texmf-dist/doc/latex/exceltex/README b/Master/texmf-dist/doc/latex/exceltex/README new file mode 100644 index 00000000000..7b4ce950340 --- /dev/null +++ b/Master/texmf-dist/doc/latex/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 + + +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/Master/texmf-dist/doc/latex/exceltex/README.TEXLIVE b/Master/texmf-dist/doc/latex/exceltex/README.TEXLIVE new file mode 100644 index 00000000000..aef54a7532e --- /dev/null +++ b/Master/texmf-dist/doc/latex/exceltex/README.TEXLIVE @@ -0,0 +1,7 @@ +The following files have been removed in the TeX Live installation of +the current package, typically due to duplication, lack of space, or +missing source code. You can find these files on CTAN at + http://mirror.ctan.org/macros/latex/contrib/exceltex +If questions or concerns, email tex-live@tug.org. + + manpage.pdf diff --git a/Master/texmf-dist/doc/latex/exceltex/exceltex b/Master/texmf-dist/doc/latex/exceltex/exceltex new file mode 100644 index 00000000000..919a0918f65 --- /dev/null +++ b/Master/texmf-dist/doc/latex/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 +# +# 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() + { + 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() + { + 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; +} -- cgit v1.2.3