diff options
Diffstat (limited to 'src/roff/troff/input.cc')
-rw-r--r-- | src/roff/troff/input.cc | 199 |
1 files changed, 157 insertions, 42 deletions
diff --git a/src/roff/troff/input.cc b/src/roff/troff/input.cc index e79f17d6..aeca49c1 100644 --- a/src/roff/troff/input.cc +++ b/src/roff/troff/input.cc @@ -110,7 +110,8 @@ static symbol blank_line_macro_name; int compatible_flag = 0; int ascii_output_flag = 0; int suppress_output_flag = 0; -int is_html2 = 0; +int is_html = 0; +int html_level = 0; // number of nested .html-begin requests int tcommand_flag = 0; int safer_flag = 1; // safer by default @@ -310,8 +311,10 @@ int file_iterator::next_file(FILE *f, const char *s) int file_iterator::fill(node **) { - if (newline_flag) + if (newline_flag) { + curenv->add_html_tag_eol(); lineno++; + } newline_flag = 0; unsigned char *p = buf; ptr = p; @@ -912,6 +915,7 @@ public: int interpret(macro *); int same(node *); const char *type(); + int force_tprint(); }; int non_interpreted_char_node::same(node *nd) @@ -924,6 +928,11 @@ const char *non_interpreted_char_node::type() return "non_interpreted_char_node"; } +int non_interpreted_char_node::force_tprint() +{ + return 0; +} + non_interpreted_char_node::non_interpreted_char_node(unsigned char n) : c(n) { assert(n != 0); @@ -943,6 +952,7 @@ int non_interpreted_char_node::interpret(macro *mac) static void do_width(); static node *do_non_interpreted(); static node *do_special(); +static node *do_suppress(); static void do_register(); static node *do_overstrike() @@ -1129,6 +1139,7 @@ public: token_node *get_token_node(); int same(node *); const char *type(); + int force_tprint(); }; token_node::token_node(const token &t) : tk(t) @@ -1155,6 +1166,11 @@ const char *token_node::type() return "token_node"; } +int token_node::force_tprint() +{ + return 0; +} + token::token() : nd(0), type(TOKEN_EMPTY) { } @@ -1552,6 +1568,12 @@ void token::next() nd = do_overstrike(); type = TOKEN_NODE; return; + case 'O': + nd = do_suppress(); + if (!nd) + break; + type = TOKEN_NODE; + return; case 'p': type = TOKEN_SPREAD; return; @@ -2051,7 +2073,6 @@ int_stack::~int_stack() top = top->next; delete temp; } - } int int_stack::is_empty() @@ -2508,6 +2529,18 @@ void macro::append(unsigned char c) ++length; } +void macro::append_str(const char *s) +{ + int i = 0; + + if (s) { + while (s[i] != (char)0) { + append(s[i]); + i++; + } + } +} + void macro::append(node *n) { assert(n != 0); @@ -2524,6 +2557,23 @@ void macro::append(node *n) ++length; } +void macro::append_unsigned(unsigned int i) +{ + unsigned int j = i / 10; + if (j != 0) + append_unsigned(j); + append(((unsigned char)(((int)'0') + i % 10))); +} + +void macro::append_int(int i) +{ + if (i < 0) { + append('-'); + i = -i; + } + append_unsigned((unsigned int)i); +} + void macro::print_size() { errprint("%1", length); @@ -3991,6 +4041,7 @@ public: node *copy(); int same(node *); const char *type(); + int force_tprint(); }; non_interpreted_node::non_interpreted_node(const macro &m) : mac(m) @@ -4007,6 +4058,11 @@ const char *non_interpreted_node::type() return "non_interpreted_node"; } +int non_interpreted_node::force_tprint() +{ + return 0; +} + node *non_interpreted_node::copy() { return new non_interpreted_node(mac); @@ -4111,6 +4167,22 @@ node *do_special() return new special_node(mac); } +node *do_suppress() +{ + tok.next(); + int c = tok.ch(); + + if (c == '0') + return new suppress_node(0, 0); + else if (c == '1') + return new suppress_node(1, 0); + else if (c == '2') + return new suppress_node(1, 1); + else + error("invalid argument to \\O"); + return 0; +} + void special_node::tprint(troff_output_file *out) { tprint_start(out); @@ -4342,6 +4414,67 @@ void else_request() } } +/* + * html_begin - if this is the outermost html_begin request then execute the + * rest of the line, else skip line + */ + +void html_begin() +{ + html_level++; + if (html_level == 1) + begin_alternative(); + else + skip_alternative(); +} + +/* + * html_end - if this is the outermost html_end request then execute the + * rest of the line, else skip line + */ + +void html_end() +{ + html_level--; + if (html_level == 0) + begin_alternative(); + else + skip_alternative(); + if (html_level < 0) + html_level = 0; +} + +/* + * html_image - implements the directive `.html_image {l|r|c|i} filename' + * which places the filename into a node which is later + * written out + * + * . either as a special in the form of an image tag for -Thtml + * . or as an image region definition for all other devices + * + */ + +void html_image() +{ + if (has_arg()) { + char position = tok.ch(); + if (!(position == 'l' + || position == 'r' + || position == 'c' + || position == 'i')) { + error("l, r, c, or i expected (got %1)", tok.description()); + position = 'c'; + } + else { + tok.next(); + symbol filename = get_long_name(1); + if (!filename.is_null()) + curenv->add_node(new suppress_node(filename, position)); + } + } + skip_line(); +} + static int while_depth = 0; static int while_break_flag = 0; @@ -5832,7 +5965,7 @@ int main(int argc, char **argv) case 'T': device = optarg; tflag = 1; - is_html2 = (strcmp(device, "html2") == 0); + is_html = (strcmp(device, "html") == 0); break; case 'C': compatible_flag = 1; @@ -5946,7 +6079,7 @@ int main(int argc, char **argv) init_column_requests(); #endif /* COLUMN */ init_node_requests(); - init_output_requests(); + init_html_requests(); number_reg_dictionary.define(".T", new constant_reg(tflag ? "1" : "0")); init_registers(); init_reg_requests(); @@ -6020,69 +6153,51 @@ static void init_registers() } /* - * .output request and associated registers + * registers associated with \O */ static int output_reg_minx_contents = -1; static int output_reg_miny_contents = -1; static int output_reg_maxx_contents = -1; static int output_reg_maxy_contents = -1; +static int output_low_mark_miny = -1; // internal only (limits miny) -void check_output_limits (int x, int y) +void check_output_limits(int x, int y) { - if ((output_reg_minx_contents == -1) || (x < output_reg_minx_contents)) { + if ((output_reg_minx_contents == -1) || (x < output_reg_minx_contents)) output_reg_minx_contents = x; - } - if (x > output_reg_maxx_contents) { + if (x > output_reg_maxx_contents) output_reg_maxx_contents = x; - } - if ((output_reg_miny_contents == -1) || (y < output_reg_miny_contents)) { + if (((output_reg_miny_contents == -1) || (y < output_reg_miny_contents)) + && (y >= output_low_mark_miny)) output_reg_miny_contents = y; - } - if (y > output_reg_maxy_contents) { + if (y > output_reg_maxy_contents) output_reg_maxy_contents = y; - } - // fprintf(stderr, "x = %d y=%d miny=%d maxy=%d\n", x, y, output_reg_miny_contents, output_reg_maxy_contents); } -void reset_output_registers() +void reset_output_registers(int miny) { // fprintf(stderr, "reset_output_registers\n"); + output_low_mark_miny = miny; output_reg_minx_contents = -1; output_reg_miny_contents = -1; output_reg_maxx_contents = -1; output_reg_maxy_contents = -1; } -void output_request() +void get_output_registers(int *minx, int *miny, int *maxx, int *maxy) { - if (has_arg()) { - int n; - - if (! get_integer(&n)) { - error("missing integer argument for output request"); - n = 1; - } - - if (break_flag) - curenv->do_break(); - - if (!the_output) - init_output(); - if (n == 0) { - the_output->off(); - } else { - the_output->on(); - } - } else { - error("missing argument for output request"); - } - skip_line(); + *minx = output_reg_minx_contents; + *miny = output_reg_miny_contents; + *maxx = output_reg_maxx_contents; + *maxy = output_reg_maxy_contents; } -void init_output_requests() +void init_html_requests() { - init_request("output", output_request); + init_request("html-begin", html_begin); + init_request("html-end", html_end); + init_request("html-image", html_image); } void init_input_requests() |