[lasem/mml-attrs] [Mathml] Migration to lsm_attribute_manager WIP.



commit 4b629e87b53f9a9d33c93b2425745706bb6a2bfb
Author: Emmanuel Pacaud <emmanuel gnome org>
Date:   Sun Jan 3 21:49:16 2010 +0100

    [Mathml] Migration to lsm_attribute_manager WIP.
    
    lsm_mathml_enum_list_attribute
    lsm_mathml_space_list_attribute

 src/lsmmathmlattributes.c   |  575 ++-----------------------------------------
 src/lsmmathmlattributes.h   |  121 +--------
 src/lsmmathmlelement.c      |   22 +--
 src/lsmmathmlelement.h      |    1 -
 src/lsmmathmlenums.h        |    4 +-
 src/lsmmathmltableelement.c |  172 +++++++------
 src/lsmmathmltraits.c       |  241 +++++++++++++++----
 src/lsmmathmltraits.h       |   20 +-
 8 files changed, 347 insertions(+), 809 deletions(-)
---
diff --git a/src/lsmmathmlattributes.c b/src/lsmmathmlattributes.c
index 72640b6..6ad70c2 100644
--- a/src/lsmmathmlattributes.c
+++ b/src/lsmmathmlattributes.c
@@ -145,573 +145,38 @@ lsm_mathml_space_attribute_normalize (LsmMathmlSpaceAttribute *attribute,
 	return attribute->value;
 }
 
-#include <lsmmathmlstyle.h>
-#include <lsmdebug.h>
-#include <string.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <glib/gmem.h>
-#include <glib/ghash.h>
-#include <glib-object.h>
-#include <math.h>
-
-/**************************/
-
-typedef struct {
-	ptrdiff_t bag_offset;
-	const LsmMathmlAttributeBagClass *bag_class;
-} LsmMathmlAttributeBagInfos;
-
-typedef struct {
-	ptrdiff_t attribute_offset;
-	const LsmMathmlAttributeClass *attribute_class;
-	LsmMathmlAttributeBagInfos *bag_infos;
-} LsmMathmlAttributeInfos;
-
-LsmMathmlAttributeMap *
-lsm_mathml_attribute_map_new (void)
-{
-	LsmMathmlAttributeMap *map;
-
-	map = g_new0 (LsmMathmlAttributeMap, 1);
-	g_return_val_if_fail (map != NULL,  NULL);
-
-	map->attribute_hash = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL);
-	map->bag_hash = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, NULL);
-
-	return map;
-}
-
-LsmMathmlAttributeMap *
-lsm_mathml_attribute_map_duplicate (const LsmMathmlAttributeMap *from)
-{
-	LsmMathmlAttributeMap *map;
-	GHashTableIter iter;
-	void *key;
-	void *value;
-
-	map = lsm_mathml_attribute_map_new ();
-	g_return_val_if_fail (map != NULL, NULL);
-
-	g_hash_table_iter_init (&iter, from->attribute_hash);
-	while (g_hash_table_iter_next (&iter, &key, &value))
-		g_hash_table_insert (map->attribute_hash, key, value);
-
-	g_hash_table_iter_init (&iter, from->bag_hash);
-	while (g_hash_table_iter_next (&iter, &key, &value))
-		g_hash_table_insert (map->bag_hash, key, value);
-
-	return map;
-}
-
 void
-lsm_mathml_attribute_map_free (LsmMathmlAttributeMap *map)
+lsm_mathml_space_list_attribute_normalize (LsmMathmlSpaceListAttribute *attribute,
+					   const LsmMathmlSpaceList *default_value,
+					   const LsmMathmlStyle *style)
 {
-	g_return_if_fail (map != NULL);
-
-	g_hash_table_unref (map->attribute_hash);
-	g_hash_table_unref (map->bag_hash);
-	g_free (map);
-}
-
-void
-lsm_mathml_attribute_map_add_bag_attribute  (LsmMathmlAttributeMap *map,
-					     const char *name,
-					     ptrdiff_t attribute_offset,
-					     const LsmMathmlAttributeClass *attribute_class,
-					     ptrdiff_t bag_offset,
-					     const LsmMathmlAttributeBagClass *bag_class)
-{
-	LsmMathmlAttributeInfos *attribute_infos;
-	LsmMathmlAttributeBagInfos *bag_infos;
-
-	g_return_if_fail (map != NULL);
-	g_return_if_fail (name != NULL);
-	g_return_if_fail (attribute_offset >= 0);
-
-	if (g_hash_table_lookup (map->attribute_hash, name) != NULL) {
-		g_warning ("[LsmMathmlAttributeMap::add_attribute] %s already defined", name);
-		return;
-	}
-
-	attribute_infos = g_new (LsmMathmlAttributeInfos, 1);
-	attribute_infos->attribute_offset = attribute_offset;
-	attribute_infos->attribute_class = attribute_class;
-
-	g_hash_table_insert (map->attribute_hash, (char *) name, attribute_infos);
-
-	if (bag_class != NULL) {
-		bag_infos = g_hash_table_lookup (map->bag_hash, bag_class);
-		if (bag_infos == NULL) {
-			bag_infos = g_new (LsmMathmlAttributeBagInfos, 1);
-			bag_infos->bag_offset = bag_offset;
-			bag_infos->bag_class = bag_class;
-
-			g_hash_table_insert (map->bag_hash, (void *) bag_class, bag_infos);
-		}
-		attribute_infos->bag_infos = bag_infos;
-	} else
-		attribute_infos->bag_infos = NULL;
-
-}
-
-void
-lsm_mathml_attribute_map_add_attribute_full (LsmMathmlAttributeMap *map,
-					     const char *name,
-					     ptrdiff_t offset,
-					     const LsmMathmlAttributeClass *attribute_class)
-{
-	lsm_mathml_attribute_map_add_bag_attribute (map, name, offset, attribute_class, 0, NULL);
-}
-
-void
-lsm_mathml_attribute_map_add_attribute_full_width_default (LsmMathmlAttributeMap *map,
-							   const char *name,
-							   ptrdiff_t offset,
-							   const LsmMathmlAttributeClass *attribute_class)
-{
-	lsm_mathml_attribute_map_add_bag_attribute (map, name, offset, attribute_class, 0, NULL);
-}
-
-void
-lsm_mathml_attribute_map_add_attribute (LsmMathmlAttributeMap *map,
-					const char *name,
-					ptrdiff_t offset)
-{
-	lsm_mathml_attribute_map_add_bag_attribute (map, name, offset, NULL, 0, NULL);
-}
-
-static LsmMathmlAttribute *
-_get_attribute (LsmMathmlAttributeMap *map,
-		void *instance,
-		const char *name)
-{
-	LsmMathmlAttributeInfos *attribute_infos;
-	LsmMathmlAttribute *attribute;
-
-	attribute_infos = g_hash_table_lookup (map->attribute_hash, name);
-	if (attribute_infos == NULL) {
-		lsm_debug ("[LsmMathmlAttribute] Attribute not found (%s)", name);
-		return NULL;
-	}
-
-	if (attribute_infos->bag_infos == NULL)
-		attribute = (void *)(instance + attribute_infos->attribute_offset);
-	else {
-		LsmMathmlAttributeBag **bag_ptr;
-
-		bag_ptr = (void *)(instance + attribute_infos->bag_infos->bag_offset);
-		g_return_val_if_fail (bag_ptr != NULL, FALSE);
-
-		if (*bag_ptr == NULL)
-			*bag_ptr = attribute_infos->bag_infos->bag_class->init ();
-		g_return_val_if_fail (*bag_ptr != NULL, FALSE);
-
-		attribute = (((void *) *bag_ptr) + attribute_infos->attribute_offset);
-	}
-
-	g_return_val_if_fail (attribute != NULL, NULL);
-
-	return attribute;
-}
-
-gboolean
-lsm_mathml_attribute_map_set_attribute (LsmMathmlAttributeMap *map,
-					void *instance,
-					const char *name,
-					const char *value)
-{
-	LsmMathmlAttribute *attribute;
-
-	g_return_val_if_fail (map != NULL, FALSE);
-
-	attribute = _get_attribute (map, instance, name);
-	if (attribute == NULL)
-		return FALSE;
-
-	g_free (attribute->value);
-	attribute->value = value != NULL ? g_strdup (value) : NULL;
-
-	return TRUE;
-}
-
-gboolean
-lsm_mathml_attribute_map_set_css_attribute (LsmMathmlAttributeMap *map,
-					    void *instance,
-					    const char *name,
-					    const char *value,
-					    LsmMathmlCssType type)
-{
-	LsmMathmlAttribute *attribute;
-
-	g_return_val_if_fail (map != NULL, FALSE);
-
-	attribute = _get_attribute (map, instance, name);
-	if (attribute == NULL)
-		return FALSE;
-
-	g_free (attribute->css_value);
-	attribute->css_value = value != NULL ? g_strdup (value) : NULL;
-	attribute->css_type = type;
-
-	return TRUE;
-}
-
-char const *
-lsm_mathml_attribute_map_get_attribute (LsmMathmlAttributeMap *map,
-					void *instance,
-					const char *name)
-{
-	LsmMathmlAttributeInfos *attribute_infos;
-	LsmMathmlAttribute *attribute;
-
-	g_return_val_if_fail (map != NULL, NULL);
-
-	attribute_infos = g_hash_table_lookup (map->attribute_hash, name);
-	if (attribute_infos == NULL)
-		return NULL;
-
-	if (attribute_infos->bag_infos == NULL)
-		attribute = (void *)(instance + attribute_infos->attribute_offset);
-	else {
-		LsmMathmlAttributeBag **bag_ptr;
-
-		bag_ptr = (void *)(instance + attribute_infos->bag_infos->bag_offset);
-		g_return_val_if_fail (bag_ptr != NULL, NULL);
-		if (*bag_ptr == NULL)
-			return NULL;
-		attribute = (void *)(*bag_ptr + attribute_infos->attribute_offset);
-	}
-	g_return_val_if_fail (attribute != NULL, NULL);
-
-	return attribute->value;
-}
-
-gboolean
-lsm_mathml_attribute_map_is_attribute_defined (LsmMathmlAttributeMap *map,
-					       void *instance,
-					       const char *name)
-{
-	LsmMathmlAttributeInfos *attribute_infos;
-	LsmMathmlAttribute *attribute;
-
-	g_return_val_if_fail (map != NULL, FALSE);
-
-	attribute_infos = g_hash_table_lookup (map->attribute_hash, name);
-	if (attribute_infos == NULL)
-		return FALSE;
-
-	attribute = (void *)(instance + attribute_infos->attribute_offset);
-	g_return_val_if_fail (attribute != NULL, FALSE);
-
-	return attribute->value != NULL;
-}
-
-gboolean
-lsm_mathml_attribute_is_defined (const LsmMathmlAttribute *attribute)
-{
-	return (attribute != NULL && attribute->value != NULL);
-}
-
-static void
-lsm_mathml_attribute_finalize_cb (gpointer key,
-				  gpointer value,
-				  gpointer instance)
-{
-	LsmMathmlAttributeInfos *attribute_infos = value;
-	LsmMathmlAttribute *attribute;
-
-	attribute = (void *)(instance + attribute_infos->attribute_offset);
-	if (attribute != NULL) {
-		g_free (attribute->value);
-		g_free (attribute->css_value);
-
-		attribute->value = NULL;
-		attribute->css_value = NULL;
-
-		if (attribute_infos->attribute_class != NULL &&
-		    attribute_infos->attribute_class->finalize != NULL)
-			attribute_infos->attribute_class->finalize (attribute);
-	}
-}
-
-static void
-lsm_mathml_attribute_bag_finalize_cb (gpointer key,
-				      gpointer value,
-				      gpointer instance)
-{
-	LsmMathmlAttributeBagInfos *bag_infos = value;
-	LsmMathmlAttributeBag **bag_ptr;
-
-	bag_ptr = (void *)(instance + bag_infos->bag_offset);
-	if (*bag_ptr != NULL) {
-		if (bag_infos->bag_class->finalize != NULL)
-			bag_infos->bag_class->finalize (*bag_ptr);
-
-		*bag_ptr = NULL;
-	}
-}
-
-void
-lsm_mathml_attribute_map_free_attributes (LsmMathmlAttributeMap *map, void *instance)
-{
-	g_return_if_fail (map != NULL);
-
-	g_hash_table_foreach (map->attribute_hash, lsm_mathml_attribute_finalize_cb, instance);
-	g_hash_table_foreach (map->bag_hash, lsm_mathml_attribute_bag_finalize_cb, instance);
-}
-
-char const *
-lsm_mathml_attribute_get_value (const LsmMathmlAttribute *attribute)
-{
-	g_return_val_if_fail (attribute != NULL, NULL);
-
-	if (attribute->css_value != NULL &&
-	    attribute->css_type >= LSM_MATHML_CSS_TYPE_AUTHOR)
-		return attribute->css_value;
-
-	return attribute->value;
-}
-
-void
-lsm_mathml_enum_attribute_parse (LsmMathmlEnumAttribute *attribute,
-			      unsigned int *style_value,
-			      LsmDomNamedConvert convert)
-{
-	const char *string;
-
-	g_return_if_fail (attribute != NULL);
-	g_return_if_fail (style_value != NULL);
-
-	string = lsm_mathml_attribute_get_value ((LsmMathmlAttribute *) attribute);
-	if (string == NULL) {
-		attribute->value = *style_value;
-		return;
-	}
-
-	attribute->value = convert (string);
-	*style_value = attribute->value;
-}
-
-void
-lsm_mathml_enum_list_attribute_parse (LsmMathmlEnumListAttribute *attribute,
-				   LsmMathmlEnumList *style_value,
-				   LsmDomNamedConvert convert)
-{
-	const char *string;
-	char **items;
+	LsmMathmlSpaceAttribute space_attribute;
 	unsigned int i;
 
 	g_return_if_fail (attribute != NULL);
-	g_return_if_fail (style_value != NULL);
-
-	g_free (attribute->values);
-	attribute->n_values = 0;
-
-	string = lsm_mathml_attribute_get_value ((LsmMathmlAttribute *) attribute);
-	if (string == NULL) {
-		if (style_value->n_values > 0) {
-			attribute->values = g_new (unsigned int, style_value->n_values);
-			memcpy (attribute->values, style_value->values,
-				sizeof (unsigned int) * style_value->n_values);
-		} else
-			attribute->values = NULL;
-		attribute->n_values = style_value->n_values;
-
-		return;
-	}
-
-	items = g_strsplit_set (string, " ", -1);
-	attribute->n_values = g_strv_length (items);
-
-	attribute->values = g_new (unsigned int, attribute->n_values);
-	for (i = 0; i < attribute->n_values; i++)
-		attribute->values[i] = convert (items[i]);
-
-	g_strfreev (items);
-}
-
-void
-lsm_mathml_enum_list_attribute_finalize (void *abstract)
-{
-	LsmMathmlEnumListAttribute *attribute = abstract;
-
-	g_return_if_fail (attribute != NULL);
-
-	g_free (attribute->values);
-	attribute->n_values = 0;
-	attribute->values = NULL;
-}
-
-static const LsmMathmlAttributeClass enum_list_attribute_class = {
-	.finalize = lsm_mathml_enum_list_attribute_finalize
-};
-
-void
-lsm_mathml_attribute_map_add_enum_list (LsmMathmlAttributeMap *map,
-					char const *name,
-					ptrdiff_t offset)
-{
-	lsm_mathml_attribute_map_add_attribute_full (map, name, offset, &enum_list_attribute_class);
-}
-
-static void
-lsm_mathml_space_list_attribute_finalize (void *abstract)
-{
-	LsmMathmlSpaceListAttribute *attribute = abstract;
-
-	g_return_if_fail (attribute != NULL);
+	g_return_if_fail (default_value != NULL);
+	g_return_if_fail (style != NULL);
 
-	lsm_mathml_space_list_free (attribute->space_list);
 	g_free (attribute->values);
-	attribute->space_list = NULL;
 	attribute->values = NULL;
-}
-
-void
-lsm_mathml_space_list_attribute_parse (LsmMathmlSpaceListAttribute *attribute,
-				       LsmMathmlSpaceList *style_value,
-				       const LsmMathmlStyle *style)
-{
-	unsigned int i;
-	const char *string;
-
-	g_return_if_fail (attribute != NULL);
-	g_return_if_fail (style_value != NULL);
-
-	lsm_mathml_space_list_attribute_finalize (attribute);
-
-	string = lsm_mathml_attribute_get_value ((LsmMathmlAttribute *) attribute);
-	if (string == NULL) {
-		attribute->space_list = lsm_mathml_space_list_duplicate (style_value);
-	} else {
-		unsigned int n_items;
-		char *unit_str;
-		char **items;
-
-		items = g_strsplit_set (string, " ", -1);
-		n_items = g_strv_length (items);
-
-		attribute->space_list = lsm_mathml_space_list_new (n_items);
-		for (i = 0; i < n_items; i++) {
-			LsmMathmlSpace *space;
-
-			space = &attribute->space_list->spaces[i];
-
-			space->name = lsm_mathml_space_name_from_string (items[i]);
-			if (space->name == LSM_MATHML_SPACE_NAME_ERROR) {
-				LsmMathmlUnit unit;
-				double value;
-
-				value = g_strtod (items[i], &unit_str);
-				unit = lsm_mathml_unit_from_string (unit_str);
 
-				if (style_value->n_spaces > 0) {
-					unsigned int index;
-
-					index = MIN (i, style_value->n_spaces - 1);
-
-					if (unit == LSM_MATHML_UNIT_NONE) {
-						unit = style_value->spaces[index].length.unit;
-						value *= style_value->spaces[index].length.value;
-					} else if (unit == LSM_MATHML_UNIT_PERCENT) {
-						unit = style_value->spaces[index].length.unit;
-						value *= style_value->spaces[index].length.value / 100.0;
-					}
-				} else {
-					unit = LSM_MATHML_UNIT_PX;
-					value = 0.0;
-				}
-
-				space->length.unit = unit;
-				space->length.value = value;
-			} else {
-				space->length.value = 0.0;
-				space->length.unit = LSM_MATHML_UNIT_PX;
-			}
+	if (attribute->base.value == NULL)
+		lsm_mathml_space_list_init (&attribute->space_list, default_value);
 
-			/* FIXME copy the new values to style */
-			if (i < style_value->n_spaces)
-				style_value->spaces[i] = *space;
-		}
-		g_strfreev (items);
+	if (attribute->space_list.n_spaces == 0) {
+		attribute->values = g_new (double, 1);
+		attribute->values[0] = 0.0;
+		return;
 	}
 
-	attribute->values = g_new (double, attribute->space_list->n_spaces);
-
-	for (i = 0; i < attribute->space_list->n_spaces; i++) {
-		switch (attribute->space_list->spaces[i].name) {
-			case LSM_MATHML_SPACE_NAME_VERY_VERY_THIN:
-				attribute->values[i] = style->very_very_thin_math_space;
-				break;
-			case LSM_MATHML_SPACE_NAME_VERY_THIN:
-				attribute->values[i] = style->very_thin_math_space;
-				break;
-			case LSM_MATHML_SPACE_NAME_THIN:
-				attribute->values[i] = style->thin_math_space;
-				break;
-			case LSM_MATHML_SPACE_NAME_MEDIUM:
-				attribute->values[i] = style->medium_math_space;
-				break;
-			case LSM_MATHML_SPACE_NAME_THICK:
-				attribute->values[i] = style->thick_math_space;
-				break;
-			case LSM_MATHML_SPACE_NAME_VERY_THICK:
-				attribute->values[i] = style->very_thick_math_space;
-				break;
-			case LSM_MATHML_SPACE_NAME_VERY_VERY_THICK:
-				attribute->values[i] = style->very_very_thick_math_space;
-				break;
-			case LSM_MATHML_SPACE_NAME_ERROR:
-			default:
-				if (style_value->n_spaces > 0) {
-					unsigned int index;
-
-					index = MIN (i, style_value->n_spaces - 1);
+	space_attribute.base.value = "";
 
-					attribute->values[i] = lsm_mathml_length_normalize
-						(&attribute->space_list->spaces[i].length,
-						 &style_value->spaces[index].length,
-						 style->math_size);
-				} else
-					attribute->values[i] = lsm_mathml_length_normalize
-						(&attribute->space_list->spaces[i].length,
-						 NULL,
-						 style->math_size);
-		}
+	attribute->values = g_new (double, attribute->space_list.n_spaces);
+	for (i = 0; i < attribute->space_list.n_spaces; i++) {
+		space_attribute.space = attribute->space_list.spaces[i];
+		lsm_mathml_space_attribute_normalize (&space_attribute,
+						      &default_value->spaces[MIN(i, default_value->n_spaces - 1)],
+						      style);
+		attribute->values[i] = space_attribute.value;
 	}
 }
-
-void
-lsm_mathml_row_align_list_attribute_parse (LsmMathmlEnumListAttribute *attribute,
-					   LsmMathmlEnumList *style_value)
-{
-	lsm_mathml_enum_list_attribute_parse (attribute, style_value, lsm_mathml_row_align_from_string);
-}
-
-void
-lsm_mathml_column_align_list_attribute_parse (LsmMathmlEnumListAttribute *attribute,
-					      LsmMathmlEnumList *style_value)
-{
-	lsm_mathml_enum_list_attribute_parse (attribute, style_value, lsm_mathml_column_align_from_string);
-}
-
-void
-lsm_mathml_line_list_attribute_parse (LsmMathmlEnumListAttribute *attribute,
-				      LsmMathmlEnumList *style_value)
-{
-	lsm_mathml_enum_list_attribute_parse (attribute, style_value, lsm_mathml_line_from_string);
-}
-
-static const LsmMathmlAttributeClass space_list_attribute_class = {
-	.finalize = lsm_mathml_space_list_attribute_finalize
-};
-
-void
-lsm_mathml_attribute_map_add_space_list (LsmMathmlAttributeMap *map,
-					 char const *name,
-					 ptrdiff_t offset)
-{
-	lsm_mathml_attribute_map_add_attribute_full (map, name, offset, &space_list_attribute_class);
-}
-
diff --git a/src/lsmmathmlattributes.h b/src/lsmmathmlattributes.h
index cd2a491..159d511 100644
--- a/src/lsmmathmlattributes.h
+++ b/src/lsmmathmlattributes.h
@@ -67,8 +67,6 @@ typedef struct {
 
 gboolean		lsm_mathml_boolean_attribute_inherit 	(LsmMathmlBooleanAttribute *attribute,
 								 gboolean value);
-unsigned int		lsm_mathml_enum_attribute_inherit	(LsmMathmlEnumAttribute *attribute,
-								 unsigned int value);
 double 			lsm_mathml_double_attribute_inherit 	(LsmMathmlDoubleAttribute *attribute,
 								 double value);
 LsmMathmlColor		lsm_mathml_color_attribute_inherit 	(LsmMathmlColorAttribute *attribute,
@@ -79,6 +77,14 @@ const char *		lsm_mathml_string_attribute_inherit	(LsmMathmlStringAttribute *att
 int			lsm_mathml_script_level_attribute_apply	(LsmMathmlScriptLevelAttribute *attribute,
 								 int script_level);
 
+unsigned int		lsm_mathml_enum_attribute_inherit	(LsmMathmlEnumAttribute *attribute,
+								 unsigned int value);
+
+typedef struct {
+	LsmAttribute base;
+	LsmMathmlEnumList enum_list;
+} LsmMathmlEnumListAttribute;
+
 typedef struct {
 	LsmAttribute base;
 	LsmMathmlLength length;
@@ -99,117 +105,16 @@ double 		lsm_mathml_space_attribute_normalize 	(LsmMathmlSpaceAttribute *attribu
 							 const LsmMathmlSpace *default_value,
 							 const LsmMathmlStyle *style);
 
-/*******************************/
-
-typedef struct {
-	char *value;
-	char *css_value;
-	LsmMathmlCssType css_type;
-} LsmMathmlAttribute;
-
-typedef struct {
-	GHashTable *attribute_hash;
-	GHashTable *bag_hash;
-} LsmMathmlAttributeMap;
-
-typedef struct {
-} LsmMathmlAttributeBag;
-
 typedef struct {
-	void * 			(*init) 	(void);
-	void 			(*finalize) 	(void *bag);
-} LsmMathmlAttributeBagClass;
-
-typedef struct {
-	void (*finalize) (void *attribute);
-} LsmMathmlAttributeClass;
-
-typedef void (*LsmMathmlAttributeFinalizeFunc) (void *);
-
-LsmMathmlAttributeMap *	lsm_mathml_attribute_map_new 		(void);
-LsmMathmlAttributeMap *	lsm_mathml_attribute_map_duplicate		(const LsmMathmlAttributeMap *from);
-void			lsm_mathml_attribute_map_free		(LsmMathmlAttributeMap *map);
-
-void 		lsm_mathml_attribute_map_add_bag_attribute  	(LsmMathmlAttributeMap *map,
-								 const char *name,
-								 ptrdiff_t attribute_offset,
-								 const LsmMathmlAttributeClass *attribute_class,
-								 ptrdiff_t bag_offset,
-								 const LsmMathmlAttributeBagClass *bag_class);
-void		lsm_mathml_attribute_map_add_attribute_full	(LsmMathmlAttributeMap *map,
-								 char const *name,
-								 ptrdiff_t offset,
-								 const LsmMathmlAttributeClass *attribute_class);
-void		lsm_mathml_attribute_map_add_attribute 		(LsmMathmlAttributeMap *map,
-								 char const *name,
-								 ptrdiff_t offset);
-
-void		lsm_mathml_attribute_map_free_attributes 	(LsmMathmlAttributeMap *map,
-								 void *instance);
-
-gboolean	lsm_mathml_attribute_map_set_attribute		(LsmMathmlAttributeMap *map,
-								 void *instance,
-								 char const *name,
-								 char const *value);
-char const *	lsm_mathml_attribute_map_get_attribute		(LsmMathmlAttributeMap *map,
-								 void *instance,
-								 char const *name);
-gboolean	lsm_mathml_attribute_map_set_css_attribute	(LsmMathmlAttributeMap *map,
-								 void *instance,
-								 char const *name,
-								 char const *value,
-								 LsmMathmlCssType css_type);
-gboolean	lsm_mathml_attribute_map_is_attribute_defined	(LsmMathmlAttributeMap *map,
-								 void *instance,
-								 char const *name);
-
-gboolean 	lsm_mathml_attribute_is_defined 		(const LsmMathmlAttribute *attribute);
-char const * 	lsm_mathml_attribute_get_value 			(const LsmMathmlAttribute *attribute);
-
-typedef unsigned int (*LsmDomNamedConvert) (const char *string);
-
-typedef struct {
-	unsigned int n_values;
-	unsigned int *values;
-} LsmMathmlEnumList;
-
-typedef struct {
-	LsmMathmlAttribute attr;
-	unsigned int n_values;
-	unsigned int *values;
-} LsmMathmlEnumListAttribute;
-
-typedef struct {
-	LsmMathmlAttribute attr;
-	LsmMathmlSpaceList *space_list;
+	LsmAttribute base;
+	LsmMathmlSpaceList space_list;
 	double *values;
 } LsmMathmlSpaceListAttribute;
 
-void 		lsm_mathml_enum_list_attribute_parse 	(LsmMathmlEnumListAttribute *attribute,
-							 LsmMathmlEnumList *style_value,
-							 LsmDomNamedConvert convert);
-
-void 		lsm_mathml_enum_list_attribute_finalize	(void *abstract);
-
-
-void 		lsm_mathml_attribute_map_add_enum_list 	(LsmMathmlAttributeMap *map,
-							 char const *name,
-							 ptrdiff_t offset);
-
-void 		lsm_mathml_space_list_attribute_parse 	(LsmMathmlSpaceListAttribute *attribute,
-							 LsmMathmlSpaceList *style_value,
-							 const LsmMathmlStyle *style);
-
-void 	lsm_mathml_row_align_list_attribute_parse 	(LsmMathmlEnumListAttribute *attribute,
-							 LsmMathmlEnumList *style_value);
-void 	lsm_mathml_column_align_list_attribute_parse 	(LsmMathmlEnumListAttribute *attribute,
-							 LsmMathmlEnumList *style_value);
-void 	lsm_mathml_line_list_attribute_parse 		(LsmMathmlEnumListAttribute *attribute,
-							 LsmMathmlEnumList *style_value);
+void 		lsm_mathml_space_list_attribute_normalize 	(LsmMathmlSpaceListAttribute *attribute,
+								 const LsmMathmlSpaceList *default_value,
+								 const LsmMathmlStyle *style);
 
-void 	lsm_mathml_attribute_map_add_space_list 	(LsmMathmlAttributeMap *map,
-							 char const *name,
-							 ptrdiff_t offset);
 G_END_DECLS
 
 #endif
diff --git a/src/lsmmathmlelement.c b/src/lsmmathmlelement.c
index 30b7234..2348c65 100644
--- a/src/lsmmathmlelement.c
+++ b/src/lsmmathmlelement.c
@@ -68,24 +68,17 @@ lsm_mathml_element_set_attribute (LsmDomElement *self, const char* name, const c
 {
 	LsmMathmlElementClass *m_element_class = LSM_MATHML_ELEMENT_GET_CLASS(self);
 
-	if (!lsm_attribute_manager_set_attribute (m_element_class->attribute_manager,
-						  self, name, value))
-		lsm_mathml_attribute_map_set_attribute (m_element_class->attributes, self,
-							name, value);
+	lsm_attribute_manager_set_attribute (m_element_class->attribute_manager,
+					     self, name, value);
 }
 
 const char *
 lsm_mathml_element_get_attribute (LsmDomElement *self, const char *name)
 {
 	LsmMathmlElementClass *m_element_class = LSM_MATHML_ELEMENT_GET_CLASS(self);
-	const char *value;
 
-	value = lsm_attribute_manager_get_attribute (m_element_class->attribute_manager,
-						     self, name);
-	if (value != NULL)
-		return value;
-
-	return lsm_mathml_attribute_map_get_attribute (m_element_class->attributes, self, name);
+	return lsm_attribute_manager_get_attribute (m_element_class->attribute_manager,
+						    self, name);
 }
 
 /* LsmMathmlElement implementation */
@@ -421,10 +414,10 @@ lsm_mathml_element_finalize (GObject *object)
 	LsmMathmlElementClass *m_element_class = LSM_MATHML_ELEMENT_GET_CLASS (object);
 	LsmMathmlElement *m_element = LSM_MATHML_ELEMENT (object);
 
-	lsm_mathml_attribute_map_free_attributes (m_element_class->attributes, object);
-
 	g_free (m_element->style.math_family);
 
+	lsm_attribute_manager_clean_attributes (m_element_class->attribute_manager, m_element);
+
 	parent_class->finalize (object);
 }
 
@@ -473,9 +466,6 @@ lsm_mathml_element_class_init (LsmMathmlElementClass *m_element_class)
 	m_element_class->render = _render;
 	m_element_class->get_embellished_core = _get_embellished_core;
 	m_element_class->is_inferred_row = _is_inferred_row;
-
-	m_element_class->attributes = lsm_mathml_attribute_map_new ();
-
 	m_element_class->attribute_manager = lsm_attribute_manager_new (G_N_ELEMENTS (lsm_svg_attribute_infos),
 									lsm_svg_attribute_infos);
 }
diff --git a/src/lsmmathmlelement.h b/src/lsmmathmlelement.h
index 747de8d..017b214 100644
--- a/src/lsmmathmlelement.h
+++ b/src/lsmmathmlelement.h
@@ -73,7 +73,6 @@ struct _LsmMathmlElementClass {
 	LsmDomElementClass  parent_class;
 
 	LsmAttributeManager *attribute_manager;
-	LsmMathmlAttributeMap *attributes;
 
 	void				(*update)		(LsmMathmlElement *element, LsmMathmlStyle *style);
 	gboolean			(*update_children)	(LsmMathmlElement *element, LsmMathmlStyle *style);
diff --git a/src/lsmmathmlenums.h b/src/lsmmathmlenums.h
index 84a6135..30e0d7c 100644
--- a/src/lsmmathmlenums.h
+++ b/src/lsmmathmlenums.h
@@ -39,7 +39,7 @@ typedef enum {
 	LSM_MATHML_MODE_INLINE
 } LsmMathmlMode;
 
-const char *		lsm_mathml_mode_to_string			(LsmMathmlMode mode);
+const char *		lsm_mathml_mode_to_string		(LsmMathmlMode mode);
 LsmMathmlMode		lsm_mathml_mode_from_string		(const char *string);
 
 typedef enum {
@@ -48,7 +48,7 @@ typedef enum {
 } LsmMathmlDisplay;
 
 const char *		lsm_mathml_display_to_string		(LsmMathmlDisplay display);
-LsmMathmlDisplay		lsm_mathml_display_from_string		(const char *string);
+LsmMathmlDisplay	lsm_mathml_display_from_string		(const char *string);
 
 typedef enum {
 	LSM_MATHML_SPACE_NAME_ERROR,
diff --git a/src/lsmmathmltableelement.c b/src/lsmmathmltableelement.c
index edc7cfe..dd56958 100644
--- a/src/lsmmathmltableelement.c
+++ b/src/lsmmathmltableelement.c
@@ -27,6 +27,28 @@
 
 #define LSM_MATHML_TABLE_ELEMENT_LINE_WIDTH 1 /* 1 pt */
 
+static const gboolean equal_default = FALSE;
+static const LsmMathmlLine frame_default = LSM_MATHML_LINE_NONE;
+static unsigned int row_align_values[1] = {LSM_MATHML_ROW_ALIGN_BASELINE};
+static const LsmMathmlEnumList row_align_default = {.n_values = 1, .values = row_align_values};
+static unsigned int column_align_values[1] = {LSM_MATHML_COLUMN_ALIGN_CENTER};
+static const LsmMathmlEnumList column_align_default = {.n_values = 1, .values = column_align_values};
+static LsmMathmlSpace row_spacing_values[1] = {
+	{.name = LSM_MATHML_SPACE_NAME_ERROR, .length = {.unit = LSM_MATHML_UNIT_EX, .value = 1.0}}
+};
+static const LsmMathmlSpaceList row_spacing_default = {.n_spaces = 1, .spaces = row_spacing_values};
+static LsmMathmlSpace column_spacing_values[1] = {
+	{.name = LSM_MATHML_SPACE_NAME_ERROR, .length = {.unit = LSM_MATHML_UNIT_EM, .value = 0.8}}
+};
+static const LsmMathmlSpaceList column_spacing_default = {.n_spaces = 1, .spaces = column_spacing_values};
+static unsigned int lines_values[1] = {LSM_MATHML_LINE_NONE};
+static const LsmMathmlEnumList lines_default = {.n_values = 1, .values = lines_values};
+static LsmMathmlSpace frame_spacing_values[2] = {
+	{.name = LSM_MATHML_SPACE_NAME_ERROR, .length = {.unit = LSM_MATHML_UNIT_EM, .value = 0.4}},
+	{.name = LSM_MATHML_SPACE_NAME_ERROR, .length = {.unit = LSM_MATHML_UNIT_EX, .value = 0.5}}
+};
+static const LsmMathmlSpaceList frame_spacing_default = {.n_spaces = 2, .spaces = frame_spacing_values};
+
 static GObjectClass *parent_class;
 
 /* GdomNode implementation */
@@ -49,53 +71,10 @@ static void
 lsm_mathml_table_element_update (LsmMathmlElement *self, LsmMathmlStyle *style)
 {
 	LsmMathmlTableElement *table = LSM_MATHML_TABLE_ELEMENT (self);
-	LsmMathmlSpaceList *space_list;
-	LsmMathmlEnumList enum_list;
-	unsigned int enum_attribute;
-
-	enum_list.n_values = 1;
-	enum_list.values = &enum_attribute;
-
-	enum_attribute = LSM_MATHML_ROW_ALIGN_BASELINE;
-	lsm_mathml_row_align_list_attribute_parse (&table->row_align, &enum_list);
-
-	enum_attribute = LSM_MATHML_COLUMN_ALIGN_CENTER;
-	lsm_mathml_column_align_list_attribute_parse (&table->column_align, &enum_list);
-
-	space_list = lsm_mathml_space_list_new (1);
-
-	space_list->spaces[0].length.value = 1.0;
-	space_list->spaces[0].length.unit = LSM_MATHML_UNIT_EX;
-	space_list->spaces[0].name = LSM_MATHML_SPACE_NAME_ERROR;
-
-	lsm_mathml_space_list_attribute_parse (&table->row_spacing, space_list, style);
-
-	space_list->spaces[0].length.value = 0.8;
-	space_list->spaces[0].length.unit = LSM_MATHML_UNIT_EM;
-	space_list->spaces[0].name = LSM_MATHML_SPACE_NAME_ERROR;
-
-	lsm_mathml_space_list_attribute_parse (&table->column_spacing, space_list, style);
-
-	lsm_mathml_space_list_free (space_list);
-
-	enum_attribute = LSM_MATHML_LINE_NONE;
-	lsm_mathml_line_list_attribute_parse (&table->row_lines, &enum_list);
-
-	enum_attribute = LSM_MATHML_LINE_NONE;
-	lsm_mathml_line_list_attribute_parse (&table->column_lines, &enum_list);
-
-	space_list = lsm_mathml_space_list_new (2);
-
-	space_list->spaces[0].length.value = 0.4;
-	space_list->spaces[0].length.unit = LSM_MATHML_UNIT_EM;
-	space_list->spaces[0].name = LSM_MATHML_SPACE_NAME_ERROR;
-	space_list->spaces[1].length.value = 0.5;
-	space_list->spaces[1].length.unit = LSM_MATHML_UNIT_EX;
-	space_list->spaces[1].name = LSM_MATHML_SPACE_NAME_ERROR;
-
-	lsm_mathml_space_list_attribute_parse (&table->frame_spacing, space_list, style);
 
-	lsm_mathml_space_list_free (space_list);
+	lsm_mathml_space_list_attribute_normalize (&table->row_spacing, &row_spacing_default, style);
+	lsm_mathml_space_list_attribute_normalize (&table->column_spacing, &column_spacing_default, style);
+	lsm_mathml_space_list_attribute_normalize (&table->frame_spacing, &frame_spacing_default, style);
 }
 
 static const LsmMathmlBbox *
@@ -207,7 +186,7 @@ lsm_mathml_table_element_measure (LsmMathmlElement *self, LsmMathmlView *view, c
 		for (column = 0; column < table->n_columns; column++)
 			table->widths[column] = max_width;
 
-	max_index = table->column_spacing.space_list->n_spaces -  1;
+	max_index = table->column_spacing.space_list.n_spaces -  1;
 	for (column = 0; column < table->n_columns; column++) {
 		self->bbox.width += table->widths[column];
 		if (column < table->n_columns - 1)
@@ -216,7 +195,7 @@ lsm_mathml_table_element_measure (LsmMathmlElement *self, LsmMathmlView *view, c
 
 	height = 0.0;
 
-	max_index = table->row_spacing.space_list->n_spaces -  1;
+	max_index = table->row_spacing.space_list.n_spaces -  1;
 	for (row = 0; row < table->n_rows; row++) {
 		height += table->heights[row] + table->depths[row];
 		if (row < table->n_rows - 1)
@@ -291,8 +270,8 @@ lsm_mathml_table_element_layout (LsmMathmlElement *self, LsmMathmlView *view,
 	if (table->n_rows < 1 || table->n_columns < 1)
 		return;
 
-	max_column = table->column_spacing.space_list->n_spaces -  1;
-	max_row = table->row_spacing.space_list->n_spaces -  1;
+	max_column = table->column_spacing.space_list.n_spaces -  1;
+	max_row = table->row_spacing.space_list.n_spaces -  1;
 
 	y_offset = -self->bbox.height;
         y_offset += table->frame_spacing.values[1];
@@ -310,7 +289,8 @@ lsm_mathml_table_element_layout (LsmMathmlElement *self, LsmMathmlView *view,
 		     cell_node = cell_node->next_sibling) {
 			bbox = lsm_mathml_element_get_bbox (LSM_MATHML_ELEMENT (cell_node));
 
-			switch (table->row_align.values[MIN (row, table->row_align.n_values - 1)]) {
+			switch (table->row_align.enum_list.values[MIN (row,
+								       table->row_align.enum_list.n_values - 1)]) {
 				case LSM_MATHML_ROW_ALIGN_TOP:
 					y_cell = y + y_offset + bbox->height;
 					break;
@@ -328,7 +308,9 @@ lsm_mathml_table_element_layout (LsmMathmlElement *self, LsmMathmlView *view,
 					y_cell = y + y_offset + table->heights[row];
 			}
 
-			switch (table->column_align.values[MIN (column, table->column_align.n_values - 1)]) {
+			switch (table->column_align.enum_list.values[MIN (column,
+									  table->column_align.enum_list.n_values
+									  - 1)]) {
 				case LSM_MATHML_COLUMN_ALIGN_LEFT:
 					x_cell = x + x_offset;
 					break;
@@ -387,11 +369,13 @@ lsm_mathml_table_element_render (LsmMathmlElement *self, LsmMathmlView *view)
 
 	for (i = 0; i < table->n_rows - 1; i++) {
 		position += table->heights[i] + table->depths[i];
-		spacing = table->row_spacing.values[MIN (i, table->row_spacing.space_list->n_spaces - 1)];
+		spacing = table->row_spacing.values[MIN (i, table->row_spacing.space_list.n_spaces - 1)];
 		y = position + (0.5 * spacing) + table->line_width * 0.5;
 		lsm_mathml_view_show_line (view, &self->style,
 					x0, y, x1, y,
-					table->row_lines.values[MIN (i, table->row_lines.n_values - 1)],
+					table->row_lines.enum_list.values[MIN (i,
+									       table->row_lines.enum_list.n_values
+									       - 1)],
 					table->line_width);
 		position += spacing + table->line_width;
 	}
@@ -402,11 +386,13 @@ lsm_mathml_table_element_render (LsmMathmlElement *self, LsmMathmlView *view)
 
 	for (i = 0; i < table->n_columns - 1; i++) {
 		position += table->widths[i];
-		spacing = table->column_spacing.values[MIN (i, table->column_spacing.space_list->n_spaces - 1)];
+		spacing = table->column_spacing.values[MIN (i, table->column_spacing.space_list.n_spaces - 1)];
 		x = position + 0.5 * (spacing + table->line_width);
 		lsm_mathml_view_show_line (view, &self->style,
 					x, y0, x, y1,
-					table->column_lines.values[MIN (i, table->column_lines.n_values - 1)],
+					table->column_lines.enum_list.values[MIN (i,
+										  table->column_lines.enum_list.n_values
+										  - 1)],
 					table->line_width);
 		position += spacing + table->line_width;
 	}
@@ -422,9 +408,6 @@ lsm_mathml_table_element_new (void)
 	return g_object_new (LSM_TYPE_MATHML_TABLE_ELEMENT, NULL);
 }
 
-static const gboolean equal_default = FALSE;
-static const LsmMathmlLine frame_default = LSM_MATHML_LINE_NONE;
-
 static void
 lsm_mathml_table_element_init (LsmMathmlTableElement *table)
 {
@@ -438,6 +421,11 @@ lsm_mathml_table_element_init (LsmMathmlTableElement *table)
 	table->equal_columns.value = equal_default;
 	table->equal_rows.value = equal_default;
 	table->frame.value = frame_default;
+
+	lsm_mathml_enum_list_init (&table->row_align.enum_list, &row_align_default);
+	lsm_mathml_enum_list_init (&table->column_align.enum_list, &column_align_default);
+	lsm_mathml_enum_list_init (&table->row_lines.enum_list, &lines_default);
+	lsm_mathml_enum_list_init (&table->column_lines.enum_list, &lines_default);
 }
 
 static void
@@ -452,6 +440,13 @@ lsm_mathml_table_element_finalize (GObject *object)
 	table->heights = NULL;
 	table->depths = NULL;
 
+	g_free (table->row_spacing.values);
+	g_free (table->column_spacing.values);
+	g_free (table->frame_spacing.values);
+	table->row_spacing.values = NULL;
+	table->column_spacing.values = NULL;
+	table->frame_spacing.values = NULL;
+
 	parent_class->finalize (object);
 }
 
@@ -475,6 +470,48 @@ static const LsmAttributeInfos _attribute_infos[] = {
 		.attribute_offset = offsetof (LsmMathmlTableElement, frame),
 		.trait_class = &lsm_mathml_line_trait_class,
 		.trait_default = &frame_default
+	},
+	{
+		.name = "rowalign",
+		.attribute_offset = offsetof (LsmMathmlTableElement, row_align),
+		.trait_class = &lsm_mathml_row_align_list_trait_class,
+		.trait_default = &row_align_default
+	},
+	{
+		.name = "columnalign",
+		.attribute_offset = offsetof (LsmMathmlTableElement, column_align),
+		.trait_class = &lsm_mathml_column_align_list_trait_class,
+		.trait_default = &column_align_default
+	},
+	{
+		.name = "rowspacing",
+		.attribute_offset = offsetof (LsmMathmlTableElement, row_spacing),
+		.trait_class = &lsm_mathml_space_list_trait_class,
+		.trait_default = &row_spacing_default
+	},
+	{
+		.name = "columnspacing",
+		.attribute_offset = offsetof (LsmMathmlTableElement, column_spacing),
+		.trait_class = &lsm_mathml_space_list_trait_class,
+		.trait_default = &column_spacing_default
+	},
+	{
+		.name = "rowlines",
+		.attribute_offset = offsetof (LsmMathmlTableElement, row_lines),
+		.trait_class = &lsm_mathml_line_list_trait_class,
+		.trait_default = &lines_default
+	},
+	{
+		.name = "columnlines",
+		.attribute_offset = offsetof (LsmMathmlTableElement, column_lines),
+		.trait_class = &lsm_mathml_line_list_trait_class,
+		.trait_default = &lines_default
+	},
+	{
+		.name = "framespacing",
+		.attribute_offset = offsetof (LsmMathmlTableElement, frame_spacing),
+		.trait_class = &lsm_mathml_space_list_trait_class,
+		.trait_default = &frame_spacing_default
 	}
 };
 
@@ -502,23 +539,6 @@ lsm_mathml_table_element_class_init (LsmMathmlTableElementClass *table_class)
 	lsm_attribute_manager_add_attributes (m_element_class->attribute_manager,
 					      G_N_ELEMENTS (_attribute_infos),
 					      _attribute_infos);
-
-	m_element_class->attributes = lsm_mathml_attribute_map_duplicate (m_element_class->attributes);
-
-	lsm_mathml_attribute_map_add_enum_list (m_element_class->attributes, "rowalign",
-					   offsetof (LsmMathmlTableElement, row_align));
-	lsm_mathml_attribute_map_add_enum_list (m_element_class->attributes, "columnalign",
-					   offsetof (LsmMathmlTableElement, column_align));
-	lsm_mathml_attribute_map_add_enum_list (m_element_class->attributes, "rowspacing",
-					   offsetof (LsmMathmlTableElement, row_spacing));
-	lsm_mathml_attribute_map_add_enum_list (m_element_class->attributes, "columnspacing",
-					   offsetof (LsmMathmlTableElement, column_spacing));
-	lsm_mathml_attribute_map_add_enum_list (m_element_class->attributes, "rowlines",
-					   offsetof (LsmMathmlTableElement, row_lines));
-	lsm_mathml_attribute_map_add_enum_list (m_element_class->attributes, "columnlines",
-					   offsetof (LsmMathmlTableElement, column_lines));
-	lsm_mathml_attribute_map_add_space_list (m_element_class->attributes, "framespacing",
-					   offsetof (LsmMathmlTableElement, frame_spacing));
 }
 
 G_DEFINE_TYPE (LsmMathmlTableElement, lsm_mathml_table_element, LSM_TYPE_MATHML_ELEMENT)
diff --git a/src/lsmmathmltraits.c b/src/lsmmathmltraits.c
index bd392dc..69cf4de 100644
--- a/src/lsmmathmltraits.c
+++ b/src/lsmmathmltraits.c
@@ -223,6 +223,143 @@ const LsmTraitClass lsm_mathml_form_trait_class = {
 	.to_string = lsm_mathml_form_trait_to_string
 };
 
+typedef unsigned int (*LsmMathmlEnumFromString) (const char *string);
+typedef char * (*LsmMathmlEnumToString) (unsigned int value);
+
+static void
+lsm_mathml_enum_list_trait_from_string (LsmMathmlEnumList *enum_list,
+					LsmMathmlEnumFromString from_string,
+					char *string)
+{
+	char **items;
+	unsigned int i;
+
+	g_free (enum_list->values);
+
+	items = g_strsplit_set (string, " ", -1);
+	enum_list->n_values = g_strv_length (items);
+
+	enum_list->values = g_new (unsigned int, enum_list->n_values);
+	for (i = 0; i < enum_list->n_values; i++)
+		enum_list->values[i] = from_string (items[i]);
+
+	g_strfreev (items);
+}
+
+static char *
+lsm_mathml_enum_list_trait_to_string (LsmMathmlEnumList *enum_list,
+				      LsmMathmlEnumToString to_string)
+{
+	return g_strdup ("FIXME");
+}
+
+static void
+lsm_mathml_enum_list_trait_init (LsmTrait *abstract_trait,
+				 const LsmTrait *abstract_default)
+{
+	LsmMathmlEnumList *enum_list = (LsmMathmlEnumList *) abstract_trait;
+	LsmMathmlEnumList *enum_list_defaut = (LsmMathmlEnumList *) abstract_default;
+
+	enum_list->n_values = enum_list_defaut->n_values;
+	if (enum_list->n_values == 0)
+		enum_list->values = NULL;
+	else {
+		enum_list->values = g_new (unsigned int, enum_list->n_values);
+		memcpy (enum_list->values, enum_list_defaut->values, sizeof (unsigned int) * enum_list->n_values);
+	}
+}
+
+void
+lsm_mathml_enum_list_init (LsmMathmlEnumList *enum_list, const LsmMathmlEnumList *enum_list_default)
+{
+	g_return_if_fail (enum_list != NULL);
+	g_return_if_fail (enum_list_default != NULL);
+
+	lsm_mathml_enum_list_trait_init (enum_list, enum_list_default);
+}
+
+static void
+lsm_mathml_enum_list_trait_finalize (LsmTrait *abstract_trait)
+{
+	LsmMathmlEnumList *enum_list = (LsmMathmlEnumList *) abstract_trait;
+
+	g_free (enum_list->values);
+	enum_list->values = NULL;
+	enum_list->n_values = 0;
+}
+
+static void
+lsm_mathml_row_align_list_trait_from_string (LsmTrait *abstract_trait,
+					     char *string)
+{
+	lsm_mathml_enum_list_trait_from_string ((LsmMathmlEnumList *) abstract_trait,
+						(LsmMathmlEnumFromString) lsm_mathml_row_align_from_string,
+						string);
+}
+
+static char *
+lsm_mathml_row_align_list_trait_to_string (LsmTrait *abstract_trait)
+{
+	return lsm_mathml_enum_list_trait_to_string ((LsmMathmlEnumList *) abstract_trait,
+						     (LsmMathmlEnumToString) lsm_mathml_row_align_to_string);
+}
+
+const LsmTraitClass lsm_mathml_row_align_list_trait_class = {
+	.size = sizeof (LsmMathmlEnumList),
+	.from_string = lsm_mathml_row_align_list_trait_from_string,
+	.to_string = lsm_mathml_row_align_list_trait_to_string,
+	.init = lsm_mathml_enum_list_trait_init,
+	.finalize = lsm_mathml_enum_list_trait_finalize
+};
+
+static void
+lsm_mathml_column_align_list_trait_from_string (LsmTrait *abstract_trait,
+					     char *string)
+{
+	lsm_mathml_enum_list_trait_from_string ((LsmMathmlEnumList *) abstract_trait,
+						(LsmMathmlEnumFromString) lsm_mathml_column_align_from_string,
+						string);
+}
+
+static char *
+lsm_mathml_column_align_list_trait_to_string (LsmTrait *abstract_trait)
+{
+	return lsm_mathml_enum_list_trait_to_string ((LsmMathmlEnumList *) abstract_trait,
+						     (LsmMathmlEnumToString) lsm_mathml_column_align_to_string);
+}
+
+const LsmTraitClass lsm_mathml_column_align_list_trait_class = {
+	.size = sizeof (LsmMathmlEnumList),
+	.from_string = lsm_mathml_column_align_list_trait_from_string,
+	.to_string = lsm_mathml_column_align_list_trait_to_string,
+	.init = lsm_mathml_enum_list_trait_init,
+	.finalize = lsm_mathml_enum_list_trait_finalize
+};
+
+static void
+lsm_mathml_line_list_trait_from_string (LsmTrait *abstract_trait,
+					     char *string)
+{
+	lsm_mathml_enum_list_trait_from_string ((LsmMathmlEnumList *) abstract_trait,
+						(LsmMathmlEnumFromString) lsm_mathml_line_from_string,
+						string);
+}
+
+static char *
+lsm_mathml_line_list_trait_to_string (LsmTrait *abstract_trait)
+{
+	return lsm_mathml_enum_list_trait_to_string ((LsmMathmlEnumList *) abstract_trait,
+						     (LsmMathmlEnumToString) lsm_mathml_line_to_string);
+}
+
+const LsmTraitClass lsm_mathml_line_list_trait_class = {
+	.size = sizeof (LsmMathmlEnumList),
+	.from_string = lsm_mathml_line_list_trait_from_string,
+	.to_string = lsm_mathml_line_list_trait_to_string,
+	.init = lsm_mathml_enum_list_trait_init,
+	.finalize = lsm_mathml_enum_list_trait_finalize
+};
+
 static void
 lsm_mathml_script_level_trait_from_string (LsmTrait *abstract_trait, char *string)
 {
@@ -360,6 +497,16 @@ lsm_mathml_string_trait_to_string (LsmTrait *abstract_trait)
 }
 
 static void
+lsm_mathml_string_trait_init (LsmTrait *abstract_trait,
+			      const LsmTrait *abstract_default)
+{
+	char **value = (char **) abstract_trait;
+	char **default_value = (char **) abstract_default;
+
+	*value = g_strdup (*default_value);
+}
+
+static void
 lsm_mathml_string_trait_finalize (LsmTrait *abstract_trait)
 {
 	char **value = (char **) abstract_trait;
@@ -372,6 +519,7 @@ const LsmTraitClass lsm_mathml_string_trait_class = {
 	.size = sizeof (char *),
 	.from_string = lsm_mathml_string_trait_from_string,
 	.to_string = lsm_mathml_string_trait_to_string,
+	.init = lsm_mathml_string_trait_init,
 	.finalize = lsm_mathml_string_trait_finalize
 };
 
@@ -530,67 +678,70 @@ const LsmTraitClass lsm_mathml_space_trait_class = {
 	.to_string = lsm_mathml_space_trait_to_string
 };
 
-
-GType
-lsm_mathml_space_list_get_type (void)
+void
+lsm_mathml_space_list_trait_from_string (LsmTrait *abstract_trait, char *string)
 {
-	static GType our_type = 0;
+	LsmMathmlSpaceList *space_list = (LsmMathmlSpaceList *) abstract_trait;
+	char **items;
+	unsigned int i;
 
-	if (our_type == 0)
-		our_type = g_boxed_type_register_static
-			("LsmMathmlSpaceList",
-			 (GBoxedCopyFunc) lsm_mathml_space_list_duplicate,
-			 (GBoxedFreeFunc) lsm_mathml_space_list_free);
-	return our_type;
-}
+	g_free (space_list->spaces);
 
-LsmMathmlSpaceList *
-lsm_mathml_space_list_new (unsigned int n_spaces)
-{
-	LsmMathmlSpaceList *space_list;
+	items = g_strsplit_set (string, " ", -1);
+	space_list->n_spaces = g_strv_length (items);
 
-	space_list = g_new (LsmMathmlSpaceList, 1);
-	if (space_list == NULL)
-		return NULL;
+	space_list->spaces = g_new (LsmMathmlSpace, space_list->n_spaces);
+	for (i = 0; i < space_list->n_spaces; i++)
+		lsm_mathml_space_trait_from_string (&space_list->spaces[i], items[i]);
 
-	space_list->n_spaces = n_spaces;
+	g_strfreev (items);
+}
 
-	if (n_spaces > 0) {
-		space_list->spaces = g_new (LsmMathmlSpace, n_spaces);
+static char *
+lsm_mathml_space_list_trait_to_string (LsmTrait *abstract_trait)
+{
+	return g_strdup ("FIXME");
+}
 
-		if (space_list->spaces == NULL) {
-			g_free (space_list);
-			return NULL;
-		}
-	} else
-		space_list->spaces = NULL;
+static void
+lsm_mathml_space_list_trait_init (LsmTrait *abstract_trait,
+				  const LsmTrait *abstract_default)
+{
+	LsmMathmlSpaceList *space_list = (LsmMathmlSpaceList *) abstract_trait;
+	LsmMathmlSpaceList *space_list_defaut = (LsmMathmlSpaceList *) abstract_default;
 
-	return space_list;
+	space_list->n_spaces = space_list_defaut->n_spaces;
+	if (space_list->n_spaces == 0)
+		space_list->spaces = NULL;
+	else {
+		space_list->spaces = g_new (LsmMathmlSpace, space_list->n_spaces);
+		memcpy (space_list->spaces, space_list_defaut->spaces, sizeof (LsmMathmlSpace) * space_list->n_spaces);
+	}
 }
 
-void
-lsm_mathml_space_list_free (LsmMathmlSpaceList *space_list)
+static void
+lsm_mathml_space_list_trait_finalize (LsmTrait *abstract_trait)
 {
-	if (space_list == NULL)
-		return;
-
-	space_list->n_spaces = 0;
+	LsmMathmlSpaceList *space_list = (LsmMathmlSpaceList *) abstract_trait;
 
 	g_free (space_list->spaces);
-	g_free (space_list);
+	space_list->spaces = NULL;
+	space_list->n_spaces = 0;
 }
 
-LsmMathmlSpaceList *
-lsm_mathml_space_list_duplicate (const LsmMathmlSpaceList *space_list)
+void
+lsm_mathml_space_list_init (LsmMathmlSpaceList *space_list, const LsmMathmlSpaceList *space_list_default)
 {
-	LsmMathmlSpaceList *new_space_list;
-
-	g_return_val_if_fail (space_list != NULL, NULL);
+	g_return_if_fail (space_list != NULL);
+	g_return_if_fail (space_list_default != NULL);
 
-	new_space_list = lsm_mathml_space_list_new (space_list->n_spaces);
-	memcpy (new_space_list->spaces, space_list->spaces,
-		sizeof (LsmMathmlSpace) * space_list->n_spaces);
-
-	return new_space_list;
+	lsm_mathml_space_list_trait_init (space_list, space_list_default);
 }
 
+const LsmTraitClass lsm_mathml_space_list_trait_class = {
+	.size = sizeof (LsmMathmlSpaceList),
+	.from_string = lsm_mathml_space_list_trait_from_string,
+	.to_string = lsm_mathml_space_list_trait_to_string,
+	.init = lsm_mathml_space_list_trait_init,
+	.finalize = lsm_mathml_space_list_trait_finalize
+};
diff --git a/src/lsmmathmltraits.h b/src/lsmmathmltraits.h
index 35e8711..3ef3b0e 100644
--- a/src/lsmmathmltraits.h
+++ b/src/lsmmathmltraits.h
@@ -63,6 +63,11 @@ typedef struct {
 	int level;
 } LsmMathmlScriptLevel;
 
+typedef struct {
+	unsigned int n_values;
+	unsigned int *values;
+} LsmMathmlEnumList;
+
 #define LSM_TYPE_MATHML_SPACE (lsm_mathml_space_get_type())
 
 typedef struct {
@@ -72,21 +77,18 @@ typedef struct {
 
 GType 	lsm_mathml_space_get_type 	(void);
 
-#define LSM_TYPE_MATHML_SPACE_LIST (lsm_mathml_space_list_get_type())
-
 typedef struct {
 	unsigned int n_spaces;
 	LsmMathmlSpace *spaces;
 } LsmMathmlSpaceList;
 
-GType 			lsm_mathml_space_list_get_type 	(void);
-LsmMathmlSpaceList *	lsm_mathml_space_list_new  	(unsigned int n_spaces);
-void 			lsm_mathml_space_list_free 	(LsmMathmlSpaceList *space_list);
-LsmMathmlSpaceList *	lsm_mathml_space_list_duplicate	(const LsmMathmlSpaceList *space_list);
+void lsm_mathml_enum_list_init  (LsmMathmlEnumList *enum_list, const LsmMathmlEnumList *enum_list_default);
+void lsm_mathml_space_list_init (LsmMathmlSpaceList *space_list, const LsmMathmlSpaceList *space_list_default);
 
 extern const LsmTraitClass lsm_mathml_boolean_trait_class;
 
 extern const LsmTraitClass lsm_mathml_unsigned_trait_class;
+
 extern const LsmTraitClass lsm_mathml_display_trait_class;
 extern const LsmTraitClass lsm_mathml_mode_trait_class;
 extern const LsmTraitClass lsm_mathml_line_trait_class;
@@ -95,12 +97,18 @@ extern const LsmTraitClass lsm_mathml_font_weight_trait_class;
 extern const LsmTraitClass lsm_mathml_variant_trait_class;
 extern const LsmTraitClass lsm_mathml_form_trait_class;
 
+extern const LsmTraitClass lsm_mathml_row_align_list_trait_class;
+extern const LsmTraitClass lsm_mathml_column_align_list_trait_class;
+extern const LsmTraitClass lsm_mathml_line_list_trait_class;
+
 extern const LsmTraitClass lsm_mathml_script_level_trait_class;
 
 extern const LsmTraitClass lsm_mathml_double_trait_class;
 extern const LsmTraitClass lsm_mathml_string_trait_class;
 extern const LsmTraitClass lsm_mathml_length_trait_class;
+
 extern const LsmTraitClass lsm_mathml_space_trait_class;
+extern const LsmTraitClass lsm_mathml_space_list_trait_class;
 
 extern const LsmTraitClass lsm_mathml_color_trait_class;
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]