/* Glimmer - syntax-highlight.c * * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include "declarations.h" #include "gtkextext/gtkextext.h" #include "syntax-highlight.h" #include "colors.h" #include "insert.h" #include "macro-language.h" #include "main.h" #include "misc.h" #include "settings.h" #include "signals.h" void g_strconvescape (gchar * source); GList *highlight_options = NULL; GList *highlight_tables = NULL; GdsFileHighlightTable *parse_table = NULL; gboolean parsing_language = FALSE; GList *syntax_list = NULL; GList *pattern_list = NULL; GList *embedded_list = NULL; struct highlight_cache HighlightCache; GtkWidget * build_highlight_menu (void) { FILE *file; GList *filenames = NULL; GList *names = NULL; GList *cur = NULL; GtkWidget *menu = NULL; GtkWidget *none_item = NULL; GtkWidget *menuitem = NULL; gchar *text; gchar buffer[1024]; gchar *filename = NULL; gchar home_dir[384] = ""; gchar install_dir[] = LANG_DIR; g_snprintf (home_dir, sizeof (home_dir), "%s/." PACKAGE "/languages", getenv ("HOME")); menu = gtk_menu_new (); none_item = gtk_menu_item_new_with_label ("None"); gtk_object_set_data (GTK_OBJECT (none_item), "filename", "none"); highlight_options = g_list_append (highlight_options, (gpointer) none_item); gtk_signal_connect (GTK_OBJECT (none_item), "activate", GTK_SIGNAL_FUNC (highlight_table_change_cb), GINT_TO_POINTER (1)); gtk_menu_append (GTK_MENU (menu), none_item); gtk_widget_show (none_item); gtk_widget_show (menu); filenames = build_file_listing (home_dir, filenames); filenames = build_file_listing (install_dir, filenames); for (cur = g_list_first (filenames); cur; cur = cur->next) { filename = (gchar *) cur->data; if (!(file = fopen (filename, "r"))) continue; while (fgets (buffer, sizeof (buffer), file)) { if (buffer[0] == '#') continue; if (strstr (buffer, "")) { while (fgets (buffer, sizeof (buffer), file) != NULL) { if (strstr (buffer, "")) break; if (strstr (buffer, "\n")) buffer[strlen (buffer) - 1] = '\0'; if ((text = strstr (buffer, ""))) { gchar *end; text = text + strlen (""); end = strstr (text, ""); if (end) *end = '\0'; text = g_strdup (text); if (!check_list_for_string (names, text)) { menuitem = gtk_menu_item_new_with_label (text); highlight_options = g_list_append (highlight_options, (gpointer) menuitem); gtk_object_set_data (GTK_OBJECT (menuitem), "filename", (gpointer) g_strdup (filename)); gtk_signal_connect (GTK_OBJECT (menuitem), "activate", GTK_SIGNAL_FUNC (highlight_table_change_cb), GINT_TO_POINTER (1)); gtk_menu_append (GTK_MENU (menu), menuitem); gtk_widget_show (menuitem); names = g_list_append (names, (gpointer) text); continue; } else { g_free (text); } } } } } fclose (file); } g_list_delete_all (filenames); g_list_delete_all (names); return (menu); } void highlight_table_change_cb (GtkWidget * widget, gint num) { gchar *filename; GdsFileHighlightTable *table; filename = gtk_object_get_data (GTK_OBJECT (widget), "filename"); table = cur_file->tables; attach_highlight_tables (cur_file, filename); if (cur_file->tables != table) cur_file->default_lang = FALSE; adjust_sensitivity (); } GList * build_file_listing (gchar * directory, GList * filenames) { DIR *dir_list = NULL; struct dirent *dir; gchar *full_path = NULL; dir_list = opendir (directory); if (dir_list) { while ((dir = readdir (dir_list)) != NULL) { if (dir->d_ino > 0) { /* Still a possible mem leak starting here. */ full_path = g_strconcat (directory, "/", dir->d_name, NULL); filenames = g_list_append (filenames, (gpointer) full_path); } } closedir (dir_list); } return (filenames); } gint reparse_highlight_table (GdsFileHighlightTable * table) { GList *new_list = NULL; GList *temp; GdsFile *current; GdsFile *old; gchar *filename; gint retval = 0; if (table == NULL) return (0); old = cur_file; filename = g_strdup (table->filename); for (temp = g_list_first (files_list); temp; temp = temp->next) { current = GDS_FILE (temp->data); if (current->tables == table) { detach_highlight_tables (current); new_list = g_list_append (new_list, (gpointer) current); } } for (temp = g_list_first (new_list); temp; temp = temp->next) { current = GDS_FILE (temp->data); cur_file = current; attach_highlight_tables (current, filename); retval++; } cur_file = old; g_list_free (new_list); g_free (filename); return (retval); } void apply_color_changes (void) { GList *temp; GdsFile *current; temp = g_list_first (files_list); for (temp = g_list_first (files_list); temp; temp = temp->next) { current = (GdsFile *) temp->data; if (current->tables && current->tables->syntax) gtk_extext_install_table (GTK_EXTEXT (current->text), current->tables->syntax); if (current->tables && current->tables->pattern) gtk_extext_install_table (GTK_EXTEXT (current->text), current->tables->pattern); if (current->tables && current->tables->embedded) gtk_extext_install_table (GTK_EXTEXT (current->text), current->tables->embedded); if (current == cur_file) gtk_widget_queue_draw (current->text); } } void attach_highlight_tables (GdsFile * file_ptr, gchar * path_to_file) { gchar home_dir[384]; GdsFileHighlightTable *table = NULL; gchar *extension = NULL; gchar *filename = NULL; gchar install_dir[] = LANG_DIR; gchar *mime_type; GList *temp = NULL; GdsFileHighlightTable *current; g_snprintf (home_dir, sizeof (home_dir), "%s/." PACKAGE "/languages", getenv ("HOME")); detach_highlight_tables (file_ptr); if (path_to_file) { for (temp = g_list_first (highlight_tables); temp; temp = temp->next) { current = (GdsFileHighlightTable *) temp->data; if (!strcmp (current->filename, path_to_file)) { table = current; break; } } if (!table) { xmlDocPtr doc; doc = parse_glimmer_definition (path_to_file); if (doc) { table = make_highlight_tables (doc, path_to_file); xmlFreeDoc (doc); } } } else { filename = get_file_from_filename (file_ptr->filename); extension = strrchr (filename, '.'); if (extension) extension++; else extension = filename; mime_type = (gchar *) gnome_vfs_mime_type_from_name (filename); table = find_highlight_tables (extension, mime_type, home_dir); if (!table) table = find_highlight_tables (extension, mime_type, install_dir); } if (table) { file_ptr->tables = table; table->refcount++; if (table->syntax) gtk_extext_install_table (GTK_EXTEXT (file_ptr->text), table->syntax); if (table->pattern) gtk_extext_install_table (GTK_EXTEXT (file_ptr->text), table->pattern); if (table->embedded) gtk_extext_install_table (GTK_EXTEXT (file_ptr->text), table->embedded); gtk_extext_set_highlight (GTK_EXTEXT (file_ptr->text), general_preferences.syntax); #ifdef WITH_PYTHON if (table->table_add_callback) table_emit_scripting_signal ("table-add", file_ptr->tables); if (table->file_focus_callback) file_emit_scripting_signal ("focus-in", file_ptr); #endif } else { gtk_extext_set_highlight (GTK_EXTEXT (file_ptr->text), FALSE); } g_free (filename); } gboolean detach_highlight_tables (GdsFile * file_ptr) { if (file_ptr->tables != NULL) { #ifdef WITH_PYTHON if (file_ptr->tables->file_unfocus_callback) file_emit_scripting_signal ("focus-out", file_ptr); if (file_ptr->tables->table_remove_callback) table_emit_scripting_signal ("table-remove", file_ptr->tables); if (file_ptr->compile_pid == -1 && file_ptr->tables->stop_compile_hook) file_emit_scripting_signal ("stop-compile", file_ptr); if (file_ptr->debug_pid == -1 && file_ptr->tables->stop_debug_hook) file_emit_scripting_signal ("stop-debug", file_ptr); if (file_ptr->exec_pid == -1 && file_ptr->tables->stop_execute_hook) file_emit_scripting_signal ("stop-execute", file_ptr); #endif file_ptr->tables->refcount--; delete_highlight_tables (file_ptr->tables); file_ptr->tables = NULL; GTK_EXTEXT (file_ptr->text)->syntax_table = NULL; GTK_EXTEXT (file_ptr->text)->pattern_table = NULL; GTK_EXTEXT (file_ptr->text)->embedded_table = NULL; gtk_extext_set_highlight (GTK_EXTEXT (file_ptr->text), FALSE); return (TRUE); } else return (FALSE); } gboolean delete_highlight_tables (GdsFileHighlightTable * table) { #ifdef WITH_PYTHON GList *list = NULL; #endif if (table->refcount > 0) return (FALSE); if (table->syntax) gtk_extext_table_free (table->syntax); if (table->pattern) gtk_extext_table_free (table->pattern); if (table->embedded) gtk_extext_table_free (table->embedded); g_free (table->filename); g_list_delete_all (table->extensions); g_list_delete_all (table->mime_types); g_free (table->props.compiler); g_free (table->props.debugger); g_free (table->props.execution); #ifdef WITH_PYTHON if (table->table_destroy_callback) table_emit_scripting_signal ("table-destroy", table); remove_signal_hooks (table); #endif highlight_tables = g_list_remove (highlight_tables, table); #ifdef WITH_PYTHON table->menu_entries = g_list_reverse (table->menu_entries); for (list = g_list_first (table->menu_entries); list; list = list->next) { if ((g_list_index (edit_entries, list->data) >= 0)) { edit_entries = g_list_remove (edit_entries, list->data); } if ((g_list_index (dynamic_build, list->data) >= 0)) { dynamic_build = g_list_remove (dynamic_build, list->data); } if (list->data) { gtk_widget_destroy (GTK_WIDGET (list->data)); } } g_list_free (table->menu_entries); for (list = g_list_first (table->toolbar_entries); list; list = list->next) { if (list->data) { gtk_widget_destroy (GTK_WIDGET (list->data)); } } g_list_free (table->toolbar_entries); #endif g_free (table); return (TRUE); } GdsFileHighlightTable * find_highlight_tables (gchar * extension, gchar * mime_type, gchar * cur_dir) { GList *temp = NULL; GList *ptr = NULL; GdsFileHighlightTable *current; DIR *dir_list; struct dirent *dir; gchar buffer[256]; gchar full_path[384]; GdsFileHighlightTable *new_table = NULL; xmlDocPtr doc; for (temp = g_list_first (highlight_tables); temp; temp = temp->next) { current = (GdsFileHighlightTable *) temp->data; for (ptr = g_list_first (current->extensions); ptr; ptr = ptr->next) { if (!strcmp ((gchar *) ptr->data, extension)) { return (current); } } for (ptr = g_list_first (current->mime_types); ptr; ptr = ptr->next) { if (!strcmp ((gchar *) ptr->data, mime_type)) { return (current); } } } dir_list = opendir (cur_dir); if (dir_list) { while ((dir = readdir (dir_list)) != NULL) { if (dir->d_ino > 0) { gboolean found = FALSE; for (temp = g_list_first (highlight_tables); temp; temp = temp->next) { current = (GdsFileHighlightTable *) temp->data; if (!strcmp (current->filename, buffer)) { found = TRUE; break; } } if (found) continue; g_snprintf (full_path, sizeof (full_path), "%s/%s", cur_dir, dir->d_name); doc = parse_glimmer_definition (full_path); if (doc) { if (check_mime_type (doc, extension, mime_type)) { new_table = make_highlight_tables (doc, full_path); xmlFreeDoc (doc); break; } else { xmlFreeDoc (doc); } } } } closedir (dir_list); } return (new_table); } xmlDocPtr parse_glimmer_definition (gchar * filename) { xmlDocPtr doc = NULL; FILE *infile; FILE *outfile; gchar buffer[2048]; gchar *tempfile; gint line_count = 0; if (strstr (filename, "languages/.")) return (NULL); tempfile = g_strconcat (getenv ("HOME"), "/." PACKAGE "/temp.xml", NULL); if (!(infile = fopen (filename, "r"))) return (NULL); if (!(outfile = fopen (tempfile, "w"))) { g_free (tempfile); fclose (infile); return (NULL); } while (fgets (buffer, sizeof (buffer), infile) != NULL) { if (strstr (buffer, "") != NULL) { do { fprintf (outfile, "%s", buffer); line_count++; if (strstr (buffer, "")) break; } while (fgets (buffer, sizeof (buffer), infile) != NULL); } } fclose (infile); fclose (outfile); if (line_count) { doc = xmlParseFile (tempfile); } g_free (tempfile); return (doc); } gboolean check_mime_type (xmlDocPtr doc, gchar * extension, gchar * mime_type) { xmlNodePtr root; xmlNodePtr node; char *namestring; gboolean found = FALSE; root = xmlDocGetRootElement (doc); node = root->xmlChildrenNode; if (!node) { return (found); } if (strcmp (node->name, "settings")) { return (found); } node = node->next; if (strcmp (node->name, "mime-types")) { return (found); } for (node = node->xmlChildrenNode; node != NULL; node = node->next) { if (!strcmp (node->name, "extension")) { namestring = xmlNodeListGetString (doc, node->xmlChildrenNode, 1); if (namestring) { if (!strcmp (namestring, extension)) { found = TRUE; } g_free (namestring); } } else if (!strcmp (node->name, "mime-type")) { namestring = xmlNodeListGetString (doc, node->xmlChildrenNode, 1); if (namestring) { if (!strcmp (namestring, mime_type)) { found = TRUE; } g_free (namestring); } } if (found) break; } return (found); } void g_strconvescape (gchar * source) { char cur_char; char last_char = '\0'; gint iterations = 0; gint max_chars; gchar *dest; max_chars = strlen (source); dest = source; for (iterations = 0; iterations < max_chars; iterations++) { cur_char = source[iterations]; *dest = cur_char; if (last_char == '\\' && cur_char == 'n') { dest--; *dest = '\n'; } else if (last_char == '\\' && cur_char == 't') { dest--; *dest = '\t'; } last_char = cur_char; dest++; } *dest = '\0'; } GdsFileHighlightTable * make_highlight_tables (xmlDocPtr doc, gchar * filename) { GdsFileHighlightTable *new_table; xmlNodePtr root; xmlNodePtr section; xmlNodePtr node; xmlNodePtr item; gchar *name = NULL; gchar *start = NULL; gchar *end = NULL; gchar *regex = NULL; gchar *style = NULL; gchar *cclass = NULL; gchar *text = NULL; gchar *default_class = "d"; new_table = (GdsFileHighlightTable *) g_malloc0 (sizeof (GdsFileHighlightTable)); parse_table = new_table; new_table->filename = g_strdup (filename); new_table->props.over_ride = FALSE; new_table->props.auto_indent = general_preferences.auto_indent; new_table->props.use_spaces = general_preferences.use_spaces; new_table->props.spaces = general_preferences.spaces; new_table->props.syntax = general_preferences.syntax; new_table->props.bracketmatch = general_preferences.bracketmatch; new_table->props.dir = NULL; new_table->props.compiler = NULL; new_table->props.debugger = NULL; new_table->props.execution = NULL; root = xmlDocGetRootElement (doc); for (section = root->xmlChildrenNode; section != NULL; section = section->next) { if (!strcmp (section->name, "settings")) { for (node = section->xmlChildrenNode; node != NULL; node = node->next) { if (!strcmp (node->name, "language")) { } else if (!strcmp (node->name, "compiler")) { new_table->props.compiler = xmlNodeListGetString (doc, node->xmlChildrenNode, 1); } else if (!strcmp (node->name, "debugger")) { new_table->props.debugger = xmlNodeListGetString (doc, node->xmlChildrenNode, 1); } else if (!strcmp (node->name, "execution")) { new_table->props.execution = xmlNodeListGetString (doc, node->xmlChildrenNode, 1); } else if (!strcmp (node->name, "auto-indent")) { text = xmlNodeListGetString (doc, node->xmlChildrenNode, 1); if (text) { new_table->props.auto_indent = atoi (text); g_free (text); } } else if (!strcmp (node->name, "use-spaces")) { text = xmlNodeListGetString (doc, node->xmlChildrenNode, 1); if (text) { new_table->props.use_spaces = atoi (text); g_free (text); } } else if (!strcmp (node->name, "tab-stop")) { text = xmlNodeListGetString (doc, node->xmlChildrenNode, 1); if (text) { new_table->props.spaces = atoi (text); g_free (text); } } else if (!strcmp (node->name, "over-ride")) { text = xmlNodeListGetString (doc, node->xmlChildrenNode, 1); if (text) { new_table->props.over_ride = atoi (text); g_free (text); } } } } else if (!strcmp (section->name, "mime-types")) { for (node = section->xmlChildrenNode; node != NULL; node = node->next) { if (!strcmp (node->name, "extension")) { text = xmlNodeListGetString (doc, node->xmlChildrenNode, 1); if (text) { new_table->extensions = g_list_append (new_table->extensions, (gpointer) text); } } else if (!strcmp (node->name, "mime-type")) { text = xmlNodeListGetString (doc, node->xmlChildrenNode, 1); if (text) { new_table->mime_types = g_list_append (new_table->mime_types, (gpointer) text); } } } } else if (!strcmp (section->name, "syntax-items")) { for (node = section->xmlChildrenNode; node != NULL; node = node->next) { HighlightInfo *info; gint found_count = 0; gboolean class_found = FALSE; for (item = node->xmlChildrenNode; item != NULL; item = item->next) { if (!strcmp (item->name, "name")) { name = xmlNodeListGetString (doc, item->xmlChildrenNode, 1); found_count++; } else if (!strcmp (item->name, "start-regex")) { start = xmlNodeListGetString (doc, item->xmlChildrenNode, 1); g_strconvescape (start); found_count++; } else if (!strcmp (item->name, "end-regex")) { end = xmlNodeListGetString (doc, item->xmlChildrenNode, 1); g_strconvescape (end); found_count++; } else if (!strcmp (item->name, "style")) { style = xmlNodeListGetString (doc, item->xmlChildrenNode, 1); found_count++; } else if (!strcmp (item->name, "class")) { cclass = xmlNodeListGetString (doc, item->xmlChildrenNode, 1); class_found = TRUE;; } } if (found_count == 4) { if (class_found) info = get_highlight_info (style, cclass); else info = get_highlight_info (style, default_class); syntax_list = gtk_extext_syntax_entry_new (syntax_list, name, start, end, info->color, NULL, info->font, info->flags, GINT_TO_POINTER (info-> type)); g_free (info); } if (name) { g_free (name); name = NULL; } if (start) { g_free (start); start = NULL; } if (end) { g_free (end); end = NULL; } if (style) { g_free (style); style = NULL; } if (cclass) { g_free (cclass); cclass = NULL; } } } else if (!strcmp (section->name, "pattern-items")) { for (node = section->xmlChildrenNode; node != NULL; node = node->next) { HighlightInfo *info; gint found_count = 0; gboolean class_found = FALSE; for (item = node->xmlChildrenNode; item != NULL; item = item->next) { if (!strcmp (item->name, "name")) { name = xmlNodeListGetString (doc, item->xmlChildrenNode, 1); found_count++; } else if (!strcmp (item->name, "regex")) { regex = xmlNodeListGetString (doc, item->xmlChildrenNode, 1); g_strconvescape (regex); found_count++; } else if (!strcmp (item->name, "style")) { style = xmlNodeListGetString (doc, item->xmlChildrenNode, 1); found_count++; } else if (!strcmp (item->name, "class")) { cclass = xmlNodeListGetString (doc, item->xmlChildrenNode, 1); class_found = TRUE;; } } if (found_count == 3) { if (class_found) info = get_highlight_info (style, cclass); else info = get_highlight_info (style, default_class); pattern_list = gtk_extext_pattern_entry_new (pattern_list, name, regex, info->color, NULL, info->font, info->flags, GINT_TO_POINTER (info-> type)); g_free (info); } if (name) { g_free (name); name = NULL; } if (regex) { g_free (regex); regex = NULL; } if (style) { g_free (style); style = NULL; } if (cclass) { g_free (cclass); cclass = NULL; } } } else if (!strcmp (section->name, "embedded-items")) { for (node = section->xmlChildrenNode; node != NULL; node = node->next) { HighlightInfo *info; gint found_count = 0; gboolean class_found = FALSE; for (item = node->xmlChildrenNode; item != NULL; item = item->next) { if (!strcmp (item->name, "name")) { name = xmlNodeListGetString (doc, item->xmlChildrenNode, 1); found_count++; } else if (!strcmp (item->name, "outside-regex")) { start = xmlNodeListGetString (doc, item->xmlChildrenNode, 1); g_strconvescape (start); found_count++; } else if (!strcmp (item->name, "inside-regex")) { regex = xmlNodeListGetString (doc, item->xmlChildrenNode, 1); g_strconvescape (regex); found_count++; } else if (!strcmp (item->name, "style")) { style = xmlNodeListGetString (doc, item->xmlChildrenNode, 1); found_count++; } else if (!strcmp (item->name, "class")) { cclass = xmlNodeListGetString (doc, item->xmlChildrenNode, 1); class_found = TRUE;; } } if (found_count == 4) { if (class_found) info = get_highlight_info (style, cclass); else info = get_highlight_info (style, default_class); embedded_list = gtk_extext_embedded_entry_new (embedded_list, name, start, regex, info->color, NULL, info->font, info->flags, GINT_TO_POINTER (info-> type)); g_free (info); } if (name) { g_free (name); name = NULL; } if (start) { g_free (start); start = NULL; } if (regex) { g_free (regex); regex = NULL; } if (style) { g_free (style); style = NULL; } if (cclass) { g_free (cclass); cclass = NULL; } } } } #ifdef WITH_PYTHON run_python_file (filename); #endif if (syntax_list) new_table->syntax = gtk_extext_syntax_table_new (syntax_list); if (pattern_list) new_table->pattern = gtk_extext_pattern_table_new (pattern_list); if (embedded_list) new_table->embedded = gtk_extext_embedded_table_new (embedded_list); syntax_list = NULL; pattern_list = NULL; embedded_list = NULL; parse_table = NULL; highlight_tables = g_list_append (highlight_tables, (gpointer) new_table); new_table->refcount = 0; return (new_table); } #ifdef WITH_PYTHON void run_python_file (gchar * filename) { FILE *ifile; FILE *ofile; gchar temp_file[384]; gchar buffer[1024]; g_snprintf (temp_file, sizeof (temp_file), "%s/." PACKAGE "/%s", getenv ("HOME"), "highlight.py"); if (!(ifile = fopen (filename, "r"))) return; if (!(ofile = fopen (temp_file, "w"))) { fclose (ifile); return; } while (fgets (buffer, sizeof (buffer), ifile) != NULL) { if (strstr (buffer, "")) { while (fgets (buffer, sizeof (buffer), ifile)) { if (strstr (buffer, "")) break; fprintf (ofile, "%s", buffer); } } } fclose (ifile); fclose (ofile); if (!(ifile = fopen (temp_file, "r"))) return; parsing_language = TRUE; PyRun_SimpleFile (ifile, temp_file); fclose (ifile); parsing_language = FALSE; } #endif void g_list_delete_all (GList * list) { GList *ptr = NULL; ptr = g_list_first (list); while (ptr) { g_free (ptr->data); ptr = ptr->next; } g_list_free (list); } /* Returns a table of highlight info, to be g_free()'d by caller */ HighlightInfo * get_highlight_info (gchar * color, gchar * cclass) { gint i; HighlightInfo *info; gboolean set = FALSE; info = g_new0 (HighlightInfo, 1); if (strchr (cclass, 'i') && strchr (cclass, 'b')) info->type = FONT_BOLD_ITALIC; else if (strchr (cclass, 'i')) info->type = FONT_ITALIC; else if (strchr (cclass, 'b')) info->type = FONT_BOLD; if (cclass && strcmp (cclass, "d")) set = TRUE; //This means it came from getprefs.c, elsewise it will always be "d" (from parser above) for (i = 0; i < EDITOR_COLORS; i++) { if (!strcmp (editor_color_names[i], color)) { info->color = &HighlightCache.colors[i]; info->font = HighlightCache.fonts[i]; if (!set) info->type = HighlightCache.types[i]; info->flags = HighlightCache.flags[i]; } } info->font = get_font (info->type); if (strchr (cclass, 'u')) info->flags |= GTK_EXTEXT_STYLE_UNDER; if (strchr (cclass, 's')) info->flags |= GTK_EXTEXT_STYLE_STRIKE; return (info); } GdkFont * get_font (gint type) { GdkFont *font = NULL; if (type == FONT_BOLD_ITALIC) { font = general_preferences.boldi; } else if (type == FONT_ITALIC) { font = general_preferences.italic; } else if (type == FONT_BOLD) { font = general_preferences.bold; } else { font = general_preferences.font; } return (font); } void highlight_tables_font_change (GdkFont * nfont, gint type) { GList *tables = NULL; GList *entry = NULL; GdsFileHighlightTable *table; GtkExTextSyntaxEntry *syntax; GtkExTextPatternEntry *pattern; GtkExTextEmbeddedEntry *embedded; for (tables = g_list_first (highlight_tables); tables; tables = tables->next) { table = (GdsFileHighlightTable *) tables->data; if (table->syntax) for (entry = g_list_first (table->syntax->entries); entry; entry = entry->next) { syntax = (GtkExTextSyntaxEntry *) entry->data; if (GPOINTER_TO_INT (syntax->data) == type) syntax->font = nfont; } if (table->pattern) for (entry = g_list_first (table->pattern->entries); entry; entry = entry->next) { pattern = (GtkExTextPatternEntry *) entry->data; if (GPOINTER_TO_INT (pattern->data) == type) pattern->font = nfont; } if (table->embedded) for (entry = g_list_first (table->embedded->entries); entry; entry = entry->next) { embedded = (GtkExTextEmbeddedEntry *) entry->data; if (GPOINTER_TO_INT (embedded->data) == type) embedded->font = nfont; } } }