Use the txtwrite device to get text layout information out

    For details on options of -dTextFormat see
    https://www.ghostscript.com/doc/current/VectorDevices.htm#TXT

    Format is like
    <page>
    <line>
    <span bbox="left top right bottom" font="..." size="...">
    <char bbox="...." c="X"/>

    :param pageno: number of page to extract, or all pages if None
    :return: XML-ish text representation in bytes

def extract_text(input_file, pageno=1):
    """Use the txtwrite device to get text layout information out

    For details on options of -dTextFormat see
    https://www.ghostscript.com/doc/current/VectorDevices.htm#TXT

    Format is like
    <page>
    <line>
    <span bbox="left top right bottom" font="..." size="...">
    <char bbox="...." c="X"/>

    :param pageno: number of page to extract, or all pages if None
    :return: XML-ish text representation in bytes
    """

    if pageno is not None:
        pages = ['-dFirstPage=%i' % pageno, '-dLastPage=%i' % pageno]
    else:
        pages = []

    args_gs = (
        [
            'gs',
            '-dQUIET',
            '-dSAFER',
            '-dBATCH',
            '-dNOPAUSE',
            '-sDEVICE=txtwrite',
            '-dTextFormat=0',
        ]
        + pages
        + ['-o', '-', fspath(input_file)]
    )

    p = run(args_gs, stdout=PIPE, stderr=PIPE)
    if p.returncode != 0:
        raise SubprocessOutputError(
            'Ghostscript text extraction failed\n%s\n%s\n%s'
            % (input_file, p.stdout.decode(), p.stderr.decode())
        )

    return p.stdout