home *** CD-ROM | disk | FTP | other *** search
/ Dream 52 / Amiga_Dream_52.iso / Linux / Divers / lyx-0.13.2.tar.gz / lyx-0.13.2.tar / lyx-0.13.2 / src / trans.C < prev    next >
C/C++ Source or Header  |  1998-04-23  |  7KB  |  406 lines

  1. #include <config.h>
  2.  
  3. #include <stdio.h>
  4.  
  5. #ifdef __GNUG__
  6. #pragma implementation "trans.h"
  7. #endif
  8.  
  9. #include "LyXView.h"
  10. #include "trans.h"
  11. #include "filetools.h"
  12. #include "tex-strings.h"
  13. #include "lyxlex.h"
  14. #include "error.h"
  15. #include "trans_mgr.h"
  16.  
  17.  
  18. // KmodInfo
  19. KmodInfo::KmodInfo()
  20. {
  21.     exception_list=NULL;
  22. }
  23.  
  24.  
  25. KmodInfo::KmodInfo(const KmodInfo& o)
  26. {
  27.     (*this)=o;
  28. }
  29.  
  30.  
  31. KmodInfo& KmodInfo::operator=(const KmodInfo& o)
  32. {
  33.     if (this!=&o) {
  34.         allowed=o.allowed;
  35.         accent=o.accent;
  36.         data=o.data;
  37.         exception_list=o.exception_list;
  38.     }
  39.  
  40.     return *this;
  41. }
  42.  
  43.     
  44. // Default Trans
  45. bool DefaultTrans::init_=false;
  46.  
  47.  
  48. DefaultTrans::DefaultTrans()
  49. {
  50.     if (init_==false) {
  51.         // Do initialization
  52.         init_=true;
  53.     }
  54. }
  55.  
  56.  
  57. LString DefaultTrans::process(char c,TransManager& k)
  58. {
  59.     char dummy[2]="?";
  60.     dummy[0]=c;
  61.     
  62.     return k.normalkey(c,dummy);
  63. }
  64.  
  65.  
  66. // Trans class
  67.  
  68. Trans::Trans()
  69. {
  70.     int i;
  71.  
  72.     for(i=0; i<256; i++)
  73.         keymap_[i]=NULL;
  74.  
  75.     for(i=0; i<TEX_MAX_ACCENT+1; i++)
  76.         kmod_list_[i]=0;
  77. }
  78.  
  79.  
  80. Trans::~Trans()
  81. {
  82.     FreeKeymap();
  83. }
  84.  
  85.  
  86. void Trans::InsertException(Trans::keyexc& exclist, char c,
  87.                 const LString& data,bool flag,tex_accent accent)
  88. {
  89.     keyexc p;
  90.  
  91.     p = new Keyexc; 
  92.     p -> next = exclist;
  93.     p -> c = c;
  94.  
  95.     p->data = data;
  96.     p->combined=flag;
  97.     p->accent=accent;
  98.  
  99.     exclist = p;
  100. }
  101.  
  102.  
  103. void Trans::FreeException(Trans::keyexc& exclist)
  104. {
  105.     Trans::keyexc p;
  106.  
  107.     p = exclist;
  108.     while (p) {
  109.         p = exclist->next;
  110.         delete exclist;
  111.         exclist = p;
  112.     }
  113. }
  114.  
  115.  
  116. void Trans::FreeKeymap()
  117. {
  118.     int i;
  119.  
  120.     for(i=0; i<256; i++)
  121.         if (keymap_[i]) {
  122.             delete keymap_[i];
  123.             keymap_[i]=NULL;
  124.         }
  125.     for(i=0; i<TEX_MAX_ACCENT+1; i++)
  126.         if (kmod_list_[i]) {
  127.             FreeException(kmod_list_[i]->exception_list);
  128.             delete kmod_list_[i];
  129.             kmod_list_[i]=0;
  130.         }
  131. }
  132.  
  133.  
  134. bool Trans::IsDefined()
  135. {
  136.     return !name_.empty();
  137. }
  138.  
  139.  
  140. const LString& Trans::GetName()
  141. {
  142.     return name_;
  143. }
  144.  
  145.  
  146. enum _kmaptags {
  147.     KCOMB=1,
  148.     KMOD,
  149.     KMAP,
  150.     KXMOD,
  151.     K_LAST
  152. };
  153.  
  154.  
  155. struct keyword_item kmapTags[K_LAST-1] = {
  156.     {"\\kcomb",KCOMB },
  157.     { "\\kmap", KMAP },
  158.     { "\\kmod", KMOD },
  159.     { "\\kxmod", KXMOD }
  160. };
  161.  
  162.  
  163. tex_accent getkeymod(const LString&);
  164.  
  165.  
  166. void Trans::AddDeadkey(tex_accent accent,const LString& keys,
  167.                const LString& allowed)
  168. {
  169.     if (kmod_list_[accent]) {
  170.         FreeException(kmod_list_[accent]->exception_list);
  171.         
  172.         delete kmod_list_[accent];
  173.     }
  174.     
  175.     kmod_list_[accent] = new kmod_list_decl;
  176.     kmod_list_[accent]->data = keys;
  177.     kmod_list_[accent]->accent = accent;
  178.     if (allowed=="all") { 
  179.         kmod_list_[accent]->allowed=lyx_accent_table[accent].native;
  180.     } else { 
  181.         kmod_list_[accent]->allowed = allowed;
  182.     }
  183.     
  184.     for(int i=0;i<keys.length();i++) {
  185.         char *temp;
  186.         temp=keymap_[(unsigned char)keys[i]]=new char[2];
  187.         temp[0]=0; temp[1]=accent;
  188.     }
  189.     kmod_list_[accent]->exception_list=NULL;
  190. }
  191.  
  192.  
  193. int Trans::Load(LyXLex &lex)
  194. {
  195.     bool error = false;
  196.  
  197.     while (lex.IsOK() && !error) {
  198.         switch(lex.lex()) {
  199.         case KMOD:
  200.         {
  201.             if (lyxerr.debugging(Error::KBMAP))
  202.                 fprintf(stderr,"KMOD:    %s\n",lex.text());
  203.             if (lex.next(true)) {
  204.                 if (lyxerr.debugging(Error::KBMAP))
  205.                     fprintf(stderr, "key     `%s'\n", lex.text());
  206.             } else
  207.                 return -1;
  208.             
  209.             LString keys = lex.GetString();
  210.  
  211.             if (lex.next(true)) {
  212.                 if ( lyxerr.debugging(Error::KBMAP))
  213.                     fprintf(stderr, "accent     `%s'\n", lex.text());
  214.             } else
  215.                 return -1;
  216.  
  217.             tex_accent accent = getkeymod(lex.GetString());
  218.  
  219.             if (accent==TEX_NOACCENT)
  220.                 return -1;
  221.  
  222.             if (lex.next(true)) {
  223.                 if (lyxerr.debugging(Error::KBMAP))
  224.                     fprintf(stderr,
  225.                         "allowed     `%s'\n",
  226.                         lex.text());
  227.             } else
  228.                 return -1;
  229.  
  230.             LString allowed = lex.GetString();
  231.  
  232.             AddDeadkey(accent, keys, allowed);
  233.             break;
  234.         }    
  235.         case KCOMB: {
  236.             const char *str;
  237.  
  238.             lyxerr.debug("KCOMB:",Error::KBMAP);
  239.             if (lex.next(true)) {
  240.                 str=lex.text();
  241.                 lyxerr.debug(str,Error::KBMAP);
  242.             } else
  243.                 return -1;
  244.             
  245.             tex_accent accent_1=getkeymod(str);
  246.             if (accent_1==TEX_NOACCENT) return -1;
  247.  
  248.             if (lex.next(true)) {
  249.                 str=lex.text();
  250.                 lyxerr.debug(str,Error::KBMAP);
  251.             } else
  252.                 return -1;
  253.  
  254.             tex_accent accent_2=getkeymod(str);
  255.             if (accent_2==TEX_NOACCENT) return -1;
  256.  
  257.             if (kmod_list_[accent_1]==NULL || kmod_list_[accent_2]==NULL)
  258.                 return -1;
  259.  
  260.             // Find what key accent_2 is on - should check about accent_1 also
  261.             int key;
  262.  
  263.             for(key=0;key<256;key++) 
  264.                 if (keymap_[key] && keymap_[key][0]==0 && keymap_[key][1]==accent_2)
  265.                     break;
  266.             
  267.             LString allowed;
  268.  
  269.             if (lex.next()) {
  270.                 allowed=lex.GetString();
  271.                 lyxerr.debug("allowed: "+allowed,Error::KBMAP);
  272.             } else
  273.                 return -1;
  274.  
  275.             InsertException(kmod_list_[accent_1]->exception_list,(char)key,allowed,true,accent_2);
  276.         }
  277.         break;
  278.         case KMAP: {
  279.             char key_from;
  280.             char *string_to;
  281.  
  282.             if (lyxerr.debugging(Error::KBMAP))
  283.                 fprintf(stderr, "KMAP: %s\n", lex.text());
  284.             if (lex.next(true)) {
  285.                 key_from=lex.text()[0];
  286.                 if (lyxerr.debugging(Error::KBMAP))
  287.                     fprintf(stderr, "     `%s'\n", lex.text());
  288.             } else
  289.                 return -1;
  290.  
  291.             if (lex.next(true)) {
  292.                 char const *t = lex.text();
  293.                 string_to = strcpy(new char[strlen(t)+1],t);
  294.                 keymap_[(unsigned char)key_from]=string_to;
  295.                 if (lyxerr.debugging(Error::KBMAP))
  296.                     fprintf(stderr, "     `%s'\n", string_to);
  297.             } else
  298.                 return -1;
  299.  
  300.             break;
  301.         }
  302.         case KXMOD: {
  303.             tex_accent accent;
  304.             char key;
  305.             const char *str;
  306.  
  307.             if (lyxerr.debugging(Error::KBMAP))
  308.                 fprintf(stderr, "KXMOD: %s\n", lex.text());
  309.             if (lex.next(true)) {
  310.                 if (lyxerr.debugging(Error::KBMAP))
  311.                     fprintf(stderr, "     `%s'\n", lex.text());
  312.                 accent = getkeymod(lex.GetString());
  313.             } else
  314.                 return -1;
  315.  
  316.             if (lex.next(true)) {
  317.                 if (lyxerr.debugging(Error::KBMAP))
  318.                     fprintf(stderr, "      `%s'\n", lex.text());
  319.                 key=lex.text()[0];
  320.             } else
  321.                 return -1;
  322.  
  323.             if (lex.next(true)) {
  324.                 if (lyxerr.debugging(Error::KBMAP))
  325.                     fprintf(stderr, "      `%s'\n", lex.text());
  326.                 str=lex.text();
  327.             } else
  328.                 return -1;
  329.  
  330.             InsertException(kmod_list_[accent]->exception_list,key,str);
  331.             break;
  332.         }
  333.         case LyXLex::LEX_FEOF:
  334.             lyxerr.debug("End of parsing",Error::KBMAP);
  335.             break;
  336.         default:
  337.             lex.printError("ParseKeymapFile: "
  338.                        "Unknown tag: `$$Token'");
  339.             return -1;
  340.         }
  341.     }
  342.     return 0;
  343. }
  344.  
  345.  
  346. bool Trans::isAccentDefined(tex_accent accent,KmodInfo& i)
  347. {
  348.     if (kmod_list_[accent]!=NULL) {
  349.         i=*kmod_list_[accent];
  350.         return true;
  351.     }
  352.     return false;
  353. }
  354.  
  355.  
  356. LString Trans::process(char c,TransManager& k)
  357. {
  358.     char dummy[2]="?";
  359.     char *dt=dummy;
  360.     char *t=Match(c);
  361.     
  362.     
  363.     if ((t==NULL && (*dt=c)) || (t[0]!=0 && (dt=t)) ){
  364.         return k.normalkey(c,dt);
  365.     } else {
  366.         return k.deadkey(c,*kmod_list_[(tex_accent)t[1]]);
  367.     }
  368. }
  369.  
  370.  
  371. int Trans::Load(LString const &language)
  372. {
  373.     LString filename = LibFileSearch("kbd", language, "kmap");
  374.     if (filename.empty())
  375.         return -1;
  376.  
  377.     FreeKeymap();
  378.     LyXLex lex(kmapTags, K_LAST-1);
  379.     lex.setFile(filename);
  380.     
  381.     int res=Load(lex);
  382.  
  383.     if (res==0) {
  384.         name_=language;
  385.     } else
  386.         name_.erase();
  387.  
  388.     return res;
  389. }
  390.  
  391.  
  392. tex_accent getkeymod(LString const &p)
  393.     /* return modifier - decoded from p and update p */
  394. {
  395.     for (int i = 1; i <= TEX_MAX_ACCENT; i++) {
  396.         //if (lyxerr.debugging(Error::KBMAP))
  397.         //    lyxerr.print("p = " + p + ", lyx_accent_table[" + int(i) + "].name = `" + lyx_accent_table[i].name);
  398.         
  399.         if ( lyx_accent_table[i].name && p.contains(lyx_accent_table[i].name)) {
  400.             //lyxerr.debug("Found it!",Error::KBMAP);
  401.             return (tex_accent)i;
  402.         }
  403.     }
  404.     return TEX_NOACCENT;
  405. }
  406.