home *** CD-ROM | disk | FTP | other *** search
/ Media Share 9 / MEDIASHARE_09.ISO / progmisc / postit61.zip / POSTIT61.BAS < prev    next >
BASIC Source File  |  1993-07-04  |  25KB  |  927 lines

  1. DECLARE FUNCTION Analyze% (Filename$)
  2. DECLARE FUNCTION CheckForFile& ()
  3. DECLARE SUB ExtractFile ()
  4. DECLARE FUNCTION GetInformation% ()
  5. DECLARE FUNCTION GetInput$ (Prompt$, MaxLen%)
  6. DECLARE SUB Initialize ()
  7. DECLARE SUB JustDoIt ()
  8. DECLARE SUB MrFilter ()
  9. DECLARE SUB MsgSplit (Filename$, TheName$, OutN$, LPP%, Reserve%)
  10. DECLARE FUNCTION Num2Str$ (a%)
  11. DECLARE FUNCTION ParseFileName$ ()
  12. DECLARE SUB PrepareFile ()
  13. DECLARE SUB PrintDecoder ()
  14. DECLARE SUB PrintLine (a$)
  15. DECLARE SUB ProcessLine (In$)
  16. DECLARE SUB PutByte (a%)
  17. DECLARE SUB PutBytes (a%)
  18. DECLARE SUB ShortCopyright ()
  19. DECLARE SUB Twirl ()
  20. '===========================================================================
  21. 'BBS: FliegWeg BBS
  22. 'Date: 06-01-93 (22:54)             Number: 864
  23. 'From: VICTOR YIU                   Refer#: NONE
  24. '  To: ALL                           Recvd: NO
  25. 'Subj: PostIt! 6.1 --> 1/11           Conf: (19) QuickBasic
  26. '---------------------------------------------------------------------------
  27. 'Hi, All!
  28.  
  29. '    I'm proud to present the new version of PostIt!  I've tried to make
  30. 'everything as painless as possible.  From now on, you can just run everything
  31. 'through PostIt!, to encode and to decode.  Messages and binary.  Enjoy!
  32. '    By the way, the source code is only 22K, compared to 36K previously!
  33.  
  34. 'Victor
  35. '______O_/__________________| SNIP |__________________\_O______
  36. '      O \                  | HERE |                  / O
  37. 'This file created by PostIt! v6.1.
  38. '>>> Start of page 1.
  39.  
  40. '╔═══════════════════════════════════════════════════════╗
  41. '║   PostIt! 6.1   THE Binary <-> BASIC Script Creator   ║
  42. '╟───────────────────────────────────────────────────────╢
  43. '║      Rich Geldreich, Jim Giordano, Mark H Butler,     ║
  44. '║   Quinn Tyler Jackson, Scott Wunsch, and Victor Yiu.  ║
  45. '╚═══════════════════════════════════════════════════════╝
  46. '
  47. 'Purpose:
  48. ' To enable the posting of compressed listings on a text only net.
  49. ' This program takes a binary input file and converts it to a series
  50. ' of small, postable files which other people can capture and run to
  51. ' get the original binary file.  Do not post text files in binary
  52. ' PostIt! form, though.
  53. '
  54. ' New 6.1 features:
  55. '   o  Automatic decoding/filtering of text-scripts
  56. '   o  Automatic extraction of binary scripts
  57. '   o  Decreased source-code size
  58. '
  59. ' New huge script capability to be added in a future version
  60.  
  61. DEFINT A-Z
  62.  
  63. CONST True = -1, False = NOT True
  64. CONST LineLength = 65    ' please don't change this for safety
  65.  
  66. DIM SHARED Shift(6), Proplr$, BytesOut, TotalLinesOut, LinesOut
  67. DIM SHARED PageLength, CurrentPage, FileLength, TabStops
  68. DIM SHARED SourceFile$, DestFile$, RealSource$, aLength
  69. DIM SHARED Row, Col, CheckSum, CurrentByte, CurrentBit, Char
  70. DIM SHARED Work$, ComprChar$, Qt$, Prefix$, DefaultFile$
  71.  
  72. Good$ = "abcdefghijklmnopqrstuvwxyz"
  73. Good$ = Good$ + UCASE$(Good$) + "0123456789#$"
  74.  
  75. Initialize
  76. Func = GetInformation
  77.  
  78. SELECT CASE Func
  79.     CASE 1
  80.         ExtractFile
  81.     CASE 2
  82.         MrFilter
  83.     CASE 3
  84.         PrepareFile     ' open file, print header, etc.
  85.         JustDoIt        ' do the binary stuff
  86.         PrintDecoder    ' print decoder, close file
  87.  
  88.         LOCATE Row, Col
  89.         PRINT "          "
  90.         PRINT
  91.         PRINT TotalLinesOut; "lines in"; CurrentPage;
  92.         PRINT "file(s) written."
  93.     CASE 4
  94.         MsgSplit SourceFile$, RealSource$, DestFile$, PageLength, LinesOut
  95. END SELECT
  96.  
  97. END
  98.  
  99. ErrorRead:
  100.     PRINT "Error reading script."
  101.     END
  102.  
  103.  
  104. '______O_/__________________| SNIP |__________________\_O______
  105. '      O \                  | HERE |                  / O
  106.  
  107. 'That's all, folks!  All you have to do to get PostIt! 6.1 working is to
  108. 'clump all the messages together, headers and all, and run them through
  109. 'Mr. Filter.  Fortunately (and unfortunately for me -- I've just killed another
  110. 'one of my programs <G>  i.e. MessageSplit), it will be the last time you'll
  111. 'have to use it.  Everything should be able to be automated with PostIt!.
  112.  
  113. 'Comments and suggestions greatly welcome!
  114.  
  115. 'Victor
  116.  
  117. '... To a cat, "NO!" means "Not while I am looking"
  118. '--- Blue Wave/RA v2.12 [NR]
  119. ' * Origin: Hard Disc Cafe | Houston Texas | (713) 589-2690 |  (1:106/30.0)
  120.  
  121. FUNCTION Analyze (Filename$)
  122. ' 1=PostIt! binary
  123. ' 2=PostIt! text
  124. ' 3=regular binary
  125. ' 4=regular text
  126.  
  127. a = 4096
  128. IF LOF(1) < a THEN a = LOF(1)
  129. a$ = INPUT$(a, 1)
  130.  
  131. a = INSTR(a$, "C" + "LS:?STRING$(50,178):DEFINT A-Z 'Created by" + " PostIt! 6.")
  132. IF a THEN
  133.     CheckSum = a   ' use it to pass the start to decoder
  134.     Analyze = 1
  135.     EXIT FUNCTION
  136. END IF
  137.  
  138. a = INSTR(a$, "'" + ">>> Start of page")
  139. IF a THEN
  140.     Analyze = 2
  141.     CheckSum = a    ' use to pass it to Mr. Filter
  142.     EXIT FUNCTION
  143. END IF
  144.  
  145. Analyze = 4
  146. FOR a = 1 TO 20
  147.     Ch$ = MID$(a$, a, 1)
  148.     IF LEN(Ch$) THEN
  149.         Ch = ASC(Ch$)
  150.         SELECT CASE Ch
  151.             CASE 10, 13
  152.             CASE IS < 32
  153.                 Analyze = 3: EXIT FOR
  154.             CASE IS > 127
  155.                 HiASCII = HiASCII + 1
  156.         END SELECT
  157.     ELSE EXIT FOR
  158.     END IF
  159. NEXT
  160. IF HiASCII > 12 THEN Analyze = 3
  161.  
  162. END FUNCTION
  163.  
  164. FUNCTION CheckForFile&
  165.  
  166. OPEN SourceFile$ FOR BINARY AS #1
  167. a& = LOF(1)
  168. IF a& = 0 THEN
  169.     CLOSE
  170.     KILL SourceFile$
  171.     COLOR 7: PRINT "   File not found."
  172. END IF
  173. CheckForFile& = a&
  174.  
  175. END FUNCTION
  176.  
  177. SUB ExtractFile
  178. SHARED Good$
  179.  
  180. COLOR 7: PRINT : PRINT "Examining "; SourceFile$; "..."
  181.  
  182. ON ERROR GOTO ErrorRead
  183.  
  184. CLOSE : OPEN SourceFile$ FOR INPUT AS #1 LEN = 4096
  185. SEEK #1, CheckSum
  186. LINE INPUT #1, a$   'remove start line
  187. LINE INPUT #1, a$
  188.  
  189. Temp = INSTR(a$, ",1,")
  190. IF Temp = 0 THEN GOTO ErrorReading
  191. NewFile$ = MID$(a$, Temp + 4)
  192. OPEN NewFile$ FOR BINARY AS #2
  193.  
  194. PRINT "Loading "; SourceFile$; "..."
  195.  
  196. LINE INPUT #1, a$   'remove T$
  197. DO
  198.     IF EOF(1) THEN GOTO ErrorReading
  199.  
  200.     LINE INPUT #1, a$
  201.  
  202.     SELECT CASE LEFT$(a$, 1)
  203.         CASE "G"
  204.             IF NOT QuoteOn THEN
  205.                 a$ = MID$(a$, 3)
  206.                 IF RIGHT$(a$, 1) = Qt$ THEN a$ = LEFT$(a$, LEN(a$) - 1)
  207.  
  208.                 FOR Q = 2 TO 9       ' expand the string
  209.                     Look$ = MID$(ComprChar$, Q - 1, 1)
  210.                     S = 1
  211.                     DO
  212.                         S = INSTR(S, a$, Look$)
  213.                         IF S THEN
  214.                             a$ = LEFT$(a$, S - 1) + STRING$(Q, 97) + MID$(a$, S + 1)
  215.                         END IF
  216.                     LOOP WHILE S
  217.                 NEXT
  218.  
  219.                 Dat$ = Dat$ + RTRIM$(a$)
  220.             END IF
  221.         CASE "'"
  222.  
  223.             QuoteOn = NOT QuoteOn
  224.         CASE ELSE                ' just comments or junk
  225.             IF NOT QuoteOn THEN
  226.                 IF (MID$(a$, 2, 1) = "=") AND INSTR(a$, "Bad") THEN EXIT DO
  227.             END IF
  228.     END SELECT
  229. LOOP
  230.  
  231. n = VAL(MID$(a$, 3))             ' extract size of file
  232.  
  233. Temp = INSTR(a$, "$)<>")
  234. IF Temp = 0 THEN GOTO ErrorReading
  235. IF LEN(Dat$) <> VAL(MID$(a$, Temp + 4)) THEN GOTO ErrorReading
  236. LINE INPUT #1, a$
  237. LINE INPUT #1, a$
  238. LINE INPUT #1, a$
  239. CheckVal = VAL(MID$(a$, 8))
  240. CLOSE #1
  241.  
  242. PRINT "Decoding "; SourceFile$; "..."
  243. PRINT STRING$(50, 178);     ' print initial bar
  244. LOCATE , , 0
  245.  
  246. k = 255: V! = 50 / n
  247.  
  248. FOR a = 1 TO n          ' decode file
  249.     IF L = 0 THEN
  250.         GOSUB G: L = 6
  251.         LOCATE , 1: PRINT STRING$(V! * a, 177);
  252.     END IF
  253.  
  254.     W = T \ Shift(6 - L): GOSUB G: W = W OR T * Shift(L)
  255.     L = L - 2: B$ = CHR$(W AND k)
  256.     PUT 2, , B$
  257. NEXT
  258.  
  259. PRINT
  260. PRINT
  261. IF (C = CheckVal) AND (LOF(2) = n) THEN
  262.     PRINT NewFile$; " successfully extracted."
  263. ELSE
  264.     PRINT "Bad checksum or incomplete script!"
  265. END IF
  266.  
  267. CLOSE
  268. END
  269.  
  270. G:
  271.     I = I + 1: T = INSTR(Good$, MID$(Dat$, I, 1)) - 1
  272.     C = (C + T) * 2: C = C \ 256 + (C AND 255)
  273. RETURN
  274.  
  275. ErrorReading:
  276.     PRINT "Error reading script."
  277.     END
  278. END SUB
  279.  
  280. FUNCTION GetInformation
  281.  
  282.     '**** Remark the below for QBasic ***
  283. Temp$ = LTRIM$(RTRIM$(COMMAND$))
  284.  
  285. ShortCopyright
  286.  
  287. DO
  288.     IF LEN(Temp$) = 0 THEN
  289.         SourceFile$ = UCASE$(GetInput$("Input filename" + " (text/binary)? ", -1))
  290.     ELSE
  291.         SourceFile$ = Temp$: Temp$ = ""
  292.     END IF
  293.  
  294.     IF LEN(SourceFile$) THEN a& = CheckForFile ELSE END
  295. LOOP UNTIL a&
  296. PRINT : DefaultFile$ = ParseFileName$
  297.  
  298. Recommend = Analyze(SourceFile$)
  299. IF Recommend <= 2 THEN GetInformation = Recommend: EXIT FUNCTION
  300.  
  301. COLOR 15: PRINT "I recommend using the ";
  302. COLOR 13
  303. IF Recommend = 3 THEN
  304.     PRINT "binary script (Y)";
  305.     R$ = "Y"
  306. ELSE
  307.  
  308.     PRINT "message wrapper (N)";
  309.     R$ = "N"
  310. END IF
  311. COLOR 15: PRINT " on this file."
  312.  
  313. WhatFmt$ = UCASE$(GetInput$("Which format [" + R$ + "]? ", 1))
  314. IF (WhatFmt$ <> "Y") AND (WhatFmt$ <> "N") THEN WhatFmt$ = R$
  315. LOCATE CSRLIN - 1, 19
  316. PRINT WhatFmt$
  317.  
  318. IF WhatFmt$ = "Y" THEN
  319.     IF a& > 24000 THEN
  320.         COLOR 7: PRINT
  321.         PRINT "Sorry -- PostIt! doesn't support huge scripts" + " yet."
  322.         END
  323.     END IF
  324.     Recommend = 3
  325.     FileLength = a&
  326. ELSE
  327.     Recommend = 4
  328. END IF
  329.  
  330. a$ = "What is the destination prefix (max. 6 chars.) ["
  331. DestFile$ = UCASE$(GetInput$(a$ + DefaultFile$ + "]? ", 6))
  332. IF LEN(DestFile$) = 0 THEN
  333.     DestFile$ = DefaultFile$
  334.     LOCATE CSRLIN - 1, 52 + LEN(DefaultFile$)
  335.     PRINT DefaultFile$
  336. END IF
  337.  
  338. PRINT
  339. IF Recommend = 4 THEN
  340.     TabStops = VAL(GetInput$("Expand tabs to how many spaces" + " [4]? ", 1))
  341.     IF TabStops <= 0 THEN
  342.         TabStops = 4
  343.         LOCATE CSRLIN - 1, 36
  344.         PRINT TabStops
  345.     END IF
  346. END IF
  347.  
  348. PageLength = VAL(GetInput$("Page length [85]? ", 3))
  349. IF PageLength < 5 THEN
  350.     PageLength = 85
  351.     LOCATE CSRLIN - 1, 19
  352.     PRINT "85 "
  353. END IF
  354.  
  355. LinesOut$ = GetInput$("Lines to reserve on first message [5]? ", 2)
  356. LinesOut = VAL(LinesOut$)
  357. IF (LEN(LinesOut$) = 0) OR (LinesOut < 0) THEN
  358.     LinesOut = 5
  359.     LOCATE CSRLIN - 1, 40
  360.     PRINT "5 "
  361. END IF
  362.  
  363. LOCATE , , 0
  364. GetInformation = Recommend
  365.  
  366. END FUNCTION
  367.  
  368. FUNCTION GetInput$ (Prompt$, MaxLen)
  369.  
  370. Null$ = CHR$(0): SpaceBar$ = " "
  371. IF MaxLen < 1 THEN MaxLen = 80 - LEN(Prompt$) - POS(0)
  372.  
  373. COLOR 14: PRINT Prompt$;
  374. StartX = POS(0): Cursor = 1
  375. COLOR 7
  376.  
  377. DO
  378.     IF Updt THEN
  379.         LOCATE , StartX, 0
  380.         PRINT OutS$; SpaceBar$;
  381.         Updt = False
  382.     END IF
  383.  
  384.     LOCATE , Cursor + StartX - 1, 1, 0, 16
  385.     DO: I$ = INKEY$
  386.     LOOP UNTIL LEN(I$)
  387.  
  388.     IF LEN(I$) = 1 THEN
  389.         Updt = True
  390.  
  391.         SELECT CASE ASC(I$)
  392.         CASE IS >= 32
  393.             IF (LEN(OutS$) < MaxLen) OR (NOT Insrt AND (Cursor <= MaxLen)) THEN
  394.                 IF Cursor > 0 THEN
  395.                     OutS$ = LEFT$(OutS$, Cursor - 1) + I$ + MID$(OutS$, Cursor - (NOT Insrt))
  396.                 ELSE
  397.                     OutS$ = I$
  398.                 END IF
  399.                 Cursor = Cursor + 1
  400.             ELSE
  401.                 Updt = False
  402.             END IF
  403.         CASE 8
  404.             IF LEN(OutS$) AND (Cursor > 1) THEN
  405.                 OutS$ = LEFT$(OutS$, Cursor - 2) + MID$(OutS$, Cursor)
  406.                 Cursor = Cursor - 1
  407.             ELSE
  408.                 Updt = False
  409.             END IF
  410.         CASE 13
  411.             EXIT DO
  412.         CASE 27
  413.             IF LEN(OutS$) > 0 THEN
  414.                 LOCATE , StartX, 0
  415.                 PRINT SPACE$(LEN(OutS$) + 1);
  416.  
  417.                 OutS$ = ""
  418.                 Cursor = 1
  419.                 Updt = False
  420.             ELSE
  421.                 EXIT DO
  422.             END IF
  423.         END SELECT
  424.     END IF
  425. LOOP
  426.  
  427. LOCATE , , 1, 0, 16: PRINT
  428. GetInput$ = LTRIM$(RTRIM$(OutS$))
  429.  
  430. END FUNCTION
  431.  
  432. SUB Initialize
  433.  
  434. LOCATE , , 0
  435. FOR DefShift = 0 TO 6: Shift(DefShift) = 2 ^ DefShift: NEXT
  436.  
  437. ComprChar$ = "()*+,-./": Proplr$ = CHR$(179) + "/-\"
  438. Qt$ = CHR$(34): a$ = " "
  439.  
  440. CurrentPage = 1: CurrentBit = 0: Char = 0
  441.  
  442. END SUB
  443.  
  444. SUB JustDoIt
  445.  
  446. SEEK #1, 1
  447. LinesOut = LinesOut + 2     ' compensate for header
  448. TotalLinesOut = 3
  449. DO
  450.     CurrentByte = SEEK(1)
  451.     L& = FileLength - CurrentByte + 1 ' what's left?
  452.     SELECT CASE L&
  453.         CASE IS > 4096
  454.             Block$ = SPACE$(4096)
  455.         CASE IS <= 0
  456.             EXIT DO
  457.         CASE ELSE
  458.             Block$ = SPACE$(L&)     ' rest of it
  459.     END SELECT
  460.     GET #1, , Block$
  461.  
  462.     FOR Pointr = 1 TO LEN(Block$)
  463.         IF (Pointr AND 15) = 0 THEN
  464.             CurrentByte = CurrentByte + 16
  465.             Twirl
  466.         END IF
  467.         PutBytes ASC(MID$(Block$, Pointr, 1))
  468.     NEXT
  469. LOOP
  470.  
  471.     'flush the input buffer if it contains any bits
  472. IF CurrentBit > 0 THEN
  473.     CurrentBit = -1: PutByte Char
  474.  
  475. END IF
  476.  
  477. IF aLength > 0 THEN
  478.     IF aLength = 1 THEN
  479.         Work$ = Work$ + "a"
  480.     ELSE
  481.         Work$ = Work$ + MID$(ComprChar$, aLength - 1, 1)
  482.     END IF
  483. END IF
  484.  
  485. IF LEN(Work$) > 2 THEN
  486.     'flush the line buffer if it contains any characters
  487.     PrintLine Work$ + Qt$
  488. END IF
  489.  
  490. END SUB
  491.  
  492. SUB MrFilter
  493.  
  494. Temp = INSTR(DefaultFile$, ".")
  495. IF Temp THEN
  496.     D$ = LEFT$(DefaultFile$, Temp) + ".OUT"
  497. ELSE
  498.     D$ = DefaultFile$ + ".OUT"
  499. END IF
  500.  
  501. DestFile$ = UCASE$(GetInput$("Output filename [" + D$ + "]? ", 6))
  502. IF LEN(DestFile$) = 0 THEN
  503.     DestFile$ = D$
  504.     LOCATE CSRLIN - 1, 21 + LEN(D$), 0
  505.     PRINT D$
  506. END IF
  507.  
  508. CLOSE : OPEN SourceFile$ FOR INPUT AS #1
  509. OPEN DestFile$ FOR OUTPUT AS #2
  510. SEEK #1, CheckSum
  511.  
  512. PRINT : PRINT "Working...";
  513.  
  514. Flip = 1
  515. ChopOut = False
  516.  
  517. DO WHILE NOT EOF(1)
  518.     LINE INPUT #1, L$
  519.     L$ = RTRIM$(L$)
  520.  
  521.     IF LEN(L$) THEN
  522.         IF ASC(L$) = 39 THEN
  523.             IF LEFT$(L$, 22) = "'>>> Continued on page" THEN
  524.                 ChopOut = True
  525.                 SEEK #2, SEEK(2) - 2
  526.             ELSEIF LEFT$(L$, 18) = "'>>> Start of page" THEN
  527.                 ChopOut = False
  528.                 IF SEEK(1) <> Start THEN SEEK #1, SEEK(1) + 2
  529.             ELSEIF LEFT$(L$, 12) = "'________O_/" THEN
  530.                 ChopOut = True
  531.             ELSE
  532.                 IF NOT ChopOut THEN ProcessLine L$
  533.             END IF
  534.         ELSEIF NOT ChopOut THEN
  535.             IF NOT ChopOut THEN ProcessLine L$
  536.         END IF
  537.     ELSE
  538.         IF NOT ChopOut THEN PRINT #2,
  539.     END IF
  540. LOOP
  541. CLOSE                       ' close the files
  542.  
  543. LOCATE , 1
  544. PRINT "Complete!      "
  545. END
  546.  
  547. END SUB
  548.  
  549. SUB MsgSplit (Filename$, TheName$, OutN$, LPP, Reserve)
  550.  
  551. CLOSE : OPEN Filename$ FOR INPUT AS #1
  552.  
  553. Tab$ = CHR$(9)
  554. LinesOut = Reserve + 1
  555. FileOutNum = 1: OnMsgNumber = 1
  556. LPP = LPP - 4               ' lines per page
  557. LOFile& = LOF(1)
  558.  
  559. Base$ = LEFT$(OutN$, 6)
  560.  
  561. COLOR 7, 0: PRINT
  562. DO
  563.     OutN$ = Base$ + Num2Str$(FileOutNum)
  564.  
  565.     IF Row THEN LOCATE Row, Col: PRINT "         "
  566.     PRINT "Now writing: "; OutN$; ".PI ";
  567.     Row = CSRLIN: Col = POS(0)
  568.  
  569.     OPEN OutN$ + ".PI" FOR OUTPUT AS #2
  570.  
  571.     IF OnMsgNumber > 1 THEN
  572.         PRINT #2, "'>>> Start of page"; STR$(OnMsgNumber); "."
  573.         PRINT #2,
  574.     ELSE
  575.         GOSUB Snip
  576.         PRINT #2, "'This file created by PostIt! v6.1."
  577.         PRINT #2, "'>>> Start of page"; STR$(OnMsgNumber); "."
  578.         PRINT #2,
  579.     END IF
  580.  
  581.     TooLong = False
  582.     FOR Trans = LinesOut TO LPP
  583.         IF (Trans AND 3) = 0 THEN
  584.             Percent = (100& * SEEK(1)) \ LOFile&
  585.             Twirler$ = MID$(Proplr$, (Percent AND 3) + 1, 1)
  586.             LOCATE Row, Col: PRINT USING "! ###%"; Twirler$; Percent;
  587.         END IF
  588.  
  589.         IF NOT EOF(1) THEN
  590.             IF Trans = LinesOut THEN
  591.                 DO
  592.                     IF EOF(1) THEN
  593.                         CLOSE
  594.                         KILL OutN$ + ".PI"
  595.                         OutN$ = Base$ + Num2Str$(FileOutNum - 1)
  596.                         OPEN OutN$ + ".PI" FOR APPEND AS #2
  597.                         SEEK #2, LOF(2) - 26 - (FileOutNum > 9)
  598.                         GOSUB Snip
  599.                         CLOSE
  600.                         EXIT DO
  601.                     END IF
  602.                     LINE INPUT #1, Buf$
  603.                 LOOP WHILE LEN(Buf$) = 0
  604.                 IF LEN(Buf$) = 0 THEN EXIT DO
  605.             ELSE
  606.                 LINE INPUT #1, Buf$
  607.                 Buf$ = RTRIM$(Buf$)
  608.             END IF
  609.  
  610.             Tb = INSTR(Buf$, Tab$)  'remove chr$(8)s (tabs)
  611.             IF Tb THEN
  612.                 DO
  613.                     Temp = (Tb - 1) MOD TabStops
  614.                     IF Temp = 0 THEN Temp = TabStops
  615.                     Buf$ = LEFT$(Buf$, Tb - 1) + SPACE$(TabStops - Temp) + MID$(Buf$, Tb + 1)
  616.                     Tb = INSTR(Tb, Buf$, Tab$)
  617.                 LOOP WHILE Tb
  618.             END IF
  619.  
  620. Wrapping:
  621.             IF (LEN(Buf$) > LineLength) AND (LEFT$(Buf$, 1) <> "'") THEN
  622.                 Trans = Trans + 1
  623.                 CommentOn = False
  624.                 FOR a = LineLength TO 40 STEP -1
  625.                     IF MID$(Buf$, a, 1) = " " THEN
  626.                         WrapPoint = a
  627.                         EXIT FOR
  628.                     END IF
  629.                 NEXT
  630.                 IF WrapPoint = 0 THEN WrapPoint = LineLength
  631.  
  632.                 QuotesOn = False
  633.                 FOR a = 1 TO WrapPoint
  634.                     Temp$ = MID$(Buf$, a, 1)
  635.                     IF Temp$ = Qt$ THEN
  636.                         QuotesOn = NOT QuotesOn
  637.                     ELSEIF NOT QuotesOn THEN
  638.                         IF (Temp$ = "'") OR (UCASE$(MID$(Buf$, a, 4)) = "REM ") THEN
  639.                             CommentOn = True
  640.                             EXIT FOR
  641.                         END IF
  642.                     END IF
  643.  
  644.                 NEXT
  645.  
  646.                 Long$ = Buf$
  647.                 IF CommentOn THEN
  648.                     Buf$ = LEFT$(Buf$, WrapPoint - 1)
  649.                 ELSE
  650.                     IF QuotesOn THEN
  651.                         Buf$ = LEFT$(Buf$, WrapPoint - 1) + Qt$ + "+_"
  652.                     ELSE
  653.                         Buf$ = LEFT$(Buf$, WrapPoint - 1) + "_"
  654.                     END IF
  655.                 END IF
  656.  
  657.                 IF NOT ((Trans = LPP) AND LEN(Buf$) = 0) THEN
  658.                     PRINT #2, Buf$
  659.                 END IF
  660.  
  661.                 Buf$ = MID$(Long$, WrapPoint)
  662.                 IF CommentOn THEN Buf$ = "'" + Buf$
  663.                 IF QuotesOn THEN Buf$ = Qt$ + Buf$
  664.  
  665.                 GOTO Wrapping
  666.             END IF
  667.  
  668.             IF NOT ((Trans = LPP) AND LEN(Buf$) = 0) THEN
  669.                 PRINT #2, Buf$
  670.             END IF
  671.         END IF
  672.     NEXT
  673.     IF NOT EOF(1) THEN
  674.         PRINT #2,
  675.         PRINT #2, "'>>> Continued on page"; OnMsgNumber + 1
  676.  
  677.         OnMsgNumber = OnMsgNumber + 1
  678.         FileOutNum = FileOutNum + 1
  679.         LinesOut = 1
  680.     ELSE
  681.         PRINT #2,
  682.         GOSUB Snip
  683.         PRINT #2,
  684.     END IF
  685.  
  686.     CLOSE #2
  687. LOOP UNTIL EOF(1)
  688. CLOSE
  689.  
  690. LOCATE Row, Col
  691. PRINT "         "
  692. PRINT
  693. PRINT "Complete!"
  694. END
  695.  
  696. Snip:
  697.     PRINT #2, "'______O_/__________________| SNIP" + " |__________________\_O______"
  698.     PRINT #2, "'      O \                  | HERE |             " + "     / O"
  699. RETURN
  700.  
  701. END SUB
  702.  
  703. FUNCTION Num2Str$ (a)
  704.     Num2Str$ = MID$(STR$(a), 2)
  705. END FUNCTION
  706.  
  707. FUNCTION ParseFileName$
  708.  
  709. FOR S = LEN(SourceFile$) TO 1 STEP -1
  710.     IF INSTR("\:", MID$(SourceFile$, S, 1)) THEN EXIT FOR
  711. NEXT
  712. RealSource$ = MID$(SourceFile$, S + 1)
  713.  
  714. Ext = INSTR(RealSource$, ".")
  715. IF Ext <> 0 THEN
  716.     DestTemp$ = LEFT$(RealSource$, Ext - 1)
  717. ELSE
  718.     DestTemp$ = RealSource$
  719. END IF
  720.  
  721. ParseFileName = UCASE$(LEFT$(DestTemp$, 7))
  722.  
  723. END FUNCTION
  724.  
  725. SUB PrepareFile
  726.  
  727.  
  728. F$ = UCASE$(DestFile$ + Num2Str$(CurrentPage) + ".BAS")
  729. CheckSum = 0
  730.  
  731. COLOR 7: PRINT
  732. PRINT "Now writing: "; F$; " ";
  733. Row = CSRLIN: Col = POS(0)
  734.  
  735. OPEN F$ FOR OUTPUT AS #2 LEN = 8192     ' use 8K buffer
  736.  
  737. PRINT #2, "C";
  738. PRINT #2, "LS:?STRING$(50,178):DEFINT A-Z 'Created by PostIt!" + " 6.1"
  739. PRINT #2, "FOR A=0 TO 6:P(A)=2^A:NEXT:OPEN "; Qt$; "B"; Qt$; ",1,"; Qt$; RealSource$
  740. PRINT #2, "T$="; Qt$; "abcdefghijklmnopqrstuvwxyz"; Qt$; ":T$=T$+UCASE$(T$)+"; Qt$; "0123456789#$"
  741.  
  742. Prefix$ = "G" + Qt$
  743. Work$ = Prefix$
  744.  
  745. END SUB
  746.  
  747. SUB PrintDecoder
  748.  
  749. PrintLine "N=" + Num2Str$(FileLength) + ":K=255:IF LEN(C$)<>" + Num2Str$(BytesOut) + " THEN ?" + Qt$ + "Bad script!" + Qt$ + ":END"
  750. PrintLine "FOR A=1 TO N:LOCATE 1:?STRING$(50/N*A,177):IF L=0" + " THEN GOSUB G:L=6"
  751. PrintLine "W=T\P(6-L):GOSUB G:W=W OR T*P(L):L=L-2:B$=CHR$(W AND" + " K):PUT 1,,B$:NEXT"
  752. PrintLine "?:IF C=" + Num2Str$(CheckSum) + " THEN ?" + Qt$ + "Ok" + Qt$ + ":END ELSE ?" + Qt$ + "Bad checksum!" + Qt$ + ":END"
  753. PrintLine "G:I=I+1:T=INSTR(T$,MID$(C$,I,1))-1:C=(C+T)*2:C=C" + "\256+(C AND 255):RETURN"
  754. PrintLine "SUB G(A$):SHARED C$:FOR Q=2 TO" + " 9:DO:S=INSTR(A$,CHR$(Q+38))"
  755. PrintLine "IF S THEN A$=LEFT$(A$,S-1)+STRING$(Q,97)+MID$(A$,S+1)"
  756. PrintLine "LOOP WHILE S:NEXT:C$=C$+A$:END SUB"
  757. CLOSE
  758.  
  759. END SUB
  760.  
  761. 'Outputs one line to the output file, and opens another output file
  762. 'if the page length is exceeded.
  763. SUB PrintLine (a$)
  764. STATIC NewFileFlag
  765.  
  766. IF NewFileFlag THEN
  767.     LOCATE Row, Col: PRINT "          "
  768.  
  769.     NewFileFlag = False
  770.     CurrentPage = CurrentPage + 1
  771.     B$ = Num2Str$(CurrentPage)
  772.     PRINT #2, "'>> Continued on pg. "; B$
  773.     CLOSE #2
  774.  
  775.     F$ = UCASE$(DestFile$ + B$ + ".BAS")
  776.  
  777.     PRINT "Now writing: "; F$; " ";
  778.     Row = CSRLIN: Col = POS(0)
  779.  
  780.     OPEN F$ FOR OUTPUT AS #2 LEN = 8192
  781.  
  782.     PRINT #2, "'>> Start: pg. "; B$
  783.     LinesOut = 1
  784. END IF
  785.  
  786. PRINT #2, a$
  787.  
  788. TotalLinesOut = TotalLinesOut + 1
  789. LinesOut = LinesOut + 1
  790. IF LinesOut >= PageLength THEN NewFileFlag = True
  791.  
  792. END SUB
  793.  
  794. SUB ProcessLine (In$) STATIC   ' belongs to MrFilter
  795.  
  796. CONST Blank = " ", Plus = "+"
  797.  
  798.     IF Shave THEN
  799.         In$ = MID$(In$, 2)
  800.         Shave = False
  801.     END IF
  802.  
  803.  
  804.     In$ = Previous$ + In$
  805.     Previous$ = ""
  806.     IF ASC(RIGHT$(In$, 1)) = 95 THEN
  807.         IF LEN(In$) > 2 THEN
  808.             SELECT CASE LEFT$(RIGHT$(In$, 2), 1)
  809.                 CASE Blank
  810.                 CASE Plus
  811.                     Previous$ = LEFT$(In$, LEN(In$) - 3)
  812.                     Shave = True
  813.                 CASE ELSE
  814.                     Previous$ = LEFT$(In$, LEN(In$) - 1)
  815.             END SELECT
  816.         END IF
  817.     END IF
  818.  
  819.     IF LEN(Previous$) = 0 THEN
  820.         PRINT #2, In$
  821.     END IF
  822.  
  823.     LOCATE , 12
  824.     PRINT MID$(Proplr$, Flip + 1, 1);
  825.     Flip = (Flip + 1) AND 3
  826.  
  827. END SUB
  828.  
  829. 'Adds a character to the output string.
  830. SUB PutByte (a)
  831.     SHARED Good$
  832.  
  833. IF CurrentBit < 0 THEN LastOne = True
  834.  
  835. BytesOut = BytesOut + 1
  836.  
  837.     'calculate a checksum on the encoded data stream
  838. CheckSum = (CheckSum + a) * 2
  839. CheckSum = CheckSum \ 256 + (CheckSum AND 255)
  840.  
  841. IF (a = 0) AND (LastOne = False) THEN
  842.     IF aLength = 9 THEN
  843.         aLength = 1
  844.         Work$ = Work$ + "/"
  845.     ELSE
  846.         aLength = aLength + 1
  847.     END IF
  848. ELSE
  849.     SELECT CASE aLength
  850.     CASE 0
  851.         'translate the output character into something safe
  852.         Work$ = Work$ + MID$(Good$, a + 1, 1)
  853.     CASE 1
  854.         Work$ = Work$ + "a" + MID$(Good$, a + 1, 1)
  855.         aLength = 0
  856.     CASE ELSE
  857.         Work$ = Work$ + MID$(ComprChar$, aLength - 1, 1) + MID$(Good$, a + 1, 1)
  858.         aLength = 0
  859.    END SELECT
  860. END IF
  861.  
  862. IF LEN(Work$) >= LineLength THEN
  863.     IF LEN(Work$) = LineLength THEN
  864.         PrintLine Work$
  865.         Work$ = Prefix$
  866.     ELSE
  867.         PrintLine LEFT$(Work$, LineLength)
  868.         Work$ = Prefix$ + MID$(Work$, LineLength + 1)
  869.     END IF
  870. END IF
  871.  
  872. END SUB
  873.  
  874. SUB PutBytes (a)
  875.  
  876.     'shift the 8 bit character into the work buffer
  877. Char = Char + a * Shift(CurrentBit)
  878.  
  879.     'we've got 8 more bits now
  880. CurrentBit = CurrentBit + 8
  881.  
  882.     'write the 6 bit codes now
  883. DO WHILE CurrentBit > 5          'have at least 6 bits left?
  884.     PutByte Char AND 63          'write out the first 6 bits
  885.     Char = Char \ 64             'shift it right 6 places
  886.     CurrentBit = CurrentBit - 6  '6 bits less now
  887. LOOP
  888.  
  889.  
  890. END SUB
  891.  
  892. SUB ShortCopyright
  893.  
  894. COLOR 15, 0
  895. CLS
  896.  
  897. PRINT "╔═══════════════════════════════════════════════════════╗"
  898. PRINT "║   PostIt! 6.1   THE Binary <-> BASIC Script Creator   ║"
  899. PRINT "╟───────────────────────────────────────────────────────╢"
  900. PRINT "║      Rich Geldreich, Jim Giordano, Mark H Butler,     ║"
  901. PRINT "║   Quinn Tyler Jackson, Scott Wunsch, and Victor Yiu.  ║"
  902. PRINT "╚═══════════════════════════════════════════════════════╝"
  903. PRINT
  904. COLOR 12
  905. PRINT "PostIt! 6.1 can:"
  906. COLOR 13
  907. PRINT "  o  Encode binary files as text"
  908. PRINT "  o  Split messages and wrap lines"
  909. PRINT "  o  Extract binary scripts"
  910. PRINT "  o  Filter split messages to original state"
  911. PRINT
  912.  
  913. END SUB
  914.  
  915. SUB Twirl STATIC
  916.  
  917. LOCATE Row, Col
  918. PRINT MID$(Proplr$, Turn + 1, 1);
  919. Turn = (Turn + 1) AND 3
  920.  
  921. IF Turn = 0 THEN
  922.     PRINT USING " ###%"; 100& * CurrentByte \ FileLength;
  923. END IF
  924.  
  925. END SUB
  926.  
  927.