{"id":907,"date":"2026-07-12T08:29:16","date_gmt":"2026-07-12T06:29:16","guid":{"rendered":"https:\/\/www.gimp-libreoffice.fr\/?page_id=907"},"modified":"2026-07-12T20:20:51","modified_gmt":"2026-07-12T18:20:51","slug":"correcteur-typo-libreoffice","status":"publish","type":"page","link":"https:\/\/www.gimp-libreoffice.fr\/index.php\/outils\/correcteur-typo-libreoffice\/","title":{"rendered":"Correcteur Typo LibreOffice"},"content":{"rendered":"\n<style data-wp-block-html=\"css\">\n\/* Variables isol\u00e9es pour l'application *\/\n    .app-container {\n        --primary: #0a58ca;\n        --primary-hover: #084298;\n        --bg-color: #f8f9fa;\n        --text-color: #212529;\n        --border-color: #dee2e6;\n        --sidebar-bg: #e9ecef;\n        --code-bg: #f4f4f4;\n        --success: #198754;\n        \n        font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif;\n        display: flex;\n        color: var(--text-color);\n        background-color: var(--bg-color);\n        border: 1px solid var(--border-color);\n        border-radius: 8px;\n        margin-top: 20px;\n        position: relative;\n    }\n\n    \/* Scoping des \u00e9l\u00e9ments pour \u00e9viter les conflits *\/\n    .app-container h1, .app-container h2, .app-container h3 { margin-top: 0; }\n    \n    .app-container button {\n        background-color: var(--primary);\n        color: white;\n        border: none;\n        padding: 8px 12px;\n        border-radius: 4px;\n        cursor: pointer;\n        font-size: 14px;\n        transition: background-color 0.2s;\n    }\n\n    .app-container button:hover { background-color: var(--primary-hover); }\n    .app-container .btn-success { background-color: var(--success); }\n    .app-container .btn-success:hover { background-color: #157347; }\n\n    \/* Layout interne adaptatif *\/\n    .app-container .sidebar {\n        width: 300px;\n        background-color: var(--sidebar-bg);\n        border-right: 1px solid var(--border-color);\n        padding: 20px;\n        display: flex;\n        flex-direction: column;\n    }\n\n    .app-container .main-content {\n        flex-grow: 1;\n        padding: 30px;\n        display: flex;\n        flex-direction: column;\n    }\n\n    \/* Responsive Design pour mobile *\/\n    @media (max-width: 768px) {\n        .app-container {\n            flex-direction: column;\n        }\n        .app-container .sidebar {\n            width: 100%;\n            border-right: none;\n            border-bottom: 1px solid var(--border-color);\n        }\n    }\n\n    .app-container .theme-btn {\n        display: block;\n        width: 100%;\n        text-align: left;\n        background-color: transparent;\n        color: var(--text-color);\n        padding: 10px;\n        margin-bottom: 5px;\n        border-radius: 4px;\n    }\n\n    .app-container .theme-btn:hover, .app-container .theme-btn.active {\n        background-color: var(--border-color);\n    }\n\n    \/* Rule Cards *\/\n    .app-container .rule-card {\n        background: white;\n        border: 1px solid var(--border-color);\n        border-radius: 8px;\n        padding: 15px;\n        margin-bottom: 15px;\n        box-shadow: 0 2px 4px rgba(0,0,0,0.05);\n    }\n\n    .app-container .rule-header {\n        display: flex;\n        align-items: center;\n        margin-bottom: 15px;\n    }\n\n    .app-container .rule-header input[type=\"checkbox\"] {\n        margin-right: 10px;\n        width: 18px;\n        height: 18px;\n        cursor: pointer;\n    }\n\n    .app-container .regex-container {\n        display: grid;\n        grid-template-columns: 1fr 1fr;\n        gap: 15px;\n        background-color: var(--code-bg);\n        padding: 10px;\n        border-radius: 4px;\n        border: 1px solid var(--border-color);\n    }\n\n    .app-container .regex-box {\n        display: flex;\n        flex-direction: column;\n    }\n\n    .app-container .regex-box label {\n        font-size: 12px;\n        font-weight: bold;\n        color: #6c757d;\n        margin-bottom: 5px;\n    }\n\n    .app-container .code-row {\n        display: flex;\n        align-items: center;\n    }\n\n    .app-container code {\n        font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;\n        background-color: white;\n        padding: 6px 10px;\n        border: 1px solid var(--border-color);\n        border-radius: 4px 0 0 4px;\n        flex-grow: 1;\n        font-size: 14px;\n        word-break: break-all;\n    }\n\n    .app-container .copy-btn {\n        border-radius: 0 4px 4px 0;\n        padding: 6px 10px;\n    }\n\n    \/* Macro Section *\/\n    .app-container .macro-section {\n        margin-top: 30px;\n        padding-top: 20px;\n        border-top: 2px solid var(--border-color);\n    }\n\n    .app-container textarea#macro-output {\n        width: 100%;\n        height: 250px;\n        font-family: monospace;\n        padding: 10px;\n        border-radius: 4px;\n        border: 1px solid var(--border-color);\n        margin-top: 10px;\n        resize: vertical;\n    }\n\n    .app-container .top-bar {\n        display: flex;\n        justify-content: space-between;\n        align-items: center;\n        margin-bottom: 20px;\n        flex-wrap: wrap;\n        gap: 10px;\n    }\n\n    .app-container .toast {\n        position: absolute;\n        bottom: 20px;\n        right: 20px;\n        background-color: var(--success);\n        color: white;\n        padding: 10px 20px;\n        border-radius: 4px;\n        opacity: 0;\n        transition: opacity 0.3s;\n        pointer-events: none;\n        z-index: 100;\n    }\n\n    \/* Outils sp\u00e9cifiques *\/\n    .app-container .form-group {\n        margin-bottom: 15px;\n    }\n    .app-container .form-group label {\n        display: block;\n        margin-bottom: 5px;\n        font-weight: bold;\n        font-size: 14px;\n    }\n    .app-container .form-control {\n        width: 100%;\n        padding: 8px;\n        border: 1px solid var(--border-color);\n        border-radius: 4px;\n        font-size: 14px;\n        box-sizing: border-box;\n        font-family: monospace;\n    }\n    .app-container .checkbox-inline {\n        display: flex;\n        align-items: center;\n        gap: 10px;\n        margin-top: 10px;\n    }\n<\/style>\n\n<script data-wp-block-html=\"js\">\n\/\/ BASE DE DONN\u00c9ES DES R\u00c8GLES\n    const database = [\n        {\n            theme: \"1. Nettoyage structurel\",\n            rules: [\n                { id: \"net-1\", name: \"Espaces multiples et tabulations \u2192 espace simple\", search: \"[ \\\\t]{2,}\", replace: \" \", desc: \"Remplace 2 espaces (ou tabulations) ou plus par un seul.\" },\n                { id: \"net-2\", name: \"Suppression espaces en d\u00e9but d'alin\u00e9a\", search: \"^[ \\\\t]+\", replace: \"\", desc: \"Nettoie le d\u00e9but des paragraphes.\" },\n                { id: \"net-3\", name: \"Suppression espaces avant ponctuation\", search: \"[ \\\\t]+([.,)\\\\]])\", replace: \"$1\", desc: \"Supprime l'espace avant point, virgule, parenth\u00e8se ou crochet fermant.\" }\n            ]\n        },\n       {\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 theme: \"2. Typographie & Ponctuation\",\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 rules: [\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 { id: \"typo-1\", name: \"Points r\u00e9p\u00e9t\u00e9s \u2192 points de suspension\", search: \"\\\\.{2,}\", replace: \"\u2026\", desc: \"Convertit .. ou ... en vrai caract\u00e8re \u2026\" },\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 { id: \"typo-2\", name: \"Apostrophe dactylo \u2192 typo\", search: \"'\", replace: \"\u2019\", desc: \"Apostrophe droite vers courbe.\" },\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 { id: \"typo-3\", name: \"Espaces ins\u00e9cables avant ponctuations hautes\", search: \"([a-zA-Z\u00c0-\u00ff0-9\u00bb>])[ \\\\t]*([!?:;])\", replace: \"$1\\u00A0$2\", desc: \"Ajoute ou remplace l'espace par une ins\u00e9cable (U+00A0) avant ! ? : ;\" }\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 ]\n\u00a0 \u00a0 \u00a0 \u00a0 },\n\u00a0 \u00a0 \u00a0 \u00a0 {\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 theme: \"3. Nombres et Dates\",\n            rules: [\n                { id: \"num-1\", name: \"Heure erron\u00e9e (suppr 0 avant h)\", search: \"\\\\b0h\\\\b\", replace: \"h\", desc: \"ex: 15 0h \u2192 15 h (et g\u00e8re l'espace avant).\" },\n                { id: \"num-2\", name: \"Espace ins\u00e9cable milliers (4 chiffres min)\", search: \"([0-9])([0-9]{3})(?=[^0-9]|$)\", replace: \"$1\\u00A0$2\", desc: \"Ex: 1000 \u2192 1 000 (\u00e0 r\u00e9p\u00e9ter si n\u00e9cessaire).\" }\n            ]\n        },\n        {\n            theme: \"4. Abr\u00e9viations\",\n            rules: [\n                { id: \"abr-1\", name: \"Corrige etc...\", search: \"etc\\\\.{2,}|etc\u2026\", replace: \"etc.\", desc: \"Remet etc. au propre.\" },\n                { id: \"abr-2\", name: \"Monsieur (M.) + ins\u00e9cable\", search: \"\\\\bM\\\\.[ \\\\t]+([A-Z])\", replace: \"M.\\u00A0$1\", desc: \"Assure l'ins\u00e9cable entre M. et le nom propre.\" },\n                { id: \"abr-3\", name: \"Madame (Mme) + ins\u00e9cable\", search: \"\\\\bMme\\\\.?[ \\\\t]+([A-Z])\", replace: \"Mme\\u00A0$1\", desc: \"Assure l'ins\u00e9cable entre Mme et le nom propre (standardise sans point).\" }\n            ]\n        },\n        {\n            theme: \"5. Orthotypographie & Traits d'union\",\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 rules: [\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 { id: \"ortho-1\", name: \"c'est \u00e0 dire \u2192 c'est-\u00e0-dire\", search: \"c'est[ \\\\t]+\u00e0[ \\\\t]+dire\", replace: \"c'est-\u00e0-dire\", desc: \"Ajout des traits d'union peu importe l'espace d'origine.\" },\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 { id: \"ortho-2\", name: \"Chef-d'\u0153uvre (Ligatures et syntaxe)\", search: \"([Cc]hef[s]?)[ \\\\t-]*d['\u2019]oeuvre([s]?)\", replace: \"$1-d\u2019\u0153uvre$2\", desc: \"Corrige l'orthographe, le trait d'union et l'apostrophe.\" },\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 { id: \"ortho-3\", name: \"Premi\u00e8re Guerre mondiale\", search: \"[Pp]remi\u00e8re [Gg]uerre [Mm]ondiale\", replace: \"Premi\u00e8re Guerre mondiale\", desc: \"Gestion des majuscules historiques.\" }\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 ]\n\u00a0 \u00a0 \u00a0 \u00a0 }\n\u00a0 \u00a0 ];\n\n\u00a0 \u00a0 let currentTheme = 'all';\n\n    function init() {\n        renderSidebar();\n        renderRules('all');\n    }\nfunction updateAllToolReplace() {\n    const isCalc = document.getElementById('calc-format').checked;\n    const replaceVal = isCalc ? \"\\\\n$0\\\\n\" : \"$0\";\n    const replaceBetweenVal = isCalc ? \"\\\\n$2\\\\n\" : \"$2\";\n\n    \/\/ Met \u00e0 jour les e-mails et URLs\n    document.querySelectorAll('.replace-code').forEach(el => el.innerText = replaceVal);\n    \/\/ Met \u00e0 jour le \"entre balises\"\n    document.querySelectorAll('.replace-between-code').forEach(el => el.innerText = replaceBetweenVal);\n}\n\nfunction updateBetweenRegex() {\n    let start = document.getElementById('regex-start').value;\n    let end = document.getElementById('regex-end').value;\n    let searchEl = document.getElementById('regex-between-search');\n\n    if (!start || !end) {\n        searchEl.innerText = 'Saisissez un d\u00e9but et une fin...';\n        return;\n    }\n\n    let escapeRegExp = (string) => string.replace(\/[.*+?^${}()|[\\]\\\\]\/g, '\\\\$&');\n    \n    \/\/ On cr\u00e9e 3 groupes : (D\u00e9but)(Contenu)(Fin)\n    let finalRegex = \"(\" + escapeRegExp(start) + \")(.*?)(\" + escapeRegExp(end) + \")\";\n    \n    searchEl.innerText = finalRegex;\n}\nfunction updateToolRegexes() {\n    const addNewline = document.getElementById('add-newline').checked;\n    const replaceVal = addNewline ? \"$0\\\\n\" : \"$0\";\n    \n    \/\/ Met \u00e0 jour les champs de remplacement visuels\n    document.getElementById('regex-email-replace').innerText = replaceVal;\n    document.getElementById('regex-url-replace').innerText = replaceVal;\n}\n\nfunction updateCalcMode() {\n    const isCalc = document.getElementById('calc-format').checked;\n    const output = document.getElementById('regex-replace-output');\n    \n    \/\/ Si coch\u00e9, on propose \\n$0\\n pour isoler totalement l'\u00e9l\u00e9ment pour Calc\n    output.innerText = isCalc ? \"\\\\n$0\\\\n\" : \"$0\";\n}\n\n\n    function renderSidebar() {\n        const list = document.getElementById('theme-list');\n        list.innerHTML = `<button class=\"theme-btn active\" onclick=\"selectTheme('all', this)\">Tous les traitements<\/button>`;\n        \n        database.forEach(theme => {\n            list.innerHTML += `<button class=\"theme-btn\" onclick=\"selectTheme('${theme.theme}', this)\">${theme.theme}<\/button>`;\n        });\n    }\n\n    function selectTheme(themeName, btnElement) {\n        currentTheme = themeName;\n        document.querySelectorAll('.theme-btn').forEach(btn => btn.classList.remove('active'));\n        btnElement.classList.add('active');\n        \n        document.getElementById('current-theme-title').innerText = themeName === 'all' ? 'Tous les traitements' : themeName;\n        \n        document.getElementById('rules-container').style.display = 'block';\n        document.getElementById('macro-section').style.display = 'block';\n        document.getElementById('current-theme-title').parentElement.style.display = 'flex';\n        document.getElementById('tools-container').style.display = 'none';\n\n        renderRules(themeName);\n    }\n\n    function showTools(btnElement) {\n        document.querySelectorAll('.theme-btn').forEach(btn => btn.classList.remove('active'));\n        btnElement.classList.add('active');\n\n        document.getElementById('rules-container').style.display = 'none';\n        document.getElementById('macro-section').style.display = 'none';\n        document.getElementById('current-theme-title').parentElement.style.display = 'none';\n        document.getElementById('tools-container').style.display = 'block';\n    }\n\n \n\n    function renderRules(themeName) {\n        const container = document.getElementById('rules-container');\n        container.innerHTML = '';\n\n        database.forEach(theme => {\n            if (themeName === 'all' || theme.theme === themeName) {\n                \n                if (themeName === 'all') {\n                    container.innerHTML += `<h3 style=\"margin-top: 20px; border-bottom: 1px solid #ccc; padding-bottom: 5px;\">${theme.theme}<\/h3>`;\n                }\n\n                theme.rules.forEach(rule => {\n                    container.innerHTML += `\n                        <div class=\"rule-card\">\n                            <div class=\"rule-header\">\n                                <input type=\"checkbox\" id=\"chk-${rule.id}\" class=\"rule-checkbox\" checked data-search=\"${encodeURIComponent(rule.search)}\" data-replace=\"${encodeURIComponent(rule.replace)}\">\n                                <label for=\"chk-${rule.id}\"><strong>${rule.name}<\/strong> <span style=\"color:#666; font-weight:normal;\">\u2014 ${rule.desc}<\/span><\/label>\n                            <\/div>\n                            <div class=\"regex-container\">\n                                <div class=\"regex-box\">\n                                    <label>Rechercher :<\/label>\n                                    <div class=\"code-row\">\n                                        <code id=\"search-${rule.id}\">${escapeHtml(rule.search)}<\/code>\n                                        <button class=\"copy-btn\" onclick=\"copyText('search-${rule.id}')\">Copier<\/button>\n                                    <\/div>\n                                <\/div>\n                                <div class=\"regex-box\">\n                                    <label>Remplacer par :<\/label>\n                                    <div class=\"code-row\">\n                                        <code id=\"replace-${rule.id}\">${escapeHtml(rule.replace)}<\/code>\n                                        <button class=\"copy-btn\" onclick=\"copyText('replace-${rule.id}')\">Copier<\/button>\n                                    <\/div>\n                                <\/div>\n                            <\/div>\n                        <\/div>\n                    `;\n                });\n            }\n        });\n    }\n\n    function selectAll() {\n        document.querySelectorAll('.rule-checkbox').forEach(chk => chk.checked = true);\n    }\n    \n    function deselectAll() {\n        document.querySelectorAll('.rule-checkbox').forEach(chk => chk.checked = false);\n    }\n\n    function copyText(elementId) {\n        const text = document.getElementById(elementId).innerText;\n        fallbackCopy(text);\n    }\n\n    function copyMacro() {\n        const text = document.getElementById('macro-output').value;\n        if(text) {\n            fallbackCopy(text);\n        }\n    }\n\n    function fallbackCopy(text) {\n        const textArea = document.createElement(\"textarea\");\n        textArea.value = text;\n        textArea.style.position = \"fixed\";\n        textArea.style.opacity = \"0\";\n        document.body.appendChild(textArea);\n        textArea.focus();\n        textArea.select();\n        \n        try {\n            document.execCommand('copy');\n            showToast();\n        } catch (err) {\n            console.error('Erreur lors de la copie', err);\n        }\n        \n        document.body.removeChild(textArea);\n    }\n\n    function showToast() {\n        const toast = document.getElementById('toast');\n        toast.style.opacity = 1;\n        setTimeout(() => toast.style.opacity = 0, 2000);\n    }\n\n    function escapeHtml(unsafe) {\n        return unsafe\n            .replace(\/&\/g, \"&amp;\")\n            .replace(\/<\/g, \"&lt;\")\n            .replace(\/>\/g, \"&gt;\")\n            .replace(\/\"\/g, \"&quot;\")\n            .replace(\/'\/g, \"&#039;\");\n    }\n\n    function generateMacro() {\n        const checkboxes = document.querySelectorAll('.rule-checkbox:checked');\n        \n        if(checkboxes.length === 0) {\n            document.getElementById('macro-output').value = \"' Aucune r\u00e8gle s\u00e9lectionn\u00e9e.\";\n            return;\n        }\n\n        let macroCode = `' Macro g\u00e9n\u00e9r\u00e9e automatiquement pour le nettoyage typographique\n' Respectez les options de recherche (Expressions r\u00e9guli\u00e8res coch\u00e9es)\nSub CorrectionTypoAutomatique\n    Dim oDoc As Object\n    Dim oReplace As Object\n    Dim searchArray As Variant\n    Dim replaceArray As Variant\n    Dim i As Integer\n\n    oDoc = ThisComponent\n    oReplace = oDoc.createReplaceDescriptor()\n    \n    ' Configuration de la recherche\n    oReplace.SearchRegularExpression = True\n    oReplace.SearchCaseSensitive = True\n\n    ' Tableaux des recherches et remplacements\n    searchArray = Array( _\\n`;\n        \n        let replaceCode = `    replaceArray = Array( _\\n`;\n\n        checkboxes.forEach((chk, index) => {\n            const isLast = index === checkboxes.length - 1;\n            const searchStr = decodeURIComponent(chk.getAttribute('data-search')).replace(\/\"\/g, '\"\"');\n            const replaceStr = decodeURIComponent(chk.getAttribute('data-replace')).replace(\/\"\/g, '\"\"');\n            \n            macroCode += `        \"${searchStr}\"${isLast ? \"\" : \", _\"}\\n`;\n            replaceCode += `        \"${replaceStr}\"${isLast ? \"\" : \", _\"}\\n`;\n        });\n\n        macroCode += `    )\\n\\n`;\n        replaceCode += `    )\\n\\n`;\n\n        const loopCode = `    ' Boucle d'ex\u00e9cution\n    For i = LBound(searchArray) To UBound(searchArray)\n        oReplace.SearchString = searchArray(i)\n        oReplace.ReplaceString = replaceArray(i)\n        oDoc.replaceAll(oReplace)\n    Next i\n    \n    MsgBox \"Correction termin\u00e9e (\" & (UBound(searchArray) + 1) & \" r\u00e8gles appliqu\u00e9es).\", 64, \"Correcteur Typo\"\nEnd Sub`;\n\n        document.getElementById('macro-output').value = macroCode + replaceCode + loopCode;\n    }\n\n    if (document.readyState === 'loading') {\n        document.addEventListener('DOMContentLoaded', init);\n    } else {\n        init();\n    }\n<\/script>\n\n<h1>Correcteur Typo LibreOffice<\/h1>\n<div class=\"app-container\">\n    <div class=\"sidebar\">\n        <h2>Th\u00e8mes<\/h2>\n        <p style=\"font-size: 13px; color: #666;\">Respectez l\u2019ordre de traitement pour \u00e9viter les conflits.<\/p>\n        <div id=\"theme-list\">\n            <!-- Themes injected via JS -->\n        <\/div>\n        \n        <h2 style=\"margin-top: 30px;\">Utilitaires<\/h2>\n        <button class=\"theme-btn\" id=\"btn-tools\" onclick=\"showTools(this)\">Bo\u00eete \u00e0 outils (Emails, URLs\u2026)<\/button>\n    <\/div>\n\n    <div class=\"main-content\">\n        <div class=\"top-bar\">\n            <h2 id=\"current-theme-title\">Tous les traitements<\/h2>\n            <div>\n                <button onclick=\"selectAll()\">Tout cocher<\/button>\n                <button onclick=\"deselectAll()\">Tout d\u00e9cocher<\/button>\n            <\/div>\n        <\/div>\n\n        <div id=\"rules-container\">\n            <!-- Rules injected via JS -->\n        <\/div>\n\n        <!-- Section des Outils (Masqu\u00e9e par d\u00e9faut) -->\n<div id=\"tools-container\" style=\"display: none;\">\n    <div class=\"top-bar\">\n        <h2>Bo\u00eete \u00e0 outils d\u2019extraction<\/h2>\n    <\/div>\n\n    <div class=\"rule-card\">\n        <h3>Configuration de l&rsquo;export<\/h3>\n        <div class=\"form-group checkbox-inline\">\n            <input type=\"checkbox\" id=\"calc-format\" onchange=\"updateAllToolReplace()\">\n            <label for=\"calc-format\" style=\"font-weight: bold; color: var(--primary);\">Activer le formatage pour Calc (Ajoute \\n autour des \u00e9l\u00e9ments)<\/label>\n        <\/div>\n    <\/div>\n\n    <!-- 1. Emails -->\n    <div class=\"rule-card\">\n        <h3>E-mails<\/h3>\n        <div class=\"regex-container\">\n            <div class=\"regex-box\">\n                <label>Rechercher :<\/label>\n                <code>[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}<\/code>\n            <\/div>\n            <div class=\"regex-box\">\n                <label>Remplacer :<\/label>\n                <code class=\"replace-code\" id=\"replace-email\">$0<\/code>\n            <\/div>\n        <\/div>\n    <\/div>\n\n    <!-- 2. URLs -->\n    <div class=\"rule-card\">\n        <h3>URLs<\/h3>\n        <div class=\"regex-container\">\n            <div class=\"regex-box\">\n                <label>Rechercher :<\/label>\n                <code>https?:\/\/[^\\s&lt;&gt;\"]+|www\\.[^\\s&lt;&gt;\"]+<\/code>\n            <\/div>\n            <div class=\"regex-box\">\n                <label>Remplacer :<\/label>\n                <code class=\"replace-code\" id=\"replace-url\">$0<\/code>\n            <\/div>\n        <\/div>\n    <\/div>\n\n<!-- 3. Entre Balises -->\n    <div class=\"rule-card\">\n        <h3>Entre balises \/ textes<\/h3>\n        <div class=\"form-group\">\n            <label>D\u00e9but (ex: &lt;b&gt;) :<\/label>\n            <input type=\"text\" id=\"regex-start\" class=\"form-control\" oninput=\"updateBetweenRegex()\">\n        <\/div>\n        <div class=\"form-group\">\n            <label>Fin (ex: &lt;\/b&gt;) :<\/label>\n            <input type=\"text\" id=\"regex-end\" class=\"form-control\" oninput=\"updateBetweenRegex()\">\n        <\/div>\n        <div class=\"regex-container\" style=\"margin-top: 10px;\">\n            <div class=\"regex-box\" style=\"grid-column: 1 \/ -1;\">\n                <label>Rechercher :<\/label>\n                <div class=\"code-row\">\n                    <code id=\"regex-between-search\">Saisissez un d\u00e9but et une fin...<\/code>\n                    <button class=\"copy-btn\" onclick=\"copyText('regex-between-search')\">Copier<\/button>\n                <\/div>\n            <\/div>\n            <div class=\"regex-box\" style=\"grid-column: 1 \/ -1;\">\n                <label>Remplacer (pour extraire le contenu $2) :<\/label>\n                <div class=\"code-row\">\n                    <code class=\"replace-between-code\" id=\"replace-between\">$2<\/code>\n                    <button class=\"copy-btn\" onclick=\"copyText('replace-between')\">Copier<\/button>\n                <\/div>\n            <\/div>\n        <\/div>\n    <\/div>\n        <div class=\"macro-section\" id=\"macro-section\">\n            <div class=\"top-bar\">\n                <h2>G\u00e9n\u00e9rateur de Macro LibreOffice BASIC<\/h2>\n                <button class=\"btn-success\" onclick=\"generateMacro()\">G\u00e9n\u00e9rer la macro avec la s\u00e9lection<\/button>\n            <\/div>\n            <p style=\"font-size: 14px; color: #666;\">Copiez ce code et collez-le dans <code>Outils &gt; Macros &gt; \u00c9diter les macros<\/code>.<\/p>\n            <textarea id=\"macro-output\" readonly=\"\" placeholder=\"Le code de la macro appara\u00eetra ici...\"><\/textarea>\n            <br><br>\n            <button onclick=\"copyMacro()\">Copier la Macro<\/button>\n        <\/div>\n    <\/div>\n\n    <div id=\"toast\" class=\"toast\">Copi\u00e9 !<\/div>\n<\/div><\/div>\n","protected":false},"excerpt":{"rendered":"<div class=\"slide-text-bg2\">\n<h3>Correcteur Typo LibreOffice Th\u00e8mes Respectez l\u2019ordre de traitement pour \u00e9viter les conflits. Utilitaires Bo\u00eete \u00e0 outils (Emails, URLs\u2026) Tous les<\/h3>\n<\/div>\n<div class=\"flex-btn-div\"><a href=\"https:\/\/www.gimp-libreoffice.fr\/index.php\/outils\/correcteur-typo-libreoffice\/\" class=\"btn1 flex-btn\">Lire la suite<\/a><\/div>\n","protected":false},"author":1,"featured_media":0,"parent":915,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-907","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.gimp-libreoffice.fr\/index.php\/wp-json\/wp\/v2\/pages\/907","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.gimp-libreoffice.fr\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.gimp-libreoffice.fr\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.gimp-libreoffice.fr\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.gimp-libreoffice.fr\/index.php\/wp-json\/wp\/v2\/comments?post=907"}],"version-history":[{"count":19,"href":"https:\/\/www.gimp-libreoffice.fr\/index.php\/wp-json\/wp\/v2\/pages\/907\/revisions"}],"predecessor-version":[{"id":933,"href":"https:\/\/www.gimp-libreoffice.fr\/index.php\/wp-json\/wp\/v2\/pages\/907\/revisions\/933"}],"up":[{"embeddable":true,"href":"https:\/\/www.gimp-libreoffice.fr\/index.php\/wp-json\/wp\/v2\/pages\/915"}],"wp:attachment":[{"href":"https:\/\/www.gimp-libreoffice.fr\/index.php\/wp-json\/wp\/v2\/media?parent=907"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}