175584Sru// -*- C++ -*-
2151497Sru/* Copyright (C) 1989, 1990, 1991, 1992, 2001, 2002, 2004, 2005
3114402Sru   Free Software Foundation, Inc.
475584Sru     Written by James Clark (jjc@jclark.com)
575584Sru
675584SruThis file is part of groff.
775584Sru
875584Srugroff is free software; you can redistribute it and/or modify it under
975584Sruthe terms of the GNU General Public License as published by the Free
1075584SruSoftware Foundation; either version 2, or (at your option) any later
1175584Sruversion.
1275584Sru
1375584Srugroff is distributed in the hope that it will be useful, but WITHOUT ANY
1475584SruWARRANTY; without even the implied warranty of MERCHANTABILITY or
1575584SruFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1675584Srufor more details.
1775584Sru
1875584SruYou should have received a copy of the GNU General Public License along
1975584Sruwith groff; see the file COPYING.  If not, write to the Free Software
20151497SruFoundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */
2175584Sru
22151497Sruvoid do_divert(int append, int boxing);
23151497Sruvoid end_diversions();
24151497Sruvoid page_offset();
25151497Sru
2675584Sruclass diversion {
2775584Sru  friend void do_divert(int append, int boxing);
2875584Sru  friend void end_diversions();
2975584Sru  diversion *prev;
3075584Sru  node *saved_line;
3175584Sru  hunits saved_width_total;
3275584Sru  int saved_space_total;
3375584Sru  hunits saved_saved_indent;
3475584Sru  hunits saved_target_text_length;
3575584Sru  int saved_prev_line_interrupted;
3675584Sruprotected:
3775584Sru  symbol nm;
3875584Sru  vunits vertical_position;
3975584Sru  vunits high_water_mark;
4075584Srupublic:
41151497Sru  int any_chars_added;
4279543Sru  int no_space_mode;
43151497Sru  int needs_push;
44151497Sru  int saved_seen_break;
45151497Sru  int saved_seen_space;
46151497Sru  int saved_seen_eol;
47151497Sru  int saved_suppress_next_eol;
48151497Sru  state_set modified_tag;
4975584Sru  vunits marked_place;
5075584Sru  diversion(symbol s = NULL_SYMBOL);
5175584Sru  virtual ~diversion();
5275584Sru  virtual void output(node *nd, int retain_size, vunits vs, vunits post_vs,
5375584Sru		      hunits width) = 0;
5475584Sru  virtual void transparent_output(unsigned char) = 0;
5575584Sru  virtual void transparent_output(node *) = 0;
5675584Sru  virtual void space(vunits distance, int forced = 0) = 0;
5775584Sru#ifdef COLUMN
5875584Sru  virtual void vjustify(symbol) = 0;
5975584Sru#endif /* COLUMN */
6075584Sru  vunits get_vertical_position() { return vertical_position; }
6175584Sru  vunits get_high_water_mark() { return high_water_mark; }
6275584Sru  virtual vunits distance_to_next_trap() = 0;
6375584Sru  void need(vunits);
6475584Sru  const char *get_diversion_name() { return nm.contents(); }
6575584Sru  virtual void set_diversion_trap(symbol, vunits) = 0;
6675584Sru  virtual void clear_diversion_trap() = 0;
6775584Sru  virtual void copy_file(const char *filename) = 0;
68151497Sru  virtual int is_diversion() = 0;
6975584Sru};
7075584Sru
7175584Sruclass macro;
7275584Sru
7375584Sruclass macro_diversion : public diversion {
7475584Sru  macro *mac;
7575584Sru  hunits max_width;
7675584Sru  symbol diversion_trap;
7775584Sru  vunits diversion_trap_pos;
7875584Srupublic:
7975584Sru  macro_diversion(symbol, int);
8075584Sru  ~macro_diversion();
8175584Sru  void output(node *nd, int retain_size, vunits vs, vunits post_vs,
8275584Sru	      hunits width);
8375584Sru  void transparent_output(unsigned char);
8475584Sru  void transparent_output(node *);
8575584Sru  void space(vunits distance, int forced = 0);
8675584Sru#ifdef COLUMN
8775584Sru  void vjustify(symbol);
8875584Sru#endif /* COLUMN */
8975584Sru  vunits distance_to_next_trap();
9075584Sru  void set_diversion_trap(symbol, vunits);
9175584Sru  void clear_diversion_trap();
9275584Sru  void copy_file(const char *filename);
93151497Sru  int is_diversion() { return 1; }
9475584Sru};
9575584Sru
9675584Srustruct trap {
9775584Sru  trap *next;
9875584Sru  vunits position;
9975584Sru  symbol nm;
10075584Sru  trap(symbol, vunits, trap *);
10175584Sru};
10275584Sru
103151497Sruclass output_file;
10475584Sru
10575584Sruclass top_level_diversion : public diversion {
10675584Sru  int page_number;
10775584Sru  int page_count;
10875584Sru  int last_page_count;
10975584Sru  vunits page_length;
11075584Sru  hunits prev_page_offset;
11175584Sru  hunits page_offset;
11275584Sru  trap *page_trap_list;
11375584Sru  trap *find_next_trap(vunits *);
11475584Sru  int have_next_page_number;
11575584Sru  int next_page_number;
11675584Sru  int ejecting_page;		// Is the current page being ejected?
11775584Srupublic:
11875584Sru  int before_first_page;
11975584Sru  top_level_diversion();
12075584Sru  void output(node *nd, int retain_size, vunits vs, vunits post_vs,
12175584Sru	      hunits width);
12275584Sru  void transparent_output(unsigned char);
12375584Sru  void transparent_output(node *);
12475584Sru  void space(vunits distance, int forced = 0);
12575584Sru#ifdef COLUMN
12675584Sru  void vjustify(symbol);
12775584Sru#endif /* COLUMN */
12875584Sru  hunits get_page_offset() { return page_offset; }
12975584Sru  vunits get_page_length() { return page_length; }
13075584Sru  vunits distance_to_next_trap();
13175584Sru  void add_trap(symbol nm, vunits pos);
13275584Sru  void change_trap(symbol nm, vunits pos);
13375584Sru  void remove_trap(symbol);
13475584Sru  void remove_trap_at(vunits pos);
13575584Sru  void print_traps();
13675584Sru  int get_page_count() { return page_count; }
13775584Sru  int get_page_number() { return page_number; }
13875584Sru  int get_next_page_number();
13975584Sru  void set_page_number(int n) { page_number = n; }
140114402Sru  int begin_page(vunits = V0);
14175584Sru  void set_next_page_number(int);
14275584Sru  void set_page_length(vunits);
14375584Sru  void copy_file(const char *filename);
14475584Sru  int get_ejecting() { return ejecting_page; }
14575584Sru  void set_ejecting() { ejecting_page = 1; }
14675584Sru  friend void page_offset();
14775584Sru  void set_diversion_trap(symbol, vunits);
14875584Sru  void clear_diversion_trap();
14975584Sru  void set_last_page() { last_page_count = page_count; }
150151497Sru  int is_diversion() { return 0; }
15175584Sru};
15275584Sru
15375584Sruextern top_level_diversion *topdiv;
15475584Sruextern diversion *curdiv;
15575584Sru
15675584Sruextern int exit_started;
15775584Sruextern int done_end_macro;
15875584Sruextern int last_page_number;
15975584Sruextern int seen_last_page_ejector;
16075584Sru
16175584Sruvoid spring_trap(symbol);	// implemented by input.c
16275584Sruextern int trap_sprung_flag;
16375584Sruvoid postpone_traps();
16475584Sruint unpostpone_traps();
16575584Sru
16675584Sruvoid push_page_ejector();
16775584Sruvoid continue_page_eject();
16875584Sruvoid handle_first_page_transition();
16975584Sruvoid blank_line();
170104862Sruvoid begin_page();
17175584Sru
17275584Sruextern void cleanup_and_exit(int);
173