gnome-mud r824 - in trunk: . src
- From: lharris svn gnome org
- To: svn-commits-list gnome org
- Subject: gnome-mud r824 - in trunk: . src
- Date: Sun, 22 Mar 2009 00:32:09 +0000 (UTC)
Author: lharris
Date: Sun Mar 22 00:32:09 2009
New Revision: 824
URL: http://svn.gnome.org/viewvc/gnome-mud?rev=824&view=rev
Log:
MudLog now parses the ECMA-48 codes and emits a html file instead of the raw color information.
Added:
trunk/src/ecma48.h
Modified:
trunk/ChangeLog
trunk/src/mud-log.c
Added: trunk/src/ecma48.h
==============================================================================
--- (empty file)
+++ trunk/src/ecma48.h Sun Mar 22 00:32:09 2009
@@ -0,0 +1,57 @@
+/* GNOME-Mud - A simple Mud Client
+ * ecma48.h
+ * Copyright (C) 2005-2009 Les Harris <lharris gnome org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef ECMA_48_H
+#define ECMA_48_H
+
+G_BEGIN_DECLS
+
+#define ECMA_ESCAPE_BYTE 0x1B
+#define ECMA_ESCAPE_BYTE_C '\x1B'
+
+#define ECMA_ATTRIBUTE_NORMAL 0
+#define ECMA_ATTRIBUTE_BOLD 1
+#define ECMA_ATTRIBUTE_ITALIC 3
+#define ECMA_ATTRIBUTE_UNDERLINE 4
+#define ECMA_ATTRIBUTE_BLINK 5
+#define ECMA_ATTRIBUTE_REVERSE 7
+#define ECMA_ATTRIBUTE_NODISPLAY 8
+
+#define ECMA_FORECOLOR_BLACK 30
+#define ECMA_FORECOLOR_RED 31
+#define ECMA_FORECOLOR_GREEN 32
+#define ECMA_FORECOLOR_YELLOW 33
+#define ECMA_FORECOLOR_BLUE 34
+#define ECMA_FORECOLOR_MAGENTA 35
+#define ECMA_FORECOLOR_CYAN 36
+#define ECMA_FORECOLOR_WHITE 37
+
+#define ECMA_BACKCOLOR_BLACK 40
+#define ECMA_BACKCOLOR_RED 41
+#define ECMA_BACKCOLOR_GREEN 42
+#define ECMA_BACKCOLOR_YELLOW 43
+#define ECMA_BACKCOLOR_BLUE 44
+#define ECMA_BACKCOLOR_MAGENTA 45
+#define ECMA_BACKCOLOR_CYAN 46
+#define ECMA_BACKCOLOR_WHITE 47
+
+G_END_DECLS
+
+#endif // ECMA_48_H
+
Modified: trunk/src/mud-log.c
==============================================================================
--- trunk/src/mud-log.c (original)
+++ trunk/src/mud-log.c Sun Mar 22 00:32:09 2009
@@ -36,6 +36,7 @@
#include "mud-connection-view.h"
#include "mud-line-buffer.h"
#include "utils.h"
+#include "ecma48.h"
struct _MudLogPrivate
{
@@ -59,6 +60,8 @@
gboolean done;
gboolean finalizing;
+ gboolean bold;
+ gboolean first;
gint next_count;
gint prev_count;
@@ -70,6 +73,8 @@
FILE *logfile;
+ GQueue *span_queue;
+
MudLineBuffer *line_buffer;
MudWindow *parent_window;
@@ -121,6 +126,20 @@
/* Private Methods */
static void mud_log_write(MudLog *log, const gchar *data, gsize size);
static void mud_log_remove(MudLog *log);
+static gchar *mud_log_parse_ansi(MudLog *self, const gchar *data, gsize size);
+static void mud_log_parse_ecma_color(MudLog *self,
+ const gchar *data,
+ gsize size,
+ GString *output);
+static void mud_log_write_html_header(MudLog *self);
+static void mud_log_write_html_footer(MudLog *self);
+static void mud_log_write_html_foreground_span(MudLog *self,
+ GString *output,
+ gboolean bold,
+ gint ecma_code);
+static void mud_log_write_html_background_span(MudLog *self,
+ GString *output,
+ gint ecma_code);
// MudLog class functions
static void
@@ -232,6 +251,8 @@
g_error("Tried to instantiate MudLog without passing MudConnectionView.");
}
+ self->priv->span_queue = g_queue_new();
+
return obj;
}
@@ -248,6 +269,8 @@
if(MLog->priv->active)
mud_log_close(MLog);
+ g_queue_free(MLog->priv->span_queue);
+
if(MLog->mud_name)
g_free(MLog->mud_name);
@@ -626,10 +649,22 @@
if(result == GTK_RESPONSE_OK)
{
+ if(self->priv->color)
+ {
+ gchar *temp = self->priv->filename;
+
+ self->priv->filename = g_strdup_printf("%s.html", self->priv->filename);
+
+ g_free(temp);
+
+ }
self->priv->logfile = fopen(self->priv->filename,
(self->priv->append) ? "a" : "w");
if (self->priv->logfile)
{
+ if(self->priv->color)
+ mud_log_write_html_header(self);
+
time(&t);
strftime(buf, 1024,
_("\n*** Log starts *** %d/%m/%Y %H:%M:%S\n"),
@@ -740,6 +775,10 @@
localtime(&t));
fprintf(log->priv->logfile, "%s", buf);
+
+ if(log->priv->color)
+ mud_log_write_html_footer(log);
+
fsync(fileno(log->priv->logfile));
fclose(log->priv->logfile);
@@ -824,12 +863,378 @@
}
else
{
- write_size = fwrite(data, 1, size, log->priv->logfile);
- fsync(fileno(log->priv->logfile));
+ gchar *output;
- if(write_size != size)
- g_critical(_("Could not write data to log file!"));
+ output = mud_log_parse_ansi(log, data, size);
+
+ if(output)
+ {
+ write_size = fwrite(output, 1, strlen(output), log->priv->logfile);
+ fsync(fileno(log->priv->logfile));
+
+ g_free(output);
+ }
+ }
+}
+
+static gchar *
+mud_log_parse_ansi(MudLog *self,
+ const gchar *data,
+ gsize size)
+{
+ gsize i;
+ GString *ecma_color;
+ GString *output;
+
+ output = g_string_new(NULL);
+
+ for(i = 0; i < size; ++i)
+ {
+ if(data[i] == ECMA_ESCAPE_BYTE_C)
+ {
+ ecma_color = g_string_new(NULL);
+ ++i;
+
+ while(data[++i] != 'm' && i < size)
+ ecma_color = g_string_append_c(ecma_color, data[i]);
+
+ mud_log_parse_ecma_color(self,
+ ecma_color->str,
+ ecma_color->len,
+ output);
+
+ g_string_free(ecma_color, TRUE);
+
+ continue;
+ }
+
+ if(data[i] != '\r') // Just log newlines
+ {
+ if(data[i] == '<')
+ output = g_string_append(output, "<");
+ else if(data[i] == '>')
+ output = g_string_append(output, ">");
+ else
+ output = g_string_append_c(output, data[i]);
+ }
+ }
+
+ return g_string_free(output, (output->len == 0) );
+}
+
+#define STATE_ATTRIBUTE 0
+#define STATE_FORECOLOR 1
+#define STATE_BACKCOLOR 2
+
+static void
+mud_log_parse_ecma_color(MudLog *self,
+ const gchar *data,
+ gsize size,
+ GString *output)
+{
+ gint i, argc, byte, color_index;
+ gchar **argv;
+
+ argv = g_strsplit(data, ";", -1);
+ argc = g_strv_length(argv);
+
+ if(argc < 1 || argc > 3)
+ {
+ g_strfreev(argv);
+
+ return;
+ }
+
+ self->priv->bold = FALSE;
+
+ for(i = 0; i < argc; ++i)
+ {
+ switch(i)
+ {
+ case STATE_ATTRIBUTE:
+ byte = (gint)atol(argv[0]);
+
+ switch(byte)
+ {
+ case ECMA_ATTRIBUTE_NORMAL:
+ while(!g_queue_is_empty(self->priv->span_queue))
+ {
+ output = g_string_append(output, "</span>");
+ g_queue_pop_head(self->priv->span_queue);
+ }
+
+ self->priv->bold = FALSE;
+ break;
+
+ case ECMA_ATTRIBUTE_BOLD:
+ output = g_string_append(output, "<span style=\"font-weight: bold;\">");
+ g_queue_push_head(self->priv->span_queue, GINT_TO_POINTER(ECMA_ATTRIBUTE_BOLD));
+ self->priv->bold = TRUE;
+ break;
+
+ case ECMA_ATTRIBUTE_ITALIC:
+ output = g_string_append(output, "<span style=\"font-style: italic;\">");
+ g_queue_push_head(self->priv->span_queue, GINT_TO_POINTER(ECMA_ATTRIBUTE_ITALIC));
+ break;
+
+ case ECMA_ATTRIBUTE_UNDERLINE:
+ output = g_string_append(output, "<span style=\"text-decoration: underline;\">");
+ g_queue_push_head(self->priv->span_queue, GINT_TO_POINTER(ECMA_ATTRIBUTE_UNDERLINE));
+ break;
+
+ case ECMA_ATTRIBUTE_BLINK:
+ output = g_string_append(output, "<span style=\"text-decoration: blink;\">");
+ g_queue_push_head(self->priv->span_queue, GINT_TO_POINTER(ECMA_ATTRIBUTE_BLINK));
+ break;
+
+ /* FIXME: Figure out what to do to make text reversed in the browser */
+ case ECMA_ATTRIBUTE_REVERSE:
+ output = g_string_append(output, "<span>");
+ g_queue_push_head(self->priv->span_queue, GINT_TO_POINTER(ECMA_ATTRIBUTE_REVERSE));
+ break;
+
+ case ECMA_ATTRIBUTE_NODISPLAY:
+ // Dont' display it.
+ break;
+ }
+ break;
+
+ case STATE_FORECOLOR:
+ byte = (gint)atol(argv[1]);
+
+ switch(byte)
+ {
+ case ECMA_FORECOLOR_BLACK:
+ mud_log_write_html_foreground_span(self,
+ output,
+ self->priv->bold,
+ ECMA_FORECOLOR_BLACK);
+ break;
+
+ case ECMA_FORECOLOR_RED:
+ mud_log_write_html_foreground_span(self,
+ output,
+ self->priv->bold,
+ ECMA_FORECOLOR_RED);
+ break;
+
+ case ECMA_FORECOLOR_GREEN:
+ mud_log_write_html_foreground_span(self,
+ output,
+ self->priv->bold,
+ ECMA_FORECOLOR_GREEN);
+ break;
+
+ case ECMA_FORECOLOR_YELLOW:
+ mud_log_write_html_foreground_span(self,
+ output,
+ self->priv->bold,
+ ECMA_FORECOLOR_YELLOW);
+ break;
+
+ case ECMA_FORECOLOR_BLUE:
+ mud_log_write_html_foreground_span(self,
+ output,
+ self->priv->bold,
+ ECMA_FORECOLOR_BLUE);
+ break;
+
+ case ECMA_FORECOLOR_MAGENTA:
+ mud_log_write_html_foreground_span(self,
+ output,
+ self->priv->bold,
+ ECMA_FORECOLOR_MAGENTA);
+ break;
+
+ case ECMA_FORECOLOR_CYAN:
+ mud_log_write_html_foreground_span(self,
+ output,
+ self->priv->bold,
+ ECMA_FORECOLOR_CYAN);
+ break;
+
+ case ECMA_FORECOLOR_WHITE:
+ mud_log_write_html_foreground_span(self,
+ output,
+ self->priv->bold,
+ ECMA_FORECOLOR_WHITE);
+ }
+ break;
+ case STATE_BACKCOLOR:
+ byte = (gint)atol(argv[2]);
+
+ switch(byte)
+ {
+ case ECMA_BACKCOLOR_BLACK:
+ mud_log_write_html_background_span(self,
+ output,
+ ECMA_BACKCOLOR_BLACK);
+ break;
+
+ case ECMA_BACKCOLOR_RED:
+ mud_log_write_html_background_span(self,
+ output,
+ ECMA_BACKCOLOR_RED);
+ break;
+
+ case ECMA_BACKCOLOR_GREEN:
+ mud_log_write_html_background_span(self,
+ output,
+ ECMA_BACKCOLOR_GREEN);
+ break;
+
+ case ECMA_BACKCOLOR_YELLOW:
+ mud_log_write_html_background_span(self,
+ output,
+ ECMA_BACKCOLOR_YELLOW);
+ break;
+
+ case ECMA_BACKCOLOR_BLUE:
+ mud_log_write_html_background_span(self,
+ output,
+ ECMA_BACKCOLOR_BLUE);
+ break;
+
+ case ECMA_BACKCOLOR_MAGENTA:
+ mud_log_write_html_background_span(self,
+ output,
+ ECMA_BACKCOLOR_MAGENTA);
+ break;
+
+ case ECMA_BACKCOLOR_CYAN:
+ mud_log_write_html_background_span(self,
+ output,
+ ECMA_BACKCOLOR_CYAN);
+ break;
+
+ case ECMA_BACKCOLOR_WHITE:
+ mud_log_write_html_background_span(self,
+ output,
+ ECMA_BACKCOLOR_WHITE);
+ break;
+ }
+ break;
+ }
+ }
+
+ g_strfreev(argv);
+}
+
+static void
+mud_log_write_html_header(MudLog *self)
+{
+ gchar *title = g_path_get_basename(self->priv->filename);
+
+ fprintf(self->priv->logfile, "%s", "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
+ fprintf(self->priv->logfile, "%s", "\t<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n ");
+ fprintf(self->priv->logfile, "%s", "\t\t\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n\n");
+
+ fprintf(self->priv->logfile, "%s", "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n");
+
+ fprintf(self->priv->logfile, "\t<head>\n\t\t<title>%s</title>\n\n\t\t",
+ title);
+
+ g_free(title);
+
+ fprintf(self->priv->logfile, "%s", "<style type=\"text/css\">\n\t\t\t");
+
+ fprintf(self->priv->logfile, "body {\n\t\t\t\tbackground-color: rgb(%d, %d, %d);\n",
+ self->priv->parent->profile->preferences->Background.red / 256,
+ self->priv->parent->profile->preferences->Background.green / 256,
+ self->priv->parent->profile->preferences->Background.blue / 256);
+
+ fprintf(self->priv->logfile, "\t\t\t\tcolor: rgb(%d, %d, %d);\n",
+ self->priv->parent->profile->preferences->Foreground.red / 256,
+ self->priv->parent->profile->preferences->Foreground.green / 256,
+ self->priv->parent->profile->preferences->Foreground.blue / 256);
+
+ fprintf(self->priv->logfile, "%s", "\t\t\t\tfont-family: monospace;\n");
+
+ fprintf(self->priv->logfile, "\t\t\t}\n");
+
+ fprintf(self->priv->logfile, "%s", "\t\t</style>\n\n\t</head>\n\n\t<body>\n\t\t<pre>\n");
+
+ fsync(fileno(self->priv->logfile));
+}
+
+static void
+mud_log_write_html_footer(MudLog *self)
+{
+ fprintf(self->priv->logfile, "%s", "\t\t</pre>\n\t</body>\n</html>\n");
+ fprintf(self->priv->logfile, "<!-- Generated by Gnome-Mud %s http://live.gnome.org/GnomeMud -->\n", VERSION);
+
+ fsync(fileno(self->priv->logfile));
+}
+
+static void
+mud_log_write_html_foreground_span(MudLog *self,
+ GString *output,
+ gboolean bold,
+ gint ecma_code)
+{
+ gint color_index = ecma_code - 30;
+
+ /* Work around some gnome-mud palette weirdness */
+ switch(ecma_code)
+ {
+ case ECMA_FORECOLOR_GREEN:
+ color_index = 4;
+ break;
+
+ case ECMA_FORECOLOR_YELLOW:
+ color_index = 5;
+ break;
+
+ case ECMA_FORECOLOR_BLUE:
+ color_index = 2;
+ break;
+
+ case ECMA_FORECOLOR_MAGENTA:
+ color_index = 3;
+ break;
+ }
+
+ color_index += (bold) ? 8 : 0;
+
+ g_string_append_printf(output, "<span style=\"color: rgb(%d, %d, %d);\">",
+ self->priv->parent->profile->preferences->Colors[color_index].red / 256,
+ self->priv->parent->profile->preferences->Colors[color_index].blue / 256,
+ self->priv->parent->profile->preferences->Colors[color_index].green / 256);
+ g_queue_push_head(self->priv->span_queue, GINT_TO_POINTER(ecma_code));
+}
+
+static void
+mud_log_write_html_background_span(MudLog *self,
+ GString *output,
+ gint ecma_code)
+{
+ gint color_index = ecma_code - 40;
+
+ /* Work around some gnome-mud palette weirdness */
+ switch(ecma_code)
+ {
+ case ECMA_BACKCOLOR_GREEN:
+ color_index = 4;
+ break;
+
+ case ECMA_BACKCOLOR_YELLOW:
+ color_index = 5;
+ break;
+
+ case ECMA_BACKCOLOR_BLUE:
+ color_index = 2;
+ break;
+
+ case ECMA_BACKCOLOR_MAGENTA:
+ color_index = 3;
+ break;
}
+
+ g_string_append_printf(output, "<span style=\"background-color: rgb(%d, %d, %d);\">",
+ self->priv->parent->profile->preferences->Colors[color_index].red / 256,
+ self->priv->parent->profile->preferences->Colors[color_index].blue / 256,
+ self->priv->parent->profile->preferences->Colors[color_index].green / 256);
+ g_queue_push_head(self->priv->span_queue, GINT_TO_POINTER(ecma_code));
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]