summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDon Scorgie <dscorgie@src.gnome.org>2007-06-14 20:04:14 +0000
committerDon Scorgie <dscorgie@src.gnome.org>2007-06-14 20:04:14 +0000
commit1bc97272e1333418e5aa22f9a96567ddf4e841a7 (patch)
tree47facee120a64dd6f620801f3424d01159e188b4
parent07ccb9d89438b6f242f058e0e5078dfd5dbdb495 (diff)
downloadyelp-1bc97272e1333418e5aa22f9a96567ddf4e841a7.tar.gz
Minor fix to recognise man:<filepath>
* src/yelp-utils.c: Minor fix to recognise man:<filepath> * src/Makefile.am: * src/yelp-window.c: Add support for docbook (yay!) and man pages Rename silly function names to something slightly more sensible Update my email address in help dialog (minor) * src/test-document.c: * src/yelp-document.c: * src/yelp-document.h: * src/yelp-docbook.c: Add support for getting the sections GtkTreeModel out * src/yelp-page.c: * src/yelp-page.h: Add functions to get the length (remaining) of page svn path=/branches/yelp-spoon/; revision=2826
-rw-r--r--ChangeLog26
-rw-r--r--src/Makefile.am15
-rw-r--r--src/test-document.c1
-rw-r--r--src/yelp-docbook.c10
-rw-r--r--src/yelp-document.c18
-rw-r--r--src/yelp-document.h4
-rw-r--r--src/yelp-page.c17
-rw-r--r--src/yelp-page.h1
-rw-r--r--src/yelp-utils.c24
-rw-r--r--src/yelp-window.c173
10 files changed, 246 insertions, 43 deletions
diff --git a/ChangeLog b/ChangeLog
index 81db0190..0bd0b450 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,29 @@
+2007-06-14 Don Scorgie <dscorgie@svn.gnome.org>
+
+ * src/yelp-utils.c:
+ Minor fix to recognise man:<filepath>
+
+ * src/Makefile.am:
+ * src/yelp-window.c:
+ Add support for docbook (yay!) and
+ man pages
+ Rename silly function names to something slightly
+ more sensible
+ Update my email address in help dialog (minor)
+
+ * src/test-document.c:
+ * src/yelp-document.c:
+ * src/yelp-document.h:
+ * src/yelp-docbook.c:
+ Add support for getting the sections GtkTreeModel
+ out
+
+ * src/yelp-page.c:
+ * src/yelp-page.h:
+ Add functions to get the length (remaining)
+ of page
+
+
2007-06-13 Don Scorgie <dscorgie@svn.gnome.org>
* src/yelp-window.c:
diff --git a/src/Makefile.am b/src/Makefile.am
index c773cca7..639be536 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -19,13 +19,14 @@ yelp_SOURCES = \
yelp-transform.c yelp-transform.h \
yelp-gecko-services.h yelp-gecko-services.cpp \
yelp-document.h yelp-document.c \
- yelp-toc.h yelp-toc.c
-
-#if ENABLE_MAN
-#yelp_SOURCES += \
-# yelp-man-parser.c yelp-man-parser.h \
-# yelp-man-pager.c yelp-man-pager.h
-#endif
+ yelp-toc.h yelp-toc.c \
+ yelp-docbook.h yelp-docbook.c
+
+if ENABLE_MAN
+yelp_SOURCES += \
+ yelp-man-parser.c yelp-man-parser.h \
+ yelp-man.c yelp-man.h
+endif
#if ENABLE_INFO
#yelp_SOURCES += \
diff --git a/src/test-document.c b/src/test-document.c
index e83d0990..a7adb427 100644
--- a/src/test-document.c
+++ b/src/test-document.c
@@ -70,6 +70,7 @@ document_func (YelpDocument *document,
printf (" NEXT: %s\n", page->next_id);
printf (" UP: %s\n", page->up_id);
printf (" ROOT: %s\n", page->root_id);
+ printf (" SECTIONS: %s\n", yelp_document_get_sections (document) ? "yep": "nah");
yelp_page_read (page, contents, 60, &read, NULL);
/* contents isn't \0-terminated */
contents_ = g_strndup (contents, read);
diff --git a/src/yelp-docbook.c b/src/yelp-docbook.c
index ed33ccb7..9aca4bb9 100644
--- a/src/yelp-docbook.c
+++ b/src/yelp-docbook.c
@@ -84,6 +84,7 @@ static void docbook_request (YelpDocument *document,
gchar *page_id,
YelpDocumentFunc func,
gpointer user_data);
+static gpointer docbook_get_sections (YelpDocument *document);
/* YelpTransform */
static void transform_func (YelpTransform *transform,
@@ -141,6 +142,7 @@ docbook_class_init (YelpDocbookClass *klass)
document_class->request = docbook_request;
document_class->cancel = NULL;
+ document_class->get_sections = docbook_get_sections;
g_type_class_add_private (klass, sizeof (YelpDocbookPriv));
}
@@ -225,6 +227,14 @@ yelp_docbook_new (gchar *filename)
/******************************************************************************/
/** YelpDocument **************************************************************/
+static gpointer
+docbook_get_sections (YelpDocument *document)
+{
+ YelpDocbook *db = (YelpDocbook *) document;
+
+ return (gpointer) (db->priv->sections);
+}
+
static void
docbook_request (YelpDocument *document,
gint req_id,
diff --git a/src/yelp-document.c b/src/yelp-document.c
index 619d854c..0679d568 100644
--- a/src/yelp-document.c
+++ b/src/yelp-document.c
@@ -56,6 +56,7 @@ struct _YelpDocumentPriv {
GHashTable *reqs_by_page_id; /* Indexed by page ID, contains GSList */
GSList *reqs_pending; /* List of requests that need a page */
+ GtkTreeModel *sections; /* Sections of the document, for display */
/* Real page IDs map to themselves, so this list doubles
* as a list of all valid page IDs.
*/
@@ -72,6 +73,7 @@ struct _YelpDocumentPriv {
static void document_class_init (YelpDocumentClass *klass);
static void document_init (YelpDocument *document);
static void document_dispose (GObject *object);
+static gpointer document_get_sections (YelpDocument *document);
static gboolean request_idle_title (Request *request);
static gboolean request_idle_page (Request *request);
@@ -123,6 +125,8 @@ document_class_init (YelpDocumentClass *klass)
object_class->dispose = document_dispose;
+ klass->get_sections = document_get_sections;
+
g_type_class_add_private (klass, sizeof (YelpDocumentPriv));
}
@@ -145,6 +149,7 @@ document_init (YelpDocument *document)
(GDestroyNotify) g_slist_free);
priv->reqs_pending = NULL;
+ priv->sections = NULL;
priv->page_ids = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
priv->titles = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
priv->contents = g_hash_table_new_full (g_str_hash, g_str_equal,
@@ -158,6 +163,13 @@ document_init (YelpDocument *document)
priv->up_ids = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
}
+static gpointer
+document_get_sections (YelpDocument *document)
+{
+ return NULL;
+}
+
+
static void
document_dispose (GObject *object)
{
@@ -467,6 +479,12 @@ yelp_document_has_page (YelpDocument *document, gchar *page_id)
return !(content == NULL);
}
+GtkTreeModel *
+yelp_document_get_sections (YelpDocument *document)
+{
+ return (YELP_DOCUMENT_GET_CLASS (document)->get_sections(document));
+}
+
void
yelp_document_error_request (YelpDocument *document, gint req_id, YelpError *error)
{
diff --git a/src/yelp-document.h b/src/yelp-document.h
index b0bbeb24..e8a1ffca 100644
--- a/src/yelp-document.h
+++ b/src/yelp-document.h
@@ -24,6 +24,7 @@
#define __YELP_DOCUMENT_H__
#include <glib-object.h>
+#include <gtk/gtk.h>
#define YELP_TYPE_DOCUMENT (yelp_document_get_type ())
#define YELP_DOCUMENT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), YELP_TYPE_DOCUMENT, YelpDocument))
@@ -80,6 +81,7 @@ struct _YelpDocumentClass {
gpointer user_data);
void (*release_page) (YelpDocument *document,
YelpPage *page);
+ gpointer (*get_sections) (YelpDocument *document);
};
@@ -124,5 +126,7 @@ void yelp_document_error_request (YelpDocument *document,
YelpError *error);
void yelp_document_error_pending (YelpDocument *document,
YelpError *error);
+GtkTreeModel *yelp_document_get_sections (YelpDocument *document);
+
#endif /* __YELP_DOCUMENT_H__ */
diff --git a/src/yelp-page.c b/src/yelp-page.c
index 00fce62d..c0ad894e 100644
--- a/src/yelp-page.c
+++ b/src/yelp-page.c
@@ -61,6 +61,14 @@ yelp_page_new_string (YelpDocument *document,
return page;
}
+gsize
+yelp_page_get_length (YelpPage *page)
+{
+ g_return_val_if_fail (page != NULL, 0);
+
+ return page->content_len;
+}
+
GIOStatus
yelp_page_read (YelpPage *page,
gchar *buffer,
@@ -84,8 +92,15 @@ page_read_string (YelpPage *page,
gsize *bytes_read,
YelpError **error)
{
+ gint real_count = 0;
g_return_val_if_fail (page != NULL, G_IO_STATUS_ERROR);
+ if (count < 0) {
+ real_count = (page->content_len - page->content_offset) + 1;
+ } else {
+ real_count = count;
+ }
+
if (page->content_offset == page->content_len) {
/* FIXME: set the error */
@@ -95,7 +110,7 @@ page_read_string (YelpPage *page,
/* FIXME: set the error */
return G_IO_STATUS_ERROR;
}
- else if (page->content_offset + count <= page->content_len) {
+ else if (page->content_offset + real_count <= page->content_len) {
strncpy (buffer, page->content + page->content_offset, count);
page->content_offset += count;
*bytes_read = count;
diff --git a/src/yelp-page.h b/src/yelp-page.h
index f4428fad..30a45bf7 100644
--- a/src/yelp-page.h
+++ b/src/yelp-page.h
@@ -79,6 +79,7 @@ GIOStatus yelp_page_read (YelpPage *page,
gsize count,
gsize *bytes_read,
YelpError **error);
+gsize yelp_page_get_length (YelpPage *page);
void yelp_page_free (YelpPage *page);
diff --git a/src/yelp-utils.c b/src/yelp-utils.c
index 8e119890..16b91079 100644
--- a/src/yelp-utils.c
+++ b/src/yelp-utils.c
@@ -1184,6 +1184,7 @@ YelpSpoonType
resolve_man_page (const gchar *name, gchar **result, gchar **section)
{
/* Various ways the path could be presented:
+ * filename - full filename after man:
* name(section) - resolve to a particular section
* name.section - ditto. This must be tested twice. Once for full filename and
* once for section
@@ -1201,7 +1202,7 @@ resolve_man_page (const gchar *name, gchar **result, gchar **section)
if (lbrace) {
rbrace = strrchr (name, ')');
if (rbrace) {
- sect = g_strndup (lbrace+1, rbrace - lbrace - 1);
+ /*sect = g_strndup (lbrace+1, rbrace - lbrace - 1);*/
real_name = g_strndup (name, lbrace - name);
} else {
sect = NULL;
@@ -1211,12 +1212,12 @@ resolve_man_page (const gchar *name, gchar **result, gchar **section)
lbrace = strrchr (name, '.');
if (lbrace) {
repeat = TRUE;
- sect = strdup (lbrace+1);
+ /*sect = strdup (lbrace+1);*/
real_name = g_strndup (name, lbrace - name);
} else {
lbrace = strrchr (name, '#');
if (lbrace) {
- sect = strdup (lbrace+1);
+ /*sect = strdup (lbrace+1);*/
real_name = g_strndup (name, lbrace - name);
} else {
real_name = strdup (name);
@@ -1224,17 +1225,30 @@ resolve_man_page (const gchar *name, gchar **result, gchar **section)
}
}
}
+ printf ("Checking %s\n", real_name);
+ if (g_file_test (real_name, G_FILE_TEST_EXISTS)) {
+ /* Full filename */
+ printf ("Exists\n");
+ *result = g_strdup (real_name);
+ return YELP_SPOON_TYPE_MAN;
+ } else if (g_file_test (name, G_FILE_TEST_EXISTS)) {
+ /* Full filename */
+ printf ("Exists\n");
+ *result = g_strdup (name);
+ return YELP_SPOON_TYPE_MAN;
+ }
+
entry = spoon_man_find_from_name (real_name, sect);
if (entry) {
*result = strdup (entry->path);
- *section = strdup (entry->section);
+ /**section = strdup (entry->section);*/
return YELP_SPOON_TYPE_MAN;
} else if (repeat) {
entry = spoon_man_find_from_name (name, NULL);
if (entry) {
*result = strdup (entry->path);
- *section = strdup (entry->section);
+ /**section = strdup (entry->section);*/
return YELP_SPOON_TYPE_MAN;
}
}
diff --git a/src/yelp-window.c b/src/yelp-window.c
index 163ac1a6..eb72002d 100644
--- a/src/yelp-window.c
+++ b/src/yelp-window.c
@@ -48,6 +48,8 @@
#include "yelp-settings.h"
//#include "yelp-toc-pager.h"
#include "yelp-toc.h"
+#include "yelp-man.h"
+#include "yelp-docbook.h"
#include "yelp-window.h"
#include "yelp-print.h"
#include "yelp-debug.h"
@@ -99,6 +101,9 @@ static void window_populate_find (YelpWindow *window,
GtkWidget *find_bar);
static void window_set_sections (YelpWindow *window,
GtkTreeModel *sections);
+static void window_set_section_cursor (YelpWindow *window,
+ GtkTreeModel *model);
+
/*static void window_do_load (YelpWindow *window,
YelpDocInfo *doc_info,
gchar *frag_id);*/
@@ -232,6 +237,8 @@ static void window_find_previous_cb (GtkAction *action,
YelpWindow *window);
static gboolean tree_model_iter_following (GtkTreeModel *model,
GtkTreeIter *iter);
+static void window_write_html (YelpWindow *window,
+ YelpPage *page);
enum {
NEW_WINDOW_REQUESTED,
@@ -272,6 +279,7 @@ struct _YelpWindowPriv {
/* Location Information */
gchar *uri;
gchar *req_uri;
+ gchar *base_uri;
gint current_request;
YelpDocument *current_document;
gchar *current_frag;
@@ -279,6 +287,7 @@ struct _YelpWindowPriv {
GSList *history_forward;
GtkWidget *back_menu;
GtkWidget *forward_menu;
+ GtkTreeModel *current_sidebar;
/* Callbacks and Idles */
gulong start_handler;
@@ -909,30 +918,24 @@ yelp_window_new (GNode *doc_tree, GList *index)
}
static void
-document_func (YelpDocument *document,
+page_request_cb (YelpDocument *document,
YelpDocumentSignal signal,
gint req_id,
gpointer *func_data,
YelpWindow *window)
{
- YelpHtml *html = window->priv->html_view;
- gchar contents[BUFFER_SIZE];
- gsize read;
+ gchar *contents;
YelpPage *page;
YelpError *error;
+
switch (signal) {
case YELP_DOCUMENT_SIGNAL_PAGE:
- yelp_html_set_base_uri (html, "file:///tmp/blah.html");
- yelp_html_open_stream (html, "application/xhtml+xml");
- page = (YelpPage *) func_data;
- do {
- yelp_page_read (page, contents, BUFFER_SIZE, &read, NULL);
- yelp_html_write (html, contents, read);
- } while (read == BUFFER_SIZE);
- yelp_html_close (html);
+ window_set_sections (window, yelp_document_get_sections (document));
+
+ window_write_html (window, (YelpPage *) func_data);
window->priv->current_request = -1;
- yelp_page_free (page);
+ yelp_page_free ((YelpPage *) func_data);
break;
case YELP_DOCUMENT_SIGNAL_TITLE:
printf ("TITLE: %s (%i)\n", (gchar *) func_data, req_id);
@@ -958,7 +961,6 @@ yelp_window_load (YelpWindow *window, const gchar *uri)
YelpSpoonType type = YELP_SPOON_TYPE_ERROR;
YelpDocument *doc = NULL;
-
g_return_if_fail (YELP_IS_WINDOW (window));
priv = window->priv;
@@ -968,7 +970,6 @@ yelp_window_load (YelpWindow *window, const gchar *uri)
priv->current_request = -1;
}
-
type = yelp_uri_resolve (uri, &real_uri, &frag_id);
/* TODO: handle type errors here first */
@@ -979,8 +980,16 @@ yelp_window_load (YelpWindow *window, const gchar *uri)
switch (type) {
case YELP_SPOON_TYPE_TOC:
doc = yelp_toc_get ();
+ priv->base_uri = g_strdup ("file:///fakefile");
+ break;
+ case YELP_SPOON_TYPE_MAN:
+ priv->base_uri = g_strdup ("file:///fakefile");
+ doc = yelp_man_new (real_uri);
+ priv->uri = "";
break;
case YELP_SPOON_TYPE_DOC:
+ priv->base_uri = g_strdup (uri);
+ doc = yelp_docbook_new (real_uri);
break;
case YELP_SPOON_TYPE_HTML:
break;
@@ -990,12 +999,14 @@ yelp_window_load (YelpWindow *window, const gchar *uri)
}
if (doc) {
+ if (!frag_id)
+ frag_id = g_strdup ("index");
priv->uri = real_uri;
priv->current_frag = frag_id;
priv->req_uri = g_strdup (uri);
priv->current_request = yelp_document_get_page (doc,
frag_id,
- document_func,
+ page_request_cb,
(void *) window);
}
priv->current_document = doc;
@@ -1458,11 +1469,11 @@ window_populate (YelpWindow *window)
g_object_set (priv->side_sects,
"headers-visible", FALSE,
NULL);
- /*gtk_tree_view_insert_column_with_attributes
+ gtk_tree_view_insert_column_with_attributes
(GTK_TREE_VIEW (priv->side_sects), -1,
NULL, gtk_cell_renderer_text_new (),
- "text", YELP_PAGER_COLUMN_TITLE,
- NULL);*/
+ "text", YELP_DOCUMENT_COLUMN_TITLE,
+ NULL);
/* DISABLE FOR NOW
gtk_tree_view_enable_model_drag_source (GTK_TREE_VIEW (priv->side_sects),
@@ -1609,14 +1620,102 @@ window_set_sections (YelpWindow *window,
g_return_if_fail (YELP_IS_WINDOW (window));
priv = window->priv;
- gtk_tree_view_set_model (GTK_TREE_VIEW (priv->side_sects), sections);
+ gtk_tree_view_set_model (GTK_TREE_VIEW (priv->side_sects), sections);
+
+ if (sections) {
+ gtk_widget_show_all (priv->side_sw);
+ window_set_section_cursor (window, sections);
+ } else
+ gtk_widget_hide (priv->side_sw);
- if (sections)
- gtk_widget_show_all (priv->side_sw);
- else
- gtk_widget_hide (priv->side_sw);
}
+static void
+window_set_section_cursor (YelpWindow * window, GtkTreeModel *model)
+{
+ gboolean valid;
+ gchar *id = NULL;
+ GtkTreeIter iter;
+ YelpWindowPriv *priv = window->priv;
+ GtkTreeSelection *selection =
+ gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->side_sects));
+ g_signal_handlers_block_by_func (selection,
+ tree_selection_changed_cb,
+ window);
+ gtk_tree_selection_unselect_all (selection);
+
+ valid = gtk_tree_model_get_iter_first (model, &iter);
+ while (valid) {
+ gtk_tree_model_get (model, &iter,
+ YELP_DOCUMENT_COLUMN_ID, &id,
+ -1);
+ if (g_str_equal (id, priv->current_frag)) {
+ GtkTreePath *path = NULL;
+ GtkTreeIter parent;
+ if (gtk_tree_model_iter_parent (model, &parent, &iter)) {
+ path = gtk_tree_model_get_path (model, &parent);
+ gtk_tree_view_expand_to_path (GTK_TREE_VIEW (priv->side_sects),
+ path);
+ gtk_tree_path_free(path);
+ }
+ path = gtk_tree_model_get_path (model, &iter);
+ gtk_tree_selection_select_path (selection, path);
+
+ gtk_tree_path_free (path);
+ g_free (id);
+ break;
+ }
+
+ g_free (id);
+
+ valid = tree_model_iter_following (model, &iter);
+ }
+ g_signal_handlers_unblock_by_func (selection,
+ tree_selection_changed_cb,
+ window);
+}
+
+/* if (model) {
+ GtkTreeSelection *selection =
+ gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->side_sects));
+ g_signal_handlers_block_by_func (selection,
+ tree_selection_changed_cb,
+ window);
+ gtk_tree_selection_unselect_all (selection);
+
+ valid = gtk_tree_model_get_iter_first (model, &iter);
+ while (valid) {
+ gtk_tree_model_get (model, &iter,
+ YELP_PAGER_COLUMN_ID, &id,
+ -1);
+ if (yelp_pager_page_contains_frag (pager,
+ id,
+ priv->current_frag)) {
+ GtkTreePath *path = NULL;
+ GtkTreeIter parent;
+ if (gtk_tree_model_iter_parent (model, &parent, &iter)) {
+ path = gtk_tree_model_get_path (model, &parent);
+ gtk_tree_view_expand_to_path (GTK_TREE_VIEW (priv->side_sects),
+ path);
+ gtk_tree_path_free(path);
+ }
+ path = gtk_tree_model_get_path (model, &iter);
+ gtk_tree_selection_select_path (selection, path);
+
+ gtk_tree_path_free (path);
+ g_free (id);
+ break;
+ }
+
+ g_free (id);
+
+ valid = tree_model_iter_following (model, &iter);
+ }
+ g_signal_handlers_unblock_by_func (selection,
+ tree_selection_changed_cb,
+ window);
+ }*/
+
#if 0
static gboolean
window_do_load_pager (YelpWindow *window,
@@ -2251,7 +2350,6 @@ html_uri_selected_cb (YelpHtml *html,
debug_print (DB_FUNCTION, "entering\n");
debug_print (DB_ARG, " uri = \"%s\"\n", uri);
-
if (!handled) {
yelp_window_load (window, uri);
}
@@ -2323,7 +2421,6 @@ static void
tree_selection_changed_cb (GtkTreeSelection *selection,
YelpWindow *window)
{
-#if 0
YelpWindowPriv *priv;
GtkTreeModel *model;
GtkTreeIter iter;
@@ -2336,13 +2433,12 @@ tree_selection_changed_cb (GtkTreeSelection *selection,
if (gtk_tree_selection_get_selected (selection, NULL, &iter)) {
model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->side_sects));
gtk_tree_model_get (model, &iter,
- YELP_PAGER_COLUMN_ID, &id,
+ YELP_DOCUMENT_COLUMN_ID, &id,
-1);
- uri = yelp_doc_info_get_uri (priv->current_doc, id, YELP_URI_TYPE_ANY);
+ uri = g_strdup_printf ("%s#%s", priv->base_uri, id);
yelp_window_load (window, uri);
g_free (uri);
}
-#endif
}
static void
@@ -3062,7 +3158,7 @@ window_about_cb (GtkAction *action, YelpWindow *window)
"Mikael Hallendal <micke@imendio.com>",
"Alexander Larsson <alexl@redhat.com>",
"Shaun McCance <shaunm@gnome.org>",
- "Don Scorgie <DonScorgie@Blueyonder.co.uk>",
+ "Don Scorgie <Don@Scorgie.org>",
"Brent Smith <gnome@nextreality.net>",
NULL
};
@@ -3371,3 +3467,20 @@ idle_write (IdleWriterContext *context)
return FALSE;
}
+static void
+window_write_html (YelpWindow *window, YelpPage *page)
+{
+ gsize read;
+ YelpHtml *html = window->priv->html_view;
+ gchar contents[BUFFER_SIZE];
+
+ /* Use a silly fake URI to stop gecko doing silly things */
+ yelp_html_set_base_uri (html, window->priv->base_uri);
+ yelp_html_open_stream (html, "application/xhtml+xml");
+
+ do {
+ yelp_page_read (page, contents, BUFFER_SIZE, &read, NULL);
+ yelp_html_write (html, contents, read);
+ } while (read == BUFFER_SIZE);
+ yelp_html_close (html);
+}