Handle help: URI. They are used by KDE apps, and susehelp. It's a bit hackish to
have to handle things this way, and hopefully a common doc metadata format will
solve this kind of issues in the future.

Index: yelp-2.28.0/src/yelp-utils.c
===================================================================
--- yelp-2.28.0.orig/src/yelp-utils.c
+++ yelp-2.28.0/src/yelp-utils.c
@@ -39,6 +39,8 @@
 
 YelpRrnType    resolve_process_ghelp      (char         *uri, 
 					   gchar       **result);
+static void    resolve_process_help       (gchar       *uri,
+					   gchar      **result);
 gchar *        resolve_get_section        (const gchar  *uri);
 gboolean       resolve_is_man_path        (const gchar  *path, 
 					   const gchar  *encoding);
@@ -378,6 +380,25 @@ yelp_uri_resolve (gchar *uri, gchar **re
 	if (*result) {
 	    *section = intern_section;
 	}
+    } else if (!strncmp (uri, "help:", 4)) {
+	resolve_process_help (intern_uri, result);
+	/* we got a file: uri, so let's redo the resolve process */
+	if (*result) {
+	    gchar *buf1 = NULL;
+	    gchar *buf2 = NULL;
+
+	    ret = yelp_uri_resolve (*result, &buf1, &buf2);
+
+	    g_free (*result);
+	    *result = buf1;
+
+	    if (ret == YELP_RRN_TYPE_ERROR)
+	        *section = NULL;
+	    else if (ret == YELP_RRN_TYPE_EXTERNAL)
+	        *section = NULL;
+	    else
+	        *section = intern_section;
+	}
     } else if (!strncmp (uri, "man:", 4)) {
 	ret = resolve_man_page (&uri[4], result, section);
 	if (ret == YELP_RRN_TYPE_ERROR) {
@@ -531,3 +552,204 @@ yelp_uri_resolve (gchar *uri, gchar **re
 	g_free (intern_uri);
     return ret;
 }
+
+static gchar *
+help_uri_check_file (gchar *filename) {
+    if (g_file_test (filename, G_FILE_TEST_IS_REGULAR)) {
+	gchar *full_uri;
+	full_uri = g_strconcat ("file://", filename, NULL);
+	return full_uri;
+    }
+
+    return NULL;
+}
+
+static gchar *
+help_uri_check_dir (gchar *path, gchar *identifier)
+{
+    gchar *result;
+    gchar *full_path;
+    gchar *full_identifier;
+
+    result = help_uri_check_file (path);
+    if (result)
+	return result;
+
+    full_path = g_build_filename (path, "index.docbook", NULL);
+    result = help_uri_check_file (full_path);
+    g_free (full_path);
+    if (result)
+	return result;
+
+    full_identifier = g_strconcat (identifier, ".xml", NULL);
+    full_path = g_build_filename (path, full_identifier, NULL);
+    result = help_uri_check_file (full_path);
+    g_free (full_path);
+    g_free (full_identifier);
+    if (result)
+	return result;
+
+    full_path = g_build_filename (path, "index.html", NULL);
+    result = help_uri_check_file (full_path);
+    g_free (full_path);
+    if (result)
+	return result;
+
+    full_identifier = g_strconcat (identifier, ".html", NULL);
+    full_path = g_build_filename (path, full_identifier, NULL);
+    result = help_uri_check_file (full_path);
+    g_free (full_path);
+    g_free (full_identifier);
+    if (result)
+	return result;
+
+    return NULL;
+}
+
+static gchar *
+help_uri_search (gchar *path, gchar *identifier)
+{
+    gchar *result;
+
+    result = help_uri_check_dir (path, identifier);
+    if (result)
+	return result;
+
+    if (g_str_has_suffix (path, ".html")) {
+	gchar *slash = strrchr (path, '/');
+	if (slash != NULL) {
+	    gchar *shortened = g_strndup (path, slash - path);
+	    result = help_uri_check_dir (shortened, identifier);
+	    g_free (shortened);
+	    if (result)
+		return result;
+	}
+    }
+    return NULL;
+}
+
+static gchar *
+help_uri_expand_datadirs (gchar *path, gchar *identifier)
+{
+    char const* const* data_dirs = g_get_system_data_dirs ();
+    int i;
+    gchar *result;
+
+    for (i = 0; data_dirs[i]; i++) {
+	char *full_path = g_build_filename (data_dirs[i], path, NULL);
+	result = help_uri_search (full_path, identifier);
+	g_free (full_path);
+	if (result)
+	    return result;
+    }
+    return NULL;
+}
+
+static void
+resolve_process_help (gchar *uri, gchar **result)
+{
+    gchar  *path;
+    gchar  *file_name = NULL;
+    const gchar * const * langs;
+    gchar *full_path;
+    int i;
+
+    if ((path = strchr(uri, ':')))
+	path++;
+    else
+	return;
+
+    while (*path == '/')
+	path++;
+
+    path = g_strdup (path);
+    g_strstrip (path);
+
+    if (!*path) {
+	g_free (path);
+	return;
+    }
+
+    full_path = g_strconcat ("/", path, NULL);
+    *result = help_uri_check_file (full_path);
+    g_free (full_path);
+    if (*result)
+	goto end;
+
+    /* This isn't the filename so much as the rest of the path after the first
+     * bit of the path. */
+    file_name = strchr (path, '/');
+    if (file_name) {
+	*file_name = 0;
+	file_name ++;
+    } else {
+	file_name = "";
+    }
+
+    langs = g_get_language_names ();
+
+    for (i = 0; langs[i] != NULL; i++) {
+	full_path = g_strdup_printf ("/gnome/help/%s/%s/%s", path, langs[i], file_name);
+	*result = help_uri_expand_datadirs (full_path, path);
+	g_free (full_path);
+	if (*result)
+	    goto end;
+
+	full_path = g_strdup_printf ("/gnome/help-bundle/%s/%s/%s", path, langs[i], file_name);
+	*result = help_uri_expand_datadirs (full_path, path);
+	g_free (full_path);
+	if (*result)
+	    goto end;
+
+	full_path = g_strdup_printf ("/doc/kde/HTML/%s/%s/%s", langs[i], path, file_name);
+	*result = help_uri_expand_datadirs (full_path, path);
+	g_free (full_path);
+	if (*result)
+	    goto end;
+
+	full_path = g_strdup_printf ("/doc/HTML/%s/%s/%s", langs[i], path, file_name);
+	*result = help_uri_expand_datadirs (full_path, path);
+	g_free (full_path);
+	if (*result)
+	    goto end;
+
+	full_path = g_strdup_printf ("/doc-bundle/HTML/%s/%s/%s", langs[i], path, file_name);
+	*result = help_uri_expand_datadirs (full_path, path);
+	g_free (full_path);
+	if (*result)
+	    goto end;
+    }
+
+    full_path = g_strdup_printf ("/gnome/help/%s/C/%s", path, file_name);
+    *result = help_uri_expand_datadirs (full_path, path);
+    g_free (full_path);
+    if (*result)
+	goto end;
+
+    full_path = g_strdup_printf ("/gnome/help-bundle/%s/C/%s", path, file_name);
+    *result = help_uri_expand_datadirs (full_path, path);
+    g_free (full_path);
+    if (*result)
+	goto end;
+
+    full_path = g_strdup_printf ("/doc/kde/HTML/en/%s/%s", path, file_name);
+    *result = help_uri_expand_datadirs (full_path, path);
+    g_free (full_path);
+    if (*result)
+	goto end;
+
+    full_path = g_strdup_printf ("/doc/HTML/en/%s/%s", path, file_name);
+    *result = help_uri_expand_datadirs (full_path, path);
+    g_free (full_path);
+    if (*result)
+	goto end;
+
+    full_path = g_strdup_printf ("/doc-bundle/HTML/en/%s/%s", path, file_name);
+    *result = help_uri_expand_datadirs (full_path, path);
+    g_free (full_path);
+    if (*result)
+	goto end;
+
+ end:
+    g_free (path);
+}
