#!/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
#
###############################################################################
"""

import os, string, re
print "Collatinus pour python\n  chargement du lexique..."

# manipulation de chaînes

# =====================================================
# morphologie
def Nombre(i):
   Lnombres = [' ', 'singulier', 'pluriel']
   return Lnombres[i]
    
Lmodeles = ['uita', 'amicus', 'puer', 'ager', 'templum', 
      'miles', 'ciuis', 'corpus', 'mare', 'manus', 'res',  
      'bonus', 'miser', 'pulcher', 'fortis', 'uetus', 'acer',
      'amo', 'moneo', 'lego', 'capio', 'audio', 'sum', 'eo',
      'imitor', 'uereor', 'sequor', 'patior', 'potior',
      'pronoms', 'invaria']
  
def Modele(i):  # ligne 1: 0-4; 2: 5-10; 3: 11-16; 4: 17-23; 5: 24-28; 6: 29,30
   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):
   if m == 0:
      return 'a'
   elif m in [1, 9, 11]: #== 1 or m == 9 or m == 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 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
class tdes:   
   def __init__(self, gr, c, gn, n, d, p, t, mde, v, mdl, r):
      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 (%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()
            
# =====================================================

# =====================================================
#~ classe tirregs
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

# =====================================================

# =====================================================
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
 
   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 environnemen \\begin{itemize} ou {enumerate}"""
      return '\item \\textbf{%s} %s' % (self.graphie, self.texte)

   def affiche(self):
       print self.doc()
       pass
      
   def ecris(self, f):
      """ écrit les données du lemme dans le fichier f) """
      f.write('<canon>\n')
      #f.write('<id_canon>' + self.id_canon + '</id_canon>\n')
      f.write('   <graphie>' + self.graphie + '</graphie>\n')
      f.write('   <modele>' + str(self.modele) + '</modele>\n')
      try: 
         f.write('   <R2>' + self.r2 + '</R2>\n')
      except:
	 pass
      try:
         f.write('   <R3>' + self.r3 + '</R3>\n')
      except:
         pass
      f.write('   <texte>' + self.texte + '</texte>\n')
      f.write('</canon>\n')
# =====================================================

# =====================================================
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():
   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
      else:
         #~ ajout de la forme dans la clé      
         irregs[g][len(irregs[g])] = irreg
      linea = fdata.readline()

   fdata.close()

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"
   fichier = open('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")
      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..."
   fichier = open('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..."
   fichier = open("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][0] = irreg
	    #~ ajout de la désinence dans la clé      
	 else:
	    irregs[g][len(irregs[g])] = irreg
	    #~ réinitialisation graphie et modele ont toujours une valeur   
         cas = genre = nombre = degre = personne = temps = mode = voix = '0'
   fichier.close()

   # précompilation:
   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+'\n'
      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].keys():
         linea = irr + '|'
         linea += irregs[irr][i].canon + '|' + str(irregs[irr][i].cas)+'|' 
         linea += str(irregs[irr][i].genre) + '|'\
	    + str(irregs[irr][i].nombre)+'|'
         linea += str(irregs[irr][i].personne) +'|'\
	    +str(irregs[irr][i].temps)+'|'
         linea += str(irregs[irr][i]. mode)+'|'+str(irregs[irr][i].voix)+'|'\
           + str(irregs[irr][i].modele) + '\n'
      fpre.write(linea)
   fpre.write('---finis---')
   fpre.close()

# 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() 

print "  ", len(lexique), " entrees ;"
print len(desinences), " desinences ;"
print len(radicaux[2]), "radicaux 2 ;"
print len(radicaux[3]), "radicaux 3 ;"
print len(irregs), "irreguliers."

# =====================================================
# 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(entete)
   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
def analysesDe(mot):
   resultat = {}
   #~ chercher les formes canoniques
   if lexique.has_key(mot):
      resultat[mot] = []
      resultat[mot].append(MorphoK(lexique[mot].modele))
   if lexique.has_key(mot + ' (2)'):
      mot = mot + ' (2)'
      resultat[mot] = []
      resultat[mot].append(MorphoK(lexique[mot].modele))
   #~ chercher les formes irrégulières
   if irregs.has_key(mot):
      for iIrr in range(len(irregs[mot])):
         Irr = irregs[mot][iIrr]
         if not resultat.has_key(Irr.canon):
            resultat[Irr.canon] = []
         resultat[Irr.canon].append(Irr.morpho())   
   # 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]
            grMorpho = Des.morpho()
            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:
                     #~ si la clé n'existe pas dans resultat
                        if not resultat.has_key(radix[iRad].canon):
                            resultat[radix[iRad].canon] = []
                            resultat[radix[iRad].canon].append(grMorpho)                         
                        else:
                           resultat[radix[iRad].canon].append(grMorpho)
            else: # if Des[iDes].modele > 13:
               K = grRad + DesK(Des.modele)     
               if lexique.has_key(K)\
                  and Des.modele == lexique[K].modele:
                     if not resultat.has_key(K):
                        resultat[K] = []     
                        resultat[K].append(grMorpho)
                     else: 
                        resultat[K].append(grMorpho)
               if lexique.has_key(K + ' (2)')\
                  and Des.modele == lexique[K + ' (2)'].modele:
                     K = K + ' (2)'
                     if not resultat.has_key(K):
                        resultat[K] = []     
                        resultat[K].append(grMorpho)
                     else: 
                        resultat[K].append(grMorpho)
   return resultat

# =====================================================
#~ chaîne de retour d'une analyse

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

def chaineAnalyse(forme):
    f = ijuv(forme)
    res = analysesDe(f)
    if res == {}:
        return "?"
    else  :
        retour = ""
        for i in range(len(res)):
            K = res.keys()[i]
            retour = retour + lexique[K].doc() 
            for iK in range(len(res[K])):
                retour = retour + '    '+ res[K][iK] + '\n' 
        return retour

# =====================================================
# dialogue d'analyse morphologique

def dialogueAnalyse():
   forme = ""
   while forme != "q":
      print chaineAnalyse(forme)  
      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):
        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> : ?'
            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

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

def lemmatisem(m, format):
      """ lemmatisation d'un seul mot """
      retour = ""
      dico = [] 
      lignes = analysesDe(m)
      if lignes == {}:              
          # essayer en minuscules
          lignes = analysesDe(ijuv(string.lower(m)))
      # essais suffixes
      if m[-3:] == 'que':
         lignes.update(analysesDe(m[:-3]))
      if lignes == {}:
	 if format == 'texte':
	        L = m + ' : ?'
	 elif format == 'html':
                L = '<li><b>' + m + '</b> : ?</li>'
	 elif format == 'LaTeX':
	        L = '\item \\textbf{' + m + '} : --'
         try:
                dico.index(L)
         except:
                dico.append(L)
      else:
         for iLin in range(len(lignes)):
	        if format == 'texte':
                   L = lexique[lignes.keys()[iLin]].doc()
		elif format == 'html':
                   L = lexique[lignes.keys()[iLin]].dochtml()
		else: 
                   L = lexique[lignes.keys()[iLin]].docLaTeX()
                try:
                   dico.index(L)
                except:
                   dico.append(L)
      # tri et ajout au résultat
      dico.sort()
      # éliminer le : ? en première ligne.
      for i in range(len(dico)):
         retour = retour + dico[i] + '\n'
      return retour


# =====================================================
# lemmatisation d'un texte, retour en html.
			    
def lemmatise(t, format):
   """renvoie dans un tableau html de deux colonnes
      le lexique utilisé par le texte t."""
   # 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 = " " + t + " "
   tableau = re.split('[\W]', t)
   # pourquoi des items vides à chaque bout ?
   retour = ''
   dico = []
   # 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 == {}:
	     if format == 'texte':
	        L = f + ' : ?'
	     elif format == 'html':
                L = '<li><b>' + f + '</b> : ?</li>'
	     elif format == 'LaTeX':
	        L = '\item \\textbf{' + f + '} : --'
             try:
                dico.index(L)
             except:
                dico.append(L)
          else:
             for iLin in range(len(lignes)):
	        if format == 'texte':
                   L = lexique[lignes.keys()[iLin]].doc()
		elif format == 'html':
                   L = lexique[lignes.keys()[iLin]].dochtml()
		else: 
                   L = lexique[lignes.keys()[iLin]].docLaTeX()
                try:
                   dico.index(L)
                except:
                   dico.append(L)
   # tri et ajout au résultat
   dico.sort()
   # éliminer le : ? en première ligne.
   del dico[0]
   for i in range(len(dico)):
         retour = retour + dico[i]
   return retour

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

