home *** CD-ROM | disk | FTP | other *** search
/ High Voltage Shareware / high1.zip / high1 / DIR36 / RENUMBER.ZIP / RENUMBER.S
Text File  |  1993-06-12  |  14KB  |  412 lines

  1. /**********************************************************************
  2. procedure==>  vmReNumber () 1.21  <==by Volker Multhopp  05/14/93
  3.     An easy way to repeatedly renumber a text or block.
  4.  
  5.  
  6.     returns: nothing
  7.     notes: see below
  8.  
  9.     Bound to <Ctrl grey*> at end of source.
  10.  
  11.  
  12.  
  13. Ultra-short instructions:
  14.  
  15.         Call vmReNumber() wherever you want automatic renumbering.
  16.  
  17.  
  18. Some definitions:
  19.  
  20.     NSTRING:  A renumberable "number" string of all digits, ie 0-9; all caps,
  21.         ie A-Z; or all lower case, ie a-z; or the null string "".  The nstring
  22.         is terminated with a period and preceded by a bullet.
  23.  
  24.         The nstring may contain a leading tilde, ie "~", to prevent nstring
  25.         incrementing.
  26.  
  27.         The nstring may contain a leading caret, ie "^", to reset the nstring
  28.         to a particular value.
  29.  
  30.         Note: unless there's a leading caret ONLY THE FIRST NSTRING in a
  31.         sequence has any value meaning to the procedure-- the rest are just
  32.         placeholders!
  33.  
  34.     BULLET:  A special character used to mark the start of a nstring.  The
  35.         default bullet is "", chr(16), which can be reset by the user to
  36.         define distinct sequences.  The bullet should be a character not
  37.         otherwise used in the text.  The bullets can later be removed from
  38.         the final text for printing and distribution.
  39.  
  40.  
  41. DESCRIPTION OF OPERATION:
  42.  
  43.     1.  The procedure asks if the user would like to:
  44.  
  45.         a:  Renumber immediately.
  46.  
  47.         b:  Insert a number.  If so a bullet and a period are inserted into
  48.         the text at the current location.
  49.  
  50.         c:  Change the bullet.  If so, the bullet is changed according to the
  51.         user's wish.
  52.  
  53.     2.  The procedure then goes to the beginning of the text, or marked
  54.     block, and proceeds all the way to the end of the text or block.  The
  55.     pre-call position is later restored.
  56.  
  57.     3.  The procedure finds the first bullet-nstring-period sequence.  If that
  58.     nstring is empty, then it is made "1".  This nstring determines the value
  59.     of all the following ones.  This nstring should not be preceded by a
  60.     tilde.
  61.  
  62.     4.  The procedure finds the next bullet-nstring-period sequence.
  63.  
  64.         a.  If the new nstring begins with a caret, go back to step 3.
  65.  
  66.         b.  If the new ntsring begins with a tilde, it is discarded and
  67.         replaced with a tilde and the previous nstring.
  68.  
  69.         c.  Otherwise the new nstring is discarded.  The previous nstring is
  70.         incremented by one and inserted to its place.  Numbers are incremented
  71.         in the standard fashion.  Alphas are similarly incremented, ie:
  72.         A,B,C,...,Y,Z,AA,AB,...,GZY,GZZ,HAA,... etc.
  73.  
  74.     5.  Step 4. is repeated until finished.
  75.  
  76.  
  77.  
  78. AN EXAMPLE.  I'll demonstrate with a short, but complicated example.
  79.  
  80.     Let's say you want to make a list of the animals you've owned, and you
  81.     like this format:
  82.  
  83.         A. horses
  84.             A.1. arabians
  85.             A.2. quarter horses
  86.         B. goats
  87.         C. dogs
  88.             C.1. shepherds          [Fig. 1.]
  89.             C.2. hounds
  90.             C.3. pointers
  91.         D. aquarium fish
  92.  
  93.     Now suppose you want to add "cats" after "goats".  You'll have a lot of
  94.     changes to make (Pretend the list is much longer.).  But you could have
  95.     entered it as:
  96.  
  97.         A. horses
  98.             ~.1. arabians
  99.             ~.. quarter horses
  100.         . goats
  101.         . dogs
  102.             ~.^1. shepherds        [Fig. 2.]
  103.             ~.. hounds
  104.             ~.. pointers
  105.         . aquarium fish
  106.  
  107.     Well, that looks pretty abstract and ugly.  As you entered it, you could
  108.     have put in the BCD23's, etc, to get the format clearer and make it more
  109.     text-like.  Or you could have left out the 1's, because '1' is the default
  110.     sequence start.  Anyway, the '' bullets mark one series, which uses caps
  111.     and begins with 'A', because of the 'A' by horses.  The series is kept
  112.     from incrementing at the horse and dog sub-types by the tildes.
  113.  
  114.     The '' bullets (chr(19)) actually represent two distinct sequences,
  115.     because the bullet is re-initialized by the caret at shepherds.
  116.  
  117.     Anyway, if you call vmReNumber() (You need to call it twice actually,
  118.     since you have two different bullets), you'll get:
  119.  
  120.         A. horses
  121.             ~A.1. arabians
  122.             ~A.2. quarter horses
  123.         B. goats
  124.         C. dogs
  125.             ~C.^1. shepherds       [Fig. 3.]
  126.             ~C.2. hounds
  127.             ~C.3. pointers
  128.         D. aquarium fish
  129.  
  130.     Now that looks more like it.  Still, it's ugly with the funny characters,
  131.     and the shepherds aren't even aligned.  But whenever you're ready to
  132.     print, you can pull out the bullets, tildes, and carets.  The shepherds
  133.     will then be aligned and the text will look like Fig. 1.
  134.  
  135.     Anyway, you can now insert a ". cats" line (or "C. cats" or
  136.     "anything.cats") beneath the goats line, and again call vmReNumber() by
  137.     hitting the assigned key, or calling ExecMacro().  You'll get:
  138.  
  139.         A. horses
  140.             ~A.1. arabians
  141.             ~A.2. quarter horses
  142.         B. goats
  143.         C. cats
  144.         D. dogs
  145.             ~D.^1. shepherds       [Fig. 4.]
  146.             ~D.2. hounds
  147.             ~D.3. pointers
  148.         E. aquarium fish
  149.  
  150.     instantly.  Of course, with just ten lines, it's not so impressive, but
  151.     if you had dozens or hundreds of numbers spread over many pages, the labor
  152.     savings would be considerable.
  153.  
  154.  
  155.  
  156. USING VMRENUMBER()'S INSERT NUMBER OPTION:
  157.         The procedure will insert a bullet-period at the current location if
  158.         you select option 'I'.  It will then renumber the text ( or block).
  159.         However, if this is the first bullet, the procedure will put in the
  160.         default '1'.  If you want an alphabetical sequence, or different
  161.         starting value, just back up, delete the '1', and put in what you
  162.         want.  You'll also have to put in any tildes or carets 'by hand'.
  163.  
  164.  
  165. SETTING THE STARTING VALUE OF A SEQUENCE:
  166.         Only the first nstring is unchanged after a renumbering.  You could
  167.         start a series with "245", "aay", or whatever.
  168.  
  169.  
  170. SPECIFYING DIFFERENT BULLETS:
  171.         If you use option 'C'-- Change bullet, you have to give the procedure
  172.         a non-standard ascii character to use as the new bullet. I find the
  173.         easiest way to enter abnormal characters is with the standard DOS
  174.         alt-keypad technique.  Hold down <Alt> and tap <1> and <6> on the
  175.         number keypad, then release the <Alt>, you'll get chr(16). The numlock
  176.         state doesn't matter.  However, this may not work if you've redefined
  177.         those keys.  
  178.  
  179.         When you first change to a new bullet, the procedure will attempt to
  180.         renumber.  It probably won't find any valid sequences, and will tell
  181.         you so.  Just ignore the 'warning'.
  182.  
  183.  
  184. DON'T FORGET:   BULLET-NSTRING-PERIOD.
  185.                     Renumbering only affects the current bullet.  Other
  186.                         bullets are ignored.
  187.                     Tilde "~" says, "Don't increment here; use the previous
  188.                         value."
  189.                     Caret "^" says, "We're restarting this bullet sequence.
  190.                         The new starting value follows immediately."
  191.                     You reset the whole sequence by resetting the first value.
  192.  
  193. **********************************************************************/
  194.  
  195. string vmReNumberBullet[1] = ''  // delocalized variable for re-use.
  196.  
  197. proc vmReNumber ()
  198.     // I like to bind macro procedures to keys-- see end.
  199.     // If you prefer to use the execmacro technique, you could rename this
  200.     // Main(), and call with the filename, or declare vmReNumber public.
  201.  
  202.     constant
  203.     maxlen = 9      // if you need more than a billion numbers . . .
  204.  
  205.     integer
  206.     n = 1,      // value of nstring when numerical
  207.     alpha = 0,    // type of nstring: 0=num, 1=caps, 2=lower
  208.     i = 0,
  209.     k = 0,
  210.     errflag = 0,
  211.     initflag = 0
  212.  
  213.     string
  214.     nstring[maxlen] = '',
  215.     bullet[1] = vmReNumberBullet,
  216.     c[1] = '',
  217.     min[1] = '0',
  218.     max[1] = '9',
  219.     errstr[35] = ''
  220.  
  221.     // Give user his options.
  222.     ask(' Renumber; Insert number; or Change bullet "'
  223.         + bullet +'" [ric]?', c)
  224.  
  225.     lower(c)
  226.     if length(c) == 0
  227.         return()    // user escaped or returned -- do nothing.
  228.     elseif c =='c' or c == 'b'
  229.         // Let user reset the bullet
  230.         c = ''
  231.         Ask ('Set bullet from "' + bullet + '" to . . . ',c)
  232.         if length(c)
  233.             if c >= ' ' and c <= '~'  // "typewriter ascii"
  234.                 // protect the user from much more harm than good
  235.                 errstr = 'Sorry, unsafe character selected.'
  236.                 goto error
  237.             endif
  238.             bullet = c
  239.             vmReNumberBullet = bullet  // save for posterity
  240.         else
  241.             return()  // user escaped
  242.         endif
  243.     elseif c == 'i'
  244.         inserttext( bullet + '.', _insert_ )
  245.     elseif c <> 'r'
  246.         errstr = 'Unsupported key.'
  247.         goto error
  248.     endif
  249.  
  250.     // Renumber!
  251.  
  252.     pushposition()  // we're coming back
  253.     pushblock()   // saves for user if there's a block in another file.
  254.  
  255.     Set(marking,off)
  256.     if isBlockinCurrFile()
  257.         GotoBlockBegin()
  258.     else  // mark the whole file.
  259.         endFile()
  260.         Markstream()
  261.         begFile()
  262.         MarkStream()
  263.         Set(marking,off)
  264.     endif
  265.     // now we're 'block local'
  266.  
  267.     // find first bullet-nstring-period.
  268.  
  269.     if not lfind(bullet + "\^?~?[0-9A-Za-z]*\." , "glx")
  270.         errstr = 'Proper bullet "' + bullet + '" seq. not found.'
  271.         popblock()
  272.         popposition()
  273.         goto error
  274.     endif
  275.  
  276.     initialize:  // the 1st nstring
  277.     // reset defaults.
  278.     initflag = 0
  279.     i = 0
  280.     alpha = 0
  281.     min = '0'
  282.     max = '9'
  283.     nstring = ''
  284.  
  285.     // cursor is now on the 1st bullet, or a caret.
  286.     // skip over bullet, tilde, caret
  287.     c = chr(currchar())
  288.     while c == bullet or c == '~' or c == '^'
  289.         right()
  290.         c = chr(currchar())
  291.     endwhile
  292.  
  293.     if c == '.'     // null starting nstring?
  294.         // drop '1' in there, and pretend we didn't
  295.         inserttext('1',_insert_)
  296.         left()
  297.         c = chr(currchar())
  298.     endif
  299.  
  300.     // check what type of nstring we may have.
  301.     if c >= min and c <= max
  302.         // ok, use defaults.
  303.     elseif c >= 'A' and c <= 'Z'
  304.         min = 'A'
  305.         max = 'Z'
  306.         alpha = 1
  307.     elseif c >= 'a' and c <= 'z'
  308.         min = 'a'
  309.         max = 'z'
  310.         alpha = 2
  311.     endif
  312.  
  313.     // make sure it's ok, and build our nstring.
  314.     // gather the string one char at a time and check it.
  315.     while  c <> '.'
  316.         nstring = nstring + c
  317.         i = i + 1
  318.         if i > maxlen or not ((c >= min and c <= max))
  319.             errflag = 1
  320.         endif
  321.         right()
  322.         c = chr(currchar())
  323.     endwhile
  324.  
  325.     if errflag
  326.         // something's wrong with the user's init nstring.
  327.         updatedisplay() // put him on the error.
  328.         killposition()
  329.         popblock()
  330.         errstr = 'Initial string error.'
  331.         goto error
  332.     endif
  333.  
  334.     if not alpha
  335.         n = val (nstring) // initialize numerical sequence.
  336.     endif
  337.  
  338.     // Main loop, our strategy here is to look ahead with a find,
  339.     // peek if there's a tilde.  If yes, just replace the found nstring
  340.     // with ours.  If not, increase our nstring and then replace.
  341.     // But if there's a caret, reinitialize.
  342.  
  343.     while lfind (bullet + '\^?~?[0-9A-Za-z]*\.' , 'lx' )
  344.         right()
  345.         if currchar() == asc('~')
  346.             // just wait!
  347.         elseif currchar() == asc('^')
  348.             initflag = 1
  349.             break
  350.         else  // no tilde or caret; increase our nstring
  351.             if not alpha  // it's a number sequence
  352.                 n = n + 1
  353.                 nstring = str (n)
  354.             else  // an alpha string
  355.                 // increment  string
  356.                 n = length (nstring)
  357.                 i = n
  358.                 while 1     // increase the ith character
  359.                     if substr( nstring, i, 1) == max    // Is the ith a Z?
  360.                         // change it to A, and increase the preceder.
  361.                         if i == 1   // first string char?
  362.                             nstring = min + min + substr(nstring, 2, n-1 )
  363.                             // in fact, all the chars will be A's.
  364.                             break
  365.                         else
  366.                             nstring = substr( nstring, 1, i-1 ) + min
  367.                                 + substr( nstring, i + 1 , n-i )
  368.                             // this is the only looper!
  369.                             i = i - 1
  370.                         endif
  371.                     else        // 96.15% of the time just. . .
  372.                         nstring = substr ( nstring, 1, i -1 )
  373.                             + chr( asc(substr(nstring, i, 1) ) +1 )
  374.                             + substr( nstring, i + 1 , n-i )
  375.                         break
  376.                     endif
  377.                 endwhile  // until finished incrementing string.
  378.             endif
  379.             left()  // get a running start.
  380.         endif
  381.         lreplace ('[0-9A-Za-z]*\.', nstring +  '\.', 'lx1' )
  382.         // which bypasses any tildes.
  383.     endwhile    // loop for each find.
  384.  
  385.     if initflag
  386.         goto initialize
  387.     endif
  388.  
  389.     //done
  390.     popblock()
  391.     popposition()
  392.     return()
  393.  
  394.     error:
  395.     warn( errstr + '  ')
  396.     return()
  397.  
  398. end  // of vmReNumber ().
  399.  
  400. // test
  401. <ctrl grey*>   vmReNumber ()
  402.  
  403. /**********************************************************************
  404.  
  405.     Revision history:
  406.         1.0  Fully operational version.  5/14/93.
  407.         1.1  Added insert number option.  Modified doc.  Uploaded to CIS. 5/16.
  408.         1.2  Minor maintenance.  Added a Set(Marking,Off) into main stream.
  409.             Added this revision history.  Added an i=0 in initialize:.
  410.  
  411. **********************************************************************/
  412.