def from_file(cls, file): line_number = 1 rows = [] text = None with codecs.open(file, encoding='utf-8') as f: for line in f: if line_number == 1: identifier = line.strip() elif line_number == 2: parts = line.split(PART_SEPARATOR) dice_part = parts[0] if re.search(r"d\*", dice_part): dice = None else: dice = Dice.from_string(parts[0]) title = parts[1].strip() if len(parts) > 2: text = parts[2].strip() else: try: rows.append(RollTableRow.from_string(line.strip())) except MalformedRowError: rows.append( RollTableRow.from_string('{}{}{}'.format( line_number - 2, PART_SEPARATOR, line.strip()))) line_number += 1 if len(rows) == 0: raise Exception('Empty file: {}'.format('file')) if dice is None: dice = Dice([Die(len(rows))]) table = cls(dice, rows, title, text) return (identifier, table)
def evaluate_numeric(expression, mapping=None): if isinstance(expression, Roll): return expression.number if isinstance(expression, int): return expression match = re.search(r"\[\[(.*)(\s?\*(\d+))?\]\]", expression) if match: multiplier = None if match.group(3): multiplier = int(match.group(3)) return Dice.from_string(match.group(1)).roll(multiplier).number if mapping and type(expression) is str: match = re.search(r"@(\w+)", expression) if match: return evaluate_numeric(mapping[match.group(1)]) return int(expression)
def evaluate_text(self): text = self.text pattern = r"\[\[@(\w+) ([^\]*]*)(\s?\*(\d+))?\]\]" match = re.search(pattern, text) roll = None mapping = {} while match is not None: key = match.group(1) dice = Dice.from_string(match.group(2)) multiplier = None if match.group(4): multiplier = int(match.group(4)) roll = dice.roll(multiplier=multiplier) mapping[key] = roll sub = '({})'.format(roll) text = re.sub(pattern, sub, text, count=1) match = re.search(pattern, text) return (text, mapping)