[Résolu][Writer] Supprimer fins paragraphe en milieu phrase

Discussions et questions sur tout ce qui concerne la programmation tous langages et tous modules confondus.

Modérateur : Vilains modOOs

Règles du forum
:alerte: Balisage obligatoire dans cette section !
Aidez-nous à vous aider au mieux en balisant correctement votre question : reportez-vous sur les règles de cette section avant de poster !
forumateur
Membre lOOyal
Membre lOOyal
Messages : 28
Inscription : 11 nov. 2008 00:28

[Résolu][Writer] Supprimer fins paragraphe en milieu phrase

Message par forumateur »

Bonjour,
Un problème souvent débattu mais pour lequel je n'ai pas trouvé de solution satisfaisante:
Quand on extrait du texte à partir d'un PDF, on obtient des coupures très fréquentes des phrases par des marques de paragraphe.
Je cherche à écrire une macro qui résolve ce problème, c'est à dire qui remplace les marques de paragraphe qui suivent une lettre ou une virgule par un espace (mais n'enlève pas les marques de paragraphes qui suivent "." ":" ou ";" par exemple).

Mais :

Code : Tout sélectionner

repl.SearchRegularExpression = True
repl.SearchString = "$"
repl.ReplaceString = " "
document.replaceAll(repl)
trouve bien toutes les marques de paragraphe et les remplace par un espace;

par contre :

Code : Tout sélectionner

repl.SearchRegularExpression = True
repl.SearchString = "e$"
repl.ReplaceString = "e "
document.replaceAll(repl)
trouve bien les "e" suivis d'une marque de paragraphe, mais ajoute un espace après le "e" sans supprimer la marque de paragraphe.
Je ne comprends pas comment faire...
Quelqu'un peut-il m'aider . Y a-t-il un autre moyen de sélectionner et supprimer ces marques de paragraphe ?
Merci
Dernière modification par forumateur le 05 juil. 2019 09:22, modifié 2 fois.
LibreOffice 6.1 sous Windows 10
(LibreOffice 6.1 par choix)
Jeff
GourOOu
GourOOu
Messages : 9608
Inscription : 18 sept. 2006 11:40
Localisation : France

Re: [Writer] Supprimer marques de paragraphe en milieu de ph

Message par Jeff »

Bonjour,

Les marques de paragraphes sont souvent plus complexes à sélectionner que les marques de fin de ligne, j'utilise donc l'extension [Writer] Remplacer fins de ligne ⇿ fins de paragraphe.

Si je prends le texte suivant, extrait d'un tuto sur le forum :
Capture du 2019-07-01 09-20-30.png
Menu Édition > Rechercher et remplacer, je cherche une lettre minuscule en fin de paragraphe, puis y ajoute une espace :
Rechercher :

Code : Tout sélectionner

[:alpha:]$
Remplacer : le code exact est &espace

L'extension citée plus haut me donne une entrée dans le menu Édition, qui est Fin paragraphe :arrow: Fin ligne, tous les paragraphes sont convertis en fin de ligne.

Je recherche toutes les espaces suivies d'une fin de ligne :
Rechercher : le code exact est espace\n
Remplacer : saisir une espace

L'extension citée plus haut me donne une entrée dans le menu Édition, qui est Fin ligne :arrow: Fin paragraphe, toutes les fins de ligne sont converties en paragraphe, j'obtiens :
Capture du 2019-07-01 09-32-14.png
dans l'extrait que j'ai choisi, je dois encore sélectionner les espace suivies d'une majuscule :
Rechercher :

Code : Tout sélectionner

 [:upper:]
le code exact est espace[:upper:]
Remplacer par : Au final, en moins d'un quart d'heure, j'obtiens :
Capture du 2019-07-01 09-38-57.png
Il y a encore une espace parasite en début de certaines lignes due au dernier traitement, pour laquelle je préconise plutôt le formateur de texte de Grammalecte, qui va se charger de nettoyer les espaces superflues, mais également des apostrophes typographiques et quantité d'autres options :

Image

À toi de voir si tu veux créer une macro basée sur cette démarche :wink:

A +
Avatar de l’utilisateur
Dredd
Membre cOOnverti
Membre cOOnverti
Messages : 362
Inscription : 24 mai 2006 11:15
Localisation : Mega-City One

Re: [Writer] Supprimer marques de paragraphe en milieu de ph

Message par Dredd »

Bonjour,

Regarde du côté de l'extension altsearch.
https://forum.openoffice.org/fr/forum/v ... hp?t=29800
Propulsé par OpenOffice 4.1.6 sous Windows 10 x64
forumateur
Membre lOOyal
Membre lOOyal
Messages : 28
Inscription : 11 nov. 2008 00:28

Re: [Writer] Supprimer marques de paragraphe en milieu de ph

Message par forumateur »

Merci Jeff !!
En effet avec des ↵ çà marche. Exemple

Rechercher :

Code : Tout sélectionner

([a-z])(\n)
Remplacer : fait le job !

L'extension [Writer] Remplacer fins de ligne ⇿ fins de paragraphe marche très bien.

La seule chose qui me chagrine un peu est de remplacer toutes les ¶, et pas seulement celles qui ne suivent pas une ponctuation : "." ou ";" ou ":" .

Merci encore
LibreOffice 6.1 sous Windows 10
(LibreOffice 6.1 par choix)
forumateur
Membre lOOyal
Membre lOOyal
Messages : 28
Inscription : 11 nov. 2008 00:28

Re: [Writer] Supprimer marques de paragraphe en milieu de ph

Message par forumateur »

Merci Dredd !

Avec Altsearch, en recherchant : e\p et en remplaçant par e suivi d'un espace, j'arrive à supprimer les ¶ précédées d'un e.
Mais si je mets [a-z]\p dans Rechercher, que faut-il mettre dans Remplacer pour que la lettre entre a et z soit conservée et suivie d'un espace en supprimant la ¶ ? (pour ne pas avoir à faire la manip pour chaque lettre séparément...)

Merci pour ton aide !
LibreOffice 6.1 sous Windows 10
(LibreOffice 6.1 par choix)
forumateur
Membre lOOyal
Membre lOOyal
Messages : 28
Inscription : 11 nov. 2008 00:28

Re: [Writer] Supprimer marques de paragraphe en milieu de ph

Message par forumateur »

Bonjour à tous,
J'ai poursuivi mes essais.
Dans un texte assez long (j'ai testé sur 40 pages environ) l'addon Remplacer fins de paragraphe ⇿ fins de ligne met 3 à 4 minutes !
Je recherche donc toujours une solution avec une macro Basic.
Le problème vient de ce que :

Rechercher : $ sélectionne la marque paragraphe, mais :
Rechercher : a$ sélectionne le “a” avant une marque de paragraphe
Par contre, Rechercher : a\n sélectionne bien “a” ET le saut de ligne.
Dans une macro Basic :
Y a-t-il un moyen autre pour sélectionner un caractère [a-z] et la marque paragraphe qui le suit ?
Pourquoi ne peut-on pas remplacer les marques de paragraphe recherchées avec $ par un saut de ligne \n ?
Y a-t-il moyen un fois sélectionné le “a” devant une marque de paragraphe d'étendre la sélection au caractère suivant (c'est-à-dire la marque de paragraphe) ?
Si vous avez une idée, Merci !
LibreOffice 6.1 sous Windows 10
(LibreOffice 6.1 par choix)
Avatar de l’utilisateur
Hubert Lambert
SuppOOrter
SuppOOrter
Messages : 1214
Inscription : 06 avr. 2016 09:26

Re: [Writer] Supprimer marques de paragraphe en milieu de ph

Message par Hubert Lambert »

Bonjour,

Ci-joint un petit script python qui, a priori, devrait aider.
Pour l'utiliser (pour LibreOffice uniquement) :
1. décompresser le fichier joint et extraire le fichier "forumateur.py" dans le répertoire "<profil utilisateur>\Scripts\python" (si nécessaire, créer les répertoires "Scripts" et "python" en respectant bien la casse);
2. depuis le menu Outils -> Macros -> Exécuter la macro -> Mes macros -> forumateur, lancer au choix "supprimer_faux_retours" ou "supprimer_faux_retours_selection", suivant que tu souhaites appliquer la recherche à tout le document ou à la sélection courante seulement.

J'ai testé sur un document de 250 pages, cela prend quelque petites secondes. Pour les grands documents, la macro générale est plus rapide que celle qui s'applique à la sélection.
Normalement, les textes contenus dans les cadres et tableaux sont aussi pris en compte.

Cordialement.

________
Le code pour les curieux :

Code : Tout sélectionner

# -*- coding: utf-8 -*-

from string import ascii_lowercase, whitespace

def supprimer_faux_retours(event=None):
    '''Supprime les marques de paragraphes situées en milieu de phrase.
    Agit sur le document entier'''
    doc = XSCRIPTCONTEXT.getDocument()
    undo = doc.UndoManager
    undo.enterUndoContext('Supprimer faux retours')
    doc.lockControllers()
    try:
        _supprimer_faux_retours(doc)
        win = doc.CurrentController.ComponentWindow
        win.Toolkit.createMessageBox(win, 0, 1, "", "Ok !").execute()
    finally:
        doc.unlockControllers()
        undo.leaveUndoContext()


def supprimer_faux_retours_selection(event=None):
    '''Supprime les marques de paragraphes situées en milieu de phrase.
    Agit sur la sélection uniquement.'''
    doc = XSCRIPTCONTEXT.getDocument()
    undo = doc.UndoManager
    undo.enterUndoContext('Supprimer faux retours (sélection)')
    doc.lockControllers()
    try:
        for selection in doc.CurrentSelection:
            T = selection.Text
            tcursor = T.createTextCursorByRange(selection)
            tcursor.gotoEndOfSentence(False)
            while tcursor.gotoNextSentence(True):
                if T.compareRegionEnds(tcursor, selection) < 0:
                    break
                if tcursor.String.startswith('\r\n'):
                    s = ' '
                    while s in whitespace:
                        tcursor.goRight(1, True)
                        s = tcursor.String[-1]
                    if s in ascii_lowercase:
                        tcursor.String = ' ' + s
                tcursor.gotoEndOfSentence(False)
            for p in selection.createEnumeration():
                try:
                    if p.supportsService('com.sun.star.text.TextTable'):
                        cellnames = p.CellNames
                        for cellname in cellnames:
                            cell = p.getCellByName(cellname)
                            _supprimer_faux_retours(cell)
                except AttributeError:
                        pass
            for textcontent in selection.createContentEnumeration('com.sun.star.text.TextContent'):
                if textcontent.supportsService('com.sun.star.text.TextFrame'):
                    _supprimer_faux_retours(textcontent)
            win = doc.CurrentController.ComponentWindow
        win.Toolkit.createMessageBox(win, 0, 1, "", "Ok !").execute()
    finally:
        doc.unlockControllers()
        undo.leaveUndoContext()


def _supprimer_faux_retours(container):
    T = container.Text
    tcursor = T.createTextCursor()
    tcursor.gotoEndOfSentence(False)
    while tcursor.gotoNextSentence(True):
        if tcursor.String.startswith('\r\n'):
            s = ' '
            while s in whitespace:
                tcursor.goRight(1, True)
                s = tcursor.String[-1]
            if s in ascii_lowercase:
                tcursor.String = ' ' + s
        tcursor.gotoEndOfSentence(False)
    try:
        for frame in container.TextFrames:
            _supprimer_faux_retours(frame)
    except AttributeError:
        pass
    try:
        for table in container.TextTables:
            cellnames = table.CellNames
            for cellname in cellnames:
                cell = table.getCellByName(cellname)
                _supprimer_faux_retours(cell)
    except AttributeError:
        pass


g_exportedScripts = supprimer_faux_retours, supprimer_faux_retours_selection,
Pièces jointes
forumateur.py.zip
(1.03 Kio) Téléchargé 79 fois
AOOo 4.1.7 sur Win10
AOOo 4.1.x sur Linux Mint
LibreOffice 5.x/6.x sur Linux Mint
--
| « Nos défauts devraient nous donner une qualité : l'indulgence pour les défauts des autres » (Rivarol)
forumateur
Membre lOOyal
Membre lOOyal
Messages : 28
Inscription : 11 nov. 2008 00:28

Re: [Writer] Supprimer marques de paragraphe en milieu de ph

Message par forumateur »

Merci beaucoup Hubert, çà parait très intéressant, mais je n'ai pas réussi à faire fonctionner...
Faut dire que je suis débutant en basic, mais aucune notion en python.

J'ai décompressé comme indiqué dans le dossier python que j'ai créé.

Quand je cherche à exécuter la macro, la bibliothèque forumateur est bien présente, mais pas de macro visible.

Quand je rentre par "gérer les macros", j'ai bien les 2 macros supprimer_faux_retours, mais si je demande exécution, j'ai le message d'erreur "Fatal Error" : "pyuno._createUnoStructHelper: member 'Context' of struct type 'com.sun.star.uno.Exception' not given a value;"
Qu'est-ce que j'ai fait comme bétise ??
Y a-t-il un autre moyen d'enregistrer cette macro à partir du code que tu as donné ?
J'en profite pour te demander si tu as une idée pourquoi on peut faire cette macro pour supprimer les marque paragrahes en python et pas en basic ?
Merci
LibreOffice 6.1 sous Windows 10
(LibreOffice 6.1 par choix)
forumateur
Membre lOOyal
Membre lOOyal
Messages : 28
Inscription : 11 nov. 2008 00:28

Re: [Writer] Supprimer marques de paragraphe en milieu de ph

Message par forumateur »

P.S.
Pour Hubert,
Avec Notepad++, j'arrive bien à ouvrir la macro .py ...
LibreOffice 6.1 sous Windows 10
(LibreOffice 6.1 par choix)
Avatar de l’utilisateur
Hubert Lambert
SuppOOrter
SuppOOrter
Messages : 1214
Inscription : 06 avr. 2016 09:26

Re: [Writer] Supprimer marques de paragraphe en milieu de ph

Message par Hubert Lambert »

Bonjour,

Voici une version plus simple, qui fonctionne en outre également sous linux. Je joins également un document avec la macro intégrée, pour voir si cela fait une différence.
Pourrais-tu, si elle se reproduit, faire une capture d'écran de l'erreur ?
J'ai choisi python pour sa faciliter dans la manipulation des textes (et aussi parce que je m'y sens mieux :wink: ), mais dans le cas présent l'équivalent en basic devrait être très proche. Je le transcrirai si ça te convient.
Cordialement.
Pièces jointes
forumateur.py.zip
(993 octets) Téléchargé 91 fois
forumateur.odt
(22.23 Kio) Téléchargé 100 fois
AOOo 4.1.7 sur Win10
AOOo 4.1.x sur Linux Mint
LibreOffice 5.x/6.x sur Linux Mint
--
| « Nos défauts devraient nous donner une qualité : l'indulgence pour les défauts des autres » (Rivarol)
forumateur
Membre lOOyal
Membre lOOyal
Messages : 28
Inscription : 11 nov. 2008 00:28

Re: [Writer] Supprimer marques de paragraphe en milieu de ph

Message par forumateur »

Merci Hubert,
Il ne se passe rien quand je clique sur les boutons dans le .odt que tu as joins.
Et même résultat que précédemment avec la macro simplifiée...
Pour le message d'erreur, je te le mets en pièce jointe...
Est-ce qu'il peut y avoir un rapport, quand je cherche à entrer dans les macros, libreoffice m'envoie parfois, mais pas toujours un message me demandant d'installer Java JRE bits, qui est normalement installé (version 8) (et les macros basic marchent bien; est-ce qu'elles utilisent aussi Java ?)
Cordialement


P.S.
Si tu as l'équivallent en basic, je suis preneur ++, et au vu de mes recherches sur différents forums, c'est une question qui a été souvent soulevée, et pas totalement résolue. Alors, ce serait une grande avancée pour tous !!
Merci encore
Pièces jointes
Capture.JPG
LibreOffice 6.1 sous Windows 10
(LibreOffice 6.1 par choix)
Avatar de l’utilisateur
Hubert Lambert
SuppOOrter
SuppOOrter
Messages : 1214
Inscription : 06 avr. 2016 09:26

Re: [Writer] Supprimer marques de paragraphe en milieu de ph

Message par Hubert Lambert »

Est-ce que tu as bien respecté la casse dans le chemin du fichier py : "Scripts" avec majuscule initiale et "python" en minuscules ?
Quant au fichier exemple, assure-toi que l'exécution de macros embarquées est bien autorisée : Outils-> Options-> Sécurité.
AOOo 4.1.7 sur Win10
AOOo 4.1.x sur Linux Mint
LibreOffice 5.x/6.x sur Linux Mint
--
| « Nos défauts devraient nous donner une qualité : l'indulgence pour les défauts des autres » (Rivarol)
forumateur
Membre lOOyal
Membre lOOyal
Messages : 28
Inscription : 11 nov. 2008 00:28

Re: [Writer] Supprimer marques de paragraphe en milieu de ph

Message par forumateur »

Hubert,
Autant pour moi...
J'avais créé un dossier Python, et le réglage sécurité était réglé sur moyenne, libreoffice étant sensé me demander avant d'exécuter un script d'origine inconnue...
J'arrive à faire marcher tes scripts en enlevant cette sécurité, même si je ne comprend pas pourquoi le logiciel ne demande pas pour permettre l'exécution...
Quelques petites remarques :
- la forumateur.py ne fait les modifications que après qu'on ait cliqué sur le message de fin d'exécution.
- j'ai l'impression que tu as construit cette macro pour rechercher les fins de paragraphe suivis d'une minuscule, alors qu'il peut y avoir un saut de paragraphe à supprimer même s'il y a une majuscule après (notamment un nom propre).
- la forumateur2.py semble elle traiter les fins de paragraphes suivant une lettre, un chiffre, un ";" ou un ":" etc..., mais de manière inconstante les "," et parfois même un "." !
Tu as une idée pourquoi ? (NB le but est de supprimer les fins de paragraphes suivant une lettre quelconque ou une virgule (pour ne conserver que les fins de paragraphes suivant "." ";" "?" ou ":" par exemple.)
Merci encore pour tes efforts pour m'aider !!
Une autre question : saurais-tu écrire une macro en basic pour remplacer les fins de paragraphe par un saut de ligne ?
Merci


Mise à jour :
Je viens d'essayer le remplacement des fins de paragraphe par fins de ligne par AltSearch : sur un document de 100.000 mots : exactement 1 heure pour effectuer ce remplacement !!! (il y avait quand même 6800 fins de paragraphe, mais çà fait moins de 2 remplacements à la seconde, et je précise que je travaille avec un i5-7600 à 3.5GHz, et 16Go de RAM ! (et je n'effectuait aucune autre tâche pendant plus de 50 minutes)).
Dernière modification par forumateur le 04 juil. 2019 13:52, modifié 1 fois.
LibreOffice 6.1 sous Windows 10
(LibreOffice 6.1 par choix)
Avatar de l’utilisateur
Oukcha
RespOOnsable modération
RespOOnsable modération
Messages : 3929
Inscription : 06 oct. 2008 10:03

Re: [Writer] Supprimer marques de paragraphe en milieu de ph

Message par Oukcha »

Bonjour,
forumateur a écrit :Une autre question
Nous vous rappelons que la règle n° 7 stipule qu'il ne faut mettre qu'une question par fil : les règles de ce forum
  • Poser plusieurs questions complique la compréhension et n'encourage pas les réponses : il vaut donc mieux découper votre problème.
  • Le titre de votre question ne peut pas refléter l'ensemble des problèmes exposés.
  • Afin que nous puissions avoir une base de connaissance efficace lors d'une recherche sur un seul de vos problèmes, nous vous prions de créer autant de fil que de questions.
Merci de votre collaboration.
                                        
Pour tout savoir sur le fonctionnement de ce forum :arrow: À lire avant tout ! Image
forumateur
Membre lOOyal
Membre lOOyal
Messages : 28
Inscription : 11 nov. 2008 00:28

Re: [Writer] Supprimer marques de paragraphe en milieu de ph

Message par forumateur »

Bonjour Oukcha,
On recherche toujours une solution simple et utilisable par tous pour remplacer les fins de paragraphe intempestives qui sont ajoutées quand on fait un copier-coller d'un texte à partir d'une page web ou d'un PDF par exemple.
On se heurte en effet à de nombreux problèmes, mais le jeu en vaut la chandelle à mon avis car celà touche beaucoup de monde, et je n'ai pas encore trouvé de solution malgré des heures passées à parcourir différents forums...
Pour résumer :
- On s'en approche avec la solution en Python proposée par Hubert, mais j'avoue que je ne connais absolument pas python, et je ne peux pour l'instant pas adapter sa solution à mes besoins
- Je ne comprends toujours pas pourquoi on ne peut pas simplement en basic sélectionner les fins de paragraphe précédées d'une lettre et les supprimer
- Si on veut contourner cet écueil, on peut traiter des fins de lignes à la place des fins de paragraphe (parceque qu'après il est facile de les traiter comme signalé plus haut dans les discussions), mais je n'ai pas encore trouvé de moyen simple (AltSearch ou macro basic) pour changer les fins de paragraphe en fin de ligne (ou alors 1heure de travail pour AltSearch..., et la macro signalée plus haut remplacer fin ligne --> fin paragraphe plante souvent chez moi)

Peut-être celà permet-il de recentrer le débat, car je comprend aisément que le lecteur qui prend en route peut être un peu "dérouté"...

Encore une fois, si quelqu'un a une solution, un grand Merci d'avance...

PS je vais être absent pour plusieurs semaines à partir de demain, dans une île (presque) déserte sans ordi ni connexion internet facile, et je pourrai donc plus poster pendant un moment. Merci encore à ceux qui ont alimenté cette discussion
LibreOffice 6.1 sous Windows 10
(LibreOffice 6.1 par choix)
Avatar de l’utilisateur
Hubert Lambert
SuppOOrter
SuppOOrter
Messages : 1214
Inscription : 06 avr. 2016 09:26

Re: [Writer] Supprimer marques de paragraphe en milieu de ph

Message par Hubert Lambert »

Une première approche en basic, sur base de ta logique :

Code : Tout sélectionner

private nonfin

sub main
  on error goto terminus
	nonfin = "abcdefghijklmnopqrstuvwxyzàâäéèêëîïôöûüùÿ,-"

	doc = thiscomponent
	undo = doc.UndoManager
	undo.enterUndoContext("Suprrimer faux retours")
	doc.lockControllers()
	supprime_faux_retours(doc)
    for each frame in doc.TextFrames
        supprime_faux_retours(frame)
	next frame
	tables = doc.TextTables
	for n = 0 to tables.Count -1
		table = tables(n)
		cellnames = table.CellNames
		for each cellname in cellnames
			cell = table.getCellByName(cellname)
			supprime_faux_retours(cell)
		next cellname
	next n
  terminus:
	if err > 0 then
		msgbox "Erreur " & err & " : " & error$ + chr(13) + "À la ligne : " + erl, 16 ,"une erreur s'est produite"
		on error goto 0
	end if
	undo.leaveUndoContext()
	doc.unlockControllers()
end sub

sub supprime_faux_retours(conteneur)
	T = conteneur.Text
	tc = T.createTextCursor()
	do while tc.gotoNextParagraph(False)
		start = tc.Start
		tc.goLeft(1, False)
		do
			tc.goLeft(1, True)
			s = tc.String
			if instr(nonfin, s) > 0 then
				tc.gotoRange(start, True)
				do
					 tc.goRight(1, True)
					 if asc(right(tc.String, 1)) = 10 then	'paragraphe vide
					 	goto suite
					 end if
				loop while right(tc.String, 1) = " "
				tc.goLeft(1, True)
				tc.String = s + " "
				exit do
			elseif s = " " then
				tc.collapseToStart(False)
			else
				tc.gotoRange(start, False)
				exit do
			end if
		loop
		suite:
	loop
end sub
AOOo 4.1.7 sur Win10
AOOo 4.1.x sur Linux Mint
LibreOffice 5.x/6.x sur Linux Mint
--
| « Nos défauts devraient nous donner une qualité : l'indulgence pour les défauts des autres » (Rivarol)
forumateur
Membre lOOyal
Membre lOOyal
Messages : 28
Inscription : 11 nov. 2008 00:28

Re: [Writer] Supprimer marques de paragraphe en milieu de ph

Message par forumateur »

Un immense Merci Hubert !
Super !
Je pars en vacances heureux !
Et j'étudierai ta macro à mon retour; elle marche impeccable sur un premier essai !
Bonnes vacances à toi si tu en prends !
Cordialement
LibreOffice 6.1 sous Windows 10
(LibreOffice 6.1 par choix)
Verrouillé