[comp.sys.mac.programmer] The Eternal Question

stadler@Apple.COM (Andy Stadler) (12/03/89)

In article <11881@phoenix.Princeton.EDU> bskendig@phoenix.Princeton.EDU
 (Brian Kendig) writes:

> I have several documents that must be called up by the program.  They
> range in size from about 5k to 100k.  The program must be able to call
> text file of arbitrary length in a scrollable window - not just a text
> field, but a window in its own right, with a vertical scroll bar.
> Reading the text off disk instead of hardcoding it in the stack allows
> me more flexibility.  I think that I shouldn't have any problem
> reading the file (correct me if I'm wrong, but can't variable
> containers hold data of arbitrary length?).  If I could pass the
> container with the text in it to an XCMD that would then display it,
> my problems would be solved.

You might as well start using separate text files for the text right
now.  In my group here, we have a -bulletin board- system we use here every
day, written with hypercard.  And that's exactly how it works- every posting
is a text file on a server, and the "news reader" has just 3 cards, a "new
listings" card, a "read message" card, and a "write message" card.  The
reader card just opens a text file, reads it all in, and sticks it in the
field.

However, I don't think putting >32k into any container, even if it's not
a field, is a good idea.  If you want to do the file + xcmd route, I'd pass
the file name to the xcmd and let it read the data.

> First difficulty - how do I coerce TextEdit to show the more than 32k
> and still allow for natural scrolling?  (This is where the 'Eternal
> Question' bit comes into play - I imagine that plenty of people have
> asked this before!)  If anyone has any code that would do this, or any
> suggestions on the matter, believe me, I'm all ears.  I know it's
> possible - word processors do this kind of thing naturally.

Nope.  WP's don't use TextEdit.  TE is not, and can't be modified to be,
capable of > 32k of text.

> Second difficulty - how can I determine what word was clicked on in
> the text window?  I achieve this right now with a lot of calculations
> in HyperTalk for the text field, but I'm not sure how I'd go about it
> in C.

> Any help whatsoever (in the form of ideas or code) would be greatly
> appreciated.

Most of the hard part of writing textedit is SELECTING and CHANGING the text.
You have described a read-only system.  So my solution?  Write your own read-
only textedit.  It's really quite easy!!!  Just scan through the text, using
the TextWidth() call, to calculate the number of characters to display on
each line.  Save all the line lengths in a big array, and just display 'em
yourself with a scroll bar to determine which line to start with.

In addition, since you will have all the info about which words are on
each line and where, it will be easy to calculate word offsets for "active
text".

> Also, if you happen to come up with another idea of how
> I could go about this whole business of displaying large amounts of
> text, please do suggest them!

A field with >32k of text is A LOT to read.  I strongly suggest you look
over the design, and the division of information.  Maybe you're trying to
put too much on one card.


--Andy        stadler@apple.com

bskendig@phoenix.Princeton.EDU (Brian Kendig) (12/03/89)

Good points; let me just clarify a few things I said:

In article <36956@apple.Apple.COM> stadler@Apple.COM (Andy Stadler) writes:
>In article <11881@phoenix.Princeton.EDU> bskendig@phoenix.Princeton.EDU
> (Brian Kendig) writes:
>
>> First difficulty - how do I coerce TextEdit to show the more than 32k
>> and still allow for natural scrolling?  (This is where the 'Eternal
>> Question' bit comes into play - I imagine that plenty of people have
>> asked this before!)  If anyone has any code that would do this, or any
>> suggestions on the matter, believe me, I'm all ears.  I know it's
>> possible - word processors do this kind of thing naturally.
>
>Nope.  WP's don't use TextEdit.  TE is not, and can't be modified to be,
>capable of > 32k of text.

Is there any code out there to show me how to 'simulate' TextEdit,
then, for a large amount of text?  This doesn't sound like child's
play...

>> Also, if you happen to come up with another idea of how
>> I could go about this whole business of displaying large amounts of
>> text, please do suggest them!
>
>A field with >32k of text is A LOT to read.  I strongly suggest you look
>over the design, and the division of information.  Maybe you're trying to
>put too much on one card.

I need to be able to display all of the text in one place.  Also,
here's an added curve ball to the entire plan that I had forgotten
about originally: It would be dandy, and indeed necessary, to have
some sort of search function implemented in the window, so that the
user could jump to the next section heading or back to any reference
in the text.  Again, I'm not sure how I'd go about this.

The text involved here is indeed read-only; I had overlooked that!
This makes life a *little*, if not greatly, easier.

Keep your suggestions coming!

     << Brian >>

-- 
| Brian S. Kendig       |  I feel more like I   | bskendig                   |
| Computer Engineering  |  did when I got here  | @phoenix.Princeton.EDU     |
| Princeton University  |       than I do now.  | @PUCC.BITNET               |
| Systems Engineering, NASA Space Station Freedom / General Electric WP3     |

oster@dewey.soe.berkeley.edu (David Phillip Oster) (12/03/89)

In article <36956@apple.Apple.COM> stadler@Apple.COM (Andy Stadler) writes:
>yourself with a scroll bar to determine which line to start with.
		 ------ ---
And don't forget that scrollbars themselves can only handle a range of
0-32767 since they use signed 16-bit ints. I use the following structure
to provide a wrapper around scrollbars to give them a 32-bit range:
/* ExtendedControl - 32 bit analog to scroll bars.
 */
typedef struct ExtendedControl{
	ControlHandle ch;
	LongInt max, min, value;
	Integer shiftFactor;
}ExtendedControl, *ExtendedControlPtr, **ExtendedControlHandle;

I use the shiftFactor to stuff the high order non-zero 15 bits of max, min
and value into the appropriate ControlHandle fields, and wrote my own set
of calls that mimic the control manager calls but use LongInts
throughout.

CAPPS' from Symantec will handle text longer than 32k, but it is only
available in source code form at the moment, and the last price they
quoted me was $5000.00. Their examples all use standard scrollbars, so
they suffer from the 32k line problem as I outlined above.
Your milage may differ.

> The mac is a detour in the inevitable march of mediocre computers.
> drs@bnlux0.bnl.gov (David R. Stampf)
--- David Phillip Oster          -master of the ad hoc odd hack. 
Arpa: oster@dewey.soe.berkeley.edu 
Uucp: {uwvax,decvax}!ucbvax!oster%dewey.soe.berkeley.edu 

minow@mountn.dec.com (Martin Minow) (12/03/89)

In article <11887@phoenix.Princeton.EDU> bskendig@phoenix.Princeton.EDU
(Brian Kendig) writes:
>Good points; let me just clarify a few things I said:
>
>Is there any code out there to show me how to 'simulate' TextEdit,
>then, for a large amount of text?  This doesn't sound like child's
>play...

It's not.  The source for my TextEdit clone (to appear this spring in
MacTutor) fills most of a floppy.  And it doesn't change the underlying
-- inefficient -- organization of the data (this is left as an excercise
for the student :-).

What I'd do is to write a separate program that breaks the text into
paragraph-sized chunks (each paragraph <= 32K bytes) and store each
paragraph in a database of sorts.  I suppose you could use a resource
fork, though there are more efficient (and less general) organizations.

Then you need to build a database of paragraphs with the database designator
(location in the file, text size, and formatting information).  Your "build"
program would do this by reading each paragraph into a TextEdit record
and calling TEGetHeight (IM-V) to get the formatting information.  Now,
to display the text, you read enough paragraphs to fill the screen and
write them in a window (Don't use TextEdit for this.)  Note, by the way,
that you'll have to handle styles and multiple fonts yourself.  This
isn't that difficult to do.

As a previous reply mentioned, you will have to "jacket" the scroll
bars so the range you present to the control manager is within the
short integer range permitted.  Keeping the "true" range in floating-point
would probably be sufficient.  I.e., if the range is 0-1.0, you would
do something like
	SetCtlMin(..., 0);
	SetCtlMax(..., 32767);
	SetCtlValue(..., (short int) (true_value * 32767.0));
Your scroll/display module would read paragraphs from the database
as needed.  You probably want to manage the paragraph storage yourself,
rather than relying on the Macintosh storage routines.

You also mention searching.  If you have a large chunk of text, consider
building a search-hash array for each line (or one per paragraph and
one per line).  Such an array would have, say, 256 bits per line.
Each word in the text would hash to a single bit, which would be set
in the hash array.  Your search word would then be hashed.  To search
the database, you need only look at those paragraphs/lines which have
the search bit set. There is a lot of room for experimentation here:
what is the right number of bits, should you set more than one bit,
and require the pre-search to match both, etc.  There might be something
on this in Knuth V3, or other books on searching.  I remember reading
about this technique in a CACM article in the late 1960's or early 1970's.

>The text involved here is indeed read-only; I had overlooked that!
>This makes life a *little*, if not greatly, easier.

This is the key to a fast system: do the work up front in a "database
compiler" so the user is not delayed.

Good luck.

Martin Minow
minow@thundr.enet.dec.com