python-pptx: получение нечетных разбиений при извлечении текста из слайдов - PullRequest
0 голосов
/ 20 мая 2019

Я использую пример «Извлечь весь текст из слайдов в презентацию» по адресу https://python -pptx.readthedocs.io / en / latest / user / quickstart.html для извлечения текста из некоторых PowerPointслайды.

from pptx import Presentation

prs = Presentation(path_to_presentation)

# text_runs will be populated with a list of strings,
# one for each text run in presentation
text_runs = []

for slide in prs.slides:
    for shape in slide.shapes:
        if not shape.has_text_frame:
            continue
        for paragraph in shape.text_frame.paragraphs:
            for run in paragraph.runs:
                text_runs.append(run.text)

Кажется, все работает нормально, за исключением того, что я получаю нечетные разбиения в некоторых из text_runs.Вещи, которые, как я ожидал, будут сгруппированы, распадаются, и я не могу обнаружить очевидного паттерна.Например, иногда заголовок слайда разбивается на две части, а иногда это не

. Я обнаружил, что могу устранить нечетные разбиения, повторно набрав текст на слайде, но это не масштабирует.

Я не могу или, по крайней мере, не хочу объединять две части разделенного текста вместе, потому что иногда вторая часть текста объединяется с другим прогоном текста.Например, на титульном слайде слайда заголовок будет разделен на две части, а вторая часть заголовка объединена с текстом субтитров титульного слайда.

Любые предложения по устранению нечетных / нежелательных разбиений?Или такое поведение более или менее следует ожидать при чтении текста из PowerPoint?

1 Ответ

1 голос
/ 20 мая 2019

Я бы сказал, что это определенно следовало ожидать. PowerPoint будет разбивать прогоны в любое удобное время, например, чтобы выделить слово с ошибкой, или просто, если вы приостановите ввод или войдете, чтобы исправить опечатку или что-то в этом роде.

Единственное, что можно точно сказать о серии, это то, что все содержащиеся в ней символы имеют одинаковое форматирование символов. Например, нет никакой гарантии, что цикл - это то, что можно назвать «жадным», включая столько символов, сколько возможно, чтобы do использовали одинаковое форматирование символов.

Если вы хотите восстановить эту «жадную» последовательность в прогонах, вам решать, возможно, с помощью алгоритма, подобного следующему:

last_run = None
for run in paragraph.runs:
    if last_run is None:
        last_run = run
        continue
    if has_same_formatting(run, last_run):
        last_run = combine_runs(last_run, run)
        continue
    last_run = run

Это оставляет вам возможность реализовать has_same_formatting() и combine_runs(). Здесь есть определенное преимущество, потому что прогоны могут содержать различия, которые вас не волнуют, например, грязный атрибут или что-то еще, и вы можете выбирать, какие из них важны для вас.

Начало реализации has_same_formatting() будет:

def has_same_formatting(run, run_2):
    font, font_2 = run.font, run_2.font
    if font.bold != font_2.bold:
        return False
    if font.italic != font_2.italic:
        return False
    # ---same with color, size, type-face, whatever you want---
    return True

combine_runs(base, suffix) будет выглядеть примерно так:

def combine_runs(base, suffix):
    base.text = base.text + suffix.text
    r_to_remove = suffix._r
    r_to_remove.getparent().remove(r_to_remove)
...