Spaces:
Sleeping
Sleeping
| import re | |
| import unicodedata | |
| import gradio as gr | |
| def normalize(text): | |
| text = text.lower() | |
| text = unicodedata.normalize('NFD', text) | |
| return ''.join(c for c in text if unicodedata.category(c) != 'Mn') | |
| def build_norm_map(original): | |
| norm_chars = [] | |
| mapping = [] | |
| for i, ch in enumerate(original): | |
| decomposed = unicodedata.normalize('NFD', ch) | |
| base_chars = ''.join(c for c in decomposed if unicodedata.category(c) != 'Mn') | |
| if base_chars == '': | |
| continue | |
| for nb in base_chars: | |
| norm_chars.append(nb.lower()) | |
| mapping.append(i) | |
| return ''.join(norm_chars), mapping | |
| def slice_original_from_norm_span(orig, map_norm, start_norm, end_norm): | |
| start_orig = map_norm[start_norm] | |
| end_orig = map_norm[end_norm - 1] + 1 | |
| return orig[start_orig:end_orig] | |
| # ----------------------------- | |
| # LISTES EXHAUSTIVES | |
| # ----------------------------- | |
| intensificateurs = [ | |
| "trop","très","si","fort","forte","forts","fortes","tellement","plus que jamais","aussi jamais","carrément" | |
| "bien","furieusement","intensément","tant","à tel point que","à tel point qu'","au point que","au point qu'","largement", | |
| "complètement","pleinement","violemment","parfaitement","ardemment ","infiniment ","vivement ","totalement","beaucoup","énormément","extrêmement", | |
| "hyper","profondément","follement","absolument","vraiment","extraordinairement","incroyablement","terriblement","particulièrement","singulièrement", | |
| "prodigieusement","excessivement","vachement","bigrement","puissamment","fortement","hautement","considérablement","remarquablement" | |
| ] | |
| moderateurs = [ | |
| "assez","modérément","moyennement","quasi"," plus ou moins"," ni trop longs ni trop courts", | |
| "quasiment","presque","pas mal","plutôt","léger","légère","légers","légères","relatif","relative","relatifs","relatives", | |
| "relativement","légèrement","quelque peu","un tantinet","pas mal","pour ainsi dire","mi-" | |
| ] | |
| attenuateurs = [ | |
| "peu","à peine","médiocrement","passablement", | |
| "petitement","un peu","faiblement","un brin","modiquement" | |
| ] | |
| adj_intensificateurs = [ | |
| "énorme","énormes","immense","immenses","extrême","extrêmes", | |
| "suprême","suprêmes","immensurable","immensurables","inouïe","inouï","inouïs","inouïes","exacerbé","exacerbée","exacerbés","exacerbées", | |
| "profond","profonde","profondes", "profonds","parfait","parfaite", "parfaits", "parfaites","accru","accrue","accrus","accrues", | |
| "irréprochable","irréprochables","implacable", "implacables","insondable","insondables", | |
| "infini","infinie","infinis","infinies","formidable","formidables", | |
| "exceptionnel","exceptionnelle","exceptionnels", "exceptionnelles","incroyable","incroyables", | |
| "extraordinaire","extraordinaires","fantastique","fantastiques", | |
| "gigantesque","gigantesques","monumental","monumentale","monumentales","monumentaux", | |
| "colossal", "colossale","colossaux","colossales","remarquable","remarquables", | |
| "phénoménal","phénoménale","phénoménaux","phénoménales","intense","intenses", | |
| "absolu", "absolue", "absolus", "absolues","titanesque","titanesques","herculéenne","herculéen","herculéens","herculéennes", | |
| "appuyé","appuyés","appuyée","maximal","maximale","maximaux","maximales","optimal","optimale","optimaux","optimales","appuyées","démesuré","démesurée","démesurés","démesurées","accablants","accablantes","furieux","furieuse","furieuses","frappant","frappante","fulgurante","fulgurant","fulgurants","fulgurantes","considérable","considérables","élevé","élevée","élevés","élevées","accablant","accablante" | |
| ] | |
| adj_intensificateurs += [ | |
| "surdoué","surdouée","surdoués","surdouées", | |
| "surhumain","surhumaine","surhumains","surhumaines", | |
| "surchargé","surchargée","surchargés","surchargées", | |
| "surmené","surmenée","surmenés","surmenées", | |
| "surpuissant","surpuissante","surpuissants","surpuissantes", | |
| "surqualifié","surqualifiée","surqualifiés","surqualifiées", | |
| "surproductif","surproductive","surproductifs","surproductives", | |
| "surabondant","surabondante","surabondants","surabondantes", | |
| "surintensif","surintensive","surintensifs","surintensives", | |
| "surdimensionné","surdimensionnée","surdimensionnés","surdimensionnées", | |
| "suréquipé","suréquipée","suréquipés","suréquipées","survoltée","survolté","survoltés","survoltées" | |
| ] | |
| adj_attenuateurs = ["infime","infimes","minime","minimes","minuscules","minuscule","minimale","minimal","minimales","minimaux"] | |
| adj_attenuateurs += [ | |
| "sous-dimensionné","sous-dimensionnée","sous-dimensionnés","sous-dimensionnées", | |
| "sous-estimé","sous-estimée","sous-estimés","sous-estimées","sous-payé","sous-payée","sous-payés","sous-payées", | |
| "sous-développé","sous-développée","sous-développés","sous-développées", | |
| "sous-alimenté","sous-alimentée","sous-alimentés","sous-alimentées", | |
| "sous-exploité","sous-exploitée","sous-exploités","sous-exploitées", | |
| "sous-utilisé","sous-utilisée","sous-utilisés","sous-utilisées", | |
| "sous-évalué","sous-évaluée","sous-évalués","sous-évaluées", | |
| "sous-qualifié","sous-qualifiée","sous-qualifiés","sous-qualifiées", | |
| "sous-optimal","sous-optimale","sous-optimaux","sous-optimales" | |
| ] | |
| prefixes_intensifs = ["archi", "extra", "super", "hyper", "mega"] | |
| prefixes_attenuateurs = ["hypo", "infra", "mini"] | |
| # ----------------------------- | |
| # LISTE D'EXCLUSION | |
| # ----------------------------- | |
| exclusions = [ | |
| "plus tard","plus de vingt ans","superbe","miniature ","beaucoup de gens ","beaucoup de choses ","énormément de modalisateurs", "bien que", "bien qu","mini-jupe","mini-jupes","peu à peu","ne plus","au moins","du moins","mais aussi","si tout","se si","extraits","élève", | |
| "s'il","si elle","si le","si la","si les","si un","si une","si des","si nous","si vous","si je","si tu","si elles","si ils","si son","si sa","si ses","si leurs","si leur","si mon","si ma","si mes","relatif à","relative à","relatifs à","relatives à","pas mal de","n'est plus","n'était plus","ne plus" | |
| ] | |
| # ----------------------------- | |
| # PHRASÉOLOGISMES (EXHAUSTIFS, toutes formes) | |
| # ----------------------------- | |
| phras_intensifs = [ | |
| "avoir le cafard","ai le cafard", "as le cafard","a le cafard","avons le cafard","avez le cafard", "ont le cafard", | |
| "avais le cafard","avait le cafard", "avions le cafard","aviez le cafard","avaient le cafard", | |
| "être au septième ciel","suis au septième ciel", "es au septième ciel", | |
| "est au septième ciel","sommes au septième ciel", "êtes au septième ciel","sont au septième ciel","étais au septième ciel", "était au septième ciel", | |
| "étions au septième ciel","étiez au septième ciel", "étaient au septième ciel", | |
| "serai au septième ciel","sera au septième ciel", "serons au septième ciel","serez au septième ciel","seront au septième ciel", | |
| "serais au septième ciel","serait au septième ciel", "serions au septième ciel", | |
| "seriez au septième ciel","seraient au septième ciel", | |
| "se tordre de douleur","me tords de douleur", "te tords de douleur", | |
| "se tord de douleur","nous nous tordons de douleur", "vous vous tordez de douleur", | |
| "se tordent de douleur","à fleur de peau","sur les nerfs","à bout de nerfs", | |
| "mourir de rire","meurs de rire","meurt de rire","mourons de rire", | |
| "mourez de rire","meurent de rire", | |
| "mourir de faim","meurs de faim","meurt de faim","mourons de faim", | |
| "mourez de faim","meurent de faim", | |
| "mourir de froid","meurs de froid", "meurt de froid","mourons de froid", | |
| "mourez de froid","meurent de froid", | |
| "brûler d'amour","brûle d'amour", "brûlait d'amour","brûlerai d'amour", | |
| "brûler d'impatience","brûle d'impatience","brûlait d'impatience","brûlerai d'impatience", | |
| "au plus vite","au plus haut degré", "à l'extrême","se mettre sur son trente et un","être sur son trente et un", | |
| "trembler de peur","tremble de peur","fort comme un turc","rouge comme une tomate", | |
| "malade comme un chien","tremblait de peur", "tremblerai de peur","un travail d'Hercule", | |
| "être transporté de joie","suis transporté de joie", "est transporté de joie","roule sur l'or","rouler sur l'or" | |
| "sommes transportés de joie", "à verse","un coeur de pierre","rapides comme l'éclair","rapides comme l'éclair", | |
| "à couper le souffle","à mort","à fond","à pas de géant","plein à craquer","à l'extrême","à l'excès","outre mesure", | |
| "laid à pleurer","hors de lui","au comble de la joie","au comble de la performance","tiré à quatre épingles","habillé comme un prince","mettre les bouchées doubles", | |
| "fièvre de cheval","froideur de glace","faim de loup","froid de canard","sur des charbons ardents","à outrance","à la folie","comme jamais", | |
| "appétit d'orge","patience d'ange", "comme une souche","comme un trou","comme un putois","le cœur en capilotade", | |
| "avoir le cœur en capilotade", "à bout de force", "à bout de souffle","comme un poisson dans l'eau","pousser comme une mauvaise herbe","pousse comme une mauvaise herbe", | |
| "se traîner comme une limace","timide comme une souris","froid comme un glaçon","à en mourir","à en crever","à en perdre la raison", | |
| "d'une lenteur d'escargot","faible comme une plume","avoir les jambes en coton","de plus en plus", | |
| "mal en point","pluie diluvienne","force herculéenne","froid sibérien","à gorge déployée","à toute allure","à toute vitesse","de toutes forces","de toutes ses oreilles", | |
| "tout yeux tout oreilles ","tout oreilles","tout ouïe", | |
| ] | |
| phras_att = [ | |
| "appétit d'oiseau","de faible envergure","de moins en moins" | |
| ] | |
| phras_mod = [ | |
| "dans une certaine mesure","à moitié chemin","à la limite","tant bien que mal","peu ou prou ","vaille que vaille ","à demi","à moitié","moitié moitié" | |
| ] | |
| # ----------------------------- | |
| # COMPARATIFS & SUPERLATIFS | |
| # ----------------------------- | |
| comparatifs = ["plus","moins","autant","aussi", "pire","meilleur","meilleure","meilleures","meilleurs","pires","moins","mieux"] | |
| superlatifs = ["le plus","la plus", "les plus", "le meilleur", "la meilleure","les meilleurs","les meilleures", | |
| "le mieux", "le pire", "la pire", "les pires","le moins","la moindre", "les moindres"] | |
| # ----------------------------- | |
| # NORMALISATION DES LISTES | |
| # ----------------------------- | |
| norm_exclusions = [normalize(w) for w in exclusions] | |
| norm_phras_int = [normalize(w) for w in phras_intensifs] | |
| norm_phras_mod = [normalize(w) for w in phras_mod] | |
| norm_phras_att = [normalize(w) for w in phras_att] | |
| norm_intens = [normalize(w) for w in intensificateurs + adj_intensificateurs + prefixes_intensifs] | |
| norm_mod = [normalize(w) for w in moderateurs] | |
| norm_att = [normalize(w) for w in attenuateurs + adj_attenuateurs + prefixes_attenuateurs] | |
| norm_comparatifs = [normalize(w) for w in comparatifs] | |
| norm_superlatifs = [normalize(w) for w in superlatifs] | |
| # ----------------------------- | |
| # FONCTIONS DE DÉTECTION | |
| # ----------------------------- | |
| def detect_trop_adj(orig, occupied): | |
| """ | |
| Détecte uniquement 'trop + adjectif' comme intensificateur, | |
| en ignorant les zones déjà détectées comme modérateurs. | |
| """ | |
| matches = [] | |
| # Pattern 'trop' suivi d'au moins un mot (adjectif) | |
| pattern = r'\btrop\s+[a-zA-ZÀ-ÿ\-]+\b' | |
| for m in re.finditer(pattern, orig, flags=re.IGNORECASE): | |
| start, end = m.span() | |
| # Ignorer si chevauchement avec un modérateur | |
| if any(o_start < end and start < o_end for o_start, o_end in occupied): | |
| continue | |
| # Ajouter comme intensificateur | |
| matches.append({ | |
| "type": "intensificateur", | |
| "start": start, | |
| "end": end, | |
| "text": orig[start:end] | |
| }) | |
| occupied.append((start, end)) | |
| return matches | |
| def detect_multiword_with_gaps(text_norm, map_norm, orig, phrase_norm, max_gaps=3): | |
| matches = [] | |
| parts = phrase_norm.split() | |
| if not parts: return matches | |
| escaped = [re.escape(p) for p in parts] | |
| gap = r'(?:\s+\w+){0,' + str(max_gaps) + r'}\s*' | |
| pattern = r'\b' + gap.join(escaped) + r'\b' | |
| for m in re.finditer(pattern, text_norm): | |
| s, e = m.start(), m.end() | |
| matches.append((s, e, slice_original_from_norm_span(orig, map_norm, s, e))) | |
| return matches | |
| def detect_words_general(text_norm, map_norm, orig, norm_items, occupied): | |
| matches = [] | |
| for item in sorted(set(norm_items), key=lambda s: -len(s)): | |
| if not item: continue | |
| for s,e,orig_sub in detect_multiword_with_gaps(text_norm, map_norm, orig, item, max_gaps=3): | |
| if any(occupied[s:e]): continue | |
| for i in range(s,e): occupied[i]=True | |
| matches.append((s,e,orig_sub)) | |
| return matches | |
| def detect_prefixed_words(text_norm, map_norm, orig, prefixes, occupied): | |
| """ | |
| Détecte les mots contenant des préfixes soudés (hyperactif, minuscule, etc.) | |
| """ | |
| matches = [] | |
| for pref in sorted(prefixes, key=len, reverse=True): | |
| pattern = rf'\b{re.escape(pref)}[a-z]{{3,}}\b' | |
| for m in re.finditer(pattern, text_norm): | |
| s, e = m.start(), m.end() | |
| if any(occupied[s:e]): | |
| continue | |
| for i in range(s, e): | |
| occupied[i] = True | |
| matches.append((s, e, slice_original_from_norm_span(orig, map_norm, s, e))) | |
| return matches | |
| def detect_issime(text_norm, map_norm, orig, occupied): | |
| matches = [] | |
| for m in re.finditer(r'\b\w+issimes?\b', text_norm): | |
| s, e = m.start(), m.end() | |
| if any(occupied[s:e]): | |
| continue | |
| for i in range(s, e): | |
| occupied[i] = True | |
| matches.append((s, e, slice_original_from_norm_span(orig, map_norm, s, e))) | |
| return matches | |
| def detect_exclamatives(text_norm, map_norm, orig, occupied): | |
| matches = [] | |
| start_words = ["que c'est", "comme", "combien", "quel", "quelle", "quels", "quelles"] | |
| start_words_norm = [normalize(w) for w in start_words] | |
| for start in start_words_norm: | |
| start_pattern = re.escape(start).replace(r'\ ', r'\s+').replace(r"\'", r"[’']") | |
| pattern = rf'\b{start_pattern}\b[^\!]*\!' | |
| for m in re.finditer(pattern, text_norm): | |
| s, e = m.start(), m.end() | |
| if any(occupied[s:e]): | |
| continue | |
| for i in range(s, e): | |
| occupied[i] = True | |
| matches.append((s, e, slice_original_from_norm_span(orig, map_norm, s, e))) | |
| return matches | |
| def exclude_aussi_connecteur(text_norm, map_norm, orig, occupied): | |
| matches = [] | |
| for m in re.finditer(r'(^|[.!?])\s*aussi\b', text_norm): | |
| s = m.start(0) | |
| e = m.end(0) | |
| for i in range(s, e): | |
| occupied[i] = True | |
| matches.append( | |
| (s, e, slice_original_from_norm_span(orig, map_norm, s, e)) | |
| ) | |
| return matches | |
| # ----------------------------- | |
| # DETECTION COMPARATIFS ET SUPERLATIFS | |
| # ----------------------------- | |
| def detect_comparatifs_superlatifs(text_norm, map_norm, orig, occupied): | |
| comp_matches = [] | |
| super_matches = [] | |
| articles_super = ["le","la","les","de","mon","ma","mes","ton","ta","tes", | |
| "son","sa","ses","notre","nos","votre","vos","leur","leurs"] | |
| tokens = list(re.finditer(r'\b\w+\b', text_norm)) | |
| i = 0 | |
| while i < len(tokens): | |
| tok = tokens[i] | |
| s, e = tok.start(), tok.end() | |
| word = text_norm[s:e] | |
| if any(occupied[s:e]): | |
| i += 1 | |
| continue | |
| # Vérifie superlatif (précédé d'article ou possessif) | |
| prev_context_start = max(0, s-15) | |
| context = text_norm[prev_context_start:s].strip() | |
| matched_super = None | |
| for sp in norm_superlatifs: | |
| sp_parts = sp.split() | |
| if word == sp_parts[-1]: | |
| if len(sp_parts) == 1: | |
| if any(context.endswith(a) for a in articles_super): | |
| matched_super = sp | |
| break | |
| else: | |
| start_check = max(0, i - (len(sp_parts)-1)) | |
| span_words = [tokens[j].group() for j in range(start_check, i+1)] | |
| if [w.lower() for w in span_words] == sp_parts: | |
| matched_super = sp | |
| break | |
| if matched_super: | |
| start_idx = tokens[i - len(matched_super.split()) + 1].start() if len(matched_super.split()) > 1 else s | |
| end_idx = e | |
| for j in range(start_idx, end_idx): | |
| occupied[j] = True | |
| super_matches.append((start_idx, end_idx, slice_original_from_norm_span(orig, map_norm, start_idx, end_idx))) | |
| i += 1 | |
| continue | |
| # Comparatif simple | |
| matched_comp = None | |
| for cp in norm_comparatifs: | |
| cp_parts = cp.split() | |
| if word == cp_parts[0]: | |
| if len(cp_parts) == 1: | |
| matched_comp = cp | |
| else: | |
| if i + len(cp_parts) -1 < len(tokens): | |
| span_words = [tokens[i + j].group() for j in range(len(cp_parts))] | |
| if [w.lower() for w in span_words] == cp_parts: | |
| matched_comp = cp | |
| if matched_comp: | |
| start_idx = s | |
| end_idx = tokens[i + len(cp_parts)-1].end() if len(cp_parts) >1 else e | |
| for j in range(start_idx, end_idx): | |
| occupied[j] = True | |
| comp_matches.append((start_idx, end_idx, slice_original_from_norm_span(orig, map_norm, start_idx, end_idx))) | |
| break | |
| i += 1 | |
| return comp_matches, super_matches | |
| # ----------------------------- | |
| # ANALYSEUR PRINCIPAL | |
| # ----------------------------- | |
| def analyse_text(text): | |
| if not text or not text.strip(): | |
| return "Entrez un texte valide." | |
| orig = text | |
| text_norm, map_norm = build_norm_map(orig) | |
| occupied = [False] * max(1, len(text_norm)) | |
| # Exclusions prioritaires | |
| detect_words_general(text_norm, map_norm, orig, norm_exclusions, occupied) | |
| exclude_aussi_connecteur(text_norm, map_norm, orig, occupied) | |
| # Phraséologismes | |
| phras_int = detect_words_general(text_norm, map_norm, orig, norm_phras_int, occupied) | |
| phras_mod = detect_words_general(text_norm, map_norm, orig, norm_phras_mod, occupied) | |
| phras_att = detect_words_general(text_norm, map_norm, orig, norm_phras_att, occupied) | |
| # Général lexical (formes isolées) | |
| general_intens = detect_words_general(text_norm, map_norm, orig, norm_intens, occupied) | |
| general_mod = detect_words_general(text_norm, map_norm, orig, norm_mod, occupied) | |
| general_att = detect_words_general(text_norm, map_norm, orig, norm_att, occupied) | |
| # Préfixes soudés (NOUVEAU) | |
| pref_intens = detect_prefixed_words( | |
| text_norm, map_norm, orig, | |
| prefixes=[normalize(p) for p in prefixes_intensifs], | |
| occupied=occupied | |
| ) | |
| pref_att = detect_prefixed_words( | |
| text_norm, map_norm, orig, | |
| prefixes=[normalize(p) for p in prefixes_attenuateurs], | |
| occupied=occupied | |
| ) | |
| issime_detect = detect_issime(text_norm, map_norm, orig, occupied) | |
| excl_detect = detect_exclamatives(text_norm, map_norm, orig, occupied) | |
| comp_detect, super_detect = detect_comparatifs_superlatifs( | |
| text_norm, map_norm, orig, occupied | |
| ) | |
| # Séparation par catégorie | |
| intens_detect = general_intens + pref_intens + issime_detect + excl_detect | |
| moder_detect = general_mod | |
| atten_detect = general_att + pref_att | |
| # Préparation des highlights | |
| highlights = [] | |
| for s, e, txt in intens_detect: | |
| highlights.append((s, e, 'intensifs', txt)) | |
| for s, e, txt in moder_detect: | |
| highlights.append((s, e, 'moder', txt)) | |
| for s, e, txt in atten_detect: | |
| highlights.append((s, e, 'atten', txt)) | |
| for s, e, txt in comp_detect: | |
| highlights.append((s, e, 'comp', txt)) | |
| for s, e, txt in super_detect: | |
| highlights.append((s, e, 'super', txt)) | |
| for s, e, txt in phras_int: | |
| highlights.append((s, e, 'phras_int', txt)) | |
| for s, e, txt in phras_mod: | |
| highlights.append((s, e, 'phras_mod', txt)) | |
| for s, e, txt in phras_att: | |
| highlights.append((s, e, 'phras_att', txt)) | |
| highlights.sort(key=lambda x: x[0]) | |
| # HTML surbrillance simple | |
| html_out="" | |
| last=0 | |
| colors = { | |
| "intensifs":"background-color:#ff4d4d;", | |
| "moder":"background-color:#a6e1ff;", | |
| "atten":"background-color:#d9d9d9;", | |
| "phras_int":"background-color:#ffb3b3;", | |
| "phras_mod":"background-color:#cfe9ff;", | |
| "phras_att":"background-color:#f0f0f0;", | |
| "comp":"background-color:#ffff99;", # jaune | |
| "super":"background-color:#ff9933;" # orange | |
| } | |
| def esc(s): return s.replace("&","&").replace("<","<").replace(">",">") | |
| for s_norm,e_norm,cat,orig_sub in highlights: | |
| try: | |
| s_o = map_norm[s_norm] | |
| e_o = map_norm[e_norm-1]+1 | |
| html_out += esc(orig[last:s_o]) | |
| html_out += f"<span style='{colors[cat]} padding:2px 2px; border-radius:3px'>{esc(orig[s_o:e_o])}</span>" | |
| last=e_o | |
| except: | |
| html_out += esc(orig[last:]) | |
| last=len(orig) | |
| break | |
| html_out += esc(orig[last:]) | |
| # Listes uniques | |
| def uniq(seq): | |
| seen=set() | |
| out=[] | |
| for s,e,txt in seq: | |
| if txt not in seen: | |
| seen.add(txt) | |
| out.append(txt) | |
| return out | |
| intens_list=uniq(intens_detect) | |
| moder_list=uniq(moder_detect) | |
| atten_list=uniq(atten_detect) | |
| phras_int_list=[t[2] for t in phras_int] | |
| phras_mod_list=[t[2] for t in phras_mod] | |
| phras_att_list=[t[2] for t in phras_att] | |
| comp_list=uniq(comp_detect) | |
| super_list=uniq(super_detect) | |
| # Notes traduction réorganisées | |
| translate_notes_html = "" | |
| if phras_int_list: | |
| translate_notes_html += "<strong>Intensificateurs :</strong><br>" | |
| translate_notes_html += "<br>".join([f"- « {idi} » — traduire avec précaution pour préserver la force expressive." for idi in phras_int_list]) | |
| translate_notes_html += "<br><br>" | |
| if phras_mod_list: | |
| translate_notes_html += "<strong>Modérateurs :</strong><br>" | |
| translate_notes_html += "<br>".join([f"- « {idi} » — vérifier la nuance; une traduction littérale peut altérer le ton." for idi in phras_mod_list]) | |
| translate_notes_html += "<br><br>" | |
| if phras_att_list: | |
| translate_notes_html += "<strong>Atténuateurs :</strong><br>" | |
| translate_notes_html += "<br>".join([f"- « {idi} » — adapter selon le registre cible pour conserver l'effet atténuateur." for idi in phras_att_list]) | |
| translate_notes_html += "<br>" | |
| # Degré de modalisation | |
| total_occurrences = len(intens_list)+len(moder_list)+len(atten_list)+len(phras_int_list)+len(phras_mod_list)+len(phras_att_list)+len(comp_list)+len(super_list) | |
| if total_occurrences <=3: deg_modal="faible" | |
| elif total_occurrences <=6: deg_modal="moyen" | |
| else: deg_modal="fort" | |
| # Rapport Markdown HTML final avec tous les titres foncés | |
| report_md = f""" | |
| <strong>🎯 RAPPORT D'ANALYSE — MODALISATION</strong> | |
| Aperçu (occurrences surlignées) 🔬 : | |
| <div style="padding:10px;border:1px solid #ddd;border-radius:6px;font-size:14px;font-family:Arial,sans-serif">{html_out}</div> | |
| <hr> | |
| <strong>💥 Intensificateurs détectés ({len(intens_list)}):</strong> | |
| {', '.join(intens_list) if intens_list else 'Aucun'} | |
| <strong>⚖️ Modérateurs détectés ({len(moder_list)}):</strong> | |
| {', '.join(moder_list) if moder_list else 'Aucun'} | |
| <strong>🌫️ Atténuateurs détectés ({len(atten_list)}):</strong> | |
| {', '.join(atten_list) if atten_list else 'Aucun'} | |
| <strong>⭐ Comparatifs détectés ({len(comp_list)}):</strong> | |
| {', '.join(comp_list) if comp_list else 'Aucun'} | |
| <strong>🟠 Superlatifs détectés ({len(super_list)}):</strong> | |
| {', '.join(super_list) if super_list else 'Aucun'} | |
| <hr> | |
| <strong>🔎 Phraséologismes (séparés par type):</strong> | |
| <strong>🔥 Intensificateurs ({len(phras_int_list)}):</strong> | |
| {', '.join(phras_int_list) if phras_int_list else 'Aucun'} | |
| <strong>🌱 Modérateurs ({len(phras_mod_list)}):</strong> | |
| {', '.join(phras_mod_list) if phras_mod_list else 'Aucun'} | |
| <strong>🌧️ Atténuateurs ({len(phras_att_list)}):</strong> | |
| {', '.join(phras_att_list) if phras_att_list else 'Aucun'} | |
| <hr> | |
| <strong>📝 Notes et conseils de traduction</strong><br> | |
| {translate_notes_html if translate_notes_html else 'Aucun phraséologisme détecté.'} | |
| <hr> | |
| <strong>📊 Degré de la modalisation intensive du texte :</strong> {deg_modal} (total occurrences : {total_occurrences}) | |
| <hr> | |
| <strong>🛠️ Note technique:</strong> | |
| Les mots sont surlignés par catégorie : intensificateurs en rouge, modérateurs en bleu, atténuateurs en gris, comparatifs en jaune et superlatifs en orange. | |
| Les phraséologismes héritent d'une teinte plus claire que celle de leur catégorie principale pour les distinguer visuellement des mots isolés et faciliter l'analyse. | |
| """ | |
| return report_md | |
| # ----------------------------- | |
| # INTERFACE GRADIO | |
| # ----------------------------- | |
| iface = gr.Interface( | |
| fn=analyse_text, | |
| inputs=gr.Textbox(label="Entrez le texte à analyser🖊️", lines=40, placeholder="Collez votre texte ici..."), | |
| outputs=gr.Markdown(label="Rapport"), | |
| title="Analyseur de modalisateurs et d'intensité textuelle🌡️", | |
| description=("Cette application détecte et surligne les modalisateurs (intensificateurs, modérateurs et atténuateurs) " | |
| "ainsi que les phraséologismes. Elle calcule ensuite le degré de la modalisation intensive du texte saisi et fournit " | |
| "des notes et conseils pour l'équivalence traductive 🌍.") | |
| ) | |
| if __name__ == "__main__": | |
| iface.launch(share=True) |