#: 140937 S16/7.0 Beta Test
    05-Dec-92  23:43:58
Sb: #140930-What have I done now?
Fm: John G. Bennett 72431,1407
To: Julie Rosenberg Vol\PS 71630,511 (X)

Julie,

To get a macro to repeat, you must make loops.  You have to edit the actual
macro text file.  (I hope you've gotten far enough with the manual to figure
out some of what's going on in there.)

A loop is made by putting a label at the point in the code where you want the
loop to start, and a GoTo <label> statement where you want it to end. This is
just like a loop in spaghetti BASIC, except that with older BASICs every line
has a label (called a line number).

For your macros, start by recording the sequence of keystrokes you want to
repeat.  Then issue ^MD followed by the name of the macro you gave when you
recorded it.  You'll find yourself editing a non-doc file which may look
something like this:

    Sub Main
        SetHelpLevel(2)
        Insert(On)
        CmdTags(On)
        HideDots(Off)
        ColMode(Off)
        ColReplace(On)
        AutoRestore(ON)
        Key("{Ctrl+Q}f{Ctrll+Q}y"}
    End sub

You can safely ignore the first 8 lines if you want.  The Sub Main identifies
the subroutine that follows, most of the rest set various WS states (their
names make obvious which).  If you want to be picky, you can delete any which
are irrelevant to the functioning of your macro, but leave AutoRestore(ON)
which sets things back as they were before your macro executed.  Even if you
don't need that, it's best to leave it in.

The line in this macro you are interested in is the one that starts with "Key";
that's the one that replays the keystrokes you have recorded.  It might have
appeared this way (it's hard to know how the macro recorder will break things
up):

        Key("{Ctrl+Q}f")
        Key("{Ctrl+Q}y")

You want the Key line(s) to repeat, so you must insert a label and a GoTo,
thus:

        REM Other stuff omited here
    Start: Key("{Ctrl+Q}f{Ctrl+Q}y")
        GoTo Start
    End Sub


 [More]


#: 140938 S16/7.0 Beta Test
    05-Dec-92  23:44:10
Sb: #140930-What have I done now?
Fm: John G. Bennett 72431,1407
To: Julie Rosenberg Vol\PS 71630,511 (X)

 [Continued]

If you had two lines you would do this:

  Start: Key("{Ctrl+Q}f")
         Key("{Ctrl+Q}y")
         GoTo Start
   End sub

When you are through editing, issue ^KD and WS compiles the new macro for you. 
When you run it, you'll have to stop it with ^Break or Esc.

I do this sort of thing so often that I have a macro which puts the Loops in
simple macros like this.  It searches for the first "Key" and puts the label
"Start:" before it, and then searches for the End Sub and puts a "GoTo Start:"
before it.

Is this clear?  When you've mastered this, we'll go on to study how to get the
macro to stop automatically when you want it to; that's the fun part.

-jgb

PS: True recursion seems to be beyond the capability of WS macros in this
incarnation as it has always been.  What we have called recursion in previous
versions is just "tail recursion,"  which looks like recursion, but is really
just repetition.


#: 140950 S16/7.0 Beta Test
    06-Dec-92  11:12:53
Sb: #140938-What have I done now?
Fm: Julie Rosenberg Vol\PS 71630,511
To: John G. Bennett 72431,1407

Thanks, John. I'll play with this later and let you know what happens. With
respect to stopping the macro, I just want it to behave itself at the end of
the file <g>. I use these faux-recursive macros (in WS6) to substitute for
operations that ^QA can't handle, such as converting ASCII tabs to symseqs, or
converting from regular symseq tabs to decimal, and that sort of thing.
Generally it's an operation I want done globally, so I want it to continue
(loop) until it reaches the end of the file and then politely <g> terminate.

--jr






#: 140952 S16/7.0 Beta Test
    06-Dec-92  11:30:54
Sb: cursor synch
Fm: Robert J. Sawyer 76702,747
To: Rich Zuris 76702,520

Hi, Rich.

Any luck reproducing the cursor-synchronziation bug?  I still can't come up
with a series of steps that will do it every time, but I get it very quickly
when doing ^KA block copies between windows with different insert states.  It
happens with a default, undmodified WS.EXE.  Generally, copying between
windows, with insert-state changes in one window or the other between ^KA
commands, makes it happen.

It's driving me batty; I may have to go back to 7.0C for my production work and
only poke at 7.0D when actually making time for beta teting.

Cheers.

#: 140954 S16/7.0 Beta Test
    06-Dec-92  11:54:10
Sb: #140950-What have I done now?
Fm: Robert J. Sawyer 76702,747
To: Julie Rosenberg Vol\PS 71630,511

 Hi, Julie.

 Just as an aside, WS 7.0 Rev. C can do both of the operations you
 cite (converting ASCII tabs to symseqs; converting regular tabs
 to decimal) WITHOUT resorting to macros.

 To convert ASCII tabs to symseq tabs, just do a find for ^PI
 and replace with ^PI.  Yes, you've entered the same thing
 in both the find and the replace fields, but WordStar
 understands what you want to do.

 As for converting regular tabs to decimal tabs, that happens
 automatically when you reformat now.  The only change I made
 between the two samples below was changing the tab in the ruler
 line from ! to #, then issuing ^QU.  As you can see, WordStar
 dutifully changed the regular tabs to decimal for me.

 ====================================================

 .rr-----------------------------!-------------R
 Sales                           1,000.00
 Tax                             10.00
 Profits                         1.00
 Debt                            1,000,000.00

 ====================================================

 .rr-----------------------------#-------------R
 Sales                      1,000.00
 Tax                           10.00
 Profits                        1.00
 Debt                   1,000,000.00

 ====================================================

 Cheers.

Cheers.

#: 140968 S16/7.0 Beta Test
    06-Dec-92  15:05:48
Sb: #140954-What have I done now?
Fm: Julie Rosenberg Vol\PS 71630,511
To: Robert J. Sawyer 76702,747 (X)

Thanks, Rob. I guess my WS6 habits are somewhat ingrained, neh? <g>

There are similar macro tasks for which the syntax will be useful, so this is a
little classroom assignment for me even if the "fixtabs" macro isn't itself
necessary for 7C (or D...). I've learned something about the language syntax,
using a shorthand example with which I'm familiar.

Most of the use I make of the "fixtabs" operation is in the office, where (I
confess) WS7 has yet to be installed. The distribution diskettes for both 7A
and 7C are locked in the vault...installing 7 has been on the RSN list there
for quite some time, but for various and sundry reasons (not the least of which
has been the post-hurricane chaos, and now the pending office move) I've not
tackled it. I've just not had the appropriate block of quiet-time necessary for
customizing, tweaking, and so forth.

--jr







#: 140959 S16/7.0 Beta Test
    06-Dec-92  13:39:59
Sb: #140947-What have I done now?
Fm: Sandy Garrett 72677,1021
To: Sandy Garrett 72677,1021 (X)

IT WORKS!!!  I'm absolutely stunned (and not a little exhausted and
confused), but it works.
 
Sub Main
    AutoRestore(ON)
    Insert(ON)
    ColMode(OFF)
    ColReplace(OFF)
    Key("p")
    Key("f:\docs\print.rpt{Enter}")
    Key("pd")
    Key("f:\docs\print.xtr{Enter}")
    Key("^Kr")
    Key("f:\docs\girls.kr{Enter}")
    Key("^Qgp^D^D^KB")
    PauseForInput("{Enter}", 'Troop Number?  ')
    Key("^Kk")
    Key("^D")
    Key("^MDRenum^K")
    Key("^QG""")
    Key("^D^QT""")
    Key("^KA")
    Key("^KD")
    Key("^KD")
    Key("Y")
    PlayMacro 'Renum'
    Key("r.trp^K")
       IfException
       DEF: Key("{Enter}")
            Key("^U")
       End IfException
    Key("e")
    Key("f:\docs\print.xtr{Tab}")
    PlayMacro 'Renum'
    Key("r.trp^K")
    Key("p{Alt+C}2{Enter}")
    Key("p")
End Sub
 
WS is kind enough to ignore the extraneous ^U when necessary.  Not as pretty
as yours, but I understand it!  - Sandy G



#: 140982 S16/7.0 Beta Test
    06-Dec-92  17:12:25
Sb: #140947-#What have I done now?
Fm: Karl Fuss 71640,552
To: Sandy Garrett 72677,1021

Well, ACK and QRY is such a can of worms that there really should be a 
GAK!  The short course on the subject is there simply is no consistency 
in the use of one or the other.  The *only* way to find out what WS 
likes in a given situation is to *record* the situation and see what 
shows up.

Take your example, for instance.  In the first case, where you say 
"Okay, stupid, go ahead and erase it as I told you to," WS wants an ACK, 
even though there's a choice.  In the second case, where you say
"That's okay, dear, don't worry about it," WS wants a QRY!  Absolutely 
the opposite of what TFM says!  For that reason, wherever there's no 
confusion or branching possible in what I want done, I always use DEF.  
That'll work every time.

Your example, though, is one case in which DEF won't work, since there 
are two possible exception situations, not one.  Using ACK and QRY, once 
we know what WS expects in the deletion situation, we can make a single 
IfException statement to cover both eventualities.

Sub Main
    Key("y")
    Key("thisfile{Enter}")
       IfException
       ACK: Key("{Enter}")        'Does it if the file's there.
       QRY: Key("{Enter}")        'Abandons the project if it's not.
            Key("{Ctrl+U}")
       End IfException
End Sub

Go figure.  Ours not to reason.

[More...]

There is 1 Reply.


#: 140983 S16/7.0 Beta Test
    06-Dec-92  17:12:35
Sb: #140982-What have I done now?
Fm: Karl Fuss 71640,552
To: Karl Fuss 71640,552

[Part 2 of message 140982]

John may have more to say about this, being the resident logician, but 
the reason my nested IfExceptions appear to be backwards is that that 
results in the most efficient testing of situation.  If everything's 
okay, and there isn't already a file by that name present, then the 
entire IfException part of the macro is simply skipped.  I'm assuming 
that will be the normal situation.  In the rare case that that file is 
already there, we take the extra time to put things in order.

    Rename:
    Key("e{Tab}")                           'Rename
    PlayMacro 'troop'                       'Insert the number
    Key("r.trp^K")                          'Finish filename, execute.
      IfException                           'If it already exists --
      DEF: Key("{Enter}^U")                 '-- abandon the renaming.
           Key("y")                         'Erase
           PlayMacro 'troop'                'Supply the filename again
           Key("r.trp^K")
             IfException                    'Confirm erasure --
             DEF: Key("y")
             End IfException
           GoTo Rename                      '-- and go back to rename
      End IfException

Now, I know the second DEF could as well be QRY, but I haven't tested
whether the first one should be ACK or QRY.  I *think* WS would like an  
ACK, but it really makes no difference to me, since DEF will work.

--Karl


#: 140977 S16/7.0 Beta Test
    06-Dec-92  16:41:22
Sb: #140947-What have I done now?
Fm: John G. Bennett 72431,1407
To: Sandy Garrett 72677,1021

Sandy,

I'm glad you got your macro running properly, but I'm not too surprised. Macros
really aren't too hard, when they are behaving properly.

On ACK, QRY, and DEF:  You've got it basically right.  The DEF label is one you
can use to indicate what's to be done in case either a ACK or a QRY exception
occurs, when you want the same action done for both.  DEF is different from
`Key("{Enter}")' because it's just a label; you can follow it by whatever you
want.  It's like QRY and ACK, except you use it when you don't care which sort
of exception is generated.  (I have run into cases where WS misbehaves and
won't pay attention to ACK or QRY, but will to DEF.)  Getting clear about ACK
and QRY is the hard part; and knowing which one will ge generated by WS is
sometimes hard.  But the interesting thing is that you can record these two, if
you make sure that one will be generated when you record your macro.

-jgb


