Page 1 sur 1

[Issue][Writer] Décalage (as Long) de caractère d'un texte

Publié : 05 juin 2018 14:16
par Icare
Bonjour,

Tout nouveau dans les macros, après moult heures de recherche dans la documentation, je me confronte à un problème certainement ridicule : je voudrais simplement connaitre, en nombre entier, le décalage d'un mot (donc de son premier caractère) dans un texte, en passant bien sûr par l'API.

Par exemple :

Je prends la sélection :

Code : Tout sélectionner


Dim oVCursor as Object
oVCursor = thisComponent.CurrentController.getViewCursor()

On dispose d’une méthode `getStart()`, mais elle ne renvoie pas un nombre entier (mais un objet contenant énormément de méthodes et de propriétés, mais pas `Start`, par exemple.

Je voudrais pouvoir faire :

Code : Tout sélectionner


Dim iWordOffset as Integer
iWordOffset = oVCursor.Start ' => Décalage de la sélection

J'ai bien sûr essayé plein de choses, dont l'appel à certains services (mais certainement pas les bons), dont :

Code : Tout sélectionner


iWordOffset = oVCursor.Start ' NE FONCTIONNE PAS
iWordOffset = oVCursor.getStart().value ' IDEM
iWordOffset = oVCursor.getStart().getValue() ' IDEM 
Si le document contient le texte : « Ceci est mon texte sélectionné. », je voudrais que `iWordOffset` contienne 9 (si 0-start).


Un grand merci à vous pour toute information ou toute piste suggérée.

PS : désolé si ce sujet devait plutôt se préfixer « [Basic] », je ne connais pas encore assez le langage des macros pour savoir si le problème peut être utilisé aussi dans Calc et autre.

Re: [Writer] Décalage (as Int) d'un caractère dans un texte

Publié : 05 juin 2018 15:12
par Churay
Bonjour,
Icare a écrit :je voudrais que `iWordOffset` contienne 9 (si 0-start).
A ma connaissance, Start est à 1, donc dans «Ceci est mon texte sélectionné.», la position de mon texte sélectionné sera 10 et non 9.

Cela étant précisé :

Code : Tout sélectionner

Option Explicit

Sub Main
Dim oDoc AS Object, oCursor AS Object
Dim sText AS String, sSelect AS String, iWordOffset
	oDoc = thisComponent : oCursor = oDoc.CurrentController.getViewCursor()
	sText = oCursor.Text.String : sSelect = oCursor.String

	iWordOffset = Instr(sText , sSelect)
	MsgBox iWordOffset 
End Sub
devrait répondre à ton attente.

S'il y a bien une sélection active.

Re: [Writer] Décalage (as Int) d'un caractère dans un texte

Publié : 05 juin 2018 16:34
par tintin
Bonjour,
votre signature a écrit :LibreOffice 5.1.6.2 sur Mac OS X High Sierra (10.13.2)
Afin de profiter des dernières améliorations, il est fortement recommandé d'être à jour de la dernière version stable 5.4.7

Re: [Writer] Décalage (as Int) d'un caractère dans un texte

Publié : 06 juin 2018 06:58
par Icare
Bonjour,

Merci @Churay pour ta suggestion.

Malheureusement, j'aurais dû plus insister sur le « par l'API » dans ma question (j'aurais voulu le mettre dans le titre du fil, mais on est trop limité en longueur).

D'abord, ta solution plantera LO avec une longue chaine (si je ne m'abuse, une chaine ne peut pas être supérieure à 64Ketc). Vu que je travaille sur des romans, c'est impossible.

Ensuite, je cherche vraiment une `propriété` de l’instance qui contiendrait ce décalage (ou bien sûr une méthode permettant d'accéder à cette propriété).

Même en passant par le décalage calculé en récupérant le texte puis en cherchant à l’intérieur, je me confronterais au même problème à l'envers.

Pour préciser mon problème :

Le cas en langage humain :
  • j'écris un roman.
  • En français, un bon roman ne supporte pas de répéter le même mot. La règle veut que deux mots identiques soient au moins séparés d'une page (1500 signes).
  • Je voudrais, en cours de ré-écriture (ce qui signifie qu'il peut y avoir du texte avant et après ce que j'écris), pouvoir cliquer sur un bouton pour vérifier si le mot que je suis en train d'écrire possède une proximité impossible (un autre mot identique ou similaire, avant ou après, qui serait à moins de 1500 signes) ou dangereuse (proximité entre 1500 et 3000 signes).
  • Si c'est le cas, un message doit signaler le problème à l’auteur(e), mettre le ou les mots en exergue et indiquer le décalage.
Exemple :

Soit le texte :

“““
Ceci est un texte avec un mot
qui devrait ne pas être répété avant le même
mot si un nombre de 1500 signes ne soit
écrit dans le texte avant le mot et [environ 1500 signes] encore
le mot et [environ 5000 signes] le mot à nouveau.
”””
  • Je viens d'écrire le mot en bleu.
  • Je le sélectionne
  • Je clique sur mon bouton de vérification de proximité
  • La macro transforme le texte en :
“““
Ceci est un texte avec un mot
qui devrait ne pas être répété avant le même
mot si un nombre de 1500 signes ne soit
écrit dans le texte avant le mot et [environ 1500 signes] encore
le mot et [environ 5000 signes] le mot à nouveau.
”””
  • Et la macro affiche le dialog :

Code : Tout sélectionner


         ------------------------------------------
         |  Proximité du mot « mot »              |
         |                                        |
         |       Trouvé 56 signes avant (!)       |
         |       Trouvé 1752 signes après         |
         |                                        |
         |                                        |
         |  ___________________            ____   |
         | | Supprimer exergue |          | OK |  |
         |  –––––––––––––––––––            ––––   |
          -----------------------------------------
					
Synopsis :
  • Je me concentre sur la section de texte de 3000 signes avant (si possible) à 3000 signes après (si possible) (je sais faire)
  • Je crée un descripteur de recherche (qui peut être complexe, avec expression régulière et méthodes de similarités de LibreOffice) (je sais faire)
  • Je boucle sur tous les éléments trouvés (il y en a forcément un : le mot cherché) (je sais faire)
  • Je passe le mot lui-même (je sais faire, simplement avec `compareRegionStarts`)
  • Si un mot se trouve à plus de 1500 signes (JE NE SAIS PAS FAIRE), on signale simplement sa présence, en proximité faible -> application d’un style de caractère
  • Si un mot se trouve à moins de 1500 signes (JE NE SAIS PAS FAIRE), on le met en exergue et on signale un problème sérieux -> application d’un style de caractère
Si le code est vraiment nécessaire, je peux l'adjoindre au message, mais en fait, ma demande ne concerne qu'une propriété que je pensais pouvoir atteindre très facilement (la seule difficulté pouvant éventuellement venir des imbrications d'autres objets dans le texte — problème qui n'existe pas ici, c'est toujours un texte continu dont il est question)

Bien sûr, je pourrais (peut-être (*)) passer par le texte.string lui-même, mais ça me semble fastidieux et d’un manque d’élégance absolu… :-(

(*) Comment savoir quel "mot" est celui qu'on doit comparer sans justement connaitre le décalage de la sélection ?

Un grand merci d'avance à ceux qui auront la patience d'aller jusqu'ici et pourront m’aider ou m’aiguiller.

Phil

Re: [Writer] Décalage (as Int) d'un caractère dans un texte

Publié : 06 juin 2018 07:02
par Icare
tintin a écrit : Afin de profiter des dernières améliorations, il est fortement recommandé d'être à jour de la dernière version stable 5.4.7
Merci @tintin pour la suggestion. J'ai malheureusement la mauvaise habitude d'attendre suffisamment de feedbacks d’utilisateurs avant d’upgrader mes apps. Donc je ne suis jamais à jour…

Bien à toi.

Re: [Writer] Décalage (as Int) d'un caractère dans un texte

Publié : 06 juin 2018 08:34
par Hubert Lambert
Bonjour,

Ci-dessous un exemple, mais qui sans doute ne résout pas la question d'un très long texte (voir ajout).
Cordialement.
 Ajout : Si plus de 65536 caractères séparent deux occurrences, la macro affichera '0'. Mais une version python résoudrait sans difficulté le problème. 

Re: [Writer] Décalage (as Int) d'un caractère dans un texte

Publié : 06 juin 2018 10:09
par Icare
Bonjour @Hubert_Lambert,
Hubert Lambert a écrit : Ci-dessous un exemple, mais qui sans doute ne résout pas la question d'un très long texte (voir ajout).
Oui, donc, le truc, c'est de calculer la longueur de texte entre le mot n et le mot n+1…

Dommage de devoir en passer par là :-(, mais la solution est maligne… :-)

Un grand merci à toi.

En passant, avec mon fonctionnement ne se pose pas le problème de longueur de texte puisque je ne travaille jamais sur le texte entier.

Je reste bien sûr à l'écoute de toute personne qui pourra m'indiquer comment atteindre la propriété voulue très simplement. Elle doit bien exister quelque part ;-) (mais bon, je comprendrais peut-être lorsque j'aurai compris la philosophie profonde de LibreOffice…).

Re: [Writer] Décalage (as Int) d'un caractère dans un texte

Publié : 06 juin 2018 12:05
par Hubert Lambert
Je ne suis pas du tout sûr que cela existe (quelqu'un infirme le cas échéant) mais, si tu as besoin d'une abstraction de plus haut niveau, pourquoi ne pas te construire une bibliothèque de fonctions par dessus l'API ?

Re: [Writer] Décalage (as Int) d'un caractère dans un texte

Publié : 06 juin 2018 12:19
par Icare
Hubert Lambert a écrit :Je ne suis pas du tout sûr que cela existe


Tu parles bien au niveau du Basic, là, au niveau des macros. Parce que l'information doit bien exister quelque part, non ?

Sur quoi se base les méthodes `getStart()` (quand elle sert à instancier un `Cursor` par exemple), `compareRegionStarts()` etc.
Hubert Lambert a écrit : mais, si tu as besoin d'une abstraction de plus haut niveau, pourquoi ne pas te construire une bibliothèque de fonctions par dessus l'API ?
Tout simplement parce que je n'en suis pas encore là (je découvre à peine le Basic LO et les macros LibreOffice) et surtout que je pensais juste faire une petite macro facilement pour ça (c'est bête, je butte seulement sur un truc hallucinement simple…).

Je pense, au final, que je vais me contenter de signaler la proximité, sans précision exacte de l'écart de signes (sauf si je reprends ton idée maligne).

Encore merci à toi !

Re: [Writer] Décalage (as Int) d'un caractère dans un texte

Publié : 06 juin 2018 22:50
par Churay
Bonsoir

La limite des 64 k concerne la variable, mais la méthode oCursor.Text.String te renseigne sur la taille exacte (dans mon test : 87995), il est donc possible de travailler sur des textes loooooooooongs, comme l'a brillamment démontré Hubert
Icare a écrit : sans précision exacte de l'écart de signes (sauf si je reprends ton idée maligne).
L'idée est effectivement maligne puisque elle fonctionne sur des textes de plus de 64 K, le seul bémol est que, si la distance est supérieure à 65536 caractères, le retour est 0.
Ce qui en soi n'est pas un problème puisque tu cherches dans l'espace des 1500 caractères : au pire, le mot situé à 12827 caractères ne sera pas signalé...

Re: [Writer] Décalage (as Int) d'un caractère dans un texte

Publié : 07 juin 2018 06:04
par Icare
Bonjour @Churay,

Merci de ta réponse.
Churay a écrit : L'idée est effectivement maligne puisque elle fonctionne sur des textes de plus de 64 K, le seul bémol est que, si la distance est supérieure à 65536 caractères, le retour est 0.
Heu… donc elle ne fonctionne pas sur des textes de plus de 64K ;-).
Churay a écrit :Ce qui en soi n'est pas un problème puisque tu cherches dans l'espace des 1500 caractères : au pire, le mot situé à 12827 caractères ne sera pas signalé...
Sur un espace de 6000 signes, oui (± 3000 par rapport à la sélection).

Oui, bien sûr, c'est possible, mais j'aurais aimé une solution plus élégante, que j'aurais pu obtenir simplement en pouvant atteindre directement la propriété de décalage.

Merci à toi !

[Résolu] Ligne impossible à enlever

Publié : 13 juin 2018 17:03
par Dude
Rappel sur la demande d'amélioration 17171 pour dépasser la limite des 65.534 caractères pour un paragraphe (95 voix à ce jour).

Faut voter !