It's the worlds ugliest highlighting code!!!! The result is okay so long
Thu May 17 16:20:04 2001 Jonathan Blandford <jrb@redhat.com> * demos/gtk-demo/main.c (fontify): It's the worlds ugliest highlighting code!!!! The result is okay so long as you don't try to stress it. It also highlights a bug in the TextView so it's in an unproportional font right now until it's fixed. *demos/gtk-demo/*.c: Clean up code a bit to make it ugly-parser(TM) friendly. (-:
This commit is contained in:
committed by
Jonathan Blandford
parent
288ff7e058
commit
009212ad28
@ -93,6 +93,271 @@ read_line (FILE *stream, GString *str)
|
||||
return n_read > 0;
|
||||
}
|
||||
|
||||
|
||||
/* Stupid syntax highlighting.
|
||||
*
|
||||
* No regex was used in the making of this highlighting.
|
||||
* It should only work for simple cases. This is good, as
|
||||
* that's all we should have in the demos.
|
||||
*/
|
||||
/* This code should not be used elsewhere, except perhaps as an example of how
|
||||
* to iterate through a text buffer.
|
||||
*/
|
||||
enum {
|
||||
STATE_NORMAL,
|
||||
STATE_IN_COMMENT,
|
||||
};
|
||||
|
||||
static gchar *tokens[] =
|
||||
{
|
||||
"/*",
|
||||
"\"",
|
||||
NULL
|
||||
};
|
||||
|
||||
static gchar *types[] =
|
||||
{
|
||||
"static",
|
||||
"const ",
|
||||
"void",
|
||||
"gint",
|
||||
"int ",
|
||||
"char ",
|
||||
"gchar ",
|
||||
"gfloat",
|
||||
"float",
|
||||
"gint8",
|
||||
"gint16",
|
||||
"gint32",
|
||||
"guint",
|
||||
"guint8",
|
||||
"guint16",
|
||||
"guint32",
|
||||
"guchar",
|
||||
"glong",
|
||||
"gboolean" ,
|
||||
"gshort",
|
||||
"gushort",
|
||||
"gulong",
|
||||
"gdouble",
|
||||
"gldouble",
|
||||
"gpointer",
|
||||
"NULL",
|
||||
"GList",
|
||||
"GSList",
|
||||
"FALSE",
|
||||
"TRUE",
|
||||
"FILE ",
|
||||
"GtkObject ",
|
||||
"GtkColorSelection ",
|
||||
"GtkWidget ",
|
||||
"GtkButton ",
|
||||
"GdkColor ",
|
||||
"GdkRectangle ",
|
||||
"GdkEventExpose ",
|
||||
"GdkGC ",
|
||||
"GdkPixbufLoader ",
|
||||
"GdkPixbuf ",
|
||||
"GError",
|
||||
"size_t",
|
||||
NULL
|
||||
};
|
||||
|
||||
static gchar *control[] =
|
||||
{
|
||||
" if ",
|
||||
" while ",
|
||||
" else",
|
||||
" do ",
|
||||
" for ",
|
||||
"?",
|
||||
":",
|
||||
"return ",
|
||||
"goto ",
|
||||
NULL
|
||||
};
|
||||
void
|
||||
parse_chars (gchar *text,
|
||||
gchar **end_ptr,
|
||||
gint *state,
|
||||
gchar **tag,
|
||||
gboolean start)
|
||||
{
|
||||
gint i;
|
||||
gchar *next_token;
|
||||
|
||||
/* Handle comments first */
|
||||
if (*state == STATE_IN_COMMENT)
|
||||
{
|
||||
*end_ptr = strstr (text, "*/");
|
||||
if (*end_ptr)
|
||||
{
|
||||
*end_ptr += 2;
|
||||
*state = STATE_NORMAL;
|
||||
*tag = "comment";
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
*tag = NULL;
|
||||
*end_ptr = NULL;
|
||||
|
||||
/* check for comment */
|
||||
if (!strncmp (text, "/*", 2))
|
||||
{
|
||||
*end_ptr = strstr (text, "*/");
|
||||
if (*end_ptr)
|
||||
*end_ptr += 2;
|
||||
else
|
||||
*state = STATE_IN_COMMENT;
|
||||
*tag = "comment";
|
||||
return;
|
||||
}
|
||||
|
||||
/* check for preprocessor defines */
|
||||
if (*text == '#' && start)
|
||||
{
|
||||
*end_ptr = NULL;
|
||||
*tag = "preprocessor";
|
||||
return;
|
||||
}
|
||||
|
||||
/* functions */
|
||||
if (start && * text != '\t' && *text != ' ' && *text != '{' && *text != '}')
|
||||
{
|
||||
if (strstr (text, "("))
|
||||
{
|
||||
*end_ptr = strstr (text, "(");
|
||||
*tag = "function";
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* check for types */
|
||||
for (i = 0; types[i] != NULL; i++)
|
||||
if (!strncmp (text, types[i], strlen (types[i])))
|
||||
{
|
||||
*end_ptr = text + strlen (types[i]);
|
||||
*tag = "type";
|
||||
return;
|
||||
}
|
||||
|
||||
/* check for control */
|
||||
for (i = 0; control[i] != NULL; i++)
|
||||
if (!strncmp (text, control[i], strlen (control[i])))
|
||||
{
|
||||
*end_ptr = text + strlen (control[i]);
|
||||
*tag = "control";
|
||||
return;
|
||||
}
|
||||
|
||||
/* check for string */
|
||||
if (text[0] == '"')
|
||||
{
|
||||
gint maybe_escape = FALSE;
|
||||
|
||||
*end_ptr = text + 1;
|
||||
*tag = "string";
|
||||
while (**end_ptr != '\000')
|
||||
{
|
||||
if (**end_ptr == '\"' && !maybe_escape)
|
||||
{
|
||||
*end_ptr += 1;
|
||||
return;
|
||||
}
|
||||
if (**end_ptr == '\\')
|
||||
maybe_escape = TRUE;
|
||||
else
|
||||
maybe_escape = FALSE;
|
||||
*end_ptr += 1;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* not at the start of a tag. Find the next one. */
|
||||
for (i = 0; tokens[i] != NULL; i++)
|
||||
{
|
||||
next_token = strstr (text, tokens[i]);
|
||||
if (next_token)
|
||||
{
|
||||
if (*end_ptr)
|
||||
*end_ptr = (*end_ptr<next_token)?*end_ptr:next_token;
|
||||
else
|
||||
*end_ptr = next_token;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; types[i] != NULL; i++)
|
||||
{
|
||||
next_token = strstr (text, types[i]);
|
||||
if (next_token)
|
||||
{
|
||||
if (*end_ptr)
|
||||
*end_ptr = (*end_ptr<next_token)?*end_ptr:next_token;
|
||||
else
|
||||
*end_ptr = next_token;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; control[i] != NULL; i++)
|
||||
{
|
||||
next_token = strstr (text, control[i]);
|
||||
if (next_token)
|
||||
{
|
||||
if (*end_ptr)
|
||||
*end_ptr = (*end_ptr<next_token)?*end_ptr:next_token;
|
||||
else
|
||||
*end_ptr = next_token;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* While not as cool as c-mode, this will do as a quick attempt at highlighting */
|
||||
static void
|
||||
fontify ()
|
||||
{
|
||||
GtkTextIter start_iter, next_iter, tmp_iter;
|
||||
gint state;
|
||||
gchar *text;
|
||||
gchar *start_ptr, *end_ptr;
|
||||
gchar *tag;
|
||||
|
||||
state = STATE_NORMAL;
|
||||
|
||||
gtk_text_buffer_get_iter_at_offset (source_buffer, &start_iter, 0);
|
||||
|
||||
next_iter = start_iter;
|
||||
while (gtk_text_iter_forward_line (&next_iter))
|
||||
{
|
||||
gboolean start = TRUE;
|
||||
start_ptr = text = gtk_text_iter_get_text (&start_iter, &next_iter);
|
||||
|
||||
do
|
||||
{
|
||||
parse_chars (start_ptr, &end_ptr, &state, &tag, start);
|
||||
|
||||
start = FALSE;
|
||||
if (end_ptr)
|
||||
{
|
||||
tmp_iter = start_iter;
|
||||
gtk_text_iter_forward_chars (&tmp_iter, end_ptr - start_ptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp_iter = next_iter;
|
||||
}
|
||||
if (tag)
|
||||
gtk_text_buffer_apply_tag_by_name (info_buffer, tag, &start_iter, &tmp_iter);
|
||||
|
||||
start_iter = tmp_iter;
|
||||
start_ptr = end_ptr;
|
||||
}
|
||||
while (end_ptr);
|
||||
|
||||
g_free (text);
|
||||
start_iter = next_iter;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
load_file (const gchar *filename)
|
||||
{
|
||||
@ -230,8 +495,7 @@ load_file (const gchar *filename)
|
||||
}
|
||||
}
|
||||
|
||||
gtk_text_buffer_get_bounds (source_buffer, &start, &end);
|
||||
gtk_text_buffer_apply_tag_by_name (info_buffer, "source", &start, &end);
|
||||
fontify ();
|
||||
|
||||
g_string_free (buffer, TRUE);
|
||||
}
|
||||
@ -381,7 +645,7 @@ create_text (GtkTextBuffer **buffer,
|
||||
|
||||
if (is_source)
|
||||
{
|
||||
font_desc = pango_font_description_from_string ("Courier 10");
|
||||
font_desc = pango_font_description_from_string ("Courier 14");
|
||||
gtk_widget_modify_font (text_view, font_desc);
|
||||
pango_font_description_free (font_desc);
|
||||
|
||||
@ -505,10 +769,26 @@ main (int argc, char **argv)
|
||||
"font", "Sans 18",
|
||||
NULL);
|
||||
|
||||
tag = gtk_text_buffer_create_tag (info_buffer, "source",
|
||||
"font", "Courier 10",
|
||||
"pixels_above_lines", 0,
|
||||
"pixels_below_lines", 0,
|
||||
tag = gtk_text_buffer_create_tag (info_buffer, "comment",
|
||||
"foreground", "blue",
|
||||
NULL);
|
||||
tag = gtk_text_buffer_create_tag (info_buffer, "type",
|
||||
"foreground", "red",
|
||||
NULL);
|
||||
tag = gtk_text_buffer_create_tag (info_buffer, "string",
|
||||
"foreground", "SpringGreen3",
|
||||
"weight", PANGO_WEIGHT_BOLD,
|
||||
NULL);
|
||||
tag = gtk_text_buffer_create_tag (info_buffer, "control",
|
||||
"foreground", "purple",
|
||||
NULL);
|
||||
tag = gtk_text_buffer_create_tag (info_buffer, "preprocessor",
|
||||
"style", PANGO_STYLE_OBLIQUE,
|
||||
"foreground", "burlywood4",
|
||||
NULL);
|
||||
tag = gtk_text_buffer_create_tag (info_buffer, "function",
|
||||
"weight", PANGO_WEIGHT_BOLD,
|
||||
"foreground", "DarkGoldenrod4",
|
||||
NULL);
|
||||
|
||||
gtk_window_set_default_size (GTK_WINDOW (window), 600, 400);
|
||||
|
||||
Reference in New Issue
Block a user