def _sub(self, txt):
        ### FIX ME: This needs serious refactoring... PLEASE

        # do per item substitution rather than entire txt to avoid variable
        # confusion.  Also allows us to call .capitalize, .lower, etc on the
        # string after substitution.
        for line in str(txt).split('\n'):
            for item in line.split(' '):
                # Not a template var? (generic pattern)
                pattern = "(.*)\%s(.*)\%s(.*)" % (
                            self.config['start_delimiter'],
                            self.config['end_delimiter'],
                            )

                if not re.match(pattern, item):
                    continue

                for key,value in sorted(self._vars.items()):
                    if key in self._word_map:
                        continue

                    pattern = "(.*)\%s(%s)\%s(.*)" % (
                        self.config['start_delimiter'],
                        key,
                        self.config['end_delimiter'],
                        )

                    m = re.match(pattern, item)
                    if m:
                        map_key = "%s%s%s" % (
                            self.config['start_delimiter'],
                            m.group(2),
                            self.config['end_delimiter'],
                            )
                        self._word_map[map_key] = str(value)
                    else:
                        pattern = "(.*)\%s(%s)\.([_a-z0-9]*)\%s(.*)" % (
                            self.config['start_delimiter'],
                            key,
                            self.config['end_delimiter'],
                            )
                        m = re.match(pattern, item)
                        if m:
                            # string method calls?
                            if len(m.group(3)) > 0:
                                if m.group(3) in ALLOWED_STR_METHODS:
                                    fixed = str(getattr(value, m.group(3))())
                                else:
                                    self.app.log.debug("str method '%s' not allowed." % m.group(3))
                                    fixed = str(value)
                            else:
                                fixed = str(value)

                            new_key = "%s%s.%s%s" % (
                                self.config['start_delimiter'],
                                m.group(2),
                                m.group(3),
                                self.config['end_delimiter'],
                                )
                            self._word_map[new_key] = fixed

        # actually replace the text
        new_txt = str(txt)
        for pattern,replacement in sorted(self._word_map.items()):
            new_txt = re.sub(pattern, replacement, new_txt)

        return new_txt
dataset/ETHPy150Open datafolklabs/boss/boss/cli/template.py/TemplateManager._sub/original