diff --git a/src/config/options.inc b/src/config/options.inc index 02e7a725..dcc134a7 100644 --- a/src/config/options.inc +++ b/src/config/options.inc @@ -782,6 +782,10 @@ static union option_info config_options_info[] = { N_("Whether to print references (URIs) of document links " "in dump output.")), + INIT_OPT_BOOL("document.dump", N_("Terminal hyperlinks"), + "terminal_hyperlinks", OPT_ZERO, 0, + N_("Whether to add terminal hyperlinks to dump output. See #198 in github.")), + INIT_OPT_STRING("document.dump", N_("Separator"), "separator", OPT_ZERO, "\n\n", N_("String which separates two dumps.")), diff --git a/src/viewer/dump/dump-specialized.h b/src/viewer/dump/dump-specialized.h index d0934499..58814edc 100644 --- a/src/viewer/dump/dump-specialized.h +++ b/src/viewer/dump/dump-specialized.h @@ -45,6 +45,10 @@ DUMP_FUNCTION_SPECIALIZED(struct document *document, struct dump_output *out) const int width = get_opt_int("document.dump.width", NULL); #endif /* DUMP_COLOR_MODE_TRUE */ + int current_link_number = 0; + int dumplinks = get_opt_bool("document.dump.terminal_hyperlinks", NULL); + struct link *next_link = NULL; + for (y = 0; y < document->height; y++) { #ifdef DUMP_COLOR_MODE_NONE int white = 0; @@ -62,6 +66,14 @@ DUMP_FUNCTION_SPECIALIZED(struct document *document, struct dump_output *out) #endif /* DUMP_COLOR_MODE_TRUE */ for (x = 0; x < document->data[y].length; x++) { + if (dumplinks) { + if (is_start_of_link(document, x, y, ¤t_link_number, &next_link)) { + write_start_of_link(next_link, out); + } + if (is_end_of_link(document, x, y, ¤t_link_number, &next_link)) { + write_end_of_link(out); + } + } #ifdef DUMP_CHARSET_UTF8 unicode_val_T c; const char *utf8_buf; diff --git a/src/viewer/dump/dump.c b/src/viewer/dump/dump.c index e9a0218d..a4a1153d 100644 --- a/src/viewer/dump/dump.c +++ b/src/viewer/dump/dump.c @@ -208,6 +208,40 @@ dump_output_flush(struct dump_output *out) return 0; } +static int +is_start_of_link(struct document *document, int x, int y, int *current_link_number, struct link **ret) +{ + int i = *current_link_number; + + for (; i < document->nlinks; i++) { + struct link *link = &document->links[i]; + + if (link->points[0].x == x && link->points[0].y == y) { + *current_link_number = i; + *ret = link; + return 1; + } + } + return 0; +} + +static int +is_end_of_link(struct document *document, int x, int y, int *current_link_number, struct link **ret) +{ + int i = *current_link_number; + + for (; i < document->nlinks; i++) { + struct link *link = &document->links[i]; + + if (link->points[link->npoints - 1].x == x && link->points[link->npoints - 1].y == y) { + *current_link_number = i; + *ret = link; + return 1; + } + } + return 0; +} + static int write_char(unsigned char c, struct dump_output *out) { @@ -220,6 +254,29 @@ write_char(unsigned char c, struct dump_output *out) return 0; } +static void +write_start_of_link(struct link *link, struct dump_output *out) +{ + char buf[D_BUF]; + char *where = link->where ?: link->where_img; + + snprintf(buf, D_BUF, "\033]8;;%s\033\\", where); + + for (char *st = buf; *st; st++) { + write_char(*st, out); + } +} + +static void +write_end_of_link(struct dump_output *out) +{ + char buf[] = "\033]8;;\033\\"; + + for (char *st = buf; *st; st++) { + write_char(*st, out); + } +} + static int write_color_16(unsigned char color, struct dump_output *out) { @@ -331,13 +388,14 @@ dump_references(struct document *document, int fd, char buf[D_BUF]) const char *label_key = get_opt_str("document.browse.links.label_key", NULL); int headlen = strlen(header); int base = strlen(label_key); + int dumplinks = get_opt_bool("document.dump.terminal_hyperlinks", NULL); if (hard_write(fd, header, headlen) != headlen) return -1; for (x = 0; x < document->nlinks; x++) { struct link *link = &document->links[x]; - char *where = link->where; + char *where = link->where ?: link->where_img; size_t reflen; if (!where) continue; @@ -346,18 +404,40 @@ dump_references(struct document *document, int fd, char buf[D_BUF]) dec2qwerty(x + 1, key_sym, label_key, base); - if (link->title && *link->title) - snprintf(buf, D_BUF, "%4s. %s\n\t%s\n", + if (link->title && *link->title) { + if (dumplinks) { + snprintf(buf, D_BUF, "%4s. \033]8;;%s\033\\%s\033]8;;\033\\\n", + key_sym, where, link->title); + } else { + snprintf(buf, D_BUF, "%4s. %s\n\t%s\n", key_sym, link->title, where); - else - snprintf(buf, D_BUF, "%4s. %s\n", + } + } else { + if (dumplinks) { + snprintf(buf, D_BUF, "%4s. \033]8;;%s\033\\%s\033]8;;\033\\\n", + key_sym, where, where); + } else { + snprintf(buf, D_BUF, "%4s. %s\n", key_sym, where); + } + } } else { - if (link->title && *link->title) - snprintf(buf, D_BUF, " . %s\n\t%s\n", + if (link->title && *link->title) { + if (dumplinks) { + snprintf(buf, D_BUF, " . \033]8;;%s\033\\%s\033]8;;\033\\\n", + where, link->title); + } else { + snprintf(buf, D_BUF, " . %s\n\t%s\n", link->title, where); - else - snprintf(buf, D_BUF, " . %s\n", where); + } + } else { + if (dumplinks) { + snprintf(buf, D_BUF, " . \033]8;;%s\033\\%s\033]8;;\033\\\n", + where, where); + } else { + snprintf(buf, D_BUF, " . %s\n", where); + } + } } reflen = strlen(buf);