#!/usr/bin/python
# -*- coding: Latin-1 -*-
entete = """
###############################################################################
#
#    This file is part of COLLATINVS.
#
#    COLLATINVS is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 2 of the License, or
#    (at your option) any later version.
#
#    COLLATINVS is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with COLLATINVS; if not, write to the Free Software
#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
###############################################################################
"""
# BOGUES :
#  - l'analyse morphologique donne fautivement uita comme modele 
#    au lieu de manus, ou inv.
#  - au futur passif, ajouter la désinence -ebere (monebere, legebere, etc.)
#  - traduction de pecuniosum : riches (au pluriel)
#
# DOCUMENTATION RAPIDE 
# Collat.py fut naguère le module de lemmatisation utilisé par collatinus.py
# Devenant trop lourd, il a été remplacé par latinus.py, qui est 
# un collat.py dont on a ôté les fonctions inutilisées.
# Le destin de collat.py est maintenant d'offrir des fonctions de communication
# et d'intégration des lexiques personnels avec le lexique officiellement distribué.
#
# A FAIRE :
#  - Écrire des fonctions d'affichage des tableaux de flexion.
#  - Malgré une relative lenteur, assurer la lecture des données xml en 
#    utilisant xml.dom.minidom
#        
#  - Ajouter un champ degré à tirreg
#  - Rationnaliser la gestion des irréguliers :
#      - en définissant les formes inusitées par paramètre morpho
#              (pas de passif, pas de vocatif...)
#      - en incluant peut-être dans canons.xml la définition de ces
#              irréguliers, rendant ainsi plus facile le maintien de
#              la base, et en supprimant un fichier dans le paquet.
#              Les radicaux sont définis de cette manière.

version = """collat.py $Revision: 7.11 $
dernière mise à jour : $Date: 2006/01/15 23:13:39 $ par $Author: georgesk $
"""

import os, string, re
from frequences import freq # qui donne la fréqence d'un lemme 
                            # dans la littérature latine.

gabarit=re.compile(".*Revision: ([0-9]*)\.([0-9]*)(.*)\$.*")
trouve = gabarit.match(version)
#############################################################
# v_majeur et v_mineur correspondent aux numéros de version #
#############################################################
v_majeur=trouve.group(1)
v_mineur=trouve.group(2)
sous_version=trouve.group(3)

print "Collatinus pour python, version "+v_majeur+"."+v_mineur+"\n  chargement du lexique..."

# =====================================================
# constantes liées au système d'exploitation
# =====================================================

Linux = os.name == "posix"
# viaD : Répertoire de config de collatinus ; viaP : fichier lexique utilisateur
if Linux:
    viaD = os.path.expanduser("~/.collatinus/")
else:
    viaD = os.path.expanduser("c:\Program Files\collatinus\\")
viaP = viaD + "canons.xml"
# créer le répertoire de conf
if not os.path.exists(viaD):
    os.mkdir(viaD, 0777)

# =====================================================
# constantes morphologiques et manipulation de chaînes
# =====================================================

def Nombre(i):
   Lnombres = [' ', 'singulier', 'pluriel']
   return Lnombres[i]
    
Lmodeles = ['uita', 'amicus', 'puer', 'ager', 'templum', #4 
      'miles', 'ciuis', 'corpus', 'mare', 'manus', 'res', # 10 
      'bonus', 'miser', 'pulcher', 'fortis', 'uetus', 'acer', # 16
      'amo', 'moneo', 'lego', 'capio', 'audio', 'sum', 'eo', # 23
      'imitor', 'uereor', 'sequor', 'patior', 'potior', # 28
      'pronoms', 'invaria']
  
def Modele(i): 
   global Lmodeles
   return Lmodeles[i]

def numero_du_modele(m):
   global Lmodeles
   return Lmodeles.index(m)
   
def MorphoK(m):
   if m < 11:
      return "nominatif singulier"
   elif m < 17:
      return "nominatif masculin singulier"
   elif m < 29:
      return "1ère singulier présent indicatif actif"
   else: 
      return ""
      
def DesK(m):
   """ Fournit la désinence canonique du lemme de modèle m.           
       Cette fonction n'est évidemment pas applicable pour 
       les modèles sans désinence canonique stable (essentiellement la 
       troisième déclinaison des noms et adjectifs)."""
   if m == 0:
      return 'a'
   elif m in [1, 9, 11]:
      return 'us'
   elif 1 < m < 4 or 11 < m < 14:
      return 'er'
   elif m == 4:
      return 'um'
   elif m == 10:
      return 'es'
   elif m == 17 or m == 19:
      return 'o'
   elif m == 18 or m == 23:
      return 'eo'
   elif 19 < m < 22:
      return 'io'
   elif m == 22:
      return 'sum'
   elif m == 24 or m == 26:
      return 'or'
   elif m == 25:
      return 'eor'
   else:
      return 'ior'
   
def Cas(i):   
   Lcas = ['', 'nominatif', 'vocatif', 'accusatif', 'génitif', 'datif', 'ablatif']
   return Lcas[i]

def Genre(i):
   Lgenres = ['', 'masculin', 'féminin', 'neutre']
   return Lgenres[i]

def Degre(i):
   LDegres = ['', 'positif', 'comparatif', 'superlatif']
   return LDegres[i]
   
def Personne(i):
   Lpersonnes = ['', '1ère', '2ème', '3ème']
   return Lpersonnes[i]
   
def Temps(i):
   Ltemps = ['', 'présent', 'futur', 'imparfait', 'parfait',
      'futur antérieur', 'plus-que-parfait']
   return Ltemps[i]
   
def Mode(i):
   Lmodes = ['', 'indicatif', 'subjonctif', 'impératif', 'infinitif',
     'participe', 'gérondif',  'adjectif verbal']
   return Lmodes[i]
   
def Voix(i):
   Lvoix = ['', 'actif', 'passif']
   return Lvoix[i]
   
# =====================================================   
# classe tdes : les désinences
# =====================================================
class tdes:   
   def __init__(self, gr, c=0, gn=0, n=0, d=0, p=0, t=0, mde=0, v=0, mdl=0, r=0):
      self.graphie = gr
      self.cas = int(c)
      self.genre = int(gn)
      self.nombre = int(n)
      self.degre = int(d)
      self.personne = int(p)
      self.temps = int(t)
      self.mode = int(mde)
      self.voix = int(v)
      self.modele = int(mdl)
      self.radnum = int(r)
         
   def morpho(self):  
      """retourne la morphologie de l'instance en utilisant les listes ci-dessus. """
      #return '%s %s %s %s %s %s %s (modèle %s) ' % (Cas(self.cas), 
      return '%s %s %s %s %s %s %s' % (Cas(self.cas), 
         Genre(self.genre), Personne(self.personne), 
         Nombre(self.nombre), Temps(self.temps), Mode(self.mode), 
         Voix(self.voix)) #, Modele(self.modele))   

   def affiche(self):
      print self.morpho()

   def ecris(self, f):
      f.write('<desinence>\n')
      f.write('   <graphie>%s</graphie>\n' % self.graphie)
      f.write('   <cas>%d</cas>\n' % self.cas)
      f.write('   <nombre>%d</nombre>\n' % self.nombre)
      f.write('   <genre>%d</genre>\n' % self.genre)
      f.write('   <personne>%d</personne>\n' % self.personne)
      f.write('   <temps>%d</temps>\n' % self.temps)
      f.write('   <mode>%d</mode>\n' % self.mode)
      f.write('   <voix>%d</voix>\n' % self.voix)
      f.write('   <modele>%d</modele>\n' % self.modele)
      f.write('   <R>%d</R>\n' % self.radnum)
      f.write('</desinence>\n')

   def doc(self):
      print "%s radical %d modèle %s : %s" % (self.graphie, 
                                              self.radnum, Lmodeles[self.modele], self.morpho()) 

   def egale(self, d):
       return self.graphie == d.graphie\
          and self.modele == d.modele\
          and self.cas == d.cas\
          and self.genre == d.genre\
          and self.nombre == d.nombre\
          and self.degre == d.degre\
          and self.personne == d.personne\
          and self.temps == d.temps\
          and self.mode == d.mode\
          and self.voix == d.voix\
          and self.modele == d.modele\
          and self.radnum == d.radnum

def ecrisDes(f):
    f.write('<?xml version="1.0" encoding="iso-8859-1" ?>\n<!--') 
    f.write(entete)
    f.write('-->\n')
    f.write('<collatinus>\n')
    for k in desinences.keys():
        for d in desinences[k].keys():
            desinences[k][d].ecris(f) 
    f.write('</collatinus>')

            
# =====================================================
#  classe tirregs : les formes irrégulières
# =====================================================
class tirreg(tdes):
   def __init__(self, gr, k, c, gn, n, p, t, mde, v, mdl):
      # graphie, canon, cas, genre, nombre, personne, temps, mode, voix, modele
      self.graphie = gr
      self.cas = int(c)
      self.genre = int(gn)
      self.nombre = int(n)
      self.personne = int(p)
      self.temps = int(t)
      self.mode = int(mde)
      self.voix = int(v)
      self.modele = int(mdl)
      self.canon = k


# =====================================================
# tentree : ses instances composent le dictionnaire *lexique*
# =====================================================

# filtreG permet de calculer le genre des noms
filtreG = re.compile("^.*([mfn])\.\s:")

class tentree:
   def __init__(self, m, g, t, r2, r3):
      # modèle, graphie, texte, radicaux 2 et 3
      self.modele = int(m)
      self.graphie = g
      self.texte = t
      #~ intégration des radicaux...
      self.r2 = r2
      self.r3 = r3
      # calcul du genre d'après le champ texte (peccatum est, id scio.)
      s = filtreG.search(self.texte)
      if s: 
         e = s.group(1) 
         if e == 'm' : self.genre = 1
         elif e == 'f' : self.genre =  2
         else : self.genre = 3
      else: self.genre = 0

   def classe_gr(self):
      if self.modele < 11: return "nom"
      if self.modele < 17: return "adj"
      if self.modele < 28: return "verbe" 
      if self.modele == 29: return "pron" 
      return "inv"

   def docLemm(self):
       return "%s, (%s)\n  %s" % (self.graphie, Lmodeles[self.modele], self.texte) 

   def doc(self):
      """ retourne le lemme suivi de ses données 
      morphologiques, et des traductions françaises """
      return '%s %s' % (self.graphie, self.texte)

   def dochtml(self):
      """ comme doc, mais le lemme est en <b> gras</b> 
          prévoit l'intégration dans un environnement <ol></ol> ou <ul></ul>"""
      return '<li><b>%s</b> %s</li>' % (self.graphie, self.texte)

   def docLaTeX(self):
      """ Nunc carmen nostimus 
          prévoit l'intégration dans un environnement \begin{itemize} ou {enumerate}"""
      return "\item \\textbf{%s} %s" % (self.graphie, self.texte)

   def affiche(self):
       print self.doc()
      
   def ecris(self, f):
      """ écrit les données du lemme dans le fichier f """
      f.write('<canon>\n')
      f.write('   <graphie>%s</graphie>\n' % self.graphie)
      f.write('   <modele>%d</modele>\n' % self.modele)
      try: 
         f.write('   <R2>%s</R2>\n' % self.r2)
      except:
	 pass
      try:
         f.write('   <R3>%s</R3>\n' % self.r3)
      except:
         pass
      t = self.texte
      while len(t) > 1 and t[-1] == '\n': t = t[:-1]
      f.write('   <texte>%s</texte>\n' % t)
      f.write('</canon>\n')

# =====================================================
#  tradical : les radicaux
# =====================================================
class tradical:  
   def __init__(self, g, k, m):
      self.graphie = g
      self.canon = k
      self.modele = m
    
   def kanon(self):
       """ retourne l'entrée de lexique correspondant au radical """  
       return lexique[self.canon]
         
   def affiche(self, i):
      print "%s : radical %d de %s" % (self.graphie, i, self.canon)


# =====================================================
# chargement du lexique
# =====================================================

def datede(file):
   """ retourne la date du fichier file, et la chaine 'nil' 
   en cas d'absence du fichier."""
   if os.path.isfile(file):
      return os.stat(file).st_mtime
   else:
      return 'nil'

# lexicorum creatio :
lexique = {}
radicaux = {}
radicaux[2] = {}
radicaux[3] = {}
desinences = {}
irregs = {}

def a_lemmatibus():
   """ Chargement rapide à partir du fichier lemmata"""
   m = 0
   t = g = r2 = r3 = ""
   fdata = open('lemmata')
   linea = fdata.readline()
   print 'lemmata leguntur...'
   while string.find(linea, '---desinentiae---') < 0:
      eclats = re.split('[|]', linea)
      g = eclats[0]
      m = int(eclats[1])
      r2 = eclats[2]
      r3 = eclats[3]
      # tentree(m, g, t, r2, r3):
      # miles|5|milit||itis, m. : soldat
      lexique[g] = tentree(m, g, eclats[4], r2, r3) 
      # peupler les radicaux
      # tradical(g, k, m):
      if r2 > "":
        if not radicaux[2].has_key(r2):
            radicaux[2][r2] = {}
            radicaux[2][r2][0] = tradical(r2, g, m)
        else:
            radicaux[2][r2][len(radicaux[2][r2])] = tradical(r2, g, m)
      if r3 > "":
         if not radicaux[3].has_key(r3):
            radicaux[3][r3] = {}
            radicaux[3][r3][0] = tradical(r3, g, m)
         else:         
            radicaux[3][r3][len(radicaux[3][r3])] = tradical(r3, g, m)
      linea = fdata.readline()
   
   # désinences
   print 'desinentiae leguntur...'
   linea = fdata.readline() 
   while string.find(linea, '---irregulares---') < 0:
      eclats = re.split('[|]', linea)
      g = eclats[0]
      # graphie,cas,genre,nombre,degré,personne,temps,mode,voix,modèle,radical
      des = tdes(g, eclats[1], eclats[2], eclats[3], eclats[4],
         eclats[5], eclats[6], eclats[7], eclats[8], eclats[9], eclats[10])
      if not desinences.has_key(g):
         #~ ajout de la clé et de la désinence
         desinences[g] = {}
         desinences[g][0] = des
      #~ ajout de la désinence dans la clé      
      else :
         desinences[g][len(desinences[g])] = des
      linea = fdata.readline() 

   # irréguliers
   print 'irregulares leguntur...'
   linea = fdata.readline()
   while string.find(linea, '---finis---') < 0:
      eclats = re.split('[|]', linea)
      g = eclats[0]
      # graphie, canon, cas, genre, nombre, temps, mode, voix, modele
      # afferte|adfero|0|0|2|afferte|adfero|0|0|22|1|3|1|0
      irreg = tirreg(g, eclats[1], eclats[2], eclats[3], eclats[4],\
         eclats[5], eclats[6], eclats[7], eclats[8], eclats[9]) #, eclats[10])  
      if not irregs.has_key(g):
         #~ ajout de la clé et de la forme
         irregs[g] = [] # {}
         #irregs[g][0] = irreg
         irregs[g].append(irreg)
      else:
         #~ ajout de la forme dans la clé      
         #irregs[g][len(irregs[g])] = irreg
         irregs[g].append(irreg)
      linea = fdata.readline()

   fdata.close()


def precompile():
   # précompilation (génération du fichier lemmata) :
   fpre = open('lemmata', 'w')
   # drapeaux : 0 = lemmes ; 1 = desinences ; 2 = irreguliers
   for lemma in lexique.keys():
      linea = lemma + '|' + str(lexique[lemma].modele)
      linea += '|' + lexique[lemma].r2 +'|' + lexique[lemma].r3 
      linea += '|' + lexique[lemma].texte
      fpre.write(linea)

   fpre.write('---desinentiae---\n')   
   for desin in desinences.keys():
      for i in desinences[desin].keys():
         linea = desin + '|'
         linea += str(desinences[desin][i].cas) + '|' 
	 linea += str(desinences[desin][i].genre) + '|' 
	 linea += str(desinences[desin][i].nombre) + '|' 
         linea += str(desinences[desin][i].degre) + '|'\
            + str(desinences[desin][i].personne) + '|'\
	    + str(desinences[desin][i].temps) + '|' 
         linea += str(desinences[desin][i]. mode) + '|'\
            + str(desinences[desin][i].voix) + '|'\
	    + str(desinences[desin][i].modele)\
	    + '|' + str(desinences[desin][i].radnum) + '\n'
         fpre.write(linea) 

   fpre.write('---irregulares---\n')   
   # graphie, canon, cas, genre, nombre, personne, temps, mode, voix, modele
   for irr in irregs.keys():
      for i in irregs[irr]: 
         linea = "%s|%s|%s|%s|%s|%s|%s|%s|%s|%s\n" % (irr,i.canon,
             i.cas,i.genre,i.nombre,i.personne,i.temps,i.mode,i.voix,i.modele)
         fpre.write(linea)
   fpre.write('---finis---')
   fpre.close()
# def precompile():

def a_xml():   
   """ chargement xml. Un drapeau est armé pour
   générer le fichier précompilé lemmata"""
   def decrasse(l, balise):
       """ ridicule parseur xml en trois lignes : 
           débarasse une ligne de <balise> et de </balise>"""
       r = string.replace(l, '<%s>' % (balise), '')
       r = string.replace(r, '</%s>' % (balise), '')
       return string.strip(r)

   #~ 1. entrées
   print "ab xml lemmata leguntur"
   try:
           fichier = open('canons.xml')
   except:
	   fichier = open('/usr/share/collatinus/canons.xml');
   ligne = ""
   m = 0
   t = g = r2 = r3 = ""

   # passer l'en-tête et les commentaires
   while string.find(ligne, "<collatinus") < 0:
      ligne = fichier.readline()

   # lecture et parsage   
   while string.find(ligne, "</collatinus") < 0:
      ligne = fichier.readline()
      if string.find(ligne, "<modele>") > -1:
         m = decrasse(ligne, "modele")
      elif string.find(ligne, "<graphie>") > -1:
         g = decrasse(ligne, "graphie")
      elif string.find(ligne, "<texte>") > -1:
         t = decrasse(ligne, "texte") +'\n'
      elif string.find(ligne, "<R2>") > 1:
         r2 = decrasse(ligne, "R2")
      elif string.find(ligne, "<R3>") > 1:
         r3 = decrasse(ligne, "R3")
      elif string.find(ligne, "</canon>") > -1:
         if lexique.has_key(g):
            g = g + ' (2)'
         lexique[g] = tentree(int(m), g, t, r2, r3) 
         if r2 > "":
            if not radicaux[2].has_key(r2):
	       radicaux[2][r2] = {}
               radicaux[2][r2][0] = tradical(r2, g, int(m))
            else:
	       radicaux[2][r2][len(radicaux[2][r2])] = tradical(r2, g, int(m))
	       lexique[g].r2 = r2
	    r2 = ""
	 if r3 > "":
	    if not radicaux[3].has_key(r3):
                 radicaux[3][r3] = {}
                 radicaux[3][r3][0] = tradical(r3, g, int(m))
	    else:         
               radicaux[3][r3][len(radicaux[3][r3])] = tradical(r3, g, int(m))
               lexique[g].r3 = r3
            r3 = ""
   fichier.close()  


   #~ 2. désinences
   print "ab xml desinentiae leguntur..."
   try:
	   fichier = open('desinences.xml')
   except:
	   fichier = open('/usr/share/collatinus/desinences.xml')
   # passer l'en-tête et les commentaires
   while string.find(ligne, "<collat") < 0:
      ligne = fichier.readline()
   # initialisation de la première désinence
   ligne = '';
   cas = genre = nombre = degre = personne = mode = temps\
      = voix = modele = radnum = '0'
   #~ boucle de lecture
   while string.find(ligne, "</collat") < 0:
      ligne = fichier.readline()   
      if string.find(ligne, "<graphie>") > -1:
         g = decrasse(ligne, "graphie")
      elif string.find(ligne, "cas") > -1:
         cas = decrasse(ligne, "cas")
      elif string.find(ligne, "<genre>") > -1:
         genre = decrasse(ligne, "genre")
      elif string.find(ligne, "<nombre>") > -1:
         nombre = decrasse(ligne, "nombre")
      elif string.find(ligne, "<degre>") > -1:
         degre = decrasse(ligne, "degre")
      elif string.find(ligne, "<personne>") > -1:
         personne = decrasse(ligne, "personne")
      elif string.find(ligne, "<temps>") > -1:
         temps = decrasse(ligne, "temps")
      elif string.find(ligne, "<mode>") > -1:
         mode = decrasse(ligne, "mode")
      elif string.find(ligne, "<voix>") > -1:
         voix = decrasse(ligne, "voix")
      elif string.find(ligne, "<modele>") > -1:
         modele = decrasse(ligne, "modele")
      elif string.find(ligne, "<R>") > -1:
         radnum = decrasse(ligne, "R")
      elif string.find(ligne, "</desinence>") > -1:
      #~ def __init__(self, gr, c, gn, n, d, p, t, mde, v, mdl, r):
         des = tdes(g, cas, genre, nombre, degre, personne,\
            temps, mode, voix, modele, radnum)
         if not desinences.has_key(g):
         #~ ajout de la clé et de la désinence
            desinences[g] = {}
            desinences[g][0] = des
         else :
         #~ ajout de la désinence dans la clé      
            desinences[g][len(desinences[g])] = des
         #~ réinitialisation graphie et modele ont toujours une valeur   
         cas = genre = nombre = degre = personne = temps = mode = voix = '0'
   fichier.close()   

   #~ irréguliers
   print "ab xml irregulares leguntur..."
   try:
	   fichier = open("irregs.xml")
   except:
	   fichier = open("/usr/share/collatinus/irregs.xml")
   # passer l'en-tête et les commentaires
   while string.find(ligne, "<collat") < 0:
      ligne = fichier.readline()
   ligne = '';
   cas = genre = nombre = degre = personne\
      = mode = temps = voix = modele = '0'

   #~ boucle de lecture
   while string.find(ligne, "</collat") < 0:
      ligne = fichier.readline()   
      if string.find(ligne, "<graphie>") > -1:
         g = decrasse(ligne, "graphie") 
      elif string.find(ligne, "cas") > -1:
         cas = decrasse(ligne, "cas")
      elif string.find(ligne, "<genre>") > -1:
         genre = decrasse(ligne, "genre")
      elif string.find(ligne, "<nombre>") > -1:
         nombre = decrasse(ligne, "nombre")
      elif string.find(ligne, "<degre>") > -1:
         degre = decrasse(ligne, "degre")
      elif string.find(ligne, "personne>") > -1:
         personne = decrasse(ligne, "personne")
      elif string.find(ligne, "<temps>") > -1:
         temps = decrasse(ligne, "temps")
      elif string.find(ligne, "<mode>") > -1:
         mode = decrasse(ligne, "mode")
      elif string.find(ligne, "<voix>") > -1:
         voix = decrasse(ligne, "voix")
      elif string.find(ligne, "<modele>") > -1:
         modele = decrasse(ligne, "modele")
      elif string.find(ligne, "<canon>") > -1:
         canon = decrasse(ligne, "canon")
      elif string.find(ligne, "</irreg>") > -1:
       #~ irreg __init__(self, gr, k, c, gn, n, p, t, mde, v, mdl)
         irreg = tirreg(g, canon, cas, genre, nombre, personne,
           temps, mode, voix, modele)
	 if not irregs.has_key(g):
	    #~ ajout de la clé et de la désinence
	    irregs[g] = []
	    irregs[g].append(irreg) #[0] = irreg
	    #~ ajout de la désinence dans la clé      
	 else:
	    irregs[g].append(irreg) #[len(irregs[g])] = irreg
	    #~ réinitialisation graphie et modele ont toujours une valeur   
         cas = genre = nombre = degre = personne = temps = mode = voix = '0'
   fichier.close()
   # ligne à supprimer ?
   precompile()


#================================================================
# Tests permettant de décider du mode de lecture : xml ou lemmata
#================================================================

# détection des fichiers de données et de leurs dates de modification   
datecanons = datede('canons.xml')
datelemmata = datede('lemmata')
# print "date l %s date xml %s " % (datelemmata, datecanons)
if datelemmata == 'nil':
  print 'pas de fichier lemmata'
  a_xml()
elif datecanons == 'nil':
  a_lemmatibus()
elif datelemmata > datecanons > 0:
  a_lemmatibus() 
else:
  a_xml() 

#==============================================   
#  Affichage des stats du chargement
#==============================================   
print "  ", len(lexique), " entrees ;"
print len(desinences), " desinences ;"
print len(radicaux[2]), "radicaux 2 ;"
print len(radicaux[3]), "radicaux 3 ;"
print len(irregs), "irreguliers."



#==============================================   
# LECTURE DU LEXIQUE PERSONNEL (LEXIQUEP) ET  
# CORRECTION DE LEXIQUE PAR LEXIQUEP
#==============================================   
from xml.dom import minidom
from os.path import *

class tentreeP(tentree):
    """Deux différences avec tentree : 
       1. un champ status qui définit
           comment altérer le lexique officiel. Trois valeurs possibles
           pour status :
           0 = ajouter 
           1 = modifier
           2 = supprimer 
       2. un champ com qui indique si l'entrée a été communiqué à un serveur collatinus.  """

    def __init__(self, s, m, g, t, r2, r3, com=0):
        tentree.__init__(self, m, g, t, r2, r3)
        self.status = s
        self.com = com

    def ecris(self, f):
        """ écrit les données du lemme dans le fichier f """
        f.write('<canon>\n')
        f.write('<status>%d</status>\n' % self.status)
        f.write('   <graphie>%s</graphie>\n' % self.graphie)
        f.write('   <modele>%d</modele>\n' % self.modele)
        if self.r2 > '':
            f.write('   <R2>%s</R2>\n' % self.r2)
        if self.r3 > '':
            f.write('   <R3>%s</R3>\n' % self.r3)
        # couper le \n final du champ texte
        t = self.texte
        while t[-1] == '\n': t = t[:-1]
        f.write('   <texte>%s</texte>\n' % t)
        f.write('   <com>%s</com>\n' % self.com)
        f.write('</canon>\n')

    def entree(self):
        return tentree(self.modele, self.graphie, self.texte, self.r2, self.r3)

def lisEntreeP(x):
    """ renvoie une instance de tentreeP à partir d'un Element DOM"""
    s = int(x.getElementsByTagName('status')[0].childNodes[0].data)
    m = x.getElementsByTagName('modele')[0].childNodes[0].data
    m = m.encode('latin-1')
    g = x.getElementsByTagName('graphie')[0].childNodes[0].data
    g = g.encode('latin-1')
    try:
        t = x.getElementsByTagName('texte')[0].childNodes[0].data
        t = t.encode('latin-1')
    except: t = ""
    try:
        r2 = x.getElementsByTagName('R2')[0].childNodes[0].data
        r2 = r2.encode('latin-1')
        if not radicaux[2].has_key(r2):
	       radicaux[2][r2] = {}
               radicaux[2][r2][0] = tradical(r2, g, int(m))
        else:
	       radicaux[2][r2][len(radicaux[2][r2])] = tradical(r2, g, int(m))
	       lexique[g].r2 = r2
    except: r2 = ""
    try:
        r3 = x.getElementsByTagName('R3')[0].childNodes[0].data 
        r3 = r3.encode('latin-1')
        if not radicaux[3].has_key(r3):
            radicaux[3][r3] = {}
            radicaux[3][r3][0] = tradical(r3, g, m)
        else:         
            radicaux[3][r3][len(radicaux[3][r3])] = tradical(r3, g, m)
    except: r3 = ""
    try: com = x.getElementsByTagName('com')[0].childNodes[0].data 
    except: com = 0 
    return tentreeP(s, m, g, t, r2, r3, com) 

# création du lexique personnel
import UserDict
class tlexicumP(UserDict.UserDict):
    def communiquees(self):
       n = 0
       for i in self.keys():
          if self.data[i].com: n += 1
       return n

    def nonCommuniquees(self):
       n = 0
       for i in self.keys():
           if not self.data[i].com: n += 1

    def setEnvoye(self):
       for i in self.keys():
           self.data[i].com = 1

    def ecris(self):
        """ Ecrit le lexique personnel """ 
        f = open(viaP, 'w')
        f.write('<?xml version="1.0" encoding="iso-8859-1" ?>\n<!--') 
        f.write(entete)
        f.write('-->\n')
        f.write('<collatinus>')
        for e in self.data.keys():
            self.data[e].ecris(f)
        f.write('</collatinus>')
        f.close()
        print "lexique personnel mis à jour"

lexicumP = tlexicumP()

# construction de l'arbre DOM à partir du fichier lexique personnel
def ecrisP():
    """ Ecrit le lexique personnel """ 
    f = open(viaP, 'w')
    f.write('<?xml version="1.0" encoding="iso-8859-1" ?>\n<!--') 
    f.write(entete)
    f.write('-->\n')
    f.write('<collatinus>')
    for e in lexicumP.keys():
        lexicumP[e].ecris(f)
    f.write('</collatinus>')
    f.close()
    print "lexique personnel mis à jour"

if not os.path.exists(viaP):
    # création du fichier 
    ecrisP()

# Chargement du lexique personnel : désactivé pour les besoins de collatcom.py
#doc = minidom.parse(viaP)
#canonsP = doc.getElementsByTagName('canon')
# constitution du lexique personnel lexicumP
#for i in canonsP:
##    gr = i.childNodes[3].firstChild.data 
#    lexicumP[gr] = lisEntreeP(i)
# correction du lexique officiel
#for e in lexicumP.keys():
#    entreeP = lexicumP[e]
#    if entreeP.status < 2: 
#        entreeP.texte += '\n'
#        lexique[e] = entreeP
#    else: del(lexique[e])
# affichage des stats du chargementP
#print "%d corrections personnelles du lexique" % len(lexicumP)
#print "   dont %d communiquées au serveur" % lexicumP.communiquees()

# =====================================================
# consultation du lexique 
# =====================================================
def dico():
   m = "dico"
   while m != "q":
      if m > "":
         if lexique.has_key(m):
            lexique[m].affiche()
         else:
            print "introuvable"
         m = raw_input("entrée (q pour quitter) : ")


# =====================================================
# insertion d'un lemme
# ===================================================== 
def l_adde(g, m, r2, r3, t):
   """ l_adde siue_lemmam adde 
       ajoute à la liste des canons le lemme 
       de graphie g, de modèle m,
       de radicaux r3 et r3, 
       et de définition t."""
   if lexique.has_key(g):
         g = g + ' (2)'
   nm = numero_du_modele(m)	 
   lexique[g] = tentree(nm, g, t, r2, r3) 
   if r2 > "":
      if not radicaux[2].has_key(r2):
            radicaux[2][r2] = {}
            radicaux[2][r2][0] = tradical(r2, g, nm)
      else:
            radicaux[2][r2][len(radicaux[2][r2])] = tradical(r2, g, nm)
   if r3 > "":
      if not radicaux[3].has_key(r3):
            radicaux[3][r3] = {}
            radicaux[3][r3][0] = tradical(r3, g, int(m))
      else:         
            radicaux[3][r3][len(radicaux[3][r3])] = tradical(r3, g, nm)
   l_scribe()
   return g + " a été ajouté au lexique"


# =====================================================
# écriture du lexique
# ===================================================== 
def l_scribe():
   """ lexicum scribe
       Ecrit le lexique sur disque.
   """
   global entete
   print "Dictionnaire de Collatinus\n"
   print "--------------------------\n"
   f = open("./canons.xml", "w")
   f.write('<?xml version="1.0" encoding="iso-8859-1" ?>')
   f.write('<!--')
   f.write(entete)
   f.write('-->')
   f.write("\n<collatinus>\n")
   cles = lexique.keys()
   cles.sort()
   for cle in cles:
      lexique[cle].ecris(f) 
   #for (graphie, entree) in lexique.items():
   #   entree.ecris(f)
   f.write("</collatinus>")
   f.close()
   print("Le lexique a été écrit dans le fichier canons.xml")


# =====================================================
# consultation des désinences
# ===================================================== 
def dicodes():
   mot = ""
   while mot != "q":
      if mot != "":   
         if desinences.has_key(mot):
            for i in range(len(desinences[mot])):
               desinences[mot][i].affiche()
         else:
            print "introuvable"           
      mot = raw_input("désinence ? (q pour quitter) ")

# =====================================================
#~ consultation des radicaux
# =====================================================
def dicorad():
   mot = ""
   while mot != "q":
      if mot > "":
         for i in [2, 3]:
            if radicaux[i].has_key(mot):
               for iRad in range(len(radicaux[i][mot])):
                  radicaux[i][mot][iRad].affiche(i)
      mot = raw_input("radical ? (q pour quitter) ")      

# =====================================================
# recherche des désinences possibles d'un mot
# =====================================================
def desforme():
   mot = ""
   while not mot == "q":
      if mot > '':
         for i in range(len(mot)):
            if desinences.has_key(mot[i:]):
               Des = desinences[mot[i:]]
               for iMorph in range(len(Des)):
                   print Des[iMorph].graphie,
                   Des[iMorph].affiche()
      mot = raw_input("forme ? (q pour quitter) ")

# =====================================================
# analyses morphologiques d'un mot
# =====================================================
class morpho:
    """  Dans cette classe, j'ai ajouté
              - lemme : le lemme ;
              - traduc : la traduction ;
         Prennent un autre sens :
              - gr[aphie] est le mot fléchi passé à l'initialisation
         Pour les autres paramètres, qui sont morphologiques et paradigmatiques,
            voir la classe tdes : graphie cas genre nombre degre personne
                                  temps mode voix modele radnum
    """
    # doc tdes :
    # self, gr, c=0, gn=0, n=0, d=0, p=0, t=0, mde=0, v=0, mdl=0, r=0
    # graphie, cas, genre, nombre, degré, personne, temps, mode, voix, modèle, radical

    def __init__(self, k, mdl, tr, gr, c=0, gn=0, n=0, d=0, p=0, t=0, mde=0, v=0, r=0):
         self.des = tdes('', c, gn, n, d, p, t, mde, v, mdl, r)
         # print '******', k, self.des.genre, self.des.morpho(), '*****'
         self.lemme = lexique[k]
         self.traduc = tr

    def humain(self):
        #return "%s %s %s" % (self.lemme, self.traduc, self.des.morpho())
        return self.des.morpho()

class morphos:
    """ morphos est la liste de toutes les analyses possibles d'un mot
        ... classe à compléter ...
    """
    def __init__(self, mot):
           self.items = {} 
           #~ chercher les formes canoniques
           for uox in [mot, mot + ' (2)']:
               if lexique.has_key(uox):
                   lm = lexique[uox]
                   if not self.items.has_key(uox):
                       self.items[uox] = []
                   m = lexique[uox].modele 
                   if m < 17: # nom ou adj 
                       if m > 10: # adj
                           self.items[uox].append(morpho(uox, m, lm.texte, uox, 1, 1, 1))
                       else: # nom
                           self.items[uox].append(morpho(uox, m, lm.texte, uox, 1, lm.genre, 1))
                   elif m < 29: # verbe
                       self.items[uox].append(morpho(uox,lm.modele, 
                             lm.texte, uox,0, 0, 1, 0, 1, 1, 1, 1))
                   else:
                       self.items[uox].append(morpho(uox, m, lm.texte, uox))

           #~ chercher les formes irrégulières
           if irregs.has_key(mot):
               for iIrr in range(len(irregs[mot])):
                  im = irregs[mot][iIrr]
                  lk = lexique[im.canon]
                  if not self.items.has_key(im.canon):
                      self.items[im.canon] = []
                  self.items[im.canon].append(morpho(im.canon, im.modele, lk.texte, mot,
                      im.cas, im.genre, im.nombre, 0,  # tirreg n'a pas de degré de sign. !
                      im.personne, im.temps, im.mode, im.voix)) #, im.radnum))

                        #k, mdl, tr, gr, c=0, gn=0, n=0, d=0, p=0, t=0, mde=0, v=0, r=0

           # chercher toutes les désinences
           for i in range(len(mot)):
              grDes = mot[i:]
              grRad = mot[:i]
              if desinences.has_key(grDes):
                 lesDes = desinences[grDes]
                 for iDes in range(len(lesDes)):
                    Des = lesDes[iDes]
                    if Des.radnum > 1:
                       if radicaux[Des.radnum].has_key(grRad):
                          radix = radicaux[Des.radnum][grRad]
                          for iRad in range(len(radix)):
                             if Des.modele == radix[iRad].modele and lexique.has_key(radix[iRad].canon)\
                                and  radix[iRad].modele == lexique[radix[iRad].canon].modele:
                                K = radix[iRad].canon
                                # si la clé n'existe pas dans les items
                                if not self.items.has_key(K):
                                    self.items[K] = []
                                lk = lexique[K]
                                self.items[K].append(morpho(lk.graphie, lk.modele, lk.texte, 
                                        mot, Des.cas, Des.genre, Des.nombre, Des.degre, 
                                        Des.personne, Des.temps, Des.mode, Des.voix, Des.radnum))

                    else: # cas plus simple : la désinence canonique est extrapolable
                       K = grRad + DesK(Des.modele) # reconstitution d'une forme canonique hypothétique    
                       if lexique.has_key(K) and Des.modele == lexique[K].modele:
                             if not self.items.has_key(K):
                                self.items[K] = []
                             lk = lexique[K]
                             self.items[K].append(morpho(K, lk.modele, lk.texte, mot, 
                                 Des.cas, Des.genre, Des.nombre, Des.degre, Des.personne,
                                 Des.temps, Des.mode, Des.voix, Des.radnum))
                       if lexique.has_key(K + ' (2)')\
                          and Des.modele == lexique[K + ' (2)'].modele:
                             K = K + ' (2)'
                             if not self.items.has_key(K):
                                self.items[K] = []
                             lk = lexique[K]
                             self.items[K].append(morpho(K, lk.modele, lk.texte, mot,
                                 Des.cas, Des.genre, Des.nombre, Des.degre, Des.personne,
                                 Des.temps, Des.mode, Des.voix, Des.radnum))
    # fin de def __init__(mot)

    def humain(self):
       res = ''
       for K in self.items.keys():
          res = "%s\n%s %s" % (res, K, self.items[K][0].traduc)
          for ik in range(len(self.items[K])):
             res = "%s    %s\n" % (res, self.items[K][ik].humain())
       return res

def analysesDe(mot):
   return morphos(mot)

# =====================================================
#  Chaîne de retour d'une analyse
# =====================================================

def ijuv(forme):
   # transformation de v et j et u et i
   r = string.replace(forme, 'v', 'u')
   r = string.replace(r, 'j', 'i')
   return r

def chaineAnalyse(forme):
    f = ijuv(forme)
    m = morphos(f)
    # majuscules
    lf = ijuv(string.lower(f))
    if lf != f:
        m.items.update(morphos(lf).items)
    # suffixes
    if m == {}:
       return '-'
    if lf[-3:] == 'que':
        m.items.update(morphos(lf[:-3]).items)
    elif lf[-2:] in ['ue', 'ne']: 
        m.items.update(morphos(lf[:-2]).items)
    return m.humain()


# =====================================================
# dialogue d'analyse morphologique
# =====================================================
def dialogueAnalyse():
   forme = ""
   arep = ''
   while forme != "q": 
       if forme != "":
           #print chaineAnalyse(forme)
           print lemmatiseMBrut(forme).humain()
       forme = raw_input("forme ? (q pour quitter) ")
      

# =====================================================
# Analyse totale : texte, morpho, Dictionnaire Jeanneau
# =====================================================

# Définition des volumes du Jeanneau 
def volume(e):    
   volumes={"abzz":"Dico-a01.html",
    "aczz":"Dico-a02.html",
    "adnzz":"Dico-a03.html",
    "aegzz":"Dico-a04.html",
    "ajzz":"Dico-a05.html",
    "alzz":"Dico-a06.html",
    "amzz":"Dico-a07.html",
    "aozz":"Dico-a08.html",
    "aqzz":"Dico-a09.html",
    "arzz":"Dico-a10.html",
    "aszz":"Dico-a11.html",
    "azz":"Dico-a12.html",
    "bzz":"Dico-b.html",
    "camzz":"Dico-c01.html",
    "carzz":"Dico-c02.html",
    "cayzz":"Dico-c03.html",
    "cezz":"Dico-c04.html",
    "cirzz":"Dico-c05.html",
    "clazz":"Dico-c06.html",
    "cofzz":"Dico-c07.html",
    "colzz":"Dico-c08.html",
    "comzz":"Dico-c09.html",
    "confzz":"Dico-c10.html",
    "conszz":"Dico-c11.html",
    "coxzz":"Dico-c12.html",
    "cuizz":"Dico-c13.html",
    "czz":"Dico-c14.html",
    "deczz":"Dico-d01.html",
    "deqzz":"Dico-d02.html",
    "dexzz":"Dico-d03.html",
    "dipzz":"Dico-d04.html",
    "diszz":"Dico-d05.html",
    "dunzz":"Dico-d06.html",
    "dzz":"Dico-d07.html",
    "efzz":"Dico-e01.html",
    "elzz":"Dico-e02.html",
    "erzz":"Dico-e03.html",
    "exazz":"Dico-e04.html",
    "exlzz":"Dico-e05.html",
    "exszz":"Dico-e06.html",
    "ezz":"Dico-e07.html",
    "fazz":"Dico-f01.html",
    "fezz":"Dico-f02.html",
    "fizz":"Dico-f03.html",
    "fozz":"Dico-f04.html",
    "frzz":"Dico-f05.html",
    "fzz":"Dico-f06.html",
    "gzz":"Dico-g.html",
    "hzz":"Dico-h.html",
    "imbzz":"Dico-i01.html",
    "impzz":"Dico-i02.html",
    "inczz":"Dico-i03.html",
    "infezz":"Dico-i04.html",
    "inmzz":"Dico-i05.html",
    "inspzz":"Dico-i06.html",
    "intepzz":"Dico-i07.html",
    "interzz":"Dico-i08.html",
    "invezz":"Dico-i09.html",
    "izz":"Dico-i10.html",
    "jzz":"Dico-j.html",
    "kzz":"Dico-k.html",
    "latzz":"Dico-l01.html",
    "leozz":"Dico-l02.html",
    "lixzz":"Dico-l03.html",
    "lubzz":"Dico-l04.html",
    "lzz":"Dico-l05.html",
    "malzz":"Dico-m01.html",
    "maxzz":"Dico-m02.html",
    "mezz":"Dico-m03.html",
    "mnzz":"Dico-m04.html",
    "mozz":"Dico-m05.html",
    "mzz":"Dico-m06.html",
    "nazz":"Dico-n01.html",
    "nenzz":"Dico-n02.html",
    "nexzz":"Dico-n03.html",
    "nizz":"Dico-n04.html",
    "nozz":"Dico-n05.html",
    "nzz":"Dico-n06.html",
    "obmzz":"Dico-o01.html",
    "obtzz":"Dico-o02.html",
    "olluszz":"Dico-o03.html",
    "opuszz":"Dico-o04.html",
    "ozz":"Dico-o05.html",
    "parzz":"Dico-p01.html",
    "pelvzz":"Dico-p02.html",
    "perczz":"Dico-p03.html",
    "perlzz":"Dico-p04.html",
    "perszz":"Dico-p05.html",
    "pidzz":"Dico-p06.html",
    "pluzz":"Dico-p07.html",
    "porzz":"Dico-p08.html",
    "praegzz":"Dico-p09.html",
    "praeszz":"Dico-p10.html",
    "prizz":"Dico-p11.html",
    "promzz":"Dico-p12.html",
    "proutzz":"Dico-p13.html",
    "pzz":"Dico-p14.html",
    "quazz":"Dico-q01.html",
    "quezz":"Dico-q02.html",
    "quizz":"Dico-q03.html",
    "qzz":"Dico-q04.html",
    "razz":"Dico-r01.html",
    "rejzz":"Dico-r02.html",
    "reszz":"Dico-r03.html",
    "rhzz":"Dico-r04.html",
    "rzz":"Dico-r05.html",
    "sazz":"Dico-s01.html",
    "sczz":"Dico-s02.html",
    "sezz":"Dico-s03.html",
    "smzz":"Dico-s04.html",
    "sozz":"Dico-s05.html",
    "sqzz":"Dico-s06.html",
    "stzz":"Dico-s07.html",
    "subzz":"Dico-s08.html",
    "sumzz":"Dico-s09.html",
    "szz":"Dico-s10.html",
    "tazz":"Dico-t01.html",
    "tezz":"Dico-t02.html",
    "tolzz":"Dico-t03.html",
    "tramzz":"Dico-t04.html",
    "trizz":"Dico-t05.html",
    "tzz":"Dico-t06.html",
    "umzz":"Dico-u01.html",
    "urzz":"Dico-u02.html",
    "uterzz":"Dico-u03.html",
    "uzz":"Dico-u04.html",
    "vazz":"Dico-v01.html",
    "verzz":"Dico-v02.html",
    "viezz":"Dico-v03.html",
    "vixzz":"Dico-v04.html",
    "vzz":"Dico-v05.html",
    "xzz":"Dico-x.html",
    "zzz":"Dico-z.html"}
   for k in volumes.keys():
      if e < k: return volumes[k]
   return "Error.html"
                
def ui2vj(f):
        """ renvoie f orthographié en -v- et -j- """
        f = re.sub('^ua', 'va', f)
        f = re.sub('^ue', 've', f)
        f = re.sub('^ui', 'vi', f)
        f = re.sub('^uo', 'vo', f)
        f = re.sub('^uu', 'vu', f)
        f = re.sub('^ia', 'ja', f)
        f = re.sub('^ie', 'je', f)
        f = re.sub('^ii', 'ji', f)
        f = re.sub('^io', 'jo', f)
        f = re.sub('^iu', 'ju', f)        
        f = re.sub('[aeiou]ua', '[aeiou]va', f)
        f = re.sub('[aeiou]ue', '[aeiou]ve', f)
        f = re.sub('[aeiou]ui', '[aeiou]vi', f)
        f = re.sub('[aeiou]uo', '[aeiou]vo', f)
        f = re.sub('[aeiou]uu', '[aeiou]vu', f)
        f = re.sub('[aeiou]ia', '[aeiou]ja', f)
        f = re.sub('[aeiou]ie', '[aeiou]je', f)
        f = re.sub('[aeiou]ii', '[aeiou]ji', f)
        f = re.sub('[aeiou]io', '[aeiou]jo', f)
        f = re.sub('[aeiou]iu', '[aeiou]ju', f)
        return f

def analyseTotale(f):
    """ Renvoie pour la forme f
       1. ses lemmes
       2. leurs analyses morpho
       3. l'entrée Jeanneau correspondante. """
    # ajout d'espaces en début et fin pour assurer la mise en tableau
    # des premier et dernier mots.
    echec = 0
    retour = ''
    if f != "":
            # analyse morpho complète
            morpho = analysesDe(f)
    if morpho == '?':              
            # essayer en minuscules
            morpho = analysesDe(ijuv(string.lower(f)))
    # essais suffixes
    if f[-3:] == 'que':
            morpho = analysesDe(f[:-3])
    if morpho == {}:
            retour = retour + '<b>' + f + '</b> : ?\n'
            echec = 1
    if not echec:
        # calcul de chaque lemme
        retour = retour + '<ol>\n'
        for iLemme in range(len(morpho)):
                # item de liste
                retour = retour + '<li>'
                # lemme en gras
                K = morpho.keys()[iLemme]
                retour = retour + 'lemme : ' +  K + '<br>'
                retour = retour + 'morphologies : '
                for iK in range(len(morpho[K])):
                        retour = retour + morpho[K][iK] + ', '
                 # recherche dans le jeanneau
                retour = retour + '<br>\ndictionnaire Jeanneau : <br>\n'
                K = string.lower(ui2vj(K))
                vol = 'jano/' + volume(K)
                fjeanneau = open(vol)
                tjeanneau = fjeanneau.read() + "<a name";
                fjeanneau.close()
                regex = re.compile('<a name="' + K + '">(.*?)<a name',  (re.I | re.S))
                article = regex.findall(tjeanneau)
                for iart in range(len(article)):
                        article[iart] = re.sub('(<LI>|</LI>|<li>|</li>)', '', article[iart])
                        retour = retour + article[iart]
                retour = retour + '</li>'
        retour = retour + '</ol>\n'
    return retour


# =====================================================
# lemmatisation d'un texte, retour type liste
# =====================================================

def listelemmes(t):
   """renvoie dans une liste de chaines 
      le lexique utilisé par le texte t."""
   retour = []
   # équivalences j->i et v->u
   t = ijuv(t)
   # requete d'analyse morpho :
   # suppression de la ponctuation et du texte entre [], mise en tableau
   t = re.sub('\[.*\]','', t)
   # ajout d'espaces en début et fin pour assurer la mise en tableau
   # des premier et dernier mots.
   t = " " + t + " "
   tableau = re.split('[^a-zA-Z]', t)
   # lemmatisation de chaque mot
   for iTab in range(len(tableau)):
       f = tableau[iTab]
       lignes = analysesDe(f)
       if lignes == {}:              
           # essayer en minuscules
           lignes = analysesDe(ijuv(string.lower(f)))
       # essais suffixes
       if f[-3:] == 'que':
           lignes.update(analysesDe(f[:-3]))
       if lignes == {}:
           L = f + ' : ?'
           try:
              retour.index(L)
           except:
              retour.append(L)
       else:
           for iLin in range(len(lignes)):
               L = lexique[lignes.keys()[iLin]].doc()
               try:
                   retour.index(L)
               except:
                   retour.append(L)
   # tri et ajout au résultat
   retour.sort()
   # éliminer le : ? en première ligne.
   del retour[0]
   for i in range(len(retour)):
         retour.append(retour[i])
   return retour

def lemmatise_fichier(f):
   """lemmatisation d'un fichier, retour texte."""
   fichier = open(f)
   t = fichier.read()
   liste = listelemmes(t)
   for l in range(len(liste)):
      print liste[l]

def lemmatiseMBrut(mot):
      """ lemmatisation d'un seul mot, retour liste d'objets morphos """
      mot = ijuv(mot)
      m = morphos(mot) 
      # essayer en minuscules
      lm = ijuv(string.lower(mot))
      if lm != mot:
          m.items.update(morphos(lm).items)
      # suffixes
      if lm[-3:] == 'que':
          m.items.update(morphos(lm[:-3]).items)
      elif lm[-2:] in ['ue', 'ne']: 
          m.items.update(morphos(lm[:-2]).items)
      return m

def lemmatisem(mot, format):
      """ lemmatisation d'un seul mot, retour fomaté """
      m = lemmatiseMBrut(mot)
      dico = []
      if m != {}:
         for k in m.items.keys():
             if format == 'texte':
                  L = lexique[k].doc()
             elif format == 'LaTeX':
                  L = lexique[k].docLaTeX()
             elif format == 'html':
                  L = lexique[k].dochtml()
             try:
                  dico.index(L)
             except:
                  dico.append(L)
      dico.sort()
      retour = ''
      #for i in range(len(dico)):
      for i in dico:
         retour = retour + i #+ '\n'
      return retour

def lemmatise(t, format, filtre=-1, tri=1):
   """renvoie dans un tableau html de deux colonnes
      le lexique utilisé par le texte t."""

   def filtreM(nm):
       """ si une fréquence est indiquée, ôte de la lemmatisation nm
           tous les lemmes dont la fréquence dépasse la fréquence *filtre*
       """
       # avec map() ça irait plus vite, m'enfin.
       if filtre > -1:
           for l in nm.items.keys():
                f = freq(l) 
                if f < filtre:
                    del nm.items[l]
       return nm
      
   # requête d'ajout
   if t[0:2] == 'a:':
         # séparation morpho/texte
	 tableau = re.split ('\|', t[2:])
         # mise en tableau des paramètres
	 morpho =  re.split ('[^a-zA-Z]', tableau[0]) 
	 texte = tableau[1] 
	 # morpho[0] : graphie
	 # morpho[1] : modèle
	 # morpho[2] : radical 2
	 # morpho[3] : radical 3
	 print "appel de ",morpho[0], " ", morpho[1], " ", morpho[2], " ", texte
	 return l_adde (morpho[0], morpho[1], morpho[2], morpho[2], texte)
	 
   # équivalences j->i et v->u
   t = ijuv(t)
   # requete d'analyse morpho :
   if t[0:2] == 'm:': 
          t = t[2:]
          return analyseTotale(t)

   # suppression de la ponctuation et du texte entre [], mise en tableau
   t = re.sub('\[.*\]','', t)
   # ajout d'espaces en début et fin pour assurer la mise en tableau
   # des premier et dernier mots.
   t = " %s " % (t)
   tableau = re.split('[\W]+', t) # 15/05/04 : ajouté le + après W
   # pourquoi des items vides à chaque bout ?
   dico = []
   # lemmatisation de chaque mot
   for iTab in tableau:
      # ne pas traiter une chaîne vide
      if string.strip(iTab) == '':
         continue
      # correction orthographique
      mot = ijuv(iTab)
      # lemmatisation ordinaire
      m = filtreM(morphos(mot)) 
      # essayer en minuscules
      lm = string.lower(mot)
      if lm != mot:
          nov = filtreM(morphos(lm))
          m.items.update(nov.items)
      # suffixes
      if lm[-3:] == 'que':
          nov = filtreM(morphos(lm[:-3]))
          m.items.update(nov.items)
      elif lm[-2:] in ['ue', 'ne']: 
          nov = filtreM(morphos(lm[:-2]))
          m.items.update(nov.items)
      # mise en format
      if m != {}:
         for k in m.items.keys():
             if format == 'texte':
                  L = lexique[k].doc()
             elif format == 'LaTeX':
                  L = lexique[k].docLaTeX()
             elif format == 'html':
                  L = lexique[k].dochtml()
             try:
                  dico.index(L)
             except:
                  dico.append(L)
   # tri et ajout au résultat
   if tri: dico.sort()
   # éliminer le : ? en première ligne.
   #del dico[0]
   retour = ''
   for lin in dico:
       retour += lin
   # print "%d mots lemmatisés" % len(dico)
   return retour

#~ test du module 
if __name__ == '__main__':
    dialogueAnalyse()

