🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.sys.mac
Article #19268

How to write TEXT editors (part 1 of 2)

#19268
From: David Phillip Oster
Date: Fri, 18 Sep 1987 19:08
270 lines
13494 bytes
Now that the system software has been extended to include a 
version of TextEdit that supports multiple fonts, sizes, styles 
(and colors) all within a single text edit record, it is possible 
for programs based on TextEdit to allow users to use multiple fonts.
With new text edit, each word (and potentially each character) can
have its own font.

Almost any program that doesn't allow multiple fonts could be 
extended to allow them. Examples include:
 o Calendar (Mosaic Codes)
 o MockWrite (C.E. Software)
 o MiniWriter (Maitreya Design)
 o Acta (Maitreya Design)

and, of course, hundreds more.

This document lists the problems I had to solve to really do a textEdit
text editor right. I am giving this hard won information away. This 
information cost me many sleepness nights to develop and implement. If all
developers pay attention, then I, as a user, will be able to buy a better
set of products.  So all you developers: listen up!

This is part one. It is a list of the problems you need to solve.  Part two
is a list of proposed standards, that if everyone followed, would make
everyone's life easier.

I had to solve the following problems to actually use new text edit in
a program:

(a) Tech Note #131, listing bugs in new TextEdit
(b) Scrolling code changes
(c) Font/size/style/color menus & dialog
(d) Insertion point font/size/style/color
(e) cut/copy/paste undo
(f) search and replace
(g) alternate forms for deficient systems
(h) smart quotes
(i) Bottom of page concerns
(j) arrows and extended keyboard.
(k) smart cut and paste
(l) preserving print record and window size
(m) save and multi-tasking issues.
(n) standard close/quit box.


(a) Tech Note #131 gives a list of bugs and work arounds for new TextEdit.
I had to do all that.

(b) My scrolling code had to be changed to handle the fact that, if lines 
have different width, the number of lines that fit on the screen is a 
function of position. The three important positions are:
(b.1) the number of lines to page forward if the user clicks in the pageDown
area of the scroll bar.
(b.2) the number of lines to page back if the user clicks in the pageUp
area.
(b.3) the number of lines that fit at the bottom of the screen, so we set the
CtlMax of the scroll bar correctly.
(CtlMax = totalNumberofLines - 1 - LinesThatFitAtBottom)

(c) you need to provide a way for the user to change the new attributes of a 
selected region. I provide font/size/style/color menus. I also provide: 

(c.1) a dialog for setting all these attributes at once.
Rather than use pop-up menus, I think it is better to use SFGetFile style
lists with a scroll bar.  They are easier for the user to cope with. This
dialog also includes an EditText field for the user to type in numbers.

(c.2) a dialog for adding named colors to the color menu (use the color 
picker, then type in a color name. The color name gets sorted into the menu
of available colors.) This dialog also contains a scrollable list of colors,
so that the user can select color to remove from the menu.

(c.3) I correctly remembered that your font/size/style/color menus and dialog
should show checkmarks to let the user know the current state.  Remember that
your size menu should use outline font to let the user know which sizes in 
the currently selected font are actually available a bitmaps and which will
be synthesized. (Note that there is no good way to convey this information
for styles, like underline, which may now also have their own bitmaps.)

(c.4) I wrote a custom menu definition procedure that shows each font in that
font (chicago is in chicago, geneva in geneva, and new your in new york.) My
menu definition procedure handles scroll arrows at the top and bottom, when
required, and since not all fonts are the same height, handles scrolling of
variable sized objects. I use this code in my font&size&style&color dialog
to present a scrollable list of fonts that look right.

(c.5) Remember that while the font/size/color menus set their values
directly into the selected text, the style menu toggles: If there is
no checkmark for "underline", and the user selects "underline" then
the program should underline the selected text. If there is a check,
then, when the user selects underline, it must remove all underlining
from the selected area. Note that there is an assymetry here. If ALL
the text is underlined, it will be checked, and if ALL the text it not
underlined it will be not checked, but if SOME of the text is
underlined, it also will not be checked. The program must do the right
thing.

(d) new text edit does not directly support setting the
font/size/style/color state of the inserttion point, when it is just a
blinking line. I had to implemnt my own mechanism for setting this
state.

(e) cut/copy/paste and most important, undo is implemented for every EditText
item in every dialog.  (including SFPutFile.)  Remember, undo is pretty 
useless without changing the text of the undo item of the edit menu to let
people know what operation will be undone: for example, the user does a font 
change.  The undo menu changes to "Undo Font Change ^Z". The user selects it,
the menu changes to "Redo Font Change ^Z". Undo is not implelemented in new
text edit. I had to do it.

(f) search and replace: Now that the user can have multiple fonts and styles,
fonts and styles become important for searching. I let the user paste into
search and replace EditText items, and also let them use the font/size/style
color menus and the font&size&style&color dialog while they are using the
search&replace dialog. Next to the search string are 5 checkboxes:

          Use this when I search
 _
|X| Text
 = 
| | Font
 = 
| | Size
 = 
| | Style
 = 
| | Color
 -

If the types some 12point plain chicago text in the search EditText item, and 
only has the "text" button checked, then searching behaves like in an old 
application, i.e. font information is ignored.  If the user checks the size 
box, then only 12point text will match the search string. 

Next to the replacement EditText item, I have checkboxes that read:

          Use this when I replace
 _
|X| Text
 = 
| | Font
 = 
| | Size
 = 
| | Style
 = 
| | Color
 -

The meaning here is similar.  This extension to the search and replace dialog
lets the user do everything he can now, and in addition, do things like:
 o Find the next underlined occurence of the word "Loisville"
 o Find all occurences of italic, and turn them to underline
 o Change all occurences of chicago to geneva bold.

All these checkboxes take a lot of room, so I use a custom 9point Chicago
font, and a custom control defintion procedure, and I paste the font into
my application. Since there is no safe way to add just one point size of a
font under the current font manager, this font is called ".Chicago" and
therefore doesn't show up on the font menu.

Of course, all replacements are undoable (including replace all.) I also
provide a menu item: "Go To Previous" that lets the user undo a cursor motion
(a "find" is a cursor motion.)

(g) alternate forms for deficient systems: If you are running under old 
text edit, I have alternate forms of all the dialogs and menus that hide
the fact that font editing is avialable. If you are running without color
quickdraw, I have alternate forms of all the dialogs and menus that hide
the fact that color editing is available.  

What I should have done, and will do, is change the dialogs so that 
unavailable choices are grayed out, and there is a "help" button in every
dialog that explains how to use that dialog and, if choices are grayed out,
why they are grayed out.

(h) smart quotes, and an option to turn them off. The slanted, typesetter
style '` and '' `` quotes look better than the vertical ' and ", but the
text editor should allow people to type normally, and automatically replace
them (except when the user turns it off, for example, usenet doesn't support
them, so I can't use them typing this document.)

(i) Bottom of page concerns. When you display text on the screen, it
is acceptable, and even desirable that, if the last line doesn't
entirely fit, you just show the top part that does fit.  Showing this
partial line reminds the user that more text is available off the
bottom.  The exceptions are: 

(i.1) if the user moves into this line, you need to scroll it so that
it is completely visible.  

(i.2) When printing, you must not show on the printed page lines that
extend partially off the bottom of the screen.

(j) The Apple user interface guidlines dictate what should happen if the user
presses an arrow key, or some of the keys on the extended keyboard:
<Home>, <End>, <PageUp>, <PageDown>, and what should happen if the user is 
also holding down the <Shift>, <Option>, or <Command> keys at the same time.
Text Edit does not do most of this stuff, and much that it does do, it does 
wrong, so you have to do it yourself. I even had to uncover what key codes 
these keys sent! 

(j.1) To properly implement auto-scrolling in the face of these keys,
you have to keep track of whether the left or the right end of the
selection area changed most recently, and auto-scroll that part into
visibility (selection areas may be bigger than the currently visible
window.)

(k) The Apple user interface guidlines dictate that cut and paste should be
"smart" and record whether the cut was at a beginning of a word on the left,
and the end of a word on the right, so that when you cut it should 
automatically delete extra white space if necessary, and when you paste, it 
should automatically insert white space if necesary. Some people hate this
feature and need a way to turn it off.

(l) preserving print record and window size. It is friendly, and the
multi-finder compatibility guidlines recommend, that when the user
saves a file, also saved with it are:

(l.1) the window position, so that when the user opens that document again, it
will show up in the same position of the screen.

(l.1.a) remember, when you open a document using a saved window position,
that this time the user might be on a system with a smaller screen. Force that
window on-screen! Force that window to be smaller than a screen (so the user
can use the grow box.)

(l.2) as long as we are saving the window position, it would be
friendly to also save the cursor position, and what line the document
is scrolled to.  I think it is obnoxious for a document to open with
the cursor off-screen, so I always auto-scroll the document so that
the most recently active end of the cursor is visible.

(l.3)the print record (if the user printed we should try to give him
the same page setup and print quality settings next time.)

(m) Suppose the user opens a document in your program, then deletes the data
file in multi-finder, or renames it, or moves it to another folder. The Apple
user interface guidline people want me to open the file, and not close it
again until the user closes or quits.
I prefer to handle this problem by reading into memory the entire document,
including the finder info and the creation and modification times, and any
resources, then closing the file.  Let the user do horrible things to the 
copy on disk. When the user saves, if my code can't find the original file,
or if the modification date doesn't match, it puts up an sfPutFile dialog
with an explanatory dialog below it on the screen:
"Something changed this file since the last time it was saved. I suggest
you "Save As" this file with a different name." 

The advantage of this scheme is there is no limit to the number of open
documents you can work with (as opposed to the small number of simultaneously
open files) and the program doesn't have to worry about the user renaming
an open file, or changing its folder.

(Thanks to David Dunham of Maitreya Designs for telling me this idea.)

(n) Standard closing/quitting box. A while back, Apple published a 
user interface guidline note saying that programs should use a standard
Closing/Quitting dialog. With the possible use of multi-finder, it is 
difficult for the user to tell which application owns the dialog.  I put my
application's icon in the dialog to solve this problem.

In part two, I'll talk about disk formats of data structures that I would
like declared standard.


--- David Phillip Oster            --My Good News: "I'm a perfectionist."
Arpa: oster@dewey.soe.berkeley.edu --My Bad News: "I don't charge by the hour."
Uucp: {uwvax,decvax,ihnp4}!ucbvax!oster%dewey.soe.berkeley.edu
Technical Details
Message-ID: <20831@ucbvax.BERKELEY.EDU>
Path: arc1-ca.pugleaf.net!utzoo!mnetor!uunet!husc6!cmcl2!rutgers!labrea!jade!ucbvax!dewey.soe.berkeley.edu!oster
References: <3875@cisunx.UUCP>

Show Full Headers
Complete Article Headers
Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP
Path: arc1-ca.pugleaf.net!utzoo!mnetor!uunet!husc6!cmcl2!rutgers!labrea!jade!ucbvax!dewey.soe.berkeley.edu!oster
From: oster@dewey.soe.berkeley.edu (David Phillip Oster)
Newsgroups: comp.sys.mac
Subject: How to write TEXT editors (part 1 of 2)
Message-ID: <20831@ucbvax.BERKELEY.EDU>
Date: Fri, 18-Sep-87 15:08:57 EDT
Article-I.D.: ucbvax.20831
Posted: Fri Sep 18 15:08:57 1987
Date-Received: Sun, 20-Sep-87 03:57:53 EDT
References: <3875@cisunx.UUCP>
Sender: usenet@ucbvax.BERKELEY.EDU
Reply-To: oster@dewey.soe.berkeley.edu.UUCP (David Phillip Oster)
Organization: School of Education, UC-Berkeley
Lines: 270
Keywords: System 4.1 and newer text edit
Summary: pitfalls in writing for new TextEdit