w32tex
About: TeX Live provides a comprehensive TeX system including all the major TeX-related programs, macro packages, and fonts that are free software. Windows sources.
  Fossies Dox: w32tex-src.tar.xz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

tables.c
Go to the documentation of this file.
1 /* tables.c - Translation of tabbing and tabular environments
2 
3 Copyright (C) 2002 The Free Software Foundation
4 
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
9 
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 
19 This file is available from http://sourceforge.net/projects/latex2rtf/
20 */
21 
22 #include <string.h>
23 #include <ctype.h>
24 #include <stdlib.h>
25 #include "main.h"
26 #include "convert.h"
27 #include "l2r_fonts.h"
28 #include "commands.h"
29 #include "funct1.h"
30 #include "tables.h"
31 #include "stack.h"
32 #include "cfg.h"
33 #include "parser.h"
34 #include "counters.h"
35 #include "util.h"
36 #include "lengths.h"
37 
38 typedef struct TabularT {
39  int n; /* number of columns */
40  char *align; /* align[1] is the alignment of the first column */
41  int *vert; /* vert[0] is the number of |'s before first column
42  vert[1] is the number of |'s after first column
43  vert[n] is the number of |'s after last column */
44  int *width; /* width[1] is the width of the first column */
45  int *cline; /* cline[1] is true when line should be draws across column 1 */
47 
51 
52 int tabcounter = 0;
59 
60 int colCount; /* number of columns in a tabular environment */
61 int actCol; /* actual column in the tabular environment */
62 char *colFmt = NULL;
63 
64 void CmdTabjump(void)
65 {
66  fprintRTF("\\tab ");
67 }
68 
69 void CmdTabset(void)
70 {
71 }
72 
73 static void
75 /******************************************************************************
76  purpose: emit RTF code to start each cell
77  ******************************************************************************/
78 {
79  fprintRTF("\\pard\\intbl\\q%c ", align);
80 }
81 
82 static void
83 EndCell(void)
84 /******************************************************************************
85  purpose: emit RTF code to end each cell
86  ******************************************************************************/
87 {
88  fprintRTF("\\cell\n");
89 }
90 
91 static char *
93 /******************************************************************************
94  purpose: convert latex formatting to something simpler
95  ******************************************************************************/
96 {
97  int braces,i;
98  char *simple;
99 
100  simple = strdup(s); /* largest possible */
101  diagnostics(4, "Entering ConvertFormatString, input=<%s>",s);
102 
103  i=0;
104  while (*s) {
105 
106  switch (*s) {
107  case 'c':
108  case 'r':
109  case 'l':
110  simple[i++] = *s;
111  break;
112  case '{': /* skip to balancing brace */
113  braces=1;
114  s++;
115  while (*s && (braces>1 || *s!='}')) {
116  if (*s=='{') braces++;
117  if (*s=='}') braces--;
118  s++;
119  }
120  break;
121  case 'p':
122  diagnostics(WARNING__, " 'p{width}' not fully supported");
123  simple[i++] = 'l';
124  break;
125  case '*':
126  diagnostics(WARNING__, " '*{num}{cols}' not supported.\n");
127  break;
128  case '@':
129  diagnostics(WARNING__, " '@{text}' not supported.\n");
130  break;
131  default:
132  break;
133  }
134  s++;
135  }
136  simple[i]='\0';
137  diagnostics(4, "Exiting ConvertFormatString, output=<%s>",simple);
138  return simple;
139 }
140 
141 static int
143 /******************************************************************************
144  purpose: return position of nth column
145  ******************************************************************************/
146 {
147  int colWidth = getLength("textwidth")/colCount;
148  return colWidth * (n+1);
149 }
150 
151 static void
152 TabularCountVert(char *s, int vert[])
153 /******************************************************************************
154  purpose: fill vert[] with number of '|' for each column
155  ******************************************************************************/
156 {
157  int braces,i;
158 
159  diagnostics(4, "Entering TabularCountVert, input=<%s>",s);
160 
161  i=0;
162  while (*s) {
163 
164  switch (*s) {
165  case 'c': case 'r': case 'l': case 'p':
166  i++;
167  break;
168  case '{': /* skip to balancing brace */
169  braces=1;
170  s++;
171  while (*s && (braces>1 || *s!='}')) {
172  if (*s=='{') braces++;
173  if (*s=='}') braces--;
174  s++;
175  }
176  break;
177  case '|':
178  vert[i]++;
179  break;
180  default:
181  break;
182  }
183  s++;
184  }
185  diagnostics(4, "Exiting TabularCountVert");
186 }
187 
188 static TabularT
189 TabularPreamble(char *text, char *width, char *pos, char *cols)
190 /******************************************************************************
191  purpose: calculate column widths
192  ******************************************************************************/
193 { TabularT tab;
194  int i;
195 
197  colCount = (int) strlen(colFmt);
198  actCol = 0;
199 
200  tab.n = colCount;
201  tab.align = (char *)calloc(sizeof(char)*(colCount+1),sizeof(char));
202  tab.vert = (int *)calloc(sizeof(int )*(colCount+1),sizeof(int ));
203  tab.width = (int *)calloc(sizeof(int )*(colCount+1),sizeof(int ));
204  tab.cline = (int *)calloc(sizeof(int )*(colCount+1),sizeof(int ));
205 
206  for (i=1; i<=colCount; i++)
207  tab.align[i] = colFmt[i-1];
208 
209  TabularCountVert(cols,tab.vert);
210 
211  if (GetTexMode() != MODE_HORIZONTAL){
214  }
215 
216  fprintRTF("\\par\n");
217  return tab;
218 }
219 
220 static void
221 TabularGetRow(char *table, char **row, char **next_row, int *height)
222 /******************************************************************************
223  purpose: scan and duplicate the next row from a tabular environment and any height changes
224  e.g. the & cell & is & here \\[2pt]
225  but & then & it & died \\
226  will return "the & cell & is & here" and height should be 40 (twips)
227  ******************************************************************************/
228 {
229  char *s,*dimension,*dim_start;
230  int slash=0;
231  size_t row_chars=0;
232  size_t dim_chars=0;
233  bool slashslash=FALSE;
234 
235  s=table;
236  *row=NULL;
237  *next_row=NULL;
238  *height=0;
239 
240  if (!s) return;
241 
242  while (!(*s == '\0') && !(*s == '\\' && slash) ) {
243  slash = (*s == '\\') ? 1 : 0;
244  row_chars++;
245  s++;
246  }
247 
248  if (*s == '\\' && slash) {
249  row_chars--;
250  slashslash=TRUE;
251  }
252 
253  *row = (char *)malloc((row_chars+1)*sizeof(char));
254  strncpy(*row, table, row_chars);
255  (*row)[row_chars]='\0';
256 
257  diagnostics(4,"row =<%s>",*row);
258  if (!slashslash) return;
259 
260 /* move after \\ */
261  s++;
262 
263 /* skip blanks */
264  while (*s != '\0' && (*s==' ' || *s=='\n')) s++;
265 
266  if (*s=='\0') return;
267 
268  if (*s != '[') {
269  *next_row = s;
270  return;
271  }
272 
273 /* read line space dimension */
274  s++;
275  dim_start=s;
276  while (*s != '\0' && *s != ']') {
277  s++;
278  dim_chars++;
279  }
280  if (*s=='\0') return;
281 
282 /* figure out the row height */
283  dimension=malloc((dim_chars+2)*sizeof(char));
284  strncpy(dimension,dim_start,dim_chars);
285  dimension[dim_chars]='\n'; /* make sure entire string is not parsed */
286  dimension[dim_chars+1]='\0';
287 
288  if (PushSource(NULL,dimension) == 0) {
289  *height=getDimension();
290  PopSource();
291  }
292 
293  diagnostics(3,"height =<%s>=%d twpi",dimension,height);
294  free(dimension);
295 
296  /* skip blanks */
297  s++;
298  while (*s != '\0' && (*s==' ' || *s=='\n')) s++;
299 
300  if (*s=='\0') return;
301  *next_row = s;
302 }
303 
304 static char *
306 /******************************************************************************
307  purpose: find the next ampersand while avoiding \&
308  ******************************************************************************/
309 {
310  char *s;
311  int escaped=0;
312 
313  s=t;
314 
315  while (s && *s != '\0' && (*s != '&' || (*s=='&' && escaped))) {
316  escaped = (*s == '\\') ? 1 : 0;
317  s++;
318  }
319  return s;
320 }
321 
322 static char *
323 TabularNextCell(char *cell_start, char **cell_end)
324 /******************************************************************************
325  purpose: scan and duplicate contents of the next cell
326  ******************************************************************************/
327 {
328  char *end, *dup, *dup2;
329 
330  end = TabularNextAmpersand(cell_start);
331 
332  if (*end=='&') {
333  dup = my_strndup(cell_start, (size_t) (end-cell_start));
334  *cell_end = end+1;
335  } else {
336  dup = strdup(cell_start);
337  *cell_end = NULL;
338  }
339 
341  free(dup);
342 
343  return dup2;
344 }
345 
346 static void
347 TabularMultiParameters(char *cell, int *col_span, char *align, int *lvert, int *rvert)
348 /******************************************************************************
349  purpose: extract information from \multicolumn's on a line
350  return col_span=0 if none are present
351  ******************************************************************************/
352 {
353  char *p, *format, *mformat, *num;
354 
355  *col_span=0;
356  *align='\0';
357  *lvert=0;
358  *rvert=0;
359 
360  p=strstr(cell,"\\multicolumn");
361  if (p == NULL) return;
362 
363  PushSource(NULL,p+strlen("\\multicolumn"));
364  num = getBraceParam();
365  format = getBraceParam();
366  PopSource();
367  mformat=ConvertFormatString(format);
368 
369  /* count '|' to the left of the column */
370  p=format;
371  while (p && *p && *p!='c' && *p!='l' && *p!='r'){
372  if (*p=='|') (*lvert)++;
373  p++;
374  }
375  if (p && *p) p++;
376 
377  /* count '|' to the right of the column */
378  while (p && *p && *p!='c' && *p!='l' && *p!='r'){
379  if (*p=='|') (*rvert)++;
380  p++;
381  }
382 
383  *col_span = atoi(num);
384  *align = mformat[0];
385  free(num);
386  free(mformat);
387  free(format);
388  diagnostics(5, "TabularMultiParameters n=%d, align=%c",*col_span, *align);
389 }
390 
391 static int
393 /******************************************************************************
394  purpose: count the number of \hline's in a line
395  ******************************************************************************/
396 {
397  char *s,*t;
398  if (row==NULL) return 0;
399 
400  s=strstr(row,"\\hline");
401  if (s==NULL) return 0;
402 
403  t = strstr(s+6,"\\hline");
404 
405  if (t==NULL) return 1;
406  return 2;
407 }
408 
409 char *
411 /******************************************************************************
412  purpose: mark columns needing underline by \cline{ 1 - 2 }
413  limited to 1-9 columns
414  ******************************************************************************/
415 {
416  char *s,*x;
417  int i,n,m;
418  char *cline=NULL;
419 
420  cline = (char *) malloc((columns+2)*sizeof(char));
421  for (i=0;i<=columns+1;i++)
422  cline[i]='\0';
423 
424  if (row==NULL) return cline;
425 
426  /* hline commands override cline commands */
427  n=TabularHline(row);
428 
429  for (i=0;i<=columns;i++)
430  cline[i]= n;
431 
432  if (n) return cline;
433 
434  s = row;
435  x = row + strlen(row);
436  while (s<x) {
437  s=strstr(s,"\\cline{");
438 
439  if (s==NULL) return cline;
440 
441  s+=7;
442 
443  while (*s && (*s==' ' || *s=='\n')) s++; /* skip spaces after { */
444 
445  if (*s<='0' || *s>='9') return cline;
446  n=atoi(s); /* first column */
447 
448  while (*s && *s!='-') s++; /* skip past '-' */
449  s++;
450 
451  while (*s && (*s==' ' || *s=='\n')) s++; /* skip spaces after '-' */
452 
453  if (*s<='0' || *s>='9') return cline;
454  m=atoi(s); /* second column */
455 
456  for (i=n; i<=m; i++) {
457  if (i<=columns && i>=1) cline[i]=1;
458  }
459  while (*s && *s!='}') s++; /* skip to last '}' */
460  }
461 
462  return cline;
463 }
464 
465 static void
466 TabularBeginRow(TabularT tabular, char *this_row, char *next_row, int first_row)
467 /******************************************************************************
468  purpose: emit RTF to start one row of a table
469 
470  the vertical bar formatting codes for the entire row must be present at
471  the start of the row. The same holds for horizontal lines. Only the first
472  line may have an hlines above it. Drawing hlines below depends on the
473  next line containing an hline (i.e., after \\ that ends the row)
474 
475  ******************************************************************************/
476 {
477  int i,n,column,rvert,lvert;
478  char align;
479  char *cell_start, *cell_end, *cell, *row;
480  int top, left, bottom, right; /* cell borders */
481  char *cline;
482 
483  fprintRTF("\\trowd");
484 
485  row=this_row;
486  cell_start = this_row;
487  column = 0;
488 
489  cline = TabularCline(next_row,tabular.n);
490 
491  while (cell_start) { /*for each cell */
492 
493  top = 0;
494  left = 0;
495  right = tabular.vert[column+1];
496  bottom = cline[column+1];
497  if (first_row) top = TabularHline(this_row);
498  if (column==0) left = tabular.vert[0];
499 
500  cell = TabularNextCell(cell_start, &cell_end);
501  TabularMultiParameters(cell,&n,&align,&lvert,&rvert);
502  if (n>1) fprintRTF("\\clmgf");
503 
504  if (left == 1) fprintRTF("\\clbrdrl\\brdrs" );
505  if (left == 2) fprintRTF("\\clbrdrl\\brdrdb");
506  if (top == 1) fprintRTF("\\clbrdrt\\brdrs");
507  if (top == 2) fprintRTF("\\clbrdrt\\brdrdb");
508  if (bottom == 1) fprintRTF("\\clbrdrb\\brdrs");
509  if (bottom == 2) fprintRTF("\\clbrdrb\\brdrdb");
510  if (right == 1 || (n == 1 && rvert == 1)) fprintRTF("\\clbrdrr\\brdrs" );
511  if (right == 2 || (n == 1 && rvert == 2)) fprintRTF("\\clbrdrr\\brdrdb");
512  fprintRTF("\\cellx%d", TabularColumnPosition(column));
513  column++;
514 
515  for (i=2; i<=n; i++) {
516  fprintRTF("\\clmrg");
517  if (top == 1) fprintRTF("\\clbrdrt\\brdrs");
518  if (top == 2) fprintRTF("\\clbrdrt\\brdrdb");
519  if (bottom == 1) fprintRTF("\\clbrdrb\\brdrs");
520  if (bottom == 2) fprintRTF("\\clbrdrb\\brdrdb");
521  if (i == n && rvert == 1) fprintRTF("\\clbrdrr\\brdrs");
522  if (i == n && rvert == 2) fprintRTF("\\clbrdrr\\brdrdb");
523  fprintRTF("\\cellx%d", TabularColumnPosition(column));
524  column++;
525  }
526 
527  free(cell);
528  cell_start = cell_end;
529  }
530  fprintRTF("\n");
531  free(cline);
532 }
533 
534 static void
536 /******************************************************************************
537  purpose: emit RTF to finish one row of a table
538  ******************************************************************************/
539 {
540  fprintRTF("\\row\n");
541 }
542 
543 char
545 /******************************************************************************
546  purpose: alignment for a column
547  ******************************************************************************/
548 {
549  return colFmt[column];
550 }
551 
552 static void
553 TabularWriteRow(TabularT tabular, char *this_row, char *next_row, int height, int first_row)
554 {
555  char *cell, *cell_start, *cell_end;
556  char align;
557  int n, lvert, rvert;
558 
559  actCol=0;
560  if (this_row==NULL || strlen(this_row)==0) return;
561 
562  diagnostics(4, "TabularWriteRow height=%d twpi, row <%s>",height, this_row);
563 
564  /* avoid writing anything for empty last row */
565  if (next_row == NULL) {
566  if (colCount==1 && strlen(this_row)==0) return;
567  if (colCount >1 && !strchr(this_row, '&')) return;
568  }
569 
570  TabularBeginRow(tabular, this_row, next_row, first_row);
571  cell_start = this_row;
572  while (cell_start) {
573 
574  cell = TabularNextCell(cell_start, &cell_end);
575 
576  /* establish cell alignment */
577  TabularMultiParameters(cell,&n,&align,&lvert,&rvert);
578  if (n == 0) {
580  n = 1;
581  }
582 
583  BeginCell(align);
584  if (cell !=NULL) {
585  diagnostics(5, "TabularWriteRow align=%c n=%d cell=<%s>",align,n,cell);
586  fprintRTF("{");
588  fprintRTF("}");
589  }
590  EndCell();
591 
592  actCol+=n;
593  cell_start = cell_end;
594  if (cell != NULL) free(cell);
595  }
596 
597  if (actCol < colCount) {
599  BeginCell(align);
600  EndCell();
601  }
602 
603  TabularEndRow();
604 }
605 
606 void
608 /******************************************************************************
609  purpose: \begin{tabular}[pos]{cols} ... \end{tabular}
610  \begin{tabular*}{width}[pos]{cols} ... \end{tabular*}
611  \begin{array}[pos]{cols} ... \end{array}
612  ******************************************************************************/
613 {
614  int true_code,this_height, next_height, first_row, begins, ends;
615  char *end,*begin,*this_row, *next_row, *next_row_start, *row_start;
616  char *table=NULL;
617  char *cols=NULL;
618  char *pos=NULL;
619  char *width=NULL;
620  TabularT tabular;
621 
622  if (!(code & ON)) {
623  diagnostics(4, "Exiting CmdTabular");
625  if (colFmt) free(colFmt);
626  colFmt=NULL;
627  return;
628  }
629 
631  width = NULL;
632  pos=NULL;
633  cols=NULL;
634  true_code = code & ~(ON);
635  switch (true_code) {
636  case TABULAR:
637  end = strdup("\\end{tabular}");
638  begin = strdup("\\begin{tabular}");
639  break;
640  case TABULAR_STAR:
641  end = strdup("\\end{tabular*}");
642  begin = strdup("\\begin{tabular*}");
643  width = getBraceParam();
644  break;
645  case TABULAR_LONG:
646  end = strdup("\\end{longtable}");
647  begin = strdup("\\begin{longtable}");
648  break;
649  case TABULAR_LONG_STAR:
650  end = strdup("\\end{longtable*}");
651  begin = strdup("\\begin{longtable*}");
652  width = getBraceParam();
653  break;
654  }
655 
656  pos = getBracketParam();
657  cols = getBraceParam();
659 
660 /* need to make sure that we don't have nested environments */
661  begins = strstr_count(table, begin);
663 
664  while (begins > ends) {
665  char *table2, *table3, *table4;
666 
667  if (begins > ends) {
668  table2 = getTexUntil(end,FALSE);
669  table3 = strdup_together(table,end);
670  table4 = strdup_together(table3,table2);
671  free(table);
672  free(table2);
673  free(table3);
674  table=table4;
675  }
676  begins = strstr_count(table, begin);
678  }
679 
680  if (begins>0) {
681  char *p;
682  int num = TexFontNumber("Typewriter");
683  diagnostics(1, "Nest tabular/tabbing environments not allowed");
684  diagnostics(2, "table_table_table_table_table\n%stable_table_table_table_table",table);
685  fprintRTF("\\pard\\ql\\b0\\i0\\scaps0\\f%d ", num);
686  p=begin;
687  while (*p) putRtfChar(*p++);
688  p=table;
689  while (*p) putRtfChar(*p++);
690  p=end;
691  while (*p) putRtfChar(*p++);
692 
693  } else {
694 
695  diagnostics(3, "Entering CmdTabular() options [%s], format {%s}",(pos)?pos:"", cols);
697  row_start=table;
698  TabularGetRow(row_start,&this_row,&next_row_start,&this_height);
699 
700  diagnostics(2, "table_table_table_table_table\n%stable_table_table_table_table",table);
701 
702  first_row = TRUE;
703  while (this_row) {
704  row_start=next_row_start;
705  TabularGetRow(row_start,&next_row,&next_row_start,&next_height);
706  TabularWriteRow(tabular, this_row, next_row, this_height, first_row);
707  free(this_row);
708  this_row = next_row;
709  this_height = next_height;
710  first_row = FALSE;
711  }
712 
713  free(tabular.cline);
714  free(tabular.align);
715  free(tabular.vert);
716  free(tabular.width);
717  if (cols) free(cols);
718  if (pos ) free(pos);
719  if (width) free(width);
720  }
721 
723  free(table);
724  free(end);
725  free(begin);
726 }
727 
728 static int
730 /******************************************************************************
731  purpose: return position of nth column
732  ******************************************************************************/
733 {
734  int colWidth = getLength("textwidth")/total;
735  return colWidth * (n+1);
736 }
737 
738 static void
739 TabbingNextCellEnd(char *t, char **cell_end, char **next_cell)
740 /******************************************************************************
741  purpose: find the next ampersand while avoiding \&
742  ******************************************************************************/
743 {
744  char *s;
745  s=t;
746 
747  while (s) {
748 
749  if (*s == '\0') {
750  *cell_end = s;
751  *next_cell = s;
752  return;
753  }
754 
755  if (*s == '\\') {
756  s++;
757  if (*s=='=' || *s=='>' || *s=='<' || *s=='\'' || *s=='`') {
758  *cell_end = s-1;
759  *next_cell = s+1;
760  return;
761  }
762  }
763  s++;
764  }
765 }
766 
767 static char *
768 TabbingNextCell(char *cell_start, char **cell_end)
769 /******************************************************************************
770  purpose: scan and duplicate contents of the next cell
771  ******************************************************************************/
772 {
773  char *end, *dup, *dup2, *next_cell, *p;
774 
775  TabbingNextCellEnd(cell_start, &end, &next_cell);
776 
777  if (end<cell_start) end=cell_start;
778  dup = my_strndup(cell_start, (size_t) (end-cell_start));
779 
780  if (*next_cell=='\0')
781  *cell_end = NULL;
782  else
783  *cell_end = next_cell;
784 
785  /* remove \- and \+ from string */
786  while( ((p=strstr(dup,"\\+")) != NULL) || ((p=strstr(dup,"\\-")) != NULL)) {
787  *p=' ';
788  p++;
789  *p=' ';
790  }
791 
793  free(dup);
794  return dup2;
795 }
796 
797 static void
798 TabbingBeginRow(int n, int n_total, char *align)
799 /******************************************************************************
800  purpose: emit RTF to start one row of a tabbing environment
801  ******************************************************************************/
802 {
803  int i;
804 
805  if (n==0) return;
806 
807  fprintRTF("\\trowd");
808 
809  for(i=0; i<n; i++)
810  fprintRTF("\\cellx%d", TabbingColumnPosition(i,n_total));
811 
812  fprintRTF("\n");
813  for(i=0; i<g_tabbing_left_position; i++) {
814  BeginCell(align[i]);
815  EndCell();
816  }
817 
818 }
819 
820 static void
821 TabbingWriteRow(char *this_row, int n, int n_total, char *align)
822 {
823  char *start, *end, *cell;
824  int i;
825 
826  if (this_row==NULL || n==0) return;
827 
828  diagnostics(4, "TabbingWriteRow n=%d <%s> [%s]",n, align, this_row);
829  if (strstr(this_row,"\\kill")) return;
830 
831  TabbingBeginRow(n, n_total, align);
832 
833  start=this_row;
834  end=this_row+strlen(this_row);
835 
836  for(i=g_tabbing_left_position; i<n; i++) {
837  BeginCell(align[i]);
839  if (cell) {
840  diagnostics(4,"cell=<%s>",cell);
842  free(cell);
843  }
844  EndCell();
845  start=end;
846  }
847  fprintRTF("\\row\n");
848 }
849 
850 static void
851 TabbingGetRow(char *table, char **row, char **next_row)
852 /******************************************************************************
853  purpose: scan and duplicate the next row from the tabbing environment
854  ******************************************************************************/
855 {
856  char *s,*arow;
857  size_t row_chars=0;
858  bool slash = FALSE;
859 
860  s=table;
861  *row=NULL;
862  *next_row=NULL;
863 
864  if (!s) return;
865 
866  /* the end of a row is caused by one of three things
867  1) the buffer ends
868  2) the line ends \\
869  3) \kill is encountered */
870  while (!(*s == '\0') &&
871  !(*s == '\\' && slash) &&
872  !((row_chars>6) && strncmp(s-5,"\\kill",5) == 0 && !isalpha((int) *s))
873  ) {
874  row_chars++;
875  slash = (*s == '\\') ? 1 : 0;
876  s++;
877  }
878 
879  if (*s != '\0') *next_row = s+1;
880  if (*s == '\\' && slash) row_chars--;
881 
882  arow = (char *)malloc((row_chars+1)*sizeof(char));
883  strncpy(arow, table, row_chars);
884  arow[row_chars]='\0';
885 
886  *row = strdup_noendblanks(arow);
887  free(arow);
888 }
889 
890 static void
891 TabbingGetColumnAlignments(char* row, char *align, int *n, int *next_left)
892 /******************************************************************************
893  purpose: scan one row of tabbing environment to obtain column alignments
894  ******************************************************************************/
895 {
896  int i;
897 
898  *next_left = g_tabbing_left_position;
899  *n = *next_left+1;
900 
901  for (i=0; i<*n; i++) align[i]='l';
902 
903  while (row && *row) {
904 
905  if (*row != '\\') {row++; continue;}
906 
907  row++;
908  switch (*row) {
909 
910  case '=' : align[*n]='l';
911  (*n)++;
912  break;
913 
914  case '>' : align[*n]='l';
915  (*n)++;
916  break;
917 
918  case '<' : break;
919 
920  case '\'' : align[*n-2]='r';
921  align[*n-1]='l';
922  break;
923 
924  case '`' : align[*n]='r';
925  (*n)++;
926  break;
927 
928  case '+' : (*next_left)++;
929  break;
930 
931  case '-' : (*next_left)--;
932  break;
933 
934  default: break;
935  }
936  }
937  align[*n]='\0';
938 
939 }
940 
941 
942 void
944 /******************************************************************************
945  purpose: \begin{tabbing} ... \end{tabbing}
946  ******************************************************************************/
947 {
948  int n,n_total,next_left;
949  char *end,*this_row, *next_row_start, *row_start;
950  char *table=NULL;
951  char align[31];
952 
953  if (!(code & ON)) {
954  diagnostics(4, "Exiting CmdTabbing");
956  if (colFmt) free(colFmt);
957  colFmt=NULL;
958  return;
959  }
960 
962  n=0;
964  strcpy(align,"l");
965 
966  end = strdup("\\end{tabbing}");
968  diagnostics(3, "Entering CmdTabbing()");
969 
970  row_start=table;
971  TabbingGetRow(row_start, &this_row, &next_row_start);
972 
973  diagnostics(2, "tabbing_tabbing_tabbing\n%s\ntabbing_tabbing_tabbing",table);
974 
975  if (GetTexMode() != MODE_HORIZONTAL){
978  }
979 
980  fprintRTF("\\par\n");
981 
982  n_total=0;
983  while (this_row && strlen(this_row)>0) {
984  diagnostics(4,"row=<%s>",this_row);
985 
986  TabbingGetColumnAlignments(this_row, align, &n, &next_left);
987  if (n>n_total) n_total=n;
988 
989  diagnostics(4,"this row n=%d <%s> left_tab=%d",n,align,g_tabbing_left_position);
990 
991  TabbingWriteRow(this_row, n, n_total, align);
992 
993  g_tabbing_left_position=next_left;
994  row_start=next_row_start;
995 
996  free(this_row);
997  TabbingGetRow(row_start, &this_row, &next_row_start);
998  }
999 
1000  ConvertString(end);
1001 
1002  free(table);
1003  free(end);
1004 }
1005 
1006 void
1008 /******************************************************************************
1009  purpose: converts the LaTex-Table to a similar Rtf-style
1010  this converting is only partially
1011  so the user has to convert some part of the Table-environment by hand
1012 parameter: type of array-environment
1013  ******************************************************************************/
1014 {
1015  char *location, *table_contents;
1016  char endtable[] = "\\end{table}";
1017 
1018  if (code & ON) {
1019 
1021  if (location) free(location);
1022 
1025 
1027  table_contents = getTexUntil(endtable, TRUE);
1028  g_table_label = ExtractLabelTag(table_contents);
1029  ConvertString(table_contents);
1030  ConvertString(endtable);
1031  free(table_contents);
1032  } else {
1036  }
1037 }
1038 
1039 void
1041 /******************************************************************************
1042  purpose: handles \multicolumn{n}{format}{content}
1043  ******************************************************************************/
1044 {
1045  long numCol, i;
1046  char *num, *format, *content, *bcontent;
1047 
1048  num = getBraceParam();
1049  format = getBraceParam();
1050  bcontent = getBraceParam();
1051 
1052  content = strdup_noendblanks(bcontent);
1053  free(bcontent);
1054 
1055  diagnostics(4,"CmdMultiCol cols=%s format=<%s> content=<%s>",num,format,content);
1056  numCol = atoi(num);
1057  free(num);
1058 
1059  diagnostics(4, "Entering Convert() from CmdMultiCol()");
1061  diagnostics(4, "Exiting Convert() from CmdMultiCol()");
1062 
1063  for (i = 1; i < numCol; i++) {
1064  fprintRTF("}\\cell\n");
1065  fprintRTF("\\pard\\intbl{");
1066  }
1067 
1068  free(content);
1069 }
1070 
1071 void
1073 {
1074 /* cline and hline are already handled by tabular code
1075  here we just properly skip the commands */
1076  char *s;
1077 
1078  if (code==1) {
1079  s = getBraceParam();
1080  free(s);
1081  skipSpaces();
1082  }
1083 }
#define strdup
Definition: Utility.h:167
struct @88 table[500]
#define width(a)
Definition: aptex-macros.h:198
#define height(a)
Definition: aptex-macros.h:200
static int column
Definition: backend_svg.c:38
#define n
Definition: t4ht.c:1290
#define MODE_HORIZONTAL
Definition: convert.h:2
#define MODE_VERTICAL
Definition: convert.h:6
@ FALSE
Definition: dd.h:101
@ TRUE
Definition: dd.h:102
#define free(a)
Definition: decNumber.cpp:310
char * strncpy()
char * strcpy()
void CmdIndent(int code)
Definition: funct1.c:339
void CmdEndParagraph(int code)
Definition: funct1.c:146
void CmdStartParagraph(int code)
Definition: funct1.c:65
#define FIRST_PAR
Definition: funct1.h:40
#define INDENT_NONE
Definition: funct1.h:44
#define s
Definition: afcover.h:80
#define t
Definition: afcover.h:96
static FIELD_PTR begin
Definition: genind.c:37
#define strchr
Definition: gsftopk.c:59
#define NULL
Definition: ftobjs.h:61
small capitals from c petite p
Definition: afcover.h:72
small capitals from c petite p scientific i
Definition: afcover.h:80
@ right
Definition: annotate.c:15
int int double double double char double char * top
Definition: gdfx.h:19
int int double double double char double char char * bottom
Definition: gdfx.h:20
voidp calloc()
int atoi(const char *)
int num
Definition: disdvi.c:621
char * strstr()
#define dup2
Definition: win32lib.h:67
static const char * tab[]
Definition: xdirtest.c:23
void ConvertString(char *string)
Definition: convert.c:103
int GetTexMode(void)
Definition: convert.c:97
void diagnostics(int level, char *format,...)
Definition: main.c:469
void fprintRTF(char *format,...)
Definition: main.c:722
void putRtfChar(char cThis)
Definition: main.c:703
#define WARNING__
Definition: main.h:32
char * g_table_label
Definition: xref.c:40
int PushSource(char *filename, char *string)
Definition: parser.c:139
void PopSource(void)
Definition: parser.c:243
#define TABULAR
Definition: tables.h:4
#define TABULAR_LONG_STAR
Definition: tables.h:7
#define TABULAR_STAR
Definition: tables.h:5
#define TABULAR_LONG
Definition: tables.h:6
#define malloc
Definition: alloca.c:91
int dup()
int strncmp()
int TexFontNumber(char *Fname)
Definition: l2r_fonts.c:123
void skipSpaces(void)
char * getTexUntil(char *target, int raw)
char * getBraceParam(void)
char * getBracketParam(void)
int getDimension(void)
int getLength(char *s)
Definition: lengths.c:99
struct cell_struct cell
const int * pos
Definition: combiners.h:905
float x
Definition: cordic.py:15
#define align(x, k)
Definition: obcommon.h:49
static int format
Definition: pbmclean.c:15
static int cols
Definition: pbmmask.c:21
int columns
Definition: pbmpscale.c:13
static int row
Definition: ps2pk.c:587
#define isalpha(ch)
Definition: utype.h:82
lft_cell * left
Definition: routines.h:73
int * width
Definition: tables.c:44
int * cline
Definition: tables.c:45
int n
Definition: tables.c:39
char * align
Definition: tables.c:40
int * vert
Definition: tables.c:41
Definition: inftrees.h:24
Definition: ttf.h:33
Definition: dvips.h:235
Definition: table.h:30
pointer location
Definition: t1imager.h:35
*job_name strlen((char *) job_name) - 4)
char * colFmt
Definition: tables.c:62
static void TabbingNextCellEnd(char *t, char **cell_end, char **next_cell)
Definition: tables.c:739
int actCol
Definition: tables.c:61
static void TabbingGetRow(char *table, char **row, char **next_row)
Definition: tables.c:851
static void TabbingWriteRow(char *this_row, int n, int n_total, char *align)
Definition: tables.c:821
void CmdTabbing(int code)
Definition: tables.c:943
bool tabbing_on_itself
Definition: tables.c:54
void CmdHline(int code)
Definition: tables.c:1072
int colCount
Definition: tables.c:60
char * TabularCline(char *row, int columns)
Definition: tables.c:410
static void TabularMultiParameters(char *cell, int *col_span, char *align, int *lvert, int *rvert)
Definition: tables.c:347
static char * ConvertFormatString(char *s)
Definition: tables.c:92
int g_tabbing_current_position
Definition: tables.c:49
static void TabbingGetColumnAlignments(char *row, char *align, int *n, int *next_left)
Definition: tables.c:891
void CmdTabular(int code)
Definition: tables.c:607
static void TabularGetRow(char *table, char **row, char **next_row, int *height)
Definition: tables.c:221
static char * TabularNextAmpersand(char *t)
Definition: tables.c:305
int * g_tabbing_locations
Definition: tables.c:50
static TabularT TabularPreamble(char *text, char *width, char *pos, char *cols)
Definition: tables.c:189
static void TabularBeginRow(TabularT tabular, char *this_row, char *next_row, int first_row)
Definition: tables.c:466
void CmdTabjump(void)
Definition: tables.c:64
void CmdTable(int code)
Definition: tables.c:1007
static int TabbingColumnPosition(int n, int total)
Definition: tables.c:729
static void TabbingBeginRow(int n, int n_total, char *align)
Definition: tables.c:798
static void BeginCell(char align)
Definition: tables.c:74
char TabularColumnAlignment(int column)
Definition: tables.c:544
bool g_processing_tabular
Definition: tables.c:57
bool g_processing_table
Definition: tables.c:58
static char * TabularNextCell(char *cell_start, char **cell_end)
Definition: tables.c:323
static char * TabbingNextCell(char *cell_start, char **cell_end)
Definition: tables.c:768
bool g_processing_tabbing
Definition: tables.c:56
static void TabularCountVert(char *s, int vert[])
Definition: tables.c:152
static void EndCell(void)
Definition: tables.c:83
static void TabularEndRow(void)
Definition: tables.c:535
bool tabbing_return
Definition: tables.c:53
int g_tabbing_left_position
Definition: tables.c:48
int tabcounter
Definition: tables.c:52
static int TabularHline(char *row)
Definition: tables.c:392
struct TabularT TabularT
static void TabularWriteRow(TabularT tabular, char *this_row, char *next_row, int height, int first_row)
Definition: tables.c:553
static int TabularColumnPosition(int n)
Definition: tables.c:142
long pos_begin_kill
Definition: tables.c:55
void CmdTabset(void)
Definition: tables.c:69
void CmdMultiCol(int code)
Definition: tables.c:1040
static int braces
Definition: tex2xindy.c:663
m
Definition: tex4ht.c:3990
return() int(((double) *(font_tbl[cur_fnt].wtbl+(int)(*(font_tbl[cur_fnt].char_wi+(int)(ch - font_tbl[cur_fnt].char_f)% 256)))/(double)(1L<< 20)) *(double) font_tbl[cur_fnt].scale)
char * my_strndup(char *src, size_t n)
Definition: util.c:79
char * strdup_noendblanks(char *s)
Definition: util.c:190
char * ExtractLabelTag(char *text)
Definition: util.c:211
int strstr_count(char *s, char *t)
Definition: util.c:52
char * strdup_together(char *s, char *t)
Definition: util.c:95
@ ON
Definition: ubidiimp.h:55
@ start
Definition: preamble.c:52
static char cline[28][256]
Definition: preamble.c:81
#define end(cp)
Definition: zic.c:71