(FILECREATED "24-May-84 17:25:43" {DSK}TEDITFILE.;9 54549  

      changes to:  (FNS \DWIN \DWOUT)

      previous date: "24-May-84 13:57:37" {DSK}TEDITFILE.;8)


(PRETTYCOMPRINT TEDITFILECOMS)

(RPAQQ TEDITFILECOMS ((FILES TEXTOFD TEDITABBREV TEDITLOOKS IMAGEOBJ TFBRAVO)
	(FNS TEDIT.BUILD.PCTB TEDIT.FORMATTEDFILEP TEDIT.GET TEDIT.INCLUDE TEDIT.INCLUDE.SPAN 
	     TEDIT.PUT TEDIT.PUT.PCTB TEDIT.PUT.PIECE.DESCRIPTOR \ATMIN \ATMOUT \DWIN \DWOUT 
	     \STRINGIN \STRINGOUT \TEDIT.FORMATTEDP1 \TEDIT.INCLUDE.SPAN \WATOM \WSTRING)
	(GLOBALVARS TEDIT.INPUT.FORMATS)
	(INITVARS (TEDIT.INPUT.FORMATS NIL))))
(FILESLOAD TEXTOFD TEDITABBREV TEDITLOOKS IMAGEOBJ TFBRAVO)
(DEFINEQ

(TEDIT.BUILD.PCTB
  [LAMBDA (TEXT TEXTOBJ START END DEFAULTLOOKS DEFAULTPARALOOKS CLEARGET?)
                                                             (* jds "18-May-84 16:37")
                                                             (* START = 1st char of file to read from, if specified)
                                                             (* END = use this as eofptr of file.
							     For use in reading files within files.)
    (PROG [SEL LINES PCTB PC OLDPC PCCOUNT TYPECODE PCLEN CHLOOKSSEEN NEWPC PARALOOKSSEEN 
	       PIECEINFOCH# CACHE CACHE? TTEXTOBJ USER.CMFILE TSTREAM USERFILEFORMAT USERTEMP 
	       EXISTINGCHARLOOKS EXLOOK EXISTINGFMTSPECS (CURFILECH# (OR START 0))
	       (CURCH# 1)
	       (TEXTSTREAM (AND TEXTOBJ (fetch STREAMHINT of TEXTOBJ]
                                                             (* Get the number of pieces needed 
							     (if AN formatted file), otherwise PCCOUNT will be NIL)
          [SETQ DEFAULTPARALOOKS (OR DEFAULTPARALOOKS (COND
				       (TEXTOBJ (fetch FMTSPEC of TEXTOBJ))
				       (T (create FMTSPEC using TEDIT.DEFAULT.FMTSPEC]
          (COND
	    (TEXTOBJ (replace TXTFILE of TEXTOBJ with TEXT)))
          (SETQ DEFAULTLOOKS (OR DEFAULTLOOKS (CHARLOOKS.FROM.FONT TEDIT.DEFAULT.FONT)))
          (SETQ TEXT (\CREATEPIECEORSTREAM TEXT DEFAULTLOOKS DEFAULTPARALOOKS START END))
          [COND
	    ((STREAMP TEXT)
	      (AND TEXTOBJ (replace TXTFILE of TEXTOBJ with TEXT))
	      [COND
		((OR [AND TEXTOBJ (SETQ CACHE? (LISTGET (fetch EDITPROPS of TEXTOBJ)
							(QUOTE CACHE]
		     (NOT (RANDACCESSP TEXT)))               (* If the file device isn't rancom access, cache the 
							     file locally.)
                                                             (* Also do this if he asks for a local cache.)
		  (SETQ CACHE (OPENSTREAM (QUOTE {NODIRCORE})
					  (QUOTE BOTH)
					  (QUOTE NEW)))
		  (COPYBYTES TEXT CACHE START END)
		  (COND
		    (CACHE?                                  (* for the folx who don't trust the connections, since 
							     all their pcs will point to core, we can close the 
							     txtfile connection)
			    (CLOSEF TEXT)))
		  (SETQ TEXT CACHE)
		  (SETQ START (SETQ END NIL]
	      (SETQ PCCOUNT (\TEDIT.FORMATTEDP1 TEXT END]
          [COND
	    ((type? PIECE TEXT)                              (* If this isn't a text stream, build a piece table with
							     the one piece in it.)
	      (SETQ PCTB (\MAKEPCTB TEXT)))
	    (CLEARGET?                                       (* If the user wants an uninterpreted stream onto the 
							     file , build a piece table with the one piece in it.)
		       (SETQ TEXT (create PIECE
					  PFILE ← TEXT
					  PFPOS ←(COND
					    (START START)
					    (T 0))
					  PLEN ←(IDIFFERENCE (OR END (GETEOFPTR TEXT))
							     (COND
							       (START START)
							       (T 0)))
					  PREVPIECE ← NIL
					  PLOOKS ← DEFAULTLOOKS
					  PPARALAST ← NIL
					  PPARALOOKS ← DEFAULTPARALOOKS))
		       (SETQ PCTB (\MAKEPCTB TEXT)))
	    ((NOT PCCOUNT)                                   (* This is an unformatted file)
	      [COND
		((SETQ USERFILEFORMAT (for FILETYPE in TEDIT.INPUT.FORMATS
					 when (SETQ USERTEMP (APPLY* (CAR FILETYPE)
								     TEXT))
					 do (RETURN FILETYPE)))
                                                             (* The input file is in a user-sensible format, which he
							     is willing to convert for TEdit's use.)
                                                             (* See if there are Bravo headers)
		  (SETQ TSTREAM (APPLY* (CADR USERFILEFORMAT)
					TEXT USERTEMP))
		  (SETQ TTEXTOBJ (TEXTOBJ TSTREAM))
		  (SETQ PCTB (fetch PCTB of TTEXTOBJ)))
		(T                                           (* Nope--it's straight unformatted text)
		   (SETQ PCTB (\MAKEPCTB (create PIECE
						 PFILE ← TEXT
						 PFPOS ← CURFILECH#
						 PLEN ←(IDIFFERENCE (OR END (GETEOFPTR TEXT))
								    CURFILECH#)
						 PREVPIECE ← NIL
						 PLOOKS ← DEFAULTLOOKS
						 PPARALAST ← NIL
						 PPARALOOKS ← DEFAULTPARALOOKS]
                                                             (* So create a single piece to describe its contents)
	      )
	    ((LISTP PCCOUNT)                                 (* This is an obsolete version of the TEdit file 
							     format.)
	      (SELECTQ (CAR PCCOUNT)
		       (0                                    (* VERSION 0)
			  (SETQ PCTB (TEDIT.BUILD.PCTB0 TEXT TEXTOBJ (CDR PCCOUNT)
							START END)))
		       (SHOULDNT 
			 "Impossible obsolete version ID while trying to convert old TEdit file.")))
	    (T                                               (* This IS a TEdit-format file, so read in all the 
							     parts.)
	       (SETQ PCTB (\MAKEPCTB NIL PCCOUNT))
	       (SETFILEPTR TEXT (IDIFFERENCE (OR END (GETEOFPTR TEXT))
					     8))
	       (SETQ PIECEINFOCH# (\DWIN TEXT))
	       (SETFILEPTR TEXT PIECEINFOCH#)
	       (bind (OLDPC ← NIL)
		     (OLDPARALOOKS ← DEFAULTPARALOOKS) for I from 1 to PCCOUNT as PCN from 
										\FirstPieceOffset
		  by \EltsPerPiece
		  do (SETQ PC NIL)                           (* This loop may not really read a piece, so we have to 
							     distinguish that case.)
		     (SETQ PCLEN (\DWIN TEXT))
		     (SETQ TYPECODE (\SMALLPIN TEXT))        (* What kind of piece is it?)
		     (SELECTC TYPECODE
			      (\PieceDescriptorPARA          (* Reading a new set of paragraph looks.)
						    (AND OLDPC (replace PPARALAST of OLDPC
								  with T))
                                                             (* Mark the end of the preceding paragraph.)
						    (SETQ OLDPARALOOKS (TEDIT.GET.PARALOOKS TEXT))
                                                             (* Get the new set of looks, for use by later pieces.)
						    (AND TEXTOBJ (replace FORMATTEDP of TEXTOBJ
								    with T))
                                                             (* Mark the document as containing paragraph formatting 
							     info)
						    (add PCN (IMINUS \EltsPerPiece))
                                                             (* This didn't create a piece -- don't count it in the 
							     PCTB placement.)
						    )
			      (\PieceDescriptorLOOKS         (* New character looks. Build a piece to describe those 
							     characters.)
						     (SETQ PC
						       (create PIECE
							       PFILE ← TEXT
							       PFPOS ← CURFILECH#
							       PLEN ← PCLEN
							       PREVPIECE ← OLDPC
							       PPARALOOKS ← OLDPARALOOKS))
                                                             (* Build the new piece)
						     (COND
						       (OLDPC 
                                                             (* If there's a prior piece, hook this one on the 
							     chain.)
							      (replace NEXTPIECE of OLDPC
								 with PC)))
						     (TEDIT.GET.CHARLOOKS PC TEXT)
                                                             (* Read the character looks for this guy.)
						     (add CURFILECH# (fetch PLEN of PC))
                                                             (* And note the passing of characters.)
						     )
			      (\PieceDescriptorOBJECT        (* It describes an object. Read that, and perhaps some 
							     description of the charlooks to go with it.)
						      (SETQ PC
							(create PIECE
								PFILE ← TEXT
								PFPOS ← CURFILECH#
								PLEN ← PCLEN
								PREVPIECE ← OLDPC
								PPARALOOKS ← OLDPARALOOKS))
						      (COND
							(OLDPC 
                                                             (* If there's a prior piece, hook this one on the 
							     chain.)
							       (replace NEXTPIECE of OLDPC
								  with PC)))
						      (TEDIT.GET.OBJECT TEXTSTREAM PC TEXT CURFILECH#)
						      (add CURFILECH# (fetch PLEN of PC))
						      [COND
							((NOT (ZEROP (\BIN TEXT)))
                                                             (* There are new character looks for this object.
							     Read them in.)
							  (\DWIN TEXT)
							  (\WIN TEXT)
                                                             (* Skip over the piece-type code we know has to be 
							     here.)
							  (TEDIT.GET.CHARLOOKS PC TEXT))
							(T 
                                                             (* No new looks; steal them from the prior piece.)
							   (replace PLOOKS of PC
							      with (OR (AND OLDPC
									    (fetch PLOOKS
									       of OLDPC))
								       DEFAULTLOOKS]
						      (replace PLEN of PC with 1)
                                                             (* OBJECTs are officially one character long.)
						      )
			      (SHOULDNT "Impossible piece-type code in BUILD.PCTB"))
		     (COND
		       (PC                                   (* If we created a piece, save it in the table.)
			   [COND
			     ((SETQ EXLOOK (for LOOK in EXISTINGCHARLOOKS
					      thereis (EQCLOOKS (fetch PLOOKS of PC)
								LOOK)))
                                                             (* These charlooks are a duplicate of pre-existing ones.
							     Re-use the old one.)
			       (replace PLOOKS of PC with EXLOOK))
			     (T (push EXISTINGCHARLOOKS (fetch PLOOKS of PC]
			   [COND
			     ((SETQ EXLOOK (for LOOK in EXISTINGFMTSPECS
					      thereis (EQUALALL (fetch PPARALOOKS of PC)
								LOOK)))
                                                             (* These paralooks are a duplicate of pre-existing ones.
							     Re-use the old one.)
			       (replace PPARALOOKS of PC with EXLOOK))
			     (T (push EXISTINGFMTSPECS (fetch PPARALOOKS of PC]
			   (\EDITSETA PCTB PCN CURCH#)
			   (\EDITSETA PCTB (ADD1 PCN)
				      PC)
			   (add CURCH# (fetch PLEN of PC))
			   (SETQ OLDPC PC)))
		  finally (\EDITSETA PCTB PCN CURCH#)
			  (\EDITSETA PCTB (ADD1 PCN)
				     (QUOTE LASTPIECE))
			  (\EDITSETA PCTB \PCTBLastPieceOffset (ADD1 PCN))
			  (\EDITSETA PCTB \PCTBFreePieces 0]
          (RETURN PCTB])

(TEDIT.FORMATTEDFILEP
  [LAMBDA (STREAM)                                           (* gbn "18-Apr-84 11:29")
                                                             (* Test to see if this stream's text would need a 
							     TEdit-format file (T) or is just plain text 
							     (NIL))
    (PROG ((TEXTOBJ (TEXTOBJ STREAM))
	   (FONTFILE NIL)
	   OLDPARALOOKS PC OLDLOOKS PREVPC TENTATIVE)
          (SETQ OLDPARALOOKS (fetch FMTSPEC of TEXTOBJ))
          (SETQ TENTATIVE (LISTGET (fetch EDITPROPS of TEXTOBJ)
				   (QUOTE TEDIT.TENTATIVE)))
                                                             (* If edits are to be shown)
          (SETQ PC (\EDITELT (fetch PCTB of TEXTOBJ)
			     (ADD1 \FirstPieceOffset)))      (* First piece in the document)
          (SETQ OLDLOOKS (OR (fetch DEFAULTCHARLOOKS of TEXTOBJ)
			     TEDIT.DEFAULT.CHARLOOKS))
          (while (AND PC (NOT FONTFILE))
	     do [COND
		  ((fetch POBJ of PC)                        (* OBJECTS require the special format)
		    (SETQ FONTFILE (QUOTE IMAGEOBJ)))
		  ([AND (OR (NOT PREVPC)
			    (fetch PPARALAST of PREVPC))
			(NOT (EQUALALL (fetch PPARALOOKS of PC)
				       (fetch FMTSPEC of TEXTOBJ]
                                                             (* We just hit a paragraph break.)
		    (SETQ FONTFILE (QUOTE PARALOOKS)))
		  ([OR (NOT (EQCLOOKS OLDLOOKS (fetch PLOOKS of PC)))
		       (AND TENTATIVE (OR (AND PREVPC (NEQ (fetch PNEW of PREVPC)
							   (fetch PNEW of PC)))
					  (AND (NOT PREVPC)
					       (fetch PNEW of PC]
                                                             (* Change in font, size, etc.)
		    (SETQ FONTFILE (QUOTE CHARLOOKS]
		(SETQ PREVPC PC)
		(SETQ PC (fetch NEXTPIECE of PC)))
          (RETURN FONTFILE])

(TEDIT.GET
  [LAMBDA (TEXTOBJ FILE)                                     (* jds "20-Apr-84 14:00")
                                                             (* Get a new file (overwriting the one being edited.))
    (PROG (OFILE OCURSOR LINES USER.CMFILE RESP (SEL (fetch SEL of TEXTOBJ))
		 (PCTB (fetch PCTB of TEXTOBJ))
		 (TEDIT.GET.FINISHEDFORMS NIL))
          (COND
	    ([AND (fetch \DIRTY of TEXTOBJ)
		  (NOT (MOUSECONFIRM "Not Saved Yet... " "LEFT to Get anyway." (fetch PROMPTWINDOW
										  of TEXTOBJ]
                                                             (* Only do the GET if he knows he'll zorch himself.)
	      (RETURN)))
          [SETQ OFILE (OR FILE (MKATOM (TEDIT.GETINPUT TEXTOBJ "File to GET:  "]
          (COND
	    [(AND OFILE (INFILEP OFILE))                     (* Only if there's a file to load and the file exists.)
	      (RESETLST (RESETSAVE (TTYDISPLAYSTREAM (OR (fetch PROMPTWINDOW of TEXTOBJ)
							 PROMPTWINDOW)))
			(RESETSAVE (CURSOR WAITINGCURSOR))
			(\SHOWSEL (fetch SEL of TEXTOBJ)
				  NIL NIL)
			(\TEXTCLOSEF (fetch STREAMHINT of TEXTOBJ))
                                                             (* CLOSE the old files)
			(SETQ OFILE (OPENSTREAM OFILE (QUOTE INPUT)))
                                                             (* And open the new one.)
			[SETQ PCTB (replace PCTB of TEXTOBJ with (TEDIT.BUILD.PCTB OFILE TEXTOBJ NIL 
										   NIL
										   (fetch 
										 DEFAULTCHARLOOKS
										      of TEXTOBJ)
										   (fetch FMTSPEC
										      of TEXTOBJ]
			(for FORM in TEDIT.GET.FINISHEDFORMS do (EVAL FORM))
                                                             (* Do any necessary cleanup for outside packages)
			(SETQ LINES (fetch LINES of TEXTOBJ))
			(replace TXTFILE of TEXTOBJ with OFILE)
			(replace \DIRTY of TEXTOBJ with NIL)
			(replace NEXTLINE of LINES with NIL)
			(replace \INSERTNEXTCH of TEXTOBJ with -1)
			[replace TEXTLEN of TEXTOBJ with (SUB1 (\EDITELT PCTB
									 (SUB1 (\EDITELT PCTB 
									     \PCTBLastPieceOffset]
			(replace CH# of SEL with (replace CHLIM of SEL with 1))
			(replace DCH of SEL with 0)
			(replace POINT of SEL with (QUOTE LEFT))
			(replace SET of SEL with T)
			(replace SET of (fetch SCRATCHSEL of TEXTOBJ) with NIL)
			(replace SET of (fetch SHIFTEDSEL of TEXTOBJ) with NIL)
			(replace SET of (fetch MOVESEL of TEXTOBJ) with NIL)
			(replace SET of TEDIT.SELECTION with NIL)
			(replace SET of TEDIT.SHIFTEDSELECTION with NIL)
			(replace CARETLOOKS of TEXTOBJ with (\TEDIT.GET.INSERT.CHARLOOKS TEXTOBJ SEL))
			(\FILLWINDOW (fetch YBOT of LINES)
				     LINES TEXTOBJ)
			(\FIXSEL SEL TEXTOBJ)
			(\SHOWSEL SEL NIL T)
			(\TEDIT.WINDOW.TITLE TEXTOBJ (\TEDIT.ORIGINAL.WINDOW.TITLE (TEXTSTREAM.TITLE
										     TEXTOBJ)))
			(\TEDIT.SET.WINDOW.EXTENT TEXTOBJ (\TEDIT.MAINW TEXTOBJ))
			(\TEDIT.HISTORYADD TEXTOBJ (create TEDITHISTORYEVENT
							   THACTION ←(QUOTE Get]
	    (OFILE (TEDIT.PROMPTPRINT TEXTOBJ "[File not found.]"))
	    (T (TEDIT.PROMPTPRINT TEXTOBJ "[Get aborted.]" T])

(TEDIT.INCLUDE
  [LAMBDA (STREAM FILE START END)                            (* jds "21-May-84 16:56")
                                                             (* Obtain a file name, and include that file's contents 
							     at the place where the caret is.)
                                                             (* Returns T if the insertion happened, NIL if there was
							     no place to put it.)
    (SETQ STREAM (TEXTOBJ STREAM))
    (PROG ((SEL (fetch SEL of STREAM))
	   PCTB TEXTLEN NFILE NNFILE INSERTCH# INSPC LEN INSPC# PCLST NPC WASOPEN PCCOUNT)
          (COND
	    ((fetch SET of SEL)                              (* There is a place to do the include.)
	      [SETQ NFILE (OR FILE (MKATOM (TEDIT.GETINPUT STREAM "Name of the file to load:  "]
	      (OR NFILE (RETURN))                            (* If no file was given, don't bother INCLUDEing.)
	      (COND
		(END                                         (* This is the copy-part-of-a-file case, with file 
							     liable to be volatile. Copy it to core for protection)
		     (SETQ NNFILE (OPENSTREAM (QUOTE {NODIRCORE})
					      (QUOTE OUTPUT)
					      (QUOTE NEW)))
                                                             (* Create the holding file)
		     [SETQ NFILE (COND
			 ((OPENP NFILE)
			   (SETQ WASOPEN T)
			   NFILE)
			 (T (OPENFILE NFILE (QUOTE INPUT]    (* And copy the file-section into it.)
		     (COPYBYTES NFILE NNFILE START END)      (* must be copychars to respect eol conventions)
		     (OR WASOPEN (CLOSEF NFILE))
		     (CLOSEF NNFILE)
		     (SETQ NFILE NNFILE)
		     (SETQ START (SETQ END NIL))             (* Then pretend nothing happened.)
		     ))
	      (TEDIT.DO.BLUEPENDINGDELETE SEL STREAM)        (* Delete any text, if need be)
	      (SETQ TEXTLEN (fetch TEXTLEN of STREAM))       (* We need the POST-deletion text length for later, so 
							     this must come after the b-p-d.)
	      (\SHOWSEL SEL NIL NIL)                         (* Turn off SELs before we go any further)
	      [SETQ NFILE (TEXTOBJ (OPENTEXTSTREAM (OPENSTREAM NFILE (QUOTE INPUT))
						   NIL NIL NIL (LIST (QUOTE FONT)
								     (\TEDIT.GET.INSERT.CHARLOOKS
								       STREAM SEL]
                                                             (* Get a textobj to describe the include source file)
	      (COND
		((AND (fetch FORMATTEDP of NFILE)
		      (NOT (fetch FORMATTEDP of STREAM)))    (* If the includED text is formatted but this file 
							     isn't, let's format it!)
		  (\TEDIT.CONVERT.TO.FORMATTED STREAM))
		((AND (fetch FORMATTEDP of STREAM)
		      (NOT (fetch FORMATTEDP of NFILE)))     (* The TARGET document is formatted, but the INCLUDEd 
							     text isn't. Better format it before completing the 
							     include.)
		  (\TEDIT.CONVERT.TO.FORMATTED NFILE)))
	      (SETQ PCTB (fetch PCTB of STREAM))             (* HERE, because the conversion to formatted will 
							     lengthen the pctb)
	      [SETQ INSERTCH# (COND
		  ((EQ (fetch POINT of SEL)
		       (QUOTE LEFT))
		    (fetch CH# of SEL))
		  (T (ADD1 (fetch CHLIM of SEL]              (* Find the place to make the insertion.)
	      (SETQ INSPC# (OR (\CHTOPCNO INSERTCH# PCTB)
			       (\EDITELT PCTB \PCTBLastPieceOffset)))
                                                             (* Likewise, this is affected by the 
							     convert-to-formatted)
	      (SETQ INSPC (\EDITELT (fetch PCTB of STREAM)
				    (ADD1 INSPC#)))          (* The piece to make the insertion in)
	      [COND
		((NEQ INSPC (QUOTE LASTPIECE))
		  (COND
		    ((IGREATERP INSERTCH# (\EDITELT PCTB INSPC#))
                                                             (* Must split the piece.)
		      (SETQ INSPC (\SPLITPIECE INSPC INSERTCH# STREAM INSPC#))
		      (add INSPC# \EltsPerPiece)
		      (SETQ PCTB (fetch PCTB of STREAM))     (* Refresh the PCTB in case it grew.)
		      ]
	      (SETQ PCLST (fetch PCTB of NFILE))             (* A temporary pctb, holding the pieces which describe 
							     the INCLUDEd text)
	      [SETQ LEN (SUB1 (\EDITELT PCLST (SUB1 (\EDITELT PCLST \PCTBLastPieceOffset]
	      (SETQ PCCOUNT (IDIFFERENCE (SUB1 (\EDITELT PCLST \PCTBLastPieceOffset))
					 \FirstPieceOffset))
                                                             (* Remember how many slots in the PCTB we took up 
							     (i.e. 2 x # of pieces))
	      (\TEDIT.INSERT.PIECES STREAM INSERTCH# (SETQ PCLST (\EDITELT PCLST (ADD1 
										\FirstPieceOffset)))
				    LEN INSPC INSPC# NIL)
	      [COND
		((AND (fetch FORMATTEDP of STREAM)
		      (NOT (fetch FORMATTEDP of NFILE)))     (* If the includED text is formatted but this file 
							     isn't, let's format it!)
		  (\TEDIT.CONVERT.TO.FORMATTED STREAM INSERTCH# (IPLUS INSERTCH# LEN]
	      (\TEDIT.HISTORYADD STREAM (create TEDITHISTORYEVENT
						THACTION ←(QUOTE Include)
						THCH# ← INSERTCH#
						THLEN ← LEN
						THFIRSTPIECE ← PCLST))
	      (replace TEXTLEN of STREAM with (IPLUS TEXTLEN LEN))
	      (AND (fetch \WINDOW of STREAM)
		   (\FIXILINES STREAM SEL INSERTCH# LEN TEXTLEN))
	      (replace CHLIM of SEL with (IPLUS (replace CH# of SEL with INSERTCH#)
						LEN -1))     (* Now fix up the selection to be the included text, 
							     point←left, character selection grain.)
	      (replace DCH of SEL with LEN)
	      (replace DX of SEL with 0)
	      (replace POINT of SEL with (QUOTE RIGHT))      (* So that several things INCLUDED in sequence fall in 
							     sequence.)
	      (replace SELKIND of SEL with (QUOTE CHAR))
	      (replace SELOBJ of SEL with NIL)
	      (COND
		((fetch \WINDOW of STREAM)
		  (TEDIT.UPDATE.SCREEN STREAM)
		  (\FIXSEL SEL STREAM)
		  (\SHOWSEL SEL NIL T)))
	      (replace \DIRTY of STREAM with T)              (* Mark the document changed)
	      (\SETUPGETCH (create EDITMARK
				   PC ← INSPC
				   PCOFF ← 0
				   PCNO ←(IPLUS INSPC# PCCOUNT))
			   STREAM)                           (* Set the fileptr to the end of the insertion.)
	      T)
	    (T (TEDIT.PROMPTPRINT STREAM "Please choose the place for the INCLUDE first." T])

(TEDIT.INCLUDE.SPAN
  [LAMBDA (STREAM INCLUDE.FILE START END)                    (* jds "10-May-84 16:40")
                                                             (* Obtain a file name, and include that file's contents 
							     at the place where the caret is.)
                                                             (* no interpretation (alternate file type e.g. Bravo) 
							     takes place. Simply include the characters)
                                                             (* Returns T if the insertion happened, NIL if there was
							     no place to put it.)
    (PROG ((STREAM (TEXTOBJ STREAM))
	   (START START)
	   (END END)
	   SEL PCTB TEXTLEN INFILE HOLDING.FILE INSERTCH# INSPC LEN INSPC# PCLST NPC WASOPEN PCCOUNT)
          (SETQ SEL (fetch SEL of STREAM))
          (COND
	    ((NOT (fetch SET of SEL))                        (* no place to include. return nil)
	      (RETURN NIL))
	    (T                                               (* There is a place to do the include.)
	       [SETQ INFILE (OR INCLUDE.FILE (MKATOM (TEDIT.GETINPUT STREAM 
						    "File to include span from:  (NIL to abort) "]
	       (OR INFILE (RETURN))                          (* If no file was given, don't bother INCLUDEing.)
	       (COND
		 (END                                        (* This is the copy-part-of-a-file case, with file 
							     liable to be volatile. Copy it to core for protection)
		      (SETQ HOLDING.FILE (OPENSTREAM (QUOTE {NODIRCORE})
						     (QUOTE OUTPUT)
						     (QUOTE NEW)))
                                                             (* Create the holding file)
		      [SETQ INFILE (COND
			  ((OPENP INFILE)
			    (SETQ WASOPEN T)
			    INFILE)
			  (T (OPENFILE INFILE (QUOTE INPUT]
                                                             (* And copy the file-section into it.)
		      (COPYBYTES INFILE HOLDING.FILE START END)
                                                             (* must be copychars to respect eol conventions)
		      (COND
			((NOT WASOPEN)
			  (CLOSEF INFILE)))
		      (CLOSEF HOLDING.FILE)
		      (SETQ INFILE HOLDING.FILE)
		      (SETQ START (SETQ END NIL))            (* Then pretend nothing happened.)
		      ))
	       (TEDIT.DO.BLUEPENDINGDELETE SEL STREAM)       (* Delete any text, if need be)
	       (SETQ TEXTLEN (fetch TEXTLEN of STREAM))      (* We need the POST-deletion text length for later, so 
							     this must come after the b-p-d.)
	       (\SHOWSEL SEL NIL NIL)                        (* Turn off SELs before we go any further)
	       [SETQ INFILE (TEXTOBJ (OPENTEXTSTREAM (OPENSTREAM INFILE (QUOTE INPUT))
						     NIL NIL NIL (LIST (QUOTE FONT)
								       (\TEDIT.GET.INSERT.CHARLOOKS
									 STREAM SEL)
								       (QUOTE CLEARGET)
								       T]
                                                             (* Get a textobj to describe the include source file)
	       (COND
		 ((AND (fetch FORMATTEDP of INFILE)
		       (NOT (fetch FORMATTEDP of STREAM)))   (* If the includED text is formatted but this file 
							     isn't, let's format it!)
		   (\TEDIT.CONVERT.TO.FORMATTED STREAM)))
	       (SETQ PCTB (fetch PCTB of STREAM))            (* HERE, because the conversion to formatted will 
							     lengthen the pctb)
	       [SETQ INSERTCH# (COND
		   ((EQ (fetch POINT of SEL)
			(QUOTE LEFT))
		     (fetch CH# of SEL))
		   (T (ADD1 (fetch CHLIM of SEL]             (* Find the place to make the insertion.)
	       (SETQ INSPC# (OR (\CHTOPCNO INSERTCH# PCTB)
				(\EDITELT PCTB \PCTBLastPieceOffset)))
                                                             (* Likewise, this is affected by the 
							     convert-to-formatted)
	       (SETQ INSPC (\EDITELT (fetch PCTB of STREAM)
				     (ADD1 INSPC#)))         (* The piece to make the insertion in)
	       [COND
		 ((NEQ INSPC (QUOTE LASTPIECE))
		   (COND
		     ((IGREATERP INSERTCH# (\EDITELT PCTB INSPC#))
                                                             (* Must split the piece.)
		       (SETQ INSPC (\SPLITPIECE INSPC INSERTCH# STREAM INSPC#))
		       (add INSPC# \EltsPerPiece)
		       (SETQ PCTB (fetch PCTB of STREAM))    (* Refresh the PCTB in case it grew.)
		       ]
	       (SETQ PCLST (fetch PCTB of INFILE))           (* A temporary pctb, holding the pieces which describe 
							     the INCLUDEd text)
	       [SETQ LEN (SUB1 (\EDITELT PCLST (SUB1 (\EDITELT PCLST \PCTBLastPieceOffset]
	       (SETQ PCCOUNT (IDIFFERENCE (\EDITELT PCLST \PCTBLastPieceOffset)
					  \FirstPieceOffset))
                                                             (* Remember how many pieces we inserted.)
	       (\TEDIT.INSERT.PIECES STREAM INSERTCH# (SETQ PCLST (\EDITELT PCLST (ADD1 
										\FirstPieceOffset)))
				     LEN INSPC INSPC# NIL)
	       [COND
		 ((AND (fetch FORMATTEDP of STREAM)
		       (NOT (fetch FORMATTEDP of INFILE)))   (* If the includED text is formatted but this file 
							     isn't, let's format it!)
		   (\TEDIT.CONVERT.TO.FORMATTED STREAM INSERTCH# (IPLUS INSERTCH# LEN]
	       (\TEDIT.HISTORYADD STREAM (create TEDITHISTORYEVENT
						 THACTION ←(QUOTE Include.Span)
						 THCH# ← INSERTCH#
						 THLEN ← LEN
						 THFIRSTPIECE ← PCLST))
	       (replace TEXTLEN of STREAM with (IPLUS TEXTLEN LEN))
	       (AND (fetch \WINDOW of STREAM)
		    (\FIXILINES STREAM SEL INSERTCH# LEN TEXTLEN))
	       (replace CHLIM of SEL with (IPLUS (replace CH# of SEL with INSERTCH#)
						 LEN -1))    (* Now fix up the selection to be the included text, 
							     point←left, character selection grain.)
	       (replace DCH of SEL with LEN)
	       (replace DX of SEL with 0)
	       (replace POINT of SEL with (QUOTE RIGHT))     (* So that several things INCLUDED in sequence fall in 
							     sequence.)
	       (replace SELKIND of SEL with (QUOTE CHAR))
	       (replace SELOBJ of SEL with NIL)
	       (COND
		 ((fetch \WINDOW of STREAM)
		   (TEDIT.UPDATE.SCREEN STREAM)
		   (\FIXSEL SEL STREAM)
		   (\SHOWSEL SEL NIL T)))
	       (replace \DIRTY of STREAM with T)             (* Mark the document changed)
	       (\SETUPGETCH (create EDITMARK
				    PC ← INSPC
				    PCOFF ← 0
				    PCNO ←(IPLUS INSPC# (ITIMES PCCOUNT \EltsPerPiece)))
			    STREAM)                          (* Set the fileptr to the end of the insertion.)
	       T])

(TEDIT.PUT
  [LAMBDA (STREAM FILE FORCENEW)                             (* gbn "25-Apr-84 01:39")
                                                             (* If the guy was editing a file, make a new updated 
							     version; else, ask for a file name)
                                                             (* If FILE is specd, it's used;
							     else the user must give us one)
    (PROG ((TEXTOBJ (TEXTOBJ STREAM))
	   OCURSOR OFILE FONTFILEUSED PROPS WINDOW PUTFN CLEARPUT CACHE (TEDIT.PUT.FINISHEDFORMS
	     NIL)
	   (TEDIT.GET.FINISHEDFORMS NIL)
	   (OUTPUT.FILE.WRITTEN NIL))
          (COND
	    (FILE                                            (* We were given a file to use.)
		  (SETQ OFILE FILE))
	    (FORCENEW                                        (* He insists on a new file. 
							     (without giving us one NIL))
		      (SETQ OFILE (TEDIT.GETINPUT TEXTOBJ "File to PUT to:  ")))
	    [(type? STREAM (fetch TXTFILE of TEXTOBJ))       (* There was a file!)
	      [SETQ OFILE (UNPACKFILENAME (fetch FULLFILENAME (fetch TXTFILE of TEXTOBJ]
	      (AND OFILE (LISTPUT OFILE (QUOTE VERSION)
				  NIL))
	      (SETQ OFILE (TEDIT.GETINPUT TEXTOBJ "File to PUT to:  " (AND OFILE (PACKFILENAME OFILE]
	    (T (SETQ OFILE (TEDIT.GETINPUT TEXTOBJ "File to PUT to:  "))
                                                             (* Get a file to put the text into)
	       ))
          (SETQ WINDOW (\TEDIT.MAINW TEXTOBJ))
          [COND
	    ([AND WINDOW (SETQ PROPS (WINDOWPROP WINDOW (QUOTE TEDIT.PROPS]
	      (SETQ PUTFN (LISTGET PROPS (QUOTE PUTFN)))
	      (SETQ CLEARPUT (LISTGET PROPS (QUOTE CLEARPUT)))
	      (SETQ CACHE (LISTGET PROPS (QUOTE CACHE]
          (COND
	    [OFILE (SETQ OFILE (OPENSTREAM (MKATOM OFILE)
					   (COND
					     (CACHE (QUOTE OUTPUT))
					     (T (QUOTE BOTH)))
					   (QUOTE NEW)
					   NIL
					   (COND
					     [CLEARPUT (QUOTE ((TYPE TEXT]
					     (T (QUOTE ((TYPE BINARY]
	    (T                                               (* If there's no file given, don't even try saving the 
							     file)
	       (RETURN)))
          (replace DESC of (fetch THISLINE of TEXTOBJ) with NIL)
          (COND
	    ((AND PUTFN (EQ (APPLY* PUTFN (fetch STREAMHINT of TEXTOBJ)
				    (fetch FULLNAME of OFILE)
				    (QUOTE BEFORE))
			    (QUOTE DON'T)))
	      (RETURN)))
          (TEDIT.PROMPTPRINT TEXTOBJ (CONCAT "PUTting file " (fetch FULLNAME of OFILE)
					     "...")
			     T)
          [COND
	    ((IGREATERP (fetch TEXTLEN of TEXTOBJ)
			0)
	      (SETQ FONTFILEUSED (TEDIT.PUT.PCTB TEXTOBJ OFILE CLEARPUT]
          (for FORM in TEDIT.PUT.FINISHEDFORMS do (EVAL FORM))
          (COND
	    ((OPENP OFILE)
	      (SETQ OUTPUT.FILE.WRITTEN T)                   (* We wrote a file. Remember the filename for next 
							     time.)
	      (CLOSEF OFILE)                                 (* Close the file, to free it up.)
	      [COND
		((NOT CACHE)                                 (* CSLI if caching do not need to reopen the output file
							     anyway)
		  (SETQ OFILE (OPENSTREAM (fetch FULLFILENAME of OFILE)
					  (QUOTE INPUT]      (* changed TEMPORary for ns filing with caching.
							     may not work in general)
                                                             (* And re-open it for INPUT only)

          (* (COND (FONTFILEUSED (* This file is formatted--build a compacted piece table.) (replace PCTB of TEXTOBJ with 
	  (TEDIT.BUILD.PCTB OFILE TEXTOBJ)) (for FORM in TEDIT.GET.FINISHEDFORMS do (EVAL FORM)) (* Finish up any left-over 
	  tasks caused by the pseudo-Get.)) (T (* Unformatted file--build a single-piece piece table.) 
	  (\CLEARPCTB (fetch PCTB of TEXTOBJ)) (\INSERTPIECE (\CREATEPIECEORSTREAM OFILE (fetch DEFAULTCHARLOOKS of TEXTOBJ)
) (QUOTE LASTPIECE) TEXTOBJ))))


	      (COND
		(OUTPUT.FILE.WRITTEN (CLOSEF? (fetch TXTFILE of TEXTOBJ))
				     (replace TXTFILE of TEXTOBJ with OFILE)))
	      (replace \DIRTY of TEXTOBJ with NIL)))
          (TEDIT.PROMPTPRINT TEXTOBJ "done.")
          (\TEDIT.WINDOW.TITLE TEXTOBJ (\TEDIT.ORIGINAL.WINDOW.TITLE (TEXTSTREAM.TITLE TEXTOBJ)))
          (replace \INSERTNEXTCH of TEXTOBJ with -1)
          (replace \INSERTPC of TEXTOBJ with NIL)            (* make sure that TEDIT doesn't try to just add to the 
							     \INSERTPC since it will now have a pfile property)
          (\TEDIT.HISTORYADD TEXTOBJ (create TEDITHISTORYEVENT
					     THACTION ←(QUOTE Put)
					     THCH# ← 0
					     THLEN ← 0
					     THFIRSTPIECE ← NIL))
          (AND PUTFN (APPLY* PUTFN (fetch STREAMHINT of TEXTOBJ)
			     (fetch FULLNAME of (fetch TXTFILE of TEXTOBJ))
			     (QUOTE AFTER)))                 (* CSLI changed to not presume ofile is the txtfile 
							     anymore)
                                                             (* Set up a history entry for this.)
      ])

(TEDIT.PUT.PCTB
  [LAMBDA (TEXTOBJ OFILE CLEARPUT SEPARATEFORMAT)            (* jds "10-May-84 16:39")
                                                             (* Put a representation of the piece table onto OFILE, 
							     preserving font changes and paragraph looks.
							     CLEARPUT means write no font or formatting info.)
    (PROG [OCURSOR CH PC PFILE PSTR POBJ OFILELEN OLDLOOKS (OLDPARALOOKS (fetch FMTSPEC of TEXTOBJ))
		   OLDCH# CURCH# PREVPC (FONTFILE NIL)
		   (PCCOUNT 0)
		   (TEDIT.PUT.FINISHEDFORMS NIL)
		   (EDITSTENTATIVE (LISTGET (fetch EDITPROPS of TEXTOBJ)
					    (QUOTE TEDIT.TENTATIVE)))
		   (PARALOOKSSEEN NIL)
		   (CACHE (LISTGET (fetch EDITPROPS of TEXTOBJ)
				   (QUOTE CACHE]
          (SETQ PC (\EDITELT (fetch PCTB of TEXTOBJ)
			     (ADD1 \FirstPieceOffset)))      (* First piece in the document)
          (SETQ OLDLOOKS (OR (fetch DEFAULTCHARLOOKS of TEXTOBJ)
			     TEDIT.DEFAULT.CHARLOOKS))
          [SETQ CURCH# (SETQ OLDCH# (ADD1 (GETFILEPTR OFILE]
          [while PC
	     do (COND
		  ([AND (OR (NOT PREVPC)
			    (fetch PPARALAST of PREVPC))
			(OR PARALOOKSSEEN (NOT (EQUALALL (fetch PPARALOOKS of PC)
							 (fetch FMTSPEC of TEXTOBJ]
                                                             (* The last piece ended a paragraph, so send out new 
							     para looks)
		    [OR FONTFILE (SETQ FONTFILE (OPENFILE (QUOTE {NODIRCORE})
							  (QUOTE BOTH)
							  (QUOTE NEW]
                                                             (* Create the formatting-info file, if it didn't exist 
							     before.)
		    (COND
		      ((NEQ CURCH# OLDCH#)                   (* There were prior characters that hadn't been 
							     described in a piece yet. Describe them)
			(TEDIT.PUT.CHARLOOKS FONTFILE OLDCH# CURCH# OLDLOOKS PREVPC EDITSTENTATIVE)
			(add PCCOUNT 1)
			(SETQ OLDCH# CURCH#)                 (* And now we've described all the characters up to the 
							     current one.)
			))
		    (TEDIT.PUT.PARALOOKS FONTFILE PC)
		    (SETQ PARALOOKSSEEN T)                   (* Remember that we've seen a foreign paralooks, and 
							     must henceforth note para boundaries)
		    (add PCCOUNT 1)))
		[COND
		  [(fetch POBJ of PC)                        (* It's an object -- go use its PUTFN)
		    [OR FONTFILE (SETQ FONTFILE (OPENFILE (QUOTE {NODIRCORE})
							  (QUOTE BOTH)
							  (QUOTE NEW]
                                                             (* Create the font-info file, if need be.)
		    (COND
		      ((NEQ CURCH# OLDCH#)                   (* There were prior characters that hadn't been 
							     described in a piece yet. Describe them)
			(TEDIT.PUT.CHARLOOKS FONTFILE OLDCH# CURCH# OLDLOOKS PREVPC EDITSTENTATIVE)
			(add PCCOUNT 1)
			(SETQ OLDCH# CURCH#)                 (* And now we've described all the characters up to the 
							     current one.)
			))                                   (* If the prior thing was text, send along its 
							     descriptor.)
		    (add CURCH# (TEDIT.PUT.OBJECT PC OFILE FONTFILE CURCH#))
                                                             (* Send out the object)
		    (add PCCOUNT 1)
		    (SETQ OLDCH# CURCH#)
		    (COND
		      ([OR (NOT (EQCLOOKS OLDLOOKS (fetch PLOOKS of PC)))
			   [AND EDITSTENTATIVE (NEQ (fetch PNEW of PC)
						    (AND PREVPC (fetch PNEW of PREVPC]
			   (AND (OR (NOT PREVPC)
				    (fetch PPARALAST of PREVPC))
				(NOT (EQUALALL (fetch PPARALOOKS of PC)
					       (fetch FMTSPEC of TEXTOBJ]
                                                             (* The OBJECT has different ooks from before)
			(\BOUT FONTFILE 1)
			(TEDIT.PUT.CHARLOOKS FONTFILE OLDCH# CURCH# (fetch PLOOKS of PC)
					     PREVPC EDITSTENTATIVE)
			(SETQ OLDLOOKS (fetch PLOOKS of PC)))
		      (T                                     (* No differences. Don't write any charlooks, and mark 
							     that fact)
			 (\BOUT FONTFILE 0)                  (* MAKE BLOODY SURE THAT THE NEXT RUN OF CHARACTERS GETS
							     ITS OWN LOOKS)
			 ]
		  (T                                         (* It's not an object.)
		     (COND
		       ([OR (NOT (EQCLOOKS OLDLOOKS (fetch PLOOKS of PC)))
			    [AND EDITSTENTATIVE (NEQ (fetch PNEW of PC)
						     (AND PREVPC (fetch PNEW of PREVPC]
			    (AND (OR (NOT PREVPC)
				     (fetch PPARALAST of PREVPC))
				 (NOT (EQUALALL (fetch PPARALOOKS of PC)
						(fetch FMTSPEC of TEXTOBJ]
                                                             (* We have a piece with new looks.)
			 [OR FONTFILE (SETQ FONTFILE (OPENFILE (QUOTE {NODIRCORE})
							       (QUOTE BOTH)
							       (QUOTE NEW]
			 (COND
			   ((NOT (IEQP OLDCH# CURCH#))       (* If there were looks past, and if the run was not 
							     empty, save a piece for its looks)
			     (TEDIT.PUT.CHARLOOKS FONTFILE OLDCH# CURCH# OLDLOOKS PREVPC 
						  EDITSTENTATIVE)
			     (add PCCOUNT 1)))
			 (SETQ OLDLOOKS (fetch PLOOKS of PC))
			 (SETQ OLDCH# CURCH#)))              (* Now dump out the non-object contents of the piece.)
		     [COND
		       [(SETQ PFILE (fetch PFILE of PC))     (* It's on a file. Copy it.)
			 [OR (OPENP PFILE)
			     (replace PFILE of PC with (SETQ PFILE (OPENSTREAM (fetch FULLNAME
										  of PFILE)
									       (QUOTE INPUT]
                                                             (* Make sure the file is open.)
			 (COPYBYTES PFILE OFILE (fetch PFPOS of PC)
				    (IPLUS (fetch PFPOS of PC)
					   (fetch PLEN of PC]
		       ((SETQ PSTR (fetch PSTR of PC))       (* It's in a string. Just print it.)
			 (for I from 1 to (fetch PLEN of PC) as CH instring PSTR
			    do (\BOUT OFILE CH]
		     (COND
		       ((AND (NOT CACHE)
			     (RANDACCESSP OFILE))            (* CSLI leave the pieces and the pctb alone and just 
							     write the file if its cached or not randomaccess)
			 (replace PFILE of PC with OFILE)
			 (replace PFPOS of PC with (SUB1 CURCH#))
			 (replace PSTR of PC with NIL)
			 (add CURCH# (fetch PLEN of PC]
		(SETQ PREVPC PC)
		(SETQ PC (fetch NEXTPIECE of PC))
	     finally                                         (* Put out a piece describing the last characters in the
							     file.)
		     (COND
		       ((AND FONTFILE (NEQ OLDCH# CURCH#))   (* Only if there WERE characters, and only if there's a 
							     need for font information)
			 (TEDIT.PUT.CHARLOOKS FONTFILE OLDCH# CURCH# OLDLOOKS PREVPC EDITSTENTATIVE)
			 (add PCCOUNT 1]
          (for FORM in TEDIT.PUT.FINISHEDFORMS do (EVAL FORM))
                                                             (* Do any user-specific cleanup)
          [COND
	    ((AND (OPENP OFILE)
		  FONTFILE)                                  (* We need to write format info.)
	      (\DWOUT FONTFILE (GETFILEPTR OFILE))           (* So remember the end of the plain-text part of the 
							     file)
	      (\SMALLPOUT FONTFILE PCCOUNT)                  (* # OF PIECES WE'' NEED TO RECONSTRUCT THIS FILE)
	      (\SMALLPOUT FONTFILE 31416)                    (* Now the password for NEW format files: 31416)
	      [COND
		((AND (NOT CLEARPUT)
		      (NOT SEPARATEFORMAT))                  (* Only write fmtg info at the end if we want it 
							     there--not if we want plain text or want it kept 
							     separate.)
		  (COPYBYTES FONTFILE OFILE 0 (GETEOFPTR FONTFILE))
                                                             (* Copy the font information to the file trailer)
		  )
		(T 

          (* (* construct a single piece file) (\CLEARPCTB (fetch PCTB of TEXTOBJ)) (\INSERTPIECE (\CREATEPIECEORSTREAM 
	  OFILE (fetch DEFAULTCHARLOOKS of TEXTOBJ)) (QUOTE LASTPIECE) TEXTOBJ))

]
	      (CLOSEF FONTFILE)
	      (COND
		((NOT SEPARATEFORMAT)                        (* Unless we want the formatting info separately, delete
							     the file)
		  (DELFILE FONTFILE]
          (RETURN (COND
		    (CLEARPUT NIL)
		    (T FONTFILE])

(TEDIT.PUT.PIECE.DESCRIPTOR
  [LAMBDA (FILE CH1 CHLIM LOOKS)                             (* jds " 1-May-84 11:58")
                                                             (* Put a description of LOOKS into FILE.
							     LOOKS apply to characters CH1 thru CHLIM-1)
    (PROG ((FONT (fetch CLFONT of LOOKS))
	   STR)
          (SETQ STR (CONCAT "(FONTCREATE " (KWOTE (FONTPROP FONT (QUOTE FAMILY)))
			    " "
			    (FONTPROP FONT (QUOTE SIZE))
			    " "
			    (KWOTE (FONTPROP FONT (QUOTE FACE)))
			    " )"))
          (\DWOUT FILE (IDIFFERENCE CHLIM CH1))              (* The length of this run of looks)
          (\SMALLPOUT FILE (NCHARS STR))                     (* The length of the description which follows)
          (PRIN1 STR FILE)                                   (* Print the form which can EVAL to re-create the font 
							     information)
          (\BOUT FILE (LOGOR (COND
			       ((fetch CLPROTECTED of LOOKS)
				 8)
			       (T 0))
			     (COND
			       ((fetch CLINVISIBLE of LOOKS)
				 NIL 4)
			       (T 0))
			     (COND
			       ((fetch CLSELHERE of LOOKS)
				 2)
			       (T 0))
			     (COND
			       ((fetch CLCANCOPY of LOOKS)
				 1)
			       (T 0])

(\ATMIN
  [LAMBDA (STREAM)                                           (* jds " 3-Apr-84 10:41")
    (PROG ((LEN (\SMALLPIN STREAM)))
          (RETURN (COND
		    ((ZEROP LEN)
		      NIL)
		    (T (PACK (for I from 1 to LEN collect (CHARACTER (\BIN STREAM])

(\ATMOUT
  [LAMBDA (STREAM ATOM)                                      (* jds " 1-May-84 11:58")
                                                             (* Write an atom's characters in length-contents form.)
    (\SMALLPOUT STREAM (NCHARS ATOM))
    (OR (ZEROP (NCHARS ATOM))
	(for CH inatom ATOM do (\BOUT STREAM CH])

(\DWIN
  [LAMBDA (FILE)                                             (* jds " 3-JAN-83 16:08")
    (IPLUS (LLSH (\BIN FILE)
		 24)
	   (LLSH (\BIN FILE)
		 16)
	   (LLSH (\BIN FILE)
		 8)
	   (\BIN FILE])

(\DWOUT
  [LAMBDA (FILE NUMBER)                                      (* jds " 3-JAN-83 15:30")
    (\BOUT FILE (LOGAND 255 (LRSH NUMBER 24)))
    (\BOUT FILE (LOGAND 255 (LRSH NUMBER 16)))
    (\BOUT FILE (LOGAND 255 (LRSH NUMBER 8)))
    (\BOUT FILE (LOGAND 255 NUMBER])

(\STRINGIN
  [LAMBDA (STREAM)                                           (* jds " 3-Apr-84 10:41")
                                                             (* Write a string on a file in length-contents form;
							     one word for the length, and one byte per character 
							     contained.)
    (PROG ((LEN (\SMALLPIN STREAM))
	   STR)
          (SETQ STR (ALLOCSTRING LEN))
          [OR (ZEROP LEN)
	      (for I from 1 to LEN do (RPLCHARCODE STR I (\BIN STREAM]
          (RETURN STR])

(\STRINGOUT
  [LAMBDA (STREAM STRING LEN)                                (* jds " 1-May-84 11:58")
                                                             (* Write a string on a file in length-contents form;
							     one word for the length, and one byte per character 
							     contained.)
    (SETQ LEN (OR LEN (NCHARS STRING)))
    (\SMALLPOUT STREAM LEN)
    (OR (ZEROP LEN)
	(for CH instring STRING as I from 1 to LEN do (\BOUT STREAM CH])

(\TEDIT.FORMATTEDP1
  [LAMBDA (FILE LEN)                                         (* jds "24-Apr-84 17:53")
                                                             (* Checks for a version-1 formatted file)

          (* Returns NIL if it isn't a formatted file, or the # of pieces needed if it is; leaves file at start of text or 
	  of piece descriptions, resp.)


    (SETQ LEN (OR LEN (GETEOFPTR FILE)))
    (PROG (DESCPTR NPIECES PASSWORD)
          (COND
	    ((ILEQ LEN 8)                                    (* Too short to be formatted.)
	      (RETURN NIL))
	    (T (SETFILEPTR FILE (IDIFFERENCE LEN 8))         (* Move to start of FILEPTR to descriptions)
	       (SETQ DESCPTR (\DWIN FILE))                   (* Read the file pos of the descriptions)
	       (SETQ NPIECES (\SMALLPIN FILE))
	       (SETQ PASSWORD (\SMALLPIN FILE))
	       (COND
		 ((IEQP PASSWORD 31416)                      (* VERSION 1 TEDIT FORMAT)
		   (SETFILEPTR FILE DESCPTR)
		   (RETURN NPIECES))
		 ((IEQP PASSWORD 31415)                      (* VERSION 0 TEDIT FORMAT)
		   (SETFILEPTR FILE DESCPTR)
		   (RETURN (CONS 0 NPIECES)))
		 (T                                          (* NOT A FORMATTED FILE)
		    (SETFILEPTR FILE 0)
		    (RETURN NIL])

(\TEDIT.INCLUDE.SPAN
  [LAMBDA (STREAM INFILE START END)                          (* jds "10-May-84 16:39")
                                                             (* takes a text stream and an OPEN stream to include.
							     Note: Start and End are inclusive ptrs, unlike in 
							     copybytes and friends)
                                                             (* no interpretation (alternate file type e.g. Bravo) 
							     takes place. Simply include the characters)
                                                             (* Default character and paragraph looks are applied)
                                                             (* (* Returns T if the insertion happened, NIL if there 
							     was no place to put it.) WHAT DOES THAT MEAN? GBN)
    (PROG ((STREAM (TEXTOBJ STREAM))
	   (START START)
	   (END END)
	   SEL PCTB TEXTLEN HOLDING.FILE INSERTCH# INSPC LEN INSPC# PCLST NPC WASOPEN)
          (SETQ SEL (fetch SEL of STREAM))
          (COND
	    ((NOT (fetch SET of SEL))
	      (SHOULDNT "\TEDIT.INCLUDE.SPAN called with no selection set"))
	    (T                                               (* There is a place to do the include.)
	       (COND
		 (END                                        (* This is the copy-part-of-a-file case, with file 
							     liable to be volatile. Copy it to core for protection)
		      (SETQ HOLDING.FILE (OPENSTREAM (QUOTE {NODIRCORE})
						     (QUOTE OUTPUT)
						     (QUOTE NEW)))
                                                             (* Create the holding file)
		      [SETQ INFILE (COND
			  ((OPENP INFILE)
			    (SETQ WASOPEN T)
			    INFILE)
			  (T (OPENFILE INFILE (QUOTE INPUT]
                                                             (* And copy the file-section into it.)
		      (COPYBYTES INFILE HOLDING.FILE START (ADD1 END))
                                                             (* must be copychars to respect eol conventions)
		      (COND
			((NOT WASOPEN)
			  (CLOSEF INFILE)))
		      (CLOSEF HOLDING.FILE)
		      (SETQ INFILE HOLDING.FILE)
		      (SETQ START (SETQ END NIL))            (* Then pretend nothing happened.)
		      ))
	       (SETQ TEXTLEN (fetch TEXTLEN of STREAM))
	       (SETQ PCTB (fetch PCTB of STREAM))
	       [SETQ INSERTCH# (COND
		   ((EQ (fetch POINT of SEL)
			(QUOTE LEFT))
		     (fetch CH# of SEL))
		   (T (ADD1 (fetch CHLIM of SEL]             (* Find the place to make the insertion.)
	       (SETQ INSPC# (OR (\CHTOPCNO INSERTCH# PCTB)
				(\EDITELT PCTB \PCTBLastPieceOffset)))
	       (SETQ INSPC (\EDITELT (fetch PCTB of STREAM)
				     (ADD1 INSPC#)))         (* The piece to make the insertion in)
	       [COND
		 ((NEQ INSPC (QUOTE LASTPIECE))
		   (COND
		     ((IGREATERP INSERTCH# (\EDITELT PCTB INSPC#))
                                                             (* Must split the piece.)
		       (SETQ INSPC (\SPLITPIECE INSPC INSERTCH# STREAM INSPC#))
		       (add INSPC# \EltsPerPiece)
		       (SETQ PCTB (fetch PCTB of STREAM))    (* Refresh the PCTB in case it grew.)
		       ]
	       (SETQ PCLST (create PIECE
				   PFILE ← INFILE
				   PFPOS ←(COND
				     (START START)
				     (T 0))
				   PLEN ←(IDIFFERENCE [COND
							(END END)
							(T 
                                                             (* get the eof pointer)
							   (COND
							     ((OPENP INFILE)
							       (GETEOFPTR INFILE))
							     (T (OPENSTREAM INFILE (QUOTE INPUT))
								(PROG1 (GETEOFPTR INFILE)
								       (CLOSEF INFILE]
						      (COND
							(START START)
							(T 0)))
				   PREVPIECE ← NIL
				   NEXTPIECE ← NIL
				   PLOOKS ←(CHARLOOKS.FROM.FONT TEDIT.DEFAULT.FONT)
				   PPARALAST ← NIL
				   PPARALOOKS ←(create FMTSPEC using TEDIT.DEFAULT.FMTSPEC)))
	       (SETQ LEN (fetch PLEN of PCLST))
	       (\TEDIT.INSERT.PIECES STREAM INSERTCH# PCLST LEN INSPC INSPC# NIL)
	       (replace TEXTLEN of STREAM with (IPLUS TEXTLEN LEN))
	       (AND (fetch \WINDOW of STREAM)
		    (\FIXILINES STREAM SEL INSERTCH# LEN TEXTLEN))
	       (replace CHLIM of SEL with (IPLUS (replace CH# of SEL with INSERTCH#)
						 LEN -1))    (* Now fix up the selection to be the included text, 
							     point←left, character selection grain.)
	       (replace DCH of SEL with LEN)
	       (replace DX of SEL with 0)
	       (replace POINT of SEL with (QUOTE RIGHT))     (* So that several things INCLUDED in sequence fall in 
							     sequence.)
	       (replace SELKIND of SEL with (QUOTE CHAR))
	       (replace SELOBJ of SEL with NIL)
	       (COND
		 ((fetch \WINDOW of STREAM)
		   (TEDIT.UPDATE.SCREEN STREAM)
		   (\FIXSEL SEL STREAM)
		   (\SHOWSEL SEL NIL T)))
	       (replace \DIRTY of STREAM with T)             (* Mark the document changed)
	       (\SETUPGETCH (create EDITMARK
				    PC ← INSPC
				    PCOFF ← 0
				    PCNO ←(IPLUS INSPC# \EltsPerPiece))
			    STREAM)                          (* Set the fileptr to the end of the insertion.)
	       T])

(\WATOM
  [LAMBDA (STREAM ATOM)                                      (* jds " 1-May-84 11:58")
                                                             (* Write an atom's characters in length-contents form.)
    (\SMALLPOUT STREAM (NCHARS ATOM))
    (for CH inatom ATOM do (\BOUT STREAM CH])

(\WSTRING
  [LAMBDA (STREAM STRING LEN)                                (* jds " 1-May-84 11:58")
                                                             (* Write a string on a file in length-contents form;
							     one word for the length, and one byte per character 
							     contained.)
    (SETQ LEN (OR LEN (NCHARS STRING)))
    (\SMALLPOUT STREAM LEN)
    (for CH instring STRING as I from 1 to LEN do (\BOUT STREAM CH])
)
(DECLARE: DOEVAL@COMPILE DONTCOPY

(ADDTOVAR GLOBALVARS TEDIT.INPUT.FORMATS)
)

(RPAQ? TEDIT.INPUT.FORMATS NIL)
(DECLARE: DONTCOPY
  (FILEMAP (NIL (673 54411 (TEDIT.BUILD.PCTB 683 . 11230) (TEDIT.FORMATTEDFILEP 11232 . 13142) (
TEDIT.GET 13144 . 16568) (TEDIT.INCLUDE 16570 . 23096) (TEDIT.INCLUDE.SPAN 23098 . 29864) (TEDIT.PUT 
29866 . 35029) (TEDIT.PUT.PCTB 35031 . 43547) (TEDIT.PUT.PIECE.DESCRIPTOR 43549 . 44831) (\ATMIN 44833
 . 45114) (\ATMOUT 45116 . 45463) (\DWIN 45465 . 45676) (\DWOUT 45678 . 45957) (\STRINGIN 45959 . 
46493) (\STRINGOUT 46495 . 46994) (\TEDIT.FORMATTEDP1 46996 . 48286) (\TEDIT.INCLUDE.SPAN 48288 . 
53606) (\WATOM 53608 . 53927) (\WSTRING 53929 . 54409)))))
STOP