📄 div.cc
字号:
} else return 0;}void continue_page_eject(){ if (topdiv->get_ejecting()) { if (curdiv != topdiv) error("can't continue page ejection because of current diversion"); else if (!vertical_position_traps_flag) error("can't continue page ejection because vertical position traps disabled"); else { push_page_ejector(); topdiv->space(topdiv->get_page_length(), 1); } }}void top_level_diversion::set_next_page_number(int n){ next_page_number= n; have_next_page_number = 1;}int top_level_diversion::get_next_page_number(){ return have_next_page_number ? next_page_number : page_number + 1;}void top_level_diversion::set_page_length(vunits n){ page_length = n;}diversion::~diversion(){}void page_offset(){ hunits n; if (!has_arg() || !get_hunits(&n, 'v', topdiv->page_offset)) n = topdiv->prev_page_offset; topdiv->prev_page_offset = topdiv->page_offset; topdiv->page_offset = n; skip_line();}void page_length(){ vunits n; if (has_arg() && get_vunits(&n, 'v', topdiv->get_page_length())) topdiv->set_page_length(n); else topdiv->set_page_length(11*units_per_inch); skip_line();}void when_request(){ vunits n; if (get_vunits(&n, 'v')) { symbol s = get_name(); if (s.is_null()) topdiv->remove_trap_at(n); else topdiv->add_trap(s, n); } skip_line();}void begin_page(){ int got_arg = 0; int n; if (has_arg() && get_integer(&n, topdiv->get_page_number())) got_arg = 1; while (!tok.newline() && !tok.eof()) tok.next(); if (curdiv == topdiv) { if (topdiv->before_first_page) { if (!break_flag) { if (got_arg) topdiv->set_next_page_number(n); if (got_arg || !topdiv->no_space_mode) topdiv->begin_page(); } else if (topdiv->no_space_mode && !got_arg) topdiv->begin_page(); else { /* Given this .wh 0 x .de x .tm \\n% .. .bp 3 troff prints 1 3 This code makes groff do the same. */ push_page_ejector(); topdiv->begin_page(); if (got_arg) topdiv->set_next_page_number(n); topdiv->set_ejecting(); } } else { push_page_ejector(); if (break_flag) curenv->do_break(); if (got_arg) topdiv->set_next_page_number(n); if (!(topdiv->no_space_mode && !got_arg)) topdiv->set_ejecting(); } } tok.next();}void no_space(){ if (curdiv == topdiv) topdiv->no_space_mode = 1; skip_line();}void restore_spacing(){ if (curdiv == topdiv) topdiv->no_space_mode = 0; skip_line();}/* It is necessary to generate a break before before reading the argument,because otherwise arguments using | will be wrong. But if we justgenerate a break as usual, then the line forced out may spring a trapand thus push a macro onto the input stack before we have had a chanceto read the argument to the sp request. We resolve this dilemma bysetting, before generating the break, a flag which will postpone theactual pushing of the macro associated with the trap sprung by theoutputting of the line forced out by the break till after we have readthe argument to the request. If the break did cause a trap to besprung, then we don't actually do the space. */void space_request(){ postpone_traps(); if (break_flag) curenv->do_break(); vunits n; if (!has_arg() || !get_vunits(&n, 'v')) n = curenv->get_vertical_spacing(); while (!tok.newline() && !tok.eof()) tok.next(); if (!unpostpone_traps()) curdiv->space(n); else // The line might have had line spacing that was truncated. truncated_space += n; tok.next();}void blank_line(){ curenv->do_break(); if (!trap_sprung_flag) curdiv->space(curenv->get_vertical_spacing()); else truncated_space += curenv->get_vertical_spacing();}/* need_space might spring a trap and so we must be careful that theBEGIN_TRAP token is not skipped over. */void need_space(){ vunits n; if (!has_arg() || !get_vunits(&n, 'v')) n = curenv->get_vertical_spacing(); while (!tok.newline() && !tok.eof()) tok.next(); curdiv->need(n); tok.next();}void page_number(){ int n; if (has_arg() && get_integer(&n, topdiv->get_page_number())) topdiv->set_next_page_number(n); skip_line();}vunits saved_space;void save_vertical_space(){ vunits x; if (get_vunits(&x, 'v')) { if (curdiv->distance_to_next_trap() > x) curdiv->space(x, 1); else saved_space = x; } skip_line();}void output_saved_vertical_space(){ while (!tok.newline() && !tok.eof()) tok.next(); if (saved_space > V0) curdiv->space(saved_space, 1); saved_space = V0; tok.next();}void flush_output(){ while (!tok.newline() && !tok.eof()) tok.next(); if (break_flag) curenv->do_break(); if (the_output) the_output->flush(); tok.next();}void macro_diversion::set_diversion_trap(symbol s, vunits n){ diversion_trap = s; diversion_trap_pos = n;}void macro_diversion::clear_diversion_trap(){ diversion_trap = NULL_SYMBOL;}void top_level_diversion::set_diversion_trap(symbol, vunits){ error("can't set diversion trap when no current diversion");}void top_level_diversion::clear_diversion_trap(){ error("can't set diversion trap when no current diversion");}void diversion_trap(){ vunits n; if (has_arg() && get_vunits(&n, 'v')) { symbol s = get_name(); if (!s.is_null()) curdiv->set_diversion_trap(s, n); else curdiv->clear_diversion_trap(); } else curdiv->clear_diversion_trap(); skip_line();}void change_trap(){ symbol s = get_name(1); if (!s.is_null()) { vunits x; if (has_arg() && get_vunits(&x, 'v')) topdiv->change_trap(s, x); else topdiv->remove_trap(s); } skip_line();}void print_traps(){ topdiv->print_traps(); skip_line();}void mark(){ symbol s = get_name(); if (s.is_null()) curdiv->marked_place = curdiv->get_vertical_position(); else if (curdiv == topdiv) set_number_reg(s, nl_reg_contents); else set_number_reg(s, curdiv->get_vertical_position().to_units()); skip_line();}// This is truly bizarre. It is documented in the SQ manual.void return_request(){ vunits dist = curdiv->marked_place - curdiv->get_vertical_position(); if (has_arg()) { if (tok.ch() == '-') { tok.next(); vunits x; if (get_vunits(&x, 'v')) dist = -x; } else { vunits x; if (get_vunits(&x, 'v')) dist = x >= V0 ? x - curdiv->get_vertical_position() : V0; } } if (dist < V0) curdiv->space(dist); skip_line();}void vertical_position_traps(){ int n; if (has_arg() && get_integer(&n)) vertical_position_traps_flag = (n != 0); else vertical_position_traps_flag = 1; skip_line();}class page_offset_reg : public reg {public: int get_value(units *); const char *get_string();}; int page_offset_reg::get_value(units *res){ *res = topdiv->get_page_offset().to_units(); return 1;}const char *page_offset_reg::get_string(){ return itoa(topdiv->get_page_offset().to_units());}class page_length_reg : public reg {public: int get_value(units *); const char *get_string();}; int page_length_reg::get_value(units *res){ *res = topdiv->get_page_length().to_units(); return 1;}const char *page_length_reg::get_string(){ return itoa(topdiv->get_page_length().to_units());}class vertical_position_reg : public reg {public: int get_value(units *); const char *get_string();}; int vertical_position_reg::get_value(units *res){ if (curdiv == topdiv && topdiv->before_first_page) *res = -1; else *res = curdiv->get_vertical_position().to_units(); return 1;}const char *vertical_position_reg::get_string(){ if (curdiv == topdiv && topdiv->before_first_page) return "-1"; else return itoa(curdiv->get_vertical_position().to_units());}class high_water_mark_reg : public reg {public: int get_value(units *); const char *get_string();}; int high_water_mark_reg::get_value(units *res){ *res = curdiv->get_high_water_mark().to_units(); return 1;}const char *high_water_mark_reg::get_string(){ return itoa(curdiv->get_high_water_mark().to_units());}class distance_to_next_trap_reg : public reg {public: int get_value(units *); const char *get_string();}; int distance_to_next_trap_reg::get_value(units *res){ *res = curdiv->distance_to_next_trap().to_units(); return 1;}const char *distance_to_next_trap_reg::get_string(){ return itoa(curdiv->distance_to_next_trap().to_units());}class diversion_name_reg : public reg {public: const char *get_string();};const char *diversion_name_reg::get_string(){ return curdiv->get_diversion_name();}class page_number_reg : public general_reg {public: page_number_reg(); int get_value(units *); void set_value(units);};page_number_reg::page_number_reg(){}void page_number_reg::set_value(units n){ topdiv->set_page_number(n);}int page_number_reg::get_value(units *res){ *res = topdiv->get_page_number(); return 1;}class next_page_number_reg : public reg {public: const char *get_string();};const char *next_page_number_reg::get_string(){ return itoa(topdiv->get_next_page_number());}class page_ejecting_reg : public reg {public: const char *get_string();};const char *page_ejecting_reg::get_string(){ return itoa(topdiv->get_ejecting());}class constant_vunits_reg : public reg { vunits *p;public: constant_vunits_reg(vunits *); const char *get_string();};constant_vunits_reg::constant_vunits_reg(vunits *q) : p(q){}const char *constant_vunits_reg::get_string(){ return itoa(p->to_units());}class nl_reg : public variable_reg {public: nl_reg(); void set_value(units);};nl_reg::nl_reg() : variable_reg(&nl_reg_contents){}void nl_reg::set_value(units n){ variable_reg::set_value(n); // Setting nl to a negative value when the vertical position in // the top-level diversion is 0 undoes the top of page transition, // so that the header macro will be called as if the top of page // transition hasn't happened. This is used by Larry Wall's // wrapman program. Setting before_first_page to 2 rather than 1, // tells top_level_diversion::begin_page not to call // output_file::begin_page again. if (n < 0 && topdiv->get_vertical_position() == V0) topdiv->before_first_page = 2;}void init_div_requests(){ init_request("wh", when_request); init_request("ch", change_trap); init_request("pl", page_length); init_request("po", page_offset); init_request("rs", restore_spacing); init_request("ns", no_space); init_request("sp", space_request); init_request("di", divert); init_request("da", divert_append); init_request("bp", begin_page); init_request("ne", need_space); init_request("pn", page_number); init_request("dt", diversion_trap); init_request("rt", return_request); init_request("mk", mark); init_request("sv", save_vertical_space); init_request("os", output_saved_vertical_space); init_request("fl", flush_output); init_request("vpt", vertical_position_traps); init_request("ptr", print_traps); number_reg_dictionary.define(".a", new constant_int_reg(&last_post_line_extra_space)); number_reg_dictionary.define(".z", new diversion_name_reg); number_reg_dictionary.define(".o", new page_offset_reg); number_reg_dictionary.define(".p", new page_length_reg); number_reg_dictionary.define(".d", new vertical_position_reg); number_reg_dictionary.define(".h", new high_water_mark_reg); number_reg_dictionary.define(".t", new distance_to_next_trap_reg); number_reg_dictionary.define("dl", new variable_reg(&dl_reg_contents)); number_reg_dictionary.define("dn", new variable_reg(&dn_reg_contents)); number_reg_dictionary.define("nl", new nl_reg); number_reg_dictionary.define(".vpt", new constant_int_reg(&vertical_position_traps_flag)); number_reg_dictionary.define("%", new page_number_reg); number_reg_dictionary.define(".pn", new next_page_number_reg); number_reg_dictionary.define(".trunc", new constant_vunits_reg(&truncated_space)); number_reg_dictionary.define(".ne", new constant_vunits_reg(&needed_space)); number_reg_dictionary.define(".pe", new page_ejecting_reg);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -