1114402Sru// -*- C++ -*-
2114402Sru/* Copyright (C) 1989, 1990, 1991, 1992, 2000 Free Software Foundation, Inc.
3114402Sru     Written by James Clark (jjc@jclark.com)
4114402Sru
5114402SruThis file is part of groff.
6114402Sru
7114402Srugroff is free software; you can redistribute it and/or modify it under
8114402Sruthe terms of the GNU General Public License as published by the Free
9114402SruSoftware Foundation; either version 2, or (at your option) any later
10114402Sruversion.
11114402Sru
12114402Srugroff is distributed in the hope that it will be useful, but WITHOUT ANY
13114402SruWARRANTY; without even the implied warranty of MERCHANTABILITY or
14114402SruFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15114402Srufor more details.
16114402Sru
17114402SruYou should have received a copy of the GNU General Public License along
18114402Sruwith groff; see the file COPYING.  If not, write to the Free Software
19151497SruFoundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */
20114402Sru
21114402Sru#ifdef COLUMN
22114402Sru
23114402Sru#include "troff.h"
24114402Sru#include "symbol.h"
25114402Sru#include "dictionary.h"
26114402Sru#include "hvunits.h"
27114402Sru#include "env.h"
28114402Sru#include "request.h"
29114402Sru#include "node.h"
30114402Sru#include "token.h"
31114402Sru#include "div.h"
32114402Sru#include "reg.h"
33114402Sru#include "stringclass.h"
34114402Sru
35114402Sruvoid output_file::vjustify(vunits, symbol)
36114402Sru{
37114402Sru  // do nothing
38114402Sru}
39114402Sru
40114402Srustruct justification_spec;
41114402Srustruct output_line;
42114402Sru
43114402Sruclass column : public output_file {
44114402Sruprivate:
45114402Sru  output_file *out;
46114402Sru  vunits bottom;
47114402Sru  output_line *col;
48114402Sru  output_line **tail;
49114402Sru  void add_output_line(output_line *);
50114402Sru  void begin_page(int pageno, vunits page_length);
51114402Sru  void flush();
52114402Sru  void print_line(hunits, vunits, node *, vunits, vunits);
53114402Sru  void vjustify(vunits, symbol);
54114402Sru  void transparent_char(unsigned char c);
55114402Sru  void copy_file(hunits, vunits, const char *);
56114402Sru  int is_printing();
57114402Sru  void check_bottom();
58114402Srupublic:
59114402Sru  column();
60114402Sru  ~column();
61114402Sru  void start();
62114402Sru  void output();
63114402Sru  void justify(const justification_spec &);
64114402Sru  void trim();
65114402Sru  void reset();
66114402Sru  vunits get_bottom();
67114402Sru  vunits get_last_extra_space();
68114402Sru  int is_active() { return out != 0; }
69114402Sru};
70114402Sru
71114402Srucolumn *the_column = 0;
72114402Sru
73114402Srustruct transparent_output_line;
74114402Srustruct vjustify_output_line;
75114402Sru
76114402Sruclass output_line {
77114402Sru  output_line *next;
78114402Srupublic:
79114402Sru  output_line();
80114402Sru  virtual ~output_line();
81114402Sru  virtual void output(output_file *, vunits);
82114402Sru  virtual transparent_output_line *as_transparent_output_line();
83114402Sru  virtual vjustify_output_line *as_vjustify_output_line();
84114402Sru  virtual vunits distance();
85114402Sru  virtual vunits height();
86114402Sru  virtual void reset();
87114402Sru  virtual vunits extra_space();	// post line
88114402Sru  friend class column;
89114402Sru  friend class justification_spec;
90114402Sru};
91114402Sru
92114402Sruclass position_output_line : public output_line {
93114402Sru  vunits dist;
94114402Srupublic:
95114402Sru  position_output_line(vunits);
96114402Sru  vunits distance();
97114402Sru};
98114402Sru
99114402Sruclass node_output_line : public position_output_line {
100114402Sru  node *nd;
101114402Sru  hunits page_offset;
102114402Sru  vunits before;
103114402Sru  vunits after;
104114402Srupublic:
105114402Sru  node_output_line(vunits, node *, hunits, vunits, vunits);
106114402Sru  ~node_output_line();
107114402Sru  void output(output_file *, vunits);
108114402Sru  vunits height();
109114402Sru  vunits extra_space();
110114402Sru};
111114402Sru
112114402Sruclass vjustify_output_line : public position_output_line {
113114402Sru  vunits current;
114114402Sru  symbol typ;
115114402Srupublic:
116114402Sru  vjustify_output_line(vunits dist, symbol);
117114402Sru  vunits height();
118114402Sru  vjustify_output_line *as_vjustify_output_line();
119114402Sru  void vary(vunits amount);
120114402Sru  void reset();
121114402Sru  symbol type();
122114402Sru};
123114402Sru
124114402Sruinline symbol vjustify_output_line::type()
125114402Sru{
126114402Sru  return typ;
127114402Sru}
128114402Sru
129114402Sruclass copy_file_output_line : public position_output_line {
130114402Sru  symbol filename;
131114402Sru  hunits hpos;
132114402Srupublic:
133114402Sru  copy_file_output_line(vunits, const char *, hunits);
134114402Sru  void output(output_file *, vunits);
135114402Sru};
136114402Sru
137114402Sruclass transparent_output_line : public output_line {
138114402Sru  string buf;
139114402Srupublic:
140114402Sru  transparent_output_line();
141114402Sru  void output(output_file *, vunits);
142114402Sru  void append_char(unsigned char c);
143114402Sru  transparent_output_line *as_transparent_output_line();
144114402Sru};
145114402Sru
146114402Sruoutput_line::output_line() : next(0)
147114402Sru{
148114402Sru}
149114402Sru
150114402Sruoutput_line::~output_line()
151114402Sru{
152114402Sru}
153114402Sru
154114402Sruvoid output_line::reset()
155114402Sru{
156114402Sru}
157114402Sru
158114402Srutransparent_output_line *output_line::as_transparent_output_line()
159114402Sru{
160114402Sru  return 0;
161114402Sru}
162114402Sru
163114402Sruvjustify_output_line *output_line::as_vjustify_output_line()
164114402Sru{
165114402Sru  return 0;
166114402Sru}
167114402Sru
168114402Sruvoid output_line::output(output_file *, vunits)
169114402Sru{
170114402Sru}
171114402Sru
172114402Sruvunits output_line::distance()
173114402Sru{
174114402Sru  return V0;
175114402Sru}
176114402Sru
177114402Sruvunits output_line::height()
178114402Sru{
179114402Sru  return V0;
180114402Sru}
181114402Sru
182114402Sruvunits output_line::extra_space()
183114402Sru{
184114402Sru  return V0;
185114402Sru}
186114402Sru
187114402Sruposition_output_line::position_output_line(vunits d)
188114402Sru: dist(d)
189114402Sru{
190114402Sru}
191114402Sru
192114402Sruvunits position_output_line::distance()
193114402Sru{
194114402Sru  return dist;
195114402Sru}
196114402Sru
197114402Srunode_output_line::node_output_line(vunits d, node *n, hunits po, vunits b, vunits a)
198114402Sru: position_output_line(d), nd(n), page_offset(po), before(b), after(a)
199114402Sru{
200114402Sru}
201114402Sru
202114402Srunode_output_line::~node_output_line()
203114402Sru{
204114402Sru  delete_node_list(nd);
205114402Sru}
206114402Sru
207114402Sruvoid node_output_line::output(output_file *out, vunits pos)
208114402Sru{
209114402Sru  out->print_line(page_offset, pos, nd, before, after);
210114402Sru  nd = 0;
211114402Sru}
212114402Sru
213114402Sruvunits node_output_line::height()
214114402Sru{
215114402Sru  return after;
216114402Sru}
217114402Sru
218114402Sruvunits node_output_line::extra_space()
219114402Sru{
220114402Sru  return after;
221114402Sru}
222114402Sru
223114402Sruvjustify_output_line::vjustify_output_line(vunits d, symbol t)
224114402Sru: position_output_line(d), typ(t)
225114402Sru{
226114402Sru}
227114402Sru
228114402Sruvoid vjustify_output_line::reset()
229114402Sru{
230114402Sru  current = V0;
231114402Sru}
232114402Sru
233114402Sruvunits vjustify_output_line::height()
234114402Sru{
235114402Sru  return current;
236114402Sru}
237114402Sru
238114402Sruvjustify_output_line *vjustify_output_line::as_vjustify_output_line()
239114402Sru{
240114402Sru  return this;
241114402Sru}
242114402Sru
243114402Sruinline void vjustify_output_line::vary(vunits amount)
244114402Sru{
245114402Sru  current += amount;
246114402Sru}
247114402Sru
248114402Srutransparent_output_line::transparent_output_line()
249114402Sru{
250114402Sru}
251114402Sru
252114402Srutransparent_output_line *transparent_output_line::as_transparent_output_line()
253114402Sru{
254114402Sru  return this;
255114402Sru}
256114402Sru
257114402Sruvoid transparent_output_line::append_char(unsigned char c)
258114402Sru{
259114402Sru  assert(c != 0);
260114402Sru  buf += c;
261114402Sru}
262114402Sru
263114402Sruvoid transparent_output_line::output(output_file *out, vunits)
264114402Sru{
265114402Sru  int len = buf.length();
266114402Sru  for (int i = 0; i < len; i++)
267114402Sru    out->transparent_char(buf[i]);
268114402Sru}
269114402Sru
270114402Srucopy_file_output_line::copy_file_output_line(vunits d, const char *f, hunits h)
271114402Sru: position_output_line(d), hpos(h), filename(f)
272114402Sru{
273114402Sru}
274114402Sru
275114402Sruvoid copy_file_output_line::output(output_file *out, vunits pos)
276114402Sru{
277114402Sru  out->copy_file(hpos, pos, filename.contents());
278114402Sru}
279114402Sru
280114402Srucolumn::column()
281114402Sru: bottom(V0), col(0), tail(&col), out(0)
282114402Sru{
283114402Sru}
284114402Sru
285114402Srucolumn::~column()
286114402Sru{
287114402Sru  assert(out != 0);
288114402Sru  error("automatically outputting column before exiting");
289114402Sru  output();
290114402Sru  delete the_output;
291114402Sru}
292114402Sru
293114402Sruvoid column::start()
294114402Sru{
295114402Sru  assert(out == 0);
296114402Sru  if (!the_output)
297114402Sru    init_output();
298114402Sru  assert(the_output != 0);
299114402Sru  out = the_output;
300114402Sru  the_output = this;
301114402Sru}
302114402Sru
303114402Sruvoid column::begin_page(int pageno, vunits page_length)
304114402Sru{
305114402Sru  assert(out != 0);
306114402Sru  if (col) {
307114402Sru    error("automatically outputting column before beginning next page");
308114402Sru    output();
309114402Sru    the_output->begin_page(pageno, page_length);
310114402Sru  }
311114402Sru  else
312114402Sru    out->begin_page(pageno, page_length);
313114402Sru
314114402Sru}
315114402Sru
316114402Sruvoid column::flush()
317114402Sru{
318114402Sru  assert(out != 0);
319114402Sru  out->flush();
320114402Sru}
321114402Sru
322114402Sruint column::is_printing()
323114402Sru{
324114402Sru  assert(out != 0);
325114402Sru  return out->is_printing();
326114402Sru}
327114402Sru
328114402Sruvunits column::get_bottom()
329114402Sru{
330114402Sru  return bottom;
331114402Sru}
332114402Sru
333114402Sruvoid column::add_output_line(output_line *ln)
334114402Sru{
335114402Sru  *tail = ln;
336114402Sru  bottom += ln->distance();
337114402Sru  bottom += ln->height();
338114402Sru  ln->next = 0;
339114402Sru  tail = &(*tail)->next;
340114402Sru}
341114402Sru
342114402Sruvoid column::print_line(hunits page_offset, vunits pos, node *nd,
343114402Sru			vunits before, vunits after)
344114402Sru{
345114402Sru  assert(out != 0);
346114402Sru  add_output_line(new node_output_line(pos - bottom, nd, page_offset, before, after));
347114402Sru}
348114402Sru
349114402Sruvoid column::vjustify(vunits pos, symbol typ)
350114402Sru{
351114402Sru  assert(out != 0);
352114402Sru  add_output_line(new vjustify_output_line(pos - bottom, typ));
353114402Sru}
354114402Sru
355114402Sruvoid column::transparent_char(unsigned char c)
356114402Sru{
357114402Sru  assert(out != 0);
358114402Sru  transparent_output_line *tl = 0;
359114402Sru  if (*tail)
360114402Sru    tl = (*tail)->as_transparent_output_line();
361114402Sru  if (!tl) {
362114402Sru    tl = new transparent_output_line;
363114402Sru    add_output_line(tl);
364114402Sru  }
365114402Sru  tl->append_char(c);
366114402Sru}
367114402Sru
368114402Sruvoid column::copy_file(hunits page_offset, vunits pos, const char *filename)
369114402Sru{
370114402Sru  assert(out != 0);
371114402Sru  add_output_line(new copy_file_output_line(pos - bottom, filename, page_offset));
372114402Sru}
373114402Sru
374114402Sruvoid column::trim()
375114402Sru{
376114402Sru  output_line **spp = 0;
377114402Sru  for (output_line **pp = &col; *pp; pp = &(*pp)->next)
378114402Sru    if ((*pp)->as_vjustify_output_line() == 0)
379114402Sru      spp = 0;
380114402Sru    else if (!spp)
381114402Sru      spp = pp;
382114402Sru  if (spp) {
383114402Sru    output_line *ln = *spp;
384114402Sru    *spp = 0;
385114402Sru    tail = spp;
386114402Sru    while (ln) {
387114402Sru      output_line *tem = ln->next;
388114402Sru      bottom -= ln->distance();
389114402Sru      bottom -= ln->height();
390114402Sru      delete ln;
391114402Sru      ln = tem;
392114402Sru    }
393114402Sru  }
394114402Sru}
395114402Sru
396114402Sruvoid column::reset()
397114402Sru{
398114402Sru  bottom = V0;
399114402Sru  for (output_line *ln = col; ln; ln = ln->next) {
400114402Sru    bottom += ln->distance();
401114402Sru    ln->reset();
402114402Sru    bottom += ln->height();
403114402Sru  }
404114402Sru}
405114402Sru
406114402Sruvoid column::check_bottom()
407114402Sru{
408114402Sru  vunits b;
409114402Sru  for (output_line *ln = col; ln; ln = ln->next) {
410114402Sru    b += ln->distance();
411114402Sru    b += ln->height();
412114402Sru  }
413114402Sru  assert(b == bottom);
414114402Sru}
415114402Sru
416114402Sruvoid column::output()
417114402Sru{
418114402Sru  assert(out != 0);
419114402Sru  vunits vpos(V0);
420114402Sru  output_line *ln = col;
421114402Sru  while (ln) {
422114402Sru    vpos += ln->distance();
423114402Sru    ln->output(out, vpos);
424114402Sru    vpos += ln->height();
425114402Sru    output_line *tem = ln->next;
426114402Sru    delete ln;
427114402Sru    ln = tem;
428114402Sru  }
429114402Sru  tail = &col;
430114402Sru  bottom = V0;
431114402Sru  col = 0;
432114402Sru  the_output = out;
433114402Sru  out = 0;
434114402Sru}
435114402Sru
436114402Sruvunits column::get_last_extra_space()
437114402Sru{
438114402Sru  if (!col)
439114402Sru    return V0;
440114402Sru  for (output_line *p = col; p->next; p = p->next)
441114402Sru    ;
442114402Sru  return p->extra_space();
443114402Sru}
444114402Sru
445114402Sruclass justification_spec {
446114402Sru  vunits height;
447114402Sru  symbol *type;
448114402Sru  vunits *amount;
449114402Sru  int n;
450114402Sru  int maxn;
451114402Srupublic:
452114402Sru  justification_spec(vunits);
453114402Sru  ~justification_spec();
454114402Sru  void append(symbol t, vunits v);
455114402Sru  void justify(output_line *, vunits *bottomp) const;
456114402Sru};
457114402Sru
458114402Srujustification_spec::justification_spec(vunits h)
459114402Sru: height(h), n(0), maxn(10)
460114402Sru{
461114402Sru  type = new symbol[maxn];
462114402Sru  amount = new vunits[maxn];
463114402Sru}
464114402Sru
465114402Srujustification_spec::~justification_spec()
466114402Sru{
467114402Sru  a_delete type;
468114402Sru  a_delete amount;
469114402Sru}
470114402Sru
471114402Sruvoid justification_spec::append(symbol t, vunits v)
472114402Sru{
473114402Sru  if (v <= V0) {
474114402Sru    if (v < V0)
475114402Sru      warning(WARN_RANGE,
476114402Sru	      "maximum space for vertical justification must not be negative");
477114402Sru    else
478114402Sru      warning(WARN_RANGE,
479114402Sru	      "maximum space for vertical justification must not be zero");
480114402Sru    return;
481114402Sru  }
482114402Sru  if (n >= maxn) {
483114402Sru    maxn *= 2;
484114402Sru    symbol *old_type = type;
485114402Sru    type = new symbol[maxn];
486114402Sru    int i;
487114402Sru    for (i = 0; i < n; i++)
488114402Sru      type[i] = old_type[i];
489114402Sru    a_delete old_type;
490114402Sru    vunits *old_amount = amount;
491114402Sru    amount = new vunits[maxn];
492114402Sru    for (i = 0; i < n; i++)
493114402Sru      amount[i] = old_amount[i];
494114402Sru    a_delete old_amount;
495114402Sru  }
496114402Sru  assert(n < maxn);
497114402Sru  type[n] = t;
498114402Sru  amount[n] = v;
499114402Sru  n++;
500114402Sru}
501114402Sru
502114402Sruvoid justification_spec::justify(output_line *col, vunits *bottomp) const
503114402Sru{
504114402Sru  if (*bottomp >= height)
505114402Sru    return;
506114402Sru  vunits total;
507114402Sru  output_line *p;
508114402Sru  for (p = col; p; p = p->next) {
509114402Sru    vjustify_output_line *sp = p->as_vjustify_output_line();
510114402Sru    if (sp) {
511114402Sru      symbol t = sp->type();
512114402Sru      for (int i = 0; i < n; i++) {
513114402Sru	if (t == type[i])
514114402Sru	  total += amount[i];
515114402Sru      }
516114402Sru    }
517114402Sru  }
518114402Sru  vunits gap = height - *bottomp;
519114402Sru  for (p = col; p; p = p->next) {
520114402Sru    vjustify_output_line *sp = p->as_vjustify_output_line();
521114402Sru    if (sp) {
522114402Sru      symbol t = sp->type();
523114402Sru      for (int i = 0; i < n; i++) {
524114402Sru	if (t == type[i]) {
525114402Sru	  if (total <= gap) {
526114402Sru	    sp->vary(amount[i]);
527114402Sru	    gap -= amount[i];
528114402Sru	  }
529114402Sru	  else {
530114402Sru	    // gap < total
531114402Sru	    vunits v = scale(amount[i], gap, total);
532114402Sru	    sp->vary(v);
533114402Sru	    gap -= v;
534114402Sru	  }
535114402Sru	  total -= amount[i];
536114402Sru	}
537114402Sru      }
538114402Sru    }
539114402Sru  }
540114402Sru  assert(total == V0);
541114402Sru  *bottomp = height - gap;
542114402Sru}
543114402Sru
544114402Sruvoid column::justify(const justification_spec &js)
545114402Sru{
546114402Sru  check_bottom();
547114402Sru  js.justify(col, &bottom);
548114402Sru  check_bottom();
549114402Sru}
550114402Sru
551114402Sruvoid column_justify()
552114402Sru{
553114402Sru  vunits height;
554114402Sru  if (!the_column->is_active())
555114402Sru    error("can't justify column - column not active");
556114402Sru  else if (get_vunits(&height, 'v')) {
557114402Sru    justification_spec js(height);
558114402Sru    symbol nm = get_long_name(1);
559114402Sru    if (!nm.is_null()) {
560114402Sru      vunits v;
561114402Sru      if (get_vunits(&v, 'v')) {
562114402Sru	js.append(nm, v);
563114402Sru	int err = 0;
564114402Sru	while (has_arg()) {
565114402Sru	  nm = get_long_name(1);
566114402Sru	  if (nm.is_null()) {
567114402Sru	    err = 1;
568114402Sru	    break;
569114402Sru	  }
570114402Sru	  if (!get_vunits(&v, 'v')) {
571114402Sru	    err = 1;
572114402Sru	    break;
573114402Sru	  }
574114402Sru	  js.append(nm, v);
575114402Sru	}
576114402Sru	if (!err)
577114402Sru	  the_column->justify(js);
578114402Sru      }
579114402Sru    }
580114402Sru  }
581114402Sru  skip_line();
582114402Sru}
583114402Sru
584114402Sruvoid column_start()
585114402Sru{
586114402Sru  if (the_column->is_active())
587114402Sru    error("can't start column - column already active");
588114402Sru  else
589114402Sru    the_column->start();
590114402Sru  skip_line();
591114402Sru}
592114402Sru
593114402Sruvoid column_output()
594114402Sru{
595114402Sru  if (!the_column->is_active())
596114402Sru    error("can't output column - column not active");
597114402Sru  else
598114402Sru    the_column->output();
599114402Sru  skip_line();
600114402Sru}
601114402Sru
602114402Sruvoid column_trim()
603114402Sru{
604114402Sru  if (!the_column->is_active())
605114402Sru    error("can't trim column - column not active");
606114402Sru  else
607114402Sru    the_column->trim();
608114402Sru  skip_line();
609114402Sru}
610114402Sru
611114402Sruvoid column_reset()
612114402Sru{
613114402Sru  if (!the_column->is_active())
614114402Sru    error("can't reset column - column not active");
615114402Sru  else
616114402Sru    the_column->reset();
617114402Sru  skip_line();
618114402Sru}
619114402Sru
620114402Sruclass column_bottom_reg : public reg {
621114402Srupublic:
622114402Sru  const char *get_string();
623114402Sru};
624114402Sru
625114402Sruconst char *column_bottom_reg::get_string()
626114402Sru{
627114402Sru  return i_to_a(the_column->get_bottom().to_units());
628114402Sru}
629114402Sru
630114402Sruclass column_extra_space_reg : public reg {
631114402Srupublic:
632114402Sru  const char *get_string();
633114402Sru};
634114402Sru
635114402Sruconst char *column_extra_space_reg::get_string()
636114402Sru{
637114402Sru  return i_to_a(the_column->get_last_extra_space().to_units());
638114402Sru}
639114402Sru
640114402Sruclass column_active_reg : public reg {
641114402Srupublic:
642114402Sru  const char *get_string();
643114402Sru};
644114402Sru
645114402Sruconst char *column_active_reg::get_string()
646114402Sru{
647114402Sru  return the_column->is_active() ? "1" : "0";
648114402Sru}
649114402Sru
650114402Srustatic int no_vjustify_mode = 0;
651114402Sru
652114402Sruclass vjustify_node : public node {
653114402Sru  symbol typ;
654114402Srupublic:
655114402Sru  vjustify_node(symbol);
656114402Sru  int reread(int *);
657114402Sru  const char *type();
658114402Sru  int same(node *);
659114402Sru  node *copy();
660114402Sru};
661114402Sru
662114402Sruvjustify_node::vjustify_node(symbol t)
663114402Sru: typ(t)
664114402Sru{
665114402Sru}
666114402Sru
667114402Srunode *vjustify_node::copy()
668114402Sru{
669151497Sru  return new vjustify_node(typ, div_nest_level);
670114402Sru}
671114402Sru
672114402Sruconst char *vjustify_node::type()
673114402Sru{
674114402Sru  return "vjustify_node";
675114402Sru}
676114402Sru
677114402Sruint vjustify_node::same(node *nd)
678114402Sru{
679114402Sru  return typ == ((vjustify_node *)nd)->typ;
680114402Sru}
681114402Sru
682114402Sruint vjustify_node::reread(int *bolp)
683114402Sru{
684114402Sru  curdiv->vjustify(typ);
685114402Sru  *bolp = 1;
686114402Sru  return 1;
687114402Sru}
688114402Sru
689114402Sruvoid macro_diversion::vjustify(symbol type)
690114402Sru{
691114402Sru  if (!no_vjustify_mode)
692114402Sru    mac->append(new vjustify_node(type));
693114402Sru}
694114402Sru
695114402Sruvoid top_level_diversion::vjustify(symbol type)
696114402Sru{
697114402Sru  if (no_space_mode || no_vjustify_mode)
698114402Sru    return;
699114402Sru  assert(first_page_begun);	// I'm not sure about this.
700114402Sru  the_output->vjustify(vertical_position, type);
701114402Sru}
702114402Sru
703114402Sruvoid no_vjustify()
704114402Sru{
705114402Sru  skip_line();
706114402Sru  no_vjustify_mode = 1;
707114402Sru}
708114402Sru
709114402Sruvoid restore_vjustify()
710114402Sru{
711114402Sru  skip_line();
712114402Sru  no_vjustify_mode = 0;
713114402Sru}
714114402Sru
715114402Sruvoid init_column_requests()
716114402Sru{
717114402Sru  the_column = new column;
718114402Sru  init_request("cols", column_start);
719114402Sru  init_request("colo", column_output);
720114402Sru  init_request("colj", column_justify);
721114402Sru  init_request("colr", column_reset);
722114402Sru  init_request("colt", column_trim);
723114402Sru  init_request("nvj", no_vjustify);
724114402Sru  init_request("rvj", restore_vjustify);
725114402Sru  number_reg_dictionary.define(".colb", new column_bottom_reg);
726114402Sru  number_reg_dictionary.define(".colx", new column_extra_space_reg);
727114402Sru  number_reg_dictionary.define(".cola", new column_active_reg);
728114402Sru  number_reg_dictionary.define(".nvj",
729114402Sru			       new constant_int_reg(&no_vjustify_mode));
730114402Sru}
731114402Sru
732114402Sru#endif /* COLUMN */
733