
int ligature_handle;
int ligature_status;


// if character is an 'i' or 'l' and previous character is an 'f', 
// delete the 'f' and substitute the ligature

int ligature_fix(int user, int view, int key)
{
 int p, c, d;

 p = prevchar();
 c = caretchar();

 // deal with 'i' or 'l' typed after 'f'
 if((key == 'i' || key == 'l') && p == 'f')
 {
  type("{Deleteb}");
  key = (key == 'i') ? '' : '';
 }

 // deal with 'f' typed before 'i' or 'l'
 if(key == 'f' && (c == 'i' || c == 'l'))
 {
  type("{Deletef}");
  key = (c == 'i') ? '' : '';
 }

 // deal with 'PC-style delete' disabled
 if((textchoicesbits() & 1) == 0)
 {
  if((key == 127 || key == 6664) && (p == '' || p == ''))
  {
   type("{Deleteb}");
   key = 'f';
  }
  if(key == 395 && (c == '' || c == ''))
  {
   type("{Deletef}" + ((c == '') ? "i" : "l"));
   key = 396;
  }
 }

 // deal with 'PC-style delete' enabled
 if((textchoicesbits() & 1) == 1)
 {
  if(key == 6664 && (p == '' || p == ''))
  {
   type("{Deleteb}");
   key = 'f';
  }
  if(key == 127 && (c == '' || c == ''))
  {
   type("{Deletef}" + ((c == '') ? "i" : "l"));
   key = 396;
  }
 }
 return(key);
}


// set up EVENT_KEYPRESS events

void ligature_setevent(int i)
{
 if(i)  
  addeventhandler(0x300, 0, "ligature_fix");
 else
  remeventhandler(0x300, 0, "ligature_fix");

 ligature_status = i;
}


// deal with 'Ligatures' menu entry

int ligature_entry(int entry, int subcode)
{
 if(subcode == -1)
  ligature_setevent(!ligature_status);
 return(0);
}


// tick or un-tick 'Ligatures' menu entry

int ligature_flags(int entry, string &text)
{
 return(ligature_status);
}


// replace 'fi' and 'fl' with ligatures

void ligature_add(void)
{
 int b1, c;

 if(activetype(TEXTFRAME) <= 1)
  return;

 b1 = bmcreate("ligature_b1");
 setbmtocaret(b1);
 bmmove(b1, 0, 4);

 while((c = bmchar(b1)))
 {
  if(bmprevchar(b1) == 'f' && (c == 'i' || c == 'l'))
  {
   setcarettobm(b1);
   type(((c == 'i') ? "" : "") + "{deletef}{CLeft}{deleteb}");
  }
  bmmove(b1, 1, 0);
 }
 bmdelete(b1);
}


// replace ligatures with 'fi' and 'fl'

void ligature_remove(void)
{
 int b1, c;

 if(activetype(TEXTFRAME) <= 1)
  return;

 b1 = bmcreate("ligature_b1");
 setbmtocaret(b1);
 bmmove(b1, 0, 4);

 while((c = bmchar(b1)))
 {
  if(c == '' || c == '')
  {
   setcarettobm(b1);
   type("{CRight}f" + ((c == '') ? "i" : "l") + "{CLeft}{CLeft}{deleteb}");
  }
  else
   bmmove(b1, 1, 0);
 }
 bmdelete(b1);
}


// deal with 'Ligatures' menu entries

int ligature_menu_entry(int entry, int subcode)
{
 switch(entry)
 {
  case 0:
         ligature_add();
         break;
  case 1:
         ligature_remove();
         break;
 }
 return(0);
}


int ligature_menu(int open)
{
 return(ligature_handle);
}


// create 'Ligatures' menu and add it to 'Applets' menu
// enable ligatures

void main(void)
{
 script_menu_initialise();

 ligature_handle = create_menu("{LIGATURE_00}");
 addentry_menu(ligature_handle, "ligature_menu_entry","","","","{LIGATURE_01}");
 addentry_menu(ligature_handle, "ligature_menu_entry","","","","{LIGATURE_02}");

 addentry_menu(script_handle,"ligature_entry","ligature_flags","ligature_menu","","{LIGATURE_00}");
 ligature_setevent(1);
}
