LCOV - code coverage report
Current view: top level - devices/grohtml - html-table.cpp (source / functions) Hit Total Coverage
Test: GNU roff Lines: 297 407 73.0 %
Date: 2026-01-16 17:51:41 Functions: 34 43 79.1 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* Copyright (C) 2002-2025 Free Software Foundation, Inc.
       2             :  *
       3             :  *  Gaius Mulley (gaius@glam.ac.uk) wrote html-table.cpp
       4             :  *
       5             :  *  html-table.h
       6             :  *
       7             :  *  provides the methods necessary to handle indentation and tab
       8             :  *  positions using html tables.
       9             :  */
      10             : 
      11             : /*
      12             : This file is part of groff, the GNU roff typesetting system.
      13             : 
      14             : groff is free software; you can redistribute it and/or modify it under
      15             : the terms of the GNU General Public License as published by the Free
      16             : Software Foundation, either version 3 of the License, or
      17             : (at your option) any later version.
      18             : 
      19             : groff is distributed in the hope that it will be useful, but WITHOUT ANY
      20             : WARRANTY; without even the implied warranty of MERCHANTABILITY or
      21             : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      22             : for more details.
      23             : 
      24             : You should have received a copy of the GNU General Public License
      25             : along with this program.  If not, see <http://www.gnu.org/licenses/>. */
      26             : 
      27             : #ifdef HAVE_CONFIG_H
      28             : #include <config.h>
      29             : #endif
      30             : 
      31             : #include <stdio.h> // FILE
      32             : #include <stdlib.h> // atoi()
      33             : 
      34             : #include "driver.h"
      35             : #include "stringclass.h"
      36             : #include "cset.h" // csspace()
      37             : #include "html-table.h"
      38             : #include "ctype.h"
      39             : #include "html.h"
      40             : #include "html-text.h"
      41             : 
      42             : #if !defined(TRUE)
      43             : #   define TRUE  (1==1)
      44             : #endif
      45             : #if !defined(FALSE)
      46             : #   define FALSE (1==0)
      47             : #endif
      48             : 
      49             : extern html_dialect dialect;
      50             : 
      51             : 
      52         269 : tabs::tabs ()
      53         269 :   : tab(NULL)
      54             : {
      55         269 : }
      56             : 
      57         538 : tabs::~tabs ()
      58             : {
      59         269 :   delete_list();
      60         269 : }
      61             : 
      62             : /*
      63             :  *  delete_list - frees the tab list and sets tab to NULL.
      64             :  */
      65             : 
      66         288 : void tabs::delete_list (void)
      67             : {
      68         288 :   tab_position *p = tab;
      69             :   tab_position *q;
      70             : 
      71        1293 :   while (p != NULL) {
      72        1005 :     q = p;
      73        1005 :     p = p->next;
      74        1005 :     delete q;
      75             :   }
      76         288 :   tab = NULL;
      77         288 : }
      78             : 
      79          19 : void tabs::clear (void)
      80             : {
      81          19 :   delete_list();
      82          19 : }
      83             : 
      84             : /*
      85             :  *  compatible - returns TRUE if the tab stops in, s, do
      86             :  *               not conflict with the current tab stops.
      87             :  *               The new tab stops are _not_ placed into
      88             :  *               this class.
      89             :  */
      90             : 
      91          33 : int tabs::compatible (const char *s)
      92             : {
      93             :   char align;
      94          33 :   int  total=0;
      95          33 :   tab_position *last = tab;
      96             : 
      97          33 :   if (last == NULL)
      98          14 :     return FALSE;  // no tab stops defined
      99             : 
     100             :   // move over tag name
     101         209 :   while ((*s != '\0') && !csspace(*s))
     102         190 :     s++;
     103             : 
     104         270 :   while (*s != '\0' && last != NULL) {
     105             :     // move over whitespace
     106         521 :     while ((*s != '\0') && csspace(*s))
     107         270 :       s++;
     108             :     // collect alignment
     109         251 :     align = *s;
     110             :     // move over alignment
     111         251 :     s++;
     112             :     // move over whitespace
     113         502 :     while ((*s != '\0') && csspace(*s))
     114         251 :       s++;
     115             :     // collect tab position
     116         251 :     total = atoi(s);
     117             :     // move over tab position
     118        1103 :     while ((*s != '\0') && !csspace(*s))
     119         852 :       s++;
     120         251 :     if (last->alignment != align || last->position != total)
     121           0 :       return FALSE;
     122             : 
     123         251 :     last = last->next;
     124             :   }
     125          19 :   return TRUE;
     126             : }
     127             : 
     128             : /*
     129             :  *  init - scans the string, s, and initializes the tab stops.
     130             :  */
     131             : 
     132          19 : void tabs::init (const char *s)
     133             : {
     134             :   char align;
     135          19 :   int  total=0;
     136          19 :   tab_position *last = NULL;
     137             : 
     138          19 :   clear(); // remove any tab stops
     139             : 
     140             :   // move over tag name
     141         209 :   while ((*s != '\0') && !csspace(*s))
     142         190 :     s++;
     143             : 
     144        1024 :   while (*s != '\0') {
     145             :     // move over whitespace
     146        2029 :     while ((*s != '\0') && csspace(*s))
     147        1024 :       s++;
     148             :     // collect alignment
     149        1005 :     align = *s;
     150             :     // move over alignment
     151        1005 :     s++;
     152             :     // move over whitespace
     153        2010 :     while ((*s != '\0') && csspace(*s))
     154        1005 :       s++;
     155             :     // collect tab position
     156        1005 :     total = atoi(s);
     157             :     // move over tab position
     158        5341 :     while ((*s != '\0') && !csspace(*s))
     159        4336 :       s++;
     160        1005 :     if (last == NULL) {
     161          19 :       tab = new tab_position;
     162          19 :       last = tab;
     163             :     } else {
     164         986 :       last->next = new tab_position;
     165         986 :       last = last->next;
     166             :     }
     167        1005 :     last->alignment = align;
     168        1005 :     last->position = total;
     169        1005 :     last->next = NULL;
     170             :   }
     171          19 : }
     172             : 
     173             : /*
     174             :  *  check_init - define tab stops using, s, providing none already exist.
     175             :  */
     176             : 
     177           8 : void tabs::check_init (const char *s)
     178             : {
     179           8 :   if (tab == NULL)
     180           3 :     init(s);
     181           8 : }
     182             : 
     183             : /*
     184             :  *  find_tab - returns the tab number corresponding to the position, pos.
     185             :  */
     186             : 
     187           9 : int tabs::find_tab (int pos)
     188             : {
     189             :   tab_position *p;
     190           9 :   int i=0;
     191             : 
     192           9 :   for (p = tab; p != NULL; p = p->next) {
     193           2 :     i++;
     194           2 :     if (p->position == pos)
     195           2 :       return i;
     196             :   }
     197           7 :   return 0;
     198             : }
     199             : 
     200             : /*
     201             :  *  get_tab_pos - returns the, nth, tab position
     202             :  */
     203             : 
     204          11 : int tabs::get_tab_pos (int n)
     205             : {
     206             :   tab_position *p;
     207             : 
     208          11 :   n--;
     209          13 :   for (p = tab; (p != NULL) && (n>0); p = p->next) {
     210           6 :     n--;
     211           6 :     if (n == 0)
     212           4 :       return p->position;
     213             :   }
     214           7 :   return 0;
     215             : }
     216             : 
     217           0 : char tabs::get_tab_align (int n)
     218             : {
     219             :   tab_position *p;
     220             : 
     221           0 :   n--;
     222           0 :   for (p = tab; (p != NULL) && (n>0); p = p->next) {
     223           0 :     n--;
     224           0 :     if (n == 0)
     225           0 :       return p->alignment;
     226             :   }
     227           0 :   return 'L';
     228             : }
     229             : 
     230             : /*
     231             :  *  dump_tab - display tab positions
     232             :  */
     233             : 
     234           0 : void tabs::dump_tabs (void)
     235             : {
     236           0 :   int i=1;
     237             :   tab_position *p;
     238             : 
     239           0 :   for (p = tab; p != NULL; p = p->next) {
     240           0 :     printf("tab %d is %d\n", i, p->position);
     241           0 :     i++;
     242             :   }
     243           0 : }
     244             : 
     245             : /*
     246             :  *  html_table - methods
     247             :  */
     248             : 
     249         269 : html_table::html_table (simple_output *op, int linelen)
     250         269 :   : out(op), columns(NULL), linelength(linelen), last_col(NULL), start_space(FALSE)
     251             : {
     252         269 :   tab_stops = new tabs();
     253         269 : }
     254             : 
     255         538 : html_table::~html_table ()
     256             : {
     257             :   cols *c;
     258         269 :   if (tab_stops != NULL)
     259         269 :     delete tab_stops;
     260             : 
     261         269 :   c = columns;
     262         777 :   while (columns != NULL) {
     263         508 :     columns = columns->next;
     264         508 :     delete c;
     265         508 :     c = columns;
     266             :   }
     267         269 : }
     268             : 
     269             : /*
     270             :  *  remove_cols - remove a list of columns as defined by, c.
     271             :  */
     272             : 
     273          10 : void html_table::remove_cols (cols *c)
     274             : {
     275             :   cols *p;
     276             : 
     277          10 :   while (c != NULL) {
     278           0 :     p = c;
     279           0 :     c = c->next;
     280           0 :     delete p;
     281             :   }
     282          10 : }
     283             : 
     284             : /*
     285             :  *  set_linelength - sets the line length value in this table.
     286             :  *                   It also adds an extra blank column to the
     287             :  *                   table should linelen exceed the last column.
     288             :  */
     289             : 
     290          20 : void html_table::set_linelength (int linelen)
     291             : {
     292          20 :   cols *p = NULL;
     293             :   cols *c;
     294          20 :   linelength = linelen;
     295             : 
     296          38 :   for (c = columns; c != NULL; c = c->next) {
     297          28 :     if (c->right > linelength) {
     298          10 :       c->right = linelength;
     299          10 :       remove_cols(c->next);
     300          10 :       c->next = NULL;
     301          10 :       return;
     302             :     }
     303          18 :     p = c;
     304             :   }
     305          10 :   if (p != NULL && p->right > 0 && linelength > p->right)
     306           8 :     add_column(p->no+1, p->right, linelength, 'L');
     307             : }
     308             : 
     309             : /*
     310             :  *  get_effective_linelength -
     311             :  */
     312             : 
     313         532 : int html_table::get_effective_linelength (void)
     314             : {
     315         532 :   if (columns != NULL)
     316         532 :     return linelength - columns->left;
     317             :   else
     318           0 :     return linelength;
     319             : }
     320             : 
     321             : /*
     322             :  *  add_indent - adds the indent to a table.
     323             :  */
     324             : 
     325         250 : void html_table::add_indent (int indent)
     326             : {
     327         250 :   if (columns != NULL && columns->left > indent)
     328         242 :     add_column(0, indent, columns->left, 'L');
     329         250 : }
     330             : 
     331             : /*
     332             :  *  emit_table_header - emits the html header for this table.
     333             :  */
     334             : 
     335          20 : void html_table::emit_table_header (int space)
     336             : {
     337          20 :   if (columns == NULL)
     338           0 :     return;
     339             : 
     340             :   // dump_table();
     341             : 
     342          20 :   last_col = NULL;
     343          20 :   if (linelength > 0) {
     344          20 :     out->nl();
     345          20 :     out->nl();
     346             : 
     347          20 :     out->put_string("<table width=\"100%\"")
     348          20 :       .put_string(" border=\"0\" rules=\"none\" frame=\"void\"\n")
     349          20 :       .put_string("       cellspacing=\"0\" cellpadding=\"0\"");
     350          20 :     out->put_string(">")
     351          20 :       .nl();
     352          20 :     if (dialect == xhtml)
     353           0 :       emit_colspan();
     354          20 :     out->put_string("<tr valign=\"top\" align=\"left\"");
     355          20 :     if (space) {
     356           0 :       out->put_string(" style=\"margin-top: ");
     357           0 :       out->put_string(STYLE_VERTICAL_SPACE);
     358           0 :       out->put_string("\"");
     359             :     }
     360          20 :     out->put_string(">").nl();
     361             :   }
     362             : }
     363             : 
     364             : /*
     365             :  *  get_right - returns the right most position of this column.
     366             :  */
     367             : 
     368          85 : int html_table::get_right (cols *c)
     369             : {
     370          85 :   if (c != NULL && c->right > 0)
     371          78 :     return c->right;
     372           7 :   if (c->next != NULL)
     373           0 :     return c->left;
     374           7 :   return linelength;
     375             : }
     376             : 
     377             : /*
     378             :  *  set_space - assigns start_space. Used to determine the
     379             :  *              vertical alignment when generating the next table row.
     380             :  */
     381             : 
     382           0 : void html_table::set_space (int space)
     383             : {
     384           0 :   start_space = space;
     385           0 : }
     386             : 
     387             : /*
     388             :  *  emit_colspan - emits a series of colspan entries defining the
     389             :  *                 table columns.
     390             :  */
     391             : 
     392           0 : void html_table::emit_colspan (void)
     393             : {
     394           0 :   cols *b = columns;
     395           0 :   cols *c = columns;
     396           0 :   int   width = 0;
     397             : 
     398           0 :   out->put_string("<colgroup>");
     399           0 :   while (c != NULL) {
     400           0 :     if (b != NULL && b != c && is_gap(b))
     401             :       /*
     402             :        *   blank column for gap
     403             :        */
     404           0 :       out->put_string("<col width=\"")
     405           0 :         .put_number(is_gap(b))
     406           0 :         .put_string("%\" class=\"center\"></col>")
     407           0 :         .nl();
     408             : 
     409           0 :     width = (get_right(c)*100 + get_effective_linelength()/2)
     410           0 :               / get_effective_linelength()
     411           0 :              - (c->left*100 + get_effective_linelength()/2)
     412           0 :                 /get_effective_linelength();
     413           0 :     switch (c->alignment) {
     414           0 :     case 'C':
     415           0 :       out->put_string("<col width=\"")
     416           0 :           .put_number(width)
     417           0 :           .put_string("%\" class=\"center\"></col>")
     418           0 :           .nl();
     419           0 :       break;
     420           0 :     case 'R':
     421           0 :       out->put_string("<col width=\"")
     422           0 :           .put_number(width)
     423           0 :           .put_string("%\" class=\"right\"></col>")
     424           0 :           .nl();
     425           0 :       break;
     426           0 :     default:
     427           0 :       out->put_string("<col width=\"")
     428           0 :           .put_number(width)
     429           0 :           .put_string("%\"></col>")
     430           0 :           .nl();
     431             :     }
     432           0 :     b = c;
     433           0 :     c = c->next;
     434             :   }
     435           0 :   out->put_string("</colgroup>").nl();
     436           0 : }
     437             : 
     438             : /*
     439             :  *  emit_td - writes out a <td> tag with a corresponding width
     440             :  *            if the dialect is html4.
     441             :  */
     442             : 
     443         133 : void html_table::emit_td (int percentage, const char *s)
     444             : {
     445         133 :   if (percentage) {
     446         100 :     if (dialect == html4) {
     447         100 :       out->put_string("<td width=\"")
     448         100 :         .put_number(percentage)
     449         100 :         .put_string("%\"");
     450         100 :       if (s != NULL)
     451         100 :         out->put_string(s);
     452         100 :       out->nl();
     453             :     }
     454             :     else {
     455           0 :       out->put_string("<td");
     456           0 :       if (s != NULL)
     457           0 :         out->put_string(s);
     458           0 :       out->nl();
     459             :     }
     460             :   }
     461         133 : }
     462             : 
     463             : /*
     464             :  *  emit_col - moves onto column, n.
     465             :  */
     466             : 
     467          63 : void html_table::emit_col (int n)
     468             : {
     469          63 :   cols *c = columns;
     470          63 :   cols *b = columns;
     471          63 :   int   width = 0;
     472             : 
     473             :   // must be a different row
     474          63 :   if (last_col != NULL && n <= last_col->no)
     475          17 :     emit_new_row();
     476             : 
     477         122 :   while (c != NULL && c->no < n)
     478          59 :     c = c->next;
     479             : 
     480             :   // can we find column, n?
     481          63 :   if (c != NULL && c->no == n) {
     482             :     // shutdown previous column
     483          63 :     if (last_col != NULL)
     484          26 :       out->put_string("</td>").nl();
     485             : 
     486             :     // find previous column
     487          63 :     if (last_col == NULL)
     488          37 :       b = columns;
     489             :     else
     490          26 :       b = last_col;
     491             : 
     492             :     // have we a gap?
     493          63 :     if (last_col != NULL) {
     494          26 :       emit_td(is_gap(b), "></td>");
     495          26 :       b = b->next;
     496             :     }
     497             : 
     498             :     // move across to column n
     499          85 :     while (b != c) {
     500             :       // we compute the difference after converting positions
     501             :       // to avoid rounding errors
     502          22 :       width = (get_right(b)*100 + get_effective_linelength()/2)
     503          22 :                 / get_effective_linelength()
     504          22 :               - (b->left*100 + get_effective_linelength()/2)
     505          22 :                   /get_effective_linelength();
     506          22 :       emit_td(width, "></td>");
     507             :       // have we a gap?
     508          22 :       emit_td(is_gap(b), "></td>");
     509          22 :       b = b->next;
     510             :     }
     511          63 :     width = (get_right(b)*100 + get_effective_linelength()/2)
     512          63 :               / get_effective_linelength()
     513          63 :             - (b->left*100 + get_effective_linelength()/2)
     514          63 :                 /get_effective_linelength();
     515          63 :     switch (b->alignment) {
     516           0 :     case 'C':
     517           0 :       emit_td(width, " align=center>");
     518           0 :       break;
     519           0 :     case 'R':
     520           0 :       emit_td(width, " align=right>");
     521           0 :       break;
     522          63 :     default:
     523          63 :       emit_td(width);
     524             :     }
     525             :     // remember column, b
     526          63 :     last_col = b;
     527             :   }
     528          63 : }
     529             : 
     530             : /*
     531             :  *  finish_row -
     532             :  */
     533             : 
     534          37 : void html_table::finish_row (void)
     535             : {
     536          37 :   int n = 0;
     537             :   cols *c;
     538             : 
     539          37 :   if (last_col != NULL) {
     540          44 :     for (c = last_col->next; c != NULL; c = c->next)
     541           7 :       n = c->no;
     542             : 
     543          37 :     if (n > 0)
     544           7 :       emit_col(n);
     545             : #if 1
     546          37 :     if (last_col != NULL) {
     547          37 :       out->put_string("</td>");
     548          37 :       last_col = NULL;
     549             :     }
     550             : #endif
     551          37 :     out->put_string("</tr>").nl();
     552             :   }
     553          37 : }
     554             : 
     555             : /*
     556             :  *  emit_new_row - move to the next row.
     557             :  */
     558             : 
     559          17 : void html_table::emit_new_row (void)
     560             : {
     561          17 :   finish_row();
     562             : 
     563          17 :   out->put_string("<tr valign=\"top\" align=\"left\"");
     564          17 :   if (start_space) {
     565           0 :     out->put_string(" style=\"margin-top: ");
     566           0 :     out->put_string(STYLE_VERTICAL_SPACE);
     567           0 :     out->put_string("\"");
     568             :   }
     569          17 :   out->put_string(">").nl();
     570          17 :   start_space = FALSE;
     571          17 :   last_col = NULL;
     572          17 : }
     573             : 
     574          20 : void html_table::emit_finish_table (void)
     575             : {
     576          20 :   finish_row();
     577          20 :   out->put_string("</table>");
     578          20 : }
     579             : 
     580             : /*
     581             :  *  add_column - adds a column. It returns FALSE if hstart..hend
     582             :  *               crosses into a different columns.
     583             :  */
     584             : 
     585         850 : int html_table::add_column (int coln, int hstart, int hend, char align)
     586             : {
     587         850 :   cols *c = get_column(coln);
     588             : 
     589         850 :   if (c == NULL)
     590         517 :     return insert_column(coln, hstart, hend, align);
     591             :   else
     592         333 :     return modify_column(c, hstart, hend, align);
     593             : }
     594             : 
     595             : /*
     596             :  *  get_column - returns the column, coln.
     597             :  */
     598             : 
     599         850 : cols *html_table::get_column (int coln)
     600             : {
     601         850 :   cols *c = columns;
     602             : 
     603        1307 :   while (c != NULL && coln != c->no)
     604         457 :     c = c->next;
     605             : 
     606         850 :   if (c != NULL && coln == c->no)
     607         333 :     return c;
     608             :   else
     609         517 :     return NULL;
     610             : }
     611             : 
     612             : /*
     613             :  *  insert_column - inserts a column, coln.
     614             :  *                  It returns TRUE if it does not bump into
     615             :  *                  another column.
     616             :  */
     617             : 
     618         517 : int html_table::insert_column (int coln, int hstart, int hend, char align)
     619             : {
     620         517 :   cols *c = columns;
     621         517 :   cols *l = columns;
     622         517 :   cols *n = NULL;
     623             : 
     624         539 :   while (c != NULL && c->no < coln) {
     625          22 :     l = c;
     626          22 :     c = c->next;
     627             :   }
     628         517 :   if (l != NULL && l->no>coln && hend > l->left)
     629           4 :     return FALSE;       // new column bumps into previous one
     630             : 
     631         513 :   l = NULL;
     632         513 :   c = columns;
     633         535 :   while (c != NULL && c->no < coln) {
     634          22 :     l = c;
     635          22 :     c = c->next;
     636             :   }
     637             : 
     638         513 :   if ((l != NULL) && (hstart < l->right))
     639           5 :     return FALSE;       // new column bumps into previous one
     640             : 
     641         508 :   if ((l != NULL) && (l->next != NULL) &&
     642           0 :       (l->next->left < hend))
     643           0 :     return FALSE;  // new column bumps into next one
     644             : 
     645         508 :   n = new cols;
     646         508 :   if (l == NULL) {
     647         493 :     n->next = columns;
     648         493 :     columns = n;
     649             :   } else {
     650          15 :     n->next = l->next;
     651          15 :     l->next = n;
     652             :   }
     653         508 :   n->left = hstart;
     654         508 :   n->right = hend;
     655         508 :   n->no = coln;
     656         508 :   n->alignment = align;
     657         508 :   return TRUE;
     658             : }
     659             : 
     660             : /*
     661             :  *  modify_column - given a column, c, modify the width to
     662             :  *                  contain hstart..hend.
     663             :  *                  It returns TRUE if it does not clash with
     664             :  *                  the next or previous column.
     665             :  */
     666             : 
     667         333 : int html_table::modify_column (cols *c, int hstart, int hend, char align)
     668             : {
     669         333 :   cols *l = columns;
     670             : 
     671         503 :   while (l != NULL && l->next != c)
     672         170 :     l = l->next;
     673             : 
     674         333 :   if ((l != NULL) && (hstart < l->right))
     675           0 :     return FALSE;       // new column bumps into previous one
     676             : 
     677         333 :   if ((c->next != NULL) && (c->next->left < hend))
     678           2 :     return FALSE;  // new column bumps into next one
     679             : 
     680         331 :   if (c->left > hstart)
     681           0 :     c->left = hstart;
     682             : 
     683         331 :   if (c->right < hend)
     684          99 :     c->right = hend;
     685             : 
     686         331 :   c->alignment = align;
     687             : 
     688         331 :   return TRUE;
     689             : }
     690             : 
     691             : /*
     692             :  *  find_tab_column - finds the column number for position, pos.
     693             :  *                    It searches through the list tab stops.
     694             :  */
     695             : 
     696           9 : int html_table::find_tab_column (int pos)
     697             : {
     698             :   // remember the first column is reserved for untabbed glyphs
     699           9 :   return tab_stops->find_tab(pos)+1;
     700             : }
     701             : 
     702             : /*
     703             :  *  find_column - find the column number for position, pos.
     704             :  *                It searches through the list of columns.
     705             :  */
     706             : 
     707          11 : int html_table::find_column (int pos)
     708             : {
     709          11 :   int   p=0;
     710             :   cols *c;
     711             : 
     712          39 :   for (c = columns; c != NULL; c = c->next) {
     713          30 :     if (c->left > pos)
     714           2 :       return p;
     715          28 :     p = c->no;
     716             :   }
     717           9 :   return p;
     718             : }
     719             : 
     720             : /*
     721             :  *  no_columns - returns the number of table columns (rather than tabs)
     722             :  */
     723             : 
     724           0 : int html_table::no_columns (void)
     725             : {
     726           0 :   int n=0;
     727             :   cols *c;
     728             : 
     729           0 :   for (c = columns; c != NULL; c = c->next)
     730           0 :     n++;
     731           0 :   return n;
     732             : }
     733             : 
     734             : /*
     735             :  *  is_gap - returns the gap between column, c, and the next column.
     736             :  */
     737             : 
     738          48 : int html_table::is_gap (cols *c)
     739             : {
     740          48 :   if (c == NULL || c->right <= 0 || c->next == NULL)
     741           0 :     return 0;
     742             :   else
     743             :     // we compute the difference after converting positions
     744             :     // to avoid rounding errors
     745          48 :     return (c->next->left*100 + get_effective_linelength()/2)
     746          48 :              / get_effective_linelength()
     747          48 :            - (c->right*100 + get_effective_linelength()/2)
     748          48 :                / get_effective_linelength();
     749             : }
     750             : 
     751             : /*
     752             :  *  no_gaps - returns the number of table gaps between the columns
     753             :  */
     754             : 
     755           0 : int html_table::no_gaps (void)
     756             : {
     757           0 :   int n=0;
     758             :   cols *c;
     759             : 
     760           0 :   for (c = columns; c != NULL; c = c->next)
     761           0 :     if (is_gap(c))
     762           0 :       n++;
     763           0 :   return n;
     764             : }
     765             : 
     766             : /*
     767             :  *  get_tab_pos - returns the, nth, tab position
     768             :  */
     769             : 
     770          11 : int html_table::get_tab_pos (int n)
     771             : {
     772          11 :   return tab_stops->get_tab_pos(n);
     773             : }
     774             : 
     775           0 : char html_table::get_tab_align (int n)
     776             : {
     777           0 :   return tab_stops->get_tab_align(n);
     778             : }
     779             : 
     780             : 
     781           0 : void html_table::dump_table (void)
     782             : {
     783           0 :   if (columns != NULL) {
     784             :     cols *c;
     785           0 :     for (c = columns; c != NULL; c = c->next) {
     786           0 :       printf("column %d  %d..%d  %c\n", c->no, c->left, c->right, c->alignment);
     787             :     }
     788             :   } else
     789           0 :     tab_stops->dump_tabs();
     790           0 : }
     791             : 
     792             : /*
     793             :  *  html_indent - creates an indent with indentation, ind, given
     794             :  *                a line length of linelength.
     795             :  */
     796             : 
     797         230 : html_indent::html_indent (simple_output *op, int ind, int pageoffset, int linelength)
     798             : {
     799         230 :   table = new html_table(op, linelength);
     800             : 
     801         230 :   table->add_column(1, ind+pageoffset, linelength, 'L');
     802         230 :   table->add_indent(pageoffset);
     803         230 :   in = ind;
     804         230 :   pg = pageoffset;
     805         230 :   ll = linelength;
     806         230 : }
     807             : 
     808         460 : html_indent::~html_indent (void)
     809             : {
     810         230 :   end();
     811         230 :   delete table;
     812         230 : }
     813             : 
     814         130 : void html_indent::begin (int space)
     815             : {
     816         130 :   if (in + pg == 0) {
     817           0 :     if (space) {
     818           0 :       table->out->put_string(" style=\"margin-top: ");
     819           0 :       table->out->put_string(STYLE_VERTICAL_SPACE);
     820           0 :       table->out->put_string("\"");
     821             :     }
     822             :   }
     823             :   else {
     824             :     //
     825             :     // we use exactly the same mechanism for calculating
     826             :     // indentation as html_table::emit_col
     827             :     //
     828         130 :     table->out->put_string(" style=\"margin-left:")
     829         130 :       .put_number(((in + pg) * 100 + ll/2) / ll -
     830         130 :                   (ll/2)/ll)
     831         130 :       .put_string("%;");
     832             : 
     833         130 :     if (space) {
     834         122 :       table->out->put_string(" margin-top: ");
     835         122 :       table->out->put_string(STYLE_VERTICAL_SPACE);
     836             :     }
     837         130 :     table->out->put_string("\"");
     838             :   }
     839         130 : }
     840             : 
     841         230 : void html_indent::end (void)
     842             : {
     843         230 : }
     844             : 
     845             : /*
     846             :  *  get_reg - collects the registers as supplied during initialization.
     847             :  */
     848             : 
     849           0 : void html_indent::get_reg (int *ind, int *pageoffset, int *linelength)
     850             : {
     851           0 :   *ind = in;
     852           0 :   *pageoffset = pg;
     853           0 :   *linelength = ll;
     854           0 : }
     855             : 
     856             : // Local Variables:
     857             : // fill-column: 72
     858             : // mode: C++
     859             : // End:
     860             : // vim: set cindent noexpandtab shiftwidth=2 textwidth=72:

Generated by: LCOV version 1.14