Generate EDTF string equivalent of a given natural language date string.

def text_to_edtf(text):
    """
    Generate EDTF string equivalent of a given natural language date string.
    """
    if not text:
        return

    t = text.lower()

    # try parsing the whole thing
    result = text_to_edtf_date(t)

    if not result:
        # split by list delims and move fwd with the first thing that returns a non-empty string.
        # TODO: assemble multiple dates into a {} or [] structure.
        for split in [",", ";", "or"]:
            for list_item in t.split(split):

                # try parsing as an interval - split by '-'
                toks = list_item.split("-")
                if len(toks) == 2:
                    d1 = toks[0].strip()
                    d2 = toks[1].strip()

                    # match looks from the beginning of the string, search
                    # looks anywhere.

                    if re.match(r'\d\D\b', d2):  # 1-digit year partial e.g. 1868-9
                        if re.search(r'\b\d\d\d\d$', d1):  # TODO: evaluate it and see if it's a year
                            d2 = d1[-4:-1] + d2
                    elif re.match(r'\d\d\b', d2):  # 2-digit year partial e.g. 1809-10
                        if re.search(r'\b\d\d\d\d$', d1):
                            d2 = d1[-4:-2] + d2
                    else:
                        century_range_match = re.search(r'\b(\d\d)(th|st|nd|rd|)-(\d\d)(th|st|nd|rd) [cC]', "%s-%s" % (d1,d2))
                        if century_range_match:
                            g = century_range_match.groups()
                            d1 = "%sC" % g[0]
                            d2 = "%sC" % g[2]

                    r1 = text_to_edtf_date(d1)
                    r2 = text_to_edtf_date(d2)

                    if r1 and r2:
                        result = r1 + "/" + r2
                        return result

                # is it an either/or year "1838/1862" - that has a different
                # representation in EDTF. If it's 'both', then we use {}. If
                # it's 'or' then we use []. Assuming the latter for now.
                # This whole section could be more friendly.

                else:
                    int_match = re.search(r"(\d\d\d\d)\/(\d\d\d\d)", list_item)
                    if int_match:
                        return "[%s, %s]" % (int_match.group(1), int_match.group(2))

                result = text_to_edtf_date(list_item)
                if result:
                    break
            if result:
                break

    is_before = re.findall(r'\bbefore\b', t)
    is_before = is_before or re.findall(r'\bearlier\b', t)

    is_after = re.findall(r'\bafter\b', t)
    is_after = is_after or re.findall(r'\bsince\b', t)
    is_after = is_after or re.findall(r'\blater\b', t)

    if is_before:
        result = u"unknown/%s" % result
    elif is_after:
        result = u"%s/unknown" % result

    return result