[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[bug #66387] [troff] the hyphenation language is global; should be a pro
From: |
G. Branden Robinson |
Subject: |
[bug #66387] [troff] the hyphenation language is global; should be a property of the environment |
Date: |
Thu, 31 Oct 2024 01:50:23 -0400 (EDT) |
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