diff -cr w3m-0.1.11-pre/file.c w3m-0.1.11-pre.joze/file.c
*** w3m-0.1.11-pre/file.c	Wed Jun 14 12:35:40 2000
--- w3m-0.1.11-pre.joze/file.c	Wed Sep 27 08:51:48 2000
***************
*** 5239,5245 ****
--- 5239,5247 ----
  	    Strcat(tmp, lineBuf2);
  	    lineBuf2 = tmp;
  	}
+ #ifdef JP_CHARSET
  	lineBuf2 = convertLine(&uf, lineBuf2, &code);
+ #endif
  	lineBuf2 = checkType(lineBuf2->ptr, propBuffer, LINELEN);
  	len = lineBuf2->length;
  	l = New(Line);
diff -cr w3m-0.1.11-pre/fm.h w3m-0.1.11-pre.joze/fm.h
*** w3m-0.1.11-pre/fm.h	Wed Jun 14 12:26:46 2000
--- w3m-0.1.11-pre.joze/fm.h	Wed Sep 27 10:02:30 2000
***************
*** 553,558 ****
--- 553,578 ----
  #endif
  extern FuncList w3mFuncList[];
  
+ enum UserCmdType {
+     UserCmdRegular,
+     UserCmdPipe,
+ };
+ 
+ typedef struct _UserMap {
+     char c;
+     Str cmd;
+     enum UserCmdType type;
+     struct _UserMap* next;
+ } UserMap;
+ 
+ global UserMap* UserEscDMap init((UserMap*)0);
+ global UserMap* UserEscBMap init((UserMap*)0);
+ global UserMap* UserEscMap init((UserMap*)0);
+ global UserMap* UserGlobalMap init((UserMap*)0);
+ 
+ global UserMap* UserActiveKeymap init((UserMap*)0);
+ global int CurrentKey init((int)0);
+ 
  global char *HTTP_proxy init(NULL);
  global char *GOPHER_proxy init(NULL);
  global char *FTP_proxy init(NULL);
diff -cr w3m-0.1.11-pre/func.c w3m-0.1.11-pre.joze/func.c
*** w3m-0.1.11-pre/func.c	Wed Jun 14 06:28:32 2000
--- w3m-0.1.11-pre.joze/func.c	Wed Sep 27 10:17:52 2000
***************
*** 11,16 ****
--- 11,89 ----
  #include "funcname.c"
  int w3mNFuncList = 0;
  
+ UserMap*
+ user_get_from_key(UserMap* start, const int c)
+ {
+     UserMap* entry;
+     for (entry = start; entry; entry = entry->next) {
+ 	if (c == entry->c) {
+ 	    return entry;
+ 	}
+     }
+     return (UserMap*)0;
+ }
+ 
+ static UserMap*
+ user_get_last(UserMap* start)
+ {
+     UserMap* entry;
+     for (entry = start; entry && entry->next; entry = entry->next) {
+ 	/* EMPTY */
+     }
+     return entry;
+ }
+ 
+ static UserMap*
+ user_alloc_entry(void)
+ {
+     UserMap* new_entry = (UserMap*)GC_MALLOC(sizeof(UserMap));
+     new_entry->c = 0;
+     new_entry->cmd = (Str)0;
+     new_entry->type = UserCmdRegular;
+     new_entry->next = 0;
+     return new_entry;
+ }
+ 
+ static void
+ user_append_command_to_map(UserMap** map, const int c, Str cmd)
+ {
+     UserMap* new_entry;
+ 
+     if (!(*map))
+ 	new_entry = (*map) = user_alloc_entry();
+     else {
+ 	new_entry = user_get_from_key(*map, c);
+ 	if (!new_entry) {
+ 	    new_entry = user_get_last(*map)->next = user_alloc_entry();
+ 	}
+     }
+ 
+     Strremovefirstspaces(cmd);
+     Strremovetrailingspaces(cmd);
+ 
+     if ('|' == *(cmd->ptr)) {
+ 	new_entry->type = UserCmdPipe;
+ 	Strdelete(cmd, 0, 1); /* delete the trailing '|' */
+     }
+ 
+     new_entry->c = c;
+     new_entry->cmd = cmd;
+ }
+ 
+ /* dispatches between the different maps */
+ static void
+ user_append_command(const int c, Str cmd)
+ {
+     if (c & K_ESCD)
+ 	user_append_command_to_map(&UserEscDMap, c & (~K_ESCD), cmd);
+     else if (c & K_ESCB)
+ 	user_append_command_to_map(&UserEscBMap, c & (~K_ESCB), cmd);
+     else if (c & K_ESC)
+ 	user_append_command_to_map(&UserEscMap, c & (~K_ESC), cmd);
+     else
+ 	user_append_command_to_map(&UserGlobalMap, c, cmd);
+ }
+ 
  void
  initKeymap(void)
  {
***************
*** 42,49 ****
  	c = getKey(s);
  	if (c < 0)		/* error */
  	    continue;
! 	s = getWord(&p);
! 	f = getFuncList(s, w3mFuncList, w3mNFuncList);
  	if (c & K_ESCD)
  	    EscDKeymap[c - K_ESCD] = (f >= 0) ? f : FUNCNAME_nulcmd;
  	else if (c & K_ESCB)
--- 115,133 ----
  	c = getKey(s);
  	if (c < 0)		/* error */
  	    continue;
! 	SKIP_BLANKS(p);
! 	if ('\'' == *p || '\"' == *p) {
! 	    s = getQWord(&p);
! 	    f = FUNCNAME_userCmd;
! 	    if (strlen(s)) {
! 		user_append_command(c, Strnew_charp(s));
! 	    } else {
! 		f = -1;
! 	    }
! 	} else {
! 	    s = getWord(&p);
! 	    f = getFuncList(s, w3mFuncList, w3mNFuncList);
! 	}
  	if (c & K_ESCD)
  	    EscDKeymap[c - K_ESCD] = (f >= 0) ? f : FUNCNAME_nulcmd;
  	else if (c & K_ESCB)
diff -cr w3m-0.1.11-pre/funcname.c w3m-0.1.11-pre.joze/funcname.c
*** w3m-0.1.11-pre/funcname.c	Wed Jun 14 06:28:32 2000
--- w3m-0.1.11-pre.joze/funcname.c	Wed Sep 27 05:17:41 2000
***************
*** 92,96 ****
--- 92,97 ----
  /*90*/ {"VIEW_IMAGE",followI},
  /*91*/ {"WHEREIS",srchfor},
  /*92*/ {"WRAP_TOGGLE",wrapToggle},
+ /*93*/ {"\"",userCmd},
  { NULL, NULL }
  };
diff -cr w3m-0.1.11-pre/funcname1.h w3m-0.1.11-pre.joze/funcname1.h
*** w3m-0.1.11-pre/funcname1.h	Wed Jun 14 06:28:32 2000
--- w3m-0.1.11-pre.joze/funcname1.h	Wed Sep 27 05:30:10 2000
***************
*** 79,81 ****
--- 79,82 ----
  #define FUNCNAME_lup1 87
  #define FUNCNAME_followI 90
  #define FUNCNAME_wrapToggle 92
+ #define FUNCNAME_userCmd 93
diff -cr w3m-0.1.11-pre/funcname2.h w3m-0.1.11-pre.joze/funcname2.h
*** w3m-0.1.11-pre/funcname2.h	Wed Jun 14 06:28:32 2000
--- w3m-0.1.11-pre.joze/funcname2.h	Wed Sep 27 05:13:55 2000
***************
*** 79,81 ****
--- 79,82 ----
  #define lup1 87
  #define followI 90
  #define wrapToggle 92
+ #define userCmd 93
diff -cr w3m-0.1.11-pre/local.c w3m-0.1.11-pre.joze/local.c
*** w3m-0.1.11-pre/local.c	Wed Jun 14 06:28:32 2000
--- w3m-0.1.11-pre.joze/local.c	Wed Sep 27 04:25:33 2000
***************
*** 231,236 ****
--- 231,240 ----
      set_environ("REMOTE_HOST", "localhost");
      set_environ("REMOTE_ADDR", "127.0.0.1");
      set_environ("SERVER_PORT", "80");	/* dummy */
+     /* conforming to
+      *    http://Web.Golux.Com/coar/cgi/draft-coar-cgi-v11-03-clean.html
+      */
+     set_environ("GATEWAY_INTERFACE", "CGI/1.1");
  }
  
  static Str
***************
*** 334,339 ****
--- 338,344 ----
  {
      int status;
  
+     set_environ("SCRIPT_NAME", file);
      file = cgi_filename(file, &status);
      if (check_local_cgi(file, status) < 0)
  	return NULL;
diff -cr w3m-0.1.11-pre/main.c w3m-0.1.11-pre.joze/main.c
*** w3m-0.1.11-pre/main.c	Wed Jun 14 12:26:46 2000
--- w3m-0.1.11-pre.joze/main.c	Wed Sep 27 10:02:30 2000
***************
*** 609,614 ****
--- 609,616 ----
  static void
  keyPressEventProc(int c)
  {
+     UserActiveKeymap = UserGlobalMap;
+     CurrentKey = c;
      w3mFuncList[(int) GlobalKeymap[c]].func();
      onA();
  }
***************
*** 661,666 ****
--- 663,669 ----
  void
  pcmap(void)
  {
+   UserActiveKeymap = (UserMap*)0;
    w3mFuncList[PcKeymap[getch()]].func ();
  }
  #else /* not __EMX__ */
***************
*** 672,678 ****
  void
  escmap(void)
  {
!     w3mFuncList[(int) EscKeymap[(int) getch()]].func();
  }
  
  void
--- 675,684 ----
  void
  escmap(void)
  {
!     char c = getch();
!     UserActiveKeymap = UserEscMap;
!     CurrentKey = (int)c;
!     w3mFuncList[(int) EscKeymap[(int) c]].func();
  }
  
  void
***************
*** 683,690 ****
  
      if (IS_DIGIT(c))
  	escdmap(c);
!     else
  	w3mFuncList[(int) EscBKeymap[(int) c]].func();
  }
  
  void
--- 689,699 ----
  
      if (IS_DIGIT(c))
  	escdmap(c);
!     else {
! 	UserActiveKeymap = UserEscBMap;
! 	CurrentKey = (int)c;
  	w3mFuncList[(int) EscBKeymap[(int) c]].func();
+     }
  }
  
  void
***************
*** 698,705 ****
  	d = d * 10 + (int) c - (int) '0';
  	c = getch();
      }
!     if (c == '~')
  	w3mFuncList[(int) EscDKeymap[d]].func();
  }
  
  static void
--- 707,717 ----
  	d = d * 10 + (int) c - (int) '0';
  	c = getch();
      }
!     if (c == '~') {
! 	UserActiveKeymap = UserEscDMap;
! 	CurrentKey = d;
  	w3mFuncList[(int) EscDKeymap[d]].func();
+     }
  }
  
  static void
***************
*** 1600,1606 ****
      if (Currentbuf->currentLine)
  	lnum = Currentbuf->currentLine->linenumber;
      Strcat_charp(cmd, Editor);
!     if (strcasestr(Editor, "vi")) {
  	Strcat(cmd, Sprintf(" +%d", lnum));
      }
      Strcat_m_charp(cmd, " ", quoteShell(fn)->ptr, NULL);
--- 1612,1618 ----
      if (Currentbuf->currentLine)
  	lnum = Currentbuf->currentLine->linenumber;
      Strcat_charp(cmd, Editor);
!     if (strcasestr(Editor, "vi") || strcasestr(Editor, "vim")) {
  	Strcat(cmd, Sprintf(" +%d", lnum));
      }
      Strcat_m_charp(cmd, " ", quoteShell(fn)->ptr, NULL);
***************
*** 1646,1652 ****
      if (Currentbuf->currentLine)
  	lnum = Currentbuf->currentLine->linenumber;
      Strcat_charp(cmd, Editor);
!     if (strcasestr(Editor, "vi")) {
  	Strcat(cmd, Sprintf(" +%d", lnum));
      }
      Strcat_char(cmd, ' ');
--- 1658,1664 ----
      if (Currentbuf->currentLine)
  	lnum = Currentbuf->currentLine->linenumber;
      Strcat_charp(cmd, Editor);
!     if (strcasestr(Editor, "vi") || strcasestr(Editor, "vim")) {
  	Strcat(cmd, Sprintf(" +%d", lnum));
      }
      Strcat_char(cmd, ' ');
***************
*** 3553,3555 ****
--- 3565,3669 ----
      execdict(GetWord(Currentbuf));
  }
  #endif				/* DICT */
+ 
+ static int
+ _SrcToPipe(char *cmd)
+ {
+     FILE *f1, *f2;
+     char c;
+ 
+     if (!Currentbuf->sourcefile)
+ 	return -1;
+ 
+     f1 = fopen(Currentbuf->sourcefile, "rb");
+     if (f1 == NULL)
+ 	return -1;
+     f2 = popen(cmd, "w");
+     if (f2 == NULL) {
+ 	fclose(f1);
+ 	return -1;
+     }
+     while (c = getc(f1), !feof(f1)) {
+ 	putc(c, f2);
+     }
+     fclose(f1);
+     pclose(f2);
+     return 0;
+ }
+ 
+ /* NOTE: frees replacement ! */
+ static int
+ user_replace_generic(Str dest, const char id, Str replacement)
+ {
+     int count = 0;
+     int pos = 0;
+     char percent = FALSE;
+     for (pos = 0; pos < dest->length; pos++) {
+ 	if ('%' == dest->ptr[pos]) {
+ 	    percent = (TRUE == percent ? FALSE : TRUE);
+ 	    continue;
+ 	} else if (TRUE == percent) {
+ 	    percent = FALSE;
+ 	    if (id == dest->ptr[pos]) {
+ 		count++;
+ 		Strdelete(dest, pos - 1, 2 /* % and id */);
+ 		Strinsert(dest, pos - 1, replacement);
+ 	    }
+ 	}
+     }
+     Strfree(replacement);
+     return count;
+ }
+ 
+ static int
+ user_replace_int(Str dest, const char id, int i)
+ {
+     Str replacement = Sprintf("%d", i);
+     return user_replace_generic(dest, id, replacement);
+ }
+ 
+ static int
+ user_replace_charp(Str dest, const char id, char* charp)
+ {
+     Str replacement = Sprintf("%s", charp);
+     return user_replace_generic(dest, id, replacement);
+ }
+ 
+ void
+ userCmd(void)
+ {
+     UserMap* entry = user_get_from_key(UserActiveKeymap, CurrentKey);
+ 
+     if (entry) {
+ 
+ 	int lnum = 0;
+ 	if (Currentbuf->currentLine)
+ 	    lnum = Currentbuf->currentLine->linenumber;
+ 
+ 	fmTerm();
+ 	switch (entry->type) {
+ 	    case UserCmdPipe:
+ 		_SrcToPipe(entry->cmd->ptr);
+ 		break;
+ 	    case UserCmdRegular:
+ 		/* FALLTHRU */
+ 	    default:
+ 		if (Currentbuf->sourcefile) {
+ 		    Str cmd = Strdup(entry->cmd);
+ 		    user_replace_charp(cmd, 's', Currentbuf->sourcefile);
+ 		    user_replace_int(cmd, 'd', lnum);
+ 		    user_replace_charp(cmd, 'u', parsedURL2Str(&Currentbuf->currentURL)->ptr);
+ 		    /* TODO: more replacements here ? */
+ 		    system(cmd->ptr);
+ 		    Strfree(cmd);
+ 		}
+ 		break;
+ 	}
+ 	fmInit();
+ 
+ 	gotoLine(Currentbuf, lnum);
+ 	arrangeCursor(Currentbuf);
+ 
+ 	displayBuffer(Currentbuf, B_FORCE_REDRAW);
+     }
+ }
diff -cr w3m-0.1.11-pre/proto.h w3m-0.1.11-pre.joze/proto.h
*** w3m-0.1.11-pre/proto.h	Wed Jun 14 12:26:46 2000
--- w3m-0.1.11-pre.joze/proto.h	Wed Sep 27 06:18:45 2000
***************
*** 492,494 ****
--- 492,497 ----
  extern void saveBufferInfo(void);
  extern char*get_os2_dft(const char*,char*);
  #include "indep.h"
+ 
+ extern void userCmd(void);
+ extern UserMap* user_get_from_key(UserMap* map, const int c);

