File size: 4,287 Bytes
d9f69e5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dad3e66
d9f69e5
dbbb9be
dad3e66
d9f69e5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dad3e66
 
 
 
 
 
d9f69e5
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#!/usr/bin/env python

import os
import re
import tempfile
from pathlib import Path

import pdfplumber
import gradio as gr

def clean_text_for_rag(text: str) -> str:
    """Normalise et nettoie le texte pour un usage RAG."""
    # Normalisation des caractères typographiques
    text = re.sub(
        r"[’‘“”«»–—\u00A0\u202F…œŒæÆ©®™§°±×÷]",
        lambda m: {
            "’": "'", "‘": "'", "“": '"', "”": '"',
            "«": '"', "»": '"', "–": "-", "—": "-",
            "…": "...", "œ": "oe", "Œ": "OE",
            "æ": "ae", "Æ": "AE", "©": "(c)", "®": "(R)",
            "™": "TM", "§": "§", "°": "°", "±": "+/-",
            "×": "x", "÷": "/"
        }.get(m.group(0), m.group(0)),
        text,
    )
    # Conserver uniquement les caractères suivants
    text = re.sub(r'[^a-zA-ZÀ-ÿæ-œ0-9\s\.\,\:\;\!\?\-\_\'\"\\\(\)]', '', text)
    # Réduire les espaces multiples
    return re.sub(r'\s+', ' ', text).strip()


def extract_and_clean_pdf(pdf_path: str) -> str:
    """Ouvre le PDF, récupère le texte et le nettoie."""
    print(f"[+] Extraction du PDF : {pdf_path}")
    all_pages = []
    with pdfplumber.open(pdf_path) as pdf:
        for page in pdf.pages:
            txt = page.extract_text()
            if txt:
                all_pages.append(txt)
    return clean_text_for_rag(" ".join(all_pages))


def extract_and_clean_txt(txt_path: str) -> str:
    """Lit un fichier texte (txt, md, …) et le nettoie."""
    print(f"[+] Lecture du fichier texte : {txt_path}")
    with open(txt_path, "r", encoding="utf-8") as f:
        lines = f.readlines()
    cleaned = [
        clean_text_for_rag(line.strip())
        for line in lines
        if line.strip()
    ]
    return "\n".join(cleaned)

def process_file(input_file: gr.File, output_name: str) -> str:
    """
    - Detecte le type (PDF ou texte)
    - Effectue l'extraction + nettoyage
    - Crée un fichier temporaire **avec le nom choisi** (output_name)
    - Retourne le chemin du fichier temporaire (Gradio le propose en téléchargement)
    """
    input_path = input_file.name
    _, ext = os.path.splitext(input_path.lower())

    if ext == ".pdf":
        cleaned_text = extract_and_clean_pdf(input_path)
    else:
        cleaned_text = extract_and_clean_txt(input_path)

    output_name = output_name.strip()
    if not output_name.lower().endswith(".md"):
        output_name = f"{output_name}.md"

    temp_dir = tempfile.mkdtemp()          
    out_path = os.path.join(temp_dir, output_name)

    with open(out_path, "w", encoding="utf-8") as f:
        f.write(cleaned_text)

    return out_path

with gr.Blocks(title="Nettoyage de texte pour RAG") as demo:
    gr.Markdown("# 📄 Nettoyage d'un fichier pour utilisation RAG")
    gr.Markdown(
        "Déposez simplement votre fichier : nous nous chargeons d’extraire son contenu textuel, de le nettoyer "
        "puis de vous le restituer en format markdown **sous le nom que vous choisissez.**"
    )

    with gr.Row():
        with gr.Column(scale=1):
            input_file = gr.File(
                label="Déposez votre fichier ici",
                file_types=["pdf", "txt", "md", "file"],
            )
            output_name = gr.Textbox(
                value="output.md",
                label="Nom du fichier de sortie (en .md)",
                placeholder="exemple.md",
                interactive=True,
            )
            submit_btn = gr.Button("Traiter le fichier", variant="primary")
        with gr.Column(scale=1):
            output_file = gr.File(
                label="Fichier nettoyé (.md)",
                file_types=["md"],
            )

    submit_btn.click(
        fn=process_file,
        inputs=[input_file, output_name],
        outputs=output_file,
    )

    gr.Markdown(
        """
        ---
        **Prétraitements effectués :**
        - Suppression des symboles non imprimables et des caractères parasites  
        - Conservation des lettres (y compris accentuées), chiffres, espaces et ponctuation simple 
        - Normalisation des espaces pour un texte harmonieux  
        - Export automatique au format **`.md`**  
        
        """
    )

if __name__ == "__main__":
    demo.launch(share=True)