Update of bug #66387 (group groff): Status: Postponed => In Progress
_______________________________________________________ Follow-up Comment #3: A bit more thought and I believe I figured it out. diff --git a/src/roff/troff/env.cpp b/src/roff/troff/env.cpp index f314a513d..20efd9b3b 100644 --- a/src/roff/troff/env.cpp +++ b/src/roff/troff/env.cpp @@ -787,6 +787,7 @@ environment::environment(symbol nm) line_number_indent(0), line_number_multiple(1), no_number_count(0), + language_code(""), hyphenation_mode(1), hyphenation_mode_default(1), hyphen_line_count(0), @@ -881,6 +882,7 @@ environment::environment(const environment *e) line_number_indent(e->line_number_indent), line_number_multiple(e->line_number_multiple), no_number_count(e->no_number_count), + language_code(e->language_code), hyphenation_mode(e->hyphenation_mode), hyphenation_mode_default(e->hyphenation_mode_default), hyphen_line_count(0), @@ -968,6 +970,7 @@ void environment::copy(const environment *e) no_number_count = e->no_number_count; tab_char = e->tab_char; leader_char = e->leader_char; + set_language_code(e->language_code.contents()); hyphenation_mode = e->hyphenation_mode; hyphenation_mode_default = e->hyphenation_mode_default; fontno = e->fontno; @@ -3542,6 +3545,10 @@ void environment::print_env() errprint(" lines remaining for which to suppress numbering: %1\n", no_number_count); } + const char *hl = language_code.contents(); + bool is_hyphenation_impossible = language_code.is_empty(); + errprint(" hyphenation language code: %1\n", + is_hyphenation_impossible ? "(none)" : hl); string hf = hyphenation_mode ? "on" : "off"; if (hyphenation_mode & HYPHEN_NOT_LAST_LINE) hf += ", not on line before vertical position trap"; @@ -3554,8 +3561,10 @@ void environment::print_env() if (hyphenation_mode & HYPHEN_NOT_FIRST_CHARS) hf += ", not allowed within first two characters"; hf += '\0'; - errprint(" hyphenation mode: %1 (%2)\n", hyphenation_mode, - hf.contents()); + errprint(" hyphenation mode: %1 (%2)%3\n", hyphenation_mode, + hf.contents(), + is_hyphenation_impossible ? " [no hyphenation language]" + : ""); errprint(" hyphenation mode default: %1\n", hyphenation_mode_default); errprint(" count of consecutive hyphenated lines: %1\n", @@ -3642,6 +3651,7 @@ static void select_hyphenation_language() { if (!has_arg()) { current_language = 0 /* nullptr */; + curenv->set_language_code(""); skip_line(); return; } @@ -3653,11 +3663,20 @@ static void select_hyphenation_language() current_language = new hyphenation_language(nm); (void) language_dictionary.lookup(nm, static_cast<hyphenation_language *>(current_language)); + curenv->set_language_code(nm.contents()); } } + assert(!(curenv->get_language_code().is_null())); skip_line(); } +// The environment class has no visibility into which hyphenation +// languages are defined; it has only a code that is either empty +// or must reference a valid one (and since the code uniquely +// identifies a language, a `const char *` is more ergonomic than a +// pointer to a type that's not visible in the class's scope). So +// updating that code is a two-step process. + void environment_copy() { if (!has_arg()) { @@ -3671,14 +3690,27 @@ void environment_copy() symbol nm = get_long_name(); assert(nm != 0 /* nullptr */); e = static_cast<environment *>(env_dictionary.lookup(nm)); - if (e != 0 /* nullptr */) + if (e != 0 /* nullptr */) { curenv->copy(e); + current_language = static_cast<hyphenation_language *> + (language_dictionary.lookup(e->get_language_code())); + } else error("cannot copy from nonexistent environment '%1'", nm.contents()); skip_line(); } +symbol environment::get_language_code() +{ + return language_code; +} + +void environment::set_language_code(const char *lang) +{ + language_code = lang; +} + void environment_switch() { if (curenv->is_dummy()) { @@ -3694,6 +3726,7 @@ void environment_switch() bool seen_eol = curenv->seen_eol; bool suppress_next_eol = curenv->suppress_next_eol; curenv = env_stack->env; + current_language = static_cast<hyphenation_language *>(language_dictionary.lookup(curenv->language_code)); curenv->seen_space = seen_space; curenv->seen_eol = seen_eol; curenv->suppress_next_eol = suppress_next_eol; @@ -3711,6 +3744,7 @@ void environment_switch() } env_stack = new env_list_node(curenv, env_stack); curenv = e; + current_language = static_cast<hyphenation_language *>(language_dictionary.lookup(curenv->language_code)); } } skip_line(); diff --git a/src/roff/troff/env.h b/src/roff/troff/env.h index 6b4ec03f9..1d70f5529 100644 --- a/src/roff/troff/env.h +++ b/src/roff/troff/env.h @@ -212,6 +212,7 @@ class environment { int line_number_indent; // in digit spaces int line_number_multiple; int no_number_count; + symbol language_code; unsigned hyphenation_mode; unsigned hyphenation_mode_default; int hyphen_line_count; @@ -312,6 +313,8 @@ public: hunits get_input_line_position(); const char *get_tabs(); int is_using_line_tabs(); + symbol get_language_code(); + void set_language_code(const char *); unsigned get_hyphenation_mode(); unsigned get_hyphenation_mode_default(); int get_hyphen_line_max(); @@ -395,6 +398,7 @@ public: friend void number_lines(); friend void leader_character(); friend void tab_character(); + friend void environment_switch(); friend void hyphenate_request(); friend void set_hyphenation_mode_default(); friend void no_hyphenate(); _______________________________________________________ Reply to this item at: <https://savannah.gnu.org/bugs/?66387> _______________________________________________ Message sent via Savannah https://savannah.gnu.org/
signature.asc
Description: PGP signature