/[csv2latex]/csv2latex.c
ViewVC logotype

Annotation of /csv2latex.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 58 - (hide annotations)
Sun Jul 1 19:43:44 2018 UTC (17 months, 2 weeks ago) by ben
File MIME type: text/plain
File size: 19696 byte(s)
document function
1 ben 1 /*
2     * csv2latex.c, copyright © 2002- Benoît Rouits <brouits@free.fr>
3     *
4     *********************************************************
5     * csv2latex translates a .csv file to a LaTex document. *
6     *********************************************************
7     *
8     * This program is free software; you can redistribute it and/or
9     * modify it under the terms of the GNU General Public License
10     * as published by the Free Software Foundation; version 2 only
11     * of the License.
12     *
13     * This program is distributed in the hope that it will be useful,
14     * but WITHOUT ANY WARRANTY; without even the implied warranty of
15     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16     * GNU General Public License for more details.
17     *
18     * You should have received a copy of the GNU General Public License
19     * along with this program; if not, write to the Free Software
20     * Foundation, Inc., 51 Franklin Street, Fifth Floor,
21     * Boston, MA 02110-1301, USA.
22     *
23     * see the COPYING file included in the csv2latex package or
24     * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
25     *
26     */
27    
28     #include <stdlib.h>
29     #include <stdio.h>
30     #include <string.h>
31     #include <libgen.h>
32     #include <getopt.h>
33     #include <unistd.h>
34     #include <ctype.h>
35     #include "version.h"
36    
37 ben 55 #define PTOMM(p) (0.3528 * (p)) /* pt to mm */
38     #define HEIGHT PTOMM(592) /* \textheight default in pt */
39 ben 56 #define SKIPR 1.2 /* default \baselineskip ratio (to multiply with font) */
40 ben 55
41 ben 1 typedef struct {
42     char* tab; /* actual escapes */
43     int size; /* escape tab len */
44     } texcape;
45    
46     typedef struct {
47     char block; /* CSV delimitor if any */
48     char sep; /* CSV separator */
49     unsigned int cols; /* CSV columns */
50     unsigned int chars; /* CSV max data length */
51     unsigned int rows; /* CSV total number of lines */
52     char pos; /* position in cell (align) */
53     unsigned int lines; /* rows per LaTeX tabular */
54     unsigned int guess; /* guess or not the CSV format */
55     unsigned int header; /* put LaTeX document header or not */
56     unsigned int red; /* table reduction level (from 1 to 4)*/
57     unsigned int longtable; /* use package longtable */
58     unsigned int escape; /* escape TeX control chars or not */
59 ben 6 unsigned int repeat; /* repeat table headers for each LaTeX table section or not */
60     unsigned int vlines; /* insert vertical lines between columns or not */
61     unsigned int hlines; /* insert horizontal lines between rows or not */
62 ben 55 unsigned int paper; /* output paper type */
63     unsigned int font; /* expected font size */
64     unsigned int land; /* landscape mode */
65 ben 1 char* clrrow; /* row graylevel (from 0 to 1) */
66     texcape* tex; /* TeX escapes */
67     } config;
68    
69     #define MAXUINT ((unsigned int)(-1))
70    
71     void rtfm(char* prog) {
72     printf("%s translates a csv file to a LaTeX file\n", basename(prog));
73     printf("Example: %s january_stats.csv > january_stats.tex\n", basename(prog));
74     printf("Usage: %s [--nohead] (LaTeX) no document header: useful for inclusion\n", basename(prog));
75     printf(" [--longtable] (LaTeX) use package longtable: useful for long input\n");
76     printf(" [--noescape] (LaTeX) do not escape text: useful for mixed CSV/TeX input\n");
77     printf(" [--guess] (CSV) guess separator and block |\n"
78     " [--separator <(c)omma|(s)emicolon|(t)ab|s(p)ace|co(l)on>] (CSV's comma)\n"
79     " [--block <(q)uote|(d)ouble|(n)one>] (CSV) block delimiter (e.g: none)\n");
80 ben 55 printf(" [--lines n] (LaTeX) rows per table: useful for long tabulars |\n");
81     printf(" [--font n] font size used (in pt)\n");
82 ben 1 printf(" [--position <l|c|r>] (LaTeX) text align in cells\n");
83     printf(" [--colorrows graylevel] (LaTeX) alternate gray rows (e.g: 0.75)\n");
84     printf(" [--reduce level] (LaTeX) reduce table size (e.g: 1)\n");
85 ben 55 printf(" [--landscape] (LaTeX) use landscape mode\n");
86 ben 6 printf(" [--repeatheader] (LaTeX) repeat table header (for long tables)\n");
87     printf(" [--nohlines] (LaTeX) don't put hline between table rows\n");
88     printf(" [--novlines] (LaTeX) don't put vline between columns\n");
89 ben 1 printf(" csv_file.csv\n");
90     printf("The \"longtable\" option needs the {longtable} LaTeX package\n");
91     printf("The \"colorrows\" option needs the {colortbl} LaTeX package\n");
92     printf("The \"reduce\" option needs the {relsize} LaTeX package\n");
93     return;
94     }
95    
96     config* parseOptions (config* conf, int argc, char **argv) {
97     /* thx to <vfebvre@lautre.net> */
98     int opt;
99     int tmp;
100    
101     #if defined USE_GETOPT
102     #else
103     int longopt_index = 0;
104     static struct option long_options[] = {
105 33 {"help", 0, NULL, 'h'},
106     {"guess", 0, NULL, 'g'},
107     {"block", 1, NULL, 'b'},
108     {"lines", 1, NULL, 'l'},
109     {"noescape", 0, NULL, 'x'},
110     {"nohead", 0, NULL, 'n'},
111     {"version", 0, NULL, 'v'},
112     {"position", 1, NULL, 'p'},
113     {"separator", 1, NULL, 's'},
114     {"colorrows", 1, NULL, 'c'},
115     {"reduce", 1, NULL, 'r'},
116     {"longtable", 0, NULL, 't'},
117     {"repeatheader", 0, NULL, 'e'},
118     {"novlines", 0, NULL, 'y'},
119     {"nohlines", 0, NULL, 'z'},
120 ben 55 {"landscape", 0, NULL, 'a'},
121     {"font", 1, NULL, 'f'},
122 33 {NULL, 0, NULL, 0} /* marks end-of-list */
123 ben 1 };
124     #endif
125     #if defined USE_GETOPT
126 ben 55 while ((opt = getopt (argc, argv, "hvgnxteyza?b:l:p:s:c:r:f:")) != EOF) {
127 ben 1 #else
128 ben 55 while ((opt = getopt_long (argc, argv, "hvgnxteyza?b:l:p:s:c:r:f:", long_options, &longopt_index)) > 0) {
129 ben 1 #endif
130     switch (opt) {
131     case '?':
132     case 'h':
133     rtfm (argv[0]);
134     exit (EXIT_SUCCESS);
135     break;
136     case 'g': /* guess the CSV */
137 33 conf->guess = 1;
138 ben 1 break;
139 ben 13 case 't': /* use package longtable */ /* thx to <Christof.Bodner@infineon.com> */
140 33 conf->longtable = 1;
141 ben 1 break;
142     case 'b': /* csv block delimiter */
143 39 if (optarg[0] == 'q')
144 ben 1 conf->block = '\'';
145 39 else if (optarg[0] == 'd')
146 ben 1 conf->block = '"';
147 39 else if (optarg[0] == 'n')
148 ben 1 conf->block = 0; /* no block delimiter */
149     break;
150     case 'l': /* number of lines per TeX tabulars */
151 39 if (isdigit(optarg[0])) {
152 33 conf->lines = atoi(optarg);
153 ben 1 } else {
154     fprintf(stderr,
155     "option \"lines\" need a positive integer value\n");
156     exit(EXIT_FAILURE);
157     }
158     break;
159     case 'n':
160 33 conf->header = 0;
161 ben 1 break;
162     case 'x':
163 33 conf->escape = 0;
164 ben 1 break;
165     case 'v': /* version */
166     printf ("%s © 2002- Benoît Rouits <brouits@free.fr>\n"
167     "\tVersion %s (%s)\n", PACKAGE, VERSION, RELEASE_DATE);
168     exit (EXIT_SUCCESS);
169     break;
170     case 'p': /* LaTeX position in cell */
171 33 conf->pos = optarg[0]; /* position char in cell */
172 ben 1 break;
173     case 's': /* csv block separator */
174 39 if (optarg[0] == 'c')
175 ben 1 conf->sep = ',';
176 39 else if (optarg[0] == 's')
177 ben 1 conf->sep = ';';
178 39 else if (optarg[0] == 't')
179 ben 1 conf->sep = '\t';
180 39 else if (optarg[0] == 'p')
181 ben 1 conf->sep = ' ';
182 39 else if (optarg[0] == 'l')
183 ben 1 conf->sep = ':';
184     break;
185     case 'c': /* color rows (thx to <jcorso@cse.Buffalo.EDU>) */
186 39 if (isdigit(optarg[0])) {
187 ben 1 conf->clrrow = (char*)malloc(strlen(optarg)+1);
188 33 strcpy(conf->clrrow, optarg);
189 ben 1 } else {
190     fprintf(stderr,
191     "option \"colorrows\" needs a real value between 0 and 1\n");
192     exit(EXIT_FAILURE);
193     }
194     break;
195     case 'r': /* reduce table size (original idea thx to <boaz.gezer@gmail.com>) */
196 39 if (isdigit(optarg[0])) {
197 ben 1 tmp = atoi(optarg);
198 33 conf->red = (tmp>4) ? 4 : (tmp<0) ? 0 : tmp; /* [1-4] */
199 ben 1 } else {
200     fprintf(stderr,
201     "option \"reduce\" needs an integer value between 1 and 4\n");
202     exit(EXIT_FAILURE);
203     }
204     break;
205 ben 6 case 'e': /*repeat table header for each table section*/
206 33 conf->repeat = 1;
207 ben 6 break;
208     case 'y': /*don't draw vlines between columns*/
209 33 conf->vlines = 0;
210 ben 6 break;
211     case 'z': /*don't draw hlines between rows*/
212 33 conf->hlines = 0;
213 ben 6 break;
214 ben 55 case 'a': /*landscape*/
215     conf->land = 1;
216     break;
217     case 'f': /*output font size*/
218     if (isdigit(optarg[0])) {
219     conf->font = atoi(optarg);
220     } else {
221     fprintf(stderr,
222     "option \"font\" need a positive integer value\n");
223     exit(EXIT_FAILURE);
224     }
225     break;
226 ben 1 }
227     }
228     return conf;
229     }
230 ben 55
231 ben 1 int guessCSV(config* conf, FILE* in) {
232     /* guess the block delimiter and the csv separator */
233     int token;
234 45
235 33 token = getc(in); /* first char is block delimiter */
236 39 if (token == EOF) {
237 49 fprintf(stderr, "ERROR: empty file ?\n");
238 45 return -1;
239 ben 1 } else if (ispunct(token) || token == ' ') {
240     /* found first block delimiter, act this way */
241 33 conf->block = token;
242     fprintf(stderr, "Guessed '%c' as Block Delimiter\n",
243 ben 1 conf->block);
244     /* stream file while token is printable data */
245 39 while ((token = getc(in)) != conf->block &&
246 ben 1 token != '\n' &&
247     token != EOF)
248     {/* getc has been done */}
249 43 if (token == conf->block) {
250 ben 1 /* second delimiter : next is separator */
251 33 conf->sep = getc(in);
252     fprintf(stderr, "Guessed '%c' as Separator\n",
253 ben 1 conf->sep);
254 45 return 0;
255     } else {
256     return -1; /* what else ? */
257 ben 1 }
258 45 } else { /* no block delimiter, act this way */
259 33 conf->block = 0;
260     fprintf(stderr, "Guessed No Block Delimiter\n");
261 ben 1 /* stream file while input is not a control char */
262 45 while (!ispunct((token = getc(in))) &&
263 ben 1 token != '\n' &&
264     token != EOF)
265     {/* getc has been done */}
266     /* guess CSV separator */
267 43 if (ispunct(token) || token == '\t' || token == ' ') {
268 33 conf->sep = token;
269     fprintf(stderr, "Guessed %c as Separator\n", conf->sep);
270 45 return 0;
271 ben 1 } else { /* did not found any separator */
272 33 fprintf(stderr, "ERROR: Did not guess any Separator!\n");
273 45 return -1;
274 ben 1 }
275     }
276 45 return 0;
277 ben 1 }
278    
279     void getMaximums(config* conf, FILE* in) {
280     /* gets the number of cols and chars of a csv file assuming a separator */
281 33 int token = 0;
282 45 int nosep = 0;
283 33 unsigned int curcol = 0;
284     unsigned int curchar = 0;
285     unsigned int inblock = 0;
286 ben 1 /* init */
287 33 conf->chars = 0;
288     conf->cols = 0;
289     conf->rows = 0;
290 ben 1
291     while (token != EOF) {
292 33 token = getc(in);
293 45
294 ben 1 /* EOF ? */
295     if (token == EOF) {
296     continue;
297     }
298    
299     /* decide the maximums */
300     if (token == '\n') {
301     curcol++;
302 33 conf->cols = (conf->cols<curcol) ? curcol : conf->cols;
303     conf->chars = (conf->chars<curchar) ? curchar : conf->chars;
304 ben 1 conf->rows++;
305 33 curcol = 0;
306     curchar = 0;
307     inblock = 0; /* reset block state */
308 ben 1 continue;
309     }
310    
311 45 /* check implicit, non-guessed, block */
312     if (token == '\"') {
313     if (nosep == 0)
314     nosep = 1;
315     else
316     nosep = 0;
317     }
318    
319 ben 1 /* enter/quit a block */
320     if (conf->block && token == conf->block) {
321 33 inblock = !inblock;
322 ben 1 continue;
323     }
324    
325     /* count cols in current line */
326 45 if (token == conf->sep && ((conf->block && !inblock) || !conf->block) && nosep == 0) {
327 ben 1 curcol++;
328     continue;
329     }
330    
331     /* count chars in current cell */
332     if (token != conf->block && ((conf->block && inblock) || !conf->block)) {
333     curchar++;
334     continue;
335     }
336     }
337     return;
338     }
339    
340 ben 55 unsigned int guessLinesPerPage(unsigned int font, double height) {
341 ben 58 /**
342     * return: estimated number of lines per page, given page height in milimeter and font size in point
343     */
344 ben 56 return height / (PTOMM(SKIPR * font));
345 ben 55 }
346    
347    
348 ben 1 void doTeXsub(config* conf, char newsep, FILE* in, FILE* out) {
349     /* substitutes CSV sep by LaTeX newsep and some TeX code */
350 33 int token = 0;
351 ben 1 int max;
352     int numcols;
353 ben 6 unsigned int lines;
354 33 int inblock = 0;
355 ben 1 int csvrows;
356 33 int firstrow = 1;
357     int nosep = 0;
358     int token1 = 0;
359     int token2 = 0;
360 ben 6 char headerrow[1000];
361 33 headerrow[0] = '\0';
362 ben 1
363 33 max = numcols = conf->cols;
364     csvrows = conf->rows;
365 ben 55
366     /* optimize a bit lines per tabular */
367     if (!conf->longtable && !conf->lines) {
368     conf->lines = guessLinesPerPage(conf->font ? conf->font : 10, conf->land ? (HEIGHT / 1.414) : HEIGHT);
369     fprintf(stderr, "guessed %d lines per page\n", conf->lines);
370     }
371    
372 ben 1 /* choose infinity when conf->lines is 0 */
373 33 lines = (conf->lines) ? conf->lines : MAXUINT;
374 ben 1
375 33 while (token != EOF) {
376     token2 = token1; /* second last character, used for detection of quotation marks */
377     token1 = token; /* last character, used for detection of quotation marks */
378     token = getc(in);
379 45
380 ben 1 /* EOF ? */
381     if (token == EOF) {
382     continue;
383     }
384    
385     /* new line ? */
386     if (token == '\n') {
387     inblock = 0; /* close block if any */
388     /* fill empty cols if any */
389     while (numcols > 1) {
390 33 putc(newsep, out);
391 ben 1 numcols--;
392     }
393 ben 6 if (!(firstrow && (conf->longtable && conf->repeat))) {
394 33 fprintf(out, "\\\\\n"); /* TeX new line */
395 ben 6 } else { /* first row and repeat and longtable */
396     fprintf(out, "%s\\\\\n", headerrow);
397     }
398 39 if (conf->hlines) {
399 33 fprintf(out, "\\hline\n"); /* TeX draw hline */
400 ben 6 }
401     if (firstrow && (conf->longtable && conf->repeat)) {
402     fprintf(out, "%s", "\\endhead\n");
403     }
404 39 if (firstrow && conf->repeat) {
405 ben 6 char tmp[12];
406 33 sprintf(tmp, (conf->hlines ? "\\\\\n\\hline" : "\\\\\n"));
407     strcat(headerrow, tmp);
408 ben 6 }
409 33 firstrow = 0;
410     numcols = max; /* reset numcols */
411 ben 1 lines--;
412     csvrows--;
413     /* put a colored row or not (alternate) */
414 ben 6 if (conf->clrrow && (lines % 2)) {
415 33 fprintf(out, "\\colorrow ");
416 ben 1 }
417 ben 6 /* if the LaTeX tabular is full create a new one, except if no more row or this is a long table */
418     if (!lines && csvrows && !conf->longtable) {
419 33 fprintf(out, "\\end{tabular}\n");
420 ben 6 fprintf(out, "\\newline\n");
421 33 fprintf(out, "\\begin{tabular}{");
422 39 if (conf->vlines) {
423 33 putc('|', out);
424 ben 6 }
425 39 while (numcols--) {
426 ben 6 putc(conf->pos, out);
427 39 if (conf->vlines) {
428 33 putc('|', out);
429 ben 6 }
430     }
431 ben 1 fprintf(out, "}\n");
432 39 if (conf->hlines) {
433 ben 6 fprintf(out, "\\hline\n");
434     }
435 39 if (conf->repeat && !conf->longtable) {
436 33 fprintf(out, "%s", headerrow);
437     putc('\n', out);
438 ben 6 }
439 33 numcols = max;
440     lines = (conf->lines) ? conf->lines : MAXUINT;
441 ben 6 }
442     /* else end of CSV data */
443 ben 1 continue;
444     }
445    
446 ben 13 /* if commas in cells */
447     /* thx to <florian@heinze.at> */
448 43 if (token == '\"') {
449 33 if (nosep == 0)
450     nosep = 1;
451 ben 13 else
452 33 nosep = 0;
453 ben 13 }
454 45
455 ben 1 /* new column ? */
456 45 if ((token == conf->sep && ((conf->block && !inblock) || !conf->block)) && nosep == 0) {
457 ben 6 if (!(firstrow && (conf->longtable && conf->repeat)))
458 33 putc(newsep, out);
459 ben 1 numcols--;
460 39 if (firstrow && conf->repeat)
461 ben 6 {
462     char tmp[2];
463 33 tmp[0] = newsep;
464     tmp[1] = '\0';
465     strcat(headerrow, tmp);
466 ben 6 }
467 ben 1 continue;
468     }
469    
470     /* enter/quit a block ? */
471     if (conf->block && token == conf->block) {
472 33 inblock = !inblock;
473 ben 1 continue;
474     }
475    
476     /* data ? */
477 33 if ((token != conf->block && ((conf->block && inblock) || !conf->block))
478     && ((token == '\"' && token1 == '\"' && token2 == '\"') || token != '\"')) {
479 ben 1 /* look for special TeX char to escape */
480     /* FIXME: put all that into a subroutine */
481 33 int i = 0;
482 ben 1 if (conf->escape)
483 33 for (i = 0; i < conf->tex->size; i++) {
484 ben 1 if (token == conf->tex->tab[i]) {
485     switch (token) {
486     case '\\':
487     fprintf(out, "\\textbackslash{}");
488 39 if (firstrow && conf->repeat)
489 ben 6 {
490     char tmp[17];
491 33 sprintf(tmp, "\\textbackslash{}");
492     strcat(headerrow, tmp);
493 ben 6 }
494 ben 1 break;
495     default:
496     fprintf(out, "\\%c", token);
497 39 if (firstrow && conf->repeat)
498 ben 6 {
499     char tmp[3];
500 33 tmp[0] = '\\';
501     tmp[1] = token;
502     tmp[2] = '\0';
503     strcat(headerrow, tmp);
504 ben 6 }
505 ben 1 break;
506     }
507     break; /* there was some escaping */
508     }
509     }
510     /* or print raw char */
511 33 if ((i >= conf->tex->size) || (!conf->escape)) {
512 ben 6 if (!(firstrow && (conf->longtable && conf->repeat)))
513     putc(token, out); /* do not print the header twice */
514 39 if (firstrow && conf->repeat)
515 ben 6 {
516     char tmp[2];
517 33 tmp[0] = token;
518     tmp[1] = '\0';
519     strcat(headerrow, tmp);
520 ben 6 }
521 ben 1 }
522     continue;
523     }
524     /* do nothing if unexpected char: just loop */
525     }
526     return;
527     }
528    
529     void doTeXdoc(config* conf, FILE* in, FILE* out) {
530     /* prepares the LaTeX tabular layout */
531     int maxcols;
532     int numcols;
533     char* relsize[5] = {"0", "0.5", "1", "2", "4"}; /* LaTeX relsize good values */
534     char* tabcolsep[5] = {"0", "0.05", "0.1", "0.2", "0.4"}; /* LaTeX tabcolsep good values */
535    
536 33 numcols = maxcols = conf->cols;
537 43 if (conf->header) {
538 ben 55 if (conf->land) {
539     if (conf->font)
540     fprintf(out, "\\documentclass[%dpt,a4paper,landscape]{article}\n", conf->font);
541     else {
542     fprintf(out, "\\documentclass[a4paper,landscape]{article}\n");
543     conf->font = 10; /* pt */
544     }
545     } else {
546     if (conf->font)
547     fprintf(out, "\\documentclass[%dpt,a4paper]{article}\n", conf->font);
548     else {
549     fprintf(out, "\\documentclass[a4paper]{article}\n");
550     conf->font = 10; /* pt */
551     }
552     }
553 ben 1 fprintf(out, "\\usepackage[T1]{fontenc}\n");
554 45 fprintf(out, "\\usepackage[utf8]{inputenc}\n");
555 43 if (conf->red) {
556 33 fprintf(out, "\\usepackage{relsize}\n");
557 ben 1 }
558 43 if (conf->clrrow) {
559 33 fprintf(out, "\\usepackage{colortbl}\n");
560 ben 1 }
561 43 if (conf->longtable) {
562 33 fprintf(out, "\\usepackage{longtable}\n");
563 ben 1 }
564     fprintf(out, "\\begin{document}\n");
565     }
566 43 if (conf->clrrow) {
567 33 fprintf(out, "\\def\\colorrow{\\rowcolor[gray]{%s}}\n",
568 ben 1 conf->clrrow);
569     }
570 43 if (conf->red) {
571 33 fprintf(out, "\\relsize{-%s}\n", relsize[conf->red]);
572     fprintf(out, "\\addtolength\\tabcolsep{-%sem}\n", tabcolsep[conf->red]);
573 ben 1 }
574     if (conf->longtable)
575 ben 6 {
576     fprintf(out, "\\begin{longtable}{");
577 39 if (conf->vlines)
578 33 putc('|', out);
579 ben 6 }
580 ben 1 else
581 ben 6 {
582     fprintf(out, "\\begin{tabular}{");
583 39 if (conf->vlines)
584 33 putc('|', out);
585 ben 6 }
586 39 while (numcols--)
587 ben 6 {
588 33 fprintf(out, "%c", conf->pos); /* position in cell */
589 39 if (conf->vlines)
590 33 putc('|', out);
591 ben 6 }
592 ben 1 fprintf(out, "}\n");
593 39 if (conf->hlines)
594 ben 6 fprintf(out, "\\hline\n");
595 ben 1 doTeXsub(conf, '&', in, out); /* & is LaTeX separator */
596     if (conf->longtable) {
597     fprintf(out, "\\end{longtable}\n");
598     } else {
599     fprintf(out, "\\end{tabular}\n");
600     }
601 43 if (conf->red) {
602 33 fprintf(out, "\\addtolength\\tabcolsep{+%sem}\n", tabcolsep[conf->red]);
603     fprintf(out, "\\relsize{+%s}\n", relsize[conf->red]);
604 ben 1 }
605 43 if (conf->header) {
606 ben 1 fprintf(out, "\\end{document}\n");
607     }
608     return;
609     }
610 33
611 ben 1 int main (int argc, char **argv) {
612     FILE* fp;
613     config* conf;
614    
615     extern int optind, opterr, optopt;
616    
617 33 conf = (config*)malloc(sizeof(config));
618 ben 1 /* defaults (ensure init): */
619 33 conf->cols = 1; /* CSV: if getMaximums fails */
620     conf->rows = 0; /* CSV: must be 0 */
621     conf->chars = 0; /* CSV: must be 0 */
622     conf->pos = 'l'; /* usual; LaTeX */
623     conf->lines = 40; /* usual; LaTeX */
624     conf->guess = 0; /* usual */
625     conf->sep = ','; /* default; csv */
626     conf->block = 0; /* default; csv */
627     conf->header = 1; /* usual; LaTeX */
628     conf->escape = 1; /* usual; LaTeX */
629     conf->clrrow = NULL; /* default; LaTeX */
630     conf->red = 0; /* default; LaTeX */
631     conf->longtable = 0; /* default; without package longtable */
632     conf->repeat = 0; /* default; do not repeat the header row */
633     conf->vlines = 1; /* default; draw lines between columns */
634     conf->hlines = 1; /* default; draw lines between rows */
635 ben 55 conf->font = 0; /* default to LaTeX defaults */
636 ben 56 conf->land = 0; /* default to LaTeX defaults */
637 45
638 ben 1 /* TeX charaters to escape */
639 33 conf->tex = (texcape*)malloc(sizeof(texcape));
640 ben 1 conf->tex->tab = "\\_#$%^&{}~";
641 33 conf->tex->size = strlen(conf->tex->tab);
642    
643 45
644 33 conf = parseOptions(conf, argc, argv);
645    
646     if (optind == argc) {
647     /* copy stdin into tmp file */
648 38 int c;
649 33 fp = tmpfile();
650     while (EOF != (c = getc(stdin))) {
651     putc(c, fp);
652     }
653     rewind(fp);
654     } else {
655     fp = fopen(argv[optind], "r");
656     }
657    
658 43 if (!fp) {
659 33 fprintf(stderr, "Can't open file %s\n", argv[optind]);
660 ben 1 exit(EXIT_FAILURE);
661     }
662 33
663 43 if (conf->guess) {
664     if (guessCSV(conf, fp)) {
665 36 fprintf(stderr, "Please run again by using --delimiter (if any) and --separator\n");
666 37 fclose(fp);
667 ben 1 exit(EXIT_FAILURE);
668     }
669     rewind(fp);
670     }
671 33
672 ben 1 getMaximums(conf, fp);
673     rewind(fp);
674 37
675 ben 1 doTeXdoc(conf, fp, stdout);
676 37
677 ben 1 free(conf->tex);
678 37 if (conf->clrrow)
679     free(conf->clrrow);
680 ben 1 free(conf);
681     fclose(fp);
682 33
683     exit(EXIT_SUCCESS);
684 ben 1 }

  ViewVC Help
Powered by ViewVC 1.1.26