Révision 2066

tmp/org.txm.analec.rcp/src/org/txm/macro/urs/edit/AccessibiliteMacro.groovy (revision 2066)
1
package org.txm.macro.urs.edit
2

  
3
import org.apache.commons.lang.*
4
import org.kohsuke.args4j.*
5
import groovy.transform.*
6
import org.txm.*
7
import org.txm.rcp.swt.widget.parameters.*
8
import org.txm.annotation.urs.*
9
import org.txm.searchengine.cqp.*
10
import org.txm.searchengine.cqp.corpus.*
11
import visuAnalec.Message.*
12
import visuAnalec.donnees.*
13
import visuAnalec.elements.*
14
import visuAnalec.vue.*
15

  
16
/*
17
   Calcule l'accessibilité (faible ou forte) d'une mention à partir de sa CATEGORIE
18
   La macro fonctionne à partir de 2 listes de catégories : accessibilité forte, accessibilité nulle.
19
   L'accessibilité faible sera le cas par défaut.
20
   
21
   La macro crée une nouvelle propriété pour les MENTION : ACCESSIBILITE
22
   Les valeurs autorisées sont : "Faible", "Forte" et "N/A"
23
   Voir si la dénomination de cette dernière valeur convient.
24
    
25
   Auteur : Matthieu Quignard
26
   Date : 19/12/2017
27
 */
28

  
29
def listeAccessibiliteForte=["PRO.PERA", "PRO.REL", "SUJ.ZERO", "DET.POS"]
30
def listeAccessibiliteNulle=["PRO.PERD"]
31

  
32

  
33
// CORPS DU SCRIPT
34

  
35
if (!(corpusViewSelection instanceof MainCorpus)) {
36
	println "Corpora selection is not a Corpus: "+corpusViewSelection
37
	return
38
}
39

  
40
// BEGINNING OF PARAMETERS
41
@Field @Option(name="unit_type", usage="", widget="String", required=true, def="MENTION")
42
def unit_type
43
if (!ParametersDialog.open(this)) return
44

  
45
corpus = corpusViewSelection
46
CQI = CQPSearchEngine.getCqiClient()
47

  
48
analecCorpus = URSCorpora.getCorpus(corpus)
49
vue = URSCorpora.getVue(corpus)
50
structure = analecCorpus.getStructure()
51
if (!structure.getUnites().contains(unit_type)) { // check if the structure contains the unit_type units
52
	println "Error: corpus structure does not contains unit with name=$unit_type"
53
	return
54
}
55

  
56
ACCESSIBILITE = "ACCESSIBILITE"
57
// Si la structure d'annotation ne contient pas ACCESSIBILITE, on la crée avec ses valeurs
58
if (!structure.getUniteProperties(unit_type).contains(ACCESSIBILITE)) {
59
	// la propriété
60
	analecCorpus.ajouterProp(Unite.class, unit_type, ACCESSIBILITE)
61
	// les valeurs
62

  
63
	structure.ajouterVal(Unite.class, unit_type, ACCESSIBILITE, "Faible")
64
	structure.ajouterVal(Unite.class, unit_type, ACCESSIBILITE, "Forte")
65
	structure.ajouterVal(Unite.class, unit_type, ACCESSIBILITE, "N/A")
66
}
67

  
68
def nModified = 0
69
def nIgnored = 0
70
def nNulle = 0
71
def nForte = 0
72
def nFaible = 0
73

  
74
errors = new HashMap()
75
def units = analecCorpus.getUnites(unit_type)
76
units.sort() { a, b -> a.getDeb() <=> b.getDeb() ?: a.getFin() <=> b.getFin() }
77
for (Unite unit : units) { // process all units
78

  
79
	def prop = unit.getProp("CATEGORIE")
80
	
81
	if (prop== null) {
82
		// On ignore les cas où la catégorie n'est pas renseignée.
83
		nIgnored++
84
	} else {
85
		nModified++
86
		if (listeAccessibiliteNulle.contains(prop)) {
87
			// Cas d'accessibilité nulle
88
			vue.setValeurChamp(unit, ACCESSIBILITE, "N/A")
89
			nNulle++
90
		} else if (listeAccessibiliteForte.contains(prop)) {
91
			// Cas d'accessibilité forte
92
			vue.setValeurChamp(unit, ACCESSIBILITE, "Forte")	
93
			nForte++
94
		} else {
95
			// Sinon, on est dans le cas d'accessibilité faible
96
			vue.setValeurChamp(unit, ACCESSIBILITE, "Faible")	
97
			nFaible++
98
		}
99
	}
100
	
101
}
102

  
103
println "Result:"
104
println "- $nModified mentions ont été modifiées."
105
println "- $nIgnored mentions ont été ignorées (leur catégorie est vide).\n"
106

  
107
println "- $nForte mentions d'accessibilité forte."
108
println "- $nFaible mentions d'accessibilité faible."
109
println "- $nNulle mentions de type 'N/A' (déictiques).\n"
110

  
tmp/org.txm.analec.rcp/src/org/txm/macro/urs/edit/Fropos2CattexMacro.groovy (revision 2066)
1
package org.txm.macro.urs.edit
2

  
3
import org.apache.commons.lang.*
4
import org.kohsuke.args4j.*
5
import groovy.transform.*
6
import org.txm.*
7
import org.txm.rcp.swt.widget.parameters.*
8
import org.txm.annotation.urs.*
9
import org.txm.searchengine.cqp.*
10
import org.txm.searchengine.cqp.corpus.*
11
import visuAnalec.Message.*
12
import visuAnalec.donnees.*
13
import visuAnalec.elements.*
14
import visuAnalec.vue.*
15

  
16
/*
17
Définit la catégorie grammaticale des mentions d'après le champ `frpos'
18
(tagset de TreeTagger). 
19

  
20
La liste des catégories grammaticales est celle de CATTEX2009
21
-- Groupes nominaux :
22
	GN.NAM (noms propres) : Henri II
23
	GN.DEF (définis) : Le roi, du roi
24
	GN.IND (indéfinis) : Un roi
25
	GN.POS (possessifs) : [Mon roi]
26
	GN.DEM (demonstratif) : Ce roi
27
	GN.NUM (numéraux) : Deux rois
28
	GN.CHECK (GN indéterminés)
29
-- Déterminants
30
	DET.POS (possessifs) : [mon] roi
31
-- Pronoms
32
	PRO.PER (personnels) : je, moi, me, on, il, etc.
33
	PRO.ADV (adverbiaux) : y, en
34
	PRO.IND (indéfinis) : tout, tous, certains, plusieurs, etc.
35
	PRO.DEM (demonstratifs) : ceci, cela, ce, ça...
36
	PRO.POS (possessifs) : le mien, les nôtres...
37
	PRO.NUM (cardinaux, ordinaux) : les deux...
38
	PRO.REL (relatifs) : qui, que, quoi, duquel, etc.
39
	PRO.INT (interrogatifs)
40
	PRO.CHECK (pronoms indéterminés)
41
-- SUJ.ZERO (Sujet Zéro) : verbes conjugués, éventuellement pronominal
42

  
43
-- ERREUR : erreur (a priori) de mention
44
-- ADJpos : adjectif possessif à fusionner ou pas avec DETpos
45
	
46
*/
47

  
48

  
49

  
50
def testRules(def positions, def Mention) {
51
	def catégorie = null
52
	
53
	// la forme du premier mot de la mention s'appelle 'forme'
54
	def forme = CQI.cpos2Str(word.getQualifiedName(), positions)[0].toLowerCase()
55
    
56
    
57
	if (Mention.length == 1) {    
58
	    
59
		     if (Mention.first() == "NOMpro"    ) catégorie = "GN.NAM"
60
		else if (Mention.first() == "DETpos") catégorie = "DET.POS"
61
		else if (Mention.first() == "ADJpos") catégorie = "ADJ.POS"
62
		else if (Mention.first() == "PROdem") catégorie = "PRO.DEM"
63
		else if (Mention.first() == "PROind") catégorie = "PRO.IND"
64
		else if (Mention.first() == "PROcar") catégorie = "PRO.NUM"
65
		else if (Mention.first() == "PROord") catégorie = "PRO.NUM" // fusionné avec Cardinaux
66
		else if (Mention.first() == "PROpos") catégorie = "PRO.POS"
67
		else if (Mention.first() == "PROper") catégorie = "PRO.PER" 
68
		else if (Mention.first() == "PROimp") catégorie = "PRO.PER" // fusionné avec Pronoms Personnels
69
		else if (Mention.first() == "PROint") catégorie = "PRO.INT"
70
		else if (Mention.first() == "PROadv") catégorie = "PRO.ADV"
71
		else if (Mention.first() == "PROrel") catégorie = "PRO.REL"
72
		
73
		else if (Mention.first().contains("VER")) catégorie = "SUJ.ZERO"
74
		
75
		else if (Mention.first() == "NOMcom") catégorie = "GN.CHECK"
76
		
77
		// Pronoms "contractés"
78
		else if (Mention.first() == "PROper.PROper") catégorie = "PRO.PER"  // double pronom personnel : ex 'jel' pour 'je le'
79
		else if (Mention.first() == "ADVgen.PROper") catégorie = "PRO.PER"  // adverbe + pronom personnel : ex 'sil' pour 'si le'
80
		else if (Mention.first() == "ADVneg.PROper") catégorie = "PRO.PER"  // adverbe + pronom personnel : ex 'nel' pour 'ne le'
81
		
82
		// Erreurs de mention
83
		else if (Mention.first() == "ADVgen") catégorie = "ERREUR"  // un adverbe seul n'est jamais référentiel
84
		else if (Mention.first() == "ADVneg") catégorie = "ERREUR"  // un adverbe seul n'est jamais référentiel
85
		else if (Mention.first() == "PRE") catégorie = "ERREUR"  // une preposition seule n'est jamais référentielle
86
		else if (Mention.first() == "ADJqua") catégorie = "ERREUR"  // un adjectif seul n'est jamais référentiel
87
		else if (Mention.first() == "ADJind") catégorie = "ERREUR"  // un adjectif seul n'est jamais référentiel
88
		else if (Mention.first() == "INJ") catégorie = "ERREUR"  // une interjection seule n'est jamais référentielle
89
		
90
		else catégorie = "PRO.CHECK"	
91

  
92
	} else if (Mention.length == 2) {
93
		if ( (Mention[0] == "NOMpro") || (Mention[1] == "NOMpro") ) catégorie = "GN.NAM"
94
		else if (Mention[1] == "PROrel") catégorie = "PRO.REL"  // "ce que" prioritaire sur "celui là"
95
		else if (Mention[1] == "PROpos") catégorie = "PRO.POS"  // "les miens"
96
		else if (Mention[1].contains("car")) catégorie = "PRO.NUM"  // "les deux"
97
		else if (Mention[1] == "PROdem") catégorie = "PRO.DEM"  // "Tout cela"
98
		
99
		else if (Mention[0].contains("DET") && Mention[1].contains("PROind")) catégorie = "PRO.IND" // "les autres"
100
		
101
		else if (Mention[0].contains("VER") && Mention[1].contains("VER")) catégorie = "SUJ.ZERO" // verbe temps composé
102
		
103
		else if (!Mention[0].contains("NOM") && !Mention[0].contains("ADJ") && !Mention[1].contains("NOM") && !Mention[1].contains("ADJ")) {
104
			if (Mention[0] == "PROdem") catégorie = "PRO.DEM"
105
			else if (Mention[1] == "VERinf") catégorie = "GN.CHECK" // Verbe substantivé
106
			else if (Mention[1] == "VERppa") catégorie = "GN.CHECK" // Verbe substantivé
107
			else if ( Mention[0].contains("PRE") && (Mention[1] == "PROper")) catégorie = "GN.CHECK" // Complément de nom
108
			else catégorie = "PRO.CHECK"
109
		}
110
		else catégorie = "GN.CHECK"           
111
	} 
112
	
113
	if ( (catégorie == null) || (catégorie == "GN.CHECK") ) {
114
		// on est dans les GN
115
		
116
		if (Mention[0] == "DETcar"     ) catégorie = "GN.NUM"
117
		else if (Mention[0] == "DETord"     ) catégorie = "GN.NUM"
118

  
119
		else if (Mention.contains("NOMpro")) catégorie = "GN.NAM"
120
				
121
		else if (Mention[0] == "DETpos" ) catégorie = "GN.POS"
122
				
123
		else if (Mention[0] == "PROdem" ) catégorie = "GN.DEM"
124
		else if (Mention[0] == "DETdem" ) catégorie = "GN.DEM"
125
		
126
		else if (Mention[0] == "PRE.DETdef" ) catégorie = "GN.DEF"
127
		else if (Mention[0] == "DETdef")   catégorie = "GN.DEF"
128
		
129
		else if (Mention[0] == "DETndf") catégorie = "GN.IND" 
130
		else if (Mention[0] == "DETind") catégorie = "GN.IND" 
131
		
132
		else if (Mention[0] == "PROind" ) catégorie = "GN.IND"
133
		else if (Mention[0].contains("PRP")) catégorie = "GN.IND"
134
		else if (Mention[0].contains("ADJ")) catégorie = "GN.IND"
135
		else if (Mention[0].contains("NOM")) catégorie = "GN.IND"
136
		
137
		
138
		
139
		else catégorie = "GN.CHECK"
140
	}
141

  
142

  
143
	
144
	return catégorie
145
}
146

  
147
//
148
// FIN DE LA DÉFINITION DES RÈGLES
149
//
150

  
151
// CORPS DU SCRIPT
152

  
153
if (!(corpusViewSelection instanceof MainCorpus)) {
154
	println "Corpora selection is not a Corpus"
155
	return
156
}
157

  
158
// BEGINNING OF PARAMETERS
159
@Field @Option(name="unit_type", usage="", widget="String", required=true, def="MENTION")
160
def unit_type
161
@Field @Option(name="pos_property_name", usage="", widget="String", required=true, def="pos")
162
def pos_property_name
163
@Field @Option(name="reset", usage="", widget="Boolean", required=true, def="true")
164
def reset
165
if (!ParametersDialog.open(this)) return
166

  
167
corpus = corpusViewSelection
168
CQI = CQPSearchEngine.getCqiClient()
169
word = corpus.getWordProperty()
170
posProperty = corpus.getProperty(pos_property_name)
171
if (posProperty == null) {
172
	println "Error: CQP corpus does not contains the word property with name=$pos_property_name"
173
	return
174
}
175
analecCorpus = URSCorpora.getCorpus(corpus)
176
vue = URSCorpora.getVue(corpus)
177
structure = analecCorpus.getStructure()
178
if (!structure.getUnites().contains(unit_type)) { // check if the structure contains the unit_type units
179
	println "Error: corpus structure does not contains unit with name=$unit_type"
180
	return
181
}
182

  
183
CATEGORIE = "CATEGORIE"
184
// Si la structure d'annotation ne contient pas CATEGORIE, on la crée avec ses valeurs
185
if (!structure.getUniteProperties(unit_type).contains(CATEGORIE)) { 
186
// la propriété
187
	analecCorpus.ajouterProp(Unite.class, unit_type, CATEGORIE)
188
// les valeurs
189
	structure.ajouterVal(Unite.class, unit_type, CATEGORIE, "GN.NAM")
190
	structure.ajouterVal(Unite.class, unit_type, CATEGORIE, "GN.DEF")
191
	structure.ajouterVal(Unite.class, unit_type, CATEGORIE, "GN.IND")
192
	structure.ajouterVal(Unite.class, unit_type, CATEGORIE, "GN.POS")
193
	structure.ajouterVal(Unite.class, unit_type, CATEGORIE, "GN.DEM")
194
	structure.ajouterVal(Unite.class, unit_type, CATEGORIE, "GN.NUM")
195
	
196
	structure.ajouterVal(Unite.class, unit_type, CATEGORIE, "GN.CHECK")
197
	
198
	structure.ajouterVal(Unite.class, unit_type, CATEGORIE, "DET.POS")
199
	
200
	structure.ajouterVal(Unite.class, unit_type, CATEGORIE, "PRO.PER")
201
	structure.ajouterVal(Unite.class, unit_type, CATEGORIE, "PRO.ADV")
202
	structure.ajouterVal(Unite.class, unit_type, CATEGORIE, "PRO.IND")
203
	structure.ajouterVal(Unite.class, unit_type, CATEGORIE, "PRO.DEM")
204
	structure.ajouterVal(Unite.class, unit_type, CATEGORIE, "PRO.POS")
205
	structure.ajouterVal(Unite.class, unit_type, CATEGORIE, "PRO.NUM")
206
	structure.ajouterVal(Unite.class, unit_type, CATEGORIE, "PRO.INT")
207
	structure.ajouterVal(Unite.class, unit_type, CATEGORIE, "PRO.REL")
208
	
209
	structure.ajouterVal(Unite.class, unit_type, CATEGORIE, "PRO.CHECK")
210
	
211
	structure.ajouterVal(Unite.class, unit_type, CATEGORIE, "SUJ.ZERO")
212
	
213
	structure.ajouterVal(Unite.class, unit_type, CATEGORIE, "ERREUR")
214
	structure.ajouterVal(Unite.class, unit_type, CATEGORIE, "ADJ.POS")
215
	
216
//...
217
}
218

  
219
def nModified = 0
220
def nIgnored = 0
221

  
222
errors = new HashMap()
223
def units = analecCorpus.getUnites(unit_type)
224
units.sort() { a, b -> a.getDeb() <=> b.getDeb() ?: a.getFin() <=> b.getFin() }
225
for (Unite unit : units) { // process all units
226
	
227
	def prop = unit.getProp(CATEGORIE)
228
	if (!reset && prop != null && prop.length() > 0) continue // l'unité a déjà une CATEGORIE
229
	
230
	int[] positions = null
231
	if (unit.getDeb() == unit.getFin()) positions = [unit.getDeb()]
232
	else positions = (unit.getDeb()..unit.getFin())
233
	
234
	def Mention = CQI.cpos2Str(posProperty.getQualifiedName(), positions)
235
	def cat = testRules(positions, Mention)
236
	
237
	if (cat != null) {
238
		vue.setValeurChamp(unit, CATEGORIE, cat)
239
		nModified++
240
	} else {
241
		nIgnored++
242
	}
243
}
244

  
245
println "Result:"
246
println "- $nModified units of type $unit_type have been modified."
247
println "- $nIgnored units of type $unit_type have not been modified.\n"
248

  
249
if (errors.size() > 0) {
250
	println "Some rules should be added to this macro to process the following remaining 'FROPOS / words' values:"
251
	errors.keySet().each { println "fropos="+it+"\twords="+errors[it].join(" | ") }
252
}
tmp/org.txm.analec.rcp/src/org/txm/macro/urs/edit/RetoucheComplementDuNomMacro.groovy (revision 2066)
1
// STANDARD DECLARATIONS
2
package org.txm.macro.urs.edit
3

  
4
import org.apache.commons.lang.*
5
import org.kohsuke.args4j.*
6
import groovy.transform.*
7
import org.txm.*
8
import org.txm.rcp.swt.widget.parameters.*
9
import org.txm.annotation.urs.*
10
import org.txm.searchengine.cqp.*
11
import org.txm.searchengine.cqp.corpus.*
12
import visuAnalec.Message.*
13
import visuAnalec.donnees.*
14
import visuAnalec.elements.*
15
import visuAnalec.vue.*
16

  
17

  
18
/*  MACRO pour corriger une erreur d'annotation
19
 Retirer le "De" du complément du nom
20
 Algo : 
21
 POUR CHAQUE MENTION dont le premier mot est "de" (en minuscules)
22
 SI     il existe une autre MENTION dans laquelle celle-ci est totalement incluse
23
 ALORS  incrémenter d'un mot la frontière gauche de la mention
24
 Ajouter la categorie CDN.CHECK pour qu'on puisse verifier facilement le job.
25
 */
26

  
27
// BEGINNING OF PARAMETERS
28
if (!(corpusViewSelection instanceof org.txm.searchengine.cqp.corpus.CQPCorpus)) {
29
	println "Selection must be a Corpus: "+corpusViewSelection
30
	return;
31
}
32
// Declare each parameter here
33
// BEGINNING OF PARAMETERS
34
@Field @Option(name="unit_type", usage="", widget="String", required=true, def="MENTION")
35
		def unit_type
36
@Field @Option(name="category_name", usage="", widget="String", required=true, def="CATEGORIE")
37
		def category_name
38
if (!ParametersDialog.open(this)) return
39

  
40
	corpus = corpusViewSelection.getMainCorpus()
41
CQI = CQPSearchEngine.getCqiClient()
42
word = corpus.getWordProperty()
43

  
44
analecCorpus = URSCorpora.getCorpus(corpus)
45
vue = URSCorpora.getVue(corpus)
46
structure = analecCorpus.getStructure()
47
if (!structure.getUnites().contains(unit_type)) { // check if the structure contains the unit_type units
48
	println "Error: corpus structure does not contains unit with name=$unit_type"
49
	return
50
}
51

  
52

  
53
// Si la structure d'annotation ne contient pas CATEGORIE, on la crée avec ses valeurs
54
if (!structure.getUniteProperties(unit_type).contains(category_name)) {
55
	structure.ajouterProp(Unite.class, unit_type, category_name)
56
}
57

  
58
def check_cat = "CDN.CHECK"
59
structure.ajouterVal(Unite.class, unit_type, category_name, check_cat)
60

  
61

  
62
def nModified = 0
63
def nIgnored1 = 0
64
def nIgnored2 = 0
65
def compteur = 0
66

  
67
errors = new HashMap()
68
def units = analecCorpus.getUnites(unit_type)
69
units.sort() { a, b -> a.getDeb() <=> b.getDeb() ?: a.getFin() <=> b.getFin() }
70

  
71
/* Test sur la premiere mention :
72
 def debut1 = units[1].getDeb()
73
 def fin1 = units[1].getFin()
74
 println "$debut1 - $fin1"
75
 units[1].setDeb( debut1 + 1)
76
 units[1].setFin( fin1 + 1)
77
 URSCorpora.getVue(analecCorpus).retablirVueParDefaut()
78
 def debut2 = units[1].getDeb()
79
 def fin2 = units[1].getFin()
80
 println "$debut2 - $fin2"
81
 */
82

  
83

  
84
for (Unite unit : units) { // process all units
85

  
86
	def debut = unit.getDeb()
87
	def fin = unit.getFin()
88
	def premierMot = CQI.cpos2Str(word.getQualifiedName(), debut)[0]
89

  
90
	if (premierMot != "de") {
91
		nIgnored1++
92
		compteur++
93
		continue
94
	} else {
95
		for (i = compteur-1; i >= 0 ; i--) {
96
			def u = units[i]
97
			def udeb = u.getDeb()
98
			def ufin = u.getFin()
99
			if (ufin >= fin) {
100
				println "\nAVANT => Unit $compteur : $debut - $fin"
101
				if (fin > debut) unit.setDeb( debut++ )
102
				else println "not resizing"
103
				def debut2 = unit.getDeb()
104
				def fin2 = unit.getFin()
105
				URSCorpora.getVue(analecCorpus).retablirVueParDefaut()
106
				println "APRES => Unit $compteur : $debut2 - $fin2"
107
				unit.getProps().put(category_name, check_cat)
108
				break
109
			}
110
		}
111
		if (i < 0) nIgnored2++
112
		else nModified++
113
		compteur++
114
	}
115
}
116

  
117
println "\nResult:"
118
println "- $nModified units have been modified."
119
println "- $nIgnored1 units have been ignored because not concerned"
120
println "- $nIgnored2 units have been ignored because no overlap.\n"
121
println "Total ($compteur)."
122

  
123
// END OF PARAMETERS
124
URSCorpora.getVue(analecCorpus).retablirVueParDefaut()
125
println "corpora selection: "+corpusViewSelection
tmp/org.txm.analec.rcp/src/org/txm/macro/urs/edit/CreationAnaphoresMacro.groovy (revision 2066)
1
// Copyright © 2016 ENS de Lyon, CNRS, University of Franche-Comté
2
// Licensed under the terms of the GNU General Public License (http://www.gnu.org/licenses)
3
// @author mdecorde
4
// STANDARD DECLARATIONS
5
package org.txm.macro.urs.edit
6

  
7
import org.kohsuke.args4j.*
8

  
9
import groovy.transform.Field
10

  
11
import org.txm.rcp.swt.widget.parameters.*
12
import org.txm.annotation.urs.*
13
import org.txm.searchengine.cqp.corpus.*
14

  
15
import visuAnalec.donnees.Structure;
16
import visuAnalec.elements.Relation;
17
import visuAnalec.elements.Schema
18
import visuAnalec.elements.Unite;
19
import visuAnalec.vue.Vue
20

  
21
if (!(corpusViewSelection instanceof MainCorpus)) {
22
	println "Corpora selection is not a Corpus"
23
	return;
24
}
25

  
26
// BEGINNING OF PARAMETERS
27
@Field @Option(name="unit_type",usage="", widget="String", required=true, def="MENTION")
28
		String unit_type
29
@Field @Option(name="schema_type",usage="", widget="String", required=true, def="CHAINE")
30
		String schema_type
31
if (!ParametersDialog.open(this)) return;
32

  
33
int nCreated = 0 // count the number of created RELATION
34

  
35
MainCorpus corpus = corpusViewSelection
36
def analecCorpus = URSCorpora.getCorpus(corpus); // analec corpus has the same name has the TXM corpus
37
Structure structure = analecCorpus.getStructure()
38
if (!structure.getUnites().contains(unit_type)) { // check if the structure contains the unit_type units
39
	println "Error: corpus structure does not contains unit with name=$unit_type"
40
	return
41
}
42
if (!structure.getSchemas().contains(schema_type)) { // check if the structure contains the unit_type units
43
	println "Error: corpus structure does not contains schema with name=$schema_type"
44
	return
45
}
46
if (!structure.getRelations().contains("ANAPHORE")) { // update the structure if needed
47
	println "Creating the 'ANAPHORE' relation in the structure"
48
	structure.ajouterType(Relation.class, "ANAPHORE")
49
	analecCorpus.ajouterProp(Relation.class, "ANAPHORE", "TYPE")
50
	analecCorpus.ajouterVal(Relation.class, "ANAPHORE", "TYPE", "COREFERENTE")
51
	analecCorpus.ajouterVal(Relation.class, "ANAPHORE", "TYPE", "ASSOCIATIVE")
52
}
53
if (analecCorpus.getRelations("ANAPHORE").size() > 0) {
54
	println "Error: This macro can't update existing Relations"
55
	return
56
}
57

  
58
for (Schema schema : analecCorpus.getSchemas(schema_type)) { // parse all CHAINE
59
	def units = []
60
	for (Unite unit : schema.getUnitesSousjacentes()) { // keep only the 'unit_type' units
61
		if (unit.type.equals(unit_type)) units << unit
62
	}
63
	units.sort() { a, b -> a.getDeb() <=> b.getDeb() ?: a.getFin() <=> b.getFin() } // sort them
64
	
65
	for (int i = 0 ; i < units.size() - 1 ; i++) { // build RELATIONS and don't process the last unit
66
		println "creating "+units[i+1]+", "+units[i]
67
		Relation relation = new Relation("ANAPHORE", units[i+1], units[i])
68
		relation.getProps().put("TYPE", "COREFERENTE")
69
		analecCorpus.addRelationLue(relation)  // add the new relation
70
		nCreated++;
71
	}
72
}
73

  
74
println "nCreated=$nCreated"
tmp/org.txm.analec.rcp/src/org/txm/macro/urs/edit/LongueurDesMentionsMacro.groovy (revision 2066)
1
package org.txm.macro.urs.edit
2

  
3
import org.apache.commons.lang.*
4
import org.kohsuke.args4j.*
5
import groovy.transform.*
6
import org.txm.*
7
import org.txm.rcp.swt.widget.parameters.*
8
import org.txm.annotation.urs.*
9
import org.txm.searchengine.cqp.*
10
import org.txm.searchengine.cqp.corpus.*
11
import visuAnalec.Message.*
12
import visuAnalec.donnees.*
13
import visuAnalec.elements.*
14
import visuAnalec.vue.*
15

  
16
/*
17
 Calcule la longueur des mentions et attribue une valeur (1, 2, 3 ou plus) dans la propriété "LONGUEUR"
18
 */
19

  
20
nLongueur1 = 0
21
nLongueur2 = 0
22
nLongueur3 = 0
23

  
24
def testRules(def positions, def Mention) {
25

  
26
	if (Mention.length == 1) {
27
		catégorie = "1"
28
		nLongueur1++
29
	}
30
	else if (Mention.length == 2) {
31
		catégorie = "2"
32
		nLongueur2++
33
	}
34
	else {
35
		catégorie = "3 ou plus"
36
		nLongueur3++
37
	}
38

  
39
	return catégorie
40
}
41

  
42
//
43
// FIN DE LA DÉFINITION DES RÈGLES
44
//
45

  
46
// CORPS DU SCRIPT
47

  
48
if (!(corpusViewSelection instanceof MainCorpus)) {
49
	println "Corpora selection is not a Corpus: "+corpusViewSelection
50
	return
51
}
52

  
53
// BEGINNING OF PARAMETERS
54
@Field @Option(name="unit_type", usage="", widget="String", required=true, def="MENTION")
55
def unit_type
56
@Field @Option(name="pos_property_name", usage="", widget="String", required=true, def="pos")
57
def pos_property_name
58
@Field @Option(name="reset", usage="", widget="Boolean", required=true, def="true")
59
def reset
60
if (!ParametersDialog.open(this)) return
61

  
62
corpus = corpusViewSelection
63
CQI = CQPSearchEngine.getCqiClient()
64
word = corpus.getWordProperty()
65
posProperty = corpus.getProperty(pos_property_name)
66
if (posProperty == null) {
67
	println "Error: CQP corpus does not contains the word property with name=$pos_property_name"
68
	return
69
}
70
analecCorpus = URSCorpora.getCorpus(corpus)
71
vue = URSCorpora.getVue(corpus)
72
structure = analecCorpus.getStructure()
73
if (!structure.getUnites().contains(unit_type)) { // check if the structure contains the unit_type units
74
	println "Error: corpus structure does not contains unit with name=$unit_type"
75
	return
76
}
77

  
78
LONGUEUR = "LONGUEUR"
79
// Si la structure d'annotation ne contient pas LONGUEUR, on la crée avec ses valeurs
80
if (!structure.getUniteProperties(unit_type).contains(LONGUEUR)) {
81
	// la propriété
82
	analecCorpus.ajouterProp(Unite.class, unit_type, LONGUEUR)
83
	// les valeurs
84

  
85
	structure.ajouterVal(Unite.class, unit_type, LONGUEUR, "1")
86
	structure.ajouterVal(Unite.class, unit_type, LONGUEUR, "2")
87
	structure.ajouterVal(Unite.class, unit_type, LONGUEUR, "3 ou plus")
88

  
89
	//...
90
}
91

  
92
def nModified = 0
93
def nIgnored = 0
94

  
95
errors = new HashMap()
96
def units = analecCorpus.getUnites(unit_type)
97
units.sort() { a, b -> a.getDeb() <=> b.getDeb() ?: a.getFin() <=> b.getFin() }
98
for (Unite unit : units) { // process all units
99

  
100
	def prop = unit.getProp(LONGUEUR)
101
	if (!reset && prop != null && prop.length() > 0) continue // l'unité a déjà une LONGUEUR
102

  
103
		int[] positions = null
104
	if (unit.getDeb() == unit.getFin()) positions = [unit.getDeb()]
105
	else positions = (unit.getDeb()..unit.getFin())
106

  
107
	def Mention = CQI.cpos2Str(posProperty.getQualifiedName(), positions)
108
	def cat = testRules(positions, Mention)
109

  
110
	if (cat != null) {
111
		vue.setValeurChamp(unit, LONGUEUR, cat)
112
		nModified++
113
	} else {
114
		nIgnored++
115
	}
116
}
117

  
118
println "Result:"
119
println "- $nModified units of type $unit_type have been modified."
120
println "- $nIgnored units of type $unit_type have not been modified.\n"
121

  
122
println "- $nLongueur1 mentions de longueur 1."
123
println "- $nLongueur2 mentions de longueur 2."
124
println "- $nLongueur3 mentions de longueur 3 ou plus.\n"
125

  
126
if (errors.size() > 0) {
127
	println "Some rules should be added to this macro to process the following remaining 'FROPOS / words' values:"
128
	errors.keySet().each { println "fropos="+it+"\twords="+errors[it].join(" | ") }
129
}
tmp/org.txm.analec.rcp/src/org/txm/macro/urs/edit/Fropos2CategorieMacro.groovy (revision 2066)
1
package org.txm.macro.urs.edit
2

  
3
import org.apache.commons.lang.*
4
import org.kohsuke.args4j.*
5
import groovy.transform.*
6
import org.txm.*
7
import org.txm.rcp.swt.widget.parameters.*
8
import org.txm.annotation.urs.*
9
import org.txm.searchengine.cqp.*
10
import org.txm.searchengine.cqp.corpus.*
11
import visuAnalec.Message.*
12
import visuAnalec.donnees.*
13
import visuAnalec.elements.*
14
import visuAnalec.vue.*
15

  
16
def testRules(def positions, def Mention) {
17
	def catégorie = null
18

  
19
// DÉFINITION DES RÈGLES
20
// elles sont testées les unes après les autres. 
21
// Dès qu'une règle est appliquée les suivantes sont ignorées.
22

  
23
// Règles de type CONTIENT
24

  
25
	     if (Mention.contains("NOMpro")) catégorie = "Nom Propre"
26
	else if (Mention.contains("DETpos")) catégorie = "Dét Possessif"
27
//  ...
28

  
29
// Règles de type COMMENCE ET NE CONTIENT PAS	
30

  
31
	else if (Mention.first() == "DETpos" && !Mention.contains("NOMpro")) catégorie = "GN Possessif"
32
	else if (Mention.first() == "DETdem" && !Mention.contains("NOMpro")) catégorie = "GN Démonstratif"
33
//  ...
34

  
35
// Règles de type CONTIENT PLUSIEURS	
36

  
37
	else if (Mention.contains("PROadv") || Mention.contains("ADVgen.PROadv")) catégorie = "Pronom Adverbial"
38
//  ...
39

  
40
// Règles de type CONTIENT ET NE CONTIENT PAS
41

  
42
	else if (
43
			 ( Mention.contains("DETdef") || Mention.contains("PRE.DETdef") )
44
			  &&
45
			  !Mention.contains("PROpos") && !Mention.contains("NOMpro") && !Mention.contains("PROcar")
46
			) catégorie = "GN Défini"
47
//  ...	
48

  
49
// Fin des règles, aucune n'a matchée. On stocke le pattern  qu'on affichera à la fin.
50
	else {
51
		def forms = CQI.cpos2Str(word.getQualifiedName(), positions)
52
		if (!errors.containsKey(Mention)) errors[Mention] = new HashSet()
53
		errors[Mention] << forms
54
	}
55
	
56
	return catégorie
57
}
58

  
59
//
60
// FIN DE LA DÉFINITION DES RÈGLES
61
//
62

  
63
// CORPS DU SCRIPT
64

  
65
if (!(corpusViewSelection instanceof MainCorpus)) {
66
	println "Corpora selection is not a Corpus"
67
	return
68
}
69

  
70
// BEGINNING OF PARAMETERS
71
@Field @Option(name="unit_type", usage="", widget="String", required=true, def="MENTION")
72
def unit_type
73
@Field @Option(name="pos_property_name", usage="", widget="String", required=true, def="pos")
74
def pos_property_name
75
@Field @Option(name="reset", usage="", widget="Boolean", required=true, def="true")
76
def reset
77
if (!ParametersDialog.open(this)) return
78

  
79
corpus = corpusViewSelection
80
CQI = CQPSearchEngine.getCqiClient()
81
word = corpus.getWordProperty()
82
posProperty = corpus.getProperty(pos_property_name)
83
if (posProperty == null) {
84
	println "Error: CQP corpus does not contains the word property with name=$pos_property_name"
85
	return
86
}
87
analecCorpus = URSCorpora.getCorpus(corpus)
88
vue = URSCorpora.getVue(corpus)
89
structure = analecCorpus.getStructure()
90
if (!structure.getUnites().contains(unit_type)) { // check if the structure contains the unit_type units
91
	println "Error: corpus structure does not contains unit with name=$unit_type"
92
	return
93
}
94

  
95
CATEGORIE = "CATEGORIE"
96
// Si la structure d'annotation ne contient pas CATEGORIE, on la crée avec ses valeurs
97
if (!structure.getUniteProperties(unit_type).contains(CATEGORIE)) { 
98
// la propriété
99
	analecCorpus.ajouterProp(Unite.class, unit_type, CATEGORIE)
100
// les valeurs
101
	analecCorpus.ajouterVal(Unite.class, unit_type, CATEGORIE, "Nom Propre")
102
	analecCorpus.ajouterVal(Unite.class, unit_type, CATEGORIE, "Pronom Impersonnel")
103
	analecCorpus.ajouterVal(Unite.class, unit_type, CATEGORIE, "Pronom Interrogatif")
104
	analecCorpus.ajouterVal(Unite.class, unit_type, CATEGORIE, "Pronom Pronom cardinal")
105
	analecCorpus.ajouterVal(Unite.class, unit_type, CATEGORIE, "Pronom Démonstratif")
106
	analecCorpus.ajouterVal(Unite.class, unit_type, CATEGORIE, "Pronom Indéfini")
107
	analecCorpus.ajouterVal(Unite.class, unit_type, CATEGORIE, "Pronom ordinal")
108
	analecCorpus.ajouterVal(Unite.class, unit_type, CATEGORIE, "Pronom Relatif")
109
//...
110
}
111

  
112
def nModified = 0
113
def nIgnored = 0
114

  
115
errors = new HashMap()
116
def units = analecCorpus.getUnites(unit_type)
117
units.sort() { a, b -> a.getDeb() <=> b.getDeb() ?: a.getFin() <=> b.getFin() }
118
for (Unite unit : units) { // process all units
119
	
120
	def prop = unit.getProp(CATEGORIE)
121
	if (!reset && prop != null && prop.length() > 0) continue // l'unité a déjà une CATEGORIE
122
	
123
	int[] positions = null
124
	if (unit.getDeb() == unit.getFin()) positions = [unit.getDeb()]
125
	else positions = (unit.getDeb()..unit.getFin())
126
	
127
	def Mention = CQI.cpos2Str(posProperty.getQualifiedName(), positions)
128
	def cat = testRules(positions, Mention)
129
	
130
	if (cat != null) {
131
		vue.setValeurChamp(unit, CATEGORIE, cat)
132
		nModified++
133
	} else {
134
		nIgnored++
135
	}
136
}
137

  
138
println "Result:"
139
println "- $nModified units of type $unit_type have been modified."
140
println "- $nIgnored units of type $unit_type have not been modified.\n"
141

  
142
if (errors.size() > 0) {
143
	println "Some rules should be added to this macro to process the following remaining 'FROPOS / words' values:"
144
	errors.keySet().each { println "fropos="+it+"\twords="+errors[it].join(" | ") }
145
}
tmp/org.txm.analec.rcp/src/org/txm/macro/urs/edit/Frpos2CategorieDemocratMacro.groovy (revision 2066)
1
// @author Bruno Oberlé (2017-04-01 21:50)
2

  
3
/*
4
Définit la catégorie grammaticale du maillon d'après le champ `frpos'
5
(tagset de TreeTagger).  Le script est adapté de
6
http://svn.code.sf.net/p/txm/code/trunk/plugins/Analec/AnalecRCP/src/org/txm/macro/analec/Fropos2CategorieMacro.groovy.
7

  
8
Voici la liste des catégories grammaticales retenues (manuel d'annotation de
9
Democrat):
10
- GN: Groupe Nominal (le petit chat, le chat, le même, ce chat etc.)
11
- POSS: Possessif (mon, ton son, ma, ta, sa, mes, tes, ses, notre, votre,
12
  leur, nos, vos, leurs)
13
- PR: Pronom (moi, toi, lui, elle, nous, vous, eux, elles, le tien, le mien,
14
  moi-même etc.)
15
- PR_CL_O: Pronom Clitique Objet (me, te, le, la, les, lui, leur, y, en)
16
- PR_CL_R: Pronom Clitique Réfléchi
17
- PR_CL_S: Pronom Clitique Sujet (je, tu, il, elle, on, nous, vous, ils,
18
  elles)
19
- PR_REL: Pronom Relatif (qui, que, quoi, dont, où, lequel, quiconque etc.)
20
- PR_WH: Pronom Interrogatif (qui, que, quoi, lequel etc.)
21

  
22
Le script ne peut pas désambiguïser les pronoms clitiques de même forme
23
(`nous' est-il un sujet, un objet ou un réfléchi?).  Dans ce cas, le script
24
opte pour le sujet (ou pour l'objet si l'ambiguïté n'est que entre objet et
25
réfléchi).
26

  
27
Quand il n'y a aucune information disponible (erreurs de l'étiqueteur), la
28
valeur est UNDEFINED.
29

  
30
L'algorithme est décrit ici:
31
https://groupes.renater.fr/wiki/democrat/prive/txm_annotation_exploitation
32

  
33
*/
34

  
35
package org.txm.macro.urs.edit
36

  
37
import org.apache.commons.lang.*
38
import org.kohsuke.args4j.*
39
import groovy.transform.*
40
import org.txm.*
41
import org.txm.rcp.swt.widget.parameters.*
42
import org.txm.annotation.urs.*
43
import org.txm.searchengine.cqp.*
44
import org.txm.searchengine.cqp.corpus.*
45
import visuAnalec.Message.*
46
import visuAnalec.donnees.*
47
import visuAnalec.elements.*
48
import visuAnalec.vue.*
49

  
50
def testClitic(def position, def frpos) {
51

  
52
   // je me sers de la forme, parce qu'il est difficile de savoir quel est le
53
   // lemme de "elle" ("il"?), de "te" ("tu"?) ou encore de "leur"
54
   def form = CQI.cpos2Str(word.getQualifiedName(), position)[0].toLowerCase()
55
   if (     form == "je" || form == "j'"
56
         || form == "tu" || form == "t'"
57
         || form == "il"
58
         || form == "elle"
59
         || form == "on"
60
         || form == "vous"
61
         || form == "nous"
62
         || form == "ils"
63
         || form == "elles" ) {
64
      return "PR_CL_S"
65
   } else if (form == "me" || form == "m'"
66
           || form == "te"
67
           || form == "le" || form == "l'"
68
           || form == "la"
69
           || form == "lui"
70
           || form == "leur"
71
           || form == "les" ) {
72
      return "PR_CL_O"
73
   } else if (form == "se" || form == "s'") {
74
      return "PR_CL_R"
75
   }
76
   return null
77

  
78
}
79

  
80
def testPhrase(def positions, def Mention) {
81

  
82
   // on doit regarder ce qui apparaît en premier:
83
   // - ce peut être un nom, comme dans `le petit chat que j'ai adopté'
84
   // - ce peut être un pronom relatif, comme dans `(le livre) dans lequel
85
   // j'ai lu cette histoire...'
86
   // NOTE: dans Democrat, on n'annote pas, bizarrement, la relative dans le
87
   // maillon, donc, dans un GN on n'a jamais de relatif inclus.  On aura donc
88
   // toujours `[le petit chat] [que] [j']ai adopté'.  Mais tout le monde
89
   // n'annote pas de la sorte...
90
   for (def i=0; i<Mention.length; i++) {
91
         def mention = Mention[i]
92
         //def form = CQI.cpos2Str(word.getQualifiedName(), positions[i])[0]
93
         if (mention == "NOM" || mention == "NAM") {
94
            return "GN"
95
         } else if (mention == "PRO:REL") {
96
            return "PR_REL"
97
         }
98
    }
99

  
100
    return null
101

  
102
}
103

  
104
def testWhPronoun(position, mention) {
105
   def form = CQI.cpos2Str(word.getQualifiedName(), position)[0]
106
   if (mention == "PRO" && (form == "qui" || form == "que" || form == "lequel")) {
107
      return "PR_WH"
108
   }
109
   return null
110

  
111
}
112

  
113
def testRules(def positions, def Mention) {
114
	def catégorie = null
115

  
116
   // a possessive (mon, ma...)
117
   if (Mention.length == 1 && Mention.contains("DET:POS"))
118
      catégorie = "POSS"
119

  
120
   // a clitic (subject: je, tu...; object: me, te; reflexive: se)
121
   if (!catégorie && Mention.length == 1 && Mention.contains("PRO:PER"))
122
      catégorie = testClitic(positions[0], Mention[0])
123

  
124
   // an interrogative pronoun
125
   if (!catégorie && Mention.length == 1)
126
      catégorie = testWhPronoun(positions[0], Mention[0])
127

  
128
   // a noun phrase or a relative pronoun
129
   if (!catégorie)
130
      catégorie = testPhrase(positions, Mention)
131

  
132
   // some other kind of pronouns
133
   if (!catégorie
134
         && (   Mention.contains("PRO")
135
             || Mention.contains("PRO:POSS")
136
             || Mention.contains("PRO:IND")
137
             || Mention.contains("PRO:DEM")
138
             || Mention.contains("PRO:PER") )
139
         && !Mention.contains("NOM")
140
         && !Mention.contains("NAM") )
141
      catégorie = "PRO"
142

  
143
// Fin des règles, aucune n'a matchée. On stocke le pattern  qu'on affichera à la fin.
144
   if (!catégorie) {
145
      catégorie = "UNDEFINED" // clear the field
146
		def forms = CQI.cpos2Str(word.getQualifiedName(), positions)
147
		if (!errors.containsKey(Mention)) errors[Mention] = new HashSet()
148
		errors[Mention] << forms
149
	}
150
	
151
	return catégorie
152
}
153

  
154
//
155
// FIN DE LA DÉFINITION DES RÈGLES
156
//
157

  
158
// CORPS DU SCRIPT
159

  
160
if (!(corpusViewSelection instanceof MainCorpus)) {
161
	println "Corpora selection is not a Corpus"
162
	return
163
}
164

  
165
// BEGINNING OF PARAMETERS
166
@Field @Option(name="unit_type", usage="", widget="String", required=true, def="MENTION")
167
def unit_type
168
@Field @Option(name="pos_property_name", usage="", widget="String", required=true, def="pos")
169
def pos_property_name
170
@Field @Option(name="reset", usage="", widget="Boolean", required=true, def="true")
171
def reset
172
if (!ParametersDialog.open(this)) return
173

  
174
corpus = corpusViewSelection
175
CQI = CQPSearchEngine.getCqiClient()
176
word = corpus.getWordProperty()
177
posProperty = corpus.getProperty(pos_property_name)
178
if (posProperty == null) {
179
	println "Error: CQP corpus does not contains the word property with name=$pos_property_name"
180
	return
181
}
182
analecCorpus = URSCorpora.getCorpus(corpus)
183
vue = URSCorpora.getVue(corpus)
184
structure = analecCorpus.getStructure()
185
if (!structure.getUnites().contains(unit_type)) { // check if the structure contains the unit_type units
186
	println "Error: corpus structure does not contains unit with name=$unit_type"
187
	return
188
}
189

  
190
CATEGORIE = "CATEGORIE"
191
// Si la structure d'annotation ne contient pas CATEGORIE, on la crée avec ses valeurs
192
if (!structure.getUniteProperties(unit_type).contains(CATEGORIE)) { 
193

  
194
// FIXME: dans le script original (see also
195
// http://forge.cbp.ens-lyon.fr/redmine/issues/2065), on utilise
196
// analecCorpus.ajouterProp/Val, mais cela ne marche pas dans ma version de
197
// TXM-Analec --> je retourne donc à structure.ajouterProp/Val
198

  
199
// la propriété
200
	structure.ajouterProp(Unite.class, unit_type, CATEGORIE)
201
// les valeurs
202
	structure.ajouterVal(Unite.class, unit_type, CATEGORIE, "GN")
203
	structure.ajouterVal(Unite.class, unit_type, CATEGORIE, "POSS")
204
	structure.ajouterVal(Unite.class, unit_type, CATEGORIE, "PRO")
205
	structure.ajouterVal(Unite.class, unit_type, CATEGORIE, "PR_CL_O")
206
	structure.ajouterVal(Unite.class, unit_type, CATEGORIE, "PR_CL_S")
207
	structure.ajouterVal(Unite.class, unit_type, CATEGORIE, "PR_CL_R")
208
	structure.ajouterVal(Unite.class, unit_type, CATEGORIE, "PR_REL")
209
	structure.ajouterVal(Unite.class, unit_type, CATEGORIE, "PR_WH")
210
//...
211
}
212

  
213
def nModified = 0
214
def nIgnored = 0
215

  
216
errors = new HashMap()
217
def units = analecCorpus.getUnites(unit_type)
218
units.sort() { a, b -> a.getDeb() <=> b.getDeb() ?: a.getFin() <=> b.getFin() }
219
for (Unite unit : units) { // process all units
220
	
221
	def prop = unit.getProp(CATEGORIE)
222
	if (!reset && prop != null && prop.length() > 0) continue // l'unité a déjà une CATEGORIE
223
	
224
	int[] positions = null
225
	if (unit.getDeb() == unit.getFin()) positions = [unit.getDeb()]
226
	else positions = (unit.getDeb()..unit.getFin())
227
	
228
	def Mention = CQI.cpos2Str(posProperty.getQualifiedName(), positions)
229
	def cat = testRules(positions, Mention)
230

  
231
	if (cat != null) {
232
		// following line in the original script but doesn't work for me:
233
      // vue.setValeurChamp(unit, CATEGORIE, cat)
234
      unit.getProps().put(CATEGORIE, cat)
235
		nModified++
236
	} else {
237
		nIgnored++
238
	}
239
}
240

  
241
println "Result:"
242
println "- $nModified units of type $unit_type have been modified."
243
println "- $nIgnored units of type $unit_type have not been modified.\n"
244

  
245
if (errors.size() > 0) {
246
	println "Some rules should be added to this macro to process the following remaining 'FROPOS / words' values:"
247
	errors.keySet().each { println "fropos="+it+"\twords="+errors[it].join(" | ") }
248
}
249

  
250
// udpate the view (also see also
251
// http://forge.cbp.ens-lyon.fr/redmine/issues/2065)
252
URSCorpora.getVue(analecCorpus).retablirVueParDefaut()
tmp/org.txm.analec.rcp/src/org/txm/macro/urs/edit/PremierMaillonMacro.groovy (revision 2066)
1
// Copyright © 2016 ENS de Lyon, CNRS, University of Franche-Comté
2
// Licensed under the terms of the GNU General Public License (http://www.gnu.org/licenses)
3
// @author mdecorde
4
// @author sheiden
5
// STANDARD DECLARATIONS
6
package org.txm.macro.urs.edit
7

  
8
import org.kohsuke.args4j.*
9

  
10
import groovy.transform.Field
11

  
12
import org.txm.rcp.swt.widget.parameters.*
13
import org.txm.annotation.urs.*
14
import org.txm.searchengine.cqp.corpus.*
15

  
16
import visuAnalec.donnees.Structure;
17
import visuAnalec.elements.Unite;
18
import visuAnalec.vue.Vue
19

  
20
if (!(corpusViewSelection instanceof MainCorpus)) {
21
	println "Corpora selection is not a Corpus"
22
	return;
23
}
24

  
25
// BEGINNING OF PARAMETERS
26
@Field @Option(name="unit_type",usage="", widget="String", required=true, def="MENTION")
27
String unit_type
28
@Field @Option(name="reset",usage="", widget="Boolean", required=true, def="true")
29
boolean reset
30

  
31
if (!ParametersDialog.open(this)) return;
32

  
33
MainCorpus corpus = corpusViewSelection
34
def analecCorpus = URSCorpora.getCorpus(corpus);
35
Structure structure = analecCorpus.getStructure()
36
if (!structure.getUnites().contains(unit_type)) { // check if the structure contains the unit_type units
37
	println "Error: corpus structure does not contains unit with name=$unit_type"
38
	return
39
}
40
def props = structure.getUniteProperties(unit_type)
41

  
42
String NEW = "NEW"
43
String REF = "REF"
44
String YES = "YES"
45
String NO = "NO"
46
if (!props.contains(NEW)) { // update the structure if needed
47
	analecCorpus.ajouterProp(Unite.class, unit_type, NEW);
48
	analecCorpus.ajouterVal(Unite.class, unit_type, NEW, "YES");
49
	analecCorpus.ajouterVal(Unite.class, unit_type, NEW, "NO");
50
}
51

  
52
if (!props.contains(REF)) { // check the unit_type units have the REF property
53
	println "Error: $unit_type units have no proprerty named 'REF'"
54
	return
55
}
56

  
57
int nIgnored = 0; // number of units ignored
58
int nYes = 0 // number of "YES" unit set
59
int nNo = 0 // number of "NO" unit set
60

  
61
def allRefs = new HashSet<String>() // store the references already seen, allow to set the 'NEW' property to 'YES' or 'NO'
62
def units = analecCorpus.getUnites(unit_type)
63
units.sort() { a, b -> a.getDeb() <=> b.getDeb() ?: a.getFin() <=> b.getFin() }
64
for (Unite unit : units) {
65
	def prop = unit.getProp(NEW);
66
	def ref = unit.getProp(REF);
67
	if (reset || prop == null || prop.length() == 0) {
68
		if (allRefs.contains(ref)) {
69
			unit.getProps().put(NEW, NO)
70
			nNo++
71
		} else { // this is the first MENTION of the CHAINE
72
			allRefs << ref
73
			unit.getProps().put(NEW, YES)
74
			nYes++
75
		}
76
	} else {
77
		// nothing to do "NEW" already exists
78
		nIgnored++
79
	}
80
}
81

  
82
println "nIgnored=$nIgnored"
83
println "nYes=$nYes"
84
println "nNo=$nNo"
tmp/org.txm.analec.rcp/src/org/txm/macro/urs/edit/AjoutDefinitudeMacro.groovy (revision 2066)
1
// Copyright © 2016 ENS de Lyon, CNRS, University of Franche-Comté
2
// Licensed under the terms of the GNU General Public License (http://www.gnu.org/licenses)
3
// @author mdecorde
4
// @author sheiden
5
// STANDARD DECLARATIONS
6
package org.txm.macro.urs.edit
7

  
8
import org.apache.commons.lang.StringUtils;
9
import org.kohsuke.args4j.*
10

  
11
import groovy.transform.Field
12

  
13
import org.txm.Toolbox;
14
import org.txm.rcp.swt.widget.parameters.*
15
import org.txm.annotation.urs.*
16
import org.txm.searchengine.cqp.AbstractCqiClient;
17
import org.txm.searchengine.cqp.corpus.*
18
import org.txm.searchengine.cqp.CQPSearchEngine
19
import visuAnalec.Message.StructureEvent;
20
import visuAnalec.Message.TypeModifStructure;
21
import visuAnalec.donnees.Structure;
22
import visuAnalec.elements.Unite;
23
import visuAnalec.vue.Vue
24

  
25
if (!(corpusViewSelection instanceof MainCorpus)) {
26
	println "Corpora selection is not a Corpus"
27
	return;
28
}
29

  
30
// BEGINNING OF PARAMETERS
31
@Field @Option(name="unit_type",usage="", widget="String", required=true, def="MENTION")
32
String unit_type
33
@Field @Option(name="reset",usage="", widget="Boolean", required=true, def="false")
34
boolean reset
35

  
36
if (!ParametersDialog.open(this)) return;
37

  
38
MainCorpus corpus = corpusViewSelection
39
AbstractCqiClient CQI = CQPSearchEngine.getCqiClient();
40
def word = corpus.getWordProperty()
41
def analecCorpus = URSCorpora.getCorpus(corpus);
42
Structure structure = analecCorpus.getStructure()
43
if (!structure.getUnites().contains(unit_type)) { // check if the structure contains the unit_type units
44
	println "Error: corpus structure does not contains unit with name=$unit_type"
45
	return
46
}
47
def props = structure.getUniteProperties(unit_type)
48

  
49
String DEFINITUDE = "DEFINITUDE"
50
if (!props.contains(DEFINITUDE)) { // update the structure if needed
51
	analecCorpus.ajouterProp(Unite.class, unit_type, DEFINITUDE);
52
	analecCorpus.ajouterVal(Unite.class, unit_type, DEFINITUDE, "DEFINI");
53
	analecCorpus.ajouterVal(Unite.class, unit_type, DEFINITUDE, "INDEFINI");
54
	analecCorpus.ajouterVal(Unite.class, unit_type, DEFINITUDE, "DEMONSTRATIF");
55
	analecCorpus.ajouterVal(Unite.class, unit_type, DEFINITUDE, "AMBIGU");
56
	analecCorpus.ajouterVal(Unite.class, unit_type, DEFINITUDE, "NONE");
57
}
58

  
59
int nIgnored = 0 // number of ignored units
60
int nModified = 0 // number of modified units
61
int nDefini = 0 // number of "DEFINI" units
62
int nIndefini = 0 // number of "InDEFINI" units
63
int nDemonstratif = 0 // number of "DEMONSTRATIF" units
64
int nAmbigu = 0 // number of "AMBIGU" units
65
int nNone = 0 // number of "NONE" units
66

  
67
def units = analecCorpus.getUnites(unit_type)
68
units = units.sort() { a, b -> a.getDeb() <=> b.getDeb() ?: a.getFin() <=> b.getFin() }
69
for (Unite unit : units) { // process all units
70
	
71
	def prop = unit.getProp(DEFINITUDE);
72
	
73
	int[] pos = null
74
	if (unit.getDeb() == unit.getFin()) pos = [unit.getDeb()]
75
	else pos = (unit.getDeb()..unit.getFin())
76
	def form = StringUtils.join(CQI.cpos2Str(word.getQualifiedName(), pos), " ")
77
	
78
	if (reset || prop == null || prop.length() == 0 || prop.equals("NONE")) {
79
		// petits ajouts à faire ? : |(ses\s.+)|(Ses\s.+)|(son\s.+)|(Son\s.+)|(sa\s.+)|(Sa\s.+)|(leurs?\s.+)|(Leurs?\s.+)|(tous\s.+)|(Tous\s.+)|(toutes\s.+)|(Toutes\s.+)
80
		if (form =~ /^(le\s.+)|(Les\s.+)|(Le\s.+)|(la\s.+)|(La\s.+)|(l'.+)|(L'.+)|(les\s.+)|(au\s.+)|(Au\s.+)|(aux\s.+)|(Aux\s.+)|(du\s.+)|(Du\s.+)/) {
81
			unit.getProps().put(DEFINITUDE, "DEFINI")
82
			nDefini++
83
		} else if (form =~ /^(un\s.+)|(une\s.+)|(Un\s.+)|(Une\s.+)|(Chaque\s.+)|(chaque\s.+)|(Certains\s.+)|(Certaines\s.+)|(certains\s.+)|(certaines\s.+)|(aucun\s.+)|(aucune\s.+)|(Aucun\s.+)|(Aucunes\s.+)|(Autre\s.+)|(Autre\s.+)|(autres\s.+)|(autre\s.+)|(quelque\s.+)|(quelques\s.+)|(Quelque\s.+)|(Quelques\s.+)/) {
84
			unit.getProps().put(DEFINITUDE, "INDEFINI")
85
			nIndefini++
86
		} else if (form =~ /^(ce\s.+)|(cette\s.+)|(Cette\s.+)|(cet\s.+)|(ces\s.+)|(Ce\s.+)|(Cet\s.+)|(Ces\s.+)/) {
87
			unit.getProps().put(DEFINITUDE, "DEMONSTRATIF")
88
			nDemonstratif++
89
		} else if (form =~ /^(des\s.+)|(de\s.+)|(Des\s.+)|(De\s.+)/) {
90
			unit.getProps().put(DEFINITUDE, "AMBIGU")
91
			nAmbigu++
92
		} else {
93
			unit.getProps().put(DEFINITUDE, "NONE")
94
			nNone++;
95
		}
96
		nModified++
97
		
98
	} else {
99
		// nothing to do
100
		nIgnored++
101
	}
102
}
103

  
104
println "nIgnored=$nIgnored"
105
println "nModified=$nModified"
106
println " nDefini=$nDefini"
107
println " nIndefini=$nIndefini"
108
println " nDemonstratif=$nDemonstratif"
109
println " nAmbigu=$nAmbigu"
110
println " nNone=$nNone"
tmp/org.txm.analec.rcp/src/org/txm/macro/urs/edit/Frpos2CattexMacro.groovy (revision 2066)
1
// @author Matthieu Quignard
2
// Date : 04 Mai 2017
3

  
4
/*
5
Définit la catégorie grammaticale des mentions d'après le champ `frpos'
6
(tagset de TreeTagger). 
7

  
8
La liste des catégories grammaticales est celle de CATTEX2009
9
-- Groupes nominaux :
10
	GN.NAM (noms propres) : Henri II
11
	GN.DEF (définis) : Le roi, du roi
12
	GN.IND (indéfinis) : Un roi
13
	GN.POS (possessifs) : [Mon roi]
14
	GN.DEM (demonstratif) : Ce roi
15
	GN.NUM (numéraux) : Deux rois
16
	GN.CHECK (GN indéterminés)
17
-- Déterminants
18
	DET.POS (possessifs) : [mon] roi
19
-- Pronoms
20
	PRO.PER (personnels) : je, moi, me, on, il, etc.
21
	PRO.ADV (adverbiaux) : y, en
22
	PRO.IND (indéfinis) : tout, tous, certains, plusieurs, etc.
23
	PRO.DEM (demonstratifs) : ceci, cela, ce, ça...
24
	PRO.POS (possessifs) : le mien, les nôtres...
25
	PRO.NUM (cardinaux, ordinaux) : les deux...
26
	PRO.REL (relatifs) : qui, que, quoi, duquel, etc.
27
	PRO.INT (interrogatifs)
28
	PRO.CHECK (pronoms indéterminés)
29
-- Sujet Zéro : verbes conjugués, éventuellement pronominal
30

  
31
-- ERREUR : erreur (a priori) de mention
32

  
33
	
34
*/
35

  
36
package org.txm.macro.urs.edit
37

  
38
import org.apache.commons.lang.*
39
import org.kohsuke.args4j.*
40
import groovy.transform.*
41
import org.txm.*
42
import org.txm.rcp.swt.widget.parameters.*
43
import org.txm.annotation.urs.*
44
import org.txm.searchengine.cqp.*
45
import org.txm.searchengine.cqp.corpus.*
46
import visuAnalec.Message.*
47
import visuAnalec.donnees.*
48
import visuAnalec.elements.*
49
import visuAnalec.vue.*
50

  
51
// Propriété donnant le lemme
52
def lemmaProperty = "frlemma"
53

  
54
/*
55
   TODO : TreeTagger fait un mauvais étiquetage des premiers mots de la phrase.
56
   La majuscule lui fait croire qu'il s'agit d'un nom propre.
57
   Vérifier que ce mot n'est pas en fait un pronom en testant sa présence dans une des listes de formes particulières 
58
*/
59

  
60

  
61
/**
62
  * Liste de formes utile à la catégorisation des mentions
63
  * TreeTagger n'est pas forcément très performant sur des états plus anciens de la langue
64
***/  
65

  
66
formesArticlesDéfinis = ["le", "la", "les", "l'", "au", "aux", "du", "des"]
67
formesArticlesIndéfinis = ["un", "une", "des"]
68
formesDéterminantsPossessifs = ["ma", "ta", "sa", "mon", "ton", "son", "mes", "tes", "ses", "notre", "votre", "leur", "nos", "vos", "leurs"]
69
formesAdjectifsDémonstratifs = ["ce", "cet", "cette", "ces"]
70

  
71
formesPronomsPersonnels = ["je", "tu", "il", "elle", "on", "nous", "vous", "ils", "elles", "moi", "toi", "eux", "me", "te", "se", "lui", "leur"]
72
formesPronomsAdverbiaux = ["en", "y"]
73
formesPronomsPossessifs = ["mien", "mienne", "miens", "miennes", "tien", "tienne", "tiens", "tiennes", "sien", "sienne", "siens", "siennes", "nôtre", "nôtres", "vôtre", "vôtres", "leur", "leurs"]
74
formesPronomsDémonstratifs = ["ce", "c'", "celui", "celle", "ceux", "celles", "ci", "ça", "ceci", "cela", "tel", "telle", "tels", "telles"]
75

  
76
toutesLesFormes = []
77
toutesLesFormes += formesArticlesDéfinis
78
toutesLesFormes += formesArticlesIndéfinis
79
toutesLesFormes += formesDéterminantsPossessifs
80
toutesLesFormes += formesAdjectifsDémonstratifs
81
toutesLesFormes += formesPronomsPersonnels
82
toutesLesFormes += formesPronomsAdverbiaux
83
toutesLesFormes += formesPronomsPossessifs
84
toutesLesFormes += formesPronomsDémonstratifs
85

  
86
/** Fin de la déclaration des formes **/
87

  
88

  
89

  
90
def testRules(def positions, def Mention) {
91
	def catégorie = null
92
    def forme = CQI.cpos2Str(word.getQualifiedName(), positions)[0].toLowerCase()
93
    
94
	if (Mention.length == 1) {    
95
	    
96
		     if (Mention.first() == "NAM"    ) catégorie = "GN.NAM"
97
		else if (Mention.first() == "DET:POS") catégorie = "DET.POS"
98
		else if (Mention.first() == "PRO:PER") {
99
			if (formesPronomsAdverbiaux.contains(forme)) catégorie = "PRO.ADV"
100
			else catégorie = "PRO.PER"
101
		}
102
		else if (Mention.first() == "PRO:DEM") catégorie = "PRO.DEM"
103
		else if (Mention.first() == "PRO:IND") catégorie = "PRO.IND"
104
		else if (Mention.first() == "PRO:REL") catégorie = "PRO.REL"
105
		else if (Mention.first().contains("VER:")) catégorie = "SUJ.ZERO"
106
		else if (Mention.first() == "PRO") catégorie = "PRO.INT"
107
		
108
		// GN indéfinis sans articles
109
		else if (Mention.first() == "NOM") catégorie = "GN.IND"
110
		else if (Mention.first() == "ADJ") catégorie = "GN.IND"
111
		
112
		// gestion des erreurs de TreeTagger
113
		else if (Mention.first() == "KON") catégorie = "PRO.REL" // Le 'que' dans une mention simple est un relatif
114
		else if (Mention.first() == "DET:ART") catégorie = "PRO.PER" // le, les
115
		else if (forme == "en") catégorie = "PRO.ADV"
116
		
117
		else if (Mention.first() == "ADV") catégorie = "ERREUR"  // un adverbe seul n'est jamais référentiel
118
		else if (Mention.first() == "PRE") catégorie = "ERREUR"  // une preposition seule n'est jamais référentielle
119
		else if (Mention.first() == "ADJ") catégorie = "ERREUR"  // un adjectif seul n'est jamais référentiel
120
		else if (Mention.first() == "INT") catégorie = "ERREUR"  // une interjection seule n'est jamais référentielle
121
		
122
		else catégorie = "PRO.CHECK"		
123
	} 
124
	
125
	else if (Mention.length == 2) {
126
		     if (Mention.contains("NAM")) catégorie = "GN.NAM"
127
		else if (Mention[1] == "PRO:POS") catégorie = "PRO.POS"  // "les miens"
128
		else if (Mention[1] == "NUM"    ) catégorie = "PRO.NUM"  // "les deux"
129
		else if (Mention[1] == "PRO:DEM") catégorie = "PRO.DEM"  // "Tout cela"
130
		else if (Mention[0] == "PRO:IND") catégorie = "GN.IND"   // "Quelques trucs"
131
		else if (Mention.contains("PRO:REL")) catégorie = "PRO.REL"
132
		else if ((Mention[0].contains("DET")) && (Mention[1] == "PROind")) catégorie = "PRO.IND" // des autres
133
		else if (Mention[1].contains("VER:")) catégorie = "SUJ.ZERO"
134
		else if (!Mention.contains("NOM") && !Mention.contains("ADJ")) {
135
			if (Mention[0] == "PRO:DEM") catégorie = "PRO.DEM"
136
			else catégorie = "PRO.CHECK"
137
		}
138
		else catégorie = "GN.CHECK"            
139
	} 
140
	
141
	if ( (catégorie == null) || (catégorie == "GN.CHECK") ) {
142
		// on est dans les GN
143
		     if (Mention[0] == "DET:POS" ) catégorie = "GN.POS"
144
		else if (Mention[0] == "NUM"     ) catégorie = "GN.NUM"
145
		else if (Mention[0] == "PRO:DEM" ) catégorie = "GN.DEM"
146
		else if (Mention[0] == "PRP:det" ) catégorie = "GN.DEF"
147
		else if (formesArticlesIndéfinis.contains(forme) || (forme == "une")) catégorie = "GN.IND" 
148
		else if (formesArticlesDéfinis.contains(forme))   catégorie = "GN.DEF"
149
		else if (Mention[0] == "PRO:IND" ) catégorie = "GN.IND"
150
		else if (Mention[0] == "PRP" ) catégorie = "GN.IND"
151
		else if (Mention[0] == "ADJ" ) catégorie = "GN.IND"
152
		else if (Mention[0] == "NOM" ) catégorie = "GN.IND"		
153
		else if (Mention.contains("NAM")) catégorie = "GN.NAM"
154
		else catégorie = "TEST"
155
	}
156
		
157
	return catégorie
158
}
159

  
160
//
161
// FIN DE LA DÉFINITION DES RÈGLES
162
//
163

  
164
// CORPS DU SCRIPT
165

  
166
if (!(corpusViewSelection instanceof MainCorpus)) {
167
	println "Corpora selection is not a Corpus"
168
	return
... Ce différentiel a été tronqué car il excède la taille maximale pouvant être affichée.

Formats disponibles : Unified diff