1 // -*- C++ -*- 2 /* Copyright (C) 1989, 1990, 1991, 1992, 2001, 2002, 2004, 2005 3 Free Software Foundation, Inc. 4 Written by James Clark (jjc@jclark.com) 5 6 This file is part of groff. 7 8 groff is free software; you can redistribute it and/or modify it under 9 the terms of the GNU General Public License as published by the Free 10 Software Foundation; either version 2, or (at your option) any later 11 version. 12 13 groff is distributed in the hope that it will be useful, but WITHOUT ANY 14 WARRANTY; without even the implied warranty of MERCHANTABILITY or 15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 16 for more details. 17 18 You should have received a copy of the GNU General Public License along 19 with groff; see the file COPYING. If not, write to the Free Software 20 Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */ 21 22 void do_divert(int append, int boxing); 23 void end_diversions(); 24 void page_offset(); 25 26 class diversion { 27 friend void do_divert(int append, int boxing); 28 friend void end_diversions(); 29 diversion *prev; 30 node *saved_line; 31 hunits saved_width_total; 32 int saved_space_total; 33 hunits saved_saved_indent; 34 hunits saved_target_text_length; 35 int saved_prev_line_interrupted; 36 protected: 37 symbol nm; 38 vunits vertical_position; 39 vunits high_water_mark; 40 public: 41 int any_chars_added; 42 int no_space_mode; 43 int needs_push; 44 int saved_seen_break; 45 int saved_seen_space; 46 int saved_seen_eol; 47 int saved_suppress_next_eol; 48 state_set modified_tag; 49 vunits marked_place; 50 diversion(symbol s = NULL_SYMBOL); 51 virtual ~diversion(); 52 virtual void output(node *nd, int retain_size, vunits vs, vunits post_vs, 53 hunits width) = 0; 54 virtual void transparent_output(unsigned char) = 0; 55 virtual void transparent_output(node *) = 0; 56 virtual void space(vunits distance, int forced = 0) = 0; 57 #ifdef COLUMN 58 virtual void vjustify(symbol) = 0; 59 #endif /* COLUMN */ get_vertical_position()60 vunits get_vertical_position() { return vertical_position; } get_high_water_mark()61 vunits get_high_water_mark() { return high_water_mark; } 62 virtual vunits distance_to_next_trap() = 0; 63 void need(vunits); get_diversion_name()64 const char *get_diversion_name() { return nm.contents(); } 65 virtual void set_diversion_trap(symbol, vunits) = 0; 66 virtual void clear_diversion_trap() = 0; 67 virtual void copy_file(const char *filename) = 0; 68 virtual int is_diversion() = 0; 69 }; 70 71 class macro; 72 73 class macro_diversion : public diversion { 74 macro *mac; 75 hunits max_width; 76 symbol diversion_trap; 77 vunits diversion_trap_pos; 78 public: 79 macro_diversion(symbol, int); 80 ~macro_diversion(); 81 void output(node *nd, int retain_size, vunits vs, vunits post_vs, 82 hunits width); 83 void transparent_output(unsigned char); 84 void transparent_output(node *); 85 void space(vunits distance, int forced = 0); 86 #ifdef COLUMN 87 void vjustify(symbol); 88 #endif /* COLUMN */ 89 vunits distance_to_next_trap(); 90 void set_diversion_trap(symbol, vunits); 91 void clear_diversion_trap(); 92 void copy_file(const char *filename); is_diversion()93 int is_diversion() { return 1; } 94 }; 95 96 struct trap { 97 trap *next; 98 vunits position; 99 symbol nm; 100 trap(symbol, vunits, trap *); 101 }; 102 103 class output_file; 104 105 class top_level_diversion : public diversion { 106 int page_number; 107 int page_count; 108 int last_page_count; 109 vunits page_length; 110 hunits prev_page_offset; 111 hunits page_offset; 112 trap *page_trap_list; 113 trap *find_next_trap(vunits *); 114 int have_next_page_number; 115 int next_page_number; 116 int ejecting_page; // Is the current page being ejected? 117 public: 118 int before_first_page; 119 top_level_diversion(); 120 void output(node *nd, int retain_size, vunits vs, vunits post_vs, 121 hunits width); 122 void transparent_output(unsigned char); 123 void transparent_output(node *); 124 void space(vunits distance, int forced = 0); 125 #ifdef COLUMN 126 void vjustify(symbol); 127 #endif /* COLUMN */ get_page_offset()128 hunits get_page_offset() { return page_offset; } get_page_length()129 vunits get_page_length() { return page_length; } 130 vunits distance_to_next_trap(); 131 void add_trap(symbol nm, vunits pos); 132 void change_trap(symbol nm, vunits pos); 133 void remove_trap(symbol); 134 void remove_trap_at(vunits pos); 135 void print_traps(); get_page_count()136 int get_page_count() { return page_count; } get_page_number()137 int get_page_number() { return page_number; } 138 int get_next_page_number(); set_page_number(int n)139 void set_page_number(int n) { page_number = n; } 140 int begin_page(vunits = V0); 141 void set_next_page_number(int); 142 void set_page_length(vunits); 143 void copy_file(const char *filename); get_ejecting()144 int get_ejecting() { return ejecting_page; } set_ejecting()145 void set_ejecting() { ejecting_page = 1; } 146 friend void page_offset(); 147 void set_diversion_trap(symbol, vunits); 148 void clear_diversion_trap(); set_last_page()149 void set_last_page() { last_page_count = page_count; } is_diversion()150 int is_diversion() { return 0; } 151 }; 152 153 extern top_level_diversion *topdiv; 154 extern diversion *curdiv; 155 156 extern int exit_started; 157 extern int done_end_macro; 158 extern int last_page_number; 159 extern int seen_last_page_ejector; 160 161 void spring_trap(symbol); // implemented by input.c 162 extern int trap_sprung_flag; 163 void postpone_traps(); 164 int unpostpone_traps(); 165 166 void push_page_ejector(); 167 void continue_page_eject(); 168 void handle_first_page_transition(); 169 void blank_line(); 170 void begin_page(); 171 172 extern void cleanup_and_exit(int); 173