diff options
Diffstat (limited to 'contrib/groff/src/roff/troff')
-rw-r--r-- | contrib/groff/src/roff/troff/dictionary.cc | 8 | ||||
-rw-r--r-- | contrib/groff/src/roff/troff/div.cc | 39 | ||||
-rw-r--r-- | contrib/groff/src/roff/troff/div.h | 2 | ||||
-rw-r--r-- | contrib/groff/src/roff/troff/env.cc | 21 | ||||
-rw-r--r-- | contrib/groff/src/roff/troff/env.h | 3 | ||||
-rw-r--r-- | contrib/groff/src/roff/troff/input.cc | 191 | ||||
-rw-r--r-- | contrib/groff/src/roff/troff/input.h | 4 | ||||
-rw-r--r-- | contrib/groff/src/roff/troff/node.h | 2 | ||||
-rw-r--r-- | contrib/groff/src/roff/troff/reg.cc | 5 | ||||
-rw-r--r-- | contrib/groff/src/roff/troff/token.h | 2 | ||||
-rw-r--r-- | contrib/groff/src/roff/troff/troff.man | 35 |
11 files changed, 251 insertions, 61 deletions
diff --git a/contrib/groff/src/roff/troff/dictionary.cc b/contrib/groff/src/roff/troff/dictionary.cc index 169536c..bca3845 100644 --- a/contrib/groff/src/roff/troff/dictionary.cc +++ b/contrib/groff/src/roff/troff/dictionary.cc @@ -1,5 +1,5 @@ // -*- C++ -*- -/* Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc. +/* Copyright (C) 1989, 1990, 1991, 1992, 2001 Free Software Foundation, Inc. Written by James Clark (jjc@jclark.com) This file is part of groff. @@ -25,10 +25,10 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // is `p' a good size for a hash table -static int is_good_size(int p) +static int is_good_size(unsigned int p) { - const int SMALL = 10; - unsigned i; + const unsigned int SMALL = 10; + unsigned int i; for (i = 2; i <= p/2; i++) if (p % i == 0) return 0; diff --git a/contrib/groff/src/roff/troff/div.cc b/contrib/groff/src/roff/troff/div.cc index 281c1af..c885ca8 100644 --- a/contrib/groff/src/roff/troff/div.cc +++ b/contrib/groff/src/roff/troff/div.cc @@ -49,7 +49,8 @@ static vunits truncated_space; static vunits needed_space; diversion::diversion(symbol s) -: prev(0), nm(s), vertical_position(V0), high_water_mark(V0), marked_place(V0) +: prev(0), nm(s), vertical_position(V0), high_water_mark(V0), + no_space_mode(0), marked_place(V0) { } @@ -249,6 +250,7 @@ void macro_diversion::transparent_output(node *n) void macro_diversion::output(node *nd, int retain_size, vunits vs, vunits post_vs, hunits width) { + no_space_mode = 0; vertical_size v(vs, post_vs); while (nd != 0) { nd->set_vertical_size(&v); @@ -316,7 +318,7 @@ top_level_diversion::top_level_diversion() page_length(units_per_inch*11), prev_page_offset(units_per_inch), page_offset(units_per_inch), page_trap_list(0), have_next_page_number(0), - ejecting_page(0), before_first_page(1), no_space_mode(0) + ejecting_page(0), before_first_page(1) { } @@ -722,15 +724,13 @@ void begin_page() void no_space() { - if (curdiv == topdiv) - topdiv->no_space_mode = 1; + curdiv->no_space_mode = 1; skip_line(); } void restore_spacing() { - if (curdiv == topdiv) - topdiv->no_space_mode = 0; + curdiv->no_space_mode = 0; skip_line(); } @@ -755,8 +755,8 @@ void space_request() n = curenv->get_vertical_spacing(); while (!tok.newline() && !tok.eof()) tok.next(); - if (!unpostpone_traps()) - curdiv->space(n); + if (!unpostpone_traps() && !curdiv->no_space_mode) + curdiv->space(n); else // The line might have had line spacing that was truncated. truncated_space += n; @@ -767,9 +767,10 @@ void space_request() void blank_line() { curenv->do_break(); - if (!trap_sprung_flag) + if (!trap_sprung_flag && !curdiv->no_space_mode) { curdiv->space(curenv->get_vertical_spacing()); - else + curenv->add_html_tag(".sp", 1); + } else truncated_space += curenv->get_vertical_spacing(); } @@ -1114,6 +1115,23 @@ void nl_reg::set_value(units n) topdiv->before_first_page = 2; } +class no_space_mode_reg : public reg { +public: + int get_value(units *); + const char *get_string(); +}; + +int no_space_mode_reg::get_value(units *val) +{ + *val = curdiv->no_space_mode; + return 1; +} + +const char *no_space_mode_reg::get_string() +{ + return curdiv->no_space_mode ? "1" : "0"; +} + void init_div_requests() { init_request("wh", when_request); @@ -1143,6 +1161,7 @@ void init_div_requests() 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(".ns", new no_space_mode_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); diff --git a/contrib/groff/src/roff/troff/div.h b/contrib/groff/src/roff/troff/div.h index 83f9e33..3b726c3 100644 --- a/contrib/groff/src/roff/troff/div.h +++ b/contrib/groff/src/roff/troff/div.h @@ -33,6 +33,7 @@ protected: vunits vertical_position; vunits high_water_mark; public: + int no_space_mode; vunits marked_place; diversion(symbol s = NULL_SYMBOL); virtual ~diversion(); @@ -101,7 +102,6 @@ class top_level_diversion : public diversion { int ejecting_page; // Is the current page being ejected? public: int before_first_page; - int no_space_mode; top_level_diversion(); void output(node *nd, int retain_size, vunits vs, vunits post_vs, hunits width); diff --git a/contrib/groff/src/roff/troff/env.cc b/contrib/groff/src/roff/troff/env.cc index 56f357c..c0743441 100644 --- a/contrib/groff/src/roff/troff/env.cc +++ b/contrib/groff/src/roff/troff/env.cc @@ -1117,7 +1117,7 @@ void point_size() void space_size() { int n; - if (get_integer(&n) && !compatible_flag) { + if (get_integer(&n)) { curenv->space_size = n; if (has_arg() && get_integer(&n)) curenv->sentence_space_size = n; @@ -2135,7 +2135,7 @@ void environment::add_html_tag_tabs() } } -void environment::do_break() +void environment::do_break(int spread) { if (curdiv == topdiv && topdiv->before_first_page) { topdiv->begin_page(); @@ -2146,7 +2146,7 @@ void environment::do_break() if (line) { line = new space_node(H0, line); // this is so that hyphenation works space_total++; - possibly_break_line(); + possibly_break_line(0, spread); } while (line != 0 && line->discardable()) { width_total -= line->width(); @@ -2185,17 +2185,27 @@ int environment::is_empty() return !current_tab && line == 0 && pending_lines == 0; } -void break_request() +void do_break_request(int spread) { while (!tok.newline() && !tok.eof()) tok.next(); if (break_flag) { - curenv->do_break(); + curenv->do_break(spread); curenv->add_html_tag(".br"); } tok.next(); } +void break_request() +{ + do_break_request(0); +} + +void break_spread_request() +{ + do_break_request(1); +} + void title() { if (curdiv == topdiv && topdiv->before_first_page) { @@ -3014,6 +3024,7 @@ void init_env_requests() init_request("cc", control_char); init_request("c2", no_break_control_char); init_request("br", break_request); + init_request("brp", break_spread_request); init_request("tl", title); init_request("ta", set_tabs); init_request("linetabs", line_tabs_request); diff --git a/contrib/groff/src/roff/troff/env.h b/contrib/groff/src/roff/troff/env.h index 256db51..851a9a0 100644 --- a/contrib/groff/src/roff/troff/env.h +++ b/contrib/groff/src/roff/troff/env.h @@ -275,7 +275,7 @@ public: void interrupt(); void spread() { spread_flag = 1; } void possibly_break_line(int start_here = 0, int forced = 0); - void do_break(); // .br + void do_break(int spread = 0); // .br void final_break(); void add_html_tag_eol(); void add_html_tag(const char *); @@ -345,6 +345,5 @@ void init_environments(); void read_hyphen_file(const char *name); extern int break_flag; -extern int compatible_flag; extern symbol default_family; extern int translate_space_to_dummy; diff --git a/contrib/groff/src/roff/troff/input.cc b/contrib/groff/src/roff/troff/input.cc index 982e5bd..54aaa3f 100644 --- a/contrib/groff/src/roff/troff/input.cc +++ b/contrib/groff/src/roff/troff/input.cc @@ -73,6 +73,8 @@ extern "C" { // initial size of buffer for reading names; expanded as necessary #define ABUF_SIZE 16 +extern "C" const char *Version_string; + #ifdef COLUMN void init_column_requests(); #endif /* COLUMN */ @@ -106,7 +108,7 @@ static void disable_warning(const char *); static int escape_char = '\\'; static symbol end_macro_name; static symbol blank_line_macro_name; -int compatible_flag = 0; +static int compatible_flag = 0; int ascii_output_flag = 0; int suppress_output_flag = 0; int is_html = 0; @@ -133,6 +135,7 @@ static void interpolate_arg(symbol); static request_or_macro *lookup_request(symbol); static int get_delim_number(units *, int); static int get_delim_number(units *, int, units); +static symbol get_delim_file_name(); static int get_line_arg(units *res, int si, charinfo **cp); static int read_size(int *); static symbol get_delim_name(); @@ -206,6 +209,8 @@ private: virtual int internal_level() { return 0; } virtual int is_file() { return 0; } virtual int is_macro() { return 0; } + virtual void save_compatible_flag(int) {} + virtual int get_compatible_flag() { return 0; } }; input_iterator::input_iterator() @@ -406,6 +411,8 @@ public: static int get_level(); static void clear(); static void pop_macro(); + static void save_compatible_flag(int); + static int get_compatible_flag(); static int limit; private: @@ -626,6 +633,16 @@ void input_stack::pop_macro() add_return_boundary(); } +inline void input_stack::save_compatible_flag(int f) +{ + top->save_compatible_flag(f); +} + +inline int input_stack::get_compatible_flag() +{ + return top->get_compatible_flag(); +} + void backtrace_request() { input_stack::backtrace_all(); @@ -1272,6 +1289,13 @@ void token::next() if (cc != escape_char || escape_char == 0) { handle_normal_char: switch(cc) { + case COMPATIBLE_SAVE: + input_stack::save_compatible_flag(compatible_flag); + compatible_flag = 0; + continue; + case COMPATIBLE_RESTORE: + compatible_flag = input_stack::get_compatible_flag(); + continue; case EOF: type = TOKEN_EOF; return; @@ -2049,14 +2073,14 @@ static void trapping_blank_line() void do_request() { - int saved_compatible_flag = compatible_flag; + int old_compatible_flag = compatible_flag; compatible_flag = 0; symbol nm = get_name(); if (nm.is_null()) skip_line(); else interpolate_macro(nm); - compatible_flag = saved_compatible_flag; + compatible_flag = old_compatible_flag; } inline int possibly_handle_first_page_transition() @@ -2701,6 +2725,7 @@ class string_iterator : public input_iterator { char_block *bp; int count; // of characters remaining node *nd; + int saved_compatible_flag; protected: symbol nm; string_iterator(); @@ -2710,6 +2735,8 @@ public: int peek(); int get_location(int, const char **, int *); void backtrace(); + void save_compatible_flag(int f) { saved_compatible_flag = f; } + int get_compatible_flag() { return saved_compatible_flag; } }; string_iterator::string_iterator(const macro &m, const char *p, symbol s) @@ -3447,11 +3474,12 @@ void handle_initial_title() static symbol dot_symbol("."); enum define_mode { DEFINE_NORMAL, DEFINE_APPEND, DEFINE_IGNORE }; +enum calling_mode { CALLING_NORMAL, CALLING_INDIRECT, CALLING_DISABLE_COMP }; -void do_define_macro(define_mode mode, int indirect) +void do_define_macro(define_mode mode, calling_mode calling) { symbol nm, term; - if (indirect) { + if (calling == CALLING_INDIRECT) { symbol temp1 = get_name(1); if (temp1.is_null()) { skip_line(); @@ -3497,6 +3525,8 @@ void do_define_macro(define_mode mode, int indirect) mac = *mm; } int bol = 1; + if (calling == CALLING_DISABLE_COMP) + mac.append(COMPATIBLE_SAVE); for (;;) { while (c == ESCAPE_NEWLINE) { if (mode == DEFINE_NORMAL || mode == DEFINE_APPEND) @@ -3505,7 +3535,7 @@ void do_define_macro(define_mode mode, int indirect) } if (bol && c == '.') { const char *s = term.contents(); - int d; + int d = 0; // see if it matches term int i; for (i = 0; s[i] != 0; i++) { @@ -3517,25 +3547,27 @@ void do_define_macro(define_mode mode, int indirect) && ((i == 2 && compatible_flag) || (d = get_copy(&n)) == ' ' || d == '\n')) { // we found it - if (d == '\n') - tok.make_newline(); - else - tok.make_space(); - if (mode == DEFINE_APPEND || mode == DEFINE_NORMAL) { - if (!mm) { - mm = new macro; - request_dictionary.define(nm, mm); - } - *mm = mac; - } - if (term != dot_symbol) { - ignoring = 0; - interpolate_macro(term); - } - else - skip_line(); - return; - } + if (d == '\n') + tok.make_newline(); + else + tok.make_space(); + if (mode == DEFINE_APPEND || mode == DEFINE_NORMAL) { + if (!mm) { + mm = new macro; + request_dictionary.define(nm, mm); + } + if (calling == CALLING_DISABLE_COMP) + mac.append(COMPATIBLE_RESTORE); + *mm = mac; + } + if (term != dot_symbol) { + ignoring = 0; + interpolate_macro(term); + } + else + skip_line(); + return; + } if (mode == DEFINE_APPEND || mode == DEFINE_NORMAL) { mac.append(c); for (int j = 0; j < i; j++) @@ -3575,23 +3607,33 @@ void do_define_macro(define_mode mode, int indirect) void define_macro() { - do_define_macro(DEFINE_NORMAL, 0); + do_define_macro(DEFINE_NORMAL, CALLING_NORMAL); +} + +void define_nocomp_macro() +{ + do_define_macro(DEFINE_NORMAL, CALLING_DISABLE_COMP); } void define_indirect_macro() { - do_define_macro(DEFINE_NORMAL, 1); + do_define_macro(DEFINE_NORMAL, CALLING_INDIRECT); } void append_macro() { - do_define_macro(DEFINE_APPEND, 0); + do_define_macro(DEFINE_APPEND, CALLING_NORMAL); +} + +void append_nocomp_macro() +{ + do_define_macro(DEFINE_APPEND, CALLING_DISABLE_COMP); } void ignore() { ignoring = 1; - do_define_macro(DEFINE_IGNORE, 0); + do_define_macro(DEFINE_IGNORE, CALLING_NORMAL); ignoring = 0; } @@ -3954,6 +3996,11 @@ static int read_size(int *x) if (!bad) { switch (inc) { case 0: + if (val == 0) { + // special case -- \s[0] and \s0 means to revert to previous size + *x = 0; + return 1; + } *x = val; break; case 1: @@ -3965,6 +4012,11 @@ static int read_size(int *x) default: assert(0); } + if (*x <= 0) { + warning(WARN_RANGE, + "\\s request results in non-positive point size; set to 1"); + *x = 1; + } return 1; } else { @@ -4033,6 +4085,65 @@ static symbol get_delim_name() } } +static symbol get_delim_file_name() +{ + token start; + start.next(); + if (start.eof()) { + error("end of input at start of delimited file name"); + return NULL_SYMBOL; + } + if (start.newline()) { + error("can't delimit file name with a newline"); + return NULL_SYMBOL; + } + int start_level = input_stack::get_level(); + char abuf[ABUF_SIZE]; + char *buf = abuf; + int buf_size = ABUF_SIZE; + int i = 0; + for (;;) { + if (i + 1 > buf_size) { + if (buf == abuf) { + buf = new char[ABUF_SIZE*2]; + memcpy(buf, abuf, buf_size); + buf_size = ABUF_SIZE*2; + } + else { + char *old_buf = buf; + buf = new char[buf_size*2]; + memcpy(buf, old_buf, buf_size); + buf_size *= 2; + a_delete old_buf; + } + } + tok.next(); + if (tok.ch() == ']' && input_stack::get_level() == start_level) + break; + if ((buf[i] = tok.ch()) == 0) { + error("missing delimiter (got %1)", tok.description()); + if (buf != abuf) + a_delete buf; + return NULL_SYMBOL; + } + i++; + } + buf[i] = '\0'; + if (buf == abuf) { + if (i == 0) { + error("empty delimited file name"); + return NULL_SYMBOL; + } + else + return symbol(buf); + } + else { + symbol s(buf); + a_delete buf; + return s; + } +} + // Implement \R static void do_register() @@ -4273,6 +4384,14 @@ node *do_suppress() { tok.next(); int c = tok.ch(); + if (c != '[') { + error("argument(s) of \\O must be enclosed in brackets (got %1)", + char(c)); + return 0; + } + tok.next(); + c = tok.ch(); + tok.next(); switch (c) { case '0': if (begin_level == 1) @@ -4293,7 +4412,12 @@ node *do_suppress() begin_level--; break; case '5': { - symbol filename = get_delim_name(); + symbol filename = get_delim_file_name(); + tok.next(); + if (filename.is_null()) { + error("missing filename as second argument to \\O"); + return 0; + } if (begin_level == 1) return new suppress_node(filename, 'i'); return 0; @@ -6034,12 +6158,14 @@ struct string_list { string_list(const char *ss) : s(ss), next(0) {} }; +#if 0 static void prepend_string(const char *s, string_list **p) { string_list *l = new string_list(s); l->next = *p; *p = l; } +#endif static void add_string(const char *s, string_list **p) { @@ -6095,7 +6221,6 @@ int main(int argc, char **argv) switch(c) { case 'v': { - extern const char *Version_string; printf("GNU troff (groff) version %s\n", Version_string); exit(0); break; @@ -6346,7 +6471,9 @@ void init_input_requests() init_request("as", append_string); init_request("de", define_macro); init_request("dei", define_indirect_macro); + init_request("de1", define_nocomp_macro); init_request("am", append_macro); + init_request("am1", append_nocomp_macro); init_request("ig", ignore); init_request("rm", remove_macro); init_request("rn", rename_macro); @@ -6638,7 +6765,7 @@ static struct { static int lookup_warning(const char *name) { - for (int i = 0; + for (unsigned int i = 0; i < sizeof(warning_table)/sizeof(warning_table[0]); i++) if (strcmp(name, warning_table[i].name) == 0) diff --git a/contrib/groff/src/roff/troff/input.h b/contrib/groff/src/roff/troff/input.h index 525e1ef..8d06574 100644 --- a/contrib/groff/src/roff/troff/input.h +++ b/contrib/groff/src/roff/troff/input.h @@ -54,6 +54,8 @@ const int LAST_PAGE_EJECTOR = 0205; const int ESCAPE_RIGHT_PARENTHESIS = 0206; const int ESCAPE_TILDE = 0207; const int ESCAPE_COLON = 0210; +const int COMPATIBLE_SAVE = 0211; +const int COMPATIBLE_RESTORE = 0212; #else /* IS_EBCDIC_HOST */ @@ -88,5 +90,7 @@ const int LAST_PAGE_EJECTOR = 065; const int ESCAPE_RIGHT_PARENTHESIS = 066; const int ESCAPE_TILDE = 067; const int ESCAPE_COLON = 070; +const int COMPATIBLE_SAVE = 071; +const int COMPATIBLE_RESTORE = 072; #endif /* IS_EBCDIC_HOST */ diff --git a/contrib/groff/src/roff/troff/node.h b/contrib/groff/src/roff/troff/node.h index 1dc0718..a58afed 100644 --- a/contrib/groff/src/roff/troff/node.h +++ b/contrib/groff/src/roff/troff/node.h @@ -181,9 +181,9 @@ public: }; struct width_list { - width_list *next; hunits width; hunits sentence_width; + width_list *next; width_list(hunits, hunits); width_list(width_list *); }; diff --git a/contrib/groff/src/roff/troff/reg.cc b/contrib/groff/src/roff/troff/reg.cc index 254b0ff..8ac20c9 100644 --- a/contrib/groff/src/roff/troff/reg.cc +++ b/contrib/groff/src/roff/troff/reg.cc @@ -1,5 +1,6 @@ // -*- C++ -*- -/* Copyright (C) 1989, 1990, 1991, 1992, 2000 Free Software Foundation, Inc. +/* Copyright (C) 1989, 1990, 1991, 1992, 2000, 2001 + Free Software Foundation, Inc. Written by James Clark (jjc@jclark.com) This file is part of groff. @@ -87,7 +88,7 @@ static const char *number_value_to_ascii(int value, char format, int width) case '1': if (width <= 0) return i_to_a(value); - else if (width > sizeof(buf) - 2) + else if (width > int(sizeof(buf) - 2)) sprintf(buf, "%.*d", int(sizeof(buf) - 2), int(value)); else sprintf(buf, "%.*d", width, int(value)); diff --git a/contrib/groff/src/roff/troff/token.h b/contrib/groff/src/roff/troff/token.h index 40283ad..b87a0b1 100644 --- a/contrib/groff/src/roff/troff/token.h +++ b/contrib/groff/src/roff/troff/token.h @@ -72,7 +72,7 @@ public: int space(); // is the current token a space? int stretchable_space(); // is the current token a stretchable space? int white_space(); // is the current token space or tab? - int special(); // is the current token a special character? + int special(); // is the current token a special character? int newline(); // is the current token a newline? int tab(); // is the current token a tab? int leader(); diff --git a/contrib/groff/src/roff/troff/troff.man b/contrib/groff/src/roff/troff/troff.man index 7fe052b..ac746dc 100644 --- a/contrib/groff/src/roff/troff/troff.man +++ b/contrib/groff/src/roff/troff/troff.man @@ -1,4 +1,4 @@ -.ig \"-*- nroff -*- +.ig Copyright (C) 1989-2000, 2001 Free Software Foundation, Inc. Permission is granted to make and distribute verbatim copies of @@ -739,6 +739,12 @@ requests only create a new object if the name of the macro, diversion or string diversion is currently undefined or if it is defined to be a request; normally they modify the value of an existing object. .TP +.BI .am1\ xx\ yy +Similar to +.BR .am , +but compatibility mode is switched off during execution. +On entry, the current compatibility mode is saved and restored at exit. +.TP .BI .asciify\ xx This request `unformats' the diversion .I xx @@ -810,6 +816,10 @@ Be sure not to confuse this with the .B br request. .TP +.B .brp +This is the same as +.BR \ep . +.TP .BI .cflags\ n\ c1\ c2\|.\|.\|. Characters .IR c1 , @@ -966,6 +976,12 @@ is equivalent to \&.de aa bb .RE .TP +.BI .de1\ xx\ yy +Similar to +.BR .de , +but compatibility mode is switched off during execution. +On entry, the current compatibility mode is saved and restored at exit. +.TP .BI .do\ xxx Interpret .I .xxx @@ -1709,8 +1725,7 @@ one twelfth of the spacewidth parameter for the current font. Initially both the word space size and the sentence space size are 12. Contrary to UNIX troff, GNU troff handles this request in nroff mode -also (if not in compatibility mode); a given value is then rounded down -to the nearest multiple of\~12. +also; a given value is then rounded down to the nearest multiple of\~12. The sentence space size is used in two circumstances: if the end of a sentence occurs at the end of a line in fill mode, then both an inter-word space and a sentence space will be added; @@ -1857,6 +1872,12 @@ Useful in conjunction with the .B \en[.trunc] register. .TP +.B \en[.ns] +.B 1 +if no-space mode is active, +.B 0 +otherwise. +.TP .B \en[.pn] The number of the next page: either the value set by a @@ -2445,6 +2466,10 @@ necessary. .SH "SEE ALSO" . . +.BR groff (@MAN7EXT@) +-- This is a short but complete reference of all requests, registers, and +escapes. +.PP .BR groff (@MAN1EXT@), .BR @g@tbl (@MAN1EXT@), .BR @g@pic (@MAN1EXT@), @@ -2460,3 +2485,7 @@ necessary. .BR groff_font (@MAN5EXT@), .BR groff_out (@MAN5EXT@), .BR groff_char (@MAN7EXT@) +. +.\" Local Variables: +.\" mode: nroff +.\" End: |