update folder script

This commit is contained in:
Tykayn 2025-08-31 22:37:24 +02:00 committed by tykayn
parent 1713aa30b5
commit da06022b56
20 changed files with 573 additions and 95 deletions

236
generate_corrections_page.py Normal file → Executable file
View file

@ -55,19 +55,53 @@ 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(',')]
spelling_errors.append({
'word': word,
'suggestions': suggestions,
'type': 'spelling'
})
# 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,
'type': 'spelling'
})
# Extraire les erreurs grammaticales
grammar_pattern = r'### Erreurs grammaticales\n\n(.*?)(?=\n\n---|\Z)'
@ -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>