update folder script
This commit is contained in:
parent
1713aa30b5
commit
da06022b56
20 changed files with 573 additions and 95 deletions
79
CORRECTIONS_ENHANCEMENTS.md
Normal file
79
CORRECTIONS_ENHANCEMENTS.md
Normal file
|
@ -0,0 +1,79 @@
|
|||
# Améliorations du système de corrections
|
||||
|
||||
Ce document décrit les améliorations apportées au système de correction orthographique et grammaticale.
|
||||
|
||||
## Fonctionnalités ajoutées
|
||||
|
||||
### 1. Contexte étendu des erreurs
|
||||
|
||||
Le système affiche maintenant plus de contexte autour des erreurs détectées, ce qui facilite la compréhension du problème et la prise de décision pour la correction.
|
||||
|
||||
- **Contexte standard** : La ligne contenant l'erreur
|
||||
- **Contexte étendu** : Les lignes précédente et suivante, en plus de la ligne contenant l'erreur
|
||||
|
||||
Cette amélioration permet de voir l'erreur dans son contexte plus large, ce qui est particulièrement utile pour les erreurs grammaticales qui peuvent dépendre du contexte.
|
||||
|
||||
### 2. Corrections personnalisées
|
||||
|
||||
Une nouvelle fonctionnalité permet d'entrer des corrections personnalisées au lieu de se limiter aux suggestions automatiques.
|
||||
|
||||
- Chaque erreur dispose maintenant d'un champ de saisie pour entrer une correction personnalisée
|
||||
- Un bouton "Appliquer" permet d'envoyer cette correction au serveur
|
||||
- La touche Entrée dans le champ de saisie applique également la correction
|
||||
|
||||
Cette fonctionnalité offre plus de flexibilité pour corriger les erreurs, notamment lorsque les suggestions automatiques ne sont pas satisfaisantes.
|
||||
|
||||
### 3. Gestion améliorée des dépendances
|
||||
|
||||
Le système gère maintenant gracieusement l'absence des modules de vérification orthographique et grammaticale.
|
||||
|
||||
- Détection automatique de la disponibilité des modules `spellchecker` et `language_tool_python`
|
||||
- Messages d'avertissement clairs lorsque les modules ne sont pas disponibles
|
||||
- Fonctionnement dégradé mais sans erreur en l'absence des modules
|
||||
|
||||
Cette amélioration rend le système plus robuste et évite les erreurs fatales lorsque les dépendances ne sont pas installées.
|
||||
|
||||
## Modifications techniques
|
||||
|
||||
### Fichiers modifiés
|
||||
|
||||
1. **analyse_orthographe_grammaire.py**
|
||||
- Ajout de la détection des modules disponibles
|
||||
- Extraction de contexte étendu pour les erreurs orthographiques et grammaticales
|
||||
- Gestion des erreurs pour éviter les plantages
|
||||
|
||||
2. **generate_corrections_page.py**
|
||||
- Mise à jour du parser pour extraire le contexte étendu
|
||||
- Ajout des champs de saisie pour les corrections personnalisées
|
||||
- Mise à jour du CSS pour styliser les nouveaux éléments
|
||||
|
||||
3. **CSS et JavaScript**
|
||||
- Nouveaux styles pour le contexte étendu et les champs de correction personnalisée
|
||||
- Nouvelle fonction JavaScript `applyCustomCorrection` pour gérer les corrections personnalisées
|
||||
- Gestion des événements pour les champs de saisie (touche Entrée)
|
||||
|
||||
## Utilisation
|
||||
|
||||
Pour utiliser ces nouvelles fonctionnalités :
|
||||
|
||||
1. Exécutez `python analyse_orthographe_grammaire.py` pour générer le rapport d'erreurs
|
||||
2. Exécutez `python generate_corrections_page.py` pour générer la page de corrections
|
||||
3. Lancez le serveur Flask avec `python app.py`
|
||||
4. Accédez à http://localhost:5000/build/corrections.html dans votre navigateur
|
||||
|
||||
Sur la page de corrections :
|
||||
- Utilisez les onglets pour naviguer entre les erreurs orthographiques et grammaticales
|
||||
- Cliquez sur les boutons de suggestion pour appliquer une correction suggérée
|
||||
- Utilisez le champ de saisie personnalisée pour entrer votre propre correction
|
||||
- Cliquez sur "Ignorer cette erreur" pour ignorer une erreur
|
||||
- Pour les erreurs orthographiques, vous pouvez également ajouter le mot au dictionnaire personnalisé
|
||||
|
||||
## Dépendances
|
||||
|
||||
Pour profiter de toutes les fonctionnalités, assurez-vous d'installer les modules suivants :
|
||||
|
||||
```bash
|
||||
pip install pyspellchecker language-tool-python
|
||||
```
|
||||
|
||||
Le système fonctionnera même sans ces modules, mais ne détectera pas les erreurs.
|
0
analyse_frequence_mots.py
Normal file → Executable file
0
analyse_frequence_mots.py
Normal file → Executable file
0
analyse_intrigues.py
Normal file → Executable file
0
analyse_intrigues.py
Normal file → Executable file
131
analyse_orthographe_grammaire.py
Normal file → Executable file
131
analyse_orthographe_grammaire.py
Normal file → Executable file
|
@ -15,8 +15,21 @@ import re
|
|||
import os
|
||||
import csv
|
||||
import argparse
|
||||
|
||||
# Vérifier si les modules nécessaires sont disponibles
|
||||
try:
|
||||
import language_tool_python
|
||||
LANGUAGE_TOOL_AVAILABLE = True
|
||||
except ImportError:
|
||||
print("AVERTISSEMENT: Module language_tool_python non disponible. La vérification grammaticale sera désactivée.")
|
||||
LANGUAGE_TOOL_AVAILABLE = False
|
||||
|
||||
try:
|
||||
from spellchecker import SpellChecker
|
||||
SPELLCHECKER_AVAILABLE = True
|
||||
except ImportError:
|
||||
print("AVERTISSEMENT: Module spellchecker non disponible. La vérification orthographique sera désactivée.")
|
||||
SPELLCHECKER_AVAILABLE = False
|
||||
|
||||
# Définir les arguments en ligne de commande
|
||||
parser = argparse.ArgumentParser(description='Analyser les fautes d\'orthographe et de grammaire dans un fichier Org-mode.')
|
||||
|
@ -94,6 +107,12 @@ def check_spelling(text, lang='fr', custom_dict_path='dictionnaire_personnalise.
|
|||
Vérifie l'orthographe d'un texte et retourne les mots mal orthographiés.
|
||||
Utilise un dictionnaire personnalisé pour exclure certains mots de la vérification.
|
||||
"""
|
||||
# Vérifier si le module spellchecker est disponible
|
||||
if not SPELLCHECKER_AVAILABLE:
|
||||
print("Vérification orthographique désactivée car le module spellchecker n'est pas disponible.")
|
||||
return []
|
||||
|
||||
try:
|
||||
spell = SpellChecker(language=lang)
|
||||
|
||||
# Charger le dictionnaire personnalisé
|
||||
|
@ -110,7 +129,7 @@ def check_spelling(text, lang='fr', custom_dict_path='dictionnaire_personnalise.
|
|||
misspelled = spell.unknown(words)
|
||||
|
||||
# Créer un dictionnaire avec les mots mal orthographiés et leurs suggestions
|
||||
spelling_errors = {}
|
||||
spelling_errors = []
|
||||
for word in misspelled:
|
||||
# Vérifier si le mot est dans le dictionnaire personnalisé
|
||||
if word in custom_words:
|
||||
|
@ -121,14 +140,53 @@ def check_spelling(text, lang='fr', custom_dict_path='dictionnaire_personnalise.
|
|||
# Limiter à 5 suggestions maximum
|
||||
suggestions_list = list(suggestions) if suggestions is not None else []
|
||||
suggestions_list = suggestions_list[:5]
|
||||
spelling_errors[word] = suggestions_list
|
||||
|
||||
# Trouver toutes les occurrences du mot dans le texte original
|
||||
for match in re.finditer(r'\b' + re.escape(word) + r'\b', text, re.IGNORECASE):
|
||||
# Extraire le contexte autour du mot
|
||||
word_start = match.start()
|
||||
word_end = match.end()
|
||||
|
||||
# Trouver les limites des lignes contenant le mot
|
||||
line_start = text.rfind('\n', 0, word_start) + 1 if text.rfind('\n', 0, word_start) >= 0 else 0
|
||||
line_end = text.find('\n', word_end) if text.find('\n', word_end) >= 0 else len(text)
|
||||
|
||||
# Extraire les lignes précédentes et suivantes pour plus de contexte
|
||||
prev_line_start = text.rfind('\n', 0, line_start - 1) + 1 if text.rfind('\n', 0, line_start - 1) >= 0 else 0
|
||||
next_line_end = text.find('\n', line_end + 1) if text.find('\n', line_end + 1) >= 0 else len(text)
|
||||
|
||||
# Créer le contexte standard et étendu
|
||||
context = text[line_start:line_end]
|
||||
extended_context = text[prev_line_start:next_line_end]
|
||||
|
||||
# Calculer les offsets pour les contextes
|
||||
context_offset = word_start - line_start
|
||||
extended_offset = word_start - prev_line_start
|
||||
|
||||
spelling_errors.append({
|
||||
'word': word,
|
||||
'context': context,
|
||||
'extended_context': extended_context,
|
||||
'context_offset': context_offset,
|
||||
'extended_offset': extended_offset,
|
||||
'suggestions': suggestions_list
|
||||
})
|
||||
|
||||
return spelling_errors
|
||||
except Exception as e:
|
||||
print(f"Erreur lors de la vérification orthographique: {str(e)}")
|
||||
return []
|
||||
|
||||
def check_grammar(text, lang='fr'):
|
||||
"""
|
||||
Vérifie la grammaire d'un texte et retourne les erreurs grammaticales.
|
||||
"""
|
||||
# Vérifier si le module language_tool_python est disponible
|
||||
if not LANGUAGE_TOOL_AVAILABLE:
|
||||
print("Vérification grammaticale désactivée car le module language_tool_python n'est pas disponible.")
|
||||
return []
|
||||
|
||||
try:
|
||||
# Initialiser l'outil de vérification grammaticale
|
||||
tool = language_tool_python.LanguageTool(lang)
|
||||
|
||||
|
@ -142,11 +200,31 @@ def check_grammar(text, lang='fr'):
|
|||
if match.ruleId.startswith('MORFOLOGIK_RULE'):
|
||||
continue
|
||||
|
||||
# Extraire plus de contexte autour de l'erreur
|
||||
error_start = match.offset
|
||||
error_end = match.offset + match.errorLength
|
||||
|
||||
# Trouver les limites des lignes contenant l'erreur
|
||||
line_start = text.rfind('\n', 0, error_start) + 1 if text.rfind('\n', 0, error_start) >= 0 else 0
|
||||
line_end = text.find('\n', error_end) if text.find('\n', error_end) >= 0 else len(text)
|
||||
|
||||
# Extraire les lignes précédentes et suivantes pour plus de contexte
|
||||
prev_line_start = text.rfind('\n', 0, line_start - 1) + 1 if text.rfind('\n', 0, line_start - 1) >= 0 else 0
|
||||
next_line_end = text.find('\n', line_end + 1) if text.find('\n', line_end + 1) >= 0 else len(text)
|
||||
|
||||
# Créer le contexte étendu
|
||||
extended_context = text[prev_line_start:next_line_end]
|
||||
|
||||
# Ajuster les offsets pour le contexte étendu
|
||||
extended_offset = error_start - prev_line_start
|
||||
|
||||
error = {
|
||||
'message': match.message,
|
||||
'context': match.context,
|
||||
'extended_context': extended_context,
|
||||
'suggestions': match.replacements,
|
||||
'offset': match.offset,
|
||||
'extended_offset': extended_offset,
|
||||
'length': match.errorLength,
|
||||
'rule': match.ruleId
|
||||
}
|
||||
|
@ -156,6 +234,9 @@ def check_grammar(text, lang='fr'):
|
|||
tool.close()
|
||||
|
||||
return grammar_errors
|
||||
except Exception as e:
|
||||
print(f"Erreur lors de la vérification grammaticale: {str(e)}")
|
||||
return []
|
||||
|
||||
def generate_error_report(chapters, output_path):
|
||||
"""
|
||||
|
@ -183,9 +264,39 @@ def generate_error_report(chapters, output_path):
|
|||
# Écrire les erreurs d'orthographe
|
||||
report_file.write("### Erreurs d'orthographe\n\n")
|
||||
if spelling_errors:
|
||||
for word, suggestions in spelling_errors.items():
|
||||
suggestions_str = ", ".join(suggestions) if suggestions else "Aucune suggestion"
|
||||
# Regrouper les erreurs par mot
|
||||
errors_by_word = {}
|
||||
for error in spelling_errors:
|
||||
word = error['word']
|
||||
if word not in errors_by_word:
|
||||
errors_by_word[word] = {
|
||||
'suggestions': error['suggestions'],
|
||||
'occurrences': []
|
||||
}
|
||||
errors_by_word[word]['occurrences'].append({
|
||||
'context': error['context'],
|
||||
'extended_context': error['extended_context'],
|
||||
'context_offset': error['context_offset'],
|
||||
'extended_offset': error['extended_offset']
|
||||
})
|
||||
|
||||
# Écrire les erreurs regroupées par mot
|
||||
for word, data in errors_by_word.items():
|
||||
suggestions_str = ", ".join(data['suggestions']) if data['suggestions'] else "Aucune suggestion"
|
||||
report_file.write(f"- **{word}**: {suggestions_str}\n")
|
||||
|
||||
# Ajouter les contextes pour chaque occurrence
|
||||
for i, occurrence in enumerate(data['occurrences']):
|
||||
# Mettre en évidence le mot dans le contexte
|
||||
context = occurrence['context']
|
||||
offset = occurrence['context_offset']
|
||||
highlighted_context = context[:offset] + f"**{word}**" + context[offset+len(word):]
|
||||
|
||||
# Ajouter le contexte étendu
|
||||
extended_context = occurrence['extended_context']
|
||||
report_file.write(f" - **Occurrence {i+1}**:\n")
|
||||
report_file.write(f" - **Contexte**: {highlighted_context}\n")
|
||||
report_file.write(f" - **Contexte étendu**: ```\n{extended_context}\n```\n")
|
||||
else:
|
||||
report_file.write("Aucune erreur d'orthographe détectée.\n")
|
||||
|
||||
|
@ -194,12 +305,20 @@ def generate_error_report(chapters, output_path):
|
|||
# Écrire les erreurs grammaticales
|
||||
report_file.write("### Erreurs grammaticales\n\n")
|
||||
if grammar_errors:
|
||||
for error in grammar_errors:
|
||||
for i, error in enumerate(grammar_errors):
|
||||
suggestions_str = ", ".join(error['suggestions'][:5]) if error['suggestions'] else "Aucune suggestion"
|
||||
|
||||
# Mettre en évidence l'erreur dans le contexte
|
||||
context = error['context'].replace(error['context'][error['offset']:error['offset']+error['length']],
|
||||
f"**{error['context'][error['offset']:error['offset']+error['length']]}**")
|
||||
report_file.write(f"- **Erreur**: {error['message']}\n")
|
||||
|
||||
report_file.write(f"- **Erreur {i+1}**: {error['message']}\n")
|
||||
report_file.write(f" - **Contexte**: {context}\n")
|
||||
|
||||
# Ajouter le contexte étendu
|
||||
if 'extended_context' in error:
|
||||
report_file.write(f" - **Contexte étendu**: ```\n{error['extended_context']}\n```\n")
|
||||
|
||||
report_file.write(f" - **Suggestions**: {suggestions_str}\n\n")
|
||||
else:
|
||||
report_file.write("Aucune erreur grammaticale détectée.\n")
|
||||
|
|
0
api_corrections.py
Normal file → Executable file
0
api_corrections.py
Normal file → Executable file
0
app.py
Normal file → Executable file
0
app.py
Normal file → Executable file
0
export_with_remove_tags.py
Normal file → Executable file
0
export_with_remove_tags.py
Normal file → Executable file
0
find_characters_in_book.py
Normal file → Executable file
0
find_characters_in_book.py
Normal file → Executable file
0
format_typo.py
Normal file → Executable file
0
format_typo.py
Normal file → Executable file
0
gantt_parser.py
Normal file → Executable file
0
gantt_parser.py
Normal file → Executable file
222
generate_corrections_page.py
Normal file → Executable file
222
generate_corrections_page.py
Normal file → Executable file
|
@ -55,14 +55,48 @@ def parse_error_report(report_path):
|
|||
spelling_errors = []
|
||||
if spelling_match and "Aucune erreur d'orthographe détectée" not in spelling_match.group(1):
|
||||
spelling_text = spelling_match.group(1)
|
||||
error_pattern = r'- \*\*(.*?)\*\*: (.*?)(?=\n- \*\*|\Z)'
|
||||
for error_match in re.finditer(error_pattern, spelling_text, re.DOTALL):
|
||||
word = error_match.group(1)
|
||||
suggestions_text = error_match.group(2).strip()
|
||||
|
||||
# Nouveau motif pour extraire les erreurs d'orthographe avec contexte étendu
|
||||
word_pattern = r'- \*\*(.*?)\*\*: (.*?)(?=\n- \*\*|\Z)'
|
||||
for word_match in re.finditer(word_pattern, spelling_text, re.DOTALL):
|
||||
word = word_match.group(1)
|
||||
suggestions_text = word_match.group(2).strip()
|
||||
suggestions = []
|
||||
if suggestions_text != "Aucune suggestion":
|
||||
suggestions = [s.strip() for s in suggestions_text.split(',')]
|
||||
|
||||
# Extraire les occurrences pour ce mot
|
||||
occurrence_text = word_match.group(0)
|
||||
occurrence_pattern = r' - \*\*Occurrence (\d+)\*\*:\n - \*\*Contexte\*\*: (.*?)\n - \*\*Contexte étendu\*\*: ```\n(.*?)\n```'
|
||||
|
||||
occurrences = re.finditer(occurrence_pattern, occurrence_text, re.DOTALL)
|
||||
|
||||
# S'il y a des occurrences, les traiter
|
||||
occurrences_found = False
|
||||
for occ_match in occurrences:
|
||||
occurrences_found = True
|
||||
occ_num = occ_match.group(1)
|
||||
context = occ_match.group(2).strip()
|
||||
extended_context = occ_match.group(3).strip()
|
||||
|
||||
# Extraire le texte en gras du contexte (le mot mal orthographié)
|
||||
error_text_match = re.search(r'\*\*(.*?)\*\*', context)
|
||||
error_text = error_text_match.group(1) if error_text_match else word
|
||||
|
||||
# Nettoyer le contexte pour l'affichage
|
||||
clean_context = re.sub(r'\*\*(.*?)\*\*', r'\1', context)
|
||||
|
||||
spelling_errors.append({
|
||||
'word': word,
|
||||
'context': clean_context,
|
||||
'extended_context': extended_context,
|
||||
'error_text': error_text,
|
||||
'suggestions': suggestions,
|
||||
'type': 'spelling'
|
||||
})
|
||||
|
||||
# Si aucune occurrence n'a été trouvée, ajouter une entrée simple
|
||||
if not occurrences_found:
|
||||
spelling_errors.append({
|
||||
'word': word,
|
||||
'suggestions': suggestions,
|
||||
|
@ -76,11 +110,16 @@ def parse_error_report(report_path):
|
|||
grammar_errors = []
|
||||
if grammar_match and "Aucune erreur grammaticale détectée" not in grammar_match.group(1):
|
||||
grammar_text = grammar_match.group(1)
|
||||
error_pattern = r'- \*\*Erreur\*\*: (.*?)\n - \*\*Contexte\*\*: (.*?)\n - \*\*Suggestions\*\*: (.*?)(?=\n\n- \*\*Erreur|\Z)'
|
||||
|
||||
# Nouveau motif pour extraire les erreurs grammaticales avec contexte étendu
|
||||
error_pattern = r'- \*\*Erreur (\d+)\*\*: (.*?)\n - \*\*Contexte\*\*: (.*?)(?:\n - \*\*Contexte étendu\*\*: ```\n(.*?)\n```)?(?:\n - \*\*Suggestions\*\*: (.*?))?(?=\n\n- \*\*Erreur|\Z)'
|
||||
|
||||
for error_match in re.finditer(error_pattern, grammar_text, re.DOTALL):
|
||||
message = error_match.group(1).strip()
|
||||
context = error_match.group(2).strip()
|
||||
suggestions_text = error_match.group(3).strip()
|
||||
error_num = error_match.group(1)
|
||||
message = error_match.group(2).strip()
|
||||
context = error_match.group(3).strip()
|
||||
extended_context = error_match.group(4).strip() if error_match.group(4) else None
|
||||
suggestions_text = error_match.group(5).strip() if error_match.group(5) else "Aucune suggestion"
|
||||
|
||||
# Extraire le texte en gras du contexte (l'erreur elle-même)
|
||||
error_text_match = re.search(r'\*\*(.*?)\*\*', context)
|
||||
|
@ -93,13 +132,19 @@ def parse_error_report(report_path):
|
|||
if suggestions_text != "Aucune suggestion":
|
||||
suggestions = [s.strip() for s in suggestions_text.split(',')]
|
||||
|
||||
grammar_errors.append({
|
||||
grammar_error = {
|
||||
'message': message,
|
||||
'context': clean_context,
|
||||
'error_text': error_text,
|
||||
'suggestions': suggestions,
|
||||
'type': 'grammar'
|
||||
})
|
||||
}
|
||||
|
||||
# Ajouter le contexte étendu s'il existe
|
||||
if extended_context:
|
||||
grammar_error['extended_context'] = extended_context
|
||||
|
||||
grammar_errors.append(grammar_error)
|
||||
|
||||
errors_by_chapter[chapter_title] = {
|
||||
'spelling': spelling_errors,
|
||||
|
@ -133,7 +178,7 @@ def create_css():
|
|||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
h1, h2, h3 {
|
||||
h1, h2, h3, h4, h5 {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
|
@ -171,6 +216,29 @@ def create_css():
|
|||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.extended-context {
|
||||
background-color: #f0f0f0;
|
||||
padding: 10px;
|
||||
border-radius: 5px;
|
||||
margin: 10px 0;
|
||||
border-left: 3px solid #7f8c8d;
|
||||
}
|
||||
|
||||
.extended-context h5 {
|
||||
margin-top: 0;
|
||||
color: #7f8c8d;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.extended-context pre {
|
||||
margin: 0;
|
||||
font-family: monospace;
|
||||
white-space: pre-wrap;
|
||||
line-height: 1.5;
|
||||
font-size: 13px;
|
||||
color: #555;
|
||||
}
|
||||
|
||||
.error-word {
|
||||
font-weight: bold;
|
||||
color: #e74c3c;
|
||||
|
@ -201,6 +269,48 @@ def create_css():
|
|||
background-color: #2980b9;
|
||||
}
|
||||
|
||||
.custom-correction {
|
||||
margin-top: 15px;
|
||||
padding: 10px;
|
||||
background-color: #f9f9f9;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.custom-correction h5 {
|
||||
margin-top: 0;
|
||||
margin-bottom: 10px;
|
||||
color: #555;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.input-group {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.custom-input {
|
||||
flex-grow: 1;
|
||||
padding: 8px;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 4px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.custom-btn {
|
||||
background-color: #9b59b6;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
padding: 8px 15px;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
transition: background-color 0.3s;
|
||||
}
|
||||
|
||||
.custom-btn:hover {
|
||||
background-color: #8e44ad;
|
||||
}
|
||||
|
||||
.action-buttons {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
|
@ -328,6 +438,12 @@ def create_js(errors_by_chapter):
|
|||
btn.disabled = true;
|
||||
btn.style.opacity = '0.5';
|
||||
}});
|
||||
|
||||
// Désactiver le champ de correction personnalisée
|
||||
const customInput = card.querySelector('.custom-input');
|
||||
const customBtn = card.querySelector('.custom-btn');
|
||||
if (customInput) customInput.disabled = true;
|
||||
if (customBtn) customBtn.disabled = true;
|
||||
}} else {{
|
||||
// Afficher un message d'erreur
|
||||
const card = document.querySelector(`#${{errorType}}-${{chapterTitle.replace(/\\s+/g, '-')}}-${{errorIndex}}`);
|
||||
|
@ -347,6 +463,41 @@ def create_js(errors_by_chapter):
|
|||
}});
|
||||
}}
|
||||
|
||||
// Fonction pour appliquer une correction personnalisée
|
||||
function applyCustomCorrection(errorType, chapterTitle, errorIndex) {{
|
||||
// Récupérer la valeur de la correction personnalisée
|
||||
const inputId = `custom-${{errorType}}-${{chapterTitle.replace(/\\s+/g, '-')}}-${{errorIndex}}`;
|
||||
const customInput = document.getElementById(inputId);
|
||||
|
||||
if (!customInput || !customInput.value.trim()) {{
|
||||
alert('Veuillez entrer une correction.');
|
||||
return;
|
||||
}}
|
||||
|
||||
// Appliquer la correction
|
||||
applyCorrection(errorType, chapterTitle, errorIndex, customInput.value.trim());
|
||||
}}
|
||||
|
||||
// Ajouter des écouteurs d'événements pour les champs de saisie personnalisée
|
||||
function setupCustomInputs() {{
|
||||
const customInputs = document.querySelectorAll('.custom-input');
|
||||
customInputs.forEach(input => {{
|
||||
input.addEventListener('keypress', (e) => {{
|
||||
if (e.key === 'Enter') {{
|
||||
// Extraire les informations de l'ID
|
||||
const inputId = input.id;
|
||||
const parts = inputId.replace('custom-', '').split('-');
|
||||
const errorType = parts[0];
|
||||
const errorIndex = parts[parts.length - 1];
|
||||
const chapterTitle = parts.slice(1, parts.length - 1).join(' ');
|
||||
|
||||
// Appliquer la correction
|
||||
applyCustomCorrection(errorType, chapterTitle, errorIndex);
|
||||
}}
|
||||
}});
|
||||
}});
|
||||
}}
|
||||
|
||||
// Fonction pour ignorer une erreur
|
||||
function ignoreError(errorType, chapterTitle, errorIndex) {{
|
||||
// Préparer les données à envoyer
|
||||
|
@ -470,6 +621,9 @@ def create_js(errors_by_chapter):
|
|||
changeTab(tab.getAttribute('data-tab'));
|
||||
}});
|
||||
}});
|
||||
|
||||
// Configurer les champs de saisie personnalisée
|
||||
setupCustomInputs();
|
||||
}});
|
||||
"""
|
||||
|
||||
|
@ -539,7 +693,26 @@ def generate_spelling_html(errors_by_chapter):
|
|||
html += f"""
|
||||
<div id="spelling-{chapter_title.replace(' ', '-')}-{i}" class="error-card spelling" data-word="{word}">
|
||||
<h4>Mot mal orthographié: <span class="error-word">{word}</span></h4>
|
||||
"""
|
||||
|
||||
# Ajouter le contexte s'il existe
|
||||
if 'context' in error:
|
||||
html += f"""
|
||||
<div class="error-context">
|
||||
{error['context'].replace(word, f'<span class="error-word">{word}</span>')}
|
||||
</div>
|
||||
"""
|
||||
|
||||
# Ajouter le contexte étendu s'il existe
|
||||
if 'extended_context' in error:
|
||||
html += f"""
|
||||
<div class="extended-context">
|
||||
<h5>Contexte étendu:</h5>
|
||||
<pre>{error['extended_context']}</pre>
|
||||
</div>
|
||||
"""
|
||||
|
||||
html += f"""
|
||||
<div class="suggestion-buttons">
|
||||
"""
|
||||
|
||||
|
@ -556,6 +729,14 @@ def generate_spelling_html(errors_by_chapter):
|
|||
html += f"""
|
||||
</div>
|
||||
|
||||
<div class="custom-correction">
|
||||
<h5>Correction personnalisée:</h5>
|
||||
<div class="input-group">
|
||||
<input type="text" id="custom-spelling-{chapter_title.replace(' ', '-')}-{i}" class="custom-input" placeholder="Entrez votre correction">
|
||||
<button class="custom-btn" onclick="applyCustomCorrection('spelling', '{chapter_title}', {i})">Appliquer</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="action-buttons">
|
||||
<button class="action-btn ignore" onclick="ignoreError('spelling', '{chapter_title}', {i})">Ignorer cette erreur</button>
|
||||
<button class="action-btn dictionary" onclick="addToDictionary('{word}')">Ajouter au dictionnaire</button>
|
||||
|
@ -601,7 +782,18 @@ def generate_grammar_html(errors_by_chapter):
|
|||
<div class="error-context">
|
||||
{highlighted_context}
|
||||
</div>
|
||||
"""
|
||||
|
||||
# Ajouter le contexte étendu s'il existe
|
||||
if 'extended_context' in error:
|
||||
html += f"""
|
||||
<div class="extended-context">
|
||||
<h5>Contexte étendu:</h5>
|
||||
<pre>{error['extended_context']}</pre>
|
||||
</div>
|
||||
"""
|
||||
|
||||
html += f"""
|
||||
<div class="suggestion-buttons">
|
||||
"""
|
||||
|
||||
|
@ -618,6 +810,14 @@ def generate_grammar_html(errors_by_chapter):
|
|||
html += f"""
|
||||
</div>
|
||||
|
||||
<div class="custom-correction">
|
||||
<h5>Correction personnalisée:</h5>
|
||||
<div class="input-group">
|
||||
<input type="text" id="custom-grammar-{chapter_title.replace(' ', '-')}-{i}" class="custom-input" placeholder="Entrez votre correction">
|
||||
<button class="custom-btn" onclick="applyCustomCorrection('grammar', '{chapter_title}', {i})">Appliquer</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="action-buttons">
|
||||
<button class="action-btn ignore" onclick="ignoreError('grammar', '{chapter_title}', {i})">Ignorer cette erreur</button>
|
||||
</div>
|
||||
|
|
0
make_intrigues_to_csv.py
Normal file → Executable file
0
make_intrigues_to_csv.py
Normal file → Executable file
|
@ -4,22 +4,54 @@
|
|||
|
||||
### Erreurs d'orthographe
|
||||
|
||||
- **eeeeeeeeeeeeeeeeee**: Aucune suggestion
|
||||
- **zou**: fou, sou, pou, zoo, cou
|
||||
- **zou**: zoo, sou, cou, mou, ou
|
||||
- **Occurrence 1**:
|
||||
- **Contexte**: Allez hein **zou** zou
|
||||
- **Contexte étendu**: ```
|
||||
Cette partie ne devrait pas avoir de titre
|
||||
Allez hein zou zou
|
||||
```
|
||||
- **Occurrence 2**:
|
||||
- **Contexte**: Allez hein zou **zou**
|
||||
- **Contexte étendu**: ```
|
||||
Cette partie ne devrait pas avoir de titre
|
||||
Allez hein zou zou
|
||||
```
|
||||
- **eeeeeeeeeeeeeeeeeeeee**: Aucune suggestion
|
||||
- **Occurrence 1**:
|
||||
- **Contexte**: **eeeeeeeeeeeeeeeeeeeee** préambule du cul eeeeeeeeeeeeeeeeee
|
||||
- **Contexte étendu**: ```
|
||||
|
||||
```
|
||||
- **eeeeeeeeeeeeeeeeee**: Aucune suggestion
|
||||
- **Occurrence 1**:
|
||||
- **Contexte**: Eeeeeeeeeeeeeeeeeeeee préambule du cul **eeeeeeeeeeeeeeeeee**
|
||||
- **Contexte étendu**: ```
|
||||
|
||||
```
|
||||
|
||||
### Erreurs grammaticales
|
||||
|
||||
- **Erreur**: Faute de frappe possible trouvée.
|
||||
- **Erreur 1**: Faute de frappe possible trouvée.
|
||||
- **Contexte**: **Eeeeeeeeeeeeeeeeeeeee** préambule du cul eeeeeeeeeeeeeeeeee Cet...
|
||||
- **Contexte étendu**: ```
|
||||
|
||||
```
|
||||
- **Suggestions**: Aucune suggestion
|
||||
|
||||
- **Erreur**: Faute de frappe possible trouvée.
|
||||
- **Erreur 2**: Faute de frappe possible trouvée.
|
||||
- **Contexte**: E**eeeeeeeeeeeeeeeeee**ee préambule du cul **eeeeeeeeeeeeeeeeee** Cette partie ne devrait pas avoir de ti...
|
||||
- **Contexte étendu**: ```
|
||||
|
||||
```
|
||||
- **Suggestions**: Aucune suggestion
|
||||
|
||||
- **Erreur**: Un mot est répété.
|
||||
- **Erreur 3**: Un mot est répété.
|
||||
- **Contexte**: ****.****.****.**** ****d****e****v****r****a****i****t**** ****p****a****s**** ****a****v****o****i****r**** ****d****e**** ****t****i****t****r****e**** **** ****A****l****l****e****z**** ****h****e****i****n**** ****z****o****u**** ****z****o****u****
|
||||
- **Contexte étendu**: ```
|
||||
Cette partie ne devrait pas avoir de titre
|
||||
Allez hein zou zou
|
||||
```
|
||||
- **Suggestions**: zou
|
||||
|
||||
|
||||
|
@ -41,41 +73,79 @@ Aucune erreur grammaticale détectée.
|
|||
|
||||
### Erreurs d'orthographe
|
||||
|
||||
- **blah**: blasé, bac, beau, boa, la
|
||||
- **bleh**: bleu, blet
|
||||
- **blah**: bleh
|
||||
- **Occurrence 1**:
|
||||
- **Contexte**: **blah** blah
|
||||
- **Contexte étendu**: ```
|
||||
|
||||
Blah blah
|
||||
Bleh bob trouva un cristal qui lui permit de communiquer avec les esprits de la nature. Avec leur aide, il put vaincre les ténèbres qui menaçaient l'île et restaurer la lumière éternelle. L'île fut sauvée et Eryndor devint un héros légendaire.
|
||||
```
|
||||
- **Occurrence 2**:
|
||||
- **Contexte**: Blah **blah**
|
||||
- **Contexte étendu**: ```
|
||||
|
||||
Blah blah
|
||||
Bleh bob trouva un cristal qui lui permit de communiquer avec les esprits de la nature. Avec leur aide, il put vaincre les ténèbres qui menaçaient l'île et restaurer la lumière éternelle. L'île fut sauvée et Eryndor devint un héros légendaire.
|
||||
```
|
||||
|
||||
### Erreurs grammaticales
|
||||
|
||||
- **Erreur**: Il manque probablement un trait d’union.
|
||||
- **Contexte**: **Celui là** on doit le voir: chapitre 1 au dessus i...
|
||||
- **Erreur 1**: Il manque probablement un trait d’union.
|
||||
- **Contexte**: **Celui là** on doit le voir : chapitre 1 au dessus ...
|
||||
- **Contexte étendu**: ```
|
||||
|
||||
```
|
||||
- **Suggestions**: Celui-là
|
||||
|
||||
- **Erreur**: Une virgule est requise.
|
||||
- **Contexte**: Celui là** on** doit le voir: chapitre 1 au dessus ici....
|
||||
- **Erreur 2**: Une virgule est requise.
|
||||
- **Contexte**: Celui là** on** doit le voir : chapitre 1 au dessus ici...
|
||||
- **Contexte étendu**: ```
|
||||
|
||||
```
|
||||
- **Suggestions**: , on
|
||||
|
||||
- **Erreur**: Les deux-points sont précédés d’une espace insécable.
|
||||
- **Contexte**: Celui là on doit le **voir:** chapitre 1 au dessus ici. Dans un mond...
|
||||
- **Suggestions**: voir :
|
||||
|
||||
- **Erreur**: « au dessus » est une faute de typographie.
|
||||
- **Erreur 3**: « au dessus » est une faute de typographie.
|
||||
- **Contexte**: Celui là on doit le voir : chapitre 1 **au dessus** ici. Dans un monde lointain, il y avai...
|
||||
- **Contexte étendu**: ```
|
||||
|
||||
```
|
||||
- **Suggestions**: au-dessus
|
||||
|
||||
- **Erreur**: Faute de frappe possible trouvée.
|
||||
- **Erreur 4**: Faute de frappe possible trouvée.
|
||||
- **Contexte**: ****.****.****.**** ****d****e****s**** ****é****t****o****i****l****e****s****.**** ****U****n**** ****j****e****u****n****e**** ****a****v****e****n****t****u****r****i****e****r**** ****n****o****m****m****é**** ****E****r****y****n****d****o****r**** ****y**** ****a****r****r****i****v****a**** ****u****n**** ****j****o****u****r****,**** ****a****t****t****i****r****é**** ****p****a****r**** ****l****e****s**** ****l****é****g****e****n****d****.****.****.****
|
||||
- **Contexte étendu**: ```
|
||||
Celui là on doit le voir : chapitre 1 au dessus ici.
|
||||
Dans un monde lointain, il y avait une île mystérieuse où les arbres avaient des feuilles qui brillaient comme des étoiles. Un jeune aventurier nommé Eryndor y arriva un jour, attiré par les légendes de l'île. Il découvrit un temple caché où les dieux anciens avaient laissé des secrets et des pouvoirs magiques.
|
||||
|
||||
```
|
||||
- **Suggestions**: Grandeur, Grandir, Brando, Condor, Rondo
|
||||
|
||||
- **Erreur**: Faute de frappe possible trouvée.
|
||||
- **Erreur 5**: Faute de frappe possible trouvée.
|
||||
- **Contexte**: ****.****.****.****d****e****s**** ****s****e****c****r****e****t****s**** ****e****t**** ****d****e****s**** ****p****o****u****v****o****i****r****s**** ****m****a****g****i****q****u****e****s****.**** **** **** ****B****l****a****h**** ****b****l****a****h**** ****B****l****e****h**** ****b****o****b**** ****t****r****o****u****v****a**** ****u****n**** ****c****r****i****s****t****a****l**** ****q****u****i**** ****l****u****i**** ****p****e****r****m****.****.****.****
|
||||
- **Contexte étendu**: ```
|
||||
|
||||
Blah blah
|
||||
Bleh bob trouva un cristal qui lui permit de communiquer avec les esprits de la nature. Avec leur aide, il put vaincre les ténèbres qui menaçaient l'île et restaurer la lumière éternelle. L'île fut sauvée et Eryndor devint un héros légendaire.
|
||||
```
|
||||
- **Suggestions**: Bla-bla
|
||||
|
||||
- **Erreur**: Faute de frappe possible trouvée.
|
||||
- **Erreur 6**: Faute de frappe possible trouvée.
|
||||
- **Contexte**: ****.****.****.****s**** ****e****t**** ****d****e****s**** ****p****o****u****v****o****i****r****s**** ****m****a****g****i****q****u****e****s****.**** **** **** ****B****l****a****h**** ****b****l****a****h**** ****B****l****e****h**** ****b****o****b**** ****t****r****o****u****v****a**** ****u****n**** ****c****r****i****s****t****a****l**** ****q****u****i**** ****l****u****i**** ****p****e****r****m****i****t**** ****d****e****.****.****.****
|
||||
- **Contexte étendu**: ```
|
||||
Blah blah
|
||||
Bleh bob trouva un cristal qui lui permit de communiquer avec les esprits de la nature. Avec leur aide, il put vaincre les ténèbres qui menaçaient l'île et restaurer la lumière éternelle. L'île fut sauvée et Eryndor devint un héros légendaire.
|
||||
|
||||
```
|
||||
- **Suggestions**: Bleu, Blé, Blés, Bled, Blet
|
||||
|
||||
- **Erreur**: Faute de frappe possible trouvée.
|
||||
- **Erreur 7**: Faute de frappe possible trouvée.
|
||||
- **Contexte**: ****.****.****.**** ****l****u****m****i****è****r****e**** ****é****t****e****r****n****e****l****l****e****.**** ****L****'****î****l****e**** ****f****u****t**** ****s****a****u****v****é****e**** ****e****t**** ****E****r****y****n****d****o****r**** ****d****e****v****i****n****t**** ****u****n**** ****h****é****r****o****s**** ****l****é****g****e****n****d****a****i****r****e****.**** **** **** ****1****1****1****1****1****1****1****1****1****.****.****.****
|
||||
- **Contexte étendu**: ```
|
||||
Blah blah
|
||||
Bleh bob trouva un cristal qui lui permit de communiquer avec les esprits de la nature. Avec leur aide, il put vaincre les ténèbres qui menaçaient l'île et restaurer la lumière éternelle. L'île fut sauvée et Eryndor devint un héros légendaire.
|
||||
|
||||
```
|
||||
- **Suggestions**: Grandeur, Grandir, Brando, Condor, Rondo
|
||||
|
||||
|
||||
|
@ -85,12 +155,16 @@ Aucune erreur grammaticale détectée.
|
|||
|
||||
### Erreurs d'orthographe
|
||||
|
||||
- **chuck**: check
|
||||
Aucune erreur d'orthographe détectée.
|
||||
|
||||
### Erreurs grammaticales
|
||||
|
||||
- **Erreur**: Faute de frappe possible : une espace est répétée
|
||||
- **Erreur 1**: Faute de frappe possible : une espace est répétée
|
||||
- **Contexte**: 2222222222222** ** Chuck fait des trucs
|
||||
- **Contexte étendu**: ```
|
||||
|
||||
Chuck fait des trucs
|
||||
```
|
||||
- **Suggestions**:
|
||||
|
||||
|
||||
|
@ -100,12 +174,16 @@ Aucune erreur grammaticale détectée.
|
|||
|
||||
### Erreurs d'orthographe
|
||||
|
||||
- **bobette**: brouette, blette, couette, tomette, bette
|
||||
Aucune erreur d'orthographe détectée.
|
||||
|
||||
### Erreurs grammaticales
|
||||
|
||||
- **Erreur**: Faute de frappe possible trouvée.
|
||||
- **Erreur 1**: Faute de frappe possible trouvée.
|
||||
- **Contexte**: 33333333333333333 **Bobette** et bob sont sur un bateau
|
||||
- **Contexte étendu**: ```
|
||||
33333333333333333
|
||||
Bobette et bob sont sur un bateau
|
||||
```
|
||||
- **Suggestions**: Boette, Bébête, Bobettes, Boetté, Bouette
|
||||
|
||||
|
||||
|
@ -114,5 +192,5 @@ Aucune erreur grammaticale détectée.
|
|||
## Résumé
|
||||
|
||||
- **Nombre total de chapitres analysés**: 5
|
||||
- **Nombre total d'erreurs d'orthographe**: 7
|
||||
- **Nombre total d'erreurs grammaticales**: 13
|
||||
- **Nombre total d'erreurs d'orthographe**: 6
|
||||
- **Nombre total d'erreurs grammaticales**: 12
|
||||
|
|
0
render_ebook.py
Normal file → Executable file
0
render_ebook.py
Normal file → Executable file
|
@ -3,5 +3,6 @@ language_tool_python==2.9.4
|
|||
matplotlib==3.10.6
|
||||
numpy==2.3.2
|
||||
pandas==2.3.2
|
||||
pyspellchecker==0.8.3
|
||||
scipy==1.16.1
|
||||
wordcloud==1.9.4
|
||||
|
|
0
stats_chapitres.py
Normal file → Executable file
0
stats_chapitres.py
Normal file → Executable file
0
structure_generator.py
Normal file → Executable file
0
structure_generator.py
Normal file → Executable file
0
test_format_typo.py
Normal file → Executable file
0
test_format_typo.py
Normal file → Executable file
|
@ -20,6 +20,7 @@ else
|
|||
cp *.py "$dossier/"
|
||||
cp *.sh "$dossier/"
|
||||
cp *.css "$dossier/"
|
||||
cp *.txt "$dossier/"
|
||||
cp README.md "$dossier/"
|
||||
cp LICENSE "$dossier/"
|
||||
|
||||
|
|
0
view_suivi_livre.py
Normal file → Executable file
0
view_suivi_livre.py
Normal file → Executable file
Loading…
Add table
Add a link
Reference in a new issue