diff -purN dillo-0.7.3/dillorc dillo-0.7.3.dev/dillorc --- dillo-0.7.3/dillorc Mon Oct 6 07:28:53 2003 +++ dillo-0.7.3.dev/dillorc Mon Oct 6 07:23:44 2003 @@ -16,6 +16,19 @@ use_dicache=NO #------------------------------------------------------------------------- +# SMART BOOKMARKS SECTION +#------------------------------------------------------------------------- +# Use "g dillo" as the URL to search google for "dillo". +# The keyword may consist only of alpha-numeric characters and must be +# separated from the URL with a semicolon. The URL must contain +# the "%s" sequence, which will be replaced with the parameter following +# the keyword. + +smart_bookmark="g;http://www.google.com/search?&q=%s" +smart_bookmark="fm;http://freshmeat.net/search/?q=%s§ion=projects" + + +#------------------------------------------------------------------------- # RENDERING SECTION #------------------------------------------------------------------------- diff -purN dillo-0.7.3/src/interface.c dillo-0.7.3.dev/src/interface.c --- dillo-0.7.3/src/interface.c Mon Oct 6 07:28:54 2003 +++ dillo-0.7.3.dev/src/interface.c Mon Oct 6 07:23:44 2003 @@ -919,8 +919,12 @@ void a_Interface_entry_open_url(GtkWidge DEBUG_MSG(1, "entry_open_url %s\n", text); if ( text && *text ) { + /* Take care of smart bookmarks. */ + gchar *smart_bookmark = a_Url_find_smart_bookmark(text); + /* Filter URL string */ - new_text = a_Url_string_strip_delimiters(text); + new_text = a_Url_string_strip_delimiters(smart_bookmark ? + smart_bookmark : text); url = a_Url_new(new_text, NULL, 0, 0); if (url) { @@ -928,6 +932,7 @@ void a_Interface_entry_open_url(GtkWidge a_Url_free(url); } g_free(new_text); + g_free(smart_bookmark); } if (bw->open_dialog_window != NULL) diff -purN dillo-0.7.3/src/prefs.c dillo-0.7.3.dev/src/prefs.c --- dillo-0.7.3/src/prefs.c Mon Oct 6 07:28:54 2003 +++ dillo-0.7.3.dev/src/prefs.c Mon Oct 6 07:28:02 2003 @@ -71,6 +71,7 @@ static const struct { { "fw_fontname", DRC_TOKEN_FW_FONT }, { "generate_submit", DRC_TOKEN_GENERATE_SUBMIT }, { "enterpress_forces_submit", DRC_TOKEN_ENTERPRESS_FORCES_SUBMIT }, + { "smart_bookmark", DRC_TOKEN_SMART_BOOKMARK }, { "focus_location_on_new", DRC_TOKEN_FOCUS_LOCATION_ON_NEW }, #ifndef DISABLE_TABS { "tab_load_in_background", DRC_TOKEN_TAB_LOAD_IN_BACKGROUND }, @@ -253,6 +254,32 @@ static guint Prefs_parser(GScanner *scan prefs.enterpress_forces_submit = (strcmp(scanner->value.v_string, "YES") == 0); break; + case DRC_TOKEN_SMART_BOOKMARK: + { + /* Split the value into keyword-url pair. */ + gchar **kw_url = g_strsplit(scanner->value.v_string, ";", 2); + if (kw_url) { + if (kw_url[0] && *kw_url[0] && kw_url[1] && *kw_url[1]) { + /* Split the url at "%s" into prefix and suffix. */ + gchar **pref_suf = g_strsplit(kw_url[1], "%s", 2); + if (pref_suf) { + if (pref_suf[0] && *pref_suf[0]) { + SmartBookmark *sb = g_new0(SmartBookmark, 1); + sb->keyword = g_strdup(kw_url[0]); + sb->prefix = g_strdup(pref_suf[0]); + sb->suffix = pref_suf[1] ? g_strdup(pref_suf[1]) : NULL; + sb->next = prefs.smart_bookmarks; + /* Push it to the beggining of the linked list of + * registered smart bookmarks. */ + prefs.smart_bookmarks = sb; + } + g_strfreev(pref_suf); + } + } + g_strfreev(kw_url); + } + } + break; case DRC_TOKEN_FOCUS_LOCATION_ON_NEW: prefs.focus_location_on_new = (strcmp(scanner->value.v_string, "YES") == 0); @@ -430,6 +457,7 @@ void a_Prefs_init(void) prefs.fw_fontname = g_strdup("courier"); prefs.generate_submit = FALSE; prefs.enterpress_forces_submit = FALSE; + prefs.smart_bookmarks = NULL; prefs.focus_location_on_new = TRUE; #ifndef DISABLE_TABS prefs.tab_load_in_background = FALSE; @@ -473,4 +501,18 @@ void a_Prefs_freeall(void) if (prefs.compress_common_prefixes_vec) g_strfreev(prefs.compress_common_prefixes_vec); #endif /* DISABLE_TABS */ + + /* Free the linked list of registered smart bookmarks. */ + { + SmartBookmark *sb = prefs.smart_bookmarks; + SmartBookmark *next = NULL; + while (sb) { + g_free(sb->keyword); + g_free(sb->prefix); + g_free(sb->suffix); + next = sb->next; + g_free(sb); + sb = next; + } + } } diff -purN dillo-0.7.3/src/prefs.h dillo-0.7.3.dev/src/prefs.h --- dillo-0.7.3/src/prefs.h Mon Oct 6 07:28:54 2003 +++ dillo-0.7.3.dev/src/prefs.h Mon Oct 6 07:26:15 2003 @@ -66,6 +66,7 @@ typedef enum { DRC_TOKEN_VW_FONT, DRC_TOKEN_GENERATE_SUBMIT, DRC_TOKEN_ENTERPRESS_FORCES_SUBMIT, + DRC_TOKEN_SMART_BOOKMARK, DRC_TOKEN_FOCUS_LOCATION_ON_NEW, #ifndef DISABLE_TABS DRC_TOKEN_TAB_LOAD_IN_BACKGROUND, @@ -84,6 +85,13 @@ typedef enum { typedef struct _DilloPrefs DilloPrefs; +typedef struct SmartBookmark { + struct SmartBookmark *next; + gchar *keyword; + gchar *prefix; + gchar *suffix; +} SmartBookmark; + struct _DilloPrefs { gint width; gint height; @@ -124,6 +132,7 @@ struct _DilloPrefs { gchar *fw_fontname; gboolean generate_submit; gboolean enterpress_forces_submit; + SmartBookmark *smart_bookmarks; gboolean focus_location_on_new; #ifndef DISABLE_TABS gboolean tab_load_in_background; diff -purN dillo-0.7.3/src/url.c dillo-0.7.3.dev/src/url.c --- dillo-0.7.3/src/url.c Mon Oct 6 07:28:54 2003 +++ dillo-0.7.3.dev/src/url.c Mon Oct 6 07:23:44 2003 @@ -38,6 +38,7 @@ #include #include "url.h" +#include "prefs.h" //#define DEBUG_LEVEL 2 #include "debug.h" @@ -577,3 +578,99 @@ gchar *a_Url_string_strip_delimiters(gch } return new_str; } + +/* + * Check if the string represents an invocation of a registered + * smart bookmark (in the form of "KEYWORD PARAMETR"). If it does, + * then process it into the URL and return it. The parameter is properly + * URL-escaped. The caller is responsible for freeing the result. + * If the string cannot be mapped to a smart bookmark, return NULL. + */ +gchar *a_Url_find_smart_bookmark(gchar *str) { + gchar *p_space = NULL; + gchar *keyword = NULL; + gchar *param = NULL; + gchar *p = NULL; + SmartBookmark *sb = prefs.smart_bookmarks; + + if (sb == NULL) /* No smart bookmarks have been registered. */ + return NULL; + + if (str == NULL || strlen(str) == 0) + return NULL; + + keyword = g_strdup(str); + p_space = strchr(keyword, ' '); + + if (p_space == NULL || p_space == keyword || *(p_space + 1) == '\0') { + g_free(keyword); + return NULL; + } + param = g_strdup(p_space + 1); + + /* The keyword may consist of alpha-numeric characters only. */ + *p_space = '\0'; + p = keyword; + while (*p) { + if (! isalpha(*p)) { + g_free(keyword); + g_free(param); + return NULL; + } + p++; + } + + /* Walk through the linked list of registered smart bookmarks to + * find an entry with matching keyword. */ + do { + if (strcmp(sb->keyword, keyword) == 0) { + break; + } + } while ((sb = sb->next)); + + + if (sb) { + /* We have found a matching smart bookmark. + * The parameter may contain any character, so we must + * URL-escape it. */ + int i; + gchar *url; + static const char *hex = "0123456789ABCDEF"; + static const char *safe_set = "0123456789" + "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "-_."; + for (i = 0; param[i]; ++i) + if (param[i] <= 0x20 || param[i] >= 0x7F || !strchr(safe_set, param[i])) + break; + + if (param[i]) { + /* needs escaping */ + GString *gstr = g_string_sized_new(64); + for (i = 0; param[i]; ++i) { + if (param[i] <= 0x20 || param[i] >= 0x7F || !strchr(safe_set, param[i])) { + g_string_append_c(gstr, '%'); + g_string_append_c(gstr, hex[(param[i] >> 4) & 15]); + g_string_append_c(gstr, hex[param[i] & 15]); + } + else { + g_string_append_c(gstr, param[i]); + } + } + g_free(param); + param = gstr->str; + g_string_free(gstr, FALSE); + } + + url = g_strconcat(sb->prefix, param, + sb->suffix ? sb->suffix : NULL, NULL); + g_free(keyword); + g_free(param); + return url; + } + else { + g_free(keyword); + g_free(param); + return NULL; + } +} diff -purN dillo-0.7.3/src/url.h dillo-0.7.3.dev/src/url.h --- dillo-0.7.3/src/url.h Mon Oct 6 07:28:54 2003 +++ dillo-0.7.3.dev/src/url.h Mon Oct 6 07:23:44 2003 @@ -140,6 +140,7 @@ void a_Url_set_pos(DilloUrl *u, gint pos void a_Url_set_ismap_coords(DilloUrl *u, gchar *coord_str); gchar *a_Url_parse_hex_path(const DilloUrl *u); gchar *a_Url_string_strip_delimiters(gchar *str); +gchar *a_Url_find_smart_bookmark(gchar *str); #ifdef __cplusplus }