|
Packit |
116408 |
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
|
|
Packit |
116408 |
/*
|
|
Packit |
116408 |
* Copyright (C) 2001-2002 Mikael Hallendal <micke@imendio.com>
|
|
Packit |
116408 |
* Copyright (C) 2008 Imendio AB
|
|
Packit |
116408 |
* Copyright (C) 2017, 2018 Sébastien Wilmet <swilmet@gnome.org>
|
|
Packit |
116408 |
*
|
|
Packit |
116408 |
* This program is free software; you can redistribute it and/or
|
|
Packit |
116408 |
* modify it under the terms of the GNU General Public License as
|
|
Packit |
116408 |
* published by the Free Software Foundation; either version 2 of the
|
|
Packit |
116408 |
* License, or (at your option) any later version.
|
|
Packit |
116408 |
*
|
|
Packit |
116408 |
* This program is distributed in the hope that it will be useful,
|
|
Packit |
116408 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
116408 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
116408 |
* General Public License for more details.
|
|
Packit |
116408 |
*
|
|
Packit |
116408 |
* You should have received a copy of the GNU General Public License
|
|
Packit |
116408 |
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
|
Packit |
116408 |
*/
|
|
Packit |
116408 |
|
|
Packit |
116408 |
#include "config.h"
|
|
Packit |
116408 |
#include "dh-link.h"
|
|
Packit |
116408 |
#include <string.h>
|
|
Packit |
116408 |
#include <glib/gi18n-lib.h>
|
|
Packit |
116408 |
|
|
Packit |
116408 |
/**
|
|
Packit |
116408 |
* SECTION:dh-link
|
|
Packit |
116408 |
* @Title: DhLink
|
|
Packit |
116408 |
* @Short_description: A link inside a #DhBook
|
|
Packit |
116408 |
*
|
|
Packit |
116408 |
* A #DhLink represents a link to an HTML page or somewhere inside a page (with
|
|
Packit |
116408 |
* an anchor) that is inside a #DhBook. The link can point to a specific symbol,
|
|
Packit |
116408 |
* or a page, or the top-level page of the #DhBook.
|
|
Packit |
116408 |
*
|
|
Packit |
116408 |
* A #DhLink has a type that can be retrieved with dh_link_get_link_type().
|
|
Packit |
116408 |
*
|
|
Packit |
116408 |
* There is exactly one #DhLink of type %DH_LINK_TYPE_BOOK per #DhBook object.
|
|
Packit |
116408 |
*/
|
|
Packit |
116408 |
|
|
Packit |
116408 |
/* Fields used only by DhLink's of type DH_LINK_TYPE_BOOK. */
|
|
Packit |
116408 |
typedef struct {
|
|
Packit |
116408 |
gchar *base_path;
|
|
Packit |
116408 |
gchar *book_id;
|
|
Packit |
116408 |
} BookData;
|
|
Packit |
116408 |
|
|
Packit |
116408 |
struct _DhLink {
|
|
Packit |
116408 |
/* To avoid some memory padding inside the struct, to use less memory,
|
|
Packit |
116408 |
* the fields are placed in this order:
|
|
Packit |
116408 |
* 1. All the pointers.
|
|
Packit |
116408 |
* 2. Other types.
|
|
Packit |
116408 |
* 3. Bit fields.
|
|
Packit |
116408 |
*
|
|
Packit |
116408 |
* Also, a union is used to use less memory. This struct is allocated a
|
|
Packit |
116408 |
* lot, so it is worth optimizing it.
|
|
Packit |
116408 |
*/
|
|
Packit |
116408 |
|
|
Packit |
116408 |
union {
|
|
Packit |
116408 |
/* @book.data is set only for links of @type DH_LINK_TYPE_BOOK. */
|
|
Packit |
116408 |
BookData *data;
|
|
Packit |
116408 |
|
|
Packit |
116408 |
/* @book.link is set only for links of @type != DH_LINK_TYPE_BOOK. */
|
|
Packit |
116408 |
DhLink *link;
|
|
Packit |
116408 |
} book;
|
|
Packit |
116408 |
|
|
Packit |
116408 |
gchar *name;
|
|
Packit |
116408 |
gchar *name_collation_key;
|
|
Packit |
116408 |
|
|
Packit |
116408 |
gchar *relative_url;
|
|
Packit |
116408 |
|
|
Packit |
116408 |
guint ref_count;
|
|
Packit |
116408 |
|
|
Packit |
116408 |
DhLinkType type : 8;
|
|
Packit |
116408 |
DhLinkFlags flags : 8;
|
|
Packit |
116408 |
};
|
|
Packit |
116408 |
|
|
Packit |
116408 |
/* If the relative_url is empty. */
|
|
Packit |
116408 |
#define DEFAULT_PAGE "index.html"
|
|
Packit |
116408 |
|
|
Packit |
116408 |
G_DEFINE_BOXED_TYPE (DhLink, dh_link,
|
|
Packit |
116408 |
dh_link_ref, dh_link_unref)
|
|
Packit |
116408 |
|
|
Packit |
116408 |
static BookData *
|
|
Packit |
116408 |
book_data_new (const gchar *base_path,
|
|
Packit |
116408 |
const gchar *book_id)
|
|
Packit |
116408 |
{
|
|
Packit |
116408 |
BookData *data;
|
|
Packit |
116408 |
|
|
Packit |
116408 |
data = g_slice_new (BookData);
|
|
Packit |
116408 |
data->base_path = g_strdup (base_path);
|
|
Packit |
116408 |
data->book_id = g_strdup (book_id);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
return data;
|
|
Packit |
116408 |
}
|
|
Packit |
116408 |
|
|
Packit |
116408 |
static void
|
|
Packit |
116408 |
book_data_free (BookData *data)
|
|
Packit |
116408 |
{
|
|
Packit |
116408 |
if (data == NULL)
|
|
Packit |
116408 |
return;
|
|
Packit |
116408 |
|
|
Packit |
116408 |
g_free (data->base_path);
|
|
Packit |
116408 |
g_free (data->book_id);
|
|
Packit |
116408 |
g_slice_free (BookData, data);
|
|
Packit |
116408 |
}
|
|
Packit |
116408 |
|
|
Packit |
116408 |
static void
|
|
Packit |
116408 |
link_free (DhLink *link)
|
|
Packit |
116408 |
{
|
|
Packit |
116408 |
if (link->type == DH_LINK_TYPE_BOOK)
|
|
Packit |
116408 |
book_data_free (link->book.data);
|
|
Packit |
116408 |
else
|
|
Packit |
116408 |
dh_link_unref (link->book.link);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
g_free (link->name);
|
|
Packit |
116408 |
g_free (link->name_collation_key);
|
|
Packit |
116408 |
g_free (link->relative_url);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
g_slice_free (DhLink, link);
|
|
Packit |
116408 |
}
|
|
Packit |
116408 |
|
|
Packit |
116408 |
static DhLink *
|
|
Packit |
116408 |
dh_link_new_common (DhLinkType type,
|
|
Packit |
116408 |
const gchar *name,
|
|
Packit |
116408 |
const gchar *relative_url)
|
|
Packit |
116408 |
{
|
|
Packit |
116408 |
DhLink *link;
|
|
Packit |
116408 |
|
|
Packit |
116408 |
link = g_slice_new0 (DhLink);
|
|
Packit |
116408 |
link->ref_count = 1;
|
|
Packit |
116408 |
link->type = type;
|
|
Packit |
116408 |
link->name = g_strdup (name);
|
|
Packit |
116408 |
link->relative_url = g_strdup (relative_url);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
return link;
|
|
Packit |
116408 |
}
|
|
Packit |
116408 |
|
|
Packit |
116408 |
/**
|
|
Packit |
116408 |
* dh_link_new_book:
|
|
Packit |
116408 |
* @base_path: the base path for the book.
|
|
Packit |
116408 |
* @book_id: the book ID.
|
|
Packit |
116408 |
* @book_title: the name of the link.
|
|
Packit |
116408 |
* @relative_url: the URL relative to the book @base_path. Can contain an
|
|
Packit |
116408 |
* anchor. Usually the index.html page.
|
|
Packit |
116408 |
*
|
|
Packit |
116408 |
* Returns: a new #DhLink of type %DH_LINK_TYPE_BOOK.
|
|
Packit |
116408 |
* Since: 3.28
|
|
Packit |
116408 |
*/
|
|
Packit |
116408 |
DhLink *
|
|
Packit |
116408 |
dh_link_new_book (const gchar *base_path,
|
|
Packit |
116408 |
const gchar *book_id,
|
|
Packit |
116408 |
const gchar *book_title,
|
|
Packit |
116408 |
const gchar *relative_url)
|
|
Packit |
116408 |
{
|
|
Packit |
116408 |
DhLink *link;
|
|
Packit |
116408 |
|
|
Packit |
116408 |
g_return_val_if_fail (base_path != NULL, NULL);
|
|
Packit |
116408 |
g_return_val_if_fail (book_id != NULL, NULL);
|
|
Packit |
116408 |
g_return_val_if_fail (book_title != NULL, NULL);
|
|
Packit |
116408 |
g_return_val_if_fail (relative_url != NULL, NULL);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
link = dh_link_new_common (DH_LINK_TYPE_BOOK, book_title, relative_url);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
link->book.data = book_data_new (base_path, book_id);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
return link;
|
|
Packit |
116408 |
}
|
|
Packit |
116408 |
|
|
Packit |
116408 |
/**
|
|
Packit |
116408 |
* dh_link_new:
|
|
Packit |
116408 |
* @type: the #DhLinkType. Must be different than %DH_LINK_TYPE_BOOK.
|
|
Packit |
116408 |
* @book_link: the #DhLink of type %DH_LINK_TYPE_BOOK for the book that the link
|
|
Packit |
116408 |
* is contained in.
|
|
Packit |
116408 |
* @name: the name of the link.
|
|
Packit |
116408 |
* @relative_url: the URL relative to the book base path. Can contain an anchor.
|
|
Packit |
116408 |
*
|
|
Packit |
116408 |
* Returns: a new #DhLink.
|
|
Packit |
116408 |
*/
|
|
Packit |
116408 |
DhLink *
|
|
Packit |
116408 |
dh_link_new (DhLinkType type,
|
|
Packit |
116408 |
DhLink *book_link,
|
|
Packit |
116408 |
const gchar *name,
|
|
Packit |
116408 |
const gchar *relative_url)
|
|
Packit |
116408 |
{
|
|
Packit |
116408 |
DhLink *link;
|
|
Packit |
116408 |
|
|
Packit |
116408 |
g_return_val_if_fail (type != DH_LINK_TYPE_BOOK, NULL);
|
|
Packit |
116408 |
g_return_val_if_fail (book_link != NULL, NULL);
|
|
Packit |
116408 |
g_return_val_if_fail (book_link->type == DH_LINK_TYPE_BOOK, NULL);
|
|
Packit |
116408 |
g_return_val_if_fail (name != NULL, NULL);
|
|
Packit |
116408 |
g_return_val_if_fail (relative_url != NULL, NULL);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
link = dh_link_new_common (type, name, relative_url);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
link->book.link = dh_link_ref (book_link);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
return link;
|
|
Packit |
116408 |
}
|
|
Packit |
116408 |
|
|
Packit |
116408 |
/**
|
|
Packit |
116408 |
* dh_link_ref:
|
|
Packit |
116408 |
* @link: a #DhLink.
|
|
Packit |
116408 |
*
|
|
Packit |
116408 |
* Increases the reference count of @link.
|
|
Packit |
116408 |
*
|
|
Packit |
116408 |
* Not thread-safe.
|
|
Packit |
116408 |
*
|
|
Packit |
116408 |
* Returns: (transfer full): the @link.
|
|
Packit |
116408 |
*/
|
|
Packit |
116408 |
DhLink *
|
|
Packit |
116408 |
dh_link_ref (DhLink *link)
|
|
Packit |
116408 |
{
|
|
Packit |
116408 |
g_return_val_if_fail (link != NULL, NULL);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
link->ref_count++;
|
|
Packit |
116408 |
|
|
Packit |
116408 |
return link;
|
|
Packit |
116408 |
}
|
|
Packit |
116408 |
|
|
Packit |
116408 |
/**
|
|
Packit |
116408 |
* dh_link_unref:
|
|
Packit |
116408 |
* @link: a #DhLink.
|
|
Packit |
116408 |
*
|
|
Packit |
116408 |
* Decreases the reference count of @link.
|
|
Packit |
116408 |
*
|
|
Packit |
116408 |
* Not thread-safe.
|
|
Packit |
116408 |
*/
|
|
Packit |
116408 |
void
|
|
Packit |
116408 |
dh_link_unref (DhLink *link)
|
|
Packit |
116408 |
{
|
|
Packit |
116408 |
g_return_if_fail (link != NULL);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
if (link->ref_count == 1)
|
|
Packit |
116408 |
link_free (link);
|
|
Packit |
116408 |
else
|
|
Packit |
116408 |
link->ref_count--;
|
|
Packit |
116408 |
}
|
|
Packit |
116408 |
|
|
Packit |
116408 |
/**
|
|
Packit |
116408 |
* dh_link_get_link_type:
|
|
Packit |
116408 |
* @link: a #DhLink.
|
|
Packit |
116408 |
*
|
|
Packit |
116408 |
* Returns: the #DhLinkType of @link.
|
|
Packit |
116408 |
*/
|
|
Packit |
116408 |
DhLinkType
|
|
Packit |
116408 |
dh_link_get_link_type (DhLink *link)
|
|
Packit |
116408 |
{
|
|
Packit |
116408 |
g_return_val_if_fail (link != NULL, 0);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
return link->type;
|
|
Packit |
116408 |
}
|
|
Packit |
116408 |
|
|
Packit |
116408 |
/**
|
|
Packit |
116408 |
* dh_link_get_flags:
|
|
Packit |
116408 |
* @link: a #DhLink.
|
|
Packit |
116408 |
*
|
|
Packit |
116408 |
* Returns: the #DhLinkFlags of @link.
|
|
Packit |
116408 |
*/
|
|
Packit |
116408 |
DhLinkFlags
|
|
Packit |
116408 |
dh_link_get_flags (DhLink *link)
|
|
Packit |
116408 |
{
|
|
Packit |
116408 |
g_return_val_if_fail (link != NULL, DH_LINK_FLAGS_NONE);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
return link->flags;
|
|
Packit |
116408 |
}
|
|
Packit |
116408 |
|
|
Packit |
116408 |
/**
|
|
Packit |
116408 |
* dh_link_set_flags:
|
|
Packit |
116408 |
* @link: a #DhLink.
|
|
Packit |
116408 |
* @flags: the new flags of the link.
|
|
Packit |
116408 |
*
|
|
Packit |
116408 |
* Sets the flags of the link.
|
|
Packit |
116408 |
*/
|
|
Packit |
116408 |
void
|
|
Packit |
116408 |
dh_link_set_flags (DhLink *link,
|
|
Packit |
116408 |
DhLinkFlags flags)
|
|
Packit |
116408 |
{
|
|
Packit |
116408 |
g_return_if_fail (link != NULL);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
link->flags = flags;
|
|
Packit |
116408 |
}
|
|
Packit |
116408 |
|
|
Packit |
116408 |
/**
|
|
Packit |
116408 |
* dh_link_get_name:
|
|
Packit |
116408 |
* @link: a #DhLink.
|
|
Packit |
116408 |
*
|
|
Packit |
116408 |
* Returns: the name of the @link. For a link of type %DH_LINK_TYPE_BOOK,
|
|
Packit |
116408 |
* returns the book title.
|
|
Packit |
116408 |
*/
|
|
Packit |
116408 |
const gchar *
|
|
Packit |
116408 |
dh_link_get_name (DhLink *link)
|
|
Packit |
116408 |
{
|
|
Packit |
116408 |
g_return_val_if_fail (link != NULL, NULL);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
return link->name;
|
|
Packit |
116408 |
}
|
|
Packit |
116408 |
|
|
Packit |
116408 |
/**
|
|
Packit |
116408 |
* dh_link_match_relative_url:
|
|
Packit |
116408 |
* @link: a #DhLink.
|
|
Packit |
116408 |
* @relative_url: an URL relative to the book base path. Can contain an anchor.
|
|
Packit |
116408 |
*
|
|
Packit |
116408 |
* Returns: whether the relative URL of @link matches with @relative_url. There
|
|
Packit |
116408 |
* is a special case for the index.html page, it can also match the empty
|
|
Packit |
116408 |
* string.
|
|
Packit |
116408 |
* Since: 3.28
|
|
Packit |
116408 |
*/
|
|
Packit |
116408 |
gboolean
|
|
Packit |
116408 |
dh_link_match_relative_url (DhLink *link,
|
|
Packit |
116408 |
const gchar *relative_url)
|
|
Packit |
116408 |
{
|
|
Packit |
116408 |
g_return_val_if_fail (link != NULL, FALSE);
|
|
Packit |
116408 |
g_return_val_if_fail (link->relative_url != NULL, FALSE);
|
|
Packit |
116408 |
g_return_val_if_fail (relative_url != NULL, FALSE);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
if (g_str_equal (link->relative_url, relative_url))
|
|
Packit |
116408 |
return TRUE;
|
|
Packit |
116408 |
|
|
Packit |
116408 |
/* Special case for index.html, can also match the empty string.
|
|
Packit |
116408 |
* Example of full URLs:
|
|
Packit |
116408 |
* file:///usr/share/gtk-doc/html/glib/
|
|
Packit |
116408 |
* file:///usr/share/gtk-doc/html/glib/index.html
|
|
Packit |
116408 |
*
|
|
Packit |
116408 |
* This supports only the root index.html page of a DhBook, this doesn't
|
|
Packit |
116408 |
* support index.html inside a sub-directory, if the relative_url
|
|
Packit |
116408 |
* contains a sub-directory. But apparently GTK-Doc doesn't create
|
|
Packit |
116408 |
* sub-directories, all the *.html pages are in the same directory.
|
|
Packit |
116408 |
*/
|
|
Packit |
116408 |
if (relative_url[0] == '\0')
|
|
Packit |
116408 |
return g_str_equal (link->relative_url, DEFAULT_PAGE);
|
|
Packit |
116408 |
else if (link->relative_url[0] == '\0')
|
|
Packit |
116408 |
return g_str_equal (relative_url, DEFAULT_PAGE);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
return FALSE;
|
|
Packit |
116408 |
}
|
|
Packit |
116408 |
|
|
Packit |
116408 |
/**
|
|
Packit |
116408 |
* dh_link_belongs_to_page:
|
|
Packit |
116408 |
* @link: a #DhLink.
|
|
Packit |
116408 |
* @page_id: a page ID, i.e. the filename without its extension.
|
|
Packit |
116408 |
*
|
|
Packit |
116408 |
* This function permits to know if @link belongs to a certain page.
|
|
Packit |
116408 |
*
|
|
Packit |
116408 |
* @page_id is usually the HTML filename without the `.html` extension. More
|
|
Packit |
116408 |
* generally, @page_id must be a relative URL (relative to the book base path),
|
|
Packit |
116408 |
* without the anchor nor the file extension.
|
|
Packit |
116408 |
*
|
|
Packit |
116408 |
* For example if @link has the relative URL `"DhLink.html#dh-link-ref"`, then
|
|
Packit |
116408 |
* this function will return %TRUE if the @page_id is `"DhLink"`.
|
|
Packit |
116408 |
*
|
|
Packit |
116408 |
* Returns: whether @link belongs to @page_id.
|
|
Packit |
116408 |
* Since: 3.28
|
|
Packit |
116408 |
*/
|
|
Packit |
116408 |
gboolean
|
|
Packit |
116408 |
dh_link_belongs_to_page (DhLink *link,
|
|
Packit |
116408 |
const gchar *page_id)
|
|
Packit |
116408 |
{
|
|
Packit |
116408 |
const gchar *relative_url;
|
|
Packit |
116408 |
gsize page_id_len;
|
|
Packit |
116408 |
|
|
Packit |
116408 |
g_return_val_if_fail (link != NULL, FALSE);
|
|
Packit |
116408 |
g_return_val_if_fail (link->relative_url != NULL, FALSE);
|
|
Packit |
116408 |
g_return_val_if_fail (page_id != NULL, FALSE);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
relative_url = link->relative_url;
|
|
Packit |
116408 |
if (relative_url[0] == '\0')
|
|
Packit |
116408 |
relative_url = DEFAULT_PAGE;
|
|
Packit |
116408 |
|
|
Packit |
116408 |
page_id_len = strlen (page_id);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
/* Check that a file extension follows. */
|
|
Packit |
116408 |
return (g_str_has_prefix (relative_url, page_id) &&
|
|
Packit |
116408 |
relative_url[page_id_len] == '.');
|
|
Packit |
116408 |
}
|
|
Packit |
116408 |
|
|
Packit |
116408 |
/**
|
|
Packit |
116408 |
* dh_link_get_uri:
|
|
Packit |
116408 |
* @link: a #DhLink.
|
|
Packit |
116408 |
*
|
|
Packit |
116408 |
* Gets the @link URI, by concateneting the book base path with the @link
|
|
Packit |
116408 |
* relative URL.
|
|
Packit |
116408 |
*
|
|
Packit |
116408 |
* Returns: (nullable): the @link URI, or %NULL if getting the URI failed. Free
|
|
Packit |
116408 |
* with g_free() when no longer needed.
|
|
Packit |
116408 |
*/
|
|
Packit |
116408 |
gchar *
|
|
Packit |
116408 |
dh_link_get_uri (DhLink *link)
|
|
Packit |
116408 |
{
|
|
Packit |
116408 |
const gchar *base_path;
|
|
Packit |
116408 |
gchar *filename;
|
|
Packit |
116408 |
gchar *uri;
|
|
Packit |
116408 |
gchar *anchor;
|
|
Packit |
116408 |
GError *error = NULL;
|
|
Packit |
116408 |
|
|
Packit |
116408 |
g_return_val_if_fail (link != NULL, NULL);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
if (link->type == DH_LINK_TYPE_BOOK)
|
|
Packit |
116408 |
base_path = link->book.data->base_path;
|
|
Packit |
116408 |
else
|
|
Packit |
116408 |
base_path = link->book.link->book.data->base_path;
|
|
Packit |
116408 |
|
|
Packit |
116408 |
filename = g_build_filename (base_path, link->relative_url, NULL);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
anchor = strrchr (filename, '#');
|
|
Packit |
116408 |
if (anchor != NULL) {
|
|
Packit |
116408 |
*anchor = '\0';
|
|
Packit |
116408 |
anchor++;
|
|
Packit |
116408 |
}
|
|
Packit |
116408 |
|
|
Packit |
116408 |
uri = g_filename_to_uri (filename, NULL, &error);
|
|
Packit |
116408 |
if (error != NULL) {
|
|
Packit |
116408 |
g_warning ("Failed to get DhLink URI: %s", error->message);
|
|
Packit |
116408 |
g_clear_error (&error);
|
|
Packit |
116408 |
}
|
|
Packit |
116408 |
|
|
Packit |
116408 |
if (uri != NULL && anchor != NULL) {
|
|
Packit |
116408 |
gchar *uri_with_anchor;
|
|
Packit |
116408 |
|
|
Packit |
116408 |
uri_with_anchor = g_strconcat (uri, "#", anchor, NULL);
|
|
Packit |
116408 |
g_free (uri);
|
|
Packit |
116408 |
uri = uri_with_anchor;
|
|
Packit |
116408 |
}
|
|
Packit |
116408 |
|
|
Packit |
116408 |
g_free (filename);
|
|
Packit |
116408 |
return uri;
|
|
Packit |
116408 |
}
|
|
Packit |
116408 |
|
|
Packit |
116408 |
/**
|
|
Packit |
116408 |
* dh_link_get_book_title:
|
|
Packit |
116408 |
* @link: a #DhLink.
|
|
Packit |
116408 |
*
|
|
Packit |
116408 |
* Returns: the title of the book that the @link is contained in.
|
|
Packit |
116408 |
*/
|
|
Packit |
116408 |
const gchar *
|
|
Packit |
116408 |
dh_link_get_book_title (DhLink *link)
|
|
Packit |
116408 |
{
|
|
Packit |
116408 |
g_return_val_if_fail (link != NULL, NULL);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
if (link->type == DH_LINK_TYPE_BOOK)
|
|
Packit |
116408 |
return link->name;
|
|
Packit |
116408 |
|
|
Packit |
116408 |
if (link->book.link != NULL)
|
|
Packit |
116408 |
return link->book.link->name;
|
|
Packit |
116408 |
|
|
Packit |
116408 |
return "";
|
|
Packit |
116408 |
}
|
|
Packit |
116408 |
|
|
Packit |
116408 |
/**
|
|
Packit |
116408 |
* dh_link_get_book_id:
|
|
Packit |
116408 |
* @link: a #DhLink.
|
|
Packit |
116408 |
*
|
|
Packit |
116408 |
* Returns: the ID of the book that the @link is contained in.
|
|
Packit |
116408 |
*/
|
|
Packit |
116408 |
const gchar *
|
|
Packit |
116408 |
dh_link_get_book_id (DhLink *link)
|
|
Packit |
116408 |
{
|
|
Packit |
116408 |
g_return_val_if_fail (link != NULL, NULL);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
if (link->type == DH_LINK_TYPE_BOOK)
|
|
Packit |
116408 |
return link->book.data->book_id;
|
|
Packit |
116408 |
|
|
Packit |
116408 |
if (link->book.link != NULL)
|
|
Packit |
116408 |
return link->book.link->book.data->book_id;
|
|
Packit |
116408 |
|
|
Packit |
116408 |
return "";
|
|
Packit |
116408 |
}
|
|
Packit |
116408 |
|
|
Packit |
116408 |
static gint
|
|
Packit |
116408 |
dh_link_type_compare (DhLinkType a,
|
|
Packit |
116408 |
DhLinkType b)
|
|
Packit |
116408 |
{
|
|
Packit |
116408 |
if (a == b)
|
|
Packit |
116408 |
return 0;
|
|
Packit |
116408 |
|
|
Packit |
116408 |
/* Same order as in a tree: first the top-level book node, then pages,
|
|
Packit |
116408 |
* then keywords (keywords are contained in a page).
|
|
Packit |
116408 |
*/
|
|
Packit |
116408 |
|
|
Packit |
116408 |
if (a == DH_LINK_TYPE_BOOK)
|
|
Packit |
116408 |
return -1;
|
|
Packit |
116408 |
if (b == DH_LINK_TYPE_BOOK)
|
|
Packit |
116408 |
return 1;
|
|
Packit |
116408 |
|
|
Packit |
116408 |
if (a == DH_LINK_TYPE_PAGE)
|
|
Packit |
116408 |
return -1;
|
|
Packit |
116408 |
if (b == DH_LINK_TYPE_PAGE)
|
|
Packit |
116408 |
return 1;
|
|
Packit |
116408 |
|
|
Packit |
116408 |
return 0;
|
|
Packit |
116408 |
}
|
|
Packit |
116408 |
|
|
Packit |
116408 |
/**
|
|
Packit |
116408 |
* dh_link_compare:
|
|
Packit |
116408 |
* @a: (type DhLink): a #DhLink.
|
|
Packit |
116408 |
* @b: (type DhLink): a #DhLink.
|
|
Packit |
116408 |
*
|
|
Packit |
116408 |
* Compares the links @a and @b. This function is used to determine in which
|
|
Packit |
116408 |
* order the links should be displayed.
|
|
Packit |
116408 |
*
|
|
Packit |
116408 |
* Returns: an integer less than zero if @a should appear before @b; zero if
|
|
Packit |
116408 |
* there are no preferences; an integer greater than zero if @b should appear
|
|
Packit |
116408 |
* before @a.
|
|
Packit |
116408 |
*/
|
|
Packit |
116408 |
gint
|
|
Packit |
116408 |
dh_link_compare (gconstpointer a,
|
|
Packit |
116408 |
gconstpointer b)
|
|
Packit |
116408 |
{
|
|
Packit |
116408 |
DhLink *la = (DhLink *) a;
|
|
Packit |
116408 |
DhLink *lb = (DhLink *) b;
|
|
Packit |
116408 |
gint flags_diff;
|
|
Packit |
116408 |
gint diff;
|
|
Packit |
116408 |
|
|
Packit |
116408 |
g_return_val_if_fail (a != NULL, 0);
|
|
Packit |
116408 |
g_return_val_if_fail (b != NULL, 0);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
/* Sort deprecated hits last. */
|
|
Packit |
116408 |
flags_diff = ((la->flags & DH_LINK_FLAGS_DEPRECATED) -
|
|
Packit |
116408 |
(lb->flags & DH_LINK_FLAGS_DEPRECATED));
|
|
Packit |
116408 |
if (flags_diff != 0)
|
|
Packit |
116408 |
return flags_diff;
|
|
Packit |
116408 |
|
|
Packit |
116408 |
/* Collation-based sorting */
|
|
Packit |
116408 |
if (G_UNLIKELY (la->name_collation_key == NULL))
|
|
Packit |
116408 |
la->name_collation_key = g_utf8_collate_key (la->name, -1);
|
|
Packit |
116408 |
if (G_UNLIKELY (lb->name_collation_key == NULL))
|
|
Packit |
116408 |
lb->name_collation_key = g_utf8_collate_key (lb->name, -1);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
diff = strcmp (la->name_collation_key,
|
|
Packit |
116408 |
lb->name_collation_key);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
if (diff != 0)
|
|
Packit |
116408 |
return diff;
|
|
Packit |
116408 |
|
|
Packit |
116408 |
return dh_link_type_compare (la->type, lb->type);
|
|
Packit |
116408 |
}
|
|
Packit |
116408 |
|
|
Packit |
116408 |
/**
|
|
Packit |
116408 |
* dh_link_type_to_string:
|
|
Packit |
116408 |
* @link_type: a #DhLinkType.
|
|
Packit |
116408 |
*
|
|
Packit |
116408 |
* Returns: a string representation of the #DhLinkType, translated in the
|
|
Packit |
116408 |
* current language.
|
|
Packit |
116408 |
*/
|
|
Packit |
116408 |
const gchar *
|
|
Packit |
116408 |
dh_link_type_to_string (DhLinkType link_type)
|
|
Packit |
116408 |
{
|
|
Packit |
116408 |
switch (link_type) {
|
|
Packit |
116408 |
case DH_LINK_TYPE_BOOK:
|
|
Packit |
116408 |
/* i18n: a documentation book */
|
|
Packit |
116408 |
return _("Book");
|
|
Packit |
116408 |
|
|
Packit |
116408 |
case DH_LINK_TYPE_PAGE:
|
|
Packit |
116408 |
/* i18n: a "page" in a documentation book */
|
|
Packit |
116408 |
return _("Page");
|
|
Packit |
116408 |
|
|
Packit |
116408 |
case DH_LINK_TYPE_KEYWORD:
|
|
Packit |
116408 |
/* i18n: a search hit in the documentation, could be a
|
|
Packit |
116408 |
* function, macro, struct, etc */
|
|
Packit |
116408 |
return _("Keyword");
|
|
Packit |
116408 |
|
|
Packit |
116408 |
case DH_LINK_TYPE_FUNCTION:
|
|
Packit |
116408 |
/* i18n: in the programming language context, if you don't
|
|
Packit |
116408 |
* have an ESTABLISHED term for it, leave it
|
|
Packit |
116408 |
* untranslated. */
|
|
Packit |
116408 |
return _("Function");
|
|
Packit |
116408 |
|
|
Packit |
116408 |
case DH_LINK_TYPE_STRUCT:
|
|
Packit |
116408 |
/* i18n: in the programming language context, if you don't
|
|
Packit |
116408 |
* have an ESTABLISHED term for it, leave it
|
|
Packit |
116408 |
* untranslated. */
|
|
Packit |
116408 |
return _("Struct");
|
|
Packit |
116408 |
|
|
Packit |
116408 |
case DH_LINK_TYPE_MACRO:
|
|
Packit |
116408 |
/* i18n: in the programming language context, if you don't
|
|
Packit |
116408 |
* have an ESTABLISHED term for it, leave it
|
|
Packit |
116408 |
* untranslated. */
|
|
Packit |
116408 |
return _("Macro");
|
|
Packit |
116408 |
|
|
Packit |
116408 |
case DH_LINK_TYPE_ENUM:
|
|
Packit |
116408 |
/* i18n: in the programming language context, if you don't
|
|
Packit |
116408 |
* have an ESTABLISHED term for it, leave it
|
|
Packit |
116408 |
* untranslated. */
|
|
Packit |
116408 |
return _("Enum");
|
|
Packit |
116408 |
|
|
Packit |
116408 |
case DH_LINK_TYPE_TYPEDEF:
|
|
Packit |
116408 |
/* i18n: in the programming language context, if you don't
|
|
Packit |
116408 |
* have an ESTABLISHED term for it, leave it
|
|
Packit |
116408 |
* untranslated. */
|
|
Packit |
116408 |
return _("Type");
|
|
Packit |
116408 |
|
|
Packit |
116408 |
case DH_LINK_TYPE_PROPERTY:
|
|
Packit |
116408 |
/* i18n: in the programming language context, if you don't
|
|
Packit |
116408 |
* have an ESTABLISHED term for it, leave it
|
|
Packit |
116408 |
* untranslated. */
|
|
Packit |
116408 |
return _("Property");
|
|
Packit |
116408 |
|
|
Packit |
116408 |
case DH_LINK_TYPE_SIGNAL:
|
|
Packit |
116408 |
/* i18n: in the programming language context, if you don't
|
|
Packit |
116408 |
* have an ESTABLISHED term for it, leave it
|
|
Packit |
116408 |
* untranslated. */
|
|
Packit |
116408 |
return _("Signal");
|
|
Packit |
116408 |
|
|
Packit |
116408 |
default:
|
|
Packit |
116408 |
break;
|
|
Packit |
116408 |
}
|
|
Packit |
116408 |
|
|
Packit |
116408 |
g_return_val_if_reached ("");
|
|
Packit |
116408 |
}
|