1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

PDF(Canvaのスライド)からMarkdown(Marp)への変換スクリプト(生成AIを使ってスライドを作成する人向け)

Posted at

概要

PDFファイルをMarp形式のMarkdownに変換するPythonスクリプトを作成しました。このスクリプトは、PDFからテキストを抽出し、適切なMarkdown形式に整形して保存します。

モチベーション

生成AIを使ってスライドを作成する際の利便性を向上させるために、このスクリプトを開発しました。多くのスライドはCanvaを使って作成されており、過去のスライドの文言やチャート(図解や絵)を再利用して新しいスライドを作成したいと考えています。

課題

さまざまな生成AIを試しましたが、1ファイルが25MBを超えると読み込めなかったり、解析に時間がかかる割に認識率が低いという問題がありました。Canvaのスライドのレイアウトを再現することは難しく、手作業でひとつひとつ入力するのは避けたいと考え、このツールを作成しました。

解決策

このスクリプトを使うことで、PDFからテキストを抽出し、Marp形式のMarkdownに変換することができます。これにより、手作業での入力を減らし、効率的にスライドを作成することが可能です。

補足

本記事では、CanvaからMarkdownへの変換について説明していますが、逆にMarp CLIを使ってPDF出力し、そのPDFをCanvaで読み込ませることも可能です。


このような形でいかがでしょうか?他に修正や追加が必要な点があれば教えてくださいね。

最終的なコード

import os
import re
import sys
import glob
from PyPDF2 import PdfReader

def extract_text_from_pdf(pdf_file):
    text = []
    with open(pdf_file, 'rb') as file:
        reader = PdfReader(file)
        for page in reader.pages:
            text.append(page.extract_text())
    return text

def clean_and_format_markdown(content):
    # 重複行の削除
    lines = content.split('\n')
    unique_lines = []
    for line in lines:
        if not unique_lines or line != unique_lines[-1]:
            unique_lines.append(line)
    content = '\n'.join(unique_lines)
    
    # 見出しの設定
    content = re.sub(r'^#\s', '## ', content, flags=re.MULTILINE)
    
    # レイアウトの改善
    content = re.sub(r'^▶', '- ', content, flags=re.MULTILINE)
    content = re.sub(r'^●', '### ', content, flags=re.MULTILINE)
    
    return content

def convert_pdf_to_marp(pdf_file):
    base_name = os.path.splitext(pdf_file)[0]
    md_file = f"{base_name}.md"

    try:
        # PDFからテキストを抽出
        extracted_text = extract_text_from_pdf(pdf_file)
        
        # Marpのフロントマター
        marp_content = "---\nmarp: true\ntheme: default\n---\n\n"
        
        # 各ページを処理
        for page_text in extracted_text:
            cleaned_text = clean_and_format_markdown(page_text)
            marp_content += cleaned_text + "\n\n---\n\n"  # ページ区切りを追加
        
        # 変更を保存
        with open(md_file, "w", encoding="utf-8") as file:
            file.write(marp_content)

        print(f"Converted {pdf_file} to {md_file}")
    except Exception as e:
        print(f"Unexpected error occurred while processing {pdf_file}: {e}")

def main():
    if len(sys.argv) > 1:
        pdf_files = sys.argv[1:]
    else:
        pdf_files = glob.glob("*.pdf")
    
    if not pdf_files:
        print("No PDF files found or specified.")
        return

    for file in pdf_files:
        if os.path.isfile(file) and file.lower().endswith('.pdf'):
            convert_pdf_to_marp(file)
        else:
            print(f"Skipping {file}: Not a valid PDF file.")

if __name__ == "__main__":
    main()

使用手順

  1. 必要なライブラリのインストール:

    pip install PyPDF2
    
  2. スクリプトを適当な名前(例:pdf_to_marp.py)で保存します。

  3. コマンドラインで、スクリプトが保存されているディレクトリに移動します。

  4. 以下のコマンドを実行して、PDFファイルをMarp形式のMarkdownに変換します:

    • 特定のPDFファイルを変換する場合:
      python pdf_to_marp.py path/to/your/file.pdf
      
    • カレントディレクトリ内のすべてのPDFファイルを変換する場合:
      python pdf_to_marp.py
      
  5. 変換が完了すると、入力PDFファイルと同じ名前で.md拡張子のファイルが生成されます。

  6. 生成されたMarkdownファイルをMarp対応のエディタ(例:VS Code with Marp extension)で開いて確認し、必要に応じて手動で調整します。

Pandocを使った試行錯誤の過程

  1. 最初のアプローチ:
    当初、PDFからMarkdownへの変換にPandocを使用しようとしました。以下のようなコマンドを試みました:

    pandoc -f pdf -t markdown input.pdf -o output.md
    

    しかし、このアプローチは「Unknown input format pdf」というエラーで失敗しました。

  2. 中間フォーマットの使用:
    次に、PDFをテキストに変換してから、そのテキストをMarkdownに変換する2段階のプロセスを試みました:

    pdftotext input.pdf temp.txt
    pandoc -f plain -t markdown temp.txt -o output.md
    

    これは部分的に機能しましたが、PDFの構造が失われ、結果が理想的ではありませんでした。

  3. 入力フォーマットの指定:
    Pandocの入力フォーマットとして plaintext を指定しましたが、これらは直接サポートされていないことがわかりました。

  4. Markdownとして扱う:
    最後に、入力を直接Markdownとして扱うことを試みました:

    pandoc -f markdown -t markdown input.txt -o output.md
    

    これは機能しましたが、PDFの構造やフォーマットを適切に保持できませんでした。

  5. 結論:
    これらの試行錯誤を経て、Pandocは本ケースでは最適なツールではないと判断しました。PDFの構造を保持し、Marp形式に適したMarkdownを生成するには、カスタムのPythonスクリプトを作成する方が効果的であることがわかりました。

この過程を経て、最終的に上記のPythonスクリプトを開発し、PDFからMarp形式のMarkdownへの直接変換を実現しました。このアプローチにより、PDFの構造をより適切に保持し、Marpに適したフォーマットを生成することができました。

生成AIの使用

  • Perplexity(CLAUDE 3.5 SONNET)とMicrosoft Copilot(Microsoft 365等ライセンス支払いなし、無料)を使用して作成しました
  • なお、開発・実行環境はMicrosoft Windows 11を搭載するPC上です
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?