From: ffang@newsuiowa.edu (Francis Fang)
Subject: Re: First 80 chars?
Date: Fri, 28 Aug 1992 21:44:18 GMT
Organization: University of Iowa, Iowa City, IA, USA
X-Newsreader: Tin 1.1 PL3

SUMMARY:

First of all, I'd like to thanks all of those who helped by responding
to my note regarding breaking up a block of text in a container to be
sent to a host excepting 80 char lines of text. I have implemented it
using a mixture of the responses.

The following is a summary of responses :

Initial message :

Hi all,

I've been designing a GUI interface for a piece of software that runs on
our DEC mini in hypercard. I need to be able to break the contents of
a field into 80 character lines so that I can send this information to
fit a field on the mini (which unfortunately does not have word wrap).
Is there some way I can do this without having to count the number of
characters in words and adding them up and so on and so forth? Isn't
there something that allows me to write the equivalent of :

   put the first 80 chars of cd fld "xxxyyyzzz" into <a container> ?

Or can I? I typed in the above (without the ?) and got a very computer
like response of "Can't understand this."

Help!? Anyone?

Thanks in advance.

The responses
--------------------------------------------------------------------------
Ian Feldman (ianf@dada.uucp) gave this solution :

 on yourCommand ----------code not tested; may require some polishing
   get field "myData" ------it now holds the data being operated upon
   repeat with i= 1 to (length(it) div 80)---# of iterations required
     put char (1+i*80)-80 to i*80 of it --redirect in right direction
   end repeat --------------------------------------------------bingo
 end yourCommand


  I can assure you that this is by far the easiest solution.  Any
  XCMD to break up the lines in fast-sized chunks that you might
  find would be _negligibly_ faster, at best, if not outright
  slower than this.

------------------------------------------------------------------------
Art Urban (urban@stout.atd.ucar.edu), 
Jasper Kips (buurt1@rulfsw.leidenuniv.nl),
and
Tantek Celik (tron@apple.com) all suggested :

(Art's message follows)
:
:

you can simply say:

  put char 1 to 80 of cd fld "xyz" into <container>

I suppose a handler to do the whole shoot'n match would be:

on handler
  repeat forever
    if cd fld "xyz" is empty then exit repeat
    put char 1 to 80 of cd fld "xyz" & return after <container>
    delete char 1 to 80 of cd fld "xyz"
  end repeat
end handler

No, I haven't tried this, but I've done similar things in the past. Hope
this helps!
------------------------------------------------------------------------
Scott Bayes (bayes@hplvec.LVLD.HP.COM) optimized the above :

Neither have I tried it, but I think you first (before the repeat) want
to copy the field to a container (get cd fld "xyz"), then use the
container in the manipulation:

on handler
  get cd fld "xyz"
  repeat forever
    if it is empty then exit repeat
    put char 1 to 80 of it & return after <container>
    delete char 1 to 80 of it
  end repeat
end handler

The reason being that operations that change fields always seem to hit
the disk, causing your script to probably be very slow, and destructive
of the orginal content of the field.

------------------------------------------------------------------------
Shawn O'Donnell (sro@media.mit.edu) offered a alternative solution :

:
  If you want to go the route of munging the field in blocks of 80
characters, you can do better than "char 1 to 80 of <container>".  You
can make the line breaks on the screen of the minicomputer appear at
word-boundaries-only by doing something like the following: (the
source is in cd fld "source, the destination is cd fld "destination",
and BufferContainer is a destructible buffer.)

on mouseUp
  put empty into cd fld "destination"
  put cd fld "source" into BufferContainer

  repeat until BufferContainer is empty
    repeat with j = 5 to 20  -- some reasonable range for wds/line
      if the length of BufferContainer < 80 then
        put BufferContainer after cd fld "destination"
        put empty into BufferContainer
      else
        if the length of (word 1 to j of BufferContainer) > 80 then
          put word 1 to (j-1) of BufferContainer & return after [opt-return]
          cd fld "destination"
          delete word 1 to (j-1) of BufferContainer
          exit repeat
        end if
      end if
    end repeat
  end repeat
end mouseUp

---
The above would have been great except we both found that when you say
line 1 of <a container>, Hypercard does not return the first line you
see on the screen in your field but the line ending with a return.

------------------------------------------------------------------------
Finally N J Taber (NJTaber@mitre.org) writes :

:
:
The following code (based on a script in a HyperCard application by
Harry Chesley at Apple) does the same job and may be easier to understand.
The message in the example is in the local variable "m" and the output (80
characters per line) is being written to card field "message".  Modify
those parameters to fit your situation.

  repeat with i = 1 to the number of lines in m
    get line i of m
    repeat while the number of chars of it > 80
      repeat with j = 80 down to 1
        if char j of it is " " then exit repeat
      end repeat
      if j < 20 then put 80 into j
      put char 1 to j of it & return after cd field "message"
      delete char 1 to j of it
    end repeat
    put it & return after cd field "message"
  end repeat


------------------------------------------------------------------------
Shawn and I had also both tried the following :

(Shawn wrote) :
You can create an invisible field, set its font to Monaco, 9 pt and
set its width so that the maximum number of characters per line is 80.
Then you put the text of the real field into the invisible field, and
you

repeat with j = 1 to the number of lines in fld "invisible"
  put line j of fld "invisible" into line j of <the mini's field>
end repeat

The line breaks will be at word boundaries, and any empty lines will
be transferred intact.   If you don't mind looking at Monaco, you
could just set the source field to Monaco, 9 point, 80 characters
wide and skip the invisible field.

---
The above would have been great except we both found that when you say
line 1 of <a container>, Hypercard does not return the first line you
see on the screen in your field but the line ending with a return.

------------------------------------------------------------------------

Once again, thanks for all your responses. Hope somebody finds this
summary somewhat helpful.

Frank.