Index: tmp/org.txm.groovy.core/src/groovy/org/txm/macro/InstallAndUpdateMacroMacro.groovy
===================================================================
--- tmp/org.txm.groovy.core/src/groovy/org/txm/macro/InstallAndUpdateMacroMacro.groovy	(revision 3216)
+++ tmp/org.txm.groovy.core/src/groovy/org/txm/macro/InstallAndUpdateMacroMacro.groovy	(revision 3217)
@@ -12,49 +12,64 @@
 	monitorShowError("Le répertoire $groovyUserDirectory n'a pas pu être créé. Abandon.")
 	return;
 }
-@Field @Option(name="targets", usage="Path to the macro to update", widget="String", required=true, def="")
-def targets
+@Field @Option(name="macroPaths", usage="Comma separated list of macro paths", widget="String", required=true, def="")
+def macroPaths
 
-@Field @Option(name="svn", usage="TXM SVN repository", widget="String", required=true, def="http://forge.cbp.ens-lyon.fr/svn/txm/tmp/org.txm.groovy.core/src/groovy/org/txm/macro/")
-def svn
+@Field @Option(name="svnRepository", usage="http based URL of TXM's SVN ", widget="String", required=true, def="http://forge.cbp.ens-lyon.fr/svn/txm/tmp/org.txm.groovy.core/src/groovy/org/txm/macro/")
+def svnRepository
 
 @Field @Option(name="debug", usage="Show devug messages", widget="Boolean", required=false, def="false")
 def debug
 
 if (!ParametersDialog.open(this)) return false;
 
-if (!svn.endsWith("/")) svn += "/"
+if (!svnRepository.endsWith("/")) svnRepository += "/"
 
-def macros = targets.split(",").collect(){it.trim()}
+def macros = macroPaths.split(",").collect(){it.trim()}
 	
-println "Copyping ${macros.size()} files: "
-def errors = []
+print "Fetching ${macros.size()} files: "
+def errors = new LinkedHashMap()
+def updated = []
+def news = []
 for (def m : macros) {
 	def f = new File(groovyUserDirectory, m+"Macro.groovy")
 	f.getParentFile().mkdirs()
-	String remoteUrl = svn+m+"Macro.groovy"
+	String remoteUrl = svnRepository+m+"Macro.groovy"
 	try {
 		
 		if (debug) print "\n"+remoteUrl
 		boolean replaced = f.exists()
 		
-		
 		def file = new FileOutputStream(f)
 		def out = new BufferedOutputStream(file)
 		out << new URL(remoteUrl).openStream()
 		out.close()
 		
-		if (replaced) print "*"
-		else print "."
+		if (replaced) {
+			print "*"
+			updated << m
+		} else {
+			print "."
+			news << m
+		}
 	} catch(Exception e ) {
 		print "x"
-		errors << "\nError while fetching $f from $remoteUrl: $e"
+		errors[m] = e;
 	}
 }
+
+if (news.size() > 0 ) {
+	println "\n${news.join(", ")} created."
+}
+
+if (updated.size() > 0 ) {
+	println "\n${updated.join(", ")} updated."
+}
+
 if (errors.size() > 0) {
-	println errors.join("\n")
+	println "\n${errors.keySet().join(", ")} failed:"
+	println errors.values().join("\n\t")
 }
-println "\n$targets updated."
 
 def monitorShowError(String message) {
 	monitor.syncExec(new Runnable() {
Index: tmp/org.txm.groovy.core/src/groovy/org/txm/macro/table/Table2XMLMacro.groovy
===================================================================
--- tmp/org.txm.groovy.core/src/groovy/org/txm/macro/table/Table2XMLMacro.groovy	(revision 3216)
+++ tmp/org.txm.groovy.core/src/groovy/org/txm/macro/table/Table2XMLMacro.groovy	(revision 3217)
@@ -23,7 +23,7 @@
 
 @Field @Option(name="textSelector", usage="<text> lines selector format is column=value", widget="String", required=false, def="Type de notice=Notice sommaire")
 		def textSelector;
-		
+
 @Field @Option(name="textOrderColumn", usage="The column used to fill the 'text-order' text metadata", widget="String", required=false, def="")
 		def textOrderColumn
 
@@ -32,7 +32,7 @@
 
 @Field @Option(name="textContentColumnList", usage="<text> textual content columns", widget="String", required=false, def="")
 		def textContentColumnList;
-		
+
 @Field @Option(name="structuresSeparator", usage="Structures", widget="Separator", required=false, def="Structures")
 		def structuresSeparator
 
@@ -50,7 +50,7 @@
 
 @Field @Option(name="structureContentColumnList", usage="structure textual content columns", widget="String", required=false, def="Titre propre,Résumé,Descripteurs (Aff. Lig.),Générique (Aff. Lig.) ,Séquences")
 		def structureContentColumnList;
-		
+
 @Field @Option(name="structureTitleColumnList", usage="structure textual content columns", widget="String", required=false, def="Titre propre,Date de diffusion")
 		def structureTitleColumnList;
 
@@ -65,7 +65,7 @@
 
 @Field @Option(name="listColumnTypeList", usage="metadata columns of type=List semi-colon separated", widget="String", required=false, def="Résumé,Séquences")
 		def listColumnTypeList
-		
+
 @Field @Option(name="debug", usage="Show devug messages", widget="Boolean", required=false, def="false")
 		def debug
 //@Field @Option(name="structureOrderColumn", usage="structure column coding structure order", widget="String", required=false, def="Titre propre,Résumé,Descripteurs (Aff. Lig.),Descripteurs (Aff. Col.),Séquences")
@@ -248,7 +248,7 @@
 		for (String att : textMetadataColumnList) {
 			if (att in dateColumnTypeList) {
 				String tri = writeMetadataDate(text, att, writer)
-				if (!textOrderWritten) {
+				if (!textOrderWritten && tri != null) {
 					textOrderWritten = tri;
 				}
 			} else {
@@ -263,7 +263,7 @@
 		metadata << "$id	$textOrderWritten\n"
 		
 		writer.writeCharacters("\n") // simple XML formating
-			
+		
 		for (String att : textContentColumnList) {
 			
 			if (att in prefixesColumnTypeList) {
@@ -349,6 +349,10 @@
 
 def writeListTextContent(def record, def att, def writer) {
 	
+	writer.writeStartElement("ab")
+	writer.writeAttribute("type", att)
+	writer.writeCharacters("\n")
+	
 	writer.writeStartElement("head")
 	writer.writeStartElement("hi")
 	writer.writeCharacters(att)
@@ -357,38 +361,57 @@
 	writer.writeCharacters("\n")
 	
 	def value = record.get(att).replaceAll(" ++", " ")
-	if (value.length() <= 1) return
-	
-	writer.writeCharacters("\n")
-	found = false
-	for (String s : value.split("\n")) {
-		s = s.trim()
-		if (s.length() == 0) continue;
-		if (s.startsWith("-")) s = s.substring(1).trim();
-		if (s.length() == 0) continue;
+	if (value.length() > 1) {
 		
-		found = true
-		writer.writeCharacters("\t")
-		writer.writeStartElement("p")
-		writer.writeAttribute("rend", "list")
-		writer.writeCharacters(s)
-		writer.writeEndElement() // p
+		
+		writer.writeStartElement("list")
+		writer.writeAttribute("type", "ordered")
 		writer.writeCharacters("\n")
-	}
-	
-	if (!found) {
-		println "Warning: '$att' list not found in '$value'"
-		writer.writeCharacters("\t")
-		writer.writeStartElement("p")
-		writer.writeAttribute("rend", "no-list")
-		writer.writeCharacters(value)
-		writer.writeEndElement() // p
+		
+		found = false
+		for (String s : value.split("\n")) {
+			s = s.trim()
+			if (s.length() == 0) continue;
+			if (s.startsWith("-")) s = s.substring(1).trim();
+			if (s.length() == 0) continue;
+			
+			found = true
+			writer.writeCharacters("\t")
+			writer.writeStartElement("item")
+			writer.writeStartElement("p")
+			writer.writeAttribute("rend", "list")
+			writer.writeCharacters(s)
+			writer.writeEndElement() // p
+			writer.writeEndElement() // item
+			writer.writeCharacters("\n")
+		}
+		
+		if (!found) {
+			println "Warning: '$att' list not found in '$value'"
+			writer.writeCharacters("\t")
+			writer.writeStartElement("item")
+			writer.writeStartElement("p")
+			writer.writeAttribute("type", att)
+			writer.writeAttribute("rend", "no-list")
+			writer.writeCharacters(value)
+			writer.writeEndElement() // p
+			writer.writeEndElement() // item
+			writer.writeCharacters("\n")
+		}
+		
+		writer.writeEndElement() // list
 		writer.writeCharacters("\n")
 	}
+	writer.writeEndElement() // ab
+	writer.writeCharacters("\n")
 }
 
 def writeTextContent(def record, def att, def writer) {
 	
+	writer.writeStartElement("ab")
+	writer.writeAttribute("type", att)
+	writer.writeCharacters("\n")
+	
 	writer.writeStartElement("head")
 	writer.writeStartElement("hi")
 	writer.writeCharacters(att)
@@ -397,22 +420,24 @@
 	writer.writeCharacters("\n")
 	
 	def value = record.get(att).replaceAll(" ++", " ")
-	if (value.length() == 0) return
-	
-	writer.writeStartElement(AsciiUtils.buildAttributeId(att));
-	writer.writeAttribute("type", att.trim())
-	if (record.get(textIDColumn) != null) {
-		writer.writeAttribute("id", record.get(textIDColumn))
+	if (value.length() > 0) {
+		
+		for (String s : value.split("\n")) {
+			writer.writeStartElement("p")
+			writer.writeCharacters(s) // a paragraphe per line
+			writer.writeEndElement() // p
+		}
 	}
-	writer.writeCharacters("\n") // simple XML formating
-	
-	writer.writeCharacters(value) // get textColumnList content
-	writer.writeEndElement() // p
-	writer.writeCharacters("\n") // simple XML formating)
+	writer.writeEndElement() // ab
+	writer.writeCharacters("\n")
 }
 
 def writePrefixTextContent(def record, def att, def writer) {
 	
+	writer.writeStartElement("ab")
+	writer.writeAttribute("type", att)
+	writer.writeCharacters("\n")
+	
 	writer.writeStartElement("head")
 	writer.writeStartElement("hi")
 	writer.writeCharacters(att)
@@ -421,39 +446,47 @@
 	writer.writeCharacters("\n")
 	
 	def value = record.get(att).replaceAll(" ++", " ")
-	if (value.length() <= 1) return
-	
-	writer.writeCharacters("\n")
-	writer.writeStartElement("list")
-	writer.writeAttribute("rend", att.trim())
-	writer.writeAttribute("type", "unordered")
-	writer.writeCharacters("\n")
-	found = false
-	
-	value.findAll( /(?s)[A-Z]{3}:? *([^;\n]+?) +[;\n]/ ).each { desc ->
-		found = true
-		writer.writeCharacters("\t")
-		writer.writeStartElement("item")
-		matches = (desc =~ /(?s)([A-Z]{3}):? *([^;\n]+?) +[;\n]/)
-		writer.writeAttribute("type", matches[0][1])
-		writer.writeStartElement("span")
-		writer.writeCharacters(matches[0][1]+" ")
-		writer.writeEndElement() // span
-		writer.writeCharacters(matches[0][2])
-		writer.writeEndElement() // item
+	if (value.length() > 1) {
+		
 		writer.writeCharacters("\n")
+		writer.writeStartElement("list")
+		writer.writeAttribute("rend", att.trim())
+		writer.writeAttribute("type", "unordered")
+		writer.writeCharacters("\n")
+		found = false
+		
+		value.findAll( /(?s)[A-Z]{3}:? *([^;\n]+?) +[;\n]/ ).each { desc ->
+			found = true
+			writer.writeCharacters("\t")
+			writer.writeStartElement("item")
+			writer.writeAttribute("type", matches[0][1])
+			writer.writeStartElement("p")
+			matches = (desc =~ /(?s)([A-Z]{3}):? *([^;\n]+?) +[;\n]/)
+			
+			writer.writeStartElement("span")
+			writer.writeCharacters(matches[0][1]+" ")
+			writer.writeEndElement() // span
+			writer.writeCharacters(matches[0][2])
+			writer.writeEndElement() // p
+			writer.writeEndElement() // item
+			writer.writeCharacters("\n")
+		}
+		if (!found) {
+			println "Warning: '$att' prefixes not found in: '$value'"
+			writer.writeStartElement("p")
+			writer.writeCharacters(value)
+			writer.writeEndElement() // p
+		}
+		writer.writeEndElement() // list
+		writer.writeCharacters("\n")
 	}
-	if (!found) {
-		println "Warning: '$att' prefixes not found in: '$value'"
-		writer.writeCharacters(value)
-	}
-	writer.writeEndElement() // list
+	writer.writeEndElement() // ab
 	writer.writeCharacters("\n")
 }
 
 def writeMetadataDate(def record, def att, def writer) {
 	String value = record.get(att)
-	if (value.length() == 0) return
+	if (value.length() == 0) return null
 	
 	String att_normalized = AsciiUtils.buildAttributeId(att)
 	matches = (value =~ /([0-9]{2})\/([0-9]{2})\/([0-9]{4})/)
Index: tmp/org.txm.groovy.core/src/groovy/org/txm/scripts/importer/transcriber/importer.groovy
===================================================================
--- tmp/org.txm.groovy.core/src/groovy/org/txm/scripts/importer/transcriber/importer.groovy	(revision 3216)
+++ tmp/org.txm.groovy.core/src/groovy/org/txm/scripts/importer/transcriber/importer.groovy	(revision 3217)
@@ -201,7 +201,7 @@
 
 		//TRANSFORM INTO XML-TEI-TXM
 		files = tokenizedDir.listFiles()
-		println("Building XML-TXM ("+files.length+" files)")
+		println("Building ${files.length} XML-TXM file"+(files.length > 1?"s":""))
 		cpb = new ConsoleProgressBar(files.length)
 		for (File tfile : files) {
 			cpb.tick()
Index: tmp/org.txm.groovy.core/src/groovy/org/txm/scripts/importer/txt/importer.groovy
===================================================================
--- tmp/org.txm.groovy.core/src/groovy/org/txm/scripts/importer/txt/importer.groovy	(revision 3216)
+++ tmp/org.txm.groovy.core/src/groovy/org/txm/scripts/importer/txt/importer.groovy	(revision 3217)
@@ -269,7 +269,7 @@
 		cpb.done()
 
 		//TRANSFORM INTO XML-TEI-TXM
-		println("Building xml-tei-txm ("+stokenizeDir.listFiles().length+" files)")
+		println("Building XML-TXM ${stokenizeDir.listFiles().length} file"+(stokenizeDir.listFiles().length > 1?"s":""))
 		cpb = new ConsoleProgressBar(stokenizeDir.listFiles().length)
 		for (File tfile : stokenizeDir.listFiles()) {
 			cpb.tick()
Index: tmp/org.txm.groovy.core/src/groovy/org/txm/scripts/importer/xtz/XTZImporter.groovy
===================================================================
--- tmp/org.txm.groovy.core/src/groovy/org/txm/scripts/importer/xtz/XTZImporter.groovy	(revision 3216)
+++ tmp/org.txm.groovy.core/src/groovy/org/txm/scripts/importer/xtz/XTZImporter.groovy	(revision 3217)
@@ -191,10 +191,11 @@
 		splitedDirectory.deleteDir()
 		
 		File xslDirectory = new File(module.getSourceDirectory(), "xsl/1-split-merge")
-		println "-- Split-Merge XSL Step with $xslDirectory"
+		
 		def xslFiles = xslDirectory.listFiles()
 		if (xslDirectory.exists() && xslFiles != null && xslFiles.size() > 0) {
 			
+			println "-- Split-Merge XSL Step with $xslDirectory"
 			splitedDirectory.mkdir()
 			xslParams["output-directory"] = splitedDirectory.getAbsoluteFile().toURI().toString();
 			
@@ -264,13 +265,14 @@
 		//filesToProcess = inputDirectory.listFiles();
 		
 		File frontXSLdirectory = new File(module.getSourceDirectory(), "xsl/2-front")
-		println "-- Front XSL Step with the $frontXSLdirectory directory."
+		
 		def xslFiles = frontXSLdirectory.listFiles()
 		
 		xslParams["output-directory"] = outputDirectory.getAbsoluteFile().toURI().toString();
 		
 		if (frontXSLdirectory.exists() && xslFiles != null && xslFiles.size() > 0) {
 			
+			println "-- Front XSL Step with the $frontXSLdirectory directory."
 			xslFiles.sort()
 			for (File xslFile : xslFiles) {
 				if (xslFile.isDirectory() || xslFile.isHidden() || !xslFile.getName().endsWith(".xsl")) continue;
@@ -458,7 +460,7 @@
 	public boolean doToXMLTXMStep() {
 		filesToProcess = new File(module.getBinaryDirectory(),"tokenized").listFiles()
 		ConsoleProgressBar cpb = new ConsoleProgressBar(filesToProcess.size())
-		println("-- Building XML-TXM ("+filesToProcess.size()+" files)")
+		println("-- Building ("+filesToProcess.size()+" XML-TXM files)")
 		for (File f : filesToProcess) {
 			//ArrayList<String> milestones = new ArrayList<String>();
 			cpb.tick()
Index: tmp/org.txm.groovy.core/src/groovy/org/txm/scripts/importer/xml/importer.groovy
===================================================================
--- tmp/org.txm.groovy.core/src/groovy/org/txm/scripts/importer/xml/importer.groovy	(revision 3216)
+++ tmp/org.txm.groovy.core/src/groovy/org/txm/scripts/importer/xml/importer.groovy	(revision 3217)
@@ -191,7 +191,7 @@
 			return false;
 		}
 		//TRANSFORM INTO XML-TEI-TXM
-		println("Building XML-TXM ("+tokenfiles.size()+" files)")
+		println("Building XML-TXM ${tokenfiles.length} file"+(tokenfiles.length > 1?"s":""))
 		cpb = new ConsoleProgressBar(tokenfiles.size())
 		for (File f : tokenfiles) {
 			//ArrayList<String> milestones = new ArrayList<String>();
Index: tmp/org.txm.groovy.core/src/java/org/txm/groovy/core/GroovyScriptedImportEngine.java
===================================================================
--- tmp/org.txm.groovy.core/src/java/org/txm/groovy/core/GroovyScriptedImportEngine.java	(revision 3216)
+++ tmp/org.txm.groovy.core/src/java/org/txm/groovy/core/GroovyScriptedImportEngine.java	(revision 3217)
@@ -164,11 +164,13 @@
 			}
 		}
 		catch (ThreadDeath td) {
+			Log.warning("Import aborted.");
 			return Status.CANCEL_STATUS;
 		}
 		catch (Exception e) {
 			// System.out.println(NLS.bind(TXMUIMessages.errorWhileRunningScriptColonP0, e));
 			Log.printStackTrace(e);
+			Log.warning("Import failed.");
 			return new Status(Status.ERROR, "org.txm.groovy.core", e.getMessage());
 		}
 		finally {
