def start_vspace(self, vspace):
     if vspace.text is None:
         drop = 1
     else:
         drop = convert_str_to_int(vspace.text)
     self.html_file.write("\\vspace{%s\drop}\n" % drop)
     return
    def _load_innate_ability_modifier(self, innate_node):
        ability_id = None
        ability_level = None

        # handle all the children
        for child in list(innate_node):
            tag = child.tag

            if tag == "abilityid":
                if ability_id is not None:
                    raise Exception("Only one id per ability modifier!")
                else:
                    ability_id = child.text.strip()

            elif tag == "level":
                ability_level = convert_str_to_int(child.text)

            elif tag is COMMENT:
                # ignore comments!
                pass

            else:
                raise Exception("UNKNOWN XML TAG (%s) File: %s Line: %s\n" %
                                (child.tag, self.fname, child.sourceline))

        if ability_id not in self.modified_abilities_lookup:
            raise Exception(
                "Unknown ability id: '%s' in archetype file: %s Line: %s\n" %
                (ability_id, self.fname, child.sourceline))
        else:
            ability = self.modified_abilities_lookup[ability_id]

        ability_level = ability.get_modified_ability_level(ability_level)
        ability_level.set_innate()
        return
    def parse(self, fname, bonus_element):
        for child in list(bonus_element):
            tag = child.tag
            if tag == "attr":
                self.attribute = contents_to_string(child)

            elif tag == "value":
                try:
                    self.bonus = convert_str_to_int(contents_to_string(child))
                except ValueError as err:
                    ValueError("%s (%s) File: %s Line: %s\n" %
                               (str(err), child.tag, fname, child.sourceline))

            elif tag is COMMENT:
                # ignore comments!
                pass

            else:
                raise Exception("UNKNOWN XML TAG (%s) File: %s Line: %s\n" %
                                (child.tag, fname, child.sourceline))
        return
    def _load(self, archetype_node, fail_fast):
        # handle all the children
        for child in list(archetype_node):

            tag = child.tag
            if tag == "archetypetitle":
                if self.title is not None:
                    raise NonUniqueTagError(tag, self.fname, child.sourceline)
                else:
                    self.title = child.text.strip()

            elif tag == "archetypeid":
                if self.archetype_id is not None:
                    raise NonUniqueTagError(tag, self.fname, child.sourceline)
                else:
                    self.archetype_id = child.text.strip()

            elif tag == "archetypeac":
                if self.ac is not None:
                    raise NonUniqueTagError(tag, self.fname, child.sourceline)
                else:
                    self.ac = child.text.strip()

            elif tag == "archetypemove":
                if self.move is not None:
                    raise NonUniqueTagError(tag, self.fname, child.sourceline)
                else:
                    self.move = child.text.strip()

            elif tag == "inheritance":
                self._load_inheritance(inheritance=child)

            elif tag == "archetypedescription":
                if self.description is not None:
                    raise NonUniqueTagError(tag, self.fname, child.sourceline)
                else:
                    self.description = children_to_string(child)

            elif tag == "archetypeinitiative":
                if self.initiative is not None:
                    raise NonUniqueTagError(tag, self.fname, child.sourceline)
                    #raise Exception("Only one archetypeinitiative per file.")
                else:
                    self.initiative = convert_str_to_int(child.text)

            elif tag == "startingcash":
                if self.starting_cash is not None:
                    raise NonUniqueTagError(tag, self.fname, child.sourceline)
                else:
                    self.starting_cash = child.text

            elif tag == "startinggear":
                if self.starting_gear is not None:
                    raise NonUniqueTagError(tag, self.fname, child.sourceline)
                else:
                    self.starting_gear = normalize_ws(child.text)

            elif tag == "height":
                if self.height is not None:
                    raise NonUniqueTagError(tag, self.fname, child.sourceline)
                else:
                    self.height = parse_measurement_to_str(self.fname, child)

            elif tag == "weight":
                if self.weight is not None:
                    raise NonUniqueTagError(tag, self.fname, child.sourceline)
                else:
                    self.weight = parse_measurement_to_str(self.fname, child)

            elif tag == "appearance":
                if self.appearance is not None:
                    raise NonUniqueTagError(tag, self.fname, child.sourceline)
                else:
                    self.appearance = normalize_ws(child.text)

            elif tag == "age":
                if self.age is not None:
                    raise NonUniqueTagError(tag, self.fname, child.sourceline)
                else:
                    self.age = normalize_ws(child.text)

            elif tag == "aspectexamples":
                if self.aspect_examples is not None:
                    raise NonUniqueTagError(tag, self.fname, child.sourceline)
                else:
                    self.aspect_examples = child.text

            elif tag == "archetypetags":
                self.tags.load(child, fail_fast)

            elif tag == "archetypeinitialabilities":
                if self.initial_abilities is not None:
                    raise NonUniqueTagError(tag, self.fname, child.sourceline)
                else:
                    self.initial_abilities = children_to_string(child)

            elif tag == "levelprogressiontable":
                self.level_progression_table.load(child, fail_fast)

            elif tag == "abilitymodifiers":
                self._load_ability_modifiers(child)

            elif tag == "attrbonus":
                bonus = AttrBonus()
                bonus.parse(self.fname, child)
                self.attr_bonuses.append(bonus)

            elif tag == "attrmax":
                attr_max = AttrLimit()
                attr_max.parse(self.fname, AttrLimitType.MAX, child)
                self.attr_limits.append(attr_max)

            elif tag == "attrmin":
                attr_min = AttrLimit()
                attr_min.parse(self.fname, AttrLimitType.MIN, child)
                self.attr_limits.append(attr_min)

            elif tag is COMMENT:
                # ignore comments!
                pass

            else:
                raise Exception("UNKNOWN XML TAG (%s) File: %s Line: %s\n" %
                                (child.tag, self.fname, child.sourceline))
        return
    def load(self, archetype_node, fail_fast):
        # handle all the children
        for child in list(archetype_node):

            tag = child.tag
            if tag == "levelnumber":
                if self.level_number is not None:
                    raise NonUniqueTagError(tag, self.fname, child.sourceline)
                else:
                    self.level_number = int(child.text.strip())

            elif tag == "levelresolve":
                if self.level_resolve is not None:
                    raise NonUniqueTagError(tag, self.fname, child.sourceline)
                else:
                    self.level_resolve = contents_to_string(child)

            elif tag == "levelresolverefresh":
                if self.level_resolve_refresh is not None:
                    raise NonUniqueTagError(tag, self.fname, child.sourceline)
                else:
                    self.level_resolve_refresh = contents_to_string(child)

            elif tag == "levelstamina":
                if self.level_stamina is not None:
                    raise NonUniqueTagError(tag, self.fname, child.sourceline)
                else:
                    self.level_stamina = normalize_ws(child.text.strip())

            elif tag == "levelstaminarefresh":
                if self.level_stamina_refresh is not None:
                    raise NonUniqueTagError(tag, self.fname, child.sourceline)
                else:
                    self.level_stamina_refresh = normalize_ws(
                        child.text.strip())

            elif tag == "levelhealth":
                if self.level_health is not None:
                    raise NonUniqueTagError(tag, self.fname, child.sourceline)
                else:
                    self.level_health = normalize_ws(child.text.strip())

            elif tag == "levelhealthrefresh":
                if self.level_health_refresh is not None:
                    raise NonUniqueTagError(tag, self.fname, child.sourceline)
                else:
                    self.level_health_refresh = normalize_ws(
                        child.text.strip())

            elif tag == "levellore":
                if self.level_lore is not None:
                    raise NonUniqueTagError(tag, self.fname, child.sourceline)
                else:
                    self.level_lore = convert_str_to_int(child.text.strip())

            elif tag == "levelmartial":
                if self.level_martial is not None:
                    raise NonUniqueTagError(tag, self.fname, child.sourceline)
                else:
                    self.level_martial = convert_str_to_int(child.text.strip())

            elif tag == "levelgeneral":
                if self.level_general is not None:
                    raise NonUniqueTagError(tag, self.fname, child.sourceline)
                else:
                    self.level_general = convert_str_to_int(child.text.strip())

            elif tag == "levelmagical":
                if self.level_magical is not None:
                    raise NonUniqueTagError(tag, self.fname, child.sourceline)
                else:
                    self.level_magical = convert_str_to_int(child.text.strip())

            elif tag == "leveldescription":
                if self.level_description is not None:
                    raise NonUniqueTagError(tag, self.fname, child.sourceline)
                else:
                    if child.text is not None:
                        self.level_description = contents_to_string(child)

            elif tag == "newlevelabilities":
                if len(self.level_abilities) > 0:
                    raise NonUniqueTagError(tag, self.fname, child.sourceline)
                else:
                    if child.text is not None:
                        self.load_level_abilities(child)

            elif tag == "newlevelpromotions":
                if len(self.level_promotions) > 0:
                    raise NonUniqueTagError(tag, self.fname, child.sourceline)
                else:
                    if child.text is not None:
                        self.load_level_promotions(child)

            elif tag == "levelmagicpool":
                if self.level_magic_pool is not None:
                    raise NonUniqueTagError(tag, self.fname, child.sourceline)
                else:
                    self.level_magic_pool = contents_to_string(child)

            elif tag == "levelmagicrefresh":
                if self.level_magic_refresh is not None:
                    raise NonUniqueTagError(tag, self.fname, child.sourceline)
                else:
                    self.level_magic_refresh = contents_to_string(child)

            elif tag == "levelfate":
                if self.level_fate is not None:
                    raise NonUniqueTagError(tag, self.fname, child.sourceline)
                else:
                    self.level_fate = contents_to_string(child)

            elif tag == "levelfaterefresh":
                if self.level_fate_refresh is not None:
                    raise NonUniqueTagError(tag, self.fname, child.sourceline)
                else:
                    self.level_fate_refresh = contents_to_string(child)

            elif tag is COMMENT:
                # ignore comments!
                pass

            else:
                raise Exception("UNKNOWN XML TAG (%s) File: %s Line: %s\n" %
                                (child.tag, self.fname, child.sourceline))
        return
    def _load_ability_group_modifier(self, ability_group_modifier):

        ability_group_id = None
        lore_point_modifier = 0
        martial_point_modifier = 0
        general_point_modifier = 0
        magical_point_modifier = 0
        successes_modifier = 0
        attempts_modifier = 0
        failures_modifier = 0

        # handle all the children
        for child in list(ability_group_modifier):
            tag = child.tag

            if tag == "abilitygroupid":
                if ability_group_id is not None:
                    raise Exception("Only one id per ability group modifier!")
                else:
                    ability_group_id = child.text.strip()

                    # if ability_group_id not in self.modified_ability_groups_lookup:
                    #     raise Exception("UNKNOWN ABILITY GROUP ID (%s) File: %s Line: %s\n" %
                    #                     (ability_group_id, self.fname, child.sourceline))

            elif tag == "lorepointmodifier":
                lore_point_modifier = convert_str_to_int(child.text)

            elif tag == "martialpointmodifier":
                martial_point_modifier = convert_str_to_int(child.text)

            elif tag == "generalpointmodifier":
                general_point_modifier = convert_str_to_int(child.text)

            elif tag == "magicalpointmodifier":
                magical_point_modifier = convert_str_to_int(child.text)

            elif tag == "successesmodifier":
                successes_modifier = convert_str_to_int(child.text)

            elif tag == "failuresmodifier":
                failures_modifier = convert_str_to_int(child.text)

            elif tag == "attemptsmodifier":
                attempts_modifier = convert_str_to_int(child.text)

            elif tag is COMMENT:
                # ignore comments!
                pass

            else:
                raise Exception("UNKNOWN XML TAG (%s) File: %s Line: %s\n" %
                                (child.tag, self.fname, child.sourceline))

        # modified_ability_group = self.modified_ability_groups_lookup[ability_group_id]
        # modified_ability_group.lore_point_modifier = lore_point_modifier
        # modified_ability_group.martial_point_modifier = martial_point_modifier
        # modified_ability_group.general_point_modifier = general_point_modifier
        # modified_ability_group.magical_point_modifier = magical_point_modifier
        # modified_ability_group.successes_modifier = successes_modifier
        # modified_ability_group.attempts_modifier = attempts_modifier
        # modified_ability_group.failures_modifier = failures_modifier

        ## assert self.ability_id is not None
        ## return ability_modifier
        return
    def _load_ability_modifier(self, ability_modifier):
        ability_id = None
        lore_point_modifier = 0
        martial_point_modifier = 0
        general_point_modifier = 0
        magical_point_modifier = 0
        successes_modifier = 0
        attempts_modifier = 0
        failures_modifier = 0

        # parse ability level modifiers last.
        ability_level_modifier_elements = []

        # handle all the children
        for child in list(ability_modifier):
            tag = child.tag

            if tag == "abilityid":
                if ability_id is not None:
                    raise Exception("Only one id per ability modifier!")
                else:
                    ability_id = child.text.strip()

            elif tag == "lorepointmodifier":
                lore_point_modifier = convert_str_to_int(child.text)

            elif tag == "martialpointmodifier":
                martial_point_modifier = convert_str_to_int(child.text)

            elif tag == "generalpointmodifier":
                self.general_point_modifier = convert_str_to_int(child.text)

            elif tag == "magicalpointmodifier":
                self.magical_point_modifier = convert_str_to_int(child.text)

            elif tag == "abilitylevelmodifier":
                ability_level_modifier_elements.append(child)

            elif tag == "successesmodifier":
                successes_modifier = convert_str_to_int(child.text)

            elif tag == "failuresmodifier":
                failures_modifier = convert_str_to_int(child.text)

            elif tag == "attemptsmodifier":
                attempts_modifier = convert_str_to_int(child.text)

            elif tag is COMMENT:
                # ignore comments!
                pass

            else:
                raise Exception("UNKNOWN XML TAG (%s) File: %s Line: %s\n" %
                                (child.tag, self.fname, child.sourceline))

        # if ability_id not in self.modified_abilities_lookup:
        #     raise Exception("UNKNOWN ABILITY (%s) File: %s Line: %s\n" %
        #                        (ability_id, self.fname, child.sourceline))

        # modified_ability = self.modified_abilities_lookup[ability_id]
        # modified_ability.martial_point_modifier = martial_point_modifier
        # modified_ability.lore_point_modifier = lore_point_modifier
        # modified_ability.general_point_modifier = general_point_modifier
        # modified_ability.magical_point_modifier = magical_point_modifier
        # modified_ability.successes_modifier = successes_modifier
        # modified_ability.failures_modifier = failures_modifier
        # modified_ability.attempts_modifier = attempts_modifier

        # # handle
        # for child in ability_level_modifier_elements:
        #     modified_ability.load_ability_level_modifier(child)

        return
    def _load(self, monster_element):
        # handle all the children
        for child in list(monster_element):
            tag = child.tag
            if tag == "monstertitle":
                if self.title is not None:
                    raise Exception(
                        "Only one monstertitle per monster. (%s) %s\n" %
                        (child.tag, str(child)))
                else:
                    self.title = child.text

            elif tag == "monsterid":
                if self.monster_id is not None:
                    raise Exception(
                        "Only one monsterid per monster. (%s) %s\n" %
                        (child.tag, str(child)))
                else:
                    # check for duplicates!
                    monster_id = child.text
                    monster_location = self._get_location(child)
                    if monster_id in self._ids:
                        raise Exception(
                            "Monster id: %s appears in two places %s and %s" %
                            (monster_id, monster_location,
                             self._ids[monster_id]))
                    else:
                        self._ids[monster_id] = monster_location

                    # save the id!
                    self.monster_id = monster_id

            elif tag == "monstertag":
                self.tags.append(child.text)

            elif tag == "monstermove":
                self.move = convert_str_to_int(child.text)

            elif tag == "monsterhealth":
                self.health = convert_str_to_int(child.text)

            elif tag == "monsterstamina":
                self.stamina = convert_str_to_int(child.text)

            elif tag == "monsterresolve":
                self.resolve = child.text
                print "set resolve pool to [%s]" % self.resolve
                #sys.exit()

            elif tag == "monstermagic":
                self.magic_pool = child.text

            elif tag == "monsteraspect":
                self.aspects.append(child.text)

            elif tag == "monsterinitiativebonus":
                self.initiative_bonus = convert_str_to_int(child.text)

            elif tag == "ac":
                self.ac = convert_str_to_int(child.text)

            elif tag == "strength":
                if self.strength is not None:
                    raise Exception(
                        "Only one strength per monster. (%s) %s\n" %
                        (child.tag, str(child)))
                else:
                    self.strength = convert_str_to_int(child.text)

            elif tag == "endurance":
                if self.endurance is not None:
                    raise Exception(
                        "Only one endurance per monster. (%s) %s\n" %
                        (child.tag, str(child)))
                else:
                    self.endurance = convert_str_to_int(child.text)

            elif tag == "agility":
                if self.agility is not None:
                    raise Exception("Only one agility per monster. (%s) %s\n" %
                                    (child.tag, str(child)))
                else:
                    self.agility = convert_str_to_int(child.text)

            elif tag == "speed":
                if self.speed is not None:
                    raise Exception("Only one speed per monster. (%s) %s\n" %
                                    (child.tag, str(child)))
                else:
                    self.speed = convert_str_to_int(child.text)

            elif tag == "luck":
                if self.luck is not None:
                    raise Exception("Only one luck per monster. (%s) %s\n" %
                                    (child.tag, str(child)))
                else:
                    self.luck = convert_str_to_int(child.text)

            elif tag == "willpower":
                if self.willpower is not None:
                    raise Exception(
                        "Only one strength per monster. (%s) %s\n" %
                        (child.tag, str(child)))
                else:
                    self.willpower = convert_str_to_int(child.text)

            elif tag == "perception":
                if self.perception is not None:
                    raise Exception(
                        "Only one perception per monster. (%s) %s\n" %
                        (child.tag, str(child)))
                else:
                    self.perception = convert_str_to_int(child.text)

            elif tag == "abilitylevelid":
                ability_level_id = child.text
                self.ability_level_ids.append(ability_level_id)

            elif tag == "monsterclass":
                self.monster_class = MonsterClass.load(child.text)
                if self.monster_class == MonsterClass.NONE:
                    raise Exception("Unknown monster class: (%s) %s in %s\n" %
                                    (child.tag, child.text, self.fname))

            elif tag == "monsterdescription":
                if self.description is not None:
                    raise Exception(
                        "Only one monsterdescription per monster. (%s) %s\n" %
                        (child.tag, str(child)))
                else:
                    #self.description = get_text(child)
                    #self.description = node_to_string(child)
                    self.description = children_to_string(child)

            elif tag is COMMENT:
                # ignore comments!
                pass

            else:
                raise Exception("UNKNOWN (%s) in file %s\n" %
                                (child.tag, self.fname))
        self.validate()
        return