From db31a25652b59d997ec9ba4ca7d7099543ea9f22 Mon Sep 17 00:00:00 2001 From: lafricain79 Date: Sat, 4 Jul 2026 23:11:43 +0200 Subject: [PATCH] fix: resolve partial verse references in crossref popup via Sword --- src/gtk/bookmarks_treeview.c | 57 +++--------------------------------- src/main/sword.cc | 23 +++++++++++++++ src/main/sword.h | 1 + 3 files changed, 28 insertions(+), 53 deletions(-) diff --git a/src/gtk/bookmarks_treeview.c b/src/gtk/bookmarks_treeview.c index ac5e4329a..9dc11887c 100644 --- a/src/gtk/bookmarks_treeview.c +++ b/src/gtk/bookmarks_treeview.c @@ -943,67 +943,18 @@ static gboolean button_release_event(GtkWidget *widget, g_free(range_start); range_start = NULL; } else if (multi && button_one && settings.crossref_popup) { - /* split on ";" first, then expand "book ch:v1,v2" */ - GList *refs = NULL; - gchar **semis = g_strsplit(key, ";", -1); - gchar *last_book = NULL; - for (gint si = 0; semis[si]; si++) { - gchar *part = g_strstrip(semis[si]); - if (!*part) continue; - gchar *full_part; - /* if no space in part but has colon, prepend last book */ - if (last_book && strchr(part, ':') && !strchr(part, ' ')) - full_part = g_strdup_printf("%s %s", last_book, part); - else { - full_part = g_strdup(part); - /* extract book name: before last space before colon */ - const gchar *col = strchr(full_part, ':'); - if (col) { - const gchar *sp = col; - while (sp > full_part && *sp != ' ') sp--; - if (sp > full_part) { - g_free(last_book); - last_book = g_strndup(full_part, sp - full_part); - } - } - } - /* handle comma-separated verses */ - const gchar *colon = strchr(full_part, ':'); - const gchar *comma = strchr(full_part, ','); - if (colon && comma && comma > colon) { - gchar *prefix = g_strndup(full_part, colon - full_part + 1); - gchar **vnums = g_strsplit(colon + 1, ",", -1); - for (gint vi = 0; vnums[vi]; vi++) { - gchar *vn = g_strstrip(vnums[vi]); - if (*vn) - refs = g_list_append(refs, - g_strdup_printf("%s%s", prefix, vn)); - } - g_strfreev(vnums); - g_free(prefix); - } else { - refs = g_list_append(refs, g_strdup(full_part)); - } - g_free(full_part); - } - g_free(last_book); - g_strfreev(semis); + GList *refs = main_parse_verse_list(module, key, + settings.currentverse); GtkWidget *popup = gtk_menu_new(); for (GList *l = refs; l; l = l->next) { - gchar *ref = (gchar *)l->data; + const gchar *ref = (const gchar *)l->data; GtkWidget *item = gtk_menu_item_new_with_label(ref); - const gchar *dash = strchr(ref, '-'); - const gchar *colon = strchr(ref, ':'); - gchar *nav_ref = (dash && colon && dash > colon) - ? g_strndup(ref, dash - ref) - : g_strdup(ref); gchar *url = g_strdup_printf( "passagestudy.jsp?action=showBookmark&" "type=%s&value=%s&module=%s", "currentTab", - main_url_encode(nav_ref), + main_url_encode(ref), main_url_encode((real_mod ? real_mod : module))); - g_free(nav_ref); g_object_set_data_full(G_OBJECT(item), "url", url, g_free); g_signal_connect(item, "activate", G_CALLBACK(lambda_open_url), NULL); diff --git a/src/main/sword.cc b/src/main/sword.cc index 11b379b0f..95bc8faf1 100644 --- a/src/main/sword.cc +++ b/src/main/sword.cc @@ -218,6 +218,29 @@ const char *main_abbrev_to_name(const char *abbreviation) return NULL; } +/****************************************************************************** + * Name + * main_parse_verse_list + * + * Synopsis + * #include "main/sword.h" + * + * GList *main_parse_verse_list(const char *module, const char *key, + * const char *current_verse) + * + * Description + * parses a verse list string using Sword, resolving partial references + * contextually (e.g. "18:10" resolved as "Matt 18:10"). + * + * Return value + * GList * + */ +GList *main_parse_verse_list(const char *module, const char *key, + const char *current_verse) +{ + return backend->parse_verse_list(module, key, (char *)current_verse); +} + /****************************************************************************** * Name * main_book_heading diff --git a/src/main/sword.h b/src/main/sword.h index d38685a88..c6b72bd64 100644 --- a/src/main/sword.h +++ b/src/main/sword.h @@ -71,6 +71,7 @@ void main_add_abbreviation(const char *name, void main_clear_abbreviations(void); const char *main_name_to_abbrev(const char *name); const char *main_abbrev_to_name(const char *abbreviation); +GList *main_parse_verse_list(const char *module, const char *key, const char *current_verse); void main_book_heading(char *mod_name); void main_chapter_heading(char *mod_name);