diff --git a/eek/eek-symbol.c b/eek/eek-symbol.c
index fbf09eaf..47ce1160 100644
--- a/eek/eek-symbol.c
+++ b/eek/eek-symbol.c
@@ -444,3 +444,38 @@ eek_symbol_get_icon_name (EekSymbol *symbol)
         return NULL;
     return priv->icon_name;
 }
+
+static const struct {
+    EekSymbolCategory category;
+    gchar *name;
+} category_names[] = {
+    { EEK_SYMBOL_CATEGORY_LETTER, "letter" },
+    { EEK_SYMBOL_CATEGORY_FUNCTION, "function" },
+    { EEK_SYMBOL_CATEGORY_KEYNAME, "keyname" },
+    { EEK_SYMBOL_CATEGORY_USER0, "user0" },
+    { EEK_SYMBOL_CATEGORY_USER1, "user1" },
+    { EEK_SYMBOL_CATEGORY_USER2, "user2" },
+    { EEK_SYMBOL_CATEGORY_USER3, "user3" },
+    { EEK_SYMBOL_CATEGORY_USER4, "user4" },
+    { EEK_SYMBOL_CATEGORY_UNKNOWN, NULL }
+};
+
+G_CONST_RETURN gchar *
+eek_symbol_category_get_name (EekSymbolCategory category)
+{
+    gint i;
+    for (i = 0; i < G_N_ELEMENTS(category_names); i++)
+        if (category_names[i].category == category)
+            return category_names[i].name;
+    return NULL;
+}
+
+EekSymbolCategory
+eek_symbol_category_from_name (const gchar *name)
+{
+    gint i;
+    for (i = 0; i < G_N_ELEMENTS(category_names); i++)
+        if (g_strcmp0 (category_names[i].name, name) == 0)
+            return category_names[i].category;
+    return EEK_SYMBOL_CATEGORY_UNKNOWN;
+}
diff --git a/eek/eek-symbol.h b/eek/eek-symbol.h
index 5889463f..6cc1d2cf 100644
--- a/eek/eek-symbol.h
+++ b/eek/eek-symbol.h
@@ -111,6 +111,11 @@ void                  eek_symbol_set_icon_name (EekSymbol        *symbol,
                                                 const gchar      *icon_name);
 G_CONST_RETURN gchar *eek_symbol_get_icon_name (EekSymbol        *symbol);
 
+G_CONST_RETURN gchar *eek_symbol_category_get_name
+                                               (EekSymbolCategory category);
+EekSymbolCategory     eek_symbol_category_from_name
+                                               (const gchar      *name);
+
 G_END_DECLS
 
 #endif  /* EEK_SYMBOL_H */
diff --git a/eek/eek-xml-layout.c b/eek/eek-xml-layout.c
index 4a9b904a..580e0794 100644
--- a/eek/eek-xml-layout.c
+++ b/eek/eek-xml-layout.c
@@ -66,8 +66,10 @@ struct _ParseCallbackData {
     gdouble corner_radius;
     GSList *points;
     GSList *symbols;
+    gchar *name;
     gchar *label;
     gchar *icon;
+    EekSymbolCategory category;
     guint keyval;
     gint groups, levels;
     EekOutline outline;
@@ -166,6 +168,7 @@ start_element_callback (GMarkupParseContext *pcontext,
     gint column = -1, row = -1, groups = -1, levels = -1;
     guint keyval = EEK_INVALID_KEYSYM;
     gchar *name = NULL, *label = NULL, *icon = NULL, *id = NULL, *version = NULL;
+    EekSymbolCategory category;
 
     validate (element_name, data->element_stack, error);
     if (error && *error)
@@ -184,6 +187,8 @@ start_element_callback (GMarkupParseContext *pcontext,
             label = g_strdup (*values);
         else if (g_strcmp0 (*names, "icon") == 0)
             icon = g_strdup (*values);
+        else if (g_strcmp0 (*names, "category") == 0)
+            category = eek_symbol_category_from_name (*values);
         else if (g_strcmp0 (*names, "keyval") == 0)
             keyval = strtoul (*values, NULL, 10);
         else if (g_strcmp0 (*names, "version") == 0)
@@ -230,9 +235,11 @@ start_element_callback (GMarkupParseContext *pcontext,
     }
 
     if (g_strcmp0 (element_name, "symbol") == 0 ||
-        g_strcmp0 (element_name, "keysym") == 0) {
+        g_strcmp0 (element_name, "keysym") == 0 ||
+        g_strcmp0 (element_name, "text") == 0) {
         data->label = g_strdup (label);
         data->icon = g_strdup (icon);
+        data->category = category;
         if (g_strcmp0 (element_name, "keysym") == 0)
             data->keyval = keyval;
     }
diff --git a/eek/eek-xml.c b/eek/eek-xml.c
index 66321596..cac9ea0d 100644
--- a/eek/eek-xml.c
+++ b/eek/eek-xml.c
@@ -77,6 +77,21 @@ output_bounds (GString *output, EekBounds *bounds)
                             bounds->height);
 }
 
+static void
+output_symbol_attributes (GString   *output,
+                          EekSymbol *symbol)
+{
+    if (eek_symbol_get_name (symbol) != NULL)
+        g_string_markup_printf (output, " name=\"%s\"",
+                                eek_symbol_get_name (symbol));
+    if (eek_symbol_get_label (symbol) != NULL)
+        g_string_markup_printf (output, " label=\"%s\"",
+                                eek_symbol_get_label (symbol));
+    if (eek_symbol_get_category (symbol) != EEK_SYMBOL_CATEGORY_UNKNOWN)
+        g_string_markup_printf (output, " category=\"%s\"",
+                                eek_symbol_category_get_name (eek_symbol_get_category (symbol)));
+}
+
 static void
 output_key_callback (EekElement *element, gpointer user_data)
 {
@@ -146,26 +161,28 @@ output_key_callback (EekElement *element, gpointer user_data)
             if (EEK_IS_KEYSYM(symbol)) {
                 guint xkeysym = eek_keysym_get_xkeysym (EEK_KEYSYM(symbol));
 
+                g_string_markup_printf (data->output, "output, symbol);
                 if (xkeysym != EEK_INVALID_KEYSYM)
-                    g_string_markup_printf
-                        (data->output,
-                         "%s\n",
-                         xkeysym,
-                         eek_symbol_get_name (symbol));
-                else
-                    g_string_markup_printf (data->output,
-                                            "%s\n",
-                                            eek_symbol_get_name (symbol));
+                    g_string_markup_printf (data->output, " keyval=\"%u\"",
+                                            xkeysym);
+                g_string_markup_printf (data->output, ">%s\n",
+                                        eek_symbol_get_name (symbol));
             }
             else if (EEK_IS_TEXT(symbol)) {
+                g_string_markup_printf (data->output, "output, symbol);
                 g_string_markup_printf (data->output,
-                                        "%s\n",
+                                        ">%s\n",
                                         eek_text_get_text (EEK_TEXT(symbol)));
             }
-            else
+            else {
+                g_string_markup_printf (data->output, "output, symbol);
                 g_string_markup_printf (data->output,
-                                        "%s\n",
+                                        ">%s\n",
                                         eek_symbol_get_name (symbol));
+            }
         }
         g_string_append_indent (data->output, data->indent + 1);
         g_string_markup_printf (data->output, "\n");
diff --git a/examples/eekxml/eekxml.in b/examples/eekxml/eekxml.in
index 1081fa11..de160093 100644
--- a/examples/eekxml/eekxml.in
+++ b/examples/eekxml/eekxml.in
@@ -44,7 +44,8 @@ def remap(keyboard, mapping):
                     if mapped.has_key('label'):
                         replace.set_label(mapped['label'])
                     if mapped.has_key('category'):
-                        replace.set_category(mapped['category'])
+                        cat = Eek.symbol_category_from_name(mapped['category'])
+                        replace.set_category(cat)
                     matrix.set_symbol(0, level, replace)
     def __each_section(element, data):
         element.foreach_child(__each_key, data)
diff --git a/examples/eekxml/mim2remap.el b/examples/eekxml/mim2remap.el
index ec2c9469..39dc8411 100644
--- a/examples/eekxml/mim2remap.el
+++ b/examples/eekxml/mim2remap.el
@@ -149,9 +149,10 @@
 		      (car from)
 		    (or (mim2remap--char-to-keyname (aref from 0))
 			(error "No keyname for %c" (aref from 0))))
-		  (if (characterp to)
-		      (list (cons :text (char-to-string to)))
-		    (list (cons :text to))))))
+		  (list (cons :text (if (characterp to)
+					(char-to-string to)
+				      to))
+			(cons :category 'letter)))))
 	(cdr sexp))))))
 
 (defun batch-mim2remap ()