import zipfile
import io


def process_text_in_zipfile(zf, process_file):
    """Process each file in a zip file using the `process_file` function.

    Returns a new zip file.

    `process_file` should be a function which accepts a filename and content as text
    and returns a (possibly modified) filename and content.  The file will be
    replaced with the new content, and renamed if necessary.

    Files with content that cannot be decoded as UTF-8 will be skipped.
    """

    new_zf = zipfile.ZipFile(io.BytesIO(), "w", zipfile.ZIP_DEFLATED)
    for name in zf.namelist():
        content = zf.read(name)
        try:
            content = content.decode("utf-8")
        except UnicodeDecodeError:
            # Probably a binary file; don't change it
            pass
        else:
            name, content = process_file(name, content)
        # writestr handles either bytes or text, and will implicitly encode text as utf-8
        new_zf.writestr(name, content)
    return new_zf