### chars.tcl - 
# regroupe les procédure de manipulation/conversion de caractères 
# 
# 
# Historique 
# - 27/07/01 (diam) : création 
# - 15/09/01 (diam) : complété par euro... 
# 
# $Id :            $
# $Date :          $
# $Revision :      $
 
###########################################################################

package provide stead 2.0

## chars -- retourne les caractères iso définis par une liste de noms
# 
# param@ args : une liste de liste de mots clés (sans espace) définissant 
#        un caractere
#        Ceci permet de passer au choix plusieurs élements, ou une liste 
#        liste de plusieurs éléments.
# 
# 
# Chaque chaine peut représente le code ascii en décimal, 
#  octal ou hexa
# 
# Cette procédure sera de plus en plus tolérante et
# permettra d'obtenir les caracteres à partir de n'importe que 
# informations :
#   - valeur décimal, octal ou hexa du caractere iso
#   - nom (standard iso) même avec des fautes d'orthographe
#   - abbréviations telle que vb ou bv ou pipe pour la barre vertical
# 
# Des options seront ajouter pour choisir le formatage de sortie.
# 
# Principe :
#   on construit un table (non bijectif) associant un clé 
#   dont une liste est passée en parametre) et la valeur du caractere 
#   à retourner.
# 
# Exemple :
#     chars ob    => retourne le caractere <leftBrace> (pour Open Brace)
#     chars 0101  => A
#     chars o101  => A
#     chars x41   => A
#     chars eacute eacute {eacute eacute}         => éééé
#     chars eacute pipe bar {124  x7c} egrave     => é||||è
#     chars bidon  => bidon
#     chars euro  => \u20AC  (caractère unicode)
#     chars < ( n   l L N   ) >  n N l L          => [{~||~}]
# 
proc chars { args } {
    
    set charsNames [join [join $args]]
    
    global charsData

    # On commence (une seule fois à construire un tableau de caracteres
    if {![info exists charsData(x41)]} {
        charsInit
    }
    
    set buf ""
    foreach key  $charsNames  {
        if {[info exists charsData($key)]} {
            append buf $charsData($key)
        } else {
        
            # que faut-il faire si on ne trouve pas ?
            # - lever une exception ?
            # - écrire un caractere arbitraire ("?") pour ce code ?
            # - ne rien dire ni retourner pour ce code
            # - retourner la chaine d'entrée ?
            # Je choisis de retourner la chaine d'entrée.
            # 
            append buf $key
        }
    }
    
    return $buf
}
proc charsInit {} {
    
    global charsData

    # 1 - On commence pour remplir la table avec les info ascii (iso...) 
    # 
    #        set charsData(65)   "A"
    #        set charsData(0101) "A"
    #        set charsData(o101) "A"
    #        set charsData(x41)  "A"
    #     
    for {set i 1} {$i <= 255} {incr i} {
    
        set charsData([format  %d  $i])  [format %c  $i]
        set charsData([format 0%o  $i])  [format %c  $i] ;# chiffre 0
        set charsData([format o%o  $i])  [format %c  $i] ;# caractere o
        set charsData([format x%x  $i])  [format %c  $i]

    }
    
    # 2 - rajouter tous les noms du type html
    # 
    foreach {htmlEntity dec * * *} \
            [char_getList5__htmlEntity_dec_hex_char_comment]    {
        set charsData($htmlEntity) [format %c  $dec] 
    }
    
    # 2 - rajouter des noms de symbole Tk (ie. Xwindows ?)
    # 
    foreach {keySym dec * } [char_getList3__tkKeySym_dec_hex]    {
        set charsData($keySym) [format %c  $dec] 
    }
    
    
    
    # 3 - quelques noms à la main
    # 
    array set charsData {
        beginbrace     "\{"
        bb             "\{"
        ob             "\{"
        (              "\{"
   
        endbrace       {\}}
        eb             {\}}
        cb             {\}}
        )              {\}}
       
        beginbracket   {[}
        br             {[}
        <              {[}
   
        endbracket     {]}
        er             {]}
        >              {]}
       
        tab            "\t"
        ht             "\t"
        vt             "\v"
       
        cr             "\r"
        lf             "\n"
       
        backslash      "\\"
        bs             "\\"
        /              "\\"
       
        numbersign     {#}
        diese          {#}
        =              {#}
       
        arobas         {@}
        at             {@}
        a              {@}
   
        pipe           {|}
        bv              |
        L              {|}
        l              {|}
   
        pourcent       {%}
        pc             {%}
   
        tilda          ~
        tilde          ~
        N              ~
        n              ~
    }
    
    # Quelques caracteres unicodes importants
    array set charsData {
        euro  \u20AC
        $     \u20AC
    }
    
}



## c2i -- convertion d'un caractère en entier
# 
proc c2i c {
    scan $c "%c" myInteger 
    set myInteger
}
## c2i -- convertion d'un caractère en hexa
# 
proc c2h c {
    scan $c "%c" myInteger 
    set myHexaInteger [format {%x} $myInteger]
}
## i2c -- convertion d'un décimal en caractère
# 
proc i2c i {
    format %c $i
}


########################################################################
# Suive deux longues procédures qui retourne deux grandes listes
########################################################################
# 

## char_getList5__htmlEntity_dec_hex_char_comment --  
#       retourne une liste5 des 128 caracteres 8 bits de html 
# 
# On crée un liste (multiple de 5) mémorisant toutes infos sur les caracteres
# html (entity)
# Cette liste peut etre exploitée comme données de référence pour de futures
# fonctionnalités (procédure plus générale de conversion...)
# 
# Référence : doc de référence de HTML
# 
proc char_getList5__htmlEntity_dec_hex_char_comment {  } {
     
     # 
     #   name     dec  hex      ascii  comment 
     # 
     set entity_list5 {
                                                    
         nbsp     160  xA0      " "    "non-break space"             
         iexcl    161  xA1      ¡      "inverted exclamation mark"   
         cent     162  xA2      ¢      "cent sign"                   
         pound    163  xA3      £      "pound sign"                  
         curren   164  xA4      ¤      "currency sign"               
         yen      165  xA5      ¥      "yen sign = yuan sign"        
         brvbar   166  xA6      ¦      "broken vertical bar"         
         sect     167  xA7      §      "section sign"                
         uml      168  xA8      ¨      "diaeresis"                   
         copy     169  xA9      ©      "copyright sign"              
         ordf     170  xAA      ª      "feminine ordinal indicator"  
         laquo    171  xAB      «      "left pointing guillemet"     
         not      172  xAC      ¬      "not sign"                    
         shy      173  xAD      ­      "soft hyphen"                 
         reg      174  xAE      ®      "registered sign"             
         macr     175  xAF      ¯      "macron = overline"           
         deg      176  xB0      °      "degree sign"                 
         plusmn   177  xB1      ±      "plus-or-minus sign"          
         sup2     178  xB2      ²      "superscript digit two"    
         sup3     179  xB3      ³      "superscript digit three"   
         acute    180  xB4      ´      "spacing acute"               
         micro    181  xB5      µ      "micro sign"                  
         para     182  xB6      ¶      "paragraph sign"              
         middot   183  xB7      ·      "middle dot"                  
         cedil    184  xB8      ¸      "cedilla = spacing cedilla"   
         sup1     185  xB9      ¹      "superscript digit one"       
         ordm     186  xBA      º      "masculine ordinal indicator" 
         raquo    187  xBB      »      "right pointing guillemet"    
         frac14   188  xBC      ¼      "fraction one quarter"        
         frac12   189  xBD      ½      "fraction one half"           
         frac34   190  xBE      ¾      "fraction three quarters"     
         iquest   191  xBF      ¿      "inverted question mark"      
         Agrave   192  xC0      À      "A grave"                     
         Aacute   193  xC1      Á      "A acute"                     
         Acirc    194  xC2      Â      "A circumflex"                
         Atilde   195  xC3      Ã      "A tilde"                     
         Auml     196  xC4      Ä      "A diaeresis"                 
         Aring    197  xC5      Å      "A ring above"                
         AElig    198  xC6      Æ      "AE ligature"                 
         Ccedil   199  xC7      Ç      "C cedilla"                   
         Egrave   200  xC8      È      "E grave"                     
         Eacute   201  xC9      É      "E acute"                     
         Ecirc    202  xCA      Ê      "E circumflex"                
         Euml     203  xCB      Ë      "E diaeresis"                 
         Igrave   204  xCC      Ì      "I grave"                     
         Iacute   205  xCD      Í      "I acute"                     
         Icirc    206  xCE      Î      "I circumflex"                
         Iuml     207  xCF      Ï      "I diaeresis"                 
         ETH      208  xD0      Ð      "ETH letter"                  
         Ntilde   209  xD1      Ñ      "N tilde"                     
         Ograve   210  xD2      Ò      "O grave"                     
         Oacute   211  xD3      Ó      "O acute"                     
         Ocirc    212  xD4      Ô      "O circumflex"                
         Otilde   213  xD5      Õ      "O tilde"                     
         Ouml     214  xD6      Ö      "O diaeresis"                 
         times    215  xD7      ×      "multiplication sign"         
         Oslash   216  xD8      Ø      "O slash"                     
         Ugrave   217  xD9      Ù      "U grave"                     
         Uacute   218  xDA      Ú      "U acute"                     
         Ucirc    219  xDB      Û      "U circumflex"                
         Uuml     220  xDC      Ü      "U diaeresis"                 
         Yacute   221  xDD      Ý      "Y acute"                     
         THORN    222  xDE      Þ      "THORN letter"                
         szlig    223  xDF      ß      "sharp s"                     
         agrave   224  xE0      à      "a grave"                     
         aacute   225  xE1      á      "a acute"                     
         acirc    226  xE2      â      "a circumflex"                
         atilde   227  xE3      ã      "a tilde"                     
         auml     228  xE4      ä      "a diaeresis"                 
         aring    229  xE5      å      "a ring"                      
         aelig    230  xE6      æ      "ae ligature"                 
         ccedil   231  xE7      ç      "c cedilla"                   
         egrave   232  xE8      è      "e grave"                     
         eacute   233  xE9      é      "e acute"                     
         ecirc    234  xEA      ê      "e circumflex"                
         euml     235  xEB      ë      "e diaeresis"                 
         igrave   236  xEC      ì      "i grave"                     
         iacute   237  xED      í      "i acute"                     
         icirc    238  xEE      î      "i circumflex"                
         iuml     239  xEF      ï      "i diaeresis"                 
         eth      240  xF0      ð      "eth letter"                  
         ntilde   241  xF1      ñ      "n tilde"                     
         ograve   242  xF2      ò      "o grave"                     
         oacute   243  xF3      ó      "o acute"                     
         ocirc    244  xF4      ô      "o circumflex"                
         otilde   245  xF5      õ      "o tilde"                     
         ouml     246  xF6      ö      "o diaeresis"                 
         divide   247  xF7      ÷      "division sign"               
         oslash   248  xF8      ø      "o slash"                     
         ugrave   249  xF9      ù      "u grave"                     
         uacute   250  xFA      ú      "u acute"                     
         ucirc    251  xFB      û      "u circumflex"                
         uuml     252  xFC      ü      "u diaeresis"                 
         yacute   253  xFD      ý      "y acute"                     
         thorn    254  xFE      þ      "thorn letter"                
         yuml     255  xFF      ÿ      "y diaeresis"
    }
    
    # Cette ligne permet :
    #   - de détecter une erreur juste par modifiaction (rare) de cette liste
    #   - précompiler la chaine <entity_list5> et la transformer en Liste
    # 
    if {[llength $entity_list5] % 5 != 0 } {
        error {
            List "entity_list5" in char_getList5__htmlEntity_dec_hex_char_comment 
            procedure must by multiple of 5.
        }
    }
    return $entity_list5
}

## char_getList3__tkKeySym_dec_hex_comment --  
#    retourne une liste3 des symboles de caracteres utilisés par tk 
#    (version >= 8.3.3) : TkCmd/keysyms.htm  acessible depuis le man 
#    de bind.
#    
#    Cette méthode ne contient que les caracteres de code inférieure à 256
#    Y compris les caracteres de controle et au caractere ascii 
#    spéciaux  de code inféreur à 128.#
#    (mais pas les caractères alphanumériques standards)
# 
# 
# Cette liste est extraite du manuel de tk peut etre exploitée comme 
# données de référence pour de futures
# fonctionnalités (procédure plus générale de conversion...)
# 
# Référence : 
#   manuel de Tk : TkCmd/keysyms.htm (version >= 8.3.3 !)
#   On peut y accéder par la commande bind.
# 
proc char_getList3__tkKeySym_dec_hex {  } {
     
     # 
     #    keySym          dec     hex  
     # 
     set tkKeySym_list3 {
        space              32     x20
        exclam             33     x21
        quotedbl           34     x22
        numbersign         35     x23
        dollar             36     x24
        percent            37     x25
        ampersand          38     x26
        quoteright         39     x27
        parenleft          40     x28
        parenright         41     x29
        asterisk           42     x2a
        plus               43     x2b
        comma              44     x2c
        minus              45     x2d
        period             46     x2e
        slash              47     x2f

        colon              58     x3a
        semicolon          59     x3b
        less               60     x3c
        equal              61     x3d
        greater            62     x3e
        question           63     x3f
        at                 64     x40

        bracketleft        91     x5b
        backslash          92     x5c
        bracketright       93     x5d
        asciicircum        94     x5e
        underscore         95     x5f
        quoteleft          96     x60

        braceleft         123     x7b
        bar               124     x7c
        braceright        125     x7d
        asciitilde        126     x7e
        nobreakspace      160     xa0
        exclamdown        161     xa1
        cent              162     xa2
        sterling          163     xa3
        currency          164     xa4
        yen               165     xa5
        brokenbar         166     xa6
        section           167     xa7
        diaeresis         168     xa8
        copyright         169     xa9
        ordfeminine       170     xaa
        guillemotleft     171     xab
        notsign           172     xac
        hyphen            173     xad
        registered        174     xae
        macron            175     xaf
        degree            176     xb0
        plusminus         177     xb1
        twosuperior       178     xb2
        threesuperior     179     xb3
        acute             180     xb4
        mu                181     xb5
        paragraph         182     xb6
        periodcentered    183     xb7
        cedilla           184     xb8
        onesuperior       185     xb9
        masculine         186     xba
        guillemotright    187     xbb
        onequarter        188     xbc
        onehalf           189     xbd
        threequarters     190     xbe
        questiondown      191     xbf
        Agrave            192     xc0
        Aacute            193     xc1
        Acircumflex       194     xc2
        Atilde            195     xc3
        Adiaeresis        196     xc4
        Aring             197     xc5
        AE                198     xc6
        Ccedilla          199     xc7
        Egrave            200     xc8
        Eacute            201     xc9
        Ecircumflex       202     xca
        Ediaeresis        203     xcb
        Igrave            204     xcc
        Iacute            205     xcd
        Icircumflex       206     xce
        Idiaeresis        207     xcf
        Eth               208     xd0
        Ntilde            209     xd1
        Ograve            210     xd2
        Oacute            211     xd3
        Ocircumflex       212     xd4
        Otilde            213     xd5
        Odiaeresis        214     xd6
        multiply          215     xd7
        Ooblique          216     xd8
        Ugrave            217     xd9
        Uacute            218     xda
        Ucircumflex       219     xdb
        Udiaeresis        220     xdc
        Yacute            221     xdd
        Thorn             222     xde
        ssharp            223     xdf
        agrave            224     xe0
        aacute            225     xe1
        acircumflex       226     xe2
        atilde            227     xe3
        adiaeresis        228     xe4
        aring             229     xe5
        ae                230     xe6
        ccedilla          231     xe7
        egrave            232     xe8
        eacute            233     xe9
        ecircumflex       234     xea
        ediaeresis        235     xeb
        igrave            236     xec
        iacute            237     xed
        icircumflex       238     xee
        idiaeresis        239     xef
        eth               240     xf0
        ntilde            241     xf1
        ograve            242     xf2
        oacute            243     xf3
        ocircumflex       244     xf4
        otilde            245     xf5
        odiaeresis        246     xf6
        division          247     xf7
        oslash            248     xf8
        ugrave            249     xf9
        uacute            250     xfa
        ucircumflex       251     xfb
        udiaeresis        252     xfc
        yacute            253     xfd
        thorn             254     xfe
        ydiaeresis        255     xff
    }
                                                    
    # 
    # Cette ligne permet :
    #   - de détecter une erreur juste par modifiaction (rare) de cette liste
    #   - précompiler la chaine <tkKeySym_list3> et la transformer en Liste
    # 
    if {[ llength $tkKeySym_list3] % 3 != 0 } {
        error {
            List "tkKeySym_list3" in char_getList3__tkKeySym_dec_hex 
            procedure must by multiple of 5.
        }
    }
    return $tkKeySym_list3
}
# ./
