1114402Sru// -*- C++ -*-
2151497Sru/* Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
3114402Sru *
4114402Sru *  Gaius Mulley (gaius@glam.ac.uk) wrote html-table.cpp
5114402Sru *
6114402Sru *  html-table.h
7114402Sru *
8114402Sru *  provides the methods necessary to handle indentation and tab
9114402Sru *  positions using html tables.
10114402Sru */
11114402Sru
12114402Sru/*
13114402SruThis file is part of groff.
14114402Sru
15114402Srugroff is free software; you can redistribute it and/or modify it under
16114402Sruthe terms of the GNU General Public License as published by the Free
17114402SruSoftware Foundation; either version 2, or (at your option) any later
18114402Sruversion.
19114402Sru
20114402Srugroff is distributed in the hope that it will be useful, but WITHOUT ANY
21114402SruWARRANTY; without even the implied warranty of MERCHANTABILITY or
22114402SruFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
23114402Srufor more details.
24114402Sru
25114402SruYou should have received a copy of the GNU General Public License along
26114402Sruwith groff; see the file COPYING.  If not, write to the Free Software
27151497SruFoundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */
28114402Sru
29114402Sru#include "driver.h"
30114402Sru#include "stringclass.h"
31114402Sru#include "cset.h"
32114402Sru#include "html-table.h"
33114402Sru#include "ctype.h"
34114402Sru#include "html.h"
35151497Sru#include "html-text.h"
36114402Sru
37114402Sru#if !defined(TRUE)
38114402Sru#   define TRUE  (1==1)
39114402Sru#endif
40114402Sru#if !defined(FALSE)
41114402Sru#   define FALSE (1==0)
42114402Sru#endif
43114402Sru
44114402Srutabs::tabs ()
45114402Sru  : tab(NULL)
46114402Sru{
47114402Sru}
48114402Sru
49114402Srutabs::~tabs ()
50114402Sru{
51114402Sru  delete_list();
52114402Sru}
53114402Sru
54114402Sru/*
55114402Sru *  delete_list - frees the tab list and sets tab to NULL.
56114402Sru */
57114402Sru
58114402Sruvoid tabs::delete_list (void)
59114402Sru{
60114402Sru  tab_position *p = tab;
61114402Sru  tab_position *q;
62114402Sru
63114402Sru  while (p != NULL) {
64114402Sru    q = p;
65114402Sru    p = p->next;
66151497Sru    delete q;
67114402Sru  }
68114402Sru  tab = NULL;
69114402Sru}
70114402Sru
71114402Sruvoid tabs::clear (void)
72114402Sru{
73114402Sru  delete_list();
74114402Sru}
75114402Sru
76114402Sru/*
77114402Sru *  compatible - returns TRUE if the tab stops in, s, do
78114402Sru *               not conflict with the current tab stops.
79114402Sru *               The new tab stops are _not_ placed into
80114402Sru *               this class.
81114402Sru */
82114402Sru
83114402Sruint tabs::compatible (const char *s)
84114402Sru{
85114402Sru  char align;
86114402Sru  int  total=0;
87114402Sru  tab_position *last = tab;
88114402Sru
89114402Sru  if (last == NULL)
90114402Sru    return FALSE;  // no tab stops defined
91114402Sru
92114402Sru  // move over tag name
93114402Sru  while ((*s != (char)0) && !isspace(*s))
94114402Sru    s++;
95114402Sru
96114402Sru  while (*s != (char)0 && last != NULL) {
97114402Sru    // move over white space
98114402Sru    while ((*s != (char)0) && isspace(*s))
99114402Sru      s++;
100114402Sru    // collect alignment
101114402Sru    align = *s;
102114402Sru    // move over alignment
103114402Sru    s++;
104114402Sru    // move over white space
105114402Sru    while ((*s != (char)0) && isspace(*s))
106114402Sru      s++;
107114402Sru    // collect tab position
108151497Sru    total = atoi(s);
109114402Sru    // move over tab position
110114402Sru    while ((*s != (char)0) && !isspace(*s))
111114402Sru      s++;
112114402Sru    if (last->alignment != align || last->position != total)
113114402Sru      return FALSE;
114114402Sru
115114402Sru    last = last->next;
116114402Sru  }
117114402Sru  return TRUE;
118114402Sru}
119114402Sru
120114402Sru/*
121114402Sru *  init - scans the string, s, and initializes the tab stops.
122114402Sru */
123114402Sru
124114402Sruvoid tabs::init (const char *s)
125114402Sru{
126114402Sru  char align;
127114402Sru  int  total=0;
128114402Sru  tab_position *last = NULL;
129114402Sru
130114402Sru  clear(); // remove any tab stops
131114402Sru
132114402Sru  // move over tag name
133114402Sru  while ((*s != (char)0) && !isspace(*s))
134114402Sru    s++;
135114402Sru
136114402Sru  while (*s != (char)0) {
137114402Sru    // move over white space
138114402Sru    while ((*s != (char)0) && isspace(*s))
139114402Sru      s++;
140114402Sru    // collect alignment
141114402Sru    align = *s;
142114402Sru    // move over alignment
143114402Sru    s++;
144114402Sru    // move over white space
145114402Sru    while ((*s != (char)0) && isspace(*s))
146114402Sru      s++;
147114402Sru    // collect tab position
148114402Sru    total = atoi(s);
149114402Sru    // move over tab position
150114402Sru    while ((*s != (char)0) && !isspace(*s))
151114402Sru      s++;
152114402Sru    if (last == NULL) {
153151497Sru      tab = new tab_position;
154114402Sru      last = tab;
155114402Sru    } else {
156151497Sru      last->next = new tab_position;
157114402Sru      last = last->next;
158114402Sru    }
159114402Sru    last->alignment = align;
160114402Sru    last->position = total;
161114402Sru    last->next = NULL;
162114402Sru  }
163114402Sru}
164114402Sru
165114402Sru/*
166151497Sru *  check_init - define tab stops using, s, providing none already exist.
167151497Sru */
168151497Sru
169151497Sruvoid tabs::check_init (const char *s)
170151497Sru{
171151497Sru  if (tab == NULL)
172151497Sru    init(s);
173151497Sru}
174151497Sru
175151497Sru/*
176114402Sru *  find_tab - returns the tab number corresponding to the position, pos.
177114402Sru */
178114402Sru
179114402Sruint tabs::find_tab (int pos)
180114402Sru{
181114402Sru  tab_position *p;
182114402Sru  int i=0;
183114402Sru
184114402Sru  for (p = tab; p != NULL; p = p->next) {
185114402Sru    i++;
186114402Sru    if (p->position == pos)
187114402Sru      return i;
188114402Sru  }
189114402Sru  return 0;
190114402Sru}
191114402Sru
192114402Sru/*
193114402Sru *  get_tab_pos - returns the, nth, tab position
194114402Sru */
195114402Sru
196114402Sruint tabs::get_tab_pos (int n)
197114402Sru{
198114402Sru  tab_position *p;
199114402Sru
200114402Sru  n--;
201114402Sru  for (p = tab; (p != NULL) && (n>0); p = p->next) {
202114402Sru    n--;
203114402Sru    if (n == 0)
204114402Sru      return p->position;
205114402Sru  }
206114402Sru  return 0;
207114402Sru}
208114402Sru
209114402Sruchar tabs::get_tab_align (int n)
210114402Sru{
211114402Sru  tab_position *p;
212114402Sru
213114402Sru  n--;
214114402Sru  for (p = tab; (p != NULL) && (n>0); p = p->next) {
215114402Sru    n--;
216114402Sru    if (n == 0)
217114402Sru      return p->alignment;
218114402Sru  }
219114402Sru  return 'L';
220114402Sru}
221114402Sru
222114402Sru/*
223114402Sru *  dump_tab - display tab positions
224114402Sru */
225114402Sru
226114402Sruvoid tabs::dump_tabs (void)
227114402Sru{
228114402Sru  int i=1;
229114402Sru  tab_position *p;
230114402Sru
231114402Sru  for (p = tab; p != NULL; p = p->next) {
232114402Sru    printf("tab %d is %d\n", i, p->position);
233114402Sru    i++;
234114402Sru  }
235114402Sru}
236114402Sru
237114402Sru/*
238114402Sru *  html_table - methods
239114402Sru */
240114402Sru
241114402Sruhtml_table::html_table (simple_output *op, int linelen)
242151497Sru  : out(op), columns(NULL), linelength(linelen), last_col(NULL), start_space(FALSE)
243114402Sru{
244114402Sru  tab_stops = new tabs();
245114402Sru}
246114402Sru
247114402Sruhtml_table::~html_table ()
248114402Sru{
249114402Sru  cols *c;
250114402Sru  if (tab_stops != NULL)
251114402Sru    delete tab_stops;
252114402Sru
253114402Sru  c = columns;
254114402Sru  while (columns != NULL) {
255114402Sru    columns = columns->next;
256151497Sru    delete c;
257114402Sru    c = columns;
258114402Sru  }
259114402Sru}
260114402Sru
261114402Sru/*
262114402Sru *  remove_cols - remove a list of columns as defined by, c.
263114402Sru */
264114402Sru
265114402Sruvoid html_table::remove_cols (cols *c)
266114402Sru{
267114402Sru  cols *p;
268114402Sru
269114402Sru  while (c != NULL) {
270114402Sru    p = c;
271114402Sru    c = c->next;
272151497Sru    delete p;
273114402Sru  }
274114402Sru}
275114402Sru
276114402Sru/*
277114402Sru *  set_linelength - sets the line length value in this table.
278114402Sru *                   It also adds an extra blank column to the
279114402Sru *                   table should linelen exceed the last column.
280114402Sru */
281114402Sru
282114402Sruvoid html_table::set_linelength (int linelen)
283114402Sru{
284114402Sru  cols *p = NULL;
285114402Sru  cols *c;
286114402Sru  linelength = linelen;
287114402Sru
288114402Sru  for (c = columns; c != NULL; c = c->next) {
289114402Sru    if (c->right > linelength) {
290114402Sru      c->right = linelength;
291114402Sru      remove_cols(c->next);
292114402Sru      c->next = NULL;
293114402Sru      return;
294114402Sru    }
295114402Sru    p = c;
296114402Sru  }
297114402Sru  if (p != NULL && p->right > 0)
298114402Sru    add_column(p->no+1, p->right, linelength, 'L');
299114402Sru}
300114402Sru
301114402Sru/*
302114402Sru *  get_effective_linelength -
303114402Sru */
304114402Sru
305114402Sruint html_table::get_effective_linelength (void)
306114402Sru{
307114402Sru  if (columns != NULL)
308114402Sru    return linelength - columns->left;
309114402Sru  else
310114402Sru    return linelength;
311114402Sru}
312114402Sru
313114402Sru/*
314114402Sru *  add_indent - adds the indent to a table.
315114402Sru */
316114402Sru
317114402Sruvoid html_table::add_indent (int indent)
318114402Sru{
319114402Sru  if (columns != NULL && columns->left > indent)
320114402Sru    add_column(0, indent, columns->left, 'L');
321114402Sru}
322114402Sru
323114402Sru/*
324114402Sru *  emit_table_header - emits the html header for this table.
325114402Sru */
326114402Sru
327114402Sruvoid html_table::emit_table_header (int space)
328114402Sru{
329114402Sru  if (columns == NULL)
330114402Sru    return;
331114402Sru
332114402Sru  // dump_table();
333114402Sru
334114402Sru  last_col = NULL;
335114402Sru  if (linelength > 0) {
336114402Sru    out->nl();
337114402Sru    out->nl();
338151497Sru
339151497Sru    out->put_string("<table width=\"100%\"")
340151497Sru      .put_string(" border=0 rules=\"none\" frame=\"void\"\n")
341151497Sru      .put_string("       cellspacing=\"0\" cellpadding=\"0\"");
342151497Sru    out->put_string(">")
343151497Sru      .nl();
344151497Sru    out->put_string("<tr valign=\"top\" align=\"left\"");
345151497Sru    if (space) {
346151497Sru      out->put_string(" style=\"margin-top: ");
347151497Sru      out->put_string(STYLE_VERTICAL_SPACE);
348151497Sru      out->put_string("\"");
349151497Sru    }
350151497Sru    out->put_string(">").nl();
351114402Sru  }
352114402Sru}
353114402Sru
354114402Sru/*
355114402Sru *  get_right - returns the right most position of this column.
356114402Sru */
357114402Sru
358114402Sruint html_table::get_right (cols *c)
359114402Sru{
360114402Sru  if (c != NULL && c->right > 0)
361114402Sru    return c->right;
362114402Sru  if (c->next != NULL)
363114402Sru    return c->left;
364114402Sru  return linelength;
365114402Sru}
366114402Sru
367114402Sru/*
368151497Sru *  set_space - assigns start_space. Used to determine the
369151497Sru *              vertical alignment when generating the next table row.
370151497Sru */
371151497Sru
372151497Sruvoid html_table::set_space (int space)
373151497Sru{
374151497Sru  start_space = space;
375151497Sru}
376151497Sru
377151497Sru/*
378114402Sru *  emit_col - moves onto column, n.
379114402Sru */
380114402Sru
381114402Sruvoid html_table::emit_col (int n)
382114402Sru{
383114402Sru  cols *c = columns;
384114402Sru  cols *b = columns;
385114402Sru  int   width = 0;
386114402Sru
387114402Sru  // must be a different row
388114402Sru  if (last_col != NULL && n <= last_col->no)
389114402Sru    emit_new_row();
390114402Sru
391114402Sru  while (c != NULL && c->no < n)
392114402Sru    c = c->next;
393114402Sru
394114402Sru  // can we find column, n?
395114402Sru  if (c != NULL && c->no == n) {
396114402Sru    // shutdown previous column
397114402Sru    if (last_col != NULL)
398114402Sru      out->put_string("</td>").nl();
399114402Sru
400114402Sru    // find previous column
401114402Sru    if (last_col == NULL)
402114402Sru      b = columns;
403114402Sru    else
404114402Sru      b = last_col;
405114402Sru
406114402Sru    // have we a gap?
407114402Sru    if (last_col != NULL) {
408114402Sru      if (is_gap(b))
409114402Sru	out->put_string("<td width=\"")
410114402Sru	    .put_number(is_gap(b))
411114402Sru	    .put_string("%\"></td>")
412114402Sru	    .nl();
413114402Sru      b = b->next;
414114402Sru    }
415114402Sru
416114402Sru    // move across to column n
417114402Sru    while (b != c) {
418114402Sru      // we compute the difference after converting positions
419114402Sru      // to avoid rounding errors
420114402Sru      width = (get_right(b)*100 + get_effective_linelength()/2)
421114402Sru		/ get_effective_linelength()
422114402Sru	      - (b->left*100 + get_effective_linelength()/2)
423114402Sru		  /get_effective_linelength();
424114402Sru      if (width)
425114402Sru	out->put_string("<td width=\"")
426114402Sru	    .put_number(width)
427114402Sru	    .put_string("%\"></td>")
428114402Sru	    .nl();
429114402Sru      // have we a gap?
430114402Sru      if (is_gap(b))
431114402Sru	out->put_string("<td width=\"")
432114402Sru	    .put_number(is_gap(b))
433114402Sru	    .put_string("%\"></td>")
434114402Sru	    .nl();
435114402Sru      b = b->next;
436114402Sru    }
437114402Sru    width = (get_right(b)*100 + get_effective_linelength()/2)
438114402Sru	      / get_effective_linelength()
439114402Sru	    - (b->left*100 + get_effective_linelength()/2)
440114402Sru		/get_effective_linelength();
441114402Sru    switch (b->alignment) {
442114402Sru    case 'C':
443114402Sru      out->put_string("<td width=\"")
444114402Sru	  .put_number(width)
445114402Sru	  .put_string("%\" align=center>")
446114402Sru	  .nl();
447114402Sru      break;
448114402Sru    case 'R':
449114402Sru      out->put_string("<td width=\"")
450114402Sru	  .put_number(width)
451114402Sru	  .put_string("%\" align=right>")
452114402Sru	  .nl();
453114402Sru      break;
454114402Sru    default:
455114402Sru      out->put_string("<td width=\"")
456114402Sru	  .put_number(width)
457114402Sru	  .put_string("%\">")
458114402Sru	  .nl();
459114402Sru    }
460114402Sru    // remember column, b
461114402Sru    last_col = b;
462114402Sru  }
463114402Sru}
464114402Sru
465114402Sru/*
466114402Sru *  finish_row -
467114402Sru */
468114402Sru
469114402Sruvoid html_table::finish_row (void)
470114402Sru{
471114402Sru  int n = 0;
472114402Sru  cols *c;
473114402Sru
474114402Sru  if (last_col != NULL) {
475114402Sru    for (c = last_col->next; c != NULL; c = c->next)
476114402Sru      n = c->no;
477114402Sru
478114402Sru    if (n > 0)
479114402Sru      emit_col(n);
480114402Sru    out->put_string("</td>").nl();
481114402Sru  }
482114402Sru}
483114402Sru
484114402Sru/*
485114402Sru *  emit_new_row - move to the next row.
486114402Sru */
487114402Sru
488114402Sruvoid html_table::emit_new_row (void)
489114402Sru{
490114402Sru  finish_row();
491151497Sru
492151497Sru  out->put_string("<tr valign=\"top\" align=\"left\"");
493151497Sru  if (start_space) {
494151497Sru    out->put_string(" style=\"margin-top: ");
495151497Sru    out->put_string(STYLE_VERTICAL_SPACE);
496151497Sru    out->put_string("\"");
497151497Sru  }
498151497Sru  out->put_string(">").nl();
499151497Sru  start_space = FALSE;
500114402Sru  last_col = NULL;
501114402Sru}
502114402Sru
503114402Sruvoid html_table::emit_finish_table (void)
504114402Sru{
505114402Sru  finish_row();
506114402Sru  out->put_string("</table>");
507114402Sru}
508114402Sru
509114402Sru/*
510114402Sru *  add_column - adds a column. It returns FALSE if hstart..hend
511114402Sru *               crosses into a different columns.
512114402Sru */
513114402Sru
514114402Sruint html_table::add_column (int coln, int hstart, int hend, char align)
515114402Sru{
516114402Sru  cols *c = get_column(coln);
517114402Sru
518114402Sru  if (c == NULL)
519114402Sru    return insert_column(coln, hstart, hend, align);
520114402Sru  else
521114402Sru    return modify_column(c, hstart, hend, align);
522114402Sru}
523114402Sru
524114402Sru/*
525114402Sru *  get_column - returns the column, coln.
526114402Sru */
527114402Sru
528114402Srucols *html_table::get_column (int coln)
529114402Sru{
530114402Sru  cols *c = columns;
531114402Sru
532114402Sru  while (c != NULL && coln != c->no)
533114402Sru    c = c->next;
534114402Sru
535114402Sru  if (c != NULL && coln == c->no)
536114402Sru    return c;
537114402Sru  else
538114402Sru    return NULL;
539114402Sru}
540114402Sru
541114402Sru/*
542114402Sru *  insert_column - inserts a column, coln.
543114402Sru *                  It returns TRUE if it does not bump into
544114402Sru *                  another column.
545114402Sru */
546114402Sru
547114402Sruint html_table::insert_column (int coln, int hstart, int hend, char align)
548114402Sru{
549114402Sru  cols *c = columns;
550151497Sru  cols *l = columns;
551114402Sru  cols *n = NULL;
552114402Sru
553114402Sru  while (c != NULL && c->no < coln) {
554114402Sru    l = c;
555114402Sru    c = c->next;
556114402Sru  }
557151497Sru  if (l != NULL && l->no>coln && hend > l->left)
558151497Sru    return FALSE;	// new column bumps into previous one
559151497Sru
560151497Sru  l = NULL;
561151497Sru  c = columns;
562151497Sru  while (c != NULL && c->no < coln) {
563151497Sru    l = c;
564151497Sru    c = c->next;
565151497Sru  }
566151497Sru
567114402Sru  if ((l != NULL) && (hstart < l->right))
568114402Sru    return FALSE;	// new column bumps into previous one
569114402Sru
570114402Sru  if ((l != NULL) && (l->next != NULL) &&
571114402Sru      (l->next->left < hend))
572114402Sru    return FALSE;  // new column bumps into next one
573114402Sru
574151497Sru  n = new cols;
575114402Sru  if (l == NULL) {
576114402Sru    n->next = columns;
577114402Sru    columns = n;
578114402Sru  } else {
579114402Sru    n->next = l->next;
580114402Sru    l->next = n;
581114402Sru  }
582114402Sru  n->left = hstart;
583114402Sru  n->right = hend;
584114402Sru  n->no = coln;
585114402Sru  n->alignment = align;
586114402Sru  return TRUE;
587114402Sru}
588114402Sru
589114402Sru/*
590114402Sru *  modify_column - given a column, c, modify the width to
591114402Sru *                  contain hstart..hend.
592114402Sru *                  It returns TRUE if it does not clash with
593114402Sru *                  the next or previous column.
594114402Sru */
595114402Sru
596114402Sruint html_table::modify_column (cols *c, int hstart, int hend, char align)
597114402Sru{
598114402Sru  cols *l = columns;
599114402Sru
600114402Sru  while (l != NULL && l->next != c)
601114402Sru    l = l->next;
602114402Sru
603114402Sru  if ((l != NULL) && (hstart < l->right))
604114402Sru    return FALSE;	// new column bumps into previous one
605114402Sru
606114402Sru  if ((c->next != NULL) && (c->next->left < hend))
607114402Sru    return FALSE;  // new column bumps into next one
608114402Sru
609114402Sru  if (c->left > hstart)
610114402Sru    c->left = hstart;
611114402Sru
612114402Sru  if (c->right < hend)
613114402Sru    c->right = hend;
614114402Sru
615114402Sru  c->alignment = align;
616114402Sru
617114402Sru  return TRUE;
618114402Sru}
619114402Sru
620114402Sru/*
621114402Sru *  find_tab_column - finds the column number for position, pos.
622114402Sru *                    It searches through the list tab stops.
623114402Sru */
624114402Sru
625114402Sruint html_table::find_tab_column (int pos)
626114402Sru{
627114402Sru  // remember the first column is reserved for untabbed glyphs
628114402Sru  return tab_stops->find_tab(pos)+1;
629114402Sru}
630114402Sru
631114402Sru/*
632114402Sru *  find_column - find the column number for position, pos.
633114402Sru *                It searches through the list of columns.
634114402Sru */
635114402Sru
636114402Sruint html_table::find_column (int pos)
637114402Sru{
638114402Sru  int   p=0;
639114402Sru  cols *c;
640114402Sru
641114402Sru  for (c = columns; c != NULL; c = c->next) {
642114402Sru    if (c->left > pos)
643114402Sru      return p;
644114402Sru    p = c->no;
645114402Sru  }
646114402Sru  return p;
647114402Sru}
648114402Sru
649114402Sru/*
650114402Sru *  no_columns - returns the number of table columns (rather than tabs)
651114402Sru */
652114402Sru
653114402Sruint html_table::no_columns (void)
654114402Sru{
655114402Sru  int n=0;
656114402Sru  cols *c;
657114402Sru
658114402Sru  for (c = columns; c != NULL; c = c->next)
659114402Sru    n++;
660114402Sru  return n;
661114402Sru}
662114402Sru
663114402Sru/*
664114402Sru *  is_gap - returns the gap between column, c, and the next column.
665114402Sru */
666114402Sru
667114402Sruint html_table::is_gap (cols *c)
668114402Sru{
669114402Sru  if (c == NULL || c->right <= 0 || c->next == NULL)
670114402Sru    return 0;
671114402Sru  else
672114402Sru    // we compute the difference after converting positions
673114402Sru    // to avoid rounding errors
674114402Sru    return (c->next->left*100 + get_effective_linelength()/2)
675114402Sru	     / get_effective_linelength()
676114402Sru	   - (c->right*100 + get_effective_linelength()/2)
677114402Sru	       / get_effective_linelength();
678114402Sru}
679114402Sru
680114402Sru/*
681114402Sru *  no_gaps - returns the number of table gaps between the columns
682114402Sru */
683114402Sru
684114402Sruint html_table::no_gaps (void)
685114402Sru{
686114402Sru  int n=0;
687114402Sru  cols *c;
688114402Sru
689114402Sru  for (c = columns; c != NULL; c = c->next)
690114402Sru    if (is_gap(c))
691114402Sru      n++;
692114402Sru  return n;
693114402Sru}
694114402Sru
695114402Sru/*
696114402Sru *  get_tab_pos - returns the, nth, tab position
697114402Sru */
698114402Sru
699114402Sruint html_table::get_tab_pos (int n)
700114402Sru{
701114402Sru  return tab_stops->get_tab_pos(n);
702114402Sru}
703114402Sru
704114402Sruchar html_table::get_tab_align (int n)
705114402Sru{
706114402Sru  return tab_stops->get_tab_align(n);
707114402Sru}
708114402Sru
709114402Sru
710114402Sruvoid html_table::dump_table (void)
711114402Sru{
712114402Sru  if (columns != NULL) {
713114402Sru    cols *c;
714114402Sru    for (c = columns; c != NULL; c = c->next) {
715114402Sru      printf("column %d  %d..%d  %c\n", c->no, c->left, c->right, c->alignment);
716114402Sru    }
717114402Sru  } else
718114402Sru    tab_stops->dump_tabs();
719114402Sru}
720114402Sru
721114402Sru/*
722114402Sru *  html_indent - creates an indent with indentation, ind, given
723114402Sru *                a line length of linelength.
724114402Sru */
725114402Sru
726114402Sruhtml_indent::html_indent (simple_output *op, int ind, int pageoffset, int linelength)
727114402Sru{
728114402Sru  table = new html_table(op, linelength);
729114402Sru
730114402Sru  table->add_column(1, ind+pageoffset, linelength, 'L');
731114402Sru  table->add_indent(pageoffset);
732114402Sru  in = ind;
733114402Sru  pg = pageoffset;
734114402Sru  ll = linelength;
735114402Sru}
736114402Sru
737114402Sruhtml_indent::~html_indent (void)
738114402Sru{
739114402Sru  end();
740114402Sru  delete table;
741114402Sru}
742114402Sru
743114402Sruvoid html_indent::begin (int space)
744114402Sru{
745151497Sru  if (in + pg == 0) {
746151497Sru    if (space) {
747151497Sru      table->out->put_string(" style=\"margin-top: ");
748151497Sru      table->out->put_string(STYLE_VERTICAL_SPACE);
749151497Sru      table->out->put_string("\"");
750151497Sru    }
751114402Sru  }
752151497Sru  else {
753151497Sru    //
754151497Sru    // we use exactly the same mechanism for calculating
755151497Sru    // indentation as html_table::emit_col
756151497Sru    //
757151497Sru    table->out->put_string(" style=\"margin-left:")
758151497Sru      .put_number(((in + pg) * 100 + ll/2) / ll -
759151497Sru		  (ll/2)/ll)
760151497Sru      .put_string("%;");
761151497Sru
762151497Sru    if (space) {
763151497Sru      table->out->put_string(" margin-top: ");
764151497Sru      table->out->put_string(STYLE_VERTICAL_SPACE);
765151497Sru    }
766151497Sru    table->out->put_string("\"");
767151497Sru  }
768114402Sru}
769114402Sru
770114402Sruvoid html_indent::end (void)
771114402Sru{
772114402Sru}
773114402Sru
774114402Sru/*
775114402Sru *  get_reg - collects the registers as supplied during initialization.
776114402Sru */
777114402Sru
778114402Sruvoid html_indent::get_reg (int *ind, int *pageoffset, int *linelength)
779114402Sru{
780114402Sru  *ind = in;
781114402Sru  *pageoffset = pg;
782114402Sru  *linelength = ll;
783114402Sru}
784