Index: tmp/org.txm.analec.rcp/src/org/txm/annotation/urs/commands/OpenDemocratTools.java
===================================================================
--- tmp/org.txm.analec.rcp/src/org/txm/annotation/urs/commands/OpenDemocratTools.java	(revision 0)
+++ tmp/org.txm.analec.rcp/src/org/txm/annotation/urs/commands/OpenDemocratTools.java	(revision 2174)
@@ -0,0 +1,64 @@
+package org.txm.annotation.urs.commands;
+
+import java.io.File;
+
+import org.codehaus.groovy.macro.methods.MacroGroovyMethods.MacroValuePlaceholder;
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.kohsuke.args4j.Option;
+import org.txm.Toolbox;
+import org.txm.annotation.urs.view.ElementPropertiesView;
+import org.txm.rcp.views.fileexplorer.MacroExplorer;
+import org.txm.utils.logger.Log;
+
+public class OpenDemocratTools  extends AbstractHandler {
+
+	/** The ID. */
+	public static String ID = "org.txm.annotation.urs.commands.LoadAnnotationStructure"; //$NON-NLS-1$
+
+	@Option(name="ecfile",usage="an example file", widget="File", required=true, def="text.ec")
+	File ecfile;
+
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.core.commands.AbstractHandler#execute(org.eclipse.core.commands.ExecutionEvent)
+	 */
+	@Override
+	public Object execute(ExecutionEvent event) throws ExecutionException {
+		
+		return open();
+	}
+	
+	public static boolean open() {
+		try {
+			IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
+			MacroExplorer view = (MacroExplorer) page.findView(MacroExplorer.ID);
+
+			// close Element View if opened
+			if (view == null) {
+				view = (MacroExplorer) page.showView(MacroExplorer.ID);
+			}
+			
+			if (view == null) {
+				return false;
+			}
+
+			File ursDirectory = new File(Toolbox.getTxmHomePath(), "scripts/groovy/user/org/txm/macro/urs/democrat");
+			view.getTreeViewer().setSelection(new StructuredSelection(ursDirectory));
+			view.getTreeViewer().expandToLevel(ursDirectory, TreeViewer.ALL_LEVELS);
+			//view.getTreeViewer().expandToLevel(elementOrTreePath, level);.collapseAll();
+			
+			return false;
+		} catch (PartInitException e1) {
+			System.out.println("Part initialisation error: "+e1.getLocalizedMessage());
+			Log.printStackTrace(e1);
+		}
+		return false;
+	}
+}

Property changes on: tmp/org.txm.analec.rcp/src/org/txm/annotation/urs/commands/OpenDemocratTools.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.analec.rcp/src/org/txm/macro/urs/DemoMacro.groovy
===================================================================
--- tmp/org.txm.analec.rcp/src/org/txm/macro/urs/DemoMacro.groovy	(revision 2173)
+++ tmp/org.txm.analec.rcp/src/org/txm/macro/urs/DemoMacro.groovy	(revision 2174)
@@ -1,173 +0,0 @@
-package org.txm.macro.urs
-
-import org.txm.annotation.urs.URSCorpora
-import org.txm.searchengine.cqp.corpus.CQPCorpus
-import visuAnalec.elements.*
-
-// get the CQP corpus
-if (!(corpusViewSelection instanceof CQPCorpus)) {
-	println "Corpus view selection is no a corpus: $corpusViewSelection"
-	return false;
-}
-def corpus = corpusViewSelection
-
-// get the Analec corpus : stores the annotations and annotation structure
-
-def analecCorpus = URSCorpora.getCorpus(corpus)
-
-// get the annotations structure : stores the available annotation types, properties and values
-
-def structure = analecCorpus.getStructure()
-
-// get the annotations view : stores annotations and annotation structure display rules
-
-def view = URSCorpora.getVue(corpus)
-
-// set a default vue -> all is visible
-view.retablirVueParDefaut()
-
-// list the viewed types and properties
-for (def type : view.getTypesAVoir(Unite.class)) {
-	println "$type: "+view.getNomsChamps(Unite.class, type)
-}
-
-// manage the viewed&enabled type, properties ; the types and properties must be enabled to use the "view.setValeurChamp(TYPE, PROPERTY, VALUE)" method
-view.ajouterType(Unite.class, "EXEMPLE")
-view.ajouterProp(Unite.class, "EXEMPLE", "PEXEMPLE")
-
-// display annotations per Element type (Unite, Relation, Schema) and per type
-
-// Create annotation type
-
-structure.ajouterType(Unite.class, "EXEMPLE");
-//structure.ajouterType(Relation.class, "EXEMPLE");
-//structure.ajouterType(Schema.class, "EXEMPLE");
-println structure.getTypes(Unite.class)
-
-// Create annotation property
-
-structure.ajouterProp(Unite.class, "EXEMPLE", "PEXEMPLE")
-println structure.getNomsProps(Unite.class, "EXEMPLE")
-
-// Create annotation value
-
-structure.ajouterVal(Unite.class, "EXEMPLE", "PEXEMPLE", "oui")
-structure.ajouterVal(Unite.class, "EXEMPLE", "PEXEMPLE", "non")
-
-// Create annotations
-
-// Unite
-def u = analecCorpus.addUniteSaisie("EXEMPLE", 0, 10, ["PEXEMPLE":"oui"])
-def u2 = analecCorpus.addUniteSaisie("EXEMPLE", 12, 12, ["PEXEMPLE":"oui"])
-println u
-
-// Edit annotations
-
-u.getProps()["PEXEMPLE"] = "non"
-
-// Unit getters
-
-println u.getDeb() // start of unit
-println u.getFin() // end of unit
-
-println u.getProp("EXEMPLE")
-println u.getType()
-
-// Relation
-Relation relation = new Relation("REXEMPLE", u, u2)
-relation.getProps().put("PEXEMPLE", "oui")
-analecCorpus.addRelationLue(relation)  // add the new relation
-
-// Schema
-Schema schema = new Schema()
-schema.type = "SEXEMPLE"
-schema.props.put("PEXEMPLE", "oui")
-schema.ajouter(u) // insert one unit
-
-analecCorpus.addSchemaLu(schema)  // add the new schema
-
-// Browse Units
-
-println "Units:"
-for (String type : structure.getUnites()) {
-	def units = analecCorpus.getUnites(type)
-	if (units.size() > 0) {
-		println "	${units.size()} $type"
-	}
-}
-
-// Browse Relations
-
-println "Relations:"
-for (String type : structure.getRelations()) {
-	def relations = analecCorpus.getRelations(type)
-	if (relations.size() > 0) {
-		println "	${relations.size()} $type"
-	}
-}
-
-// Browse Schemas
-
-println "Schemas:"
-for (String type : structure.getSchemas()) {
-	def schemas = analecCorpus.getSchemas(type)
-	if (schemas.size() > 0) {
-		println "	${schemas.size()} $type"
-	}
-}
-
-// URS selections
-
-// select Schemas
-def debug = 0 // 1 2 for more logs
-def strict_inclusion = true
-def position = 0
-def minimum_schema_size = 1;
-def maximum_schema_size = 10;
-def schema_ursql = "SEXEMPLE"
-def unit_ursql = "EXEMPLE@PEXEMPLE=oui"
-def unit_type = "EXEMPLE" 
-println AnalecUtils.selectSchemasInCorpus(debug, analecCorpus, corpus, schema_ursql, minimum_schema_size, maximum_schema_size, strict_inclusion)
-
-
-// with URSQL
-println AnalecUtils.filterElements(debug, analecCorpus.getUnites(unit_type), unit_ursql)
-
-// with intersection with CQP corpus matches
-println AnalecUtils.filterUniteByInclusion(debug, analecCorpus.getUnites(unit_type), corpus.getMatches(), strict_inclusion, position)
-
-// by size
-println AnalecUtils.filterBySize(analecCorpus.getSchemas(schema_ursql), minimum_schema_size, maximum_schema_size)
-
-// Delete annotations
-
-analecCorpus.supUnite(u)
-analecCorpus.supUnite(u2)
-analecCorpus.supRelation(relation)
-analecCorpus.supSchema(schema)
-
-// Delete annotation value
-
-structure.supprimerVal(Unite.class, "EXEMPLE", "PEXEMPLE", "oui")
-structure.supprimerVal(Unite.class, "EXEMPLE", "PEXEMPLE", "non")
-
-// Delete annotation property
-
-structure.supprimerProp(Unite.class, "EXEMPLE", "PEXEMPLE")
-structure.supprimerProp(Relation.class, "REXEMPLE", "PEXEMPLE")
-structure.supprimerProp(Schema.class, "SEXEMPLE", "PEXEMPLE")
-
-// Delete annotation type
-
-structure.supprimerType(Unite.class, "EXEMPLE");
-structure.supprimerType(Relation.class, "REXEMPLE");
-structure.supprimerType(Schema.class, "SEXEMPLE");
-
-// Revert changes
-
-//URSCorpora.revert(corpus);
-
-// Save changes
-
-//URSCorpora.saveCorpus(corpus)
-
Index: tmp/org.txm.analec.rcp/src/org/txm/macro/urs/export/ExportAsMacro.groovy
===================================================================
--- tmp/org.txm.analec.rcp/src/org/txm/macro/urs/export/ExportAsMacro.groovy	(revision 2173)
+++ tmp/org.txm.analec.rcp/src/org/txm/macro/urs/export/ExportAsMacro.groovy	(revision 2174)
@@ -1,127 +0,0 @@
-// Copyright © 2016 ENS de Lyon, CNRS, University of Franche-Comté
-// Licensed under the terms of the GNU General Public License (http://www.gnu.org/licenses)
-// @author mdecorde
-// @author sheiden
-// STANDARD DECLARATIONS
-package org.txm.macro.urs.export
-
-import groovy.transform.Field
-
-import org.jfree.chart.JFreeChart
-import org.kohsuke.args4j.*
-import org.txm.Toolbox
-import org.txm.annotation.urs.*
-import org.txm.macro.urs.AnalecUtils
-import org.txm.rcp.Application
-import org.txm.rcp.IImageKeys
-import org.txm.rcp.swt.widget.parameters.*
-import org.txm.searchengine.cqp.corpus.*
-import org.txm.searchengine.cqp.corpus.query.CQLQuery
-import org.txm.utils.io.FileCopy;
-import org.txm.utils.io.IOUtils
-import org.txm.utils.zip.Zip
-
-import visuAnalec.elements.*
-
-def scriptName = this.class.getSimpleName()
-if (!(corpusViewSelection instanceof MainCorpus)) {
-	println "** $scriptName please select a MainCorpus to run the macro"
-	return;
-}
-
-@Field @Option(name="new_name", usage="Corpus name in uppercase", widget="String", required=true, def="CORPUSNAME")
-String new_name
-if (!ParametersDialog.open(this)) return
-
-new_name = new_name.toUpperCase()
-def pattern = "[A-Z][-A-Z0-9]{1,20}"
-if (!new_name.matches(pattern)) {
-	println "New corpus name not conformant to CQP corpus name: "+pattern
-	return false
-}
-
-MainCorpus mainCorpus = corpusViewSelection.getMainCorpus()
-String name = mainCorpus.getName()
-if (mainCorpus.isModified()) {
-	println "Selected corpus is not saved. Aborting"
-	return false
-}
-
-visuAnalec.donnees.Corpus analecCorpus = URSCorpora.getCorpus(mainCorpus)
-if (analecCorpus.isModifie()) {
-	println "Selected Analec corpus is not saved. Aborting"
-	return false
-}
-
-File binDirectory = mainCorpus.getProjectDirectory()
-String binName = binDirectory.getName()
-
-
-File newBinDirectory = new File(binDirectory.getParentFile(), new_name)
-
-if (newBinDirectory.exists()) {
-	println "The new corpus directory already exists: $newBinDirectory. Aborting."
-	return false
-}
-
-FileCopy.copyFiles(binDirectory, newBinDirectory)
-if (!newBinDirectory.exists()) {
-	println "Fail to copy binary directory $binDirectory to $newBinDirectory"
-	return
-}
-
-File ecFile = new File(newBinDirectory, "analec/${name}.ec")
-File ecvFile = new File(newBinDirectory, "analec/${name}.ecv")
-File cssFile = new File(newBinDirectory, "css/${name}.css")
-File dataFile = new File(newBinDirectory, "data/${name}")
-File htmlFile = new File(newBinDirectory, "HTML/${name}")
-File defaultCSSFile = new File(newBinDirectory, "HTML/${name}/default/css/${name}.css")
-File registryFile = new File(newBinDirectory, "registry/${name.toLowerCase()}")
-File txmFile = new File(newBinDirectory, "txm/${name}")
-
-File ecFile2 = new File(newBinDirectory, "analec/${new_name}.ec")
-File ecvFile2 = new File(newBinDirectory, "analec/${new_name}.ecv")
-File cssFile2 = new File(newBinDirectory, "css/${new_name}.css")
-File dataFile2 = new File(newBinDirectory, "data/${new_name}")
-File htmlFile2 = new File(newBinDirectory, "HTML/${new_name}")
-File defaultCSSFile2 = new File(newBinDirectory, "HTML/${new_name}/default/css/${new_name}.css")
-File registryFile2 = new File(newBinDirectory, "registry/${new_name.toLowerCase()}")
-File txmFile2 = new File(newBinDirectory, "txm/${new_name}")
-
-println "renaming $ecFile : "+ecFile.renameTo(ecFile2)
-println "renaming $ecvFile : "+ecvFile.renameTo(ecvFile2)
-println "renaming $cssFile : "+cssFile.renameTo(cssFile2)
-println "renaming $dataFile : "+dataFile.renameTo(dataFile2)
-println "renaming $htmlFile : "+htmlFile.renameTo(htmlFile2)
-println "renaming $defaultCSSFile : "+defaultCSSFile.renameTo(defaultCSSFile2)
-println "renaming $registryFile : "+registryFile.renameTo(registryFile2)
-println "renaming $txmFile : "+txmFile.renameTo(txmFile2)
-
-// patch name in settings
-println "replacing old name $name ->  ${new_name} in preferences"
-File settingsDirectory = new File(newBinDirectory, ".settings")
-for (File prefFile : settingsDirectory.listFiles()) {
-	IOUtils.write(prefFile, prefFile.getText().replace(name, new_name))
-}
-
-File projectSetting = new File(newBinDirectory, ".project")
-IOUtils.write(projectSetting, projectSetting.getText().replace(name, new_name))
-
-// patch registry
-String oldcontent = registryFile2.getText();
-content = oldcontent.replace(name, new_name)
-content = content.replace(name.toLowerCase(), new_name.toLowerCase())
-registryFile2.withWriter { writer -> 
-	writer.write(content)
-}
-
-
-File zipFile = new File(newBinDirectory.getAbsolutePath()+".txm")
-Zip.compress(newBinDirectory, zipFile, monitor)
-
-if (!zipFile.exists()) {
-	println "Fail to zip binary directory $binDirectory to $zipFile"
-	return
-} else {
-	println "Done: $zipFile"
-}
\ No newline at end of file
Index: tmp/org.txm.analec.rcp/src/org/txm/macro/urs/export/ExportToGlozz1_0_0Macro.groovy
===================================================================
--- tmp/org.txm.analec.rcp/src/org/txm/macro/urs/export/ExportToGlozz1_0_0Macro.groovy	(revision 2173)
+++ tmp/org.txm.analec.rcp/src/org/txm/macro/urs/export/ExportToGlozz1_0_0Macro.groovy	(revision 2174)
@@ -1,161 +0,0 @@
-package org.txm.macro.urs.export
-
-// @author: Bruno Oberlé
-// v1.0.0 2017-08-28
-
-/*
- Cette macro exporte le corpus sélectionné et ses annotations vers deux fichiers de format Glozz:
- - un fichier .ac contenant le corpus brut,
- - un fichier .aa contenant les annotations au format XML utilisé par Glozz.
- Le corpus sélectionné dans TXM devrait contenir une structure Analec avec au moins un type d'unité défini (e.g. MENTION, maillon, etc.). S'il n'y a pas de structure,
- ce n'est pas grave: le fichier est exporter, mais aucune annotation n'est créer. Cela permet d'exporter n'importe quel corpus au format Glozz.
- Pour exporter un texte au format Glozz *sans* les annotations qu'il contient, simplement mettre un unit_type qui n'existe pas (e.g. "foobar" au lieu de "MENTION").
- La macro ne produit pour l'instant pas automatiquement de modèle Glozz (fichier .aam).  Cela n'est pas un problème pour ouvrir le résultat dans Glozz ou Analec.
- */
-
-// STANDARD DECLARATIONS
-
-import org.apache.commons.lang.*
-import org.kohsuke.args4j.*
-import groovy.transform.*
-import org.txm.*
-import org.txm.rcp.swt.widget.parameters.*
-import org.txm.annotation.urs.*
-import org.txm.searchengine.cqp.*
-import org.txm.searchengine.cqp.corpus.*
-import visuAnalec.Message.*
-import visuAnalec.donnees.*
-import visuAnalec.elements.*
-import visuAnalec.vue.*
-
-// CHECK CORPUS
-
-if (!(corpusViewSelection instanceof MainCorpus)) {
-	println "Corpora selection is not a MainCorpus: "+corpusViewSelection
-	return;
-}
-
-// BEGINNING OF PARAMETERS
-
-@Field @Option(name="unit_type",usage="", widget="String", required=true, def="MENTION")
-		String unit_type
-
-@Field @Option(name="filename",usage="", widget="String", required=true, def="filename without extension (.ac/.aa)")
-		String filename
-
-if (!ParametersDialog.open(this)) return;
-
-// VARIABLES
-
-corpus = corpusViewSelection
-
-doExport(corpus, unit_type, filename)
-
-public void doExport(MainCorpus corpus, String unit_type, String filename) {
-
-	size = corpus.getSize() // you may also use: corpus.getTextEndLimits() (= index of last token = size-1)
-	CQI = CQPSearchEngine.getCqiClient()
-	word = corpus.getWordProperty()
-	// note: using "lbn" seems to work better than "pn" (some imported corpora are missing this information)
-	//pn = corpus.getProperty("pn")
-	//if (pn == null) pn = corpus.getProperty("div")
-	pn = corpus.getProperty("lbn")
-
-	// BUILD THE RAW TEXT, THE POSITIONS AND FIND THE PARAGRAPHS
-
-	rawText = "" // the corpus for the .ac file
-	positions = [] // each element is an array [start, end] indicating the position in the rawText
-	pnCount = 0 // the par counter, used for indexing the pns array
-	lastPn = -1 // the last paragraph number
-	pns = [] // each element is an array [start, end] representing the start and end of the paragraph in the rawText
-	for (def i=0; i<size; i++) {
-		f = CQI.cpos2Str(word.getQualifiedName(), (int[])[i])[0]
-		if (pn == null) {
-			p = 1
-		} else {
-			p = CQI.cpos2Str(pn.getQualifiedName(), (int[])[i])[0]
-		}
-		start = rawText.length()
-		rawText += f
-		if (lastPn != p) {
-			pnCount++;
-			if (pnCount > 1) {
-				pns[pnCount-2][1] = end
-			}
-			pns[pnCount-1] = [start, 0]
-		}
-		lastPn = p
-		end = rawText.length() // must be after setting it up in pns!
-		if (i != size-1) rawText += " "
-		positions[i] = [start, end]
-	}
-	pns[pnCount-1][1] = end
-	println pnCount + " paragraph(s) found."
-
-
-
-	// CORPUS ANALEC (GET THE ANNOTATIONS)
-
-	// note that unit_type has been defined with an option of the dialog at the beginning
-	def analecCorpus = URSCorpora.getCorpus(corpus);
-
-	// list of properties
-
-	struct = analecCorpus.getStructure();
-	propertyList = struct.getUniteProperties(unit_type);
-
-	// export to file (corpus)
-
-	corpusFilename = filename + ".ac";
-	def corpusFile = new File(corpusFilename);
-	corpusFile.write(rawText)
-	println("Corpus written to `"+corpusFilename+"'.");
-
-	// export to file (annotations)
-
-	annotFilename = filename + ".aa";
-	def annotFile = new File(annotFilename)
-	annotFile.write("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<annotations>\n")
-		// erase (if you use << you don't erase!)
-	def counter = 0
-
-	// export paragraphs
-	for (def i=0; i<pns.size(); i++) {
-		def start = pns[i][0]
-		def end = pns[i][1]
-		annotFile << "<unit id=\"me_"+counter+"\">\n";
-		annotFile << "<metadata><author>me</author><creation-date>"+counter+"</creation-date></metadata>\n";
-		annotFile << "<characterisation><type>paragraph</type><featureSet /></characterisation>\n";
-		annotFile << "<positioning><start><singlePosition index=\""+start+"\" /></start><end><singlePosition index=\""+end+"\" /></end></positioning>\n";
-		annotFile << "</unit>\n";
-		counter++;
-	}
-
-	// export units
-	def units = analecCorpus.getUnites(unit_type);
-	//units.sort() { a, b -> a.getDeb() <=> b.getDeb() ?: a.getFin() <=> b.getFin() };
-	def unitCount = 0
-	for (Unite unit : units) {
-		unitCount++;
-		annotFile << "<unit id=\"me_"+counter+"\">\n";
-		annotFile << "<metadata><author>me</author><creation-date>"+counter+"</creation-date></metadata>\n";
-		annotFile << "<characterisation>\n";
-		annotFile << "<type>"+unit_type+"</type>\n";
-		annotFile << "<featureSet>\n";
-		for (String propertyName : propertyList) {
-			annotFile << "<feature name=\""+propertyName+"\">"+unit.getProp(propertyName)+"</feature>\n";
-		}
-		annotFile << "</featureSet>\n";
-		annotFile << "</characterisation>\n";
-		start = positions[unit.getDeb()][0]
-		end = positions[unit.getFin()][1]
-		annotFile << "<positioning><start><singlePosition index=\""+start+"\" /></start><end><singlePosition index=\""+end+"\" /></end></positioning>\n";
-		annotFile << "</unit>\n";
-		counter++;
-	}
-	annotFile << "</annotations>\n";
-
-	println unitCount + " unit(s) found."
-
-	println("Annotations written to `"+annotFilename+"'.");
-}
\ No newline at end of file
Index: tmp/org.txm.analec.rcp/src/org/txm/macro/urs/export/ExportToGlozz1_1_0Macro.groovy
===================================================================
--- tmp/org.txm.analec.rcp/src/org/txm/macro/urs/export/ExportToGlozz1_1_0Macro.groovy	(revision 2173)
+++ tmp/org.txm.analec.rcp/src/org/txm/macro/urs/export/ExportToGlozz1_1_0Macro.groovy	(revision 2174)
@@ -1,200 +0,0 @@
-package org.txm.macro.urs.export
-
-// @author: Bruno Oberle
-// v1.1.0 2017-10-25:
-//  - using the "p" structural unit if available to get paragraphs
-//  - no space before comma, parenthesis, full stop, hyphen, etc.
-//  - no space after hyphen, parenthesis, apostrophe, etc.
-// v1.0.0 2017-08-28
-
-/*
- Cette macro exporte le corpus sélectionné et ses annotations vers deux fichiers de format Glozz:
- - un fichier .ac contenant le corpus brut,
- - un fichier .aa contenant les annotations au format XML utilisé par Glozz.
- Le corpus sélectionné dans TXM devrait contenir une structure Analec avec au moins un type d'unité défini (e.g. MENTION, maillon, etc.). S'il n'y a pas de structure,
- ce n'est pas grave: le fichier est exporter, mais aucune annotation n'est créer. Cela permet d'exporter n'importe quel corpus au format Glozz.
- Pour exporter un texte au format Glozz *sans* les annotations qu'il contient, simplement mettre un unit_type qui n'existe pas (e.g. "foobar" au lieu de "MENTION").
- La macro ne produit pour l'instant pas automatiquement de modèle Glozz (fichier .aam).  Cela n'est pas un problème pour ouvrir le résultat dans Glozz ou Analec.
- */
-
-// STANDARD DECLARATIONS
-
-import org.apache.commons.lang.*
-import org.kohsuke.args4j.*
-import groovy.transform.*
-import org.txm.*
-import org.txm.rcp.swt.widget.parameters.*
-import org.txm.annotation.urs.*
-import org.txm.searchengine.cqp.*
-import org.txm.searchengine.cqp.corpus.*
-import visuAnalec.Message.*
-import visuAnalec.donnees.*
-import visuAnalec.elements.*
-import visuAnalec.vue.*
-
-
-// GLOBAL VARIABLES
-
-corpus = corpusViewSelection
-CQI = CQPSearchEngine.getCqiClient()
-
-// CHECK CORPUS
-
-if (!(corpusViewSelection instanceof MainCorpus)) {
-	println "Corpora selection is not a MainCorpus: "+corpusViewSelection
-	return;
-}
-
-// PARAGRAPH AS STRUCTURAL UNIT?
-
-/* note: some text have a structural unit called "p", which represents a paragraph.
-   If this structural unit is present, we use it.  Otherwise we ask the user (the
-   best way is to use the "pn" (paragraph number) or "lbn" (line number) property),
-   depending on what is available in the corpus. If the user give not property name,
-   we only define one paragraph for the whole text. */
-
-parUnit = corpus.getStructuralUnit("p")
-
-// BEGINNING OF PARAMETERS
-
-@Field @Option(name="unit_type",usage="", widget="String", required=true, def="MENTION")
-		String unit_type
-
-@Field @Option(name="filename",usage="", widget="String", required=true, def="filename without extension (.ac/.aa)")
-		String filename
-
-if (!parUnit) {
-	@Field @Option(name="par_prop",usage="the property used to compute paragraphs", widget="String", required=false, def="lbn")
-		String par_prop
-}
-
-if (!ParametersDialog.open(this)) return;
-
-// what paragraph unit to use?
-
-pn = null
-if (!parUnit && !par_prop.equals("")) {
-	pn = corpus.getProperty(par_prop)
-	if (!pn) {
-		println "Error: I can't find a the property `$par_prop'."
-		return
-	}
-}
-
-/*********************************/
-
-doExport(corpus, unit_type, filename)
-
-public void doExport(MainCorpus corpus, String unit_type, String filename) {
-
-	size = corpus.getSize() // you may also use: corpus.getTextEndLimits() (= index of last token = size-1)
-	word = corpus.getWordProperty()
-
-	// BUILD THE RAW TEXT, THE POSITIONS AND FIND THE PARAGRAPHS
-
-	rawText = "" // the corpus for the .ac file
-	positions = [] // each element is an array [start, end] indicating the position in the rawText
-	pnCount = 0 // the par counter, used for indexing the pars array
-	lastPn = -1 // the last paragraph number
-	pars = [] // each element is an array [start, end] representing the start and end of the paragraph in the rawText
-	insertSpace = true
-	for (def i=0; i<size; i++) {
-		f = CQI.cpos2Str(word.getQualifiedName(), (int[])[i])[0]
-		if (parUnit) {
-			p = CQI.cpos2Struc(parUnit.getQualifiedName(), (int[])[i])[0]
-		} else if (pn == null) {
-			p = 1
-		} else {
-			p = CQI.cpos2Str(pn.getQualifiedName(), (int[])[i])[0]
-		}
-		if (i > 0 && insertSpace
-				&& !f.equals(".") && !f.equals(",") && !f.equals("'") && !f.equals("’") && !f.equals("-")
-				&& !f.equals(")") && !f.equals("]") && !f.startsWith("-")) {
-			rawText += " "
-		}
-		insertSpace = true // reset
-		if (f.equals("-") || f.equals("[") || f.equals("(")
-				|| f.endsWith("-") || f.endsWith("'") || f.endsWith("’") || f.endsWith("-")) {
-			insertSpace = false
-		}
-		start = rawText.length()
-		rawText += f
-		if (lastPn != p) {
-			pnCount++;
-			if (pnCount > 1) {
-				pars[pnCount-2][1] = end
-			}
-			pars[pnCount-1] = [start, 0]
-		}
-		lastPn = p
-		end = rawText.length() // must be after setting it up in pars!
-		positions[i] = [start, end]
-	}
-	pars[pnCount-1][1] = end
-	println pnCount + " paragraph(s) found."
-
-	// CORPUS ANALEC (GET THE ANNOTATIONS)
-
-	// note that unit_type has been defined with an option of the dialog at the beginning
-	def analecCorpus = URSCorpora.getCorpus(corpus);
-
-	// list of properties
-
-	struct = analecCorpus.getStructure();
-	propertyList = struct.getUniteProperties(unit_type);
-
-	// export to file (corpus)
-
-	corpusFilename = filename + ".ac";
-	def corpusFile = new File(corpusFilename);
-	corpusFile.write(rawText)
-	println("Corpus written to `"+corpusFilename+"'.");
-
-	// export to file (annotations)
-
-	annotFilename = filename + ".aa";
-	def annotFile = new File(annotFilename)
-	annotFile.write("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<annotations>\n")
-		// erase (if you use << you don't erase!)
-	def counter = 0
-
-	// export paragraphs
-	for (def i=0; i<pars.size(); i++) {
-		def start = pars[i][0]
-		def end = pars[i][1]
-		annotFile << "<unit id=\"me_"+counter+"\">\n";
-		annotFile << "<metadata><author>me</author><creation-date>"+counter+"</creation-date></metadata>\n";
-		annotFile << "<characterisation><type>paragraph</type><featureSet /></characterisation>\n";
-		annotFile << "<positioning><start><singlePosition index=\""+start+"\" /></start><end><singlePosition index=\""+end+"\" /></end></positioning>\n";
-		annotFile << "</unit>\n";
-		counter++;
-	}
-
-	// export units
-	def units = analecCorpus.getUnites(unit_type);
-	//units.sort() { a, b -> a.getDeb() <=> b.getDeb() ?: a.getFin() <=> b.getFin() };
-	def unitCount = 0
-	for (Unite unit : units) {
-		unitCount++;
-		annotFile << "<unit id=\"me_"+counter+"\">\n";
-		annotFile << "<metadata><author>me</author><creation-date>"+counter+"</creation-date></metadata>\n";
-		annotFile << "<characterisation>\n";
-		annotFile << "<type>"+unit_type+"</type>\n";
-		annotFile << "<featureSet>\n";
-		for (String propertyName : propertyList) {
-			annotFile << "<feature name=\""+propertyName+"\">"+unit.getProp(propertyName)+"</feature>\n";
-		}
-		annotFile << "</featureSet>\n";
-		annotFile << "</characterisation>\n";
-		start = positions[unit.getDeb()][0]
-		end = positions[unit.getFin()][1]
-		annotFile << "<positioning><start><singlePosition index=\""+start+"\" /></start><end><singlePosition index=\""+end+"\" /></end></positioning>\n";
-		annotFile << "</unit>\n";
-		counter++;
-	}
-	annotFile << "</annotations>\n";
-
-	println unitCount + " unit(s) found."
-
-	println("Annotations written to `"+annotFilename+"'.");
-}
Index: tmp/org.txm.analec.rcp/src/org/txm/macro/urs/export/ExportToGlozzMacro.groovy
===================================================================
--- tmp/org.txm.analec.rcp/src/org/txm/macro/urs/export/ExportToGlozzMacro.groovy	(revision 2173)
+++ tmp/org.txm.analec.rcp/src/org/txm/macro/urs/export/ExportToGlozzMacro.groovy	(revision 2174)
@@ -1,160 +0,0 @@
-package org.txm.macro.urs.export
-
-// @author: Bruno Oberlé
-// v1.0.0 2017-08-28
-
-/*
- Cette macro exporte le corpus sélectionné et ses annotations vers deux fichiers de format Glozz:
- - un fichier .ac contenant le corpus brut,
- - un fichier .aa contenant les annotations au format XML utilisé par Glozz.
- Le corpus sélectionné dans TXM devrait contenir une structure Analec avec au moins un type d'unité défini (e.g. MENTION, maillon, etc.). S'il n'y a pas de structure,
- ce n'est pas grave: le fichier est exporter, mais aucune annotation n'est créer. Cela permet d'exporter n'importe quel corpus au format Glozz.
- Pour exporter un texte au format Glozz *sans* les annotations qu'il contient, simplement mettre un unit_type qui n'existe pas (e.g. "foobar" au lieu de "MENTION").
- La macro ne produit pour l'instant pas automatiquement de modèle Glozz (fichier .aam).  Cela n'est pas un problème pour ouvrir le résultat dans Glozz ou Analec.
- */
-
-// STANDARD DECLARATIONS
-
-import org.apache.commons.lang.*
-import org.kohsuke.args4j.*
-import groovy.transform.*
-import org.txm.*
-import org.txm.rcp.swt.widget.parameters.*
-import org.txm.annotation.urs.*
-import org.txm.searchengine.cqp.*
-import org.txm.searchengine.cqp.corpus.*
-import visuAnalec.Message.*
-import visuAnalec.donnees.*
-import visuAnalec.elements.*
-import visuAnalec.vue.*
-
-// CHECK CORPUS
-
-if (!(corpusViewSelection instanceof MainCorpus)) {
-	println "Corpora selection is not a MainCorpus: "+corpusViewSelection
-	return;
-}
-
-// BEGINNING OF PARAMETERS
-
-@Field @Option(name="unit_type",usage="", widget="String", required=true, def="MENTION")
-		String unit_type
-
-@Field @Option(name="filename",usage="", widget="String", required=true, def="filename without extension (.ac/.aa)")
-		String filename
-
-if (!ParametersDialog.open(this)) return;
-
-// VARIABLES
-
-corpus = corpusViewSelection
-
-doExport(corpus, unit_type, filename)
-
-public void doExport(MainCorpus corpus, String unit_type, String filename) {
-
-	size = corpus.getSize() // you may also use: corpus.getTextEndLimits() (= index of last token = size-1)
-	CQI = CQPSearchEngine.getCqiClient()
-	word = corpus.getWordProperty()
-	// note: using "lbn" seems to work better than "pn" (some imported corpora are missing this information)
-	//pn = corpus.getProperty("pn")
-	//if (pn == null) pn = corpus.getProperty("div")
-	pn = corpus.getProperty("lbn")
-
-	// BUILD THE RAW TEXT, THE POSITIONS AND FIND THE PARAGRAPHS
-
-	rawText = "" // the corpus for the .ac file
-	positions = [] // each element is an array [start, end] indicating the position in the rawText
-	pnCount = 0 // the par counter, used for indexing the pns array
-	lastPn = -1 // the last paragraph number
-	pns = [] // each element is an array [start, end] representing the start and end of the paragraph in the rawText
-	for (def i=0; i<size; i++) {
-		f = CQI.cpos2Str(word.getQualifiedName(), (int[])[i])[0]
-		if (pn == null) {
-			p = 1
-		} else {
-			p = CQI.cpos2Str(pn.getQualifiedName(), (int[])[i])[0]
-		}
-		start = rawText.length()
-		rawText += f
-		if (lastPn != p) {
-			pnCount++;
-			if (pnCount > 1) {
-				pns[pnCount-2][1] = end
-			}
-			pns[pnCount-1] = [start, 0]
-		}
-		lastPn = p
-		end = rawText.length() // must be after setting it up in pns!
-		if (i != size-1) rawText += " "
-		positions[i] = [start, end]
-	}
-	pns[pnCount-1][1] = end
-	println pnCount + " paragraph(s) found."
-
-
-
-	// CORPUS ANALEC (GET THE ANNOTATIONS)
-
-	// note that unit_type has been defined with an option of the dialog at the beginning
-	def analecCorpus = URSCorpora.getCorpus(corpus);
-
-	// list of properties
-
-	struct = analecCorpus.getStructure();
-	propertyList = struct.getUniteProperties(unit_type);
-
-	// export to file (corpus)
-
-	corpusFilename = filename + ".ac";
-	def corpusFile = new File(corpusFilename);
-	corpusFile.write(rawText)
-	println("Corpus written to `"+corpusFilename+"'.");
-
-	// export to file (annotations)
-
-	annotFilename = filename + ".aa";
-	def annotFile = new File(annotFilename)
-	annotFile.write("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<annotations>\n") // erase
-	def counter = 0
-
-	// export paragraphs
-	for (def i=0; i<pns.size(); i++) {
-		def start = pns[i][0]
-		def end = pns[i][1]
-		annotFile << "<unit id=\"me_"+counter+"\">\n";
-		annotFile << "<metadata><author>me</author><creation-date>"+counter+"</creation-date></metadata>\n";
-		annotFile << "<characterisation><type>paragraph</type><featureSet /></characterisation>\n";
-		annotFile << "<positioning><start><singlePosition index=\""+start+"\" /></start><end><singlePosition index=\""+end+"\" /></end></positioning>\n";
-		annotFile << "</unit>\n";
-		counter++;
-	}
-
-	// export units
-	def units = analecCorpus.getUnites(unit_type);
-	//units.sort() { a, b -> a.getDeb() <=> b.getDeb() ?: a.getFin() <=> b.getFin() };
-	def unitCount = 0
-	for (Unite unit : units) {
-		unitCount++;
-		annotFile << "<unit id=\"me_"+counter+"\">\n";
-		annotFile << "<metadata><author>me</author><creation-date>"+counter+"</creation-date></metadata>\n";
-		annotFile << "<characterisation>\n";
-		annotFile << "<type>"+unit_type+"</type>\n";
-		annotFile << "<featureSet>\n";
-		for (String propertyName : propertyList) {
-			annotFile << "<feature name=\""+propertyName+"\">"+unit.getProp(propertyName)+"</feature>\n";
-		}
-		annotFile << "</featureSet>\n";
-		annotFile << "</characterisation>\n";
-		start = positions[unit.getDeb()][0]
-		end = positions[unit.getFin()][1]
-		annotFile << "<positioning><start><singlePosition index=\""+start+"\" /></start><end><singlePosition index=\""+end+"\" /></end></positioning>\n";
-		annotFile << "</unit>\n";
-		counter++;
-	}
-	annotFile << "</annotations>\n";
-
-	println unitCount + " unit(s) found."
-
-	println("Annotations written to `"+annotFilename+"'.");
-}
\ No newline at end of file
Index: tmp/org.txm.analec.rcp/src/org/txm/macro/urs/export/ExportCorpusAsMacro.groovy
===================================================================
--- tmp/org.txm.analec.rcp/src/org/txm/macro/urs/export/ExportCorpusAsMacro.groovy	(revision 0)
+++ tmp/org.txm.analec.rcp/src/org/txm/macro/urs/export/ExportCorpusAsMacro.groovy	(revision 2174)
@@ -0,0 +1,127 @@
+// Copyright © 2016 ENS de Lyon, CNRS, University of Franche-Comté
+// Licensed under the terms of the GNU General Public License (http://www.gnu.org/licenses)
+// @author mdecorde
+// @author sheiden
+// STANDARD DECLARATIONS
+package org.txm.macro.urs.export
+
+import groovy.transform.Field
+
+import org.jfree.chart.JFreeChart
+import org.kohsuke.args4j.*
+import org.txm.Toolbox
+import org.txm.annotation.urs.*
+import org.txm.macro.urs.AnalecUtils
+import org.txm.rcp.Application
+import org.txm.rcp.IImageKeys
+import org.txm.rcp.swt.widget.parameters.*
+import org.txm.searchengine.cqp.corpus.*
+import org.txm.searchengine.cqp.corpus.query.CQLQuery
+import org.txm.utils.io.FileCopy;
+import org.txm.utils.io.IOUtils
+import org.txm.utils.zip.Zip
+
+import visuAnalec.elements.*
+
+def scriptName = this.class.getSimpleName()
+if (!(corpusViewSelection instanceof MainCorpus)) {
+	println "** $scriptName please select a MainCorpus to run the macro"
+	return;
+}
+
+@Field @Option(name="new_name", usage="Corpus name in uppercase", widget="String", required=true, def="CORPUSNAME")
+String new_name
+if (!ParametersDialog.open(this)) return
+
+new_name = new_name.toUpperCase()
+def pattern = "[A-Z][-A-Z0-9]{1,20}"
+if (!new_name.matches(pattern)) {
+	println "New corpus name not conformant to CQP corpus name: "+pattern
+	return false
+}
+
+MainCorpus mainCorpus = corpusViewSelection.getMainCorpus()
+String name = mainCorpus.getName()
+if (mainCorpus.isModified()) {
+	println "Selected corpus is not saved. Aborting"
+	return false
+}
+
+visuAnalec.donnees.Corpus analecCorpus = URSCorpora.getCorpus(mainCorpus)
+if (analecCorpus.isModifie()) {
+	println "Selected Analec corpus is not saved. Aborting"
+	return false
+}
+
+File binDirectory = mainCorpus.getProjectDirectory()
+String binName = binDirectory.getName()
+
+
+File newBinDirectory = new File(binDirectory.getParentFile(), new_name)
+
+if (newBinDirectory.exists()) {
+	println "The new corpus directory already exists: $newBinDirectory. Aborting."
+	return false
+}
+
+FileCopy.copyFiles(binDirectory, newBinDirectory)
+if (!newBinDirectory.exists()) {
+	println "Fail to copy binary directory $binDirectory to $newBinDirectory"
+	return
+}
+
+File ecFile = new File(newBinDirectory, "analec/${name}.ec")
+File ecvFile = new File(newBinDirectory, "analec/${name}.ecv")
+File cssFile = new File(newBinDirectory, "css/${name}.css")
+File dataFile = new File(newBinDirectory, "data/${name}")
+File htmlFile = new File(newBinDirectory, "HTML/${name}")
+File defaultCSSFile = new File(newBinDirectory, "HTML/${name}/default/css/${name}.css")
+File registryFile = new File(newBinDirectory, "registry/${name.toLowerCase()}")
+File txmFile = new File(newBinDirectory, "txm/${name}")
+
+File ecFile2 = new File(newBinDirectory, "analec/${new_name}.ec")
+File ecvFile2 = new File(newBinDirectory, "analec/${new_name}.ecv")
+File cssFile2 = new File(newBinDirectory, "css/${new_name}.css")
+File dataFile2 = new File(newBinDirectory, "data/${new_name}")
+File htmlFile2 = new File(newBinDirectory, "HTML/${new_name}")
+File defaultCSSFile2 = new File(newBinDirectory, "HTML/${new_name}/default/css/${new_name}.css")
+File registryFile2 = new File(newBinDirectory, "registry/${new_name.toLowerCase()}")
+File txmFile2 = new File(newBinDirectory, "txm/${new_name}")
+
+println "renaming $ecFile : "+ecFile.renameTo(ecFile2)
+println "renaming $ecvFile : "+ecvFile.renameTo(ecvFile2)
+println "renaming $cssFile : "+cssFile.renameTo(cssFile2)
+println "renaming $dataFile : "+dataFile.renameTo(dataFile2)
+println "renaming $htmlFile : "+htmlFile.renameTo(htmlFile2)
+println "renaming $defaultCSSFile : "+defaultCSSFile.renameTo(defaultCSSFile2)
+println "renaming $registryFile : "+registryFile.renameTo(registryFile2)
+println "renaming $txmFile : "+txmFile.renameTo(txmFile2)
+
+// patch name in settings
+println "replacing old name $name ->  ${new_name} in preferences"
+File settingsDirectory = new File(newBinDirectory, ".settings")
+for (File prefFile : settingsDirectory.listFiles()) {
+	IOUtils.write(prefFile, prefFile.getText().replace(name, new_name))
+}
+
+File projectSetting = new File(newBinDirectory, ".project")
+IOUtils.write(projectSetting, projectSetting.getText().replace(name, new_name))
+
+// patch registry
+String oldcontent = registryFile2.getText();
+content = oldcontent.replace(name, new_name)
+content = content.replace(name.toLowerCase(), new_name.toLowerCase())
+registryFile2.withWriter { writer -> 
+	writer.write(content)
+}
+
+println "creating the TXM file..."
+File zipFile = new File(newBinDirectory.getAbsolutePath()+".txm")
+Zip.compress(newBinDirectory, zipFile, monitor)
+
+if (!zipFile.exists()) {
+	println "Fail to zip binary directory $binDirectory to $zipFile"
+	return
+} else {
+	println "Done: $zipFile"
+}
\ No newline at end of file
Index: tmp/org.txm.analec.rcp/src/org/txm/macro/urs/export/ExportToGlozz1_0_0.groovy
===================================================================
--- tmp/org.txm.analec.rcp/src/org/txm/macro/urs/export/ExportToGlozz1_0_0.groovy	(revision 0)
+++ tmp/org.txm.analec.rcp/src/org/txm/macro/urs/export/ExportToGlozz1_0_0.groovy	(revision 2174)
@@ -0,0 +1,161 @@
+package org.txm.macro.urs.export
+
+// @author: Bruno Oberlé
+// v1.0.0 2017-08-28
+
+/*
+ Cette macro exporte le corpus sélectionné et ses annotations vers deux fichiers de format Glozz:
+ - un fichier .ac contenant le corpus brut,
+ - un fichier .aa contenant les annotations au format XML utilisé par Glozz.
+ Le corpus sélectionné dans TXM devrait contenir une structure Analec avec au moins un type d'unité défini (e.g. MENTION, maillon, etc.). S'il n'y a pas de structure,
+ ce n'est pas grave: le fichier est exporter, mais aucune annotation n'est créer. Cela permet d'exporter n'importe quel corpus au format Glozz.
+ Pour exporter un texte au format Glozz *sans* les annotations qu'il contient, simplement mettre un unit_type qui n'existe pas (e.g. "foobar" au lieu de "MENTION").
+ La macro ne produit pour l'instant pas automatiquement de modèle Glozz (fichier .aam).  Cela n'est pas un problème pour ouvrir le résultat dans Glozz ou Analec.
+ */
+
+// STANDARD DECLARATIONS
+
+import org.apache.commons.lang.*
+import org.kohsuke.args4j.*
+import groovy.transform.*
+import org.txm.*
+import org.txm.rcp.swt.widget.parameters.*
+import org.txm.annotation.urs.*
+import org.txm.searchengine.cqp.*
+import org.txm.searchengine.cqp.corpus.*
+import visuAnalec.Message.*
+import visuAnalec.donnees.*
+import visuAnalec.elements.*
+import visuAnalec.vue.*
+
+// CHECK CORPUS
+
+if (!(corpusViewSelection instanceof MainCorpus)) {
+	println "Corpora selection is not a MainCorpus: "+corpusViewSelection
+	return;
+}
+
+// BEGINNING OF PARAMETERS
+
+@Field @Option(name="unit_type",usage="", widget="String", required=true, def="MENTION")
+		String unit_type
+
+@Field @Option(name="filename",usage="", widget="String", required=true, def="filename without extension (.ac/.aa)")
+		String filename
+
+if (!ParametersDialog.open(this)) return;
+
+// VARIABLES
+
+corpus = corpusViewSelection
+
+doExport(corpus, unit_type, filename)
+
+public void doExport(MainCorpus corpus, String unit_type, String filename) {
+
+	size = corpus.getSize() // you may also use: corpus.getTextEndLimits() (= index of last token = size-1)
+	CQI = CQPSearchEngine.getCqiClient()
+	word = corpus.getWordProperty()
+	// note: using "lbn" seems to work better than "pn" (some imported corpora are missing this information)
+	//pn = corpus.getProperty("pn")
+	//if (pn == null) pn = corpus.getProperty("div")
+	pn = corpus.getProperty("lbn")
+
+	// BUILD THE RAW TEXT, THE POSITIONS AND FIND THE PARAGRAPHS
+
+	rawText = "" // the corpus for the .ac file
+	positions = [] // each element is an array [start, end] indicating the position in the rawText
+	pnCount = 0 // the par counter, used for indexing the pns array
+	lastPn = -1 // the last paragraph number
+	pns = [] // each element is an array [start, end] representing the start and end of the paragraph in the rawText
+	for (def i=0; i<size; i++) {
+		f = CQI.cpos2Str(word.getQualifiedName(), (int[])[i])[0]
+		if (pn == null) {
+			p = 1
+		} else {
+			p = CQI.cpos2Str(pn.getQualifiedName(), (int[])[i])[0]
+		}
+		start = rawText.length()
+		rawText += f
+		if (lastPn != p) {
+			pnCount++;
+			if (pnCount > 1) {
+				pns[pnCount-2][1] = end
+			}
+			pns[pnCount-1] = [start, 0]
+		}
+		lastPn = p
+		end = rawText.length() // must be after setting it up in pns!
+		if (i != size-1) rawText += " "
+		positions[i] = [start, end]
+	}
+	pns[pnCount-1][1] = end
+	println pnCount + " paragraph(s) found."
+
+
+
+	// CORPUS ANALEC (GET THE ANNOTATIONS)
+
+	// note that unit_type has been defined with an option of the dialog at the beginning
+	def analecCorpus = URSCorpora.getCorpus(corpus);
+
+	// list of properties
+
+	struct = analecCorpus.getStructure();
+	propertyList = struct.getUniteProperties(unit_type);
+
+	// export to file (corpus)
+
+	corpusFilename = filename + ".ac";
+	def corpusFile = new File(corpusFilename);
+	corpusFile.write(rawText)
+	println("Corpus written to `"+corpusFilename+"'.");
+
+	// export to file (annotations)
+
+	annotFilename = filename + ".aa";
+	def annotFile = new File(annotFilename)
+	annotFile.write("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<annotations>\n")
+		// erase (if you use << you don't erase!)
+	def counter = 0
+
+	// export paragraphs
+	for (def i=0; i<pns.size(); i++) {
+		def start = pns[i][0]
+		def end = pns[i][1]
+		annotFile << "<unit id=\"me_"+counter+"\">\n";
+		annotFile << "<metadata><author>me</author><creation-date>"+counter+"</creation-date></metadata>\n";
+		annotFile << "<characterisation><type>paragraph</type><featureSet /></characterisation>\n";
+		annotFile << "<positioning><start><singlePosition index=\""+start+"\" /></start><end><singlePosition index=\""+end+"\" /></end></positioning>\n";
+		annotFile << "</unit>\n";
+		counter++;
+	}
+
+	// export units
+	def units = analecCorpus.getUnites(unit_type);
+	//units.sort() { a, b -> a.getDeb() <=> b.getDeb() ?: a.getFin() <=> b.getFin() };
+	def unitCount = 0
+	for (Unite unit : units) {
+		unitCount++;
+		annotFile << "<unit id=\"me_"+counter+"\">\n";
+		annotFile << "<metadata><author>me</author><creation-date>"+counter+"</creation-date></metadata>\n";
+		annotFile << "<characterisation>\n";
+		annotFile << "<type>"+unit_type+"</type>\n";
+		annotFile << "<featureSet>\n";
+		for (String propertyName : propertyList) {
+			annotFile << "<feature name=\""+propertyName+"\">"+unit.getProp(propertyName)+"</feature>\n";
+		}
+		annotFile << "</featureSet>\n";
+		annotFile << "</characterisation>\n";
+		start = positions[unit.getDeb()][0]
+		end = positions[unit.getFin()][1]
+		annotFile << "<positioning><start><singlePosition index=\""+start+"\" /></start><end><singlePosition index=\""+end+"\" /></end></positioning>\n";
+		annotFile << "</unit>\n";
+		counter++;
+	}
+	annotFile << "</annotations>\n";
+
+	println unitCount + " unit(s) found."
+
+	println("Annotations written to `"+annotFilename+"'.");
+}
\ No newline at end of file
Index: tmp/org.txm.analec.rcp/src/org/txm/macro/urs/export/ExportToGlozz1_1_0.groovy
===================================================================
--- tmp/org.txm.analec.rcp/src/org/txm/macro/urs/export/ExportToGlozz1_1_0.groovy	(revision 0)
+++ tmp/org.txm.analec.rcp/src/org/txm/macro/urs/export/ExportToGlozz1_1_0.groovy	(revision 2174)
@@ -0,0 +1,200 @@
+package org.txm.macro.urs.export
+
+// @author: Bruno Oberle
+// v1.1.0 2017-10-25:
+//  - using the "p" structural unit if available to get paragraphs
+//  - no space before comma, parenthesis, full stop, hyphen, etc.
+//  - no space after hyphen, parenthesis, apostrophe, etc.
+// v1.0.0 2017-08-28
+
+/*
+ Cette macro exporte le corpus sélectionné et ses annotations vers deux fichiers de format Glozz:
+ - un fichier .ac contenant le corpus brut,
+ - un fichier .aa contenant les annotations au format XML utilisé par Glozz.
+ Le corpus sélectionné dans TXM devrait contenir une structure Analec avec au moins un type d'unité défini (e.g. MENTION, maillon, etc.). S'il n'y a pas de structure,
+ ce n'est pas grave: le fichier est exporter, mais aucune annotation n'est créer. Cela permet d'exporter n'importe quel corpus au format Glozz.
+ Pour exporter un texte au format Glozz *sans* les annotations qu'il contient, simplement mettre un unit_type qui n'existe pas (e.g. "foobar" au lieu de "MENTION").
+ La macro ne produit pour l'instant pas automatiquement de modèle Glozz (fichier .aam).  Cela n'est pas un problème pour ouvrir le résultat dans Glozz ou Analec.
+ */
+
+// STANDARD DECLARATIONS
+
+import org.apache.commons.lang.*
+import org.kohsuke.args4j.*
+import groovy.transform.*
+import org.txm.*
+import org.txm.rcp.swt.widget.parameters.*
+import org.txm.annotation.urs.*
+import org.txm.searchengine.cqp.*
+import org.txm.searchengine.cqp.corpus.*
+import visuAnalec.Message.*
+import visuAnalec.donnees.*
+import visuAnalec.elements.*
+import visuAnalec.vue.*
+
+
+// GLOBAL VARIABLES
+
+corpus = corpusViewSelection
+CQI = CQPSearchEngine.getCqiClient()
+
+// CHECK CORPUS
+
+if (!(corpusViewSelection instanceof MainCorpus)) {
+	println "Corpora selection is not a MainCorpus: "+corpusViewSelection
+	return;
+}
+
+// PARAGRAPH AS STRUCTURAL UNIT?
+
+/* note: some text have a structural unit called "p", which represents a paragraph.
+   If this structural unit is present, we use it.  Otherwise we ask the user (the
+   best way is to use the "pn" (paragraph number) or "lbn" (line number) property),
+   depending on what is available in the corpus. If the user give not property name,
+   we only define one paragraph for the whole text. */
+
+parUnit = corpus.getStructuralUnit("p")
+
+// BEGINNING OF PARAMETERS
+
+@Field @Option(name="unit_type",usage="", widget="String", required=true, def="MENTION")
+		String unit_type
+
+@Field @Option(name="filename",usage="", widget="String", required=true, def="filename without extension (.ac/.aa)")
+		String filename
+
+if (!parUnit) {
+	@Field @Option(name="par_prop",usage="the property used to compute paragraphs", widget="String", required=false, def="lbn")
+		String par_prop
+}
+
+if (!ParametersDialog.open(this)) return;
+
+// what paragraph unit to use?
+
+pn = null
+if (!parUnit && !par_prop.equals("")) {
+	pn = corpus.getProperty(par_prop)
+	if (!pn) {
+		println "Error: I can't find a the property `$par_prop'."
+		return
+	}
+}
+
+/*********************************/
+
+doExport(corpus, unit_type, filename)
+
+public void doExport(MainCorpus corpus, String unit_type, String filename) {
+
+	size = corpus.getSize() // you may also use: corpus.getTextEndLimits() (= index of last token = size-1)
+	word = corpus.getWordProperty()
+
+	// BUILD THE RAW TEXT, THE POSITIONS AND FIND THE PARAGRAPHS
+
+	rawText = "" // the corpus for the .ac file
+	positions = [] // each element is an array [start, end] indicating the position in the rawText
+	pnCount = 0 // the par counter, used for indexing the pars array
+	lastPn = -1 // the last paragraph number
+	pars = [] // each element is an array [start, end] representing the start and end of the paragraph in the rawText
+	insertSpace = true
+	for (def i=0; i<size; i++) {
+		f = CQI.cpos2Str(word.getQualifiedName(), (int[])[i])[0]
+		if (parUnit) {
+			p = CQI.cpos2Struc(parUnit.getQualifiedName(), (int[])[i])[0]
+		} else if (pn == null) {
+			p = 1
+		} else {
+			p = CQI.cpos2Str(pn.getQualifiedName(), (int[])[i])[0]
+		}
+		if (i > 0 && insertSpace
+				&& !f.equals(".") && !f.equals(",") && !f.equals("'") && !f.equals("’") && !f.equals("-")
+				&& !f.equals(")") && !f.equals("]") && !f.startsWith("-")) {
+			rawText += " "
+		}
+		insertSpace = true // reset
+		if (f.equals("-") || f.equals("[") || f.equals("(")
+				|| f.endsWith("-") || f.endsWith("'") || f.endsWith("’") || f.endsWith("-")) {
+			insertSpace = false
+		}
+		start = rawText.length()
+		rawText += f
+		if (lastPn != p) {
+			pnCount++;
+			if (pnCount > 1) {
+				pars[pnCount-2][1] = end
+			}
+			pars[pnCount-1] = [start, 0]
+		}
+		lastPn = p
+		end = rawText.length() // must be after setting it up in pars!
+		positions[i] = [start, end]
+	}
+	pars[pnCount-1][1] = end
+	println pnCount + " paragraph(s) found."
+
+	// CORPUS ANALEC (GET THE ANNOTATIONS)
+
+	// note that unit_type has been defined with an option of the dialog at the beginning
+	def analecCorpus = URSCorpora.getCorpus(corpus);
+
+	// list of properties
+
+	struct = analecCorpus.getStructure();
+	propertyList = struct.getUniteProperties(unit_type);
+
+	// export to file (corpus)
+
+	corpusFilename = filename + ".ac";
+	def corpusFile = new File(corpusFilename);
+	corpusFile.write(rawText)
+	println("Corpus written to `"+corpusFilename+"'.");
+
+	// export to file (annotations)
+
+	annotFilename = filename + ".aa";
+	def annotFile = new File(annotFilename)
+	annotFile.write("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<annotations>\n")
+		// erase (if you use << you don't erase!)
+	def counter = 0
+
+	// export paragraphs
+	for (def i=0; i<pars.size(); i++) {
+		def start = pars[i][0]
+		def end = pars[i][1]
+		annotFile << "<unit id=\"me_"+counter+"\">\n";
+		annotFile << "<metadata><author>me</author><creation-date>"+counter+"</creation-date></metadata>\n";
+		annotFile << "<characterisation><type>paragraph</type><featureSet /></characterisation>\n";
+		annotFile << "<positioning><start><singlePosition index=\""+start+"\" /></start><end><singlePosition index=\""+end+"\" /></end></positioning>\n";
+		annotFile << "</unit>\n";
+		counter++;
+	}
+
+	// export units
+	def units = analecCorpus.getUnites(unit_type);
+	//units.sort() { a, b -> a.getDeb() <=> b.getDeb() ?: a.getFin() <=> b.getFin() };
+	def unitCount = 0
+	for (Unite unit : units) {
+		unitCount++;
+		annotFile << "<unit id=\"me_"+counter+"\">\n";
+		annotFile << "<metadata><author>me</author><creation-date>"+counter+"</creation-date></metadata>\n";
+		annotFile << "<characterisation>\n";
+		annotFile << "<type>"+unit_type+"</type>\n";
+		annotFile << "<featureSet>\n";
+		for (String propertyName : propertyList) {
+			annotFile << "<feature name=\""+propertyName+"\">"+unit.getProp(propertyName)+"</feature>\n";
+		}
+		annotFile << "</featureSet>\n";
+		annotFile << "</characterisation>\n";
+		start = positions[unit.getDeb()][0]
+		end = positions[unit.getFin()][1]
+		annotFile << "<positioning><start><singlePosition index=\""+start+"\" /></start><end><singlePosition index=\""+end+"\" /></end></positioning>\n";
+		annotFile << "</unit>\n";
+		counter++;
+	}
+	annotFile << "</annotations>\n";
+
+	println unitCount + " unit(s) found."
+
+	println("Annotations written to `"+annotFilename+"'.");
+}
Index: tmp/org.txm.analec.rcp/src/org/txm/macro/urs/export/ExportUnitsToGlozz.groovy
===================================================================
--- tmp/org.txm.analec.rcp/src/org/txm/macro/urs/export/ExportUnitsToGlozz.groovy	(revision 0)
+++ tmp/org.txm.analec.rcp/src/org/txm/macro/urs/export/ExportUnitsToGlozz.groovy	(revision 2174)
@@ -0,0 +1,160 @@
+package org.txm.macro.urs.export
+
+// @author: Bruno Oberlé
+// v1.0.0 2017-08-28
+
+/*
+ Cette macro exporte le corpus sélectionné et ses annotations vers deux fichiers de format Glozz:
+ - un fichier .ac contenant le corpus brut,
+ - un fichier .aa contenant les annotations au format XML utilisé par Glozz.
+ Le corpus sélectionné dans TXM devrait contenir une structure Analec avec au moins un type d'unité défini (e.g. MENTION, maillon, etc.). S'il n'y a pas de structure,
+ ce n'est pas grave: le fichier est exporter, mais aucune annotation n'est créer. Cela permet d'exporter n'importe quel corpus au format Glozz.
+ Pour exporter un texte au format Glozz *sans* les annotations qu'il contient, simplement mettre un unit_type qui n'existe pas (e.g. "foobar" au lieu de "MENTION").
+ La macro ne produit pour l'instant pas automatiquement de modèle Glozz (fichier .aam).  Cela n'est pas un problème pour ouvrir le résultat dans Glozz ou Analec.
+ */
+
+// STANDARD DECLARATIONS
+
+import org.apache.commons.lang.*
+import org.kohsuke.args4j.*
+import groovy.transform.*
+import org.txm.*
+import org.txm.rcp.swt.widget.parameters.*
+import org.txm.annotation.urs.*
+import org.txm.searchengine.cqp.*
+import org.txm.searchengine.cqp.corpus.*
+import visuAnalec.Message.*
+import visuAnalec.donnees.*
+import visuAnalec.elements.*
+import visuAnalec.vue.*
+
+// CHECK CORPUS
+
+if (!(corpusViewSelection instanceof MainCorpus)) {
+	println "Corpora selection is not a MainCorpus: "+corpusViewSelection
+	return;
+}
+
+// BEGINNING OF PARAMETERS
+
+@Field @Option(name="unit_type",usage="", widget="String", required=true, def="MENTION")
+		String unit_type
+
+@Field @Option(name="filename",usage="", widget="String", required=true, def="filename without extension (.ac/.aa)")
+		String filename
+
+if (!ParametersDialog.open(this)) return;
+
+// VARIABLES
+
+corpus = corpusViewSelection
+
+doExport(corpus, unit_type, filename)
+
+public void doExport(MainCorpus corpus, String unit_type, String filename) {
+
+	size = corpus.getSize() // you may also use: corpus.getTextEndLimits() (= index of last token = size-1)
+	CQI = CQPSearchEngine.getCqiClient()
+	word = corpus.getWordProperty()
+	// note: using "lbn" seems to work better than "pn" (some imported corpora are missing this information)
+	//pn = corpus.getProperty("pn")
+	//if (pn == null) pn = corpus.getProperty("div")
+	pn = corpus.getProperty("lbn")
+
+	// BUILD THE RAW TEXT, THE POSITIONS AND FIND THE PARAGRAPHS
+
+	rawText = "" // the corpus for the .ac file
+	positions = [] // each element is an array [start, end] indicating the position in the rawText
+	pnCount = 0 // the par counter, used for indexing the pns array
+	lastPn = -1 // the last paragraph number
+	pns = [] // each element is an array [start, end] representing the start and end of the paragraph in the rawText
+	for (def i=0; i<size; i++) {
+		f = CQI.cpos2Str(word.getQualifiedName(), (int[])[i])[0]
+		if (pn == null) {
+			p = 1
+		} else {
+			p = CQI.cpos2Str(pn.getQualifiedName(), (int[])[i])[0]
+		}
+		start = rawText.length()
+		rawText += f
+		if (lastPn != p) {
+			pnCount++;
+			if (pnCount > 1) {
+				pns[pnCount-2][1] = end
+			}
+			pns[pnCount-1] = [start, 0]
+		}
+		lastPn = p
+		end = rawText.length() // must be after setting it up in pns!
+		if (i != size-1) rawText += " "
+		positions[i] = [start, end]
+	}
+	pns[pnCount-1][1] = end
+	println pnCount + " paragraph(s) found."
+
+
+
+	// CORPUS ANALEC (GET THE ANNOTATIONS)
+
+	// note that unit_type has been defined with an option of the dialog at the beginning
+	def analecCorpus = URSCorpora.getCorpus(corpus);
+
+	// list of properties
+
+	struct = analecCorpus.getStructure();
+	propertyList = struct.getUniteProperties(unit_type);
+
+	// export to file (corpus)
+
+	corpusFilename = filename + ".ac";
+	def corpusFile = new File(corpusFilename);
+	corpusFile.write(rawText)
+	println("Corpus written to `"+corpusFilename+"'.");
+
+	// export to file (annotations)
+
+	annotFilename = filename + ".aa";
+	def annotFile = new File(annotFilename)
+	annotFile.write("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<annotations>\n") // erase
+	def counter = 0
+
+	// export paragraphs
+	for (def i=0; i<pns.size(); i++) {
+		def start = pns[i][0]
+		def end = pns[i][1]
+		annotFile << "<unit id=\"me_"+counter+"\">\n";
+		annotFile << "<metadata><author>me</author><creation-date>"+counter+"</creation-date></metadata>\n";
+		annotFile << "<characterisation><type>paragraph</type><featureSet /></characterisation>\n";
+		annotFile << "<positioning><start><singlePosition index=\""+start+"\" /></start><end><singlePosition index=\""+end+"\" /></end></positioning>\n";
+		annotFile << "</unit>\n";
+		counter++;
+	}
+
+	// export units
+	def units = analecCorpus.getUnites(unit_type);
+	//units.sort() { a, b -> a.getDeb() <=> b.getDeb() ?: a.getFin() <=> b.getFin() };
+	def unitCount = 0
+	for (Unite unit : units) {
+		unitCount++;
+		annotFile << "<unit id=\"me_"+counter+"\">\n";
+		annotFile << "<metadata><author>me</author><creation-date>"+counter+"</creation-date></metadata>\n";
+		annotFile << "<characterisation>\n";
+		annotFile << "<type>"+unit_type+"</type>\n";
+		annotFile << "<featureSet>\n";
+		for (String propertyName : propertyList) {
+			annotFile << "<feature name=\""+propertyName+"\">"+unit.getProp(propertyName)+"</feature>\n";
+		}
+		annotFile << "</featureSet>\n";
+		annotFile << "</characterisation>\n";
+		start = positions[unit.getDeb()][0]
+		end = positions[unit.getFin()][1]
+		annotFile << "<positioning><start><singlePosition index=\""+start+"\" /></start><end><singlePosition index=\""+end+"\" /></end></positioning>\n";
+		annotFile << "</unit>\n";
+		counter++;
+	}
+	annotFile << "</annotations>\n";
+
+	println unitCount + " unit(s) found."
+
+	println("Annotations written to `"+annotFilename+"'.");
+}
\ No newline at end of file
Index: tmp/org.txm.analec.rcp/src/org/txm/macro/urs/URSDemo.groovy
===================================================================
--- tmp/org.txm.analec.rcp/src/org/txm/macro/urs/URSDemo.groovy	(revision 0)
+++ tmp/org.txm.analec.rcp/src/org/txm/macro/urs/URSDemo.groovy	(revision 2174)
@@ -0,0 +1,173 @@
+package org.txm.macro.urs
+
+import org.txm.annotation.urs.URSCorpora
+import org.txm.searchengine.cqp.corpus.CQPCorpus
+import visuAnalec.elements.*
+
+// get the CQP corpus
+if (!(corpusViewSelection instanceof CQPCorpus)) {
+	println "Corpus view selection is no a corpus: $corpusViewSelection"
+	return false;
+}
+def corpus = corpusViewSelection
+
+// get the Analec corpus : stores the annotations and annotation structure
+
+def analecCorpus = URSCorpora.getCorpus(corpus)
+
+// get the annotations structure : stores the available annotation types, properties and values
+
+def structure = analecCorpus.getStructure()
+
+// get the annotations view : stores annotations and annotation structure display rules
+
+def view = URSCorpora.getVue(corpus)
+
+// set a default vue -> all is visible
+view.retablirVueParDefaut()
+
+// list the viewed types and properties
+for (def type : view.getTypesAVoir(Unite.class)) {
+	println "$type: "+view.getNomsChamps(Unite.class, type)
+}
+
+// manage the viewed&enabled type, properties ; the types and properties must be enabled to use the "view.setValeurChamp(TYPE, PROPERTY, VALUE)" method
+view.ajouterType(Unite.class, "EXEMPLE")
+view.ajouterProp(Unite.class, "EXEMPLE", "PEXEMPLE")
+
+// display annotations per Element type (Unite, Relation, Schema) and per type
+
+// Create annotation type
+
+structure.ajouterType(Unite.class, "EXEMPLE");
+//structure.ajouterType(Relation.class, "EXEMPLE");
+//structure.ajouterType(Schema.class, "EXEMPLE");
+println structure.getTypes(Unite.class)
+
+// Create annotation property
+
+structure.ajouterProp(Unite.class, "EXEMPLE", "PEXEMPLE")
+println structure.getNomsProps(Unite.class, "EXEMPLE")
+
+// Create annotation value
+
+structure.ajouterVal(Unite.class, "EXEMPLE", "PEXEMPLE", "oui")
+structure.ajouterVal(Unite.class, "EXEMPLE", "PEXEMPLE", "non")
+
+// Create annotations
+
+// Unite
+def u = analecCorpus.addUniteSaisie("EXEMPLE", 0, 10, ["PEXEMPLE":"oui"])
+def u2 = analecCorpus.addUniteSaisie("EXEMPLE", 12, 12, ["PEXEMPLE":"oui"])
+println u
+
+// Edit annotations
+
+u.getProps()["PEXEMPLE"] = "non"
+
+// Unit getters
+
+println u.getDeb() // start of unit
+println u.getFin() // end of unit
+
+println u.getProp("EXEMPLE")
+println u.getType()
+
+// Relation
+Relation relation = new Relation("REXEMPLE", u, u2)
+relation.getProps().put("PEXEMPLE", "oui")
+analecCorpus.addRelationLue(relation)  // add the new relation
+
+// Schema
+Schema schema = new Schema()
+schema.type = "SEXEMPLE"
+schema.props.put("PEXEMPLE", "oui")
+schema.ajouter(u) // insert one unit
+
+analecCorpus.addSchemaLu(schema)  // add the new schema
+
+// Browse Units
+
+println "Units:"
+for (String type : structure.getUnites()) {
+	def units = analecCorpus.getUnites(type)
+	if (units.size() > 0) {
+		println "	${units.size()} $type"
+	}
+}
+
+// Browse Relations
+
+println "Relations:"
+for (String type : structure.getRelations()) {
+	def relations = analecCorpus.getRelations(type)
+	if (relations.size() > 0) {
+		println "	${relations.size()} $type"
+	}
+}
+
+// Browse Schemas
+
+println "Schemas:"
+for (String type : structure.getSchemas()) {
+	def schemas = analecCorpus.getSchemas(type)
+	if (schemas.size() > 0) {
+		println "	${schemas.size()} $type"
+	}
+}
+
+// URS selections
+
+// select Schemas
+def debug = 0 // 1 2 for more logs
+def strict_inclusion = true
+def position = 0
+def minimum_schema_size = 1;
+def maximum_schema_size = 10;
+def schema_ursql = "SEXEMPLE"
+def unit_ursql = "EXEMPLE@PEXEMPLE=oui"
+def unit_type = "EXEMPLE" 
+println AnalecUtils.selectSchemasInCorpus(debug, analecCorpus, corpus, schema_ursql, minimum_schema_size, maximum_schema_size, strict_inclusion)
+
+
+// with URSQL
+println AnalecUtils.filterElements(debug, analecCorpus.getUnites(unit_type), unit_ursql)
+
+// with intersection with CQP corpus matches
+println AnalecUtils.filterUniteByInclusion(debug, analecCorpus.getUnites(unit_type), corpus.getMatches(), strict_inclusion, position)
+
+// by size
+println AnalecUtils.filterBySize(analecCorpus.getSchemas(schema_ursql), minimum_schema_size, maximum_schema_size)
+
+// Delete annotations
+
+analecCorpus.supUnite(u)
+analecCorpus.supUnite(u2)
+analecCorpus.supRelation(relation)
+analecCorpus.supSchema(schema)
+
+// Delete annotation value
+
+structure.supprimerVal(Unite.class, "EXEMPLE", "PEXEMPLE", "oui")
+structure.supprimerVal(Unite.class, "EXEMPLE", "PEXEMPLE", "non")
+
+// Delete annotation property
+
+structure.supprimerProp(Unite.class, "EXEMPLE", "PEXEMPLE")
+structure.supprimerProp(Relation.class, "REXEMPLE", "PEXEMPLE")
+structure.supprimerProp(Schema.class, "SEXEMPLE", "PEXEMPLE")
+
+// Delete annotation type
+
+structure.supprimerType(Unite.class, "EXEMPLE");
+structure.supprimerType(Relation.class, "REXEMPLE");
+structure.supprimerType(Schema.class, "SEXEMPLE");
+
+// Revert changes
+
+//URSCorpora.revert(corpus);
+
+// Save changes
+
+//URSCorpora.saveCorpus(corpus)
+
Index: tmp/org.txm.analec.rcp/src/org/txm/macro/urs/exploit/UnitsIndexMacro.groovy
===================================================================
--- tmp/org.txm.analec.rcp/src/org/txm/macro/urs/exploit/UnitsIndexMacro.groovy	(revision 2173)
+++ tmp/org.txm.analec.rcp/src/org/txm/macro/urs/exploit/UnitsIndexMacro.groovy	(revision 2174)
@@ -163,7 +163,7 @@
 if (corpusViewSelection instanceof Partition) { corpus = corpusViewSelection.getCorpus() }
 else { corpus = corpusViewSelection }
 
-def title = "${corpus.getMainCorpus()}.${corpusViewSelection}\n${unit_ursql}"
+def title = "${corpus.getMainCorpus()}.${corpusViewSelection} ${unit_ursql}"
 title += "[${position_in_matches}]."
 if (word_property_display.length() > 0) title += "${word_property_display} frequencies"
 else if (unit_property_display.length() > 0) title += "${unit_property_display} frequencies"
@@ -195,44 +195,43 @@
 }
 props = keys
 
-def r = RWorkspace.getRWorkspaceInstance()
-def colnames = selection as String[]
-r.addVectorToWorkspace("texts", colnames)
-def rownames = props as String[]
-r.addVectorToWorkspace("props", rownames)
-r.addMatrixToWorkspace("textpropfreqs", matrix as DoubleMatrix2D)
-r.eval("rownames(textpropfreqs) = props")
-r.eval("colnames(textpropfreqs) = texts")
 
+
 def resultsDir = new File(Toolbox.getTxmHomePath(), "results")
 def file = File.createTempFile("txm", ".svg", resultsDir)
 
 
 //if (corpusViewSelection.getClass() == org.txm.searchengine.cqp.corpus.Partition) { corpus = corpusViewSelection.getParent() } else { corpus = corpusViewSelection }
 if (output_histogram) {
+	
+	def r = RWorkspace.getRWorkspaceInstance()
+	def colnames = selection as String[]
+	r.addVectorToWorkspace("texts", colnames)
+	def rownames = props as String[]
+	r.addVectorToWorkspace("props", rownames)
+	r.addMatrixToWorkspace("textpropfreqs", matrix as DoubleMatrix2D)
+	r.eval("rownames(textpropfreqs) = props")
+	r.eval("colnames(textpropfreqs) = texts")
+	
 	def plotScript
 	String legend = "rownames(textpropfreqs)"
 	if (!output_showlegend) legend = "NULL"
 
 	if (output_2D) {
-		plotScript = """library(RColorBrewer);
-barplot(height=textpropfreqs, main="${title}", xlab="Parties", legend=$legend, beside=TRUE, col=rainbow(length(rownames(textpropfreqs))))"""
+		plotScript = """rez <- barplot(height=textpropfreqs, main="${title}", xlab="Parties", legend=${legend}, beside=TRUE, col=rainbow(length(rownames(textpropfreqs))))"""
 	} else {
 		plotScript = """
 		   library(latticeExtra)
 		   library(lattice)
-		   library(RColorBrewer)
 		   cloud(value~col+row, ..., panel.3d.cloud=panel.3dbars, col.facet='grey', xbase=0.4, ybase=0.4, scales=list(arrows=FALSE, col=1), par.settings = list(axis.line = list(col = "transparent")))
 		   """
 	}
 
 	// execute R script
+	r.eval("library(RColorBrewer);")
 	r.plot(file, plotScript)
-
-	//println "s1: "+r.eval("s1").asString()
-
-	//display the SVG results graphic
 	
+	//display the SVG results graphic	
 }
 
 def lt = null;
Index: tmp/org.txm.analec.rcp/src/org/txm/macro/urs/exploit/SchemasProgressionMacro.groovy
===================================================================
--- tmp/org.txm.analec.rcp/src/org/txm/macro/urs/exploit/SchemasProgressionMacro.groovy	(revision 2173)
+++ tmp/org.txm.analec.rcp/src/org/txm/macro/urs/exploit/SchemasProgressionMacro.groovy	(revision 2174)
@@ -202,6 +202,11 @@
 			struct_p = struct.getProperty(struct_prop)
 		}
 		
+		def testSet = new HashSet(queries)
+		if (testSet.size() != queries.size()) {
+			println "Warning: can't draw Progression with duplicate names: $queries"
+			continue
+		}
 		Progression progression = new Progression(corpus);
 		progression.setParameters(queries,
 				struct, struct_p,	".*",
Index: tmp/org.txm.analec.rcp/src/org/txm/macro/urs/exploit/SchemasCoverageMacro.groovy
===================================================================
--- tmp/org.txm.analec.rcp/src/org/txm/macro/urs/exploit/SchemasCoverageMacro.groovy	(revision 2173)
+++ tmp/org.txm.analec.rcp/src/org/txm/macro/urs/exploit/SchemasCoverageMacro.groovy	(revision 2174)
@@ -56,7 +56,7 @@
 @Field @Option(name="structure_properties", usage="name_prpperty,name2_property2,name3_property", widget="String", required=true, def="div_n,p_n")
 		String structure_properties
 @Field @Option(name="write_properties_values", usage="name_prpperty,name2_property2,name3_property", widget="Boolean", required=true, def="false")
-		String write_properties_values
+		Boolean write_properties_values
 @Field @Option(name="debug", usage="Show internal variable content", widget="StringArray", metaVar="OFF	ON	ALL	REALLY ALL", required=true, def="OFF")
 		debug
 if (!ParametersDialog.open(this)) return
@@ -135,7 +135,7 @@
 	}
 	if (debug) println "allHighlightedUnits=${allHighlightedUnits.size()}"
 
-	println "annotating ${allSchemas.size()} schemas..." 
+	def selectedSchemas = []
 	for (Schema schema : allSchemas) {
 		if (debug) println "	schema="+schema.getProps()
 		def selectedUnits = allHighlightedUnits[schema]
@@ -150,8 +150,26 @@
 			if (debug) println schema.getProp(schema_property_display)+" -> N/A"
 			continue; // no need to go further, process next selected eleemnt of corpora view
 		}
+		selectedSchemas << schema
+	}
+	
+	println "annotating ${selectedSchemas.size()} schemas..." 
+	for (Schema schema : selectedSchemas) {
+		if (debug) println "	schema="+schema.getProps()
+		def selectedUnits = allHighlightedUnits[schema]
 
+		if (selectedUnits.size() == 0) continue;
+		selectedUnits = AnalecUtils.filterUniteByInclusion(debug, selectedUnits, corpus.getMatches(), strict_inclusion, 0)
 
+		if (selectedUnits.size() == 0) continue;
+
+		if (selectedUnits.size() < minimum_schema_size) {
+			schema.getProps()["LOCALISATION"] = "N/A"
+			if (debug) println schema.getProp(schema_property_display)+" -> N/A"
+			continue; // no need to go further, process next selected eleemnt of corpora view
+		}
+
+
 		if (debug) println "		selectedUnits=${selectedUnits.size()}"
 
 		// get all positions for the selected units
Index: tmp/org.txm.analec.rcp/src/org/txm/macro/urs/edit/ResetAllAnnotationsMacro.groovy
===================================================================
--- tmp/org.txm.analec.rcp/src/org/txm/macro/urs/edit/ResetAllAnnotationsMacro.groovy	(revision 2173)
+++ tmp/org.txm.analec.rcp/src/org/txm/macro/urs/edit/ResetAllAnnotationsMacro.groovy	(revision 2174)
@@ -19,6 +19,11 @@
 // Open the parameters input dialog box
 if (!ParametersDialog.open(this)) return;
 
+if (!CONFIRMATION) {
+	println "Aborting: CONFIRMATION was no checked."
+	return;
+}
+
 def corpus = corpusViewSelection
 def analecCorpus = URSCorpora.getCorpus(corpus);
 def structure = analecCorpus.getStructure()
Index: tmp/org.txm.analec.rcp/src/org/txm/macro/urs/AnalecUtils.groovy
===================================================================
--- tmp/org.txm.analec.rcp/src/org/txm/macro/urs/AnalecUtils.groovy	(revision 2173)
+++ tmp/org.txm.analec.rcp/src/org/txm/macro/urs/AnalecUtils.groovy	(revision 2174)
@@ -160,7 +160,6 @@
  * @return
  */
 static def filterUniteByInclusionInSchema(def debug, def groups, Integer distance) {
-	println "dist=$distance"
 	if (distance == 0) return groups;
 	if (distance > 0) distance = distance-1;
 	def newGroups = [:]
@@ -374,7 +373,7 @@
  * @return
  */
 static def groupAllUnitesInElements(def debug, def elements) {
-	return groupAllUnitesInElements(debug, elements, "","","")
+	return groupAllUnitesInElements(debug, elements, "","",true, "")
 }
 
 /**
Index: tmp/org.txm.analec.rcp/src/org/txm/macro/urs/democrat/SUJ-PARTINFMacro.groovy
===================================================================
--- tmp/org.txm.analec.rcp/src/org/txm/macro/urs/democrat/SUJ-PARTINFMacro.groovy	(revision 2173)
+++ tmp/org.txm.analec.rcp/src/org/txm/macro/urs/democrat/SUJ-PARTINFMacro.groovy	(revision 2174)
@@ -43,7 +43,7 @@
 if (!ParametersDialog.open(this)) return
 
 corpus = corpusViewSelection
-CQI = Toolbox.getCqiClient()
+CQI = CQPSearchEngine.getCqiClient()
 word = corpus.getWordProperty()
 posProperty = corpus.getProperty(pos_property_name)
 if (posProperty == null) {
Index: tmp/org.txm.analec.rcp/src/org/txm/macro/urs/democrat/VerificationsMacro.groovy
===================================================================
--- tmp/org.txm.analec.rcp/src/org/txm/macro/urs/democrat/VerificationsMacro.groovy	(revision 2173)
+++ tmp/org.txm.analec.rcp/src/org/txm/macro/urs/democrat/VerificationsMacro.groovy	(revision 2174)
@@ -18,8 +18,10 @@
 import org.kohsuke.args4j.*
 import groovy.transform.*
 import org.txm.*
+
 import org.txm.rcpapplication.swt.widget.parameters.*
-import org.txm.analec.*
+import org.txm.urs.*
+import org.txm.annotation.urs.*
 import org.txm.searchengine.cqp.*
 import org.txm.searchengine.cqp.corpus.*
 import visuAnalec.Message.*
@@ -57,7 +59,7 @@
 if (!ParametersDialog.open(this)) return
 
 corpus = corpusViewSelection
-CQI = Toolbox.getCqiClient()
+CQI = CQPSearchEngine.getCqiClient()
 word = corpus.getWordProperty()
 posProperty = corpus.getProperty(pos_property_name)
 if (posProperty == null) {
Index: tmp/org.txm.analec.rcp/src/org/txm/macro/urs/democrat/CreationAnaphoresMacro.groovy
===================================================================
--- tmp/org.txm.analec.rcp/src/org/txm/macro/urs/democrat/CreationAnaphoresMacro.groovy	(revision 2173)
+++ tmp/org.txm.analec.rcp/src/org/txm/macro/urs/democrat/CreationAnaphoresMacro.groovy	(revision 2174)
@@ -70,7 +70,7 @@
 	units.sort() { a, b -> a.getDeb() <=> b.getDeb() ?: a.getFin() <=> b.getFin() } // sort them
 	
 	for (int i = 0 ; i < units.size() - 1 ; i++) { // build RELATIONS and don't process the last unit
-		println "creating "+units[i+1]+", "+units[i]
+		println "creating relation with "+units[i+1].getProps()+", "+units[i].getProps()
 		Relation relation = new Relation("ANAPHORE", units[i+1], units[i])
 		relation.getProps().put("TYPE", "COREFERENTE")
 		analecCorpus.addRelationLue(relation)  // add the new relation
Index: tmp/org.txm.analec.rcp/src/org/txm/macro/urs/democrat/LongueurDesMentionsMacro.groovy
===================================================================
--- tmp/org.txm.analec.rcp/src/org/txm/macro/urs/democrat/LongueurDesMentionsMacro.groovy	(revision 2173)
+++ tmp/org.txm.analec.rcp/src/org/txm/macro/urs/democrat/LongueurDesMentionsMacro.groovy	(revision 2174)
@@ -107,12 +107,12 @@
 	def prop = unit.getProp(LONGUEUR)
 	if (!reset && prop != null && prop.length() > 0) continue // l'unité a déjà une LONGUEUR
 
-		int[] positions = null
+	int[] positions = null
 	if (unit.getDeb() == unit.getFin()) positions = [unit.getDeb()]
 	else positions = (unit.getDeb()..unit.getFin())
 
-	def Mention = CQI.cpos2Str(posProperty.getQualifiedName(), positions)
-	def cat = testRules(positions, Mention)
+	//def Mention = CQI.cpos2Str(posProperty.getQualifiedName(), positions)
+	def cat = testRules(positions, positions)
 
 	if (cat != null) {
 		vue.setValeurChamp(unit, LONGUEUR, cat)
Index: tmp/org.txm.analec.rcp/src/org/txm/macro/urs/democrat/Si2SingletonMacro.groovy
===================================================================
--- tmp/org.txm.analec.rcp/src/org/txm/macro/urs/democrat/Si2SingletonMacro.groovy	(revision 2173)
+++ tmp/org.txm.analec.rcp/src/org/txm/macro/urs/democrat/Si2SingletonMacro.groovy	(revision 2174)
@@ -26,10 +26,10 @@
 }
 
 // BEGINNING OF PARAMETERS
-@Field @Option(name="unitType", usage="", widget="String", required=true, def="MENTION")
-def unitType
-@Field @Option(name="refPropertyName", usage="", widget="String", required=true, def="REF")
-def refPropertyName
+@Field @Option(name="unit_type", usage="", widget="String", required=true, def="MENTION")
+def unit_type
+@Field @Option(name="ref_property_name", usage="", widget="String", required=true, def="REF")
+def ref_property_name
 if (!ParametersDialog.open(this)) return
 
 corpus = corpusViewSelection
@@ -38,32 +38,32 @@
 analecCorpus = URSCorpora.getCorpus(corpus)
 vue = URSCorpora.getVue(corpus)
 structure = analecCorpus.getStructure()
-if (!structure.getUnites().contains(unitType)) { // check if the structure contains the unitType units
-	println "Error: corpus structure does not contains unit with name=$unitType"
+if (!structure.getUnites().contains(unit_type)) { // check if the structure contains the unit_type units
+	println "Error: corpus structure does not contains unit with name=$unit_type"
 	return
 }
 
-if (!structure.getUniteProperties(unitType).contains(refPropertyName)) {
-	println "Error: corpus structure does not contains property name=$unitType"
+if (!structure.getUniteProperties(unit_type).contains(ref_property_name)) {
+	println "Error: corpus structure does not contains property name=$unit_type"
 	return
 } 
 
 def nModified = 0
 def nIgnored = 0
 
-def units = analecCorpus.getUnites(unitType)
+def units = analecCorpus.getUnites(unit_type)
 //units.sort() { a, b -> a.getDeb() <=> b.getDeb() ?: a.getFin() <=> b.getFin() }
 
 def refSet = new HashSet()
 for (Unite unit : units) { // process all units
-	def prop = unit.getProp(refPropertyName)
+	def prop = unit.getProp(ref_property_name)
 	refSet.add(prop)
 }
 
 def counter = 1
 for (Unite unit : units) { // process all units
 	
-	def prop = unit.getProp(refPropertyName)
+	def prop = unit.getProp(ref_property_name)
 	if (prop && prop == "SI") {
 		def name = "SI_" + counter
 		while (refSet.contains(name)) {
@@ -72,7 +72,7 @@
 		}
 		counter++
 		//println "old prop"+ prop
-		unit.getProps().put(refPropertyName, name)
+		unit.getProps().put(ref_property_name, name)
 		//println "new prop"+ name
 		nModified++
 	} else {
@@ -81,5 +81,5 @@
 }
 
 println "Result:"
-println "- $nModified units of type $unitType have been modified."
-println "- $nIgnored units of type $unitType have not been modified.\n"
+println "- $nModified units of type $unit_type have been modified."
+println "- $nIgnored units of type $unit_type have not been modified.\n"
Index: tmp/org.txm.analec.rcp/plugin.xml
===================================================================
--- tmp/org.txm.analec.rcp/plugin.xml	(revision 2173)
+++ tmp/org.txm.analec.rcp/plugin.xml	(revision 2174)
@@ -50,6 +50,10 @@
                         id="export">
                   </dynamic>
                </menu>
+               <command
+                     commandId="org.txm.annotation.urs.commands.OpenDemocratTools"
+                     style="push">
+               </command>
             </menu>
             <command
                   commandId="org.txm.annotation.urs.commands.EditAnnotationStructure"
@@ -104,7 +108,7 @@
                label="%menu.label.0"
                mnemonic="%menu.mnemonic.0">
             <command
-                  commandId="org.txm.annotation.urs.commands.LoadStructureFromGlozz"
+                  commandId="org.txm.annotation.urs.commands.SaveCorpus"
                   style="push">
                <visibleWhen
                      checkEnabled="false">
@@ -113,6 +117,42 @@
                   </reference>
                </visibleWhen>
             </command>
+            <menu
+                  id="menu.urs.tools"
+                  label="%menu.label.1">
+               <menu
+                     label="%menu.label.2">
+                  <dynamic
+                        class="org.txm.annotation.urs.commands.URSToolsMenuContribution"
+                        id="edit">
+                  </dynamic>
+               </menu>
+               <menu
+                     label="%menu.label.3">
+                  <dynamic
+                        class="org.txm.annotation.urs.commands.URSToolsMenuContribution"
+                        id="check">
+                  </dynamic>
+               </menu>
+               <menu
+                     label="%menu.label.4">
+                  <dynamic
+                        class="org.txm.annotation.urs.commands.URSToolsMenuContribution"
+                        id="exploit">
+                  </dynamic>
+               </menu>
+               <menu
+                     label="%menu.label.5">
+                  <dynamic
+                        class="org.txm.annotation.urs.commands.URSToolsMenuContribution"
+                        id="export">
+                  </dynamic>
+               </menu>
+               <command
+                     commandId="org.txm.annotation.urs.commands.OpenDemocratTools"
+                     style="push">
+               </command>
+            </menu>
             <command
                   commandId="org.txm.annotation.urs.commands.EditAnnotationStructure"
                   style="push">
@@ -124,7 +164,7 @@
                </visibleWhen>
             </command>
             <command
-                  commandId="org.txm.annotation.urs.commands.SaveCorpus"
+                  commandId="org.txm.annotation.urs.commands.EditVue"
                   style="push">
                <visibleWhen
                      checkEnabled="false">
@@ -133,8 +173,12 @@
                   </reference>
                </visibleWhen>
             </command>
+            <separator
+                  name="URSRCP.separator1"
+                  visible="true">
+            </separator>
             <command
-                  commandId="org.txm.annotation.urs.commands.ExportGlozzCorpus"
+                  commandId="org.txm.annotation.urs.commands.LoadStructureFromGlozz"
                   style="push">
                <visibleWhen
                      checkEnabled="false">
@@ -144,16 +188,6 @@
                </visibleWhen>
             </command>
             <command
-                  commandId="org.txm.annotation.urs.commands.ExportTEICorpus"
-                  style="push">
-               <visibleWhen
-                     checkEnabled="false">
-                  <reference
-                        definitionId="OneCorpusSelected">
-                  </reference>
-               </visibleWhen>
-            </command>
-            <command
                   commandId="org.txm.annotation.urs.commands.ImportTEIAnnotations"
                   style="push">
                <visibleWhen
@@ -163,6 +197,19 @@
                   </reference>
                </visibleWhen>
             </command>
+            <menu
+                  label="Export">
+               <command
+                     commandId="org.txm.annotation.urs.commands.ExportTEICorpus"
+                     label="%command.label.0"
+                     style="push">
+               </command>
+               <command
+                     commandId="org.txm.annotation.urs.commands.ExportGlozzCorpus"
+                     label="%command.label.1"
+                     style="push">
+               </command>
+            </menu>
          </menu>
       </menuContribution>
       <menuContribution
@@ -306,6 +353,12 @@
             id="org.txm.annotation.urs.commands.EditVue"
             name="%command.name.16">
       </command>
+      <command
+            categoryId="org.txm.rcp.category.txm"
+            defaultHandler="org.txm.annotation.urs.commands.OpenDemocratTools"
+            id="org.txm.annotation.urs.commands.OpenDemocratTools"
+            name="Democrat tools">
+      </command>
    </extension>
    <extension
          point="org.eclipse.ui.views">
