Compare commits

..

4 Commits

Author SHA1 Message Date
Alex
1f0c73e0c9 config vscode 2026-01-05 00:03:49 +01:00
Alex
17e0422fdf traduction de tout les paragraphes 2026-01-05 00:03:18 +01:00
Alex
9a0935c6e6 meilleurs gestion des paragraphes 2026-01-05 00:02:46 +01:00
Alex
4284cd357e Formattage des paragraphes 2026-01-04 23:31:20 +01:00
3 changed files with 27 additions and 39 deletions

4
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,4 @@
{
"python.formatting.provider": "black",
"python.pythonPath": "venv\\Scripts\\python.exe"
}

View File

@ -4,6 +4,7 @@ PARAMETER num_ctx 131072
SYSTEM """ SYSTEM """
You are a professional translator specialising in translating Ukrainian text into English. You are a professional translator specialising in translating Ukrainian text into English.
Translate accurately and naturally, respecting the original intonation used by the author of the text. Translate accurately and naturally, respecting the original intonation used by the author of the text.
You must always answer in french.
You must not interpret the author's thoughts or reflections. You must not interpret the author's thoughts or reflections.
Do not add any text before or after the text provided. Do not add any text before or after the text provided.
""" """

61
main.py
View File

@ -17,9 +17,6 @@ OLLAMA_URL = "http://localhost:11434/api/generate" # URL par défaut d'Ollama
TARGET_LANGUAGE = "français" # Langue cible (ex: "français", "anglais", "allemand", "espagnol", etc.) TARGET_LANGUAGE = "français" # Langue cible (ex: "français", "anglais", "allemand", "espagnol", etc.)
OUTPUT_PDF_PATH = PDF_PATH.replace(".pdf", f" ({TARGET_LANGUAGE.upper()[:2]}).pdf") # Chemin du PDF de sortie OUTPUT_PDF_PATH = PDF_PATH.replace(".pdf", f" ({TARGET_LANGUAGE.upper()[:2]}).pdf") # Chemin du PDF de sortie
# Prompt système personnalisé (instructions pour le LLM)
SYSTEM_PROMPT = """"""
def extract_parameters_from_template(template_str): def extract_parameters_from_template(template_str):
"""Extrait les paramètres du modèle à partir du template.""" """Extrait les paramètres du modèle à partir du template."""
import re import re
@ -132,47 +129,33 @@ def extract_text_from_pdf(pdf_path):
text_by_page.append(text) text_by_page.append(text)
return text_by_page return text_by_page
def merge_paragraphs_across_pages(pages_text): def split_pages_in_paragraphs(pages_text):
"""Divise le texte en chunks raisonnables pour la traduction.""" """
Divise le texte en paragraphes en détectant un point suivi d'un saut de ligne ou d'un retour à la ligne.
Conserve les sauts de ligne à l'intérieur des paragraphes.
"""
import re import re
# Concatène tout le texte # Concatène tout le texte
full_text = "\n".join(pages_text) full_text = "\n".join(pages_text)
# Essaie d'abord de diviser par les doubles sauts de ligne # Remplace les sauts de ligne à l'intérieur des paragraphes par des espaces
paragraphs = re.split(r'\n\s*\n+', full_text.strip()) # (pour éviter les sauts de ligne intempestifs dans un même paragraphe)
full_text = re.sub(r'(?<![.!?])\n+(?![.!?])', ' ', full_text)
# Si on obtient seulement un paragraphe, on divise par une taille maximale
if len(paragraphs) == 1: # Divise le texte en paragraphes : un point suivi d'un saut de ligne
print("Aucune séparation par double saut de ligne détectée. Division par taille...") paragraphs = re.split(r'(?<=[.!?])\s*\n+', full_text.strip())
# Divise par les phrases (points suivis d'un espace)
sentences = re.split(r'(?<=[.!?])\s+', full_text.strip()) # Nettoie chaque paragraphe : remplace les sauts de ligne restants par des espaces
paragraphs = [re.sub(r'\s+', ' ', p).strip() for p in paragraphs if p.strip()]
# Regroupe les phrases en chunks d'environ 1500 caractères
max_chunk_size = 1500
paragraphs = []
current_chunk = ""
for sentence in sentences:
if len(current_chunk) + len(sentence) < max_chunk_size:
current_chunk += (" " + sentence) if current_chunk else sentence
else:
if current_chunk:
paragraphs.append(current_chunk)
current_chunk = sentence
if current_chunk:
paragraphs.append(current_chunk)
else:
# Normalise les sauts de ligne internes
paragraphs = [re.sub(r'\n+', ' ', p.strip()) for p in paragraphs if p.strip()]
return paragraphs return paragraphs
def send_to_ollama(text, target_lang=TARGET_LANGUAGE, model=OLLAMA_MODEL, context_size=128000, system_prompt=SYSTEM_PROMPT):
def send_to_ollama(text, target_lang=TARGET_LANGUAGE, model=OLLAMA_MODEL, context_size=128000):
"""Envoie une requête à Ollama et retourne la réponse traduite.""" """Envoie une requête à Ollama et retourne la réponse traduite."""
# Construit le prompt avec les instructions système et la demande de traduction # Construit le prompt avec les instructions système et la demande de traduction
full_prompt = f"{system_prompt}\n\nTraduis le texte suivant de l'ukrainien vers le {target_lang} :\n{text}" full_prompt = f"\n\nTraduis le texte suivant de l'ukrainien vers le {target_lang} :\n{text}"
payload = { payload = {
"model": model, "model": model,
"prompt": full_prompt, "prompt": full_prompt,
@ -255,7 +238,7 @@ def create_pdf_from_results(results, output_path):
# Préserver la mise en page en convertissant les sauts de ligne # Préserver la mise en page en convertissant les sauts de ligne
formatted_text = translation.replace("\n", "<br/>") formatted_text = translation.replace("\n", "<br/>")
story.append(Paragraph(formatted_text, body_style)) story.append(Paragraph(formatted_text, body_style))
story.append(Spacer(1, 0.1*inch)) # story.append(Spacer(1, 0.1*inch))
# Infos sur le LLM # Infos sur le LLM
story.append(Spacer(1, 0.2*inch)) story.append(Spacer(1, 0.2*inch))
@ -274,7 +257,7 @@ def main():
print(f"Nombre de pages extraites : {len(pages)}") print(f"Nombre de pages extraites : {len(pages)}")
# Fusion des paragraphes qui s'étendent sur plusieurs pages # Fusion des paragraphes qui s'étendent sur plusieurs pages
paragraphs = merge_paragraphs_across_pages(pages) paragraphs = split_pages_in_paragraphs(pages)
print(f"Nombre de paragraphes complets extraits : {len(paragraphs)}") print(f"Nombre de paragraphes complets extraits : {len(paragraphs)}")
# Dictionnaire pour stocker les résultats # Dictionnaire pour stocker les résultats