Capitalize text which includes text tags

The point of this script is to capitalize all the letters in a string, a string which includes Ren'Py text tags. It will work for the vast majority of cases, possibly failing at ones that have stacked curled brackets.

You cannot simply use .upper(), as that will capitalize the tags, too, and they won't work properly. Under the script, there is an explanation of how the script works, as well as a download link for those who do not want to copy paste (but spoiler alert: it's faster).

# Capitalizes given string, while keeping tags untouched.
def capitalizeWithTags(ourString):

    newString = ""

    # Inside tag serves as an indicator, whether we're currently
    # iterating over a tag.
    insideTag = False

    # Iterates over characters in our string.
    for char in ourString:

        # Checks for end of a tag
        if insideTag and char == "}":
            insideTag = False

        # Inside the tag, a regular character.
        # It's a part of the tag, so we leave it just the way it is.
        elif insideTag:
            pass

        # Checks for beginning of a tag
        elif char == "{":
            insideTag = True

        # It's a regular character
        else:
            char = char.upper()

        # Appends the character to the new string
        newString += char

    # Optionally changing a Ren'Py global variable.
    # store.myVar = newString

    # Returning it if needed.
    return newString

I will now explain how the script works.

First, we set up an empty string variable newString, into which we'll copy checked characters. There's also the insideTag variable, which keeps check of whether current character is part of a tag or not.

We'll be iterating over all the characters provided in the argument ourString with the help of a for loop. The loop checks a character and does one of four actions, about which I'll talk about in a different order than they are written. It will make more sense that way, however, for the right functionality, we need the order I've chosen. This is because, for example, we want to check for an end of a tag before checking for a beginning of a new one.

        # Checks for beginning of a tag
        elif char == "{":
            insideTag = True

This one checks for the beginning of a tag. Our script finds it, of course, by finding an opening bracket. If it finds it, a tag follows, and so it sets insideTag to be True.

        # Inside the tag, a regular character.
        # It's a part of the tag, so we leave it just the way it is.
        elif insideTag:
            pass

This one happens when insideTag is True and the current character is not a bracket. In this case, we're just keeping the character as it is, as it needs to stay lowercase.

        # Checks for end of a tag
        if insideTag and char == "}":
            insideTag = False

This one checks for the end of a tag. It's done by looking for a closing bracket, in the same way the script checks for an opening bracket.

        # It's a regular character
        else:
            char = char.upper()

Finally, if neither of these cases passed, it is deemed to be a regular character, which we can capitalize. So we do that.

        # Appends the character to the new string
        newString += char

And at the very end, we append the current character to newString. The character remains the same in the first three cases, only in the else branch it is uppercase'd first.

And after the for loop is done doing it's thing, we just return the result.