Я думаю, что это не совсем возможно. Информация LaTeX больше не присутствует в PDF. Если заголовок отсутствует в метаданных, вы можете вывести заголовок из информации о структуре, если это «тегированный pdf». Однако большинство pdf-файлов этого не делают, и те, которые есть, в любом случае предоставят метаданные.
Это оставляет вас с анализом макета: попробуйте определить, какой заголовок документа, взглянув на характеристики макета. Для python вы можете взглянуть на pdfminer .
В следующем примере pdfminer используется для определения заголовка с использованием довольно упрощенного подхода:
- мы предполагаем, что заголовок находится где-то на первой странице
- мы оставляем pdfminer распознавать «блоки текста» на первой странице
- мы предполагаем, что заголовок напечатан «больше», чем остальная часть страницы. Рассматривая высоту каждой строки в текстовых блоках, мы определяем, какой блок содержит «самую высокую» строку, и предполагаем, что этот блок содержит заголовок
- мы позволяем pdfminer извлечь текст из блока,
- текст, вероятно, будет содержать новые строки (помещенные pdfminer), потому что заголовок может содержать более одной строки и другие ненужные пробелы, поэтому мы делаем некоторую простую нормализацию пробелов (заменяем последовательные пробелы одним пробелом и удаляем начальные и конечные пробел), и все!
Как я уже сказал: этот подход довольно упрощен и может дать или не дать хорошие результаты для ваших документов, но он может указать вам верное направление. Вот оно:
import sys
import re
from pdfminer.pdfparser import PDFParser, PDFDocument
from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter
from pdfminer.converter import PDFPageAggregator
from pdfminer.layout import LAParams, LTTextBox
filename = sys.argv[1]
fp = open(filename, 'rb')
parser = PDFParser(fp)
doc = PDFDocument()
parser.set_document(doc)
doc.set_parser(parser)
doc.initialize()
rsrcmgr = PDFResourceManager()
laparams = LAParams()
device = PDFPageAggregator(rsrcmgr, laparams=laparams)
interp = PDFPageInterpreter(rsrcmgr, device)
pages = doc.get_pages()
first_page = pages.next()
interp.process_page(first_page)
layout = device.get_result()
textboxes = [i for i in layout if isinstance(i, LTTextBox)]
box_with_tallest_line = max(textboxes, key=lambda x: max(i.height for i in x))
text = box_with_tallest_line.get_text()
print re.sub('\s+', ' ', text).strip()
Я оставлю переименование файла для вас (обратите внимание, что заголовок может содержать символы, которые вы, возможно, не хотите, или которые даже недействительны в именах файлов). Документация pdfminer в настоящее время довольно скудна, поэтому вы можете спросить в списке рассылки, если вам нужно узнать больше. (сам не очень разбираюсь в этом, но не удержался от попыток ;-)). Или вы можете попробовать подобный подход с другими библиотеками PDF / другими языками.