Line data Source code
1 : /* Copyright 1989-2025 Free Software Foundation, Inc. 2 : Written by James Clark (jjc@jclark.com) 3 : 4 : This file is part of groff, the GNU roff typesetting system. 5 : 6 : groff is free software; you can redistribute it and/or modify it under 7 : the terms of the GNU General Public License as published by the Free 8 : Software Foundation, either version 3 of the License, or 9 : (at your option) any later version. 10 : 11 : groff is distributed in the hope that it will be useful, but WITHOUT ANY 12 : WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 : FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 : for more details. 15 : 16 : You should have received a copy of the GNU General Public License 17 : along with this program. If not, see <http://www.gnu.org/licenses/>. */ 18 : 19 : void do_divert(bool /* appending */, bool /* boxing */); 20 : void end_diversions(); 21 : 22 : class diversion { 23 : friend void do_divert(bool /* appending */, bool /* boxing */); 24 : friend void end_diversions(); 25 : diversion *prev; 26 : node *saved_line; 27 : hunits saved_width_total; 28 : int saved_space_total; 29 : hunits saved_saved_indent; 30 : hunits saved_target_text_length; 31 : int saved_was_previous_line_interrupted; // three-valued Boolean :-| 32 : protected: 33 : symbol nm; 34 : vunits vertical_position; 35 : vunits high_water_mark; 36 : public: 37 : bool is_box; 38 : bool is_in_no_space_mode; 39 : bool saved_seen_break; // XXX: nilpotent? 40 : bool saved_seen_space; // XXX: nilpotent? 41 : bool saved_seen_eol; // XXX: nilpotent? 42 : bool saved_suppress_next_eol; // XXX: nilpotent? 43 : state_set modified_tag; 44 : vunits marked_place; 45 : diversion(symbol /* s */ = NULL_SYMBOL, bool /* boxing */ = false); 46 : virtual ~diversion(); 47 : virtual void output(node * /* nd */, bool /* retain_size */, 48 : vunits /* vs */, vunits /* post_vs */, 49 : hunits /* width */) = 0; 50 : virtual void transparent_output(unsigned char) = 0; 51 : virtual void transparent_output(node *) = 0; 52 : virtual void space(vunits distance, bool /* forcing */ = 0) = 0; 53 : #ifdef COLUMN 54 : virtual void vjustify(symbol) = 0; 55 : #endif /* COLUMN */ 56 67913 : vunits get_vertical_position() { return vertical_position; } 57 216 : vunits get_high_water_mark() { return high_water_mark; } 58 : virtual vunits distance_to_next_trap() = 0; 59 : virtual const char * get_next_trap_name() = 0; 60 : void need(vunits); 61 127653 : const char *get_diversion_name() { return nm.contents(); } 62 : virtual void set_diversion_trap(symbol, vunits) = 0; 63 : virtual void clear_diversion_trap() = 0; 64 : virtual void copy_file(const char *filename) = 0; 65 : virtual bool is_diversion() = 0; 66 : }; 67 : 68 : class macro; 69 : 70 : class macro_diversion : public diversion { 71 : macro *mac; 72 : hunits max_width; 73 : symbol diversion_trap; 74 : vunits diversion_trap_pos; 75 : public: 76 : macro_diversion(symbol, bool /* appending */, bool /* boxing */); 77 : ~macro_diversion(); 78 : void output(node * /* nd */, bool /* retain_size */, vunits /* vs */, 79 : vunits /* post_vs */, hunits /* width */); 80 : void transparent_output(unsigned char); 81 : void transparent_output(node *); 82 : void space(vunits distance, bool /* forcing */ = 0); 83 : #ifdef COLUMN 84 : void vjustify(symbol); 85 : #endif /* COLUMN */ 86 : vunits distance_to_next_trap(); 87 : const char *get_next_trap_name(); 88 : void set_diversion_trap(symbol, vunits); 89 : void clear_diversion_trap(); 90 : void copy_file(const char *filename); 91 0 : bool is_diversion() { return true; } 92 : }; 93 : 94 : struct trap { 95 : trap *next; 96 : vunits position; 97 : symbol nm; 98 : trap(symbol, vunits, trap *); 99 : }; 100 : 101 : class output_file; 102 : 103 : class top_level_diversion : public diversion { 104 : int page_number; 105 : int page_count; 106 : int last_page_count; 107 : vunits page_length; 108 : hunits prev_page_offset; 109 : hunits page_offset; 110 : trap *page_trap_list; 111 : trap *find_next_trap(vunits *); 112 : bool overriding_next_page_number; 113 : int next_page_number; 114 : bool ejecting_page; 115 : public: 116 : int before_first_page_status; // three-valued Boolean :-| 117 : top_level_diversion(); 118 : void output(node * /* nd */, bool /* retain_size */, vunits /* vs */, 119 : vunits /* post_vs */, hunits /* width */); 120 : void transparent_output(unsigned char); 121 : void transparent_output(node *); 122 : void space(vunits distance, bool /* forcing */ = false); 123 : #ifdef COLUMN 124 : void vjustify(symbol); 125 : #endif /* COLUMN */ 126 111636 : hunits get_page_offset() { return page_offset; } 127 42 : hunits get_previous_page_offset() { return prev_page_offset; } 128 : void set_page_offset(hunits /* h */); 129 9250 : vunits get_page_length() { return page_length; } 130 : vunits distance_to_next_trap(); 131 : const char *get_next_trap_name(); 132 : void add_trap(symbol nm, vunits pos); 133 : void change_trap(symbol nm, vunits pos); 134 : void remove_trap(symbol); 135 : void remove_trap_at(vunits pos); 136 : void print_traps(); 137 : int get_page_count() { return page_count; } 138 5582 : int get_page_number() { return page_number; } 139 : int get_next_page_number(); 140 35 : void set_page_number(int n) { page_number = n; } 141 : bool begin_page(vunits = V0); 142 : void set_next_page_number(int); 143 : void set_page_length(vunits); 144 : void copy_file(const char *filename); 145 4868 : bool get_ejecting() { return ejecting_page; } 146 3200 : void set_ejecting() { ejecting_page = true; } 147 : friend void page_offset(); 148 : void set_diversion_trap(symbol, vunits); 149 : void clear_diversion_trap(); 150 1403 : void set_last_page() { last_page_count = page_count; } 151 0 : bool is_diversion() { return false; } 152 : }; 153 : 154 5078 : inline void top_level_diversion::set_page_offset(hunits h) 155 : { 156 5078 : prev_page_offset = page_offset; 157 5078 : page_offset = h; 158 5078 : } 159 : 160 : extern top_level_diversion *topdiv; 161 : extern diversion *curdiv; 162 : 163 : extern bool is_exit_underway; 164 : extern bool is_eoi_macro_finished; 165 : extern bool seen_last_page_ejector; 166 : extern int last_page_number; 167 : 168 : void spring_trap(symbol); // implemented by input.c 169 : extern bool was_trap_sprung; 170 : void postpone_traps(); 171 : bool unpostpone_traps(); 172 : 173 : void push_page_ejector(); 174 : void continue_page_eject(); 175 : void handle_first_page_transition(); 176 : void blank_line(); 177 : 178 : extern void write_any_trailer_and_exit(int /* exit_code */); 179 : 180 : // Local Variables: 181 : // fill-column: 72 182 : // mode: C++ 183 : // End: 184 : // vim: set cindent noexpandtab shiftwidth=2 textwidth=72: