~ubuntu-branches/ubuntu/utopic/texlive-bin/utopic

« back to all changes in this revision

Viewing changes to texk/texlive/linked_scripts/exceltex/exceltex

  • Committer: Package Import Robot
  • Author(s): Norbert Preining
  • Date: 2012-04-10 10:16:01 UTC
  • mfrom: (1.2.3)
  • Revision ID: package-import@ubuntu.com-20120410101601-7mt8nyn280xrgza6
Tags: 2011.20120410-1
* new upstream checkout:
  - remove decls of popen and pclose (Closes: #64524) (!yow, 5 digit bug!)
  - do not declare getopt in C++, fixes FTBFS with g++ >= 4.7 
    (Closes: #667392)
* add patches (maybe to be included upstream) that allows inclusion of
  one config file in another for (x)dvipdfmx. This will be
  used by the paper code.
* fix description of libptexenc-dev package (Closes: #667694)
* remove xdvik patch, included upstream
* remove conflict with ptex-bin, we are building a transitional package now
* build with internal t1lib, as t1lib is going to disappear in
  wheezy (Closes: #667912) (no, dropping xdvi is not an option!)
  (add a lintian override otherwise this gives a lintian error)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/perl -w
 
2
# $Id: exceltex 155 2006-04-30 11:25:16Z pez $
 
3
#
 
4
# helper script for the exceltex latex package. reads contents of
 
5
# M$ Excel files using the Spreadsheet::ParseExcel perl module.
 
6
#
 
7
# (c) 2004-2006 by Hans-Peter Doerr <doerr@cip.physik.uni-freiburg.de>
 
8
#
 
9
# exceltex is free software. you can redistribute or modify it under
 
10
# the terms of the GNU GENERAL PUBLIC LICENSE Version 2. See COPYING for
 
11
# details.
 
12
 
 
13
use strict;
 
14
 
 
15
my $VERSION = "0.5.1";
 
16
my $DEBUG   = 0;
 
17
 
 
18
# this is the default encoding for all files written by exceltex
 
19
my $ENCODING = "latin1";
 
20
 
 
21
# some lookup tables
 
22
my %L2N;
 
23
{ my $i = 1; for ('A' .. 'Z') { $L2N{$_} = $i; ++$i } }
 
24
 
 
25
my @N2L;
 
26
{ for ('A' .. 'Z') { push(@N2L, $_) } }
 
27
 
 
28
 
 
29
#XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
 
30
#XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
 
31
package util;
 
32
 
 
33
#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 
34
sub DEBUG
 
35
{
 
36
    my ($msg) = @_;
 
37
 
 
38
    if ($DEBUG)
 
39
    {
 
40
        chomp($msg);
 
41
        print STDERR "DEBUG: $msg\n";
 
42
    }
 
43
}
 
44
 
 
45
 
 
46
#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 
47
sub cell2xy
 
48
{
 
49
    my ($cell) = @_;
 
50
 
 
51
    $cell = uc($cell);
 
52
    return undef if (! ($cell =~ m/^([A-Z]+)([0-9]+)$/));
 
53
 
 
54
    # return (column, row)
 
55
    return (col2x($1), $2-1);
 
56
}
 
57
 
 
58
 
 
59
#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 
60
sub xy2cell
 
61
{
 
62
    my ($x, $y) = @_;
 
63
 
 
64
    # is is likely to be slow as hell
 
65
    return undef if (! ($x =~ m/^[0-9]+$/g && $y =~ m/^[0-9]+$/g));
 
66
 
 
67
    ++$y;
 
68
    return x2col($x) .  "$y";
 
69
}
 
70
 
 
71
 
 
72
#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 
73
sub col2x
 
74
{
 
75
  my ($l) = @_;
 
76
 
 
77
    my $len = length($l);
 
78
    my @S   = split //, $l;
 
79
 
 
80
    my $n = 0;
 
81
 
 
82
    if ($len == 1) { $n =  $L2N{$l} - 1 }
 
83
    if ($len == 2) { $n =  26 * $L2N{$S[0]} + $L2N{$S[1]} - 1 }
 
84
 
 
85
    return $n;
 
86
}
 
87
 
 
88
 
 
89
#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 
90
sub x2col
 
91
{
 
92
    my ($n) = @_;
 
93
 
 
94
    return undef if (! $n =~ m/[0-9]+/);
 
95
    my $l;
 
96
    if ($n > 25) { $l =  $N2L[int($n/26)-1] . $N2L[$n % 26] }
 
97
    else { $l =  $N2L[$n] }
 
98
 
 
99
    return $l;
 
100
}
 
101
 
 
102
 
 
103
 
 
104
 
 
105
 
 
106
#XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
 
107
#XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
 
108
package main;
 
109
 
 
110
use strict;
 
111
use Getopt::Long;
 
112
use Encode;
 
113
 
 
114
my $Workbooks = {};     # workbook cache
 
115
my $nItems    = 0;      # number of processed items
 
116
my $nCells    = 0;      # number of processed cells
 
117
my $nTabs     = 0;      # number of processed tabs
 
118
my $Warnings  = 0;      # number of warnings
 
119
 
 
120
my $Jobname    = "";    # jobname of .tex file
 
121
my $inputDir   = "";    # data goes here
 
122
my $indexFile  = "";
 
123
 
 
124
 
 
125
my $optFormat = 1;  # use formatting?
 
126
my $optColor  = 1;  # use colors?
 
127
my $optComma  = 0;  # use comma for decimals
 
128
my $optFmtSci = 0;  # reformat scientific numbers?
 
129
my $ignWarn   = 0;  # ignore warnings?
 
130
my $euroSymbol  = "EUR"; # use this for the EUR currency symbol
 
131
 
 
132
my $cleanup   = 0;      # cleanup inputDir
 
133
 
 
134
my $EXTNS = "excltx";
 
135
 
 
136
# read global and local config files
 
137
# will be overwritten by commandline options
 
138
readConfigFile("$ENV{HOME}/.exceltexrc") if (-f "$ENV{HOME}/.exceltexrc");
 
139
readConfigFile(".exceltexrc") if (-f ".exceltexrc");
 
140
 
 
141
# handle commandline switches
 
142
GetOptions('format!'       => \$optFormat,
 
143
           'color!'        => \$optColor,
 
144
           'comma!'        => \$optComma,
 
145
           'reformat-sn!'  => \$optFmtSci,
 
146
           'p|plain'       => sub{$optFormat=0; $optColor=0; $optFmtSci=0;},
 
147
           'd|debug'       => \$DEBUG,
 
148
           'c|cleanup'     => \$cleanup,
 
149
           'e|encoding=s'  => \$ENCODING,
 
150
           'o|euro-symbol=s' => \$euroSymbol,
 
151
           'h|help'        => sub{ usage(); exit 0;},
 
152
           'v|version'     => sub{ print "exceltex, version $VERSION\n"; exit 0},
 
153
           'w|ignore-warnings' => \$ignWarn,
 
154
           ) || exit 2;
 
155
 
 
156
if (@ARGV == 0) {
 
157
    usage();
 
158
    exit 2;
 
159
}
 
160
 
 
161
 
 
162
 
 
163
# encoding of output files
 
164
$ENCODING = lc($ENCODING);
 
165
if (! ($ENCODING eq "latin1"      ||
 
166
       $ENCODING eq "iso-8859-1"  ||
 
167
       $ENCODING eq "latin9"      ||
 
168
       $ENCODING eq "iso-8859-15" ||
 
169
       $ENCODING eq "utf8"))
 
170
{
 
171
    print STDERR "Unsupported encoding: $ENCODING\n";
 
172
    print STDERR "currently supported: iso-8859-1 (latin1), iso-8859-15 "
 
173
        . "(latin9), utf8\n";
 
174
    exit_error();
 
175
}
 
176
 
 
177
print "exceltex helper script, version $VERSION\n";
 
178
 
 
179
 
 
180
# get jobname from first argument
 
181
if ($ARGV[0] =~ m/(\w+)\.tex/g) {
 
182
    $Jobname = $1;
 
183
}
 
184
else { $Jobname = $ARGV[0]; }
 
185
 
 
186
if (! defined($Jobname))
 
187
{
 
188
    print STDERR "can't determine jobname.\n";
 
189
    exit_error();
 
190
}
 
191
 
 
192
util::DEBUG("jobname is: $Jobname\n");
 
193
 
 
194
 
 
195
# data from spreadsheet goes here
 
196
$inputDir  = $Jobname . '-' . $EXTNS;
 
197
$indexFile = $Jobname . '.' . $EXTNS;
 
198
 
 
199
# cleanup?
 
200
if ($cleanup)
 
201
{
 
202
    cleanup();
 
203
    exit 0;
 
204
}
 
205
 
 
206
if (! -f $indexFile)
 
207
{
 
208
    print STDERR "can't read index '$indexFile: $!.\n";
 
209
    print STDERR "run latex first to create the index.\n";
 
210
    exit_error();
 
211
}
 
212
 
 
213
# create data dir
 
214
if (! -d $inputDir)
 
215
{
 
216
    if (! mkdir $inputDir)
 
217
    {
 
218
        print STDERR "can't create data directory '$inputDir': $!\n";
 
219
        exit_error();
 
220
    }
 
221
}
 
222
 
 
223
 
 
224
# rock'n'roll
 
225
processIndex($indexFile);
 
226
 
 
227
 
 
228
# exiting message
 
229
if ($Warnings)
 
230
{
 
231
    print STDERR "exceltex finished with $nItems items ($nCells cells "
 
232
        . "and $nTabs tabulars)\n";
 
233
    print STDERR "*** not all items proccessed fine, there were "
 
234
        . "$Warnings Warnings\n";
 
235
    exit 0 if ($ignWarn);
 
236
    exit 1;
 
237
}
 
238
else
 
239
{
 
240
    print "exceltex successfully finished with $nItems items ($nCells cells "
 
241
        . "and $nTabs tabulars)\n";
 
242
}
 
243
 
 
244
exit 0;
 
245
 
 
246
 
 
247
 
 
248
#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 
249
sub exit_error
 
250
{
 
251
    print STDERR "aborting.\n";
 
252
    exit 2;
 
253
}
 
254
 
 
255
#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 
256
sub usage
 
257
{
 
258
  print <<__EOF;
 
259
exceltex version $VERSION
 
260
usage: exceltex [options] file[.tex]
 
261
options:
 
262
   -h|--help             show this help
 
263
   -v|--version          show program version and exit
 
264
   -c|--cleanup          remove temporary files created by previous runs
 
265
   -w|--ignore-warnings  exit with status zero, even on warnings
 
266
   -o|--euro-symbol=sym  use sym for displaying the euro currency symbol [EUR]
 
267
   -e|--encoding=enc     set encoding to enc. Currently supported
 
268
                         encodings are: latin1, latin9, utf8 [latin1]
 
269
   --[no]reformat-sn     (dont) reformat scientific numbers to A X 10^B notation
 
270
   --[no]comma           (dont) use comma for decimal numbers
 
271
   --[no]format          (dont) use formatting
 
272
   --[no]nocolor         (dont) use colors
 
273
   -p|--plain            shorthand for --noformat --nocolor --noreformat-sn
 
274
__EOF
 
275
}
 
276
 
 
277
 
 
278
#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 
279
sub readConfigFile
 
280
{
 
281
    my ($file) = @_;
 
282
 
 
283
    open(I, "<$file") || return;
 
284
    while(<I>)
 
285
    {
 
286
        chomp();
 
287
        my ($key, $val) = split('=', $_);
 
288
 
 
289
        if ($key eq "encoding")        { $ENCODING  = $val }
 
290
        elsif ($key eq "reformat-sn")  { $optFmtSci = $val }
 
291
        elsif ($key eq "color")        { $optColor  = $val }
 
292
        elsif ($key eq "format")       { $optFormat = $val }
 
293
        elsif ($key eq "comma")        { $optComma  = $val }
 
294
        elsif ($key eq "euro-symbol")  { $euroSymbol = $val }
 
295
        elsif ($key eq "plain")        { $optColor=0; $optFormat=0}
 
296
        else  { print STDERR "unsupported config option in '$file': "
 
297
                    . "$key, ignoring\n"  }
 
298
    }
 
299
    close(I);
 
300
}
 
301
 
 
302
 
 
303
 
 
304
#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 
305
sub cleanup
 
306
{
 
307
    if (-f $indexFile)
 
308
    {
 
309
        print "removing $indexFile\n";
 
310
        unlink($indexFile);
 
311
    }
 
312
    return if (! defined($inputDir));
 
313
    return if (! -d $inputDir);
 
314
 
 
315
    print "cleaning up $inputDir/\n";
 
316
    unlink <$inputDir/c-*>;
 
317
    unlink <$inputDir/t-*>;
 
318
}
 
319
 
 
320
 
 
321
 
 
322
# read index file, extract data, write to files
 
323
#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 
324
sub processIndex
 
325
{
 
326
    my ($index) = @_;
 
327
 
 
328
    if (! open(I, "< $index"))
 
329
    {
 
330
        print STDERR "can't read index '$index': $!. Run latex first?\n";
 
331
        exit_error();
 
332
    }
 
333
 
 
334
    my $cellrefs = 0;
 
335
    while(<I>)
 
336
    {
 
337
        chomp($_);
 
338
 
 
339
        # if cellrefs is switched on, we store data in files with name
 
340
        # inputDir/[c,t]-file!sheet!cell
 
341
        if ($. == 1 && $_ eq ";cellrefs")
 
342
        {
 
343
            print "using cell referencing by name\n";
 
344
            $cellrefs = 1;
 
345
        }
 
346
 
 
347
        # ignore lines beginning with ;
 
348
        next if ($_ =~ m/^;/);
 
349
 
 
350
        my $type;
 
351
        my $idx = undef;
 
352
        my $source;
 
353
        my @flags;
 
354
 
 
355
        if ($cellrefs == 1) {($type, $source, @flags)       = split(':', $_)}
 
356
        else                {($type, $idx, $source, @flags) = split(':', $_)}
 
357
 
 
358
        # parse flags
 
359
        # not used yet
 
360
        if (@flags != 0)
 
361
        {
 
362
            my $ok  = 0;
 
363
            foreach (@flags)
 
364
            {
 
365
                $ok = 1 if ($_ eq 'plain');
 
366
            }
 
367
            print STDERR "Index '$indexFile' corrupt at line $.: bad flag\n";
 
368
            exit_error();
 
369
        }
 
370
 
 
371
        if (! defined($source))
 
372
        {
 
373
            print STDERR "Index '$indexFile' corrupt at line $.\n";
 
374
            exit_error();
 
375
        }
 
376
 
 
377
        my ($f, $s, $c1, $c2) = parseSource($source, $type);
 
378
        if (! $s)
 
379
        {
 
380
            print STDERR "Index '$indexFile' corrupt at line $.\n";
 
381
            exit_error();
 
382
        }
 
383
 
 
384
        my $string = "";
 
385
        if ($type eq 't')
 
386
        {
 
387
            $string = getTabString($f, $s, $c1, $c2);
 
388
        }
 
389
        elsif ($type eq 'c')
 
390
        {
 
391
            $string = getCellString($f, $s, $c1);
 
392
        }
 
393
        else
 
394
        {
 
395
            print STDERR "Index '$indexFile' corrupt at line $.: "
 
396
                . "unknown $type '$type'\n";
 
397
            exit_error();
 
398
        }
 
399
 
 
400
        # no need to write empty data
 
401
        next if (! defined($string));
 
402
 
 
403
        $string = decode_utf8($string, 0);
 
404
        $string = encode($ENCODING, $string, 0);
 
405
 
 
406
        if (! writeBuf($type, $idx, $string, $source))
 
407
        {
 
408
            print STDERR "can't write cell data: $!.\n";
 
409
            exit_error();
 
410
        }
 
411
    }
 
412
    close(I);
 
413
 
 
414
    return 1;
 
415
}
 
416
 
 
417
 
 
418
#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 
419
sub getFile
 
420
{
 
421
    my $file = $Jobname . ".xls";
 
422
    return $file if (-f $file);
 
423
    return undef;
 
424
}
 
425
 
 
426
#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 
427
sub parseSource
 
428
{
 
429
    my ($string, $type) = @_;
 
430
 
 
431
    my @tokens = split('!', $string);
 
432
 
 
433
    my $file;
 
434
    my $sheet;
 
435
    my $cel1;
 
436
    my $cel2;
 
437
 
 
438
    if ($type eq 'c')
 
439
    {
 
440
        if (@tokens == 2)
 
441
        {
 
442
            $file   = getFile();
 
443
            $sheet  = $tokens[0];
 
444
            $cel1   = $tokens[1];
 
445
        }
 
446
        elsif (@tokens == 3)
 
447
        {
 
448
            $file   = $tokens[0];
 
449
            $sheet  = $tokens[1];
 
450
            $cel1   = $tokens[2];
 
451
        }
 
452
        else { return  undef; }
 
453
    }
 
454
    elsif ($type eq 't')
 
455
    {
 
456
        if (@tokens == 3)
 
457
        {
 
458
            $file  = getFile();
 
459
            $sheet = $tokens[0];
 
460
            $cel1  = $tokens[1];
 
461
            $cel2  = $tokens[2];
 
462
        }
 
463
        elsif (@tokens == 4)
 
464
        {
 
465
            $file  = $tokens[0];
 
466
            $sheet = $tokens[1];
 
467
            $cel1  = $tokens[2];
 
468
            $cel2  = $tokens[3];
 
469
        }
 
470
        else { return undef; }
 
471
    }
 
472
    else { return (undef, undef, undef, undef); }
 
473
 
 
474
    return ($file, $sheet, $cel1, $cel2);
 
475
}
 
476
 
 
477
 
 
478
#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 
479
sub writeBuf
 
480
{
 
481
    my ($type, $idx, $string, $source) = @_;
 
482
    return 1 if ($string eq "");
 
483
 
 
484
    my $wfile;
 
485
 
 
486
    if (! defined($idx)) { $wfile = $inputDir . "/" . $type . "-" . $source }
 
487
    else                 { $wfile = $inputDir . "/" . $type . "-" . $idx    }
 
488
 
 
489
    return 0 if (! open (O, ">$wfile"));
 
490
    return 0 if (! print O $string);
 
491
    return 0 if (! close(O));
 
492
    return 1;
 
493
}
 
494
 
 
495
 
 
496
#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 
497
sub getWorkbook
 
498
{
 
499
    my ($file) = @_;
 
500
 
 
501
    if (! -f $file) {
 
502
        print STDERR "can't read '$file': it does not exists.\n";
 
503
        exit_error();
 
504
    }
 
505
 
 
506
    if (! defined($Workbooks->{$file}))
 
507
    {
 
508
        my $type = "xls";
 
509
        if ($file =~ m/^\w+\.(\w+)$/g) { $type = $1 };
 
510
 
 
511
        if ($type eq "xls")
 
512
        {
 
513
            print("reading '$file'\n");
 
514
            # readExcel->new() will exit, if anything bad happens
 
515
            $Workbooks->{$file} = readExcel->new($file);
 
516
        }
 
517
    }
 
518
 
 
519
    return $Workbooks->{$file};
 
520
}
 
521
 
 
522
 
 
523
#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 
524
sub texifyCell
 
525
{
 
526
    my ($cel) = @_;
 
527
 
 
528
    my $MATH   = 0; # wether to enclose string in $$ for math mode
 
529
    my $string = $cel->{value};
 
530
 
 
531
    return "" if (! defined($string) || $string eq "");
 
532
 
 
533
    # escape latex control characters
 
534
    $string =~ s/\{/\\\{/g;
 
535
    $string =~ s/\}/\\\}/g;
 
536
    # escape backslash if not followed by { or }
 
537
    $string =~ s/\\(?!({|}))/\\ensuremath\{\\backslash\}/g;
 
538
    $string =~ s/#/\\#/g;
 
539
    $string =~ s/\$/\\\$/g;
 
540
    $string =~ s/%/\\%/g;
 
541
    $string =~ s/&/\\&/g;
 
542
    $string =~ s/~/\\~/g;
 
543
    $string =~ s/_/\\_/g;
 
544
    $string =~ s/\^/\{\\verb ^ \}/g;
 
545
 
 
546
    # FIXME: needs more testing!
 
547
    # hack for EUR sign, works for me but is definetly ugly :(
 
548
    # will need some information on how exactly this
 
549
    # user-entered formatting stuff works (in excel)
 
550
    $string =~ s/\[.+\xac-{0,1}\d{1,3}\]/$euroSymbol/g;  # EUR in currency cells
 
551
    $string =~ s/\[.+EUR\]/$euroSymbol/g;                # "
 
552
    $string =~ s/.{1,1}\xac/$euroSymbol/g;               # single EUR sign
 
553
   
 
554
 
 
555
    # use decimal comma if requested
 
556
    $string =~ s/(\d)\.(\d)/$1,$2/g if ($optComma == 1);
 
557
    
 
558
    # reformat scientific numbers if requested
 
559
    if ($optFmtSci == 1)
 
560
    {
 
561
        $MATH =  1 if ($string =~ s/([0-9]+)[eE]([+-][0-9]+)/
 
562
                       simplifyScientificNumber($1, $2)/ge);
 
563
    }
 
564
 
 
565
    # apply cell formatting and colors if not requested otherweise
 
566
    $string = applyFormatting($string, $cel, $MATH) if($optFormat == 1);
 
567
 
 
568
    # same goes for colors
 
569
    $string = applyColor($string, $cel) if ($optColor == 1);
 
570
 
 
571
    util::DEBUG "  texified => '$string'";
 
572
 
 
573
    return "\$$string\$" if ($MATH);
 
574
    return $string;
 
575
}
 
576
 
 
577
 
 
578
#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 
579
sub applyFormatting
 
580
{
 
581
    my ($s, $c, $m) = @_;
 
582
 
 
583
    # font bold?
 
584
    if    ($c->{bold} && $m) { $s = "\\mathbf{$s}"; }
 
585
    elsif ($c->{bold})       { $s = "\\textbf{$s}"; }
 
586
 
 
587
    # font italic?
 
588
    if    ($c->{italic} && $m) { $s = "\\mathit{$s}"; }
 
589
    elsif ($c->{italic})       { $s = "\\textit{$s}"; }
 
590
 
 
591
    # underlined? striked out?
 
592
    $s = "\\uline{$s}" if ($c->{underline});
 
593
    $s = "\\sout{$s}"  if ($c->{strikeout});
 
594
 
 
595
    return $s;
 
596
}
 
597
 
 
598
 
 
599
#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 
600
sub applyColor
 
601
{
 
602
    my ($s, $c) = @_;
 
603
 
 
604
    # only evaluate color if it is not black anyway
 
605
    if ($c->{color} != 8)
 
606
    {
 
607
        # convert rrggbb hex color triplet to float rgb
 
608
        $s = "\\textcolor[rgb]{" . colormap($c->{color}) . "}{$s}";
 
609
    }
 
610
 
 
611
    return $s;
 
612
}
 
613
 
 
614
#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 
615
sub colormap
 
616
{
 
617
    my ($color) = @_;
 
618
 
 
619
    util::DEBUG("  color => $color\n");
 
620
 
 
621
    # get rgb triplet as floats
 
622
    return join(', ', map {hex($_)/255.0}
 
623
            unpack('a2a2a2', Spreadsheet::ParseExcel->ColorIdxToRGB($color)));
 
624
}
 
625
 
 
626
 
 
627
 
 
628
#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 
629
sub simplifyScientificNumber
 
630
{
 
631
    my ($f, $e) = @_;
 
632
 
 
633
    # extract signum
 
634
    my $s = substr($e, 0, 1);
 
635
    $s = '' if ($s eq "+");
 
636
 
 
637
    # remove signum & trailing zeros
 
638
    $e =~ s/^[+-]*//;
 
639
    $e =~ s/^0*(\d+)/$1/;
 
640
 
 
641
    return $f if ($e == 0);
 
642
    return sprintf("%s \\times 10^{%s%s}", $f, $s, $e);
 
643
}
 
644
 
 
645
 
 
646
#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 
647
sub warning
 
648
{
 
649
    my ($msg) = @_;
 
650
 
 
651
    chomp($msg);
 
652
    print STDERR "warning: "  . $msg . "\n";
 
653
    ++$Warnings;
 
654
}
 
655
 
 
656
 
 
657
#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 
658
sub getCellString
 
659
{
 
660
    my ($file, $sheet, $cell) = @_;
 
661
 
 
662
    util::DEBUG("get $file -> $sheet -> $cell\n");
 
663
 
 
664
    my $w = getWorkbook($file);
 
665
    return undef if (! defined($w));
 
666
 
 
667
    my ($x, $y) = util::cell2xy($cell);
 
668
    if (! defined($x) || ! defined($y)) {
 
669
        warning("cell '$cell' is invalid\n");
 
670
        return undef;
 
671
    }
 
672
 
 
673
    my $c = $w->getCell($sheet, $x, $y);
 
674
    warning($w->error()) if (! defined($c->{value}));
 
675
 
 
676
    ++$nItems;
 
677
    ++$nCells;
 
678
    return texifyCell($c);
 
679
}
 
680
 
 
681
 
 
682
#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 
683
sub getTabString
 
684
{
 
685
    my ($file, $sheet, $cell1, $cell2) = @_;
 
686
 
 
687
    # cell1 is upper-left and cell2 is lower-right corner
 
688
    # of the selected cell-range
 
689
    my ($lfx, $upy) = util::cell2xy($cell1);
 
690
    my ($rtx, $loy) = util::cell2xy($cell2);
 
691
 
 
692
    if (! defined($lfx))
 
693
    {
 
694
        warning "cell '$cell1' is invalid\n";
 
695
        return undef;
 
696
    }
 
697
    if (! defined($rtx))
 
698
    {
 
699
        warning "cell '$cell2' is invlaid\n";
 
700
        return undef;
 
701
    }
 
702
 
 
703
    my $book = getWorkbook($file);
 
704
    my $buf;
 
705
 
 
706
    my $empty = 1;
 
707
 
 
708
    for (my $y = $upy; $y <= $loy; ++$y)
 
709
    {
 
710
        for (my $x = $lfx; $x <= $rtx; ++$x)
 
711
        {
 
712
            my $c = $book->getCell($sheet, $x, $y);
 
713
 
 
714
            warning($book->error()) if (! defined($c));
 
715
            $empty = 0 if(defined($c->{value}));
 
716
            $buf .= texifyCell($c);
 
717
            $buf .= " & " if ($x < $rtx);
 
718
        }
 
719
        $buf .= " \\\\\n";
 
720
    }
 
721
 
 
722
    warning("table $cell1!$cell2 is empty\n") if ($empty);
 
723
 
 
724
    ++$nItems;
 
725
    ++$nTabs;
 
726
    return $buf;
 
727
}
 
728
 
 
729
 
 
730
 
 
731
 
 
732
 
 
733
#XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
 
734
#XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
 
735
package readExcel;
 
736
 
 
737
use strict;
 
738
use Spreadsheet::ParseExcel;
 
739
use Encode;
 
740
 
 
741
#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 
742
sub new
 
743
{
 
744
    my ($class, $file) = @_;
 
745
 
 
746
    my $self = {};
 
747
    $self->{ERROR} = "";
 
748
 
 
749
    if (! -f $file)
 
750
    {
 
751
        print STDERR "can't read '$file', it does not exists.\n";
 
752
        exit_error();
 
753
    }
 
754
 
 
755
    $self->{book} = 
 
756
    Spreadsheet::ParseExcel::Workbook->Parse($file);
 
757
 
 
758
    if (! defined($self->{book}))
 
759
    {
 
760
        print STDERR "SpreadSheet::ParseExcel Error: "
 
761
            . "can't parse '$file' : $!\n";
 
762
        exit_error();
 
763
    }
 
764
 
 
765
    $self->{file} = $file;
 
766
    bless $self, $class;
 
767
 
 
768
    return $self;
 
769
}
 
770
 
 
771
 
 
772
#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 
773
sub getCell
 
774
{
 
775
    my ($self, $sheet, $x, $y) = @_;
 
776
 
 
777
    my $ws = $self->{book}->Worksheet($sheet);
 
778
    if (! defined($ws))
 
779
    {
 
780
        $self->_setError("sheet '$sheet' does not exist");
 
781
        return undef;
 
782
    }
 
783
 
 
784
    my $cell = $ws->Cell($y, $x);
 
785
 
 
786
    if(! $cell)
 
787
    {
 
788
        $self->_setError("cell '$sheet!" . util::xy2cell($x, $y) . "' is emtpy "
 
789
                         . "or out of range");
 
790
 
 
791
        return { value => undef }
 
792
    }
 
793
 
 
794
    # we're internally operating with utf8, for now
 
795
    my $value = encode_utf8($cell->Value());
 
796
    util::DEBUG "  value => '$value'";
 
797
 
 
798
    # return hash containing value and formatting
 
799
    return { value     => $value,
 
800
             bold      => $cell->{Format}->{Font}->{Bold},
 
801
             italic    => $cell->{Format}->{Font}->{Italic},
 
802
             color     => $cell->{Format}->{Font}->{Color},
 
803
             underline => $cell->{Format}->{Font}->{Underline},
 
804
             strikeout => $cell->{Format}->{Font}->{Strikeout}
 
805
           };
 
806
}
 
807
 
 
808
 
 
809
#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 
810
sub _setError
 
811
{
 
812
    my ($self, $err) = @_;
 
813
    $self->{ERROR} = $err;
 
814
}
 
815
 
 
816
 
 
817
#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 
818
sub error
 
819
{
 
820
    my $self = shift;
 
821
    my $err = $self->{ERROR};
 
822
    $self->{ERROR} = undef;
 
823
    return $err;
 
824
}