def parse_ethnicity(wikicode: mwp.wikicode.Wikicode):
            wikicode = parse_markup(wikicode)
            wikicode_elements = wikicode.filter(forcetype=(Template, Wikilink))
            if " and " in wikicode:
                wikicode.replace(" and ", ", ")

            if not wikicode_elements:
                ethnicity = wikicode.strip_code().strip().title()
            else:
                for wc in wikicode_elements:
                    if isinstance(wc, Wikilink):
                        wikicode.replace(wc, wc.title.strip_code().strip())
                    elif isinstance(wc, Template):
                        params = tuple(
                            p
                            for p in (
                                p.name.strip_code()
                                if p.showkey is True
                                else p.value.strip_code()
                                for p in wc.params
                            )
                            if p != "cat"
                        )
                        if len(params) == 1:
                            wikicode.replace(wc, params[0])
                        elif "Noble" in params or "noble" in params:
                            wikicode.replace(wc, "Noble")
                        else:
                            wikicode.replace(wc, params)
                ethnicity = wikicode.strip_code().strip().title()

            if ethnicity == "Skaa, Noble":
                ethnicity = "Half-Skaa"
            return ethnicity
        def parse_residence(wikicode: mwp.wikicode.Wikicode):
            wikicode = parse_markup(wikicode)
            wikicode_elements = wikicode.filter(forcetype=(Template, Wikilink))
            if "<br>" in wikicode:
                wikicode.replace("<br>", ", ")
            if not wikicode_elements:
                residence = wikicode.strip_code().strip()
            else:
                for wc in wikicode_elements:
                    if isinstance(wc, Wikilink):
                        wikicode.replace(wc, wc.title.strip_code().strip().title())
                    elif isinstance(wc, Template):
                        params = tuple(
                            p
                            for p in (
                                p.name.strip_code()
                                if p.showkey is True
                                else p.value.strip_code()
                                for p in wc.params
                            )
                            if p != "cat"
                        )
                        if len(params) == 1:
                            wikicode.replace(wc, params[0])
                        else:
                            wikicode.replace(wc, params)
                residence = wikicode.strip_code().strip()

            residence = re.sub(r"\s?\([\w\s]+\)", "", residence)
            # special cases
            if residence.startswith("15 Stranat Place"):
                residence = "Elendel"
            return residence
        def parse_names(wikicode: mwp.wikicode.Wikicode):
            wikicode = parse_markup(wikicode)
            for t in wikicode.filter(forcetype=Template):
                if len(t.params) == 1:
                    wikicode.replace(t, t.params[0])
                elif len(t.params) > 1:
                    if "highprince" in t.params[0].lower():
                        wikicode.replace(t, "{0} of {1}".format(*t.params))
                    elif "army" in t.params[0].lower():
                        wikicode.replace(t, "{1} {0}".format(*t.params))

            return [
                n for n in (n.strip() for n in wikicode.strip_code().split(",")) if n
            ]
        def parse_abilities(wikicode: mwp.wikicode.Wikicode):
            wikicode = parse_markup(wikicode)
            abilities = []
            for wc in wikicode.filter(forcetype=(Template, Wikilink)):
                if isinstance(wc, Template):
                    if "tag" in wc.name:
                        params = tuple(
                            p.lower()
                            for p in (
                                p.name.strip_code()
                                if p.showkey is True
                                else p.value.strip_code()
                                for p in wc.params
                            )
                            if p != "cat"
                        )

                        if len(params) == 1:
                            abilities.append(params[0])
                        elif len(params) > 1:
                            if any(
                                params[0] == s for s in ("shard", "vessel", "splinter")
                            ):
                                abilities.extend(
                                    (params[0], f"{params[0]} of {params[1]}")
                                )
                            elif params[0] == "squire":
                                abilities.append(f"squire ({params[1].split()[-1]})")
                            else:
                                print(
                                    "unknown ability while parsing character: ", params
                                )

                elif isinstance(wc, Wikilink):
                    abilities.append(wc.title.strip_code().lower())

            return abilities