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 |
Formats disponibles : Unified diff