{Begin SubSec TEdit} {Title The TEdit Text Editor} {Text {Begin Note} edited 7/26/83 by Sybalsky. edited Thu, 18 Aug 83 12:17 PDT by Sannella --- various formatting changes edited Thurs, 27 Oct 83 by Sybalsky --- Add TEDIT.LOOKS documentation & various others. before 4/3 --- added window prop CARETLOOKSFN, changed window prop TEDIT.CMD.SELFN, modified PROP arg to fn TEDIT {End Note} TEdit is a window-based, modeless text editor, capable of handling fonts and some rudimentary formatting. Text is selected with the mouse, and all editor operations act on the current selection. There are two ways to start TEdit: With an explicit call to the function {FN TEDIT}, or from the background menu. At top level, you can call {Lispcode (TEDIT {Arg TEXT} {arg WINDOW})} where {Arg TEXT} is the thing you want to edit, and {Arg WINDOW} is an optional argument specifying the window you want to do the editing in. To start a fresh editing window, specify a {Arg TEXT} of {LISP NIL}. Otherwise, {Arg TEXT} may be the name of an existing file, a string to be edited, or an arbitrary [{lisp MKSTRING}-able] Lisp object. The text is displayed in an editing window, and may be edited there (see below). There will be a one-line-high prompting window across the top of the editing window; it is used to ask for file names, search strings, and the like. The {Lisp TEdit} option in the background menu opens an empty editing window; you may either type in the text you want, or use the {Lisp Put} menu option (below) to bring in a file. {begin Subsec Selecting Text} {title Selecting Text} {text TEdit works by operating on "selected" pieces of text. Selected text is highlighted in some way, and may have a caret flashing at one end. Insertions go where the caret is; deletion and other operations are applied to the currently selected text. Text is selected using the mouse. There are two regions within an edit window: The area containing text, and a "line bar" just inside the left edge of the window. While the mouse is inside the text region, the cursor is the normal up-and-left pointing arrow. When the cursor moves into the line bar, it changes to an up-and-right pointing arrow. Which region the mouse is in determines what kind of selection happens: The {lisp LEFT} mouse button always selects the smallest things. In the text region, it selects the character you're pointing at; in the line bar, it selects the single line you're pointing at. The {lisp MIDDLE} mouse button selects larger things. In the text region, it selects the word the cursor is over, and in the line bar it selects the paragraph the cursor is next to. The {lisp RIGHT} button always extends a selection. The current selection is extended to include the character/word/line/paragraph you are now pointing at. For example, if the existing selection was a whole-word selection, the extended selection will also consist of whole words. There are special ways of selecting text which carry an implicit command with them: If you hold the {lisp CTRL} key down while selecting text, the text will be shown white-on-black. When you release the {lisp CTRL} key, the selected text will be deleted. You can abort a {lisp CTRL}-selection: Hold down a mouse button, and release the {lisp CTRL} key. Then release the mouse button. Holding the {lisp SHIFT} key down while making a selection causes it to be a "copy-source" selection. A copy source is marked with a dashed underline. Whatever is selected as a copy source when the {lisp SHIFT} key is released will be copied to where the caret is. This even works to copy text from one edit window to another. You can abort a copy: Hold down a mouse button, and release the {lisp SHIFT} key. Then release the mouse button. Holding the {lisp CTRL} and {lisp SHIFT} keys down while making a selection causes it to be a "move" selection, which is marked by making it veverse video. Whatever is selected as a "move" source when the {lisp CTRL} and {lisp SHIFT} keys are released will be moved to where the caret is. This even works to move text from one edit window to another. You can abort a move: Hold down a mouse button, and release the {lisp CTRL} and {lisp SHIFT} keys. Then release the mouse button. If the variable {VAR TEDIT.EXTEND.PENDING.DELETE} is non-{lisp NIL}, extending a selection will display the selection as white-on-black. The next time something is typed (or if text is copied or moved there), the inverted text will be deleted first. This provides an easy way of replacing text. }{end subsec Selecting Text} {begin Subsec Editing Operations} {title Editing Operations} {text Inserting text: Except for command characters, whatever is typed on the keyboard gets inserted where the caret is. The {lisp BS} key and control-A both act as a backspace, deleting the character just before the caret. Control-W is the backspace-word command. Deleting Text: Hitting the {lisp DEL} key causes the currently-selected text to be deleted. Alternatively, you can use the {lisp CTRL}-selection method described above. Copying Text: Use {lisp SHIFT}-selection, as described above. Moving Text: Use {lisp CTRL}-{lisp SHIFT}-selection. Undoing an edit operation: The top blank key is the {lisp Undo} key (the {lisp KEYBOARD} key on the 1108). It will undo the most recent edit command. {lisp Undo} is itself undo-able, so you can never back up more than a single command. Redoing an edit operation: The {lisp ESC} key is the {lisp Redo} key (the forward-arrow key on the 1108). It will redo the most recent edit command on the current selection. For example, if you insert some text, then select elsewhere, hitting {lisp ESC} will insert a copy of the text in the new place also. If the last command was a delete, {lisp Redo} will delete the currently-selected text; if it was a font change, the same change will be applied to the current selection. The command menu: You can get command menus by moving into the edit window's title region and hitting the {lisp RIGHT} or {lisp MIDDLE} mouse buttons. {lisp RIGHT} gets the usual menu of window commands. {lisp MIDDLE} gets a menu of editor commands: {Begin LabeledList Editor Commands} {name {lisp Put}} {text Causes an updated version of the file to be written. Tedit will ask you for a file name, offering the existing name (if any) as the default. When the file name is offered, you may type ^E to abort the operation.} {name {lisp Get}} {text Lets you read in a new file to edit, {it without saving the one you were working on.} You'll be asked for a file name in the prompt window. Instead of a file name, you may type ^E to abort the operation.} {name {lisp Include}} {text Lets you copy the contents of a file into the edit window, inserting it where the caret is. Tedit will ask you for a file name in its prompt window. Instead of a file name, you may type ^E to abort the operation.} {name {lisp Quit}} {text Causes the editor to stop without updating the file you're editing. If you haven't saved your changes, you'll be asked to confirm this.} {name {lisp Find}} {text Asks for a search string, then hunts from the caret toward the end of document for a match. Selects the first match found; if there is none, nothing happens. The search is case-sensitive; i.e. "Foo" will not be found with the search string "FOO". If you need to include special characters (e.g. CR) in the search string, quote them with {lisp ^V}.} {name {lisp Substitute}} {text Asks for a search string and a replacement string. Within the current selection, all instances of the search string are replaced by the replacement string. If you wish, TEdit will ask you to confirm each replacement before actually doing it. If you need to include special characters (e.g. CR) in the search or replacement strings, quote them with {lisp ^V}.} {name {lisp Looks}} {text Changes the character looks of the selected characters: The font, character size, and face (bold, italic, etc.). Three menus will pop up in sequence: One to select the font name, one to select the face, and one to select the size. You may select an option in each menu. If, for example, you want to leave the character size alone, just click the mouse outside the size menu. In general, any aspect of the character looks that you don't change will remain the same.} {name {lisp Hardcopy}} {text Prints the document to your default press or InterPress printer, with 1 inch margins all around. The variable {var DEFAULTPRINTINGHOST} controls which kind of printer TEdit will send to.} {name {lisp Press File}} {text Creates a Press or InterPress file of the document, with 1 inch margins all around. The file format is also controlled by {var DEFAULTPRINTINGHOST}.} {name {lisp Expanded Menu}} {text Opens a large menu that has three parts: A TEdit operations section, a character-looks menu, and a paragraph looks ({it i.e.,} formatting) menu. This expanded menu has fill-in blanks for some fields (like what the {lisp Find} command should hunt for), and has on-off-neutral buttons to control character properties like boldness. This is described below.} {End LabeledList Editor Commands} }{end subsec Editing Operations} {begin Subsec Tedit Expanded Menu} {title Tedit Expanded Menu} {Text Selecting the item "Expanded menu" from TEdit's title-bar menu creates a small free-form menu on top of your editing window. The expanded menu contains selectable menu buttons and places for you to type text (e.g., what to search for when you do a FIND). From the main expanded menu, you can open three other sub-menus for more specialized operations: Setting character looks, setting paragraph formatting, and laying out pages for hardcopy. {begin Subsec Tedit Expanded Menu Overview} {title Using TEdit-style Menus} {Text The expanded menu is itself a TEdit window, so the usual editing operations work--with one change. Some parts of the menu can't be selected or operated on; they're protected. The places you can select are: menu buttons, the margin ruler (see below), and between pairs of curly braces, so: {bracket}. Menu buttons appear in bold; every menu button which needs to ask for text has a pair of {bracket} associated with it, e.g., the line {lispcode Quit Hardcopy {rm server:} {bracket} {rm copies:} {bracket}} has two buttons on it. The "{lisp Quit}" button needs no further arguments, while the "{lisp Hardcopy}" button can take two arguments: the name of the server to print to and the number of copies to print. When a button requires arguments, you need to fill them in before hitting the button. To get rid of an expanded menu, just close it using the right mouse button command menu. } {end Subsec Tedit Expanded Menu Overview} {begin Subsec Tedit Operations Menu} {title TEdit The Main Expanded Menu} {Text The TEdit operation menu looks like this: {lispcode Quit ParaLooks CharLooks PageLayout All Get {bracket} Put {bracket} Include {bracket} Find {bracket} Substitute {bracket} {rm for} {bracket} Hardcopy {rm server:} {bracket} {rm copies:} {bracket}} The {lisp Get}, {lisp Put}, {lisp Include}, and {lisp Find} buttons all require a text argument, which must be typed in before you hit the corresponding menu button. {lisp Substitute} requires two arguments, the second being the search string, and the first being the replacement. The {lisp Hardcopy} button takes two optional text arguments. If you specify a server name, the hardcopy will be sent there. If you leave the brackets empty, TEdit uses {var DEFAULTPRINTINGHOST} as usual. You may also specify how many copies of the document you want; if you don't put anything in the "copies" field, you get one copy. The {lisp Quit}, {lisp ParaLooks}, {lisp CharLooks}, {lisp PageLayout}, and {lisp All} buttons need no additional arguments. {lisp Quit} stops the current editing session; {lisp All} causes the entire document to be selected. This is useful for making global substitutions or changes to character looks. The three menu buttons {lisp ParaLooks}, {lisp CharLooks}, and {lisp PageLayout} give you access to the three specialized menus. } {end Subsec Tedit Operations Menu} {begin Subsec Tedit CharLooks Menu} {title The TEdit Character Looks Menu} {Text The Character Looks Menu looks like this: {lispcode APPLY SHOW {rm Props:} Bold Italic Underline StrikeThru Overbar TimesRoman Helvetica Gacha Modern Classic Terminal Other {rm other font:} {bracket} {rm Size:} {bracket} Normal Superscript Subscript {rm distance:} {bracket}} Generally speaking, you select the text you want to change, set the entries in this menu up as you want the text to appear, then make the change by hitting the {lisp APPLY} button. If you have a piece of text whose looks you want to copy, select the text and hit the {lisp SHOW} button. The menu will be filled in to match that text's looks. You can then {lisp APPLY} it elsewhere, perhaps after modifying things slightly. The second line of the menu is a list of character properties which can be modified independently. Each of the menu buttons has three states: If the button appears white-on-black, that property will be turned on; If the button appears with a diagonal line, that property will be turned off; If the button appears black-on-white, that property will be left alone. Why is it useful to leave a property alone? Suppose you have a paragraph in Times Roman with some bold and some italic in it. If you want to change the font to Helvetica without changing the boldness or italicness, you can do so. The third line of the menu is a list of font-family names. You can select among them: selecting one family deselects any others. You can also select no family by mouse buttoning between two of the families. If you {lisp APPLY} with no font family selected, the text will be left in whatever font family it was. The {lisp Other} choice in the font-family selection lets you add new fonts to the menu. To pick a family that isn't offered in the menu, first type the name between the brackets after {rm other font}. Then pick {lisp Other} as the font family. Then next time you {lisp APPLY} the menu, the new font family will be applied to the text you've selected, and the family name will be added to the menu. The last line of the menu lets you set the font's size, and specify any superscripting or subscripting. Fill in the "Size:" field with a number, and {lisp APPLY}ing will change all the selected characters to that size. Leave it empty, and the characters will retain their existing sizes. For character offsets, you have three choices: {lisp Normal} characters lie on the baseline; {lisp Superscript} characters lie above the baseline by the distance you specify (2 points by default); {lisp Subscript} characters lie below the baseline by the distance you specify (2 points by default). As with font family names, you may mouse in the space between options to neutralize the choice. {lisp APPLY}ing with a neutral choice leaves characters with the super- and subscripting they had, if any. } {end Subsec TEdit CharLooks Menu} {begin Subsec TEdit ParaLooks Menu} {title The TEdit Paragraph Formatting Menu} {Text The Paragraph Looks Menu looks like this: {lispcode APPLY SHOW Left Right Centered Justified Page Heading {rm type: } {bracket} {rm Line leading:} {bracket} {rm Paragraph leading:} {bracket} {rm New Page: } Before After {rm Tab Type:} Left Right Centered Decimal {rm Default Tab Size:} {bracket}} Below this menu is a solid black rectangle, used for setting indentations, and a ruler, used for setting tab stops. As with the Character Looks Menu, you select the text you want to change, set the entries in this menu up as you want the text to appear, then make the change by hitting the {lisp APPLY} button. If you have a paragraph whose looks you want to copy, select the text and hit the {lisp SHOW} button. The menu will be filled in to match that text's looks. You can then {lisp APPLY} it elsewhere, perhaps after modifying things slightly. The second line of the menu is for specifying how the paragraph margins are to be justified. A Left justified paragraph has a ragged right margin, but is justified flush with the left margin. A Right justified paragraph has a ragged left margin, but is justified flush on the right. A Centered paragraph is centered between the two margins. A Justified paragraph is set flush with both the left and right margins. On that line, you may also declare this paragraph to be a page heading (see the Page Layout Menu section), and say what kind of heading it is. The {lisp Page Heading} button is an On-Off-Neutral button; depending on its setting, it will make the paragraph be a page heading, make it stop being a page heading, or leave it alone. The space between lines in a paragraph is called "line leading". You can specify it, in units of printer's points. You can also leave space in front of a paragraph (without using extra carriage returns) by specifying "paragraph leading," also in units of printer's points. You may ask that a new page (or column, if you're using multiple columns to the page) be started either before or after this paragraph. These are controlled by the {lisp Before} and {lisp After} buttons, respectively. These are also 3-state buttons, and can be used to set and reset the new-page property or leave it alone. Generally, You set paragraph margins using the margin ruler on the bottom. There are three margin values: The left margin for the paragraph's first line, the left margin for the rest of the paragraph, and the paragraph's right margin. The margin ruler is has three sensitive areas, one for each margin value. Margins are measured in printer's picas (6 to the inch), with a grain of 1/2 pica. There are 12 points to the pica. Plans exist for allowing different units (and granularity) in the ruler. The first-line left margin is controlled by the top half of the ruler, left end. To move it, push a mouse button near the left edge, and hold it. Moving the mouse pulls the margin along with it; the margin ruler always shows the current values of the margins. If you push the {lisp RIGHT} mouse button over the margin, it becomes neutral; i.e., {lisp APPLY}ing the paragraph menu won't change the first-line left margins of any paragraphs. The rest-of-paragraph left margin is controlled by the bottom half of the ruler, left end. You move it (and neutralize it) the same way. Likewise for the right margin, which is controlled by the right end of the margin ruler. There are a couple of differences here. First, you can set the right margin to 0, which will create a "floating" right margin (one that follows the right edge of the edit window or of the printed page). This is signalled by a margin ruler that is as wide as the window, but shows a value of 0 at its right end. Since the editing window may be narrower than the document, you can also set the right margin beyond the edge of the window, by pulling it with the mouse, and pulling past the window edge. A right margin you can't see is represented by a double wavy line at the right edge. To make a margin "neutral", so that {lisp APPLY}ing it won't change that margin setting, move the margin with the right mouse button. The margin will become gray, to indicate that it is neutralized. You can also set tab stops using the margin ruler. The space below the ruler markings is sensitive to all three mouse buttons, and is used to represent tab stops. To set a tab, you first need to choose what kind of tab you want, using the line starting with "Tab Type:." Make your choice of tab type the same way you'd choose a font family. Left tabs are regular typewriter type tabs; Right tabs take the succeeding text and push it so it is flush-right against the tab stop location; Centered tabs cause the succeeding text to be centered about the tab stop; Decimal tabs (not implemented) cause the succeeding text to have its decimal point lined up on the tab stop. Tab stops are shown in the margin ruler as small arrows with suggestive tails. To create a new tab stop, use the middle mouse button. In the region below the ruler markings (and the numbers!), point to where you want the tab to be, and press the middle mouse button. The tab should appear; as long as you hold the button down, the tab will follow the mouse around, so you can adjust its location. To move a tab stop, point at it and press the left mouse button. As long as you hold it down, the tab stop will follow the mouse. To delete a tab stop, point at it and press the right mouse button. } {end subsec TEdit ParaLooks Menu} {begin Subsec TEdit PageLayout Menu} {title The TEdit Page Layout Menu} {Text The Paragraph Looks Menu looks like this: {lispcode APPLY SHOW {rm For page:} First(&Default) Other Left Other Right {rm Page numbers:} No Yes X: {bracket} y: {bracket} {rm Alignment:} Left Centered Right {rm Margins:} {rm Left:} {bracket} {rm Right:} {bracket} {rm Top:} {bracket} {rm Bottom:} {bracket} {rm Columns:} {bracket} {rm Col width:} {bracket} {rm Space between cols:} {bracket} Page Headings: Heading Type: {bracket} X: {bracket} Y: {bracket} Heading Type: {bracket} X: {bracket} Y: {bracket} Heading Type: {bracket} X: {bracket} Y: {bracket} Heading Type: {bracket} X: {bracket} Y: {bracket} Character Looks for Page Numbers: {it [just like character looks menu from here on]} } There are three kinds of pages in a document: The first page, all other left-hand (even, or "verso") pages, and all other right-hand (odd, or "recto") pages. For each class of page, you may specify separate layout and headings. Specify which class of page you are setting up on the second line of the menu, by choosing one of the options {lisp First(&Default)}, {lisp Other Left} or {lisp Other Right}. If you want the entire document laid out uniformly, you need only set up (and APPLY) parameters for the first page. If you want to modify an existing page layout, choose the page class you want to modify and hit the {lisp SHOW} button. The menu will be filled in from the existing layout specifications. When you have the menu set up as you want the layout to be, hit the {lisp APPLY} button, and your specifications will be saved as part of the document. There will be no noticible change in the document---page layout only happens when a document is hardcopied. SETTING UP PAGE NUMBERS: A given class of pages may or may not have page numbers. Set this by choosing one of the buttons {lisp Yes} or {lisp No} on the "Page Numbers" line. If you decide to have page numbers, you must specify where you want them. The {lisp X} and {lisp Y} fill-in blanks let you do this. Specify the page number's location as distances from the lower, left corner of the paper; the distances are measured in picas (6 to the inch). Next, you must specify how to align the page number with the location you specified. If you specify {lisp Left} alignment, the left edge of the page number will print at the location you gave; {lisp Centered} alignment centers the page number at the spot you specified; {lisp Right} alignment puts the right edgge of the page number at the location you specified. Suppose you want to have page numbers lined up against the page's margin, toward the outside edge of each page. Then you would specify {lisp Right} alignment for recto pages and {Lisp Left} alignment for verso pages. SETTING UP PAGE HEADINGS: You may have up to four kinds of page headings/footings on any page. (This limit will be relaxed in the future). For each type, specify a name (which must be a {lisp LITATOM}), and a location for the left end of the topmost line of text in the heading. Within text, headings appear as separate paragraphs. Use the "Paragraph Looks" menu to declare that a paragraph is to be a page heading. You will have to fill in the "heading type" field with the same name you used in the "Heading Type" field in this menu. SETTING CHARACTER LOOKS FOR PAGE NUMBERS: The page layout menu has a special section for setting the character looks used to print page numbers. Set the looks just as you would set regular character looks; the settings you give will take effect when you {lisp APPLY} the page layout menu. } {end Subsec TEdit PageLayout Menu} }{end Subsec TEdit Expanded Menu} {begin Subsec TEdit Functional Interface} {title TEdit Functional Interface} {Text The top-level entry to TEdit is: {FnDef {Name TEDIT} {Args TEXT WINDOW DONTSPAWN PROPS} {Text {Arg TEXT} may be a (litatom) file name, an open {lisp STREAM}, a string, or an arbitrary [{lisp MKSTRING}-able] Lisp object. The text is displayed in an editing window, and may be edited there. If {arg TEXT} is other than a file name, a {lisp STREAM}, or a string, {lisp TEDIT} will call {lisp MKSTRING} on it, and let you edit the result. If {arg WINDOW} is {lisp NIL}, you will be prompted to create a window. If {arg WINDOW} is non-{lisp NIL}, {fn TEDIT} will use it as the window to edit in. If {arg WINDOW} has a title, {fn TEDIT} will preserve it; otherwise, {fn TEDIT} will provide a descriptive title for the window. {fn TEDIT} will normally spawn a new process to run the edit, so you can edit in parallel with other work; indeed, it is possible to have several editing windows active on the screen. You can have the editing done in your process---and have TEdit return the result of the edit---by calling {fn TEDIT} with {arg DONTSPAWN} set to {lisp T}. {arg PROPS} is a prop-list-like collection of properties which control the editing session. The following options are possible: {Begin LabeledList Tedit Properties} {name {lisp FONT}} {text The default character looks (font, size, etc.) to be used in the edit window. This can be a {lisp FONTDESCRIPTOR}, or a property list of character looks properties such as {fn TEDIT.LOOKS} would accept, or a {lisp CHARLOOKS} data structure describing the character looks.} {name {lisp QUITFN}} {text A function (or list of functions) to call when the user {lisp Quit}s. If any of the functions is {lisp T} or returns {lisp T}, the user will not be asked to confirm the {lisp Quit}---even if he'll potentially lose something. If any of the functions returns {lisp DON'T}, the {lisp Quit} is aborted before the user is asked for confirmation.} {name {lisp LOOPFN}} {text A function to be called each time thru the character-read loop.} {name {lisp CHARFN}} {text A function to be called for each character typed in.} {name {lisp SELFN}} {text A function to be called each time a mouse selection is made in this edit window.} {name {lisp TERMTABLE}} {text If you want characters displayed other than TEdit's default way, set this to a Terminal table with the correct settings.} {name {lisp READTABLE}} {text If you want command characters which are local to this edit session, set this to a Read table with the appropriate settings.} {name {lisp BOUNDTABLE}} {text If you want word breaks to happen other than the default way, set this to a Read table with the appropriate settings.} {name {lisp READONLY}} {text If the value of this property is non-{lisp NIL}, then the edit window will be read-only, i.e., you can only shift-select in it.} {name {lisp CACHE}} {text If the value of this property is non-{lisp NIL}, then the file being edited will be cached locally instead of being read as needed from the remote server.} {name {lisp SEL}} {text Tells what text should be selected initially. This can be a {lisp SELECTION} (see below) describing the selected text, or a character number, or a two-element list of first character number and number of characters to select.} {name {lisp MENU}} {text Describes the menu to be displayed when the {lisp MIDDLE} mouse button is pressed in the edit window's title region. If it is a {lisp MENU}, that menu will appear. If it is a list of menu items, a new menu will be constructed.} {name {lisp AFTERQUITFN}} {text A function to be called {it after} TEdit has quit. This can be used for cleanup of side-effects by TEdit client programs.} {name {lisp TITLEMENUFN}} {text A function to get called instead of bringing up the usual TEdit command menu when the user {lisp LEFT}- or {lisp MIDDLE}-buttons in the edit window's title region.} {name {lisp PARALOOKS}} {text The default paragraph looks to be used for paragraphs in this document. This can be either a {lisp FMTSPEC} data structure, or a property list of paragraph formatting information such as {fn TEDIT.PARALOOKS} would accept.} {name {lisp CARETLOOKSFN}} {text A function that is called (with the candidate looks as an argument) whenever new caret looks are being set. If it returns NIL, the looks will be changed. If the function returns a {lisp CHARLOOKS}, it will be used in place of the candidate. This function is useful for applications which need to control the appearance of typed-in text. } {name {lisp LEAVETTY}} {text If this is non-{lisp NIL}, TEdit will not take control of the keyboard when it is started. Instead, it will wait until you first button in the editing window with the mouse.} {name {lisp PROMPTWINDOW}} {text A window that is to be used for unscheduled user interactions, in place of the prompting window that TEdit usually provides. If this is the atom {lisp DON'T}, no window will be provided, and the main prompt window will be used.} {name {lisp OVERFLOWFN}} {text A function called whenever the TEdit screen updater is about to move text off the bottom of the window. Called with argument {arg TEXTSTREAM} and {arg EDITWINDOW}, the function may perform whatever cleanup or recovery operations are necessary. If it handles the overflow completely, the function should return {lisp T}; if the function returns {lisp NIL}, the screen updater will do its usual processing. This function is intended for use with the {lisp REGION} property, when an application will be running TEdit in {it part} of a window, and needs to handle text overflows.} {name {lisp CLEARGET}} {text If this is non-{lisp NIL}, TEdit will read the file as though it were plain text---regardless of whether it is a formatted file or not.} {name {lisp CLEARPUT}} {text If this is non-{lisp NIL}, TEdit will not emit any formatting information when the file is {lisp PUT}.} {name {lisp NOEXTENT}} {text If this is non-{lisp NIL}, TEdit will not update the {lisp EXTENT} of the editing window. This is for the use of applications which run TEdit in part of the window.} {name {lisp NOTITLE}} {text If this is non-{lisp NIL}, TEdit will never change the title on the editing window.} {name {lisp PROMTPWINDOWHEIGHT}} {text The height of the [TEdit-created] prompting window, in lines.} {name {lisp TTYWINDOW}} {text If specified, this will be the window used to back the TEdit process's TTYDISPLAYSTREAM. Normally, TEdit makes a closed window that serves the purpose, which is as a path for copy-selected items to get to the edit window.} {name {lisp SLOWUPDATE}} {text Forces TEdit to bypass optimizations in its screen update.} {name {lisp INTERRUPTS}} {text A list of Lisp interrupts, in the same form as {var TEDIT.INTERRUPTS} which will be enabled while this TEdit is running.} {name {lisp PUTFN}} {text Called both before and after the TEdit PUT command is performed, with arguments {arg TextStream} {arg FullFileNmae} and one of the atoms {lisp BEFORE} or {lisp AFTER}. When called before the PUT, this function may return the atom {lisp DON'T}, which aborts the PUT process. Generally, this function is present for TEdit client systems to perform their own cleanup.} {name {lisp REGION}} {text Specifies a sub-region of the window in which TEdit is to operate. BEWARE: If this is used, the client system must control scrolling, mouse interaction, and a variety of other things. This facility is not fully debugged.} {name {lisp TEDIT.TENTATIVE}} {text If this is non-{lisp NIL}, TEdit will keep track of text which is "new" during the session, and will record that fact as part of the file at PUT time. This is present for the use of the EDITMARKS package.} {End LabeledList Tedit Properties} Any {arg PROPS} specified will be appended to the front of whatever is the value of {var TEDIT.DEFAULT.PROPS}; respecified properties will override anything in the defaults. This provides client applications with a way to set default edit properties. }}{comment end of TEDIT FNDEF.} }{End SubSec Tedit Functional Interface} {begin Subsec TEdit Data Structures} {title TEdit Functional Interface} {Text The "Text Stream" Data Structure TEdit keeps a {lisp STREAM} which describes the current state of the text you're editing. You can use most of the usual stream operations on that stream: {lisp BIN}, {lisp SETFILEPTR}, {lisp GETFILEPTR}, and {lisp GETEOFPTR} do the usual things. {lisp BOUT} inserts a character in the stream just in front of the next character you'd read if you {lisp BIN}ned. You can get the stream by calling {lisp (TEXTSTREAM {Arg EditWindow})}. If you need to save the state of an edit, you can save this stream. Calling {fn TEDIT} with the stream as the {arg TEXT} argument will let you continue from where you left off. There is a datatype called {lisp TEXTSTREAM} which defines several fields that are of interest within the stream: {Begin LabeledList fields of TEXTSTREAM} {name {lisp TEXTOBJ}} {text The {lisp TEXTOBJ} which describes the edit session.} {name {lisp PIECE}} {text The {lisp PIECE} which describes the text at the file pointer.} {End LabeledList fields of TEXTSTREAM} The "Text Object" Data Structure TEdit keeps a variety of other information about each edit window, in a data structure called a {Lisp TEXTOBJ}. Field {lisp TEXTOBJ} of a text {Lisp STREAM} points to the associated {lisp TEXTOBJ}, which contains these fields of interest: {Begin LabeledList fields of TEXTOBJ} {name {lisp \WINDOW}} {text The edit window which contains the text. If this is {lisp NIL}, there is no edit window for this text.} {name {lisp SEL}} {text The most recent selection made in this text.} {name {lisp SCRATCHSEL}} {text A scratch {lisp SELECTION}, used by the mouse handler for the edit window, but otherwise available for scratch use.} {name {lisp TEXTLEN}} {text The current length of the edited text.} {name {lisp STREAMHINT}} {text Points to the text {lisp STREAM} which describes the text.} {name {lisp EDITFINISHEDFLG}} {text If this is non-{lisp NIL}, TEdit will halt after the next time through the keyboard polling loop. No check will be made for unsaved changes. Unless it is {lisp T}, the value of {lisp EDITFINISHEDFLG} will be returned as the result of TEdit.} {End LabeledList fields of TEXTOBJ} The "Selection" Data Structure The selected text is described by an object of type {lisp SELECTION}, whose fields are as follows: {Begin LabeledList fields of SELECTION} {name {lisp CH#}} {text The character number of the first character in the selection. The first character in the text being edited is numbered 1.} {name {lisp CHLIM}} {text The character number of the last character in the selection. Must be {ge} {lisp CH#}.} {name {lisp DCH}} {text The number of characters in the selection. If {lisp DCH} is zero, then no characters are selected, and the Selection can be used only to describe a place to insert text.} {name {lisp ONFLG}} {text Tells whether the Selection is indicated in the edit window. If {lisp T}, it is; if {lisp NIL}, it's not.} {name {lisp \TEXTOBJ}} {text The {lisp TEXTOBJ} that describes the selected text. You can use this to get to the Stream itself.} {name {lisp X0}} {text The X position (edit-window-relative) of the left edge of the first selected character.} {name {lisp Y0}} {text The Y position of the bottom of the first selected character (not the character's base line, the bottom of its descent).} {name {lisp XLIM}} {text The X position of the right edge of the last character selected. If {lisp DCH} is zero (a "point" selection), {lisp XLIM}={lisp X0}.} {name {lisp YLIM}} {text The bottom of the last character in the selection.} {name {lisp DX}} {text The width of the selection. If {lisp DCH} is zero, this will be also.} {name {lisp SELOBJ}} {text This is for a future object-oriented editing interface.} {name {lisp POINT}} {text Tells which side of the selection the caret should appear on. It will be one of the atoms {lisp LEFT} and {lisp RIGHT}.} {name {lisp SET}} {text {lisp T} if this selection is currently valid, {lisp NIL} if it is obsolete or has never been set.} {name {lisp SELKIND}} {text What kind of selection this is. One of the atoms {lisp CHAR}, {lisp WORD}, {lisp LINE}, or {lisp PARA}.} {name {lisp HOW}} {text A {lisp TEXTURE}, which will be used to highlight the selecton.} {name {lisp HOWHEIGHT}} {text How high the highlighting is to extend. A selection's highlight starts at the bottom of the lowest descender, and extends upward for {lisp HOWHEIGHT} pixels. To always get highlighting a full line tall, set this to 16384.} {name {lisp HASCARET}} {text {lisp T} if this selection should have a caret flashing next to it, {lisp NIL} otherwise.} {End LabeledList fields of SELECTION} }{End SubSec Tedit Data Structures} {begin subsec TEdit Functions} {Title TEdit Interface Functions} {text TEdit exports the following functions for use in custom interfaces: {FnDef {Name OPENTEXTSTREAM} {Args TEXT WINDOW START END PROPS} {Text Creates a text {lisp STREAM} describing {arg TEXT}, and returns it. If {arg WINDOW} is specified, the text will be displayed there, and any changes to the text will be reflected there as they happen. You will also be able to scroll the window and select things there as usual. {arg TEXT} may be an existing {lisp TEXTOBJ} or text {lisp STREAM}. If {arg START} and {arg END} are given, then only the section of {arg TEXT} delimited is edited (if that portion of the file looks itself like a TEdit-structured file, then TEdit will honor the font, paragraph, and IMAGEOBJ information. Otherwise, it will be treated as a plain-text file). {arg PROPS} is the same as for {fn TEDIT}. Given the {lisp STREAM}, you can use a number of functions to change the text in an edit window, under program control. The edit window gets updated as the text is changed. }} {FnDef {Name TEDIT.SETSEL} {Args STREAM CH#orSEL LEN POINT PENDINGDEL? LEAVECARETLOOKS} {Text Sets the selection in {arg STREAM}. If {arg CH#orSEL} is a {lisp SELECTION}, it is used as-is. Otherwise, {arg CH#orSEL} is the first character in the selection, and {arg LEN} is the number of characters to select (zero is allowed, and gives just an insertion point). {arg POINT} tells which side of the selection the caret should come on. It must be one of the atoms {lisp LEFT} or {lisp RIGHT}. If {Arg PENDINGDEL?} is non-{lisp NIL}, the selection will be a pending-delete selection--the selected text will be deleted at the next type-in (or if text is copied or moved there). Otherwise, the selection will be a normal selection. Normally, the act of making a selection sets the "caret" looks--the looks for any characters typed at the caret. This can be suppressed by passing in a non-{lisp NIL} {arg LEAVECARETLOOKS}. }} {FnDef {name TEDIT.GETSEL} {args STREAM} {text Returns the {lisp SELECTION} which describes the current selection in the edit window described by {arg STREAM}. }} {FnDef {name TEDIT.SHOWSEL} {args STREAM ONFLG SEL} {text Lets you turn the highlighting of the selection {arg SEL} on and off. If {arg ONFLG} is {lisp T}, the selection {arg SEL} in {arg STREAM} will be highlit in the edit window; if {lisp NIL}, any highlighting will be turned off. If {arg SEL} is {lisp NIL}, it defaults to the current selection in {arg STREAM}. }} {FnDef {name TEDIT.SEL.AS.STRING} {args STREAM SEL} {text Returns the currently-selected text as a string. If {arg SEL} is non-{lisp NIL}, the text it describes will be returned. }} {FnDef {name COERCETEXTOBJ} {args STREAM TYPE} {text Converts a text stream, {lisp TEXTOBJ}, or edit window into another form, specified by {arg TYPE}. The possible values for {arg TYPE} are: {Begin LabeledList COERCETEXTOBJ Type values} {name {lisp STRINGP}} {text COERCETEXTOBJ will return a string (with any formatting and font information stripped out).} {name {lisp FILE}} {text COERCETEXTOBJ will return a file containing the document's text (complete with formatting and font information).} {name {lisp STREAM}} {text COERCETEXTOBJ will return a stream from which you may BIN or otherwise read the document} {name {lisp SPLIT}} {text COERCETEXTOBJ will return list of two files. The first contains the text for the document, and the second contains the formatting information. If these files are concatenated, they make a complete, legal TEdit file.} {End LabeledList COERCETEXTOBJ Type values} }} {FnDef {name TEDIT.INSERT} {args STREAM TEXT CH#orSEL LOOKS DONTSCROLL} {text Inserts the string {arg TEXT} into {arg STREAM}, as though it had been typed in. {arg CH#orSEL} tells where to insert the text: If it's {lisp NIL}, the text goes in where the caret is. If it's a {lisp FIXP}, the text is inserted in front of the corresponding character (The first character in the stream is numbered 1). If it's a {lisp SELECTION}, the text is inserted accordingly. If the {Arg LOOKS} argument is provided, it must be a font descriptor. The inserted text will appear in that font. Normally, TEdit scrolls the editing window so that each change is visible as it is made. If you want the window left where it is instead, the {Arg DONTSCROLL} argument should be non-{Lisp NIL}. }} {FnDef {name TEDIT.DELETE} {args STREAM CH#orSEL LEN} {text Deletes text from {arg STREAM}. If {arg CH#orSEL} is a {Lisp SELECTION}, the text it describes will be deleted; if {arg CH#orSEL} is a {lisp FIXP}, it is the character number of the first character to delete. In that case, {arg LEN} must also be present; it is the number of characters to be deleted. }} {FnDef {name TEDIT.INCLUDE} {args TEXTOBJ FILE START END} {text Performs the TEdit "Include" command, inserting the text from file {arg FILE} into {arg TEXTOBJ}. If {arg START} and {arg END} are supplied, only the specified portion of the file is included. }} {FnDef {name TEDIT.PUT} {args STREAM FILE} {text Performs the TEdit "Put" command, saving the text from {arg TEXTOBJ} onto the file {arg FILE}. If {arg FILE} is not supplied, the user will be asked for a file name. }} {FnDef {name TEDIT.FIND} {args STREAM TEXT START# END# WILDCARDS?} {text Searches for the next occurence of {arg TEXT} inside {arg STREAM}. If {arg START#} is present, the search starts there; otherwise, the search starts from the caret. If {arg END#} is present, the search will end at that character; otherwise, it ends at the end of the text. If a match is found, {fn TEDIT.FIND} returns the character number of the first character in the matching text. If no match is found, it returns {lisp NIL}. If {arg WILDCARDS?} is non-{lisp NIL}, the search pattern can contain wildcard characters: "#" matches any single character, "*" matches any sequence of characters, and "'" can be used to quote one of the wildcards. When wildcards are enabled, {Fn TEDIT.FIND} returns a list consisting of the character numbers of the first and last characters in the matching text. }} {FnDef {name TEDIT.HARDCOPY} {args STREAM FILE DONTSEND BREAKPAGETITLE SERVER PRINTOPTIONS} {text Sends the text contained in {arg STREAM} to the printer. If a file name is given in {arg FILE}, the press file will be left there for you to use. If {arg DONTSEND} is non-{lisp NIL}, the file will not be sent to the printer; use this if you only want to create a press file for later use. If {arg BREAKPAGETITLE} is non-{lisp NIL}, it is used as the title on the "break page" printed before the text. You can specify the print server where the hardcopy is to be sent, using the {Arg SERVER} argument; if it is {lisp NIL}, TEdit uses {Var DEFAULTPRINTINGHOST}. You may also specify printing options (number of copies, whether to print on both sides of the paper, etc.) using {arg PRINTOPTIONS}. It is a "property list" in the form accepted by {Fn SEND.FILE.TO.PRINTER} (see {pageref FN SEND.FILE.TO.PRINTER}). {ARG FILE} may aslo be an open image stream of type PRESS or INTERPRESS. If so, the hardcopy output will be appended to the already-open stream, and the stream will be left open when TEdit is finished. }} {FnDef {name TEDIT.LOOKS} {args STREAM NEWLOOKS SELORCH# LEN} {text Changes the character looks of selected characters, e.g., the font, character size, etc. {arg SELORCH#} can be a {lisp SELECTION}, an integer, or {lisp NIL}. If {arg SELORCH#} is a {Lisp SELECTION}, the text it describes will be changed; if it is a {lisp FIXP}, it is the character number of the first character to changed. In that case, {arg LEN} must also be present; it is the number of characters to be changed. A {arg SELORCH#} of {lisp NIL} will use the current selection. {arg NEWLOOKS} is a property-list-like description of the changes to be made. The property names tell what to change, and the property values describe the change. Any property which isn't changed explicitly retains its old value. Thus, it is possible to make a piece of text all bold without changing the fonts the text is in. The possible list entries are as follows: {labeledlist {name {lisp FAMILY}} {text The name of the font family. All the selected text is changed to be in that font.} {name {lisp FACE}} {text The face for the new font. This may be in either of the two forms acceptable to {fn FONTCREATE}: a list such as {lisp (BOLD ITALIC REGULAR)}, or an atom such as {lisp MRR}.} {name {lisp WEIGHT}} {text The new weight for the font. This must be one of {lisp LIGHT}, {lisp MEDIUM}, or {Lisp BOLD}. Specifying this {it disables} the {lisp FACE} parameter.} {name {lisp SLOPE}} {text The new slope for the font. This must be one of {lisp REGULAR} or {Lisp ITALIC}. Specifying this {it disables} the {lisp FACE} parameter.} {name {lisp EXPANSION}} {text The new weight for the font. This must be one of {lisp CONDENSED}, {lisp REGULAR}, or {Lisp EXPANDED}. Specifying this {it disables} the {lisp FACE} parameter.} {name {lisp SIZE}} {text The new point size.} {name {lisp UNDERLINE}} {text The value for this property must be one of the atoms {lisp ON} or {lisp OFF}. The text will be underscored or not, accordingly.} {name {lisp OVERLINE}} {text The value for this property must be one of the atoms {lisp ON} or {lisp OFF}. The text will be overscored or not, accordingly.} {name {lisp STRIKEOUT}} {text The value for this property must be one of the atoms {lisp ON} or {lisp OFF}. The text will be struck through with a single line or not, accordingly.} {name {lisp SUPERSCRIPT}} {text A distance, in points. The text will be raised above the normal baseline by that amount. This is mutually exclusive with {lisp SUBSCRIPT}.} {name {lisp SUBSCRIPT}} {text A distance, in points. The text will be raised above the normal baseline by that amount. This is mutually exclusive with {lisp SUPERSCRIPT}.} {name {lisp PROTECTED}} {text The value for this property must be one of the atoms {lisp ON} or {lisp OFF}. If it is {lisp ON}, the text will be protected from mouse selection and from deletion.} {name {lisp SELECTPOINT}} {text The value for this property must be one of the atoms {lisp ON} or {lisp OFF}. If a character has this property, the user can make a point selection just after it, even if the character is also {lisp PROTECTED}.} {name {lisp INVISIBLE}} {text The value for this property must be one of the atoms {lisp ON} or {lisp OFF}. If a character has this property, the character will not appear on the screen or on hardcopy.} } }} {FnDef {name TEDIT.GET.LOOKS} {args STREAM SELORCH#} {text Returns a P-list describing the character looks of the specified character(s). This P-list is suitable for passing to {fn TEDIT.LOOKS}. {arg SELORCH#} can be a {lisp SELECTION}, an integer, or {lisp NIL}. If {arg SELORCH#} is a {Lisp SELECTION}. }} {FnDef {name TEDIT.PARALOOKS} {args STREAM NEWLOOKS SELORCH# LEN} {text Changes the paragraph looks of selected paragraphs, e.g., the margins, line leading, etc. {arg SELORCH#} can be a {lisp SELECTION}, an integer, or {lisp NIL}. If {arg SELORCH#} is a {lisp SELECTION}, the text it describes will be changed; if it is a {lisp FIXP}, it is the character number of the first character to changed. In that case, {arg LEN} must also be present; it is the number of characters to be changed. A {arg SELORCH#} of {lisp NIL} will use the current selection. In all cases, {fn TEDIT.PARALOOKS} operates on {it whole paragraphs}. If any portion of a paragraph is included in the selection, the entire paragraph's looks will be changed. {arg NEWLOOKS} is a property-list-like description of the changes to be made. The property names tell what to change, and the property values describe the change. Any property which isn't changed explicitly retains its old value. Thus, it is possible to make a paragraph indented without changing its tab stops. The possible list entries are as follows: {Begin LabeledList} {name {lisp QUAD}} {text One of {lisp LEFT} (for flush-left, ragged-right), {lisp CENTERED} (for centered lines), {lisp RIGHT} (for flush-right, ragged-left), or {lisp JUSTIFIED} (for flush-left and -right).} {name {lisp 1STLEFTMARGIN}} {text The left margin for the first line of the paragraph, in points.} {name {lisp LEFTMARGIN}} {text The left margin for the rest of the paragraph, in points.} {name {lisp RIGHTMARGIN}} {text The right margin for all lines of the paragraph, in points. If this value is 0, one gets a "floating" right margin, which adjusts to the width of the edit window or paper.} {name {lisp TABS}} {text This is a {lisp CONS} pair, whose {lisp CAR} is a relative tab width and whose {lisp CDR} is a list of absolute tab stops. A tab advances the cursor to the next absolute tab stop to the right of the current position. Should there be no absolute tab stop to the right of the cursor, the cursor is advanced by the relative tab width. The relative tab width defaults to .5 inches (= 36 pts). Each absolute tab stop is a {lisp CONS} pair with the car being the position, and the {lisp CDR} being one of {lisp LEFT}, {lisp RIGHT} or {lisp CENTER}. This value indicates how the word following the tab will be justified with respect to the tab. For instance, {lisp LEFT} indicates that the left edge of the word following the tab will be at the tab position indicated in the {lisp CAR}. For a {lisp RIGHT} tab, the right edge of the word following the tab would have been located at the position indicated in the {lisp CAR}. {lisp CENTER} indicates that the word following the tab will be centered at the position in the {lisp CAR}.} {name {lisp LINELEADING}} {text The space to be left before each line of the paragraph, in points.} {name {lisp PARALEADING}} {text Additional space to be left before the first line of the paragraph, in points.} {name {lisp POSTPARALEADING}} {text Additional space to be left after the last line of the paragraph, in points.} {End LabeledList} }} {FnDef {name TEDIT.QUIT} {args STREAM VALUE} {text {arg STREAM} must be the text stream associated with a running TEdit. {lisp TEDIT.QUIT} causes the editing session to end. If {arg VALUE} is given, it is returned as TEdit's result; otherwise, TEdit will return the usual result. The user is not asked to confirm his desire to stop editing. }} {FnDef {name TEDIT.KILL} {args STREAM} {text {arg STREAM} must be the text stream, {lisp TEXTOBJ}, or edit window associated with a running TEdit. {lisp TEDIT.KILL} kills the TEdit process, and cleans up its data structures. It does not cause TEdit to return a result. }} {FnDef {name TEDIT.ADD.MENUITEM} {args MENU ITEM} {text Adds a menu {arg ITEM} to {arg MENU}. This will update the menu's image so that the newly-added item will appear the next time the menu pops up. This is only guaranteed to work right with pop-up menus which aren't visible. }} {FnDef {name TEDIT.REMOVE.MENUITEM} {args MENU ITEM} {text Removes a menu {arg ITEM} from {arg MENU}. This will update the menu's image so that the newly-added item will appear the next time the menu pops up. This is only guaranteed to work right with pop-up menus which aren't visible. {arg ITEM} may be either the whole menu item, or just the indicator which appears in the menu's image. }} {FnDef {name TEXTOBJ} {args STREAM/WINDOW} {text Given a text stream, or a TEdit editing window, returns the associated {Lisp TEXTOBJ}. }} {FnDef {name TEXTSTREAM} {args TEXTOBJ/WINDOW} {text Given a {Lisp TEXTOBJ} or a TEdit editing window, returns the associated text stream. }} {FnDef {name TEXTPROP} {args TEXTOBJ/STREAM PROPNAME VALUE} {text Queries or sets the value of editor properties, such as the ones passed to {FN TEDIT} or {FN OPENTEXTSTREAM} in their {arg PROPS} arguments. This can also be used to associate user data with an editing session. If {ARG VALUE} is omitted, the current value associated with {arg PROPNAME} is returned; if {arg VALUE} is present, it becomes {arg PROPNAME}'s associated value. }} {FnDef {name TEDIT.FORMATTEDFILEP} {args STREAM} {text Tells whether a given text stream is plain text (result is {Lisp NIL}) or must be stored as a special TEdit-format file (result is one of the atoms {lisp CHARLOOKS}, {lisp PARALOOKS}, or {lisp IMAGEOBJ}, depending on the amount of formatting information that must be stored). }} {FnDef {name TEDIT.CARETLOOKS} {args STREAM FONT} {text The looks of newly-typed characters are controlled by the looks that are "attached to the caret". This function lets you set those looks for a given document. {Arg FONT} is either a font descriptor or a {Lisp CHARLOOKS}. Any text inserted or typed in thereafter will appear in that font (or with those looks). }} {FnDef {name TEDIT.STREAMCHANGEDP} {args STREAM RESET?} {text Returns {lisp T} if the text represented by the {Arg STREAM} has been modified since it was last saved. If {Arg RESET?} is non-{lisp NIL}, then the change indicator will be reset--i.e., TEdit will then believe that the text is unchanged, and will not ask for confirmation of the {Lisp Quit} and {lisp Get} operations. }} {FnDef {name TEDIT.NORMALIZECARET} {args STREAM SEL} {text Makes sure that the caret is visible in the editing window; if not, the document is scrolled to place the caret on the top line of the window. This is normally controlled by the existing selection for the given text stream. However, if {arg SEL} is specified, it is used to decide the caret's location. }} {FnDef {name COPYTEXTSTREAM} {args STREAM CROSSCOPY} {text Makes a fresh copy of the text stream {arg STREAM}. If {arg CROSSCOPY} is non-{lisp NIL}, the new stream will not share structure with the old one---it can be edited without affecting the original stream. }} {FnDef {name TEDIT.SELECTED.PIECES} {args TEXTOBJ SEL CROSSCOPY PIECEMAPFN FNARG1 FNARG2} {text Returns a list of {lisp PIECE}s that describe the text selected in the selection {arg SEL} out of the document {arg TEXTOBJ}. If {arg CROSSCOPY} is non-{lisp NIL}, the pieces will be copied. {arg PIECEMAPFN}, if given, is applied in turn to arguments ({arg PIECE}, {arg TEXTOBJ}, {arg FNARG1} and {arg FNARG2}), and the value it returns is used in place of the piece (or its copy). }} {FnDef {name TEDIT.PROMPTPRINT} {args TEXTOBJ MSG CLEAR?} {text Prints a message in the TEdit prompting window associated with the given {arg TEXTOBJ}. If {arg CLEAR?} is non-{lisp NIL}, the window will be cleared first. }} }{end subsec TEdit Functions} {begin subsec Functional Attachments} {Title User-function "Hooks" in TEdit} {text TEdit provides a number of hooks where a user-supplied function can be called. To supply a function, attach it to the edit window under the appropriate indicator, using {fn WINDOWPROP}. Every user-supplied function is {lisp APPLY}ed to the text {lisp STREAM} which describes the text. Some of these functions can also be supplied using the {arg PROPS} argument to {lisp TEDIT} or {lisp OPENTEXTSTREAM}; the descriptions below contain the details. {Def {Type (Window Property)} {name TEDIT.QUITFN} {text A function to be called whenever the user ends an editing session. This may do anything; if it returns the atom {LISP DON'T}, TEdit will not terminate. Any other result permits TEdit to do its normal cleanup and termination. This can also be supplied using the {lisp PROPS} argument to {fn TEDIT} or {fn OPENTEXTSTREAM}. }} {Def {Type (Window Property)} {name TEDIT.AFTERQUITFN} {text A function to be called after the user ends an editing session. This may perform any cleanup of side effects that you desire. This can also be supplied using the {lisp PROPS} argument to {fn TEDIT} or {fn OPENTEXTSTREAM}. }} {Def {Type (Window Property)} {name TEDIT.CMD.LOOPFN} {text A function that gets called, for effect only, each time through TEdit's main command loop. This can also be supplied using the {lisp PROPS} argument to {fn TEDIT} or {fn OPENTEXTSTREAM}. }} {Def {Type (Window Property)} {name TEDIT.CMD.CHARFN} {text A function that gets called, for effect only, once for each character typed into TEdit. The character code is passed to the function as its second argument. This can also be supplied using the {lisp PROPS} argument to {fn TEDIT} or {fn OPENTEXTSTREAM}. }} {Def {Type (Window Property)} {name TEDIT.CMD.SELFN} {text A function that gets called, each time the user tries to select something with the mouse: {LISP (SELFN {ARG TEXTOBJ} {ARG SELECTION} {ARG SELECTMODE} {ARG FINAL?})}. It is called once for each tentative selection (e.g., while the mouse button is still down, but gets moved), and once---for effect only---for the final selection. The new {lisp SELECTION} is passed as the function's second argument, and an atom describing the kind of selection (one of {lisp NORMAL}, {lisp COPY}, {lisp MOVE}, {lisp PENDINGDEL} (for an extended selection that will be deleted on type-in), or {lisp DELETE}) as the third. When the function is being called with a candidate selection, {arg FINAL?} will be the atom {lisp TENTATIVE}; when being called with the final selection, {arg FINAL?} is the atom {lisp FINAL}. When the function is called with a candidate selection, it may veto that selection by returning the atom {lisp DON'T}. This can be used to limit selections to items of interest. If a selection is vetoed, the old selection will remain highlighted; the effect is that of the user being unable to move the selection from its old location. This can also be supplied using the {lisp PROPS} argument to {fn TEDIT} or {fn OPENTEXTSTREAM}. }} {Def {Type (Window Property)} {name TEDIT.PRESCROLLFN} {text Called just before TEdit scrolls the edit window. }} {Def {Type (Window Property)} {name TEDIT.POSTSCROLLFN} {text Called just after TEdit scrolls the edit window. }} {Def {Type (TEdit Property)} {name OVERFLOWFN} {text Called when TEdit is about to move some text off-screen, with the edit window and the {lisp TEXTOBJ} as arguments. This function may handle the text overflow itself (say by reshaping the window), or it may let TEdit take its normal course. If the function handles the problem, it must return a non-{lisp NIL} result. If TEdit is to handle the overflow, the value returned must be {lisp NIL}. }} {Def {Type (Window Property)} {name TEDIT.TITLEMENUFN} {text Called whenever the user presses the {lisp LEFT} or {lisp MIDDLE} mouse button in the edit window's title region. Can also be supplied using the {lisp PROPS} argument to {fn TEDIT} or {fn OPENTEXTSTREAM}. Normally, this is the function {fn TEDIT.DEFAULT.MENUFN}, which brings up the usual TEdit command menu. }} {Def {Type (TEdit Property)} {name CARETLOOKSFN} {text Called whenever TEdit is about to set the caret looks for an edit window. This function, called as {lisp (CARETLOOKSFN {arg NEWLOOKS} {arg TEXTOBJ})} may perform whatever checking it likes, and then return either the atom {lisp DON'T}, meaning that the caret looks are not to be changed, {lisp NIL}, meaning that {arg NEWLOOKS} should be used as the caret looks, or a new {lisp CHARLOOKS} which will be used as the caret looks. Note: if this function returns a new {lisp CHARLOOKS}, it must {it not} be a smashed version of {arg NEWLOOKS}. }} TEdit also saves pointers to its data structures on each edit window. They are available for any user function's use. {Def {Type (Window Property)} {name TEXTOBJ} {text The {lisp TEXTOBJ} which describes the current editing session. }} {Def {Type (Window Property)} {name TEXTSTREAM} {text The text {lisp STREAM} which describes the text of the document. }} }{end subsec Functional Attachments} {begin subsec TEdit Menu} {title Changing the TEdit Command Menu} {text You may replace the {lisp MIDDLE}-button command menu with one of your own. When you press the {lisp MIDDLE} button inside an edit window's title region, TEDIT calls the value of the {lisp TEDIT.TITLMENUFN} window property with the window as its argument. Normally, what gets called is {fn TEDIT.DEFAULT.MENUFN},{index TEDIT.DEFAULT.MENUFN Fn} but you may change it to anything you like. {fn TEDIT.DEFAULT.MENUFN} brings up a menu of commands. If the edit window has a property {lisp TEDIT.MENU},{index TEDIT.MENU (Window Property)} that menu is used. If not, TEdit looks for the window property {lisp TEDIT.MENU.COMMANDS}{index TEDIT.MENU.COMMANDS (Window Property)} (a list of menu items) and constructs a menu from that. Failing that, it uses {var TEDIT.DEFAULT.MENU}{index TEDIT.DEFAULT.MENU Var}. This means that you can control the command menu by setting the appropriate window properties. Alternatively, you may add your own menu buttons to the default menu, {var TEDIT.DEFAULT.MENU}. {lispcode (TEDIT.ADD.MENUITEM TEDIT.DEFAULT.MENU {arg ITEM})} will add {arg ITEM} to the TEdit menu. Menu items should be in the form {lisp ({arg NAME} (QUOTE {arg FUNCTION}))}, where {arg NAME} is what appears in the menu, and {arg FUNCTION} will be applied to the text stream, and can perform any operation you desire. Finally, you may {it remove} menu items from the default menu, by doing {lispcode (TEDIT.REMOVE.MENUITEM TEDIT.DEFAULT.MENU {arg ITEM})} {arg ITEM} can be either a complete menu item, or just the text that appears in the menu; either will do the job. }{end subsec TEdit Menu} {begin subsec TEdit variables} {title Variables Which Control TEdit} {text There are a number of global variables which control TEdit, or which contain state information for editing sessions in progress: {vardef {name TEDIT.EXTEND.PENDING.DELETE} {text If this is non-{lisp NIL}, extending a selection makes it into a pending-delete selection. See the selection section. }} {vardef {name TEDIT.DEFAULT.FONT} {text A {Lisp FONTDESCRIPTOR}. This is the font for displaying TEdit documents which don't specify their own font information. }} {vardef {name TEDIT.DEFAULT.FMTSPEC} {text A paragraph-looks description. This contains the default looks for a paragraph. }} {vardef {name TEDIT.SELECTION} {text A {lisp SELECTION}. This is the most recent regular selection made in {it any} TEdit window. }} {vardef {name TEDIT.SHIFTEDSELECTION} {text A {lisp SELECTION}. This is the most recent {lisp SHIFT}-selection made in {it any} TEdit window. }} {vardef {name TEDIT.MOVESELECTION} {text A {lisp SELECTION}. This is the most recent {lisp CTRL}-{lisp SHIFT}-selection made in {it any} TEdit window. }} {vardef {name TEDIT.READTABLE} {text A read table, this is used to translate typed-in characters into TEdit commands. See the section on TEdit readtables. This can be overridden using the {lisp READTABLE} property argument to {Lisp TEDIT}. }} {vardef {name TEDIT.WORDBOUND.READTABLE} {text The read table which controls TEdit's concept of word boundaries. The syntax classes in this table aslo determine which characters TEdit thinks are white space (which gets deleted by control-W along with the preceding word). This can be overridden using the {lisp BOUNDTABLE} property argument to {Lisp TEDIT}. }} {vardef {name TEDIT.DEFAULT.PROPS} {text A default set of PROPS arguments for TEDIT or OPENTEXTSTREAM. Any PROPS the user specifies are APPENDed to a copy of the default. The effect is that any user specifications override the defaults. }} }{end subsec TEdit variables} {begin subsec TEdit Terminal Table and Readtables} {title TEdit's Terminal Table and Readtables} {text When TEdit reads a character from the keyboard, the first thing it does is check to see if it's a command character. TEdit first looks at its default readtable, {var TEDIT.READTABLE},{index TEDIT.READTABLE Var} or at the readtable supplied as the {Lisp READTABLE} property. Failing that, TEdit then looks to the system terminal table. Characters with terminal sytax-classes {lisp CHARDELETE}, {lisp WORDDELETE}, or {lisp LINEDELETE} act as follows: {Begin labeledlist} {name {lisp CHARDELETE}} {text acts as a character-backspace.} {name {lisp WORDDELETE}} {text acts like control-W (in fact, this is how control-W is implemented.)} {name {lisp LINEDELETE}} {text acts like {lisp DEL}.} {End labeledlist} Since the system terminal table is used to implement these functions, you can assign them to other keys at will. Failing that, TEdit inserts the character at the current insertion point in the document. The TEdit default readtable is named {var TEDIT.READTABLE},{index TEDIT.READTABLE Var} and it is global. You can use the functions {lisp TEDIT.SETSYNTAX} and {lisp TEDIT.GETSYNTAX} to read it and make changes: {FnDef {name TEDIT.SETSYNTAX} {args CHARCODE CLASS TABLE} {text Sets the readtable syntax of the character whose charcode is {arg CHARCODE} to be {arg CLASS} in the read-table {arg TABLE}. The possible syntax classes are listed below. }} {FnDef {name TEDIT.GETSYNTAX} {args CHARCODE TABLE} {text Returns the TEdit syntax class of the character whose charcode is {arg CHARCODE}, according to the read-table {arg TABLE}. The possible syntax classes are listed below. An illegal syntax will be returned as {lisp NIL}. }} The allowable syntax classes are: {labeledlist {name {lisp CHARDELETE}} {text Typing this character acts like backspace} {name {lisp WORDDELETE}} {text Typing this character acts like control-W} {name {lisp DELETE}} {text Typing this character acts like {lisp DEL}} {name {lisp UNDO}} {text Typing this character causes {lisp Undo}} {name {lisp REDO}} {text Typing this character acts like {lisp ESC}} {name {lisp FN}} {text Typing this character calls a specified function (see below)} {name {lisp NONE}} {text Typing this character simply inserts it in the document. {lisp NIL} also has this effect.} } You can also cause a keystroke to invoke a function for you. To do so, use the function {FnDef {name TEDIT.SETFUNCTION} {args CHARCODE FN TABLE} {text Sets up the TEdit readtable {arg TABLE} so that typing the character with charcode {arg CHARCODE} will {lisp APPLY} {arg FN} to the text {lisp STREAM} and the {lisp TEXTOBJ} for the document being edited. The function may have arbitrary side-effects. }} The abbreviation feature described below is implemented using this function-call facility. Finally, TEdit uses the read table {var TEDIT.WORDBOUND.READTABLE}{index TEDIT.WORDBOUND.READTABLE Var} to decide where word boundaries are. Whenever two adjacent characters have different syntax classes, there is a word boundary between them. The state of this table can be controlled by the functions {FnDef {name TEDIT.WORDGET} {args CHAR TABLE} {text Returns the syntax class (a small integer) for a given character. {arg CHAR} may be either a character or a charcode; {arg TABLE} defaults to {var TEDIT.WORDBOUND.READTABLE}. }} {FnDef {name TEDIT.WORDSET} {args CHAR CLASS TABLE} {text Sets the syntax class for a character. Again, {arg CHAR} is either a character or a charcode; {arg TABLE} defaults to {lisp TEDIT.WORDBOUND.READTABLE}; {arg CLASS} may be either a small integer as returned by {lisp TEDIT.WORDGET}, or one of the atoms {lisp WHITESPACE}, {lisp TEXT}, or {lisp PUNCTUATION}. Those represent the syntax classes in the default {var TEDIT.WORDBOUND.READTABLE}. }} The initial {var TEDIT.WORDBOUND.READTABLE} assigns every character to one of the above classes, along pretty obvious lines. For purposes of control-W, whitespace between the caret and the word being deleted is also removed. This, too, can be over-ridden for a specific edit session using the {lisp BOUNDTABLE} property in the call to TEdit. }{end subsec TEdit Terminal Table and Readtables} {begin subsec Abbreviations} {title The TEdit Abbreviation Facility} {text The list {var TEDIT.ABBREVS}{index TEDIT.ABBREVS Var} is a list of "abbreviations known to TEdit." Each element of the list is a dotted pair of two strings. The first is the abbreviation (case does matter), and the second is what the abbreviation expands to. To expand an abbreviation, select it and type control-X. It will be replaced by its expansion. You can also expand single-character abbreviations while typing. Hitting control-X when no characters are underlined (i.e., after you have typed something) will expand the {it single-character} abbreviation to the left of the caret. Here is a list of the default abbreviations and their expansions: {labeledlist {name {lisp b}} {text The bullet ({bullet})} {name {lisp m}} {text The M-dash ({emdash})} {name {lisp n}} {text The figure dash ({endash})} {name {lisp "}} {text Open double-quotes (") which can be matched by two normal quotes (")} } }{end subsec Abbreviations} {begin subsec TEdit's IMAGEOBJ Interface} {title The TEdit IMAGEOBJ Interface} {text {FNDEF {name TEDIT.INSERT.OBJECT} {args STREAM OBJECT SELorCH#} {text Inserts the {lisp IMAGEOBJ} {arg OBJECT} into the document {arg STREAM} at the place specified by {arg SELorCH#}. } } {FNDEF {name TEDIT.OBJECT.CHANGED {args STREAM OBJECT} {text Notifies TEdit that the {lisp IMAGEOBJ} {arg OBJECT} has changed and the display should be updated. This is called by object editing functions after they have updated the object's internal information. } } }{end subsec TEdit's IMAGEOBJ Interface} {begin subsec Foreign-file-format Interface} {title TEdit's Interface for Readign Foreign File Formats} {text Whenever TEdit does a {lisp GET}, it first checks to see if the file should be converted from some foreign format. This conversion process is controlled by the variable {var TEDIT.INPUT.FORMATS}: {vardef {name TEDIT.DEFAULT.PROPS} {text A list of two-element lists. Each sublist corresponds to a potential input format. The first element of the sublist is a predicate, which is applied to the open input file; if it returns a non-{lisp NIL} result, conversion is performed: The second element of the list is applied to the open file, and must return an open {lisp TEXTSTREAM} containing the converted text. }} There is no outgoing foreign-file conversion provided as yet; one is planned, but its form hasn't been decided. }{end subsec Foreign-file-format Interface} }{End SubSec TEdit} /GACHA /z¸