*** /dev/null	Mon Sep 13 19:19:47 1993
--- xdvi-pl17+miyu.patch-beta4+markpage+toc+printdvi/README.markpage+toc+printdvi	Mon Sep 13 22:24:34 1993
***************
*** 0 ****
--- 1,200 ----
+ 
+         << xdvi-17+markpage+toc+printdvi patch について >>
+ 
+ 					1993/09/13
+ 					小野 康一
+ 					onono@fuka.info.waseda.ac.jp
+ 
+ ○xdvi-17+markpage+toc+printdvi patch とは
+   xdvi-17 + miyu-patch for xdvi PL17 に対するパッチです。このパッチをあ
+   てて作った xdvi では、以下のような機能を使うことができます。
+ 
+   1) Use_MARKPAGE
+   ページマーキング機能を、GNU Emacs のマークリング風に実現したものです。
+   ページのマーク(`m',`a')/アンマーク(`U',`A')、マークしたページへの移動
+   (`'',``')、マークしたページとカレントページとの交換('"')、マークを伴う
+   ページジャンプ('<','>')などを行なえます。
+   また、2) の toc からのマーキングも可能です。
+ 
+   2) Use_TOC
+   ページ番号リストを表示し、マウスでそのページをクリックすることで、その
+   ページへ移動(左ボタン)、そのページをマーク(真中ボタン)、アンマーク(右
+   ボタン)することができます。ドラッグにより、連続するページをマーク/アン
+   マークすることもできます。
+ 
+   3) Use_PRINTDVI
+   `o' または Print ボタンで Print-out メニューがポップアップします。ファ
+   イル全体の出力やカレントページ、最後にマークしたページ、リージョン(カ
+   レントページと最後にマークしたページとの間のページ)、マークした全部の
+   ページをメニューから選択して出力できます。
+ 
+ ○動作を確認した環境
+ 	SunOS 4.1.3 / sun4c マシン(SPARCstationシリーズ)
+ 
+ ○インストールについて
+ 
+   まず, xdvi PL17 のソース・ファイルである xdvi-17.tar.gz と
+   それに対するパッチ xdvi-17miyu.patch-beta4.gz (*1)、そして
+   当該パッチ xdvi-17+markpage+toc+printdvi.patch を用意します。
+ 
+   次に, 作業ディレクトリを作成して, そのディレクトリに移った後, 
+   xdvi-17.tar.gz を展開します。そのまま, ディレクトリを移動しないで, 
+   xdvi-17miyu.patch-beta4.gz を用いてパッチをあてます。
+   このとき, GNU のツールである gzip および patch が必要となります (*2)。
+   さらに xdvi-17+markpage+toc+printdvi.patch を用いてパッチをあてます。
+ 
+   あとは, システムに応じて Imakefile を編集した後, 
+   xmkmf を実行して Makefile を生成して, make を実行します。
+ 
+   なお、miyu-patch for xdvi PL17 については、README.miyu-patch をよく読
+   んでください。
+ 
+   (*1) これらは, 
+        ftp.tohoku.ac.jp[130.34.8.9]:~ftp/pub/tex/dviwares/xdvi/PL17 などの
+        anonymous ftp などから入手できます。
+   (*2) これらは, 
+        ftp.waseda.ac.jp[133.9.1.32]:~ftp/pub/GNU/prep 以下、または、
+        ftp.ecei.tohoku.ac.jp[130.34.222.67]:~ftp/pub/GNU/gzip および
+        ftp.ecei.tohoku.ac.jp[130.34.222.67]:~ftp/pub/GNU/patch 以下にあります。
+ 
+ ○Use_MARKPAGE および Use_TOC について
+   つけられるマークの最大数を 1024、DVI ファイルの最大ページ数も同じく 
+   1024 としてあります。これを越えることはまずないと思いますが、もし変更
+   する場合は、Imakefile の RINGSIZE および MAX_PAGE を修正してください。
+ 
+ ○Use_PRINTDVI について
+   Imakefile の Use_PRINTDVI のところは、自己サイトの環境に合わせて変更し
+   てください。%d などの意味については、print.h の最初の方のコメントに書
+   いてあります。また、デフォルトでは dvi2ps や dviselect を用いるように
+   書いてあります。このように、必要なページを切り出したり、プリンタ出力形
+   式へ変換する作業は xdvi の内部で行なわず、外部コマンドで処理するような
+   仕様にしました。したがって、これらのコマンドをあらかじめインストールし
+   ておかないと、xdvi からの出力ができません。dvi2ps, dvips, jdvi2kps,
+   dviselect など、自己サイトの環境に合ったコマンドをインストールし、それ
+   に合わせて Imakefile を修正した上で xdvi を作ってください。
+   また、デフォルトでは lpr に -v オプションを与えていません。PostScript 
+   プリンタ用のフィルタによっては -v オプションをつける必要があるかも知れ
+   ません。
+   また、デフォルトでは dvi2ps の出力を lpr の標準入力にパイプで与えてい
+   ます。lpr によっては、出力データが 1Mbyte を越えるとそれ以降を切り捨て
+   て出力するような仕様になっているかも知れません。そのような場合は、
+   dvi2ps の出力を一旦テンポラリファイル(/tmp/%F:%c@%r.ps など)にリダイレ
+   クトし、それを lpr -s で出力し、終了後に rm するようにすればいいでしょ
+   う。ただし、-s の場合、スプーリングせずに出力するため、出力が完了する
+   までそのファイルを消せません。出力完了まで待って rm する、という手続き
+   を簡単には書けないと思うので、デフォルトでは lpr の標準入力に与える方
+   法を採りました。1Mbyte を越えるくらいたくさんのページを出力するような
+   場合は、xdvi の中から出力せずにシェルのコマンドラインから
+ 	% dvi2ps file.dvi > /tmp/file.ps
+ 	% lpr -s /tmp/file.ps
+ 	(出力完了後)
+ 	% rm /tmp/file.ps
+   とした方がいいような気がします:-)
+ 
+ ○内部変数(%f など)の意味
+   print.h の最初の方のコメントにも書いてありますが、簡単に説明しておきま
+   す。Imakefile 中の PRCMD??? という変数は
+ 	PRCMDLST="(cd %d; dviselect -i %F -o /tmp/%F:%t@%r.dvi %A; dvi2ps /tmp/%F:%t@%r.dvi) | lpr -P%p -J'%F (Page %t)'; /bin/rm /tmp/%F:%t@%r.dvi"
+ 	/* all marked pages */
+   のように、% 表記の内部変数が用いられています。これは、DVI ファイルの出
+   力時に解釈されて実行されるコマンド文字列です。
+     PRCMDALL  DVI ファイルの全部を出力(する時に用いられるコマンド文字列)
+     PRCMDCUR  カレントページ(現在表示しているページ)を出力
+     PRCMDMRK  最後にマークしたページを出力
+     PRCMDRGN  リージョン(カレントページと最後にマークしたページで挟まれ
+               ている区間)内のすべてのページを出力
+     PRCMDLST  マークしたすべてのページを出力
+   これらのコマンドは、Print-out メニューで選択する項目
+ 	All pages
+ 	Current page
+ 	Marked page
+ 	Region
+ 	All marked pages
+   にそれぞれ対応しています。
+   コマンド文字列の解釈は、% 表記の内部変数を展開することによって行なわれ
+   ます。各内部変数の意味は次の通りです。
+     %f : 現在参照している DVI ファイルのファイル名(フルパス名)
+     %F : 現在参照している DVI ファイルのファイル名(basename)
+     %d : 現在参照している DVI ファイルが置かれているディレクトリ名
+          ( %f = %d/%F )
+     %p : プリンタ名(環境変数 PRINTER が定義されていればその値。また、
+          Print-menu で設定されるならその値)
+     %r : xdvi のプロセス ID
+   以下はページ番号に関する内部変数です。すべて絶対ページ番号(先頭ページ
+   を1として単調増加するページ番号。\count に左右されない)で表記します。
+     %c : カレントページ番号
+     %m : 最後にマークしたページ番号
+     %s : リージョンの開始ページ番号(%c と %m の最小値)
+     %e : リージョンの終了ページ番号(%c と %m の最大値)
+     %l : マークしたページ番号リスト(マーク順); 各ページ番号は ',' で区切
+          られている
+     %L : マークしたページ番号リスト(マーク順); 各ページ番号は ' ' で区切
+          られている
+     %t : マークしたページ番号リスト(ソートされている); 各ページ番号は
+          ',' で区切られている
+     %T : マークしたページ番号リスト(ソートされている); 各ページ番号は
+          ' ' で区切られている
+     %k : %l と同様、ただし、各ページ番号の前に '=' が置かれている
+          (dviselect を仮定している)
+     %K : %L と同様、ただし、各ページ番号の前に '=' が置かれている
+          (dviselect を仮定している)
+     %a : %t と同様、ただし、各ページ番号の前に '=' が置かれている
+          (dviselect を仮定している)
+     %A : %T と同様、ただし、各ページ番号の前に '=' が置かれている
+          (dviselect を仮定している)
+   たとえば、上記の PRCMDLST の定義で、/home/onono/doc/sample.dvi をプレ
+   ビューしていて、3,6,11,17ページをマークしている時に、Print-out メニュー
+   から all marked pages を選択すると、実行される文字列は以下のようになり
+   ます。
+ 	(cd /home/onono/doc;
+ 	 dviselect -i sample.dvi -o /tmp/sample.dvi:3,6,11,17@3255.dvi
+ 		 =3 =6 =11 =17;
+ 	 dvi2ps /tmp/sample.dvi:3,6,11,17@3255.dvi)
+ 	| lpr -Plp -J'sample.dvi (Page 3.6.11.17)';
+ 	/bin/rm /tmp/sample.dvi:3,6,11,17@3255.dvi
+   ただし、xdvi のプロセス ID = 3255、プリンタ名 = lp とします。
+ 
+ ○独立性
+   Use_MARKPAGE, Use_TOC, Use_PRINTDVI は、相互に独立して#define/#undefで
+   きるはずです(試していません)。もちろん、
+ 	#undef	Use_MARKPAGE
+ 	#define	Use_TOC
+ 	#define	Use_PRINTDVI
+   で作った場合は、toc 上でのマーキングができませんし(ページ移動はできる)、
+   Print-out メニューは All pages と current page の二つだけになるでしょ
+   う。
+ 
+ ○著作権
+   当該パッチの中のファイル
+ 	markring.c
+ 	markring.h
+ 	markpage.c
+ 	markpage.h
+ 	toc.c
+ 	toc.h
+ 	print.c
+ 	print.h
+   の著作権は、作者である
+ 	松浦 俊     MATSUURA Syun      syun@fuka.info.waseda.ac.jp
+ 	平原 厚志   HIRAHARA Atsushi   hirahara@fuka.info.waseda.ac.jp
+ 	小野 康一   ONO Kouichi        onono@fuka.info.waseda.ac.jp
+   に帰属します。なお、著作者を明らかにする限り、当該パッチの一部または全
+   体を改造、転送、再配布するのは自由とします。
+ 
+ ○ヒマがあればやろうかな
+ 
+ 1. 環境変数, オプション, リソースによる指定
+ 			-printer	*printer
+ 	XDVIPRALL	-prall		*print.all
+ 	XDVIPRCUR	-prcur		*print.currentPage
+ 	XDVIPRMKD	-prmarked	*print.markedPage
+ 	XDVIPRRGN	-prregion	*print.region
+ 	XDVIPRLST	-prlist		*print.list
+ 
+ 2. ページ移動に伴う toc のスクロールバー移動
+ 
+ 3. toc に表示するページ番号を \count0 を考慮した(実際の)ページ番号にする
+ 
+ 4. マークページリストの表記を
+ 	5,8-12,27,29,35-36,41
+    のようにする
*** /dev/null	Mon Sep 13 19:19:47 1993
--- xdvi-pl17+miyu.patch-beta4+markpage+toc+printdvi/toc.c	Mon Sep 13 22:03:21 1993
***************
*** 0 ****
--- 1,303 ----
+ /*
+  * Table of Contents / Page list for xdvi
+  *
+  * Copyright (c) 1993
+  *      MATSUURA Syun           syun@fuka.info.waseda.ac.jp
+  *      HIRAHARA Atsushi        hirahara@fuka.info.waseda.ac.jp
+  *      ONO Kouichi             onono@fuka.info.waseda.ac.jp
+  * All rights reserved.
+  */
+ 
+ #include <stdlib.h>
+ #include <X11/Intrinsic.h>
+ #include <X11/StringDefs.h>
+ #include <X11/Shell.h>
+ 
+ #include <X11/Xaw/Dialog.h>
+ #include <X11/Xaw/Cardinals.h>
+ #include <X11/Xaw/Command.h>
+ #include <X11/Xaw/List.h>
+ #include <X11/Xaw/Viewport.h>
+ 
+ 
+ #include "xdvi.h"
+ #include "toc.h"
+ #ifdef MARKPAGE
+ #include "markpage.h"
+ #endif /* MARKPAGE */
+ 
+ extern	int	pageno_correct;
+ 
+ static Widget	list_widget, viewport=NULL;
+ static char	*toc[MAX_PAGE];
+ static int	press_page_2 = -1;
+ static int	press_page_3 = -1;
+ 
+ extern	void	keystroke();
+ 
+ static  int
+   get_Page_size()
+ {
+   int  offset;
+   int  start_page = pageno_correct - 1;
+   int  end_page   = start_page + total_pages;
+   int  start_pageno_len;
+   int  end_pageno_len;
+   
+   if (start_page >= 0) {
+     offset = 0; /* plus symbol is hidden */
+   }
+   else {
+     offset = 1; /* offset for minus symbol */
+     start_page = - start_page;
+   }
+   for (start_pageno_len = offset; start_page > 0;
+        start_page /= 10, start_pageno_len++);
+   
+   if (end_page >= 0) {
+     offset = 0; /* plus symbol is hidden */
+   }
+   else {
+     offset = 1; /* offset for minus symbol */
+     end_page = - end_page;
+   }
+   for (end_pageno_len   = offset; end_page > 0;
+        end_page /= 10,   end_pageno_len++);
+   
+   return(MAX(start_pageno_len, end_pageno_len));
+   /* Plus 1 for minus symbol */
+ }
+ 
+ 
+ static int
+   /* get TOC's width size */
+   get_TOC_size()
+ {
+   /* Print format is "  NN<"    get_Page_size() is number of N */
+   return  (get_Page_size()+3)*8+20;
+ }
+ 
+ 
+ static void
+   /* set TOC's string */
+   set_TOC()
+ {
+   int   i;
+   char  s[16];
+   
+   for( i=0; i<total_pages; i++){
+     if( toc[i] )   free(toc[i]);
+ #ifdef MARKPAGE
+     if (ThisPageIsMarked(i)) {
+       sprintf(s, "%c %*d%c",
+ 	      i==LastMarkPage() ? LASTMRKPAGESYM : MRKPAGESYM,
+ 	      get_Page_size(), i+pageno_correct,
+ 	      i==current_page   ? CURPAGESYM     : NORMALPAGESYM);
+     }
+     else {
+       sprintf(s, "%c %*d%c",
+ 	      NORMALPAGESYM,
+ 	      get_Page_size(), i+pageno_correct,
+ 	      i==current_page   ? CURPAGESYM     : NORMALPAGESYM);
+     }
+ #else
+     if(i==current_page) {
+       sprintf(s, "  %*d<", get_Page_size(), i+pageno_correct);
+     }
+     else {
+       sprintf(s, "  %*d ", get_Page_size(), i+pageno_correct);
+     }
+ #endif /* MARKPAGE */
+     toc[i] = (char *)strdup(s);
+   }
+   toc[total_pages] = NULL;
+ }
+ 
+ void
+   Set_Page()
+ {
+   set_TOC();
+   XawListChange(list_widget, toc, total_pages, 55, False);
+ }
+ 
+ 
+ /* ARGSUSED */
+ static void
+   /* Called when Button-1 Pressed */
+   SelectThisPage(w, closure, call_data)
+ Widget w;
+ XtPointer closure, call_data;
+ {
+   XawListReturnStruct *item = (XawListReturnStruct*)call_data;
+   
+   keystroke('g', item->list_index+pageno_correct, 1, (XEvent *) NULL);
+   
+   set_TOC();
+   XawListChange(w, toc, total_pages, 55, False);
+ }
+ 
+ 
+ #ifdef MARKPAGE
+ static void
+   /* Called when Button-2 | 3 pressed */
+   Press_Mark_Page(w, event, button)
+ Widget  w;
+ XEvent  *event;
+ int     button;
+ {
+   int   x;
+   
+   switch( button ) {
+     /* Get item number */
+   case  2 :  press_page_2 = x = (event->xbutton.y-1)/15;    break;
+   case  3 :  press_page_3 = x = (event->xbutton.y-1)/15;    break;
+   }
+   ReverseTheMarkOfPage(x);
+   
+   set_TOC();
+   XawListChange(w, toc, total_pages, 55, False);
+ }
+ 
+ 
+ 
+ static  void
+   /* Set or Reset TOC mark */
+   set_Drag_TOC(button, x)
+ int  button, x;
+ {
+   int  i;
+   
+   i = (button==2) ? press_page_2: press_page_3;
+   
+   if( i < x ) {
+     for( ; i<=x; i++) {
+       if (button==2) {
+ 	MarkPage(i);
+       }
+       else {
+ 	UnmarkPage(i);
+       }
+     }
+   }
+   else {
+     for( ; i>=x; i--) {
+       if (button==2) {
+ 	MarkPage(i);
+       }
+       else {
+ 	UnmarkPage(i);
+       }
+     }
+   }
+ }
+ 
+ 
+ static void
+   /* Called when Button-2 | 3 released */
+   Release_Mark_Page(w, event, button)
+ Widget  w;
+ XEvent  *event;
+ int      button;
+ {
+   int   x;
+   
+   x = (event->xbutton.y-1)/15;	/* Get item number */
+   switch( button ) {
+   case  2 :  if( (press_page_2 != x) && (press_page_2 != -1) )
+     set_Drag_TOC(button, x);
+     press_page_2 = 0;
+     break;
+   case  3 :  if( (press_page_3 != x) && (press_page_3 != -1) )
+     set_Drag_TOC(button, x);
+     press_page_3 = 0;
+     break;
+   }
+   set_TOC();
+   XawListChange(w, toc, total_pages, 55, False);
+ }
+ 
+ 
+ static void
+   /* Called when mouse leaved the LIST-widget */
+   Leave_Mark_Page(w, event, button)
+ Widget  w;
+ XEvent  *event;
+ int      button;
+ {
+   press_page_2 = press_page_3 = -1;
+ }
+ #endif /* MARKPAGE */
+ 
+ 
+ static void
+   /* TOC's event handler */
+   TOCs_Event_Handler(w, n, event)
+ Widget          w;
+ int             n;
+ XEvent   *event;
+ {
+   switch( event->type ) {
+   case  ButtonPress :
+     /* when TOC pressed */
+     switch( event->xbutton.button ) {
+     case  2 : Press_Mark_Page(w, event, 2);  break;
+     case  3 : Press_Mark_Page(w, event, 3);  break;
+     }
+     break;
+     
+   case  ButtonRelease :
+     /* when TOC released */
+     switch( event->xbutton.button ) {
+     case  2 : Release_Mark_Page(w, event, 2);  break;
+     case  3 : Release_Mark_Page(w, event, 3);  break;
+     }
+     break;
+     
+   case  LeaveNotify :
+     /* when TOC leaved */
+     Leave_Mark_Page(w, event);
+     break;
+   }
+ }
+ 
+ 
+ void
+   Create_TOC(parent, h)
+ Widget    parent;
+ XtArgVal  h;
+ {
+   int   i;
+   char  s[16];
+   int   height = h - 208;
+   
+   if( total_pages > MAX_PAGE )  total_pages = MAX_PAGE;
+   
+   set_TOC();
+   
+   viewport = XtVaCreateManagedWidget("viewport", viewportWidgetClass, parent,
+ 				     XtNallowVert,	True,
+ 				     XtNforceBars,	True,
+ 				     XtNx,		78,
+ 				     XtNy,		20,
+ 				     XtNheight,		height,
+ 				     XtNwidth,		get_TOC_size(),
+ 				     NULL);
+   
+   list_widget = XtVaCreateManagedWidget( "list", listWidgetClass, viewport,
+ 					XtNlist,		toc,
+ 					XtNdefaultColumns,	1,
+ 					XtNforceColumns,	True,
+ 					XtNx,			100,
+ 					XtNy,			20,
+ 					XtNheight,		height,
+ 					XtNwidth,		get_TOC_size(),
+ 					XtNlongest,		30,
+ 					XtNverticalList,	True,
+ 					NULL);
+   XtAddCallback(list_widget, XtNcallback, SelectThisPage, (XtPointer) NULL);
+ #ifdef MARKPAGE
+   XtAddEventHandler(list_widget,
+ 		    ButtonPressMask | ButtonReleaseMask | LeaveWindowMask,
+ 		    False, TOCs_Event_Handler, NULL);
+ #endif /* MARKPAGE */
+ }
*** /dev/null	Mon Sep 13 19:19:47 1993
--- xdvi-pl17+miyu.patch-beta4+markpage+toc+printdvi/toc.h	Mon Sep 13 22:03:21 1993
***************
*** 0 ****
--- 1,25 ----
+ /*
+  * Table of Contents / Page list for xdvi
+  *
+  * Copyright (c) 1993
+  *      MATSUURA Syun           syun@fuka.info.waseda.ac.jp
+  *      HIRAHARA Atsushi        hirahara@fuka.info.waseda.ac.jp
+  *      ONO Kouichi             onono@fuka.info.waseda.ac.jp
+  * All rights reserved.
+  */
+ 
+ #ifndef MAX_PAGE
+ #define MAX_PAGE        1024
+ #endif /* MAX_PAGE */
+ 
+ #define CURPAGESYM      '<'
+ #define MRKPAGESYM      '*'
+ #define LASTMRKPAGESYM  '>'
+ #define NORMALPAGESYM   ' '
+ 
+ #ifndef MAX
+ #define MAX(i,j)        ( (i) > (j) ? (i) : (j) )
+ #endif /* MAX */
+ 
+ extern  void    Create_TOC();
+ extern  void    Set_Page();
*** /dev/null	Mon Sep 13 19:19:47 1993
--- xdvi-pl17+miyu.patch-beta4+markpage+toc+printdvi/markpage.c	Mon Sep 13 22:03:22 1993
***************
*** 0 ****
--- 1,195 ----
+ /*
+  * Page mark ring for xdvi
+  *
+  * Copyright (c) 1993
+  *      ONO Kouichi             onono@fuka.info.waseda.ac.jp
+  * All rights reserved.
+  */
+ 
+ #include <stdio.h>
+ #include "markpage.h"
+ 
+ static  MARKRING        *PageMarkRing;
+ 
+ void
+   CreateNewPageMarkRing()
+ {
+   PageMarkRing = CreateNewRing();
+ }
+ 
+ void
+   MakePageMarkRingNull()
+ {
+   MakeRingNull(PageMarkRing);
+ }
+ 
+ BOOL
+   ThisPageIsMarked(page)
+ PAGE page;
+ {
+   return(MemberOfRing(page,PageMarkRing));
+ }
+ 
+ void
+   MarkPage(page)
+ PAGE page;
+ {
+   if (ThisPageIsMarked(page)) {
+     PurgeTheValueAllFromRing(page,PageMarkRing);
+   }
+   AddElementToRing(page,PageMarkRing);
+   /* Like LRU-stack */
+ }
+ 
+ void
+   UnmarkPage(page)
+ PAGE page;
+ {
+   if (ThisPageIsMarked(page)) {
+     PurgeTheValueAllFromRing(page,PageMarkRing);
+   }
+ }
+ 
+ void
+   ReverseTheMarkOfPage(page)
+ PAGE page;
+ {
+   if (ThisPageIsMarked(page)) {
+     UnmarkPage(page);
+   }
+   else {
+     MarkPage(page);
+   }
+ }
+ 
+ BOOL
+   EmptyPageMarkRing()
+ {
+   return(EmptyRing(PageMarkRing));
+ }
+ 
+ PAGE
+   LastMarkPage()
+ {
+   return(RingLastElement(PageMarkRing));
+ }
+ 
+ void
+   SetPageMarkAtLast(page)
+ PAGE page;
+ {
+   if (! ThisPageIsMarked(page)) {
+     PurgeLastElementFromRing(PageMarkRing);
+   }
+   MarkPage(page);
+ }
+ 
+ void
+   RotatePageMarkRing()
+ {
+   RotateRing(PageMarkRing);
+ }
+ 
+ LIST_LOCATION
+   MakeMarkedPageList(PageList)
+ PAGE PageList[LISTSIZE];
+ {
+   return(MakeListFromRing(PageMarkRing,PageList));
+ }
+ 
+ LIST_LOCATION
+   MakeSortedMarkedPageList(PageList)
+ PAGE PageList[LISTSIZE];
+ {
+   return(MakeListFromRing(MakeRingSort(PageMarkRing),PageList));
+ }
+ 
+ void
+   GetMarkedPageListAsString(ResultString,prevchar,postchar,delimiter)
+ char ResultString[STRLENGTH], prevchar, postchar, delimiter;
+ {
+   PAGE          PageList[LISTSIZE];
+   LIST_LOCATION EndLocation, loc;
+   char          buff[STRLENGTH];
+   
+   ResultString[0] = NULL;
+   EndLocation = MakeMarkedPageList(PageList);
+   if (EndLocation >= INITIAL_LIST) {
+     if(prevchar!=NULL) {
+       sprintf(buff, "%c", prevchar);
+       strcat(ResultString, buff);
+     }
+     /* Put a character on the previous position of the first page number */
+     sprintf(buff, "%d", PageList[INITIAL_LIST] + 1);
+     strcat(ResultString, buff);
+     /* Put the first page number */
+     if(postchar!=NULL) {
+       sprintf(buff, "%c", postchar);
+       strcat(ResultString, buff);
+     }
+     /* Put a character on the post position of the first page number */
+     for(loc = INITIAL_LIST + 1; loc<=EndLocation; loc++) {
+       sprintf(buff, "%c", delimiter);
+       strcat(ResultString, buff);
+       /* Put the delimiter character */
+       if(prevchar!=NULL) {
+ 	sprintf(buff, "%c", prevchar);
+ 	strcat(ResultString, buff);
+       }
+       /* Put a character on the previous position of the first page number */
+       sprintf(buff, "%d", PageList[loc] + 1);
+       strcat(ResultString, buff);
+       /* Put the page number */
+       if(postchar!=NULL) {
+ 	sprintf(buff, "%c", postchar);
+ 	strcat(ResultString, buff);
+       }
+       /* Put a character on the post position of the first page number */
+     }
+   }
+ }
+ 
+ void
+   GetSortedMarkedPageListAsString(ResultString,prevchar,postchar,delimiter)
+ char ResultString[STRLENGTH], prevchar, postchar, delimiter;
+ {
+   PAGE          PageList[LISTSIZE];
+   LIST_LOCATION EndLocation, loc;
+   char          buff[STRLENGTH];
+   
+   ResultString[0] = NULL;
+   EndLocation = MakeSortedMarkedPageList(PageList);
+   if (EndLocation >= INITIAL_LIST) {
+     if(prevchar!=NULL) {
+       sprintf(buff, "%c", prevchar);
+       strcat(ResultString, buff);
+     }
+     /* Put a character on the previous position of the first page number */
+     sprintf(buff, "%d", PageList[INITIAL_LIST] + 1);
+     strcat(ResultString, buff);
+     /* Put the first page number */
+     if(postchar!=NULL) {
+       sprintf(buff, "%c", postchar);
+       strcat(ResultString, buff);
+     }
+     /* Put a character on the post position of the first page number */
+     for(loc = INITIAL_LIST + 1; loc<=EndLocation; loc++) {
+       sprintf(buff, "%c", delimiter);
+       strcat(ResultString, buff);
+       /* Put the delimiter character */
+       if(prevchar!=NULL) {
+ 	sprintf(buff, "%c", prevchar);
+ 	strcat(ResultString, buff);
+       }
+       /* Put a character on the previous position of the first page number */
+       sprintf(buff, "%d", PageList[loc] + 1);
+       strcat(ResultString, buff);
+       /* Put the page number */
+       if(postchar!=NULL) {
+ 	sprintf(buff, "%c", postchar);
+ 	strcat(ResultString, buff);
+       }
+       /* Put a character on the post position of the first page number */
+     }
+   }
+ }
*** /dev/null	Mon Sep 13 19:19:47 1993
--- xdvi-pl17+miyu.patch-beta4+markpage+toc+printdvi/markpage.h	Mon Sep 13 22:03:22 1993
***************
*** 0 ****
--- 1,28 ----
+ /*
+  * Page mark ring for xdvi
+  *
+  * Copyright (c) 1993
+  *      ONO Kouichi             onono@fuka.info.waseda.ac.jp
+  * All rights reserved.
+  */
+ 
+ #include "markring.h"
+ 
+ #define STRLENGTH       1024
+ 
+ typedef int     PAGE;
+ 
+ extern  void    CreateNewPageMarkRing();
+ extern  void    MakePageMarkRingNull();
+ extern  BOOL    ThisPageIsMarked();
+ extern  void    MarkPage();
+ extern  void    UnmarkPage();
+ extern  void    ReverseTheMarkOfPage();
+ extern  BOOL    EmptyPageMarkRing();
+ extern  PAGE    LastMarkPage();
+ extern  void    SetPageMarkAtLast();
+ extern  void    RotatePageMarkRing();
+ extern  LIST_LOCATION   MakeMarkedPageList();
+ extern  LIST_LOCATION   MakeSortedMarkedPageList();
+ extern  void    GetMarkedPageListAsString();
+ extern  void    GetSortedMarkedPageListAsString();
*** /dev/null	Mon Sep 13 19:19:47 1993
--- xdvi-pl17+miyu.patch-beta4+markpage+toc+printdvi/markring.c	Mon Sep 13 22:03:23 1993
***************
*** 0 ****
--- 1,327 ----
+ /*
+  * Mark ring package
+  *
+  * Copyright (c) 1993
+  *      ONO Kouichi             onono@fuka.info.waseda.ac.jp
+  * All rights reserved.
+  */
+ 
+ #include "markring.h"
+ #include <stdio.h>
+ #include <malloc.h>
+ 
+ void
+   MakeRingNull(ring)
+ MARKRING        *ring;
+ {
+   ring->front = INITIAL_FRONT;
+   ring->rear = INITIAL_REAR;
+ }
+ 
+ MARKRING
+   *CreateNewRing()
+ {
+   MARKRING      *ring;
+   
+   ring = (MARKRING *) calloc(1, sizeof(MARKRING));
+   MakeRingNull(ring);
+   return(ring);
+ }
+ 
+ BOOL
+   EmptyRing(ring)
+ MARKRING        *ring;
+ {
+   return(Is_Empty_Location(ring->front,ring->rear));
+ }
+ 
+ BOOL
+   ElementExistsHereInRing(index,ring)
+ RING_LOCATION   index;
+ MARKRING        *ring;
+ {
+   if (EmptyRing(ring)) {
+     return(FALSE);
+   }
+   else {
+     return(BetweenOnRing(ring->front,ring->rear,index));
+   }
+ }
+ 
+ BOOL
+   BetweenOnRing(pre,post,index)
+ RING_LOCATION   pre,post,index;
+ {
+   if (pre<=post) {
+     return((pre<=index)&&(index<=post));
+   }
+   else {
+     /* pre>post */
+     return(   (INITIAL_FRONT<=index) && (index<=        post)
+            || (pre          <=index) && (index<=INITIAL_REAR));
+   }
+ }
+ 
+ BOOL
+   MemberOfRing(elem,ring)
+ RING_ELEMENT    elem;
+ MARKRING        *ring;
+ {
+   register RING_LOCATION index=ring->front;
+   
+   while (! Is_Empty_Location(index,ring->rear)) {
+     if (ring->element[index]==elem) {
+       return(TRUE);
+     }
+     else {
+       index = Ring_Next_Location(index);
+     }
+   }
+   return(FALSE);
+ }
+ 
+ RING_LOCATION
+   LocationOfMemberInRing(elem,ring)
+ RING_ELEMENT    elem;
+ MARKRING        *ring;
+ {
+   register RING_LOCATION index=ring->front;
+   
+   while (! Is_Empty_Location(index,ring->rear)) {
+     if (ring->element[index]==elem) {
+       return(index);
+     }
+     else {
+       index = Ring_Next_Location(index);
+     }
+   }
+   return(ILLEGAL_LOCAT);
+ }
+ 
+ RING_ELEMENT
+   RingTopElement(ring)
+ MARKRING        *ring;
+ {
+   if (EmptyRing(ring)) {
+     fprintf(stderr,"Mark ring has no elements.\n");
+   }
+   else {
+     return(ring->element[ring->front]);
+   }
+ }
+ 
+ RING_ELEMENT
+   RingLastElement(ring)
+ MARKRING        *ring;
+ {
+   if (EmptyRing(ring)) {
+     fprintf(stderr,"Mark ring has no elements.\n");
+   }
+   else {
+     return(ring->element[ring->rear]);
+   }
+ }
+ 
+ NUMBER
+   NumberOfElementsInRing(ring)
+ MARKRING        *ring;
+ {
+   register NUMBER num=0;
+   
+   if(EmptyRing(ring)) {
+     return(num);
+   }
+   else {
+     register RING_LOCATION index=ring->front;
+     
+     while (! Is_Empty_Location(index,ring->rear)) {
+       num++;
+       index = Ring_Next_Location(index);
+     }
+     return(num);
+   }
+ }
+ 
+ void
+   PurgeOldElementFromRing(ring)
+ MARKRING        *ring;
+ {
+   if(EmptyRing(ring)) {
+     fprintf(stderr,"Mark ring has no elements.\n");
+   }
+   else {
+     ring->front = Ring_Next_Location(ring->front);
+     /* forget the oldest (first-in) element to free space */
+   }
+ }
+ 
+ void
+   PurgeLastElementFromRing(ring)
+ MARKRING        *ring;
+ {
+   if(EmptyRing(ring)) {
+     fprintf(stderr,"Mark ring has no elements.\n");
+   }
+   else {
+     ring->rear = Ring_Prev_Location(ring->rear);
+     /* forget the last (last-in) element to free space */
+   }
+ }
+ 
+ void
+   PurgeElementHereFromRing(index,ring)
+ RING_LOCATION   index;
+ MARKRING        *ring;
+ {
+   if (ElementExistsHereInRing(index,ring)) {
+     RING_LOCATION prev,next;
+     
+     ring->rear = Ring_Prev_Location(ring->rear);
+     next = index;
+     prev = next;
+     while (! Is_Empty_Location(prev,ring->rear)) {
+       next = Ring_Next_Location(prev);
+       ring->element[prev] = ring->element[next];
+       prev = next;
+     }
+   }
+   else {
+     fprintf(stderr,"There is no elements in the Mark ring.\n");
+   }
+ }
+ 
+ void
+   PurgeTheValueAllFromRing(elem,ring)
+ RING_ELEMENT    elem;
+ MARKRING        *ring;
+ {
+   register RING_LOCATION index;
+   
+   while ((index = LocationOfMemberInRing(elem,ring))!=ILLEGAL_LOCAT) {
+     PurgeElementHereFromRing(index,ring);
+   }
+ }
+ 
+ void
+   AddElementToRing(elem,ring)
+ RING_ELEMENT    elem;
+ MARKRING        *ring;
+ {
+   if (Is_Empty_Location(ring->front,Ring_Next_Location(ring->rear))) {
+     PurgeOldElementFromRing(ring);
+   }
+   ring->rear = Ring_Next_Location(ring->rear);
+   ring->element[ring->rear] = elem;
+ }
+ 
+ void
+   InsertElementToRing(elem,ring)
+ RING_ELEMENT    elem;
+ MARKRING        *ring;
+ {
+   if (Is_Empty_Location(Ring_Prev_Location(ring->front),ring->rear)) {
+     PurgeLastElementFromRing(ring);
+   }
+   ring->front = Ring_Prev_Location(ring->front);
+   ring->element[ring->front] = elem;
+ }
+ 
+ void
+   RotateRing(ring)
+ MARKRING        *ring;
+ {
+   RING_ELEMENT    elem;
+   
+   if (EmptyRing(ring)) {
+     fprintf(stderr,"Mark ring has no elements.\n");
+   }
+   else {
+     elem = RingLastElement(ring);
+     PurgeLastElementFromRing(ring);
+     InsertElementToRing(elem,ring);
+   }
+ }
+ 
+ void
+   ReverseRotateRing(ring)
+ MARKRING        *ring;
+ {
+   RING_ELEMENT    elem;
+   
+   if (EmptyRing(ring)) {
+     fprintf(stderr,"Mark ring has no elements.\n");
+   }
+   else {
+     elem = RingTopElement(ring);
+     PurgeOldElementFromRing(ring);
+     AddElementToRing(elem,ring);
+   }
+ }
+ 
+ MARKRING
+   *CopyRing(ring)
+ MARKRING        *ring;
+ {
+   register RING_LOCATION index=ring->front;
+   MARKRING      *newring;
+   
+   newring = CreateNewRing();
+   while (! Is_Empty_Location(index,ring->rear)) {
+     AddElementToRing(ring->element[index],newring);
+     index = Ring_Next_Location(index);
+   }
+   return(newring);
+ }
+ 
+ MARKRING
+   *MakeRingUnique(ring)
+ MARKRING        *ring;
+ {
+   register RING_LOCATION index=ring->front;
+   MARKRING      *newring;
+   
+   newring = CreateNewRing();
+   while (! Is_Empty_Location(index,ring->rear)) {
+     if (! MemberOfRing(ring->element[index],newring)) {
+       AddElementToRing(ring->element[index],newring);
+     }
+     index = Ring_Next_Location(index);
+   }
+   return(newring);
+ }
+ 
+ BOOL
+   RingElemCompare(elem1,elem2)
+ RING_ELEMENT *elem1,*elem2;
+ {
+   return(*elem1 - *elem2);
+ }
+ 
+ MARKRING
+   *MakeRingSort(ring)
+ MARKRING        *ring;
+ {
+   MARKRING      *newring;
+   
+   newring = CopyRing(ring);
+   qsort(newring->element,newring->rear+1,sizeof(RING_ELEMENT),RingElemCompare);
+   return(newring);
+ }
+ 
+ LIST_LOCATION
+   MakeListFromRing(ring,list)
+ MARKRING        *ring;
+ LIST_ELEMENT    list[LISTSIZE];
+ {
+   register RING_LOCATION index;
+   register LIST_LOCATION loc = INITIAL_LIST;
+   
+   index = ring->front;
+   
+   while (! Is_Empty_Location(index,ring->rear)) {
+     list[loc] = ring->element[index];
+     loc++;
+     index = Ring_Next_Location(index);
+   }
+   return(loc - 1);
+ }
*** /dev/null	Mon Sep 13 19:19:47 1993
--- xdvi-pl17+miyu.patch-beta4+markpage+toc+printdvi/markring.h	Mon Sep 13 22:03:23 1993
***************
*** 0 ****
--- 1,70 ----
+ /*
+  * Mark ring package
+  *
+  * Copyright (c) 1993
+  *      ONO Kouichi             onono@fuka.info.waseda.ac.jp
+  * All rights reserved.
+  */
+ 
+ typedef int             BOOL;
+ #ifndef TRUE
+ #define TRUE            (1)
+ #define FALSE           (0)
+ #endif
+ 
+ typedef unsigned short int      NUMBER;
+ 
+ typedef int             RING_ELEMENT;   /* contents of Ring */
+ #ifndef RINGSIZE
+ #define RINGSIZE        16
+ #endif /* RINGSIZE */
+ typedef short int       RING_LOCATION;  /* index of Ring */
+ #define ILLEGAL_LOCAT   -1              /* when location is illegal */
+ #define INITIAL_FRONT   0               /* front index */
+ #define INITIAL_REAR    RINGSIZE-1      /* rear index */
+ 
+ struct MarkRing {
+   RING_ELEMENT    element[RINGSIZE]  ;    /* Ring body */
+   RING_LOCATION   front,rear;
+   /* front     : index of first-in element */
+   /* rear      : index of last-in element */
+ };
+ 
+ typedef struct MarkRing MARKRING;
+ 
+ typedef RING_ELEMENT    LIST_ELEMENT;   /* contents of List */
+ #define LISTSIZE        RINGSIZE
+ typedef short int       LIST_LOCATION;  /* index of List */
+ #define INITIAL_LIST   0                /* initial position of List */
+ 
+ typedef LIST_ELEMENT    MARKLIST[LISTSIZE];
+ 
+ extern  void             MakeRingNull();
+ extern  MARKRING         *CreateNewRing();
+ extern  BOOL             EmptyRing();
+ extern  BOOL             ElementExistsHereInRing();
+ extern  BOOL             BetweenOnRing();
+ extern  BOOL             MemberOfRing();
+ extern  RING_LOCATION    LocationOfMemberInRing();
+ extern  RING_ELEMENT     RingTopElement();
+ extern  RING_ELEMENT     RingLastElement();
+ extern  NUMBER           NumberOfElementsInRing();
+ extern  void             PurgeOldElementFromRing();
+ extern  void             PurgeLastElementFromRing();
+ extern  void             PurgeElementHereFromRing();
+ extern  void             PurgeTheValueAllFromRing();
+ extern  void             AddElementToRing();
+ extern  void             InsertElementToRing();
+ extern  void             RotateRing();
+ extern  void             ReverseRotateRing();
+ extern  MARKRING         *CopyRing();
+ extern  MARKRING         *MakeRingUnique();
+ extern  BOOL             RingElemCompare();
+ extern  MARKRING         *MakeRingSort();
+ extern  LIST_LOCATION    MakeListFromRing();
+ 
+ #define Ring_Next_Location(i)   ( ((i)+1) % RINGSIZE )
+ #define Ring_Prev_Location(i)   ( (i)==INITIAL_FRONT ? INITIAL_REAR : ((i)-1) )
+ #define Is_Next_In_Ring(i,j)            ( Ring_Next_Location(j)==(i) )
+ #define Is_Prev_In_Ring(i,j)            ( Ring_Prev_Location(j)==(i) )
+ #define Is_Empty_Location(front,rear)   ( Is_Next_In_Ring(front,rear) )
*** /dev/null	Mon Sep 13 19:19:47 1993
--- xdvi-pl17+miyu.patch-beta4+markpage+toc+printdvi/print.c	Mon Sep 13 22:03:24 1993
***************
*** 0 ****
--- 1,428 ----
+ /*
+  * print-out DVI
+  *
+  * Copyright (c) 1993
+  *      MATSUURA Syun           syun@fuka.info.waseda.ac.jp
+  *      HIRAHARA Atsushi        hirahara@fuka.info.waseda.ac.jp
+  *      ONO Kouichi             onono@fuka.info.waseda.ac.jp
+  * All rights reserved.
+  */
+ 
+ #include <stdlib.h>
+ #include <stdio.h>
+ #include <string.h>
+ 
+ #include <X11/Intrinsic.h>
+ #include <X11/StringDefs.h>
+ #include <X11/Shell.h>
+ 
+ #include <X11/Xaw/AsciiText.h>
+ #include <X11/Xaw/Box.h>
+ #include <X11/Xaw/Command.h>
+ #include <X11/Xaw/Dialog.h>
+ #include <X11/Xaw/Form.h>
+ #include <X11/Xaw/Label.h>
+ #include <X11/Xaw/MenuButton.h>
+ #include <X11/Xaw/SimpleMenu.h>
+ #include <X11/Xaw/SmeBSB.h>
+ #include <X11/Xaw/Cardinals.h>
+ 
+ #include "xdvi.h"
+ #include "print.h"
+ #ifdef MARKPAGE
+ #include "markpage.h"
+ #endif /* MARKPAGE */
+ 
+ enum PRINTSTYLE
+ #ifdef MARKPAGE
+ {PRINTALL, PRINTCUR, PRINTMARKED, PRINTREGION, PRINTALLMARKED};
+ #else
+ {PRINTALL, PRINTCUR};
+ #endif /* MARKPAGE */
+ 
+ static String print_style[] =
+ #ifdef MARKPAGE
+ {LBLPRINTALL,  LBLPRINTCUR,  LBLPRINTMRK,  LBLPRINTRGN,  LBLPRINTAMK};
+ #else
+ {LBLPRINTALL,  LBLPRINTCUR};
+ #endif /* MARKPAGE */
+ 
+ static String print_command[] =
+ #ifdef MARKPAGE
+ {PRCMDALL,  PRCMDCUR,  PRCMDMRK,  PRCMDRGN,  PRCMDLST};
+ #else
+ {PRCMDALL,  PRCMDCUR};
+ #endif /* MARKPAGE */
+ 
+ static char     printer_name[PRINTERNAMELEN];
+ 
+ static Boolean  PrintMenuEnd = False;
+ 
+ static Widget   popup, dialog, print_button, print_menu;
+ 
+ static void
+   GetBaseName(pathname, basename)
+ char pathname[STRLENGTH], basename[STRLENGTH];
+ {
+   int len,i;
+   int found = -1;
+   
+   len = strlen(pathname);
+   
+   for(i=len-1; i>found; i--) {
+     if(pathname[i]==PATH_DELIMITER) /* found it */
+       found = i;
+   }
+   if (found <= -1) /* not found */
+     found = -1;
+   strcpy(basename, pathname + found + 1);
+ }
+ 
+ static void
+   GetDirName(pathname, dirname)
+ char pathname[STRLENGTH], dirname[STRLENGTH];
+ {
+   int len,i;
+   int found = -1;
+   char copypathname[STRLENGTH];
+ 
+   strcpy(copypathname, pathname);
+   
+   len = strlen(copypathname);
+   
+   for(i=len-1; i>found; i--) {
+     if(copypathname[i]==PATH_DELIMITER) /* found it */
+       found = i;
+   }
+ 
+   if (found==0) {
+     /* found, and directory is "/" */
+     copypathname[0] = PATH_DELIMITER;
+     copypathname[1] = NULL;
+   }
+   else if (found > 0) {
+     /* found, and directory is "/xxx/yyy/zz..." */
+     copypathname[found] = NULL;
+   }
+   else {
+     /* not found, pathname may be plain filename */
+     /* copy current directory */
+     copypathname[0] = '.';
+     copypathname[1] = NULL;
+   }
+   strcpy(dirname, copypathname);
+ }
+ 
+ static void
+   SubstitutePrintVar(ResultStr, SourceStr)
+ char ResultStr[STRLENGTH], SourceStr[STRLENGTH];
+ {
+   char SourceChar[STRLENGTH], DestStr[STRLENGTH], StrBuff[STRLENGTH];
+   int charpos, strlength;
+   PAGE          PageList[LISTSIZE];
+   register      LIST_LOCATION LocList, EndLocList;
+   
+   strcpy(SourceChar, SourceStr);
+   strlength=strlen(SourceChar);
+   DestStr[0] = NULL;
+   
+   for(charpos=0; charpos<strlength; charpos++) {
+     if (SourceChar[charpos]==VARMARK) { /* Is it a variable ? */
+       /* Probably it is a variable */
+       charpos++;
+       if (charpos<strlength) { /* Is the source string end ? */
+ 	/* No, the source string has more characters */
+ 	switch (SourceChar[charpos]) {
+ 	case VARMARK:
+ 	  StrBuff[0] = VARMARK;
+ 	  StrBuff[1] = NULL;
+ 	  strcat(DestStr, StrBuff);
+ 	  break;
+ 	case 'f':
+ 	  strcat(DestStr, dvi_name);
+ 	  break;
+ 	case 'F':
+ 	  GetBaseName(dvi_name,StrBuff);
+ 	  strcat(DestStr, StrBuff);
+ 	  break;
+ 	case 'd':
+ 	  GetDirName(dvi_name,StrBuff);
+ 	  strcat(DestStr, StrBuff);
+ 	  break;
+ 	case 'p':
+ 	  strcat(DestStr, printer_name);
+ 	  break;
+ 	case 'r':
+ 	  sprintf(StrBuff, "%d", getpid());
+ 	  strcat(DestStr, StrBuff);
+ 	  break;
+ 	case 'c':
+ 	  sprintf(StrBuff, "%d", current_page + 1);
+ 	  strcat(DestStr, StrBuff);
+ 	  break;
+ #ifdef MARKPAGE
+ 	case 'm':
+ 	  sprintf(StrBuff, "%d", LastMarkPage() + 1);
+ 	  strcat(DestStr, StrBuff);
+ 	  break;
+ 	case 's':
+ 	  sprintf(StrBuff, "%d", MIN(current_page + 1, LastMarkPage() + 1));
+ 	  strcat(DestStr, StrBuff);
+ 	  break;
+ 	case 'e':
+ 	  sprintf(StrBuff, "%d", MAX(current_page + 1, LastMarkPage()+ 1));
+ 	  strcat(DestStr, StrBuff);
+ 	  break;
+ 	case 'l':
+ 	  GetMarkedPageListAsString(StrBuff, NULL, NULL, ',');
+ 	  strcat(DestStr, StrBuff);
+ 	  break;
+ 	case 'L':
+ 	  GetMarkedPageListAsString(StrBuff, NULL, NULL, ' ');
+ 	  strcat(DestStr, StrBuff);
+ 	  break;
+ 	case 't':
+ 	  GetSortedMarkedPageListAsString(StrBuff, NULL, NULL, ',');
+ 	  strcat(DestStr, StrBuff);
+ 	  break;
+ 	case 'T':
+ 	  GetSortedMarkedPageListAsString(StrBuff, NULL, NULL, ' ');
+ 	  strcat(DestStr, StrBuff);
+ 	  break;
+ 	case 'k':
+ 	  GetMarkedPageListAsString(StrBuff, '=', NULL, ',');
+ 	  strcat(DestStr, StrBuff);
+ 	  break;
+ 	case 'K':
+ 	  GetMarkedPageListAsString(StrBuff, '=', NULL, ' ');
+ 	  strcat(DestStr, StrBuff);
+ 	  break;
+ 	case 'a':
+ 	  GetSortedMarkedPageListAsString(StrBuff, '=', NULL, ',');
+ 	  strcat(DestStr, StrBuff);
+ 	  break;
+ 	case 'A':
+ 	  GetSortedMarkedPageListAsString(StrBuff, '=', NULL, ' ');
+ 	  strcat(DestStr, StrBuff);
+ 	  break;
+ #endif /* MARKPAGE */
+ 	default:
+ 	  StrBuff[0] = VARMARK;
+ 	  StrBuff[1] = SourceChar[charpos];
+ 	  StrBuff[2] = NULL;
+ 	  strcat(DestStr, StrBuff);
+ 	  break;
+ 	}
+       }
+       else { /* The source string is end */
+ 	StrBuff[0] = VARMARK;
+ 	StrBuff[1] = NULL;
+ 	strcat(DestStr, StrBuff);
+ 	charpos--;
+       }
+     }
+     else { /* It is not a variable */
+       StrBuff[0] = SourceChar[charpos];
+       StrBuff[1] = NULL;
+       strcat(DestStr, StrBuff);
+     }
+   }
+   strcpy(ResultStr, DestStr);
+ }
+ 
+ static void
+   close_all_font_file()
+ {
+   register struct font *fontp;
+   
+   for (fontp = font_head; fontp != NULL; fontp = fontp->next)
+     if (fontp->file != NULL) {
+       Fclose(fontp->file);
+     }
+ }
+ 
+ static void
+   PrintDVI(widget, client_data, call_data)
+ Widget  widget;
+ XtPointer client_data, call_data;
+ {
+   int   PrintStyle, pid;
+   
+   PrintStyle = (int)client_data;
+ 
+   strcpy(printer_name, (char *)XawDialogGetValueString(dialog));
+   if (*printer_name==NULL) {
+     /* When the input of dialog widget as printer name is null string, */
+     /* Let it the default printer name */
+ #ifdef DVIPRINTER
+     strcpy(printer_name, DVIPRINTER);
+ #else
+     strcpy(printer_name, DEFAULTPRINTER);
+ #endif /* DVIPRINTER */
+   }
+ 
+   if ((pid = fork ()) < 0) {
+     perror("fork");
+     return;
+   }
+   /* Actual print-out work should be done with the child process */
+   /* Because the work takes long time */
+   
+   if (pid == 0) {
+     /* The following is the work for the child process */
+     /* It is the actual print-out work */
+     int  i;
+     char buff[STRLENGTH];
+     
+     close_all_font_file();
+     /* Forcedly close all font files */
+     
+     SubstitutePrintVar(buff, print_command[PrintStyle]);
+     system(buff);
+     exit(0);      
+   }
+ 
+   PrintMenuEnd = True;
+   /* Print-out pull down menu should be closed */
+ }
+ 
+ static void 
+   DestroyPopupPrompt(widget, client_data, call_data)
+ Widget  widget;
+ XtPointer client_data, call_data;
+ {
+   PrintMenuEnd = True;
+   /* Print-out pull down menu should be closed */
+ }
+ 
+ 
+ static char *
+   get_printer_name()
+ {
+   char  *p;
+   
+   if( p = getenv(ENVVARPRINTER) )
+     return(strdup(p));
+   else
+ #ifdef DVIPRINTER
+     return(strdup(DVIPRINTER));
+ #else
+     return(strdup(DEFAULTPRINTER));
+ #endif /* DVIPRINTER */
+ }
+ 
+ void
+   InitPrintMenu()
+ {
+   strcpy(printer_name, get_printer_name());
+ }
+ 
+ void
+   print_DVI_file(top_level)
+ Widget top_level;
+ {
+   Widget        entry;
+   Position      x, y;
+   Dimension     width, height;
+   int           i;
+   XtAppContext  PrintApp;
+   XEvent        event;
+   
+   XtVaGetValues(top_level,
+ 		XtNwidth, &width,
+ 		XtNheight, &height,
+ 		NULL);
+   XtTranslateCoords(top_level,
+ 		    (Position) (width / 3), (Position) (height / 3),
+ 		    &x, &y);
+   
+ 
+   popup = XtVaCreatePopupShell(LBLPRINTSH,
+ 			       transientShellWidgetClass,
+ 			       top_level,
+ 			       XtNx, x,
+ 			       XtNy, y,
+ 			       NULL);
+   /* 
+    * The popup will contain a dialog box, prompting the user for input. 
+    */
+   
+   dialog = XtVaCreateManagedWidget(LBLPRINTER,
+ 				   dialogWidgetClass,
+ 				   popup,
+ 				   XtNlabel,    (String)LBLPRINTER,
+ 				   XtNvalue,    (String)printer_name,
+ 				   NULL);
+ 
+   /*
+    * The prompting message's size is dynamic; allow it to request resize. 
+    */
+   
+   print_button = XtVaCreateManagedWidget(LBLPRINTOUT,
+ 					 menuButtonWidgetClass,
+ 					 dialog,
+ 					 NULL);
+   XtVaSetValues(print_button,
+ 		XtNmenuName, LBLPRINTMENU,
+ 		NULL);
+   
+   XawDialogAddButton(dialog,
+ 		     LBLCANCEL,
+ 		     DestroyPopupPrompt,
+ 		     (XtPointer)dialog);
+   
+   print_menu = XtVaCreatePopupShell(LBLPRINTMENU,
+ 				    simpleMenuWidgetClass,
+ 				    print_button,
+ 				    NULL);
+   
+   for(i = 0; (int)XtNumber(print_style) > i; i++) {
+     switch (i) {
+     case PRINTALL:
+     case PRINTCUR:
+       entry = XtVaCreateManagedWidget(print_style[i],
+ 				      smeBSBObjectClass,
+ 				      print_menu,
+ 				      NULL);
+       XtAddCallback(entry, XtNcallback, PrintDVI, (XtPointer)i);
+       break;
+ #ifdef MARKPAGE
+     case PRINTMARKED:
+     case PRINTREGION:
+     case PRINTALLMARKED:
+       if (EmptyPageMarkRing()) {
+ 	entry = XtVaCreateManagedWidget(print_style[i],
+ 					smeBSBObjectClass,
+ 					print_menu,
+ 					XtNsensitive, False,
+ 					NULL);
+       }
+       else {
+ 	entry = XtVaCreateManagedWidget(print_style[i],
+ 					smeBSBObjectClass,
+ 					print_menu,
+ 					NULL);
+       }
+       XtAddCallback(entry, XtNcallback, PrintDVI, (XtPointer)i);
+       break;
+ #endif
+     default:
+       break;
+     }
+   }
+ 
+   XtPopup(popup, XtGrabNone);
+ 
+   PrintMenuEnd = False;
+ 
+   XtAddGrab(popup, True, True);
+ 
+   PrintApp = XtWidgetToApplicationContext(popup);
+ 
+   while(! PrintMenuEnd) {
+     XtAppNextEvent(PrintApp, &event);
+     XtDispatchEvent(&event);
+   };
+ 
+   XtDestroyWidget(popup);
+ }
*** /dev/null	Mon Sep 13 19:19:47 1993
--- xdvi-pl17+miyu.patch-beta4+markpage+toc+printdvi/print.h	Mon Sep 13 22:03:24 1993
***************
*** 0 ****
--- 1,92 ----
+ /*
+  * print-out DVI
+  *
+  * Copyright (c) 1993
+  *      MATSUURA Syun           syun@fuka.info.waseda.ac.jp
+  *      HIRAHARA Atsushi        hirahara@fuka.info.waseda.ac.jp
+  *      ONO Kouichi             onono@fuka.info.waseda.ac.jp
+  * All rights reserved.
+  */
+ 
+ /*
+  * Internal variables for print-out command string
+  *
+  * %f : filename of DVI file (full pathname)
+  * %F : filename of DVI file (basename of pathname)
+  * %d : directory where DVI file is placed (directory of pathname)
+  * %p : printer name (if the environment variable PRINTER is defined, use it)
+  * %r : proces id
+  *
+  * The following variables denote absolute page number.
+  * %c : current page number
+ #ifdef MARKPAGE
+  * %m : lastly marked page number
+  * %s : start page number of region; minimum of %c and %m
+  * %e : end page number of region; maximum of %c and %m
+  * %l : marked page list; marked order; separated by ","
+  * %L : marked page list; marked order; separated by " "
+  * %t : marked page list; sorted; separated by ","
+  * %T : marked page list; sorted; separated by " "
+  * %k : like %l; '=' is put on each page number (assumed dviselect)
+  * %K : like %L; '=' is put on each page number (assumed dviselect)
+  * %a : like %t; '=' is put on each page number (assumed dviselect)
+  * %A : like %T; '=' is put on each page number (assumed dviselect)
+ #endif
+  */
+ 
+ #define DEFAULTPRINTER  "lp"
+ #define ENVVARPRINTER   "PRINTER"
+ #define PRINTERNAMELEN  32
+ 
+ #define VARMARK    '%'
+ #ifndef PRCMDALL
+ #define PRCMDALL   "(cd %d; dvi2ps %F) | lpr -P%p -J'%F'"
+ #endif /* PRCMDALL */
+ #ifndef PRCMDCUR
+ #define PRCMDCUR   "(cd %d; dviselect -i %F -o /tmp/%F:%c@%r.dvi =%c; dvi2ps /tmp/%F:%c@%r.dvi) | lpr -P%p -J'%F (Page %c)'; /bin/rm /tmp/%F:%c@%r.dvi"
+ #endif /* PRCMDCUR */
+ #ifdef MARKPAGE
+ #ifndef PRCMDMRK
+ #define PRCMDMRK   "(cd %d; dviselect -i %F -o /tmp/%F:%m@%r.dvi =%m; dvi2ps /tmp/%F:%m@%r.dvi) | lpr -P%p -J'%F (Page %m)'; /bin/rm /tmp/%F:%m@%r.dvi"
+ #endif /* PRCMDMRK */
+ #ifndef PRCMDRGN
+ #define PRCMDRGN   "(cd %d; dviselect -i %F -o /tmp/%F:%s-%e@%r.dvi =%s:%e; dvi2ps /tmp/%F:%s-%e@%r.dvi) | lpr -P%p -J'%F (Page %s-%e)'; /bin/rm /tmp/%F:%s-%e@%r.dvi"
+ #endif /* PRCMDRGN */
+ #ifndef PRCMDLST
+ #define PRCMDLST   "(cd %d; dviselect -i %F -o /tmp/%F:%t@%r.dvi %A; dvi2ps /tmp/%F:%t@%r.dvi) | lpr -P%p -J'%F (Page %t)'; /bin/rm /tmp/%F:%t@%r.dvi"
+ #endif /* PRCMDLST */
+ #endif /* MARKPAGE */
+ 
+ #define LBLPRINTSH             "Print-out"
+ 
+ #define LBLPRINTER             "Printer name"
+ 
+ #define LBLPRINTOUT            "Print"
+ #define LBLCANCEL              "Cancel"
+ 
+ #define LBLPRINTMENU           "Print menu"
+ 
+ #define LBLPRINTALL            "All pages"
+ #define LBLPRINTCUR            "Current page"
+ #ifdef MARKPAGE
+ #define LBLPRINTMRK            "Marked page"
+ #define LBLPRINTRGN            "Region"
+ #define LBLPRINTAMK            "All marked pages"
+ #endif /* MARKPAGE */
+ 
+ #ifdef MARKPAGE
+ #define MIN(i,j)        ( (i) < (j) ? (i) : (j) )
+ #define MAX(i,j)        ( (i) > (j) ? (i) : (j) )
+ #endif /* MARKPAGE */
+ 
+ #define PATH_DELIMITER  '/'
+ 
+ typedef struct {
+   int           print_style;
+   Widget        widget;
+ } PrintOrder;
+ 
+ #define TEMPFILE        "/tmp/XDVI:%r"
+ 
+ extern void     InitPrintMenu();
+ extern void     print_DVI_file();
*** xdvi-pl17+miyu.patch-beta4/Imakefile	Mon Sep 13 22:37:25 1993
--- xdvi-pl17+miyu.patch-beta4+markpage+toc+printdvi/Imakefile	Mon Sep 13 22:05:28 1993
***************
*** 7,12 ****
--- 7,15 ----
  #define	Use_ZEIT
  #define	Use_NTTZEIT
  #define	Use_PS
+ #define	Use_MARKPAGE
+ #define	Use_TOC
+ #define	Use_PRINTDVI
  
  #include "XDvi.defs"
  #include "XDvi.rules"
***************
*** 76,81 ****
--- 79,119 ----
  PS_DEFS=
  #endif	/* Use_PS */
  
+ #ifdef	Use_MARKPAGE
+ RINGSIZE=1024
+ MARKPAGE_DEFS=-DMARKPAGE -DRINGSIZE=$(RINGSIZE)
+ #else
+ MARKPAGE_DEFS=
+ #endif	/* Use_MARKPAGE */
+ 
+ #ifdef	Use_TOC
+ MAX_PAGE=1024
+ TOC_DEFS=-DTOC -DMAX_PAGE=$(MAX_PAGE)
+ #else
+ TOC_DEFS=
+ #endif	/* Use_TOC */
+ 
+ #ifdef	Use_PRINTDVI
+ /* Print-out command templates */
+ PRCMDALL="(cd %d; dvi2ps %F) | lpr -P%p -J'%F'"
+ /* all pages of DVI file */
+ PRCMDCUR="(cd %d; dviselect -i %F -o /tmp/%F:%c@%r.dvi =%c; dvi2ps /tmp/%F:%c@%r.dvi) | lpr -P%p -J'%F (Page %c)'; /bin/rm /tmp/%F:%c@%r.dvi"
+ /* the current page */
+ PRCMDMRK="(cd %d; dviselect -i %F -o /tmp/%F:%m@%r.dvi =%m; dvi2ps /tmp/%F:%m@%r.dvi) | lpr -P%p -J'%F (Page %m)'; /bin/rm /tmp/%F:%m@%r.dvi"
+ /* the lastly marked page */
+ PRCMDRGN="(cd %d; dviselect -i %F -o /tmp/%F:%s-%e@%r.dvi =%s:%e; dvi2ps /tmp/%F:%s-%e@%r.dvi) | lpr -P%p -J'%F (Page %s-%e)'; /bin/rm /tmp/%F:%s-%e@%r.dvi"
+ /* pages in the region, between the current page and the lastly marked page */
+ PRCMDLST="(cd %d; dviselect -i %F -o /tmp/%F:%t@%r.dvi %A; dvi2ps /tmp/%F:%t@%r.dvi) | lpr -P%p -J'%F (Page %t)'; /bin/rm /tmp/%F:%t@%r.dvi"
+ /* all marked pages */
+ DVIPRINTER="lp"
+ /* the default printer to print-out DVI file */
+ PRINT_DEFS=-DPRINTDVI -DPRCMDALL=\"$(PRCMDALL)\" -DPRCMDCUR=\"$(PRCMDCUR)\" \
+            -DPRCMDMRK=\"$(PRCMDMRK)\" -DPRCMDRGN=\"$(PRCMDRGN)\" \
+            -DPRCMDLST=\"$(PRCMDLST)\" -DDVIPRINTER=\"$(DVIPRINTER)\"
+ #else
+ PRINT_DEFS=
+ #endif	/* Use_PRINTDVI */
+ 
  #undef	XMachineDep
  
  #ifdef	i386
***************
*** 88,94 ****
       XMachineDep \
       -DUSE_PK -DUSE_GF -DUSE_PXL -DBUTTONS -DGREY -UTEXXET \
       -DSEARCH_SUBDIRECTORIES -UXDVIFONTS_ONLY \
!      $(SELFILE_DEFS) $(KANJI_DEFS) $(ZEIT_DEFS) $(PS_DEFS)
  
  CDEBUGFLAGS=-g
  
--- 126,133 ----
       XMachineDep \
       -DUSE_PK -DUSE_GF -DUSE_PXL -DBUTTONS -DGREY -UTEXXET \
       -DSEARCH_SUBDIRECTORIES -UXDVIFONTS_ONLY \
!      $(SELFILE_DEFS) $(KANJI_DEFS) $(ZEIT_DEFS) $(PS_DEFS) \
!      $(MARKPAGE_DEFS) $(TOC_DEFS) $(PRINT_DEFS)
  
  CDEBUGFLAGS=-g
  
***************
*** 120,129 ****
  #define	PS_OBJS
  #endif	/* Use_PS */
  
  SRCS=xdvi.c dvi_init.c dvi_draw.c fontfmts.c vf.c util.c font_open.c tpic.c \
!      SELFILE_SRCS PS_SRCS
  OBJS=xdvi.o dvi_init.o dvi_draw.o fontfmts.o vf.o util.o font_open.o tpic.o \
!      SELFILE_OBJS PS_OBJS
  
  DEFINES=$(DEFS) -DDEFAULT_FONT_PATH=\"$(DEFAULT_FONT_PATH)\" \
    -DDEFAULT_VF_PATH=\"$(DEFAULT_VF_PATH)\" \
--- 159,192 ----
  #define	PS_OBJS
  #endif	/* Use_PS */
  
+ #ifdef	Use_MARKPAGE
+ #define MARKPAGE_SRCS	markpage.c markring.c
+ #define MARKPAGE_OBJS	markpage.o markring.o
+ #else
+ #define MARKPAGE_SRCS
+ #define MARKPAGE_OBJS
+ #endif	/* Use_MARKPAGE */
+ 
+ #ifdef	Use_TOC
+ #define TOC_SRCS	toc.c
+ #define TOC_OBJS	toc.o
+ #else
+ #define TOC_SRCS
+ #define TOC_OBJS
+ #endif	/* Use_TOC */
+ 
+ #ifdef	Use_PRINTDVI
+ #define PRINT_SRCS	print.c
+ #define PRINT_OBJS	print.o
+ #else
+ #define PRINT_SRCS
+ #define PRINT_OBJS
+ #endif	/* Use_PRINTDVI */
+ 
  SRCS=xdvi.c dvi_init.c dvi_draw.c fontfmts.c vf.c util.c font_open.c tpic.c \
!      SELFILE_SRCS PS_SRCS MARKPAGE_SRCS TOC_SRCS PRINT_SRCS
  OBJS=xdvi.o dvi_init.o dvi_draw.o fontfmts.o vf.o util.o font_open.o tpic.o \
!      SELFILE_OBJS PS_OBJS MARKPAGE_OBJS TOC_OBJS PRINT_OBJS
  
  DEFINES=$(DEFS) -DDEFAULT_FONT_PATH=\"$(DEFAULT_FONT_PATH)\" \
    -DDEFAULT_VF_PATH=\"$(DEFAULT_VF_PATH)\" \
*** xdvi-pl17+miyu.patch-beta4/xdvi.c	Mon Sep 13 22:37:33 1993
--- xdvi-pl17+miyu.patch-beta4+markpage+toc+printdvi/xdvi.c	Mon Sep 13 22:03:26 1993
***************
*** 31,38 ****
--- 31,42 ----
   *	TEXXET	support reflection dvi codes (right-to-left typesetting)
   *	GREY	use grey levels to shrink fonts
   *	SELFILE	support for the SelFile selection widget
+  *	MARKPAGE	support for MarkRing of page
+  *	TOC	support for Table-of-Contents widget as page list
+  *	PRINTDVI	support for print-out menu
   */
  
+ #include <stdio.h>
  #ifndef	ALTFONT
  #define	ALTFONT	"cmr10"
  #endif
***************
*** 66,71 ****
--- 70,79 ----
  #endif
  #include "xdvi.h"
  
+ #ifdef	MARKPAGE
+ #include "markpage.h"
+ #endif	/* MARKPAGE */
+ 
  #include "patchlevel.h"
  static	struct {_Xconst char	a[33], b, c, d;}
  #ifndef X10
***************
*** 137,142 ****
--- 145,158 ----
  #endif
  #endif	/* TOOLKIT */
  
+ #ifdef	TOC
+ #include "toc.h"
+ #endif	/* TOC */
+ 
+ #ifdef	PRINTDVI
+ #include "print.h"
+ #endif	/* PRINTDVI */
+ 
  #ifdef	HAS_SIGIO
  #include <fcntl.h>
  #include <signal.h>
***************
*** 305,311 ****
  #define	ruleGC	foreGC
  #endif	/* X10 */
  
! static	int	pageno_correct	= 1;
  static	int	bak_shrink;
  
  #define	clip_w	mane.width
--- 321,331 ----
  #define	ruleGC	foreGC
  #endif	/* X10 */
  
! #ifdef	TOC
! EXTERN	int	pageno_correct = 1;
! #else
! static	int	pageno_correct = 1;
! #endif	/* TOC */
  static	int	bak_shrink;
  
  #define	clip_w	mane.width
***************
*** 376,382 ****
--- 396,406 ----
  static	Arg	form_args[] = {
  	{XtNdefaultDistance, (XtArgVal) 0},
  };
+ #ifdef	TOC
+ #define XTRA_WID	155
+ #else
  #define	XTRA_WID	79
+ #endif	/* TOC */
  
  static	Arg	line_args[] = {
  	{XtNbackground,	(XtArgVal) 0},
***************
*** 429,434 ****
--- 453,462 ----
  #ifdef	PS
  		{"PS Fig",	"psfig",	'\007',		670},
  #endif	/* PS */
+ 
+ #ifdef	PRINTDVI
+ 		{"Print",	"print",	'o',		730},
+ #endif	/* PRINTDVI */
  };
  
  static	void	handle_command();
***************
*** 485,490 ****
--- 513,521 ----
  		    command_args, XtNumber(command_args));
  	    }
  	}
+ #ifdef	TOC
+ 	Create_TOC(panel_widget, h);
+ #endif	/* TOC */
  }
  #endif	/* BUTTONS */
  
***************
*** 583,589 ****
--- 614,625 ----
  		sign		= 1;
  static	jmp_buf	canit_env;
  
+ #ifdef	TOC
+ static	void	can_exposures(), read_events();
+ extern	void	keystroke();
+ #else
  static	void	can_exposures(), read_events(), keystroke();
+ #endif	/* TOC */
  
  #ifdef	lint
  #ifndef	X10
***************
*** 1660,1666 ****
--- 1696,1706 ----
  #define	KeyPress	KeyPressed
  #endif	/* X10 */
  
+ #ifdef	TOC
+ void
+ #else
  static	void
+ #endif	/* TOC */
  keystroke(ch, number0, arg0, eventp)
  	char	ch;
  	int	number0;
***************
*** 1668,1673 ****
--- 1708,1716 ----
  	XEvent	*eventp;
  {
  	int	next_page;
+ #ifdef	MARKPAGE
+ 	PAGE    mark_page;
+ #endif	/* MARKPAGE */
  #ifdef	TOOLKIT
  	Window	ww;
  #endif
***************
*** 1703,1709 ****
--- 1746,1881 ----
  		break;
  	    case 'P':		/* declare current page */
  		pageno_correct = arg0 * number0 - current_page;
+ #ifdef	TOC
+ 		Set_Page();
+ #endif	/* TOC */ 
+ 		return;
+ #ifdef	MARKPAGE
+ 	    case '<':
+ 		/* go to the first page */
+ 		next_page = 0;
+ 		MarkPage(current_page);
+ 		break;
+ 	    case '>':
+ 		/* go to the last page */
+ 		next_page = total_pages - 1;
+ 		MarkPage(current_page);
+ 		break;
+ 	    case 'm':
+ 		/* Mark a page */
+ 		mark_page = (arg0 ? number0 - pageno_correct : current_page);
+ 		if (0 <= mark_page && mark_page < total_pages) {
+ 		  MarkPage(mark_page);
+ #ifdef	TOC
+ 		  Set_Page();
+ #endif	/* TOC */ 
+ 		}
+ 		else {
+ 		  goto bad;
+ 		}
+ 		return;
+ 	    case 'U':
+ 		/* Delete the mark */
+ 		mark_page = (arg0 ? number0 - pageno_correct : current_page);
+ 		if (0 <= mark_page && mark_page < total_pages) {
+ 		  if (ThisPageIsMarked(mark_page)) {
+ 		    UnmarkPage(mark_page);
+ #ifdef	TOC
+ 		    Set_Page();
+ #endif	/* TOC */ 
+ 		  }
+ 		  else {
+ 		    goto bad;
+ 		  }
+ 		}
+ 		else {
+ 		  goto bad;
+ 		}
+ 		return;
+ 	    case 'a':
+ 		/* Mark all pages */
+ 		for(mark_page = 0; mark_page < total_pages; mark_page++) {
+ 		  MarkPage(mark_page);
+ 		}
+ #ifdef	TOC
+ 		Set_Page();
+ #endif	/* TOC */ 
+ 		return;
+ 	    case 'A':
+ 		/* Unmark all pages */
+ 		if(! EmptyPageMarkRing()) {
+ 		  MakePageMarkRingNull();
+ #ifdef	TOC
+ 		  Set_Page();
+ #endif	/* TOC */ 
+ 		}
+ 		else {
+ 		  goto bad;
+ 		}
  		return;
+ 	    case '\'':
+ 		/* Goto lastly marked page */
+ 		if (! EmptyPageMarkRing()) {
+ 		  PAGE last_mark;
+ 
+ 		  last_mark = LastMarkPage();
+ 		  mark_page = last_mark;
+ 		  while (! (0 <= mark_page && mark_page < total_pages)) {
+ 		    RotatePageMarkRing();
+ 		    mark_page = LastMarkPage();
+ 		    if ( mark_page==last_mark ) {
+ 		      goto bad;
+ 		    }
+ 		  }
+ 		  next_page = mark_page;
+ 		}
+ 		else {
+ 		  goto bad;
+ 		}
+ 		break;
+ 	    case '\"':
+ 		/* Exchange current page and lastly marked page */
+ 		if (! EmptyPageMarkRing()) {
+ 		  PAGE last_mark;
+ 
+ 		  last_mark = LastMarkPage();
+ 		  mark_page = last_mark;
+ 		  while (! (0 <= mark_page && mark_page < total_pages)) {
+ 		    RotatePageMarkRing();
+ 		    mark_page = LastMarkPage();
+ 		    if ( mark_page==last_mark ) {
+ 		      goto bad;
+ 		    }
+ 		  }
+ 		  SetPageMarkAtLast(next_page);
+ 		  next_page = mark_page;
+ 		}
+ 		else {
+ 		  goto bad;
+ 		}
+ 		break;
+ 	    case '`':
+ 		/* Trace back Page Mark Ring */
+ 		if (! EmptyPageMarkRing()) {
+ 		  PAGE last_mark;
+ 
+ 		  last_mark = LastMarkPage();
+ 		  mark_page = last_mark;
+ 		  while (! (0 <= mark_page && mark_page < total_pages)) {
+ 		    RotatePageMarkRing();
+ 		    mark_page = LastMarkPage();
+ 		    if ( mark_page==last_mark ) {
+ 		      goto bad;
+ 		    }
+ 		  }
+ 		  RotatePageMarkRing();
+ 		  next_page = mark_page;
+ 		}
+ 		else {
+ 		  goto bad;
+ 		}
+ 		break;
+ #endif	/* MARKPAGE */
  #ifdef	VI_KEY
  	    case 'K':		/* toggle keep-position flag */
  #else	/* VI_KEY */
***************
*** 1843,1848 ****
--- 2015,2026 ----
  		return;
  #endif	/* TOOLKIT */
  
+ #ifdef	PRINTDVI
+ 	    case 'o':                       /* Print out */
+                 print_DVI_file (top_level);
+ 		return;
+ #endif	/* PRINTDVI */
+ 
  #ifndef	VI_KEY
  #ifndef X10
  	    case '\020':	/* Control P */
***************
*** 1917,1922 ****
--- 2095,2104 ----
  	if (0 <= next_page && next_page < total_pages) {
  	    if (current_page != next_page) {
  		current_page = next_page;
+ #ifdef	TOC
+ 		if ( ! resource.expert )
+ 		  Set_Page();
+ #endif	/* TOC */
  		hush_spec_now = hush_spec;
  		if (!RESOURCE(keep_flag)) home(False);
  	    }
***************
*** 1971,1976 ****
--- 2153,2161 ----
  	    temp_args[0].value = (XtArgVal) title_name;
  	    XtSetValues(top_level, temp_args, XtNumber(temp_args));
  #endif
+ #ifdef	MARKPAGE
+ 	    MakePageMarkRingNull();
+ #endif	/* MARKPAGE */
  	} else {
  	    /* User cancelled, so open old file */
  	    if (open)
***************
*** 3124,3129 ****
--- 3309,3318 ----
  
  #endif	/* TOOLKIT */
  
+ #ifdef	MARKPAGE
+ 	CreateNewPageMarkRing();
+ #endif	/* MARKPAGE */
+ 
  #ifdef	SELFILE
  	/* There isn't a filename by here, so pop up a selection box  JSP */
  	if (dvi_name == NULL)
***************
*** 3151,3156 ****
--- 3340,3353 ----
  	open_temp_ps_file();
  #endif	/* PS_LITERAL */
  	open_dvi_file();
+ 
+ #ifdef	MARKPAGE
+ 	MakePageMarkRingNull();
+ #endif	/* MARKPAGE */
+ #ifdef	PRINTDVI
+ 	InitPrintMenu();
+ #endif	/* PRINTDVI */
+ 
  	if (curr_page) {
  		current_page = (*curr_page ? atoi(curr_page) : total_pages) - 1;
  		if (current_page < 0 || current_page >= total_pages) usage();
*** xdvi-pl17+miyu.patch-beta4/mksedscript	Mon Sep 13 22:37:32 1993
--- xdvi-pl17+miyu.patch-beta4+markpage+toc+printdvi/mksedscript	Mon Sep 13 22:03:26 1993
***************
*** 27,32 ****
--- 27,40 ----
  	-DGREY)			GREY=y;;
  	-DSELFILE)		SELFILE=y;;
  	-DPS)			PS=y;;
+ 	-DMARKPAGE)		MARKPAGE=y;;
+ 	-DTOC)			TOC=y;;
+ 	-DPRINTDVI)		PRINTDVI=y;;
+ 	-DPRCMDALL=*)		PRCMDALL=$1;;
+ 	-DPRCMDCUR=*)		PRCMDCUR=$1;;
+ 	-DPRCMDMRK=*)		PRCMDMRK=$1;;
+ 	-DPRCMDRGN=*)		PRCMDRGN=$1;;
+ 	-DPRCMDLST=*)		PRCMDLST=$1;;
  	-DMAKEPK)		MAKEPK=-DMAKEPKCMD=\\\"MakeTeXPK\\\";;
  	-DMAKEPKCMD*)		MAKEPK=$1;;
  	-DBDPI=*)		BDPI=$1;;
***************
*** 50,55 ****
--- 58,78 ----
  if test -z "$GREY";	then	echo	'/^#ifgrey/,/^#/d';	fi
  if test -z "$SELFILE";	then	echo	'/^#ifselfile/,/^#/d';	fi
  if test -z "$PS";	then	echo	'/^#ifps/,/^#/d';	fi
+ if test -z "$MARKPAGE";	then
+ 	echo	'/^#ifmarkpage/,/^#endifmarkpage/d'
+ fi
+ if test -z "$TOC";	then
+ 	echo	'/^#iftoc/,/^#endiftoc/d'
+ fi
+ if test -z "$PRINTDVI";	then
+ 	echo	'/^#ifprintdvi/,/^#endifprintdvi/d'
+ else
+ 	echo	"s_%%prcmdall%%_`echo $PRCMDALL | sed s/-DPRCMDALL=//`_"
+ 	echo	"s_%%prcmdcur%%_`echo $PRCMDCUR | sed s/-DPRCMDCUR=//`_"
+ 	echo	"s_%%prcmdmrk%%_`echo $PRCMDMRK | sed s/-DPRCMDMRK=//`_"
+ 	echo	"s_%%prcmdrgn%%_`echo $PRCMDRGN | sed s/-DPRCMDRGN=//`_"
+ 	echo	"s_%%prcmdlst%%_`echo $PRCMDLST | sed s/-DPRCMDLST=//`_"
+ fi
  if test -z "$MAKEPK";	then	echo	'/^#ifmakepk/,/^#/d'
  	else	echo	"s;%%mkpk%%;`echo $MAKEPK | sed s/-DMAKEPKCMD=//`;"
  	fi
*** xdvi-pl17+miyu.patch-beta4/xdvi_man.sed	Mon Sep 13 22:37:34 1993
--- xdvi-pl17+miyu.patch-beta4+markpage+toc+printdvi/xdvi_man.sed	Mon Sep 13 22:34:32 1993
***************
*** 426,431 ****
--- 426,500 ----
  .B F
  Open the window for file selection.
  #endif
+ #ifmarkpage
+ .TP
+ .B m
+ Marks the page with the given number. If no page number is given,
+ then it marks the current page.
+ Page marking behavior is like the Mark Ring of GNU Emacs (as Control-SPC),
+ but the detail is different from it; when the marks of a page are
+ duplicated, they are simplified to one mark, like the LRU-stack.
+ #iftoc
+ Also pushing Button 2 in TOC makes the page marked.
+ #endiftoc
+ .TP
+ .B U
+ Deletes mark of the page with the given number. If no page number is given,
+ then it deletes mark of the current page.
+ #iftoc
+ Also pushing Button 3 in TOC makes the page not marked.
+ #endiftoc
+ .TP
+ .B a
+ Marks all pages.
+ .TP
+ .B A
+ Deletes marks of all pages.
+ .TP
+ .B <
+ Marks the current page, and moves to the first page (like Meta-< of GNU Emacs).
+ It is same as 'm' and '1g'.
+ .TP
+ .B >
+ Marks the current page, and moves to the last page (like Meta-> of GNU Emacs).
+ It is same as 'm' and 'g'.
+ .TP
+ .B '
+ Moves to the lastly marked page.
+ .TP
+ .B \\\\"
+ Exchanges the current page and the lastly marked page, that is,
+ the current page is marked and moves to the lastly marked page,
+ then the last mark is deleted (like Control-x Control-x of GNU Emacs).
+ Exceptionally, if the current page was already marked, the last mark
+ would not be deleted. It marks the current page (this causes the current
+ page is lastly marked), and moves to the ex-lastly marked page.
+ .TP
+ .B `
+ Traces the page mark ring in the marked order, that is,
+ it moves to the lastly marked page, then
+ the lastly marked page is changed to the previous mark of it (like
+ Control-u Control-SPC of GNU Emacs).
+ When it reaches the oldest marked page, it loops back. Because the
+ page mark ring is cyclic.
+ #endifmarkpage
+ #ifprintdvi
+ .TP
+ .B o
+ Popup the print-out menu. The menu consists of ``All pages'',
+ ``Current page''
+ #ifmarkpage
+ , ``Marked page'', ``Region'', ``All marked pages''
+ #endifmarkpage
+ ; ``All pages'' means that all pages in the DVI file are printed.
+ ``Current page'' means that the current page is only printed.
+ #ifmarkpage
+ ``Marked page'' means that the lastly marked page is only printed.
+ ``Region'' means that pages in the region between the current page and
+ the lastly marked page are printed.
+ ``All marked pages'' means that the all marked page are printed.
+ #endifmarkpage
+ #endifprintdvi
  .SH MOUSE ACTIONS
  If the shrink factor is set to any number other than one, then clicking
  any mouse button will pop up a ``magnifying glass'' which shows the unshrunk
***************
*** 440,445 ****
--- 509,632 ----
  pushing Button 1 moves the image up or right by an amount equal to the distance
  from the button press to the upper left-hand corner of the window; pushing
  Button 3 moves the image down or left by the same amount.
+ #iftoc
+ .SH TABLE OF CONTENTS
+ The page number list is shown as TOC (table of contents).
+ The current page is marked with a '<' in the right margin of TOC.
+ #ifmarkpage
+ The marked pages are marked with a '*' in the left margin of TOC.
+ In particular, the lastly marked page is marked with '>' in the left
+ margin of TOC.
+ #endifmarkpage
+ Pushing Button 1 on a page number moves the current page to the page and
+ is marked with '<'.
+ #ifmarkpage
+ Pushing Button 2 on a page number makes the page marked.
+ Pushing Button 3 on a page number makes the page not marked.
+ Button 2 and 3 can be drugged, then makes all drugged pages marked/not
+ marked.
+ #endifmarkpage
+ #endiftoc
+ #ifprintdvi
+ .SH PRINT-OUT
+ Xdvi has no functions to select necessary pages for print-out and to
+ print-out these pages inside itself.
+ Therefore, xdvi requires external commands at the print-out work, for
+ example, dviselect, dvi2ps, dvips, and so on.
+ So these commands should be installed before xdvi is installed.
+ .PP
+ In order to print-out with these external commands, xdvi has command
+ strings. Xdvi interprets the corresponding command string to the
+ selected print-out work from popup menu. The interpretation is that the
+ internal variables in the command string are instantiated and the
+ instantiated command string is executed.
+ .PP
+ The meanings of internal variables are shown in the following.
+ .TP
+ .B %f
+ Filename of DVI file (full pathname)
+ .TP
+ .B %F
+ Filename of DVI file (basename of pathname)
+ .TP
+ .B %d
+ Directory where DVI file is placed (directory of pathname)
+ .TP
+ .B %p
+ Printer name (if the environment variable PRINTER is defined, use it)
+ .TP
+ .B %r
+ Proces id of xdvi
+ .PP
+ The following variables denote absolute page number.
+ .TP
+ .B %c
+ Current page number
+ #ifmarkpage
+ .TP
+ .B %m
+ Lastly marked page number
+ .TP
+ .B %s
+ Start page number of region; minimum of %c and %m
+ .TP
+ .B %e
+ End page number of region; maximum of %c and %m
+ .TP
+ .B %l
+ Marked page list; marked order; separated by ","
+ .TP
+ .B %L
+ Marked page list; marked order; separated by " "
+ .TP
+ .B %t
+ Marked page list; sorted; separated by ","
+ .TP
+ .B %T
+ Marked page list; sorted; separated by " "
+ .TP
+ .B %k
+ Like %l; '=' is put on each page number (assumed dviselect)
+ .TP
+ .B %K
+ Like %L; '=' is put on each page number (assumed dviselect)
+ .TP
+ .B %a
+ Like %t; '=' is put on each page number (assumed dviselect)
+ .TP
+ .B %A
+ Like %T; '=' is put on each page number (assumed dviselect)
+ #endifmarkpage
+ .PP
+ The print-out popup menu has the command strings as following.
+ .TP
+ .B ``All pages''
+ %%prcmdall%%
+ .TP
+ .B ``Current page''
+ %%prcmdcur%%
+ #ifmarkpage
+ .TP
+ .B ``Marked page''
+ %%prcmdmrk%%
+ .TP
+ .B ``Region''
+ %%prcmdrgn%%
+ .TP
+ .B ``All marked pages''
+ %%prcmdlst%%
+ #endifmarkpage
+ .PP
+ For example, it is assumed that the command string to print-out
+ ``Current page'' is defined as ``(cd %d; dviselect -i %F -o
+ /tmp/%F:%c@%r.dvi =%c; dvi2ps /tmp/%F:%c@%r.dvi) | lpr -P%p -J'%F (Page
+ %c)'; /bin/rm /tmp/%F:%c@%r.dvi'', and xdvi displays the file
+ /home/foo/bar.dvi. This command string is instantiated into ``(cd
+ /home/foo; dviselect -i bar.dvi -o /tmp/bar.dvi:13@3255.dvi =13; dvi2ps
+ /tmp/bar.dvi:13@3255.dvi) | lpr -Plp -J'bar.dvi (Page 13)'; /bin/rm
+ /tmp/bar.dvi:13@3255.dvi'', where the process ID of xdvi is 3255 and
+ current page is 13 and printer name is ``lp''.
+ #endifprintdvi
  .SH ENVIRONMENT
  Uses the environment variable ``DISPLAY'' to specify which bit map display
  terminal to use.
*** xdvi-pl17+miyu.patch-beta4/README	Mon Sep 13 22:37:21 1993
--- xdvi-pl17+miyu.patch-beta4+markpage+toc+printdvi/README	Mon Sep 13 22:34:35 1993
***************
*** 110,115 ****
--- 110,125 ----
  	PS		(xdvi.c dvi_init.c gs-view.c ps.c tpic.c util.c)
  			Allow xdvi to preview dvi-file including Encapsulated
  			Postscript-style file using GNU Ghostscript.
+ 	MARKPAGE	(xdvi.c markpage.c markring.c)
+ 			Enables us to mark pages. Page marking is
+ 			implemented by the mark ring like GNU Emacs.
+ 	TOC		(xdvi.c toc.c) displays the Table-of-Contents
+ 			widget as page list. Page moving and marking can
+ 			be worked with TOC.
+ 	PRINTDVI	(xdvi.c print.c) Enables us to print-out all or
+ 			necessary pages by selecting from popup menu. It
+ 			requires the external dviwares, for example,
+ 			dviselect, dvi2ps, and so on.
  
  All flags should be set in the appropriate Makefile via the variable ``DEFS''.
  
