!* -*- Teco -*- Library created and maintained by KMP@MC ! !~Filename~:! !Macros for reading AP Newswire! APNEWS !& Setup APNEWS Library:! !S Just get us ready to go! 0FO..Q AP_..J"e :i*M.V AP_..J' 0FO..Q News_Reader_Name"e :i*M.V News_Reader_Name' 0 !& Setup Newswire:! !S This initializes the newswire buffer It takes a string arg saying what news wire to use. The string should be the second filename to look for (eg, AP or NYT). The macro will know the rest of info on canonical place to find stuff.! :i*[5 f[dfile !* Bind Teco default filename ! f[sstring !* Bind the search string ! [Previous_Buffer !* Bind the last buffer seen ! QBuffer_Name[4 !* Save Current Buffer Name in q4 ! FN M(M.MSelect_Buffer)4 !* Make sure we get back here when done! [0[1[2[4 !* Scratch qregisters ! 1,(:i* *5* )m(m.m &_Find_Buffer)+1"n 0FO..Q 5_News_Flag"e oAlready-In-Use' m(m.m Select_Buffer)*5* J' "# m(m.m Select_Buffer)*5* 1:< er DSK:COMMON;_NEWS_ _ 5@y >"n oNo-File' 1 M.V 5_News_Flag q5 m(m.m &_AP_Setup_Buffer_for_reading) J q5 m(m.m &_AP_Mark_Stories) et .TEMP.; DSK: *5* _ OUTPUT fsdfile UBuffer_Filenames 0fs modified' !* Mark ^_ between each story ! 1M.V AP_Current_Pos 0 !Already-In-Use! 0fo..q5_News_Flag"e :i* C  [Buffer_"*5*"_is_already_in_use] fs echo display out !''!' "# :i*Unknown_Errorfo..qAP_Error_Message[0 !"! :i* C  [Can't_hack_5_Summary:_0] fs echo display out' 1M.V 5_News_Flag 0fs echo activew -1 !No-File! :i*News_File_Unavailable M.V AP_Error_Message :i* C  [Unable_to_Get_News_File]fs echo display out 1M.V 5_News_Flag 0fs echo activew -1 !Format-Error! :i*News_File_Undecipherable M.V AP_Error_Message :i* C  [Unable_to_decipher_newswire_format]fs echo display out 1M.V 5_News_Flag 0fs echo activew -1 !& AP Mark Stories:! !S Put ^_ before each story. Between the angle brackets after the ^_ is the story number ! :I*[5 FN1J !* Jump to top when done ! [0[1[2[3[4 m.m ^R_Delete_Horizontal_Spaceu0 !* Macro to kill horizontal space! j <:l .-z; m0w l> j <:s(MORE) MORE ; fkd m0 > m.m ^R_Back_To_Indentationu0 j <.-Z; M0 fsshpos-5"g !* If long indent ! 0l -1,0a-10"e 15.i 12.i'' !* And no LF preceding, insert CRLF ! l > !* Loop! m.m Uppercase?u1 j !* Loop! j s r 0,.k 15.i 12.i 2r 1u0 m.m ^R_Delete_Horizontal_Spaceu3 m.m &_Just_One_CRu4 < 0l i< q0\ i> 15.i 12.i :s; 0l .u1 !* Save this point ! 1:<2fwl>"n 0;' q1j !* Make sure line isn't the last ! :l .u2 q1,.:FB:"l !* Look for colon in the line (header?)! l -1,2a-15."e !* If a lone line, assume a header ! q1,q2 fx1 !* Move line into q1 ! -s< s> !* Search for our header ! i1 fkc !* Insert the header ! @m3 i_ s: @m3 i_ :l m4 !* Add a CR ! 2c 0l .u1'' !* Jump past it! "# q1j :s; r fsshpos-5"g !* Lots of indent? ! 0l @m3 .u1 :l q1,.fx1 -s< s> i_1 :l m4 2c .u1'' q1j !More-Header! :s; r fsshpos-5"g l o More-Header' l -1,2a-15."e o More-Header' "# -l' M(m.m Uppercase?)"e l oMore-Header' !Loop! m(m.m &_Find_End_of_Block); :s; 0l !* Find next story ! 1:"n 0;' fkc fsinslength f~With"e o Loop' %0> q0 M.V AP_Z_Arg_Value  !& Read News:! !S Read News according to XJname ! fsxjname:f6[1 m(m.m Read_News_Summary)1  !AP News:! !& AP News:! !^R AP News:! !S Read the AP Newswire! m(m.m Read_News_Summary)AP  !NYT News:! !& NYT News:! !^R NYT News:! !S Read the New York Times summary! m(m.m Read_News_Summary)NYT  !Read News Summary:! !S Driver Program! :i*[9 m(m.m &_Setup_Newswire)9"n 0' :i* C  fs echo display out q9_Date[1 !* Make q1 a temp reg for date ! fsrgetty"n @'ft 1_9_Newswire_Summary._Type_"?"_for_help. Type_a_Space_to_see_the_first_message. !''! ]1 !* Pop q1 ! 15: !* Pause so display doesnt kill VT52s ! q9_..J[..J !* Make us a special ..J ! [AP_..J !* Just use q$AP ..J$ as a local name ! :I*9[News_Reader_Name !* Make name for current news reader ! :iAP_..J..J !* Copy q..J into q$AP ..J$ ! :i*[ MM_&_Set_Mode_Line !* Put the null string in & Set Mode Line! F[SSTRING !* Bind the search string ! F[DFILE !* Bind the default file ! [Previous_Buffer !* Bind the last buffer seen ! 0F[^R MORE !* --More-- type processing ! QBuffer_Name[4 !* Save Current Buffer Name in q4 ! FN M(M.MSelect_Buffer)4[4 !* Make sure we get back here when done! M(M.M Select_Buffer)*9* !* Get into the *AP* Buffer ! 0fsvbw 0fsvz !* Widen buffer just in case ! J M(M.M &_AP_Initial_Display) !* Show the initial page ! FS^R MODE"N :M(M.M&_AP_News_Options)' FS^R ENTER[1 !* Bind FS^R Enter into q1 ! :I* Q1 F[^R_ENTER !* Put FS^R Enter in effect after our ^R! M(M.M &_AP_News_Options) !* Run the options ! FS^R EXIT !* Run FS ^R Exit !  F[^R ENTER !* Put all this on FS^R Enter !  !* Get an ^R !  !& AP Initial Display:! !S Do initial display! fsrgetty"e qAP_..J[0 ft0 ' 0f[vbw fsz f[vzw @v 40.fsreread w f]vzw f]vb jl m(m.m #_AP_S)  !& AP Display Current:! !S Show this message ! M(M.M &_AP_Narrow_Bounds) M(M.M &_AP_Set_Global_Topic) fr fsrgetty"n 0u..h @V'  !& AP Set Global Topic:! !S Set up a global topic if any ! [0[1 u0 fq0-3"l qAP_..J U..J 0' fswidth-fqAP_..J-10u1 fq0-q1"g 0,(q1-3):g0 u0 q1-4:g0-."n :i*0...'"#q0'' "# q0' u0 QAP_..J[1 :i..J1_0 0 !& AP Narrow Bounds:! !S Narrow Buffer Bounds to only current story! [0 0fsvbw 0fsvz !* Make buffer fully widened. ! -:s:"l !* Search back for the ^_ ! :i*IBS Illegal_Buffer_State_in_Buffer_*AP* fs err' c 1:x0 !* Copy this line into q0 ! fsrgetty"n !* On paper, put in buffer ! !' !* Else omit it ! .-b fsvb !* Make buffer beginning be here! :s"l !* Search for trailing ^_ if any ! r z-. fsvz' !* Make that our buffer end if it is found! "# 0fsvz' !* Else use real buffer end ! fq0-1:g0->"e !* If q0 ends in a greater-than sign! j l s r :i00_ 1:@x0 zj' !* Add some text to q0! j !* Jump to top of buffer ! q0  !* Return q0 for mode line ... ! !& AP News Options:! !S Get the commands and do them! [.G 33. FS^R INIT U.G !* Bind ^G to Teco default ! 0[00[10[2 :i*[30[50[6 !* Regs 0-6 ! [..J -1 F[NOQUIT FU0 Q0-@FE QIT"E!' q0:@FG 0fsvbw 0fsvz QAP_Current_PosJ M(M.M &_AP_Display_Current) >U0 -1"N ' !* If not a toplevel job, return to Emacs! q0-1"e 400000.'+100000. fs exit' !& AP Make Macro Name:! !S Get name of AP Macro associated with this char ! [0[1 q0:i1 !* Insert q0 as char in q1 ! Q0-33"L !* If char is Space or less ! Q0+100.U1 :I1^ 1' !* Make q1 uparrow and char+100octal ! Q0-127"E :I1^?' !* If char is rubout, make q1 uparrow ? ! :i*#_AP_1  !& Just One CRLF:! !S Delete surrounding CRs or LFs, leaving one CRLF ! .[0 .[1 !* q0,q1 are region affected ! !* If CR or LF precedes, rub it out and loop ! < b-.; ((0a-13)*(0a-10))"e -d (q0-1)u0' "# 0;'> !* If CR or LF follows, rub it out and loop ! < .-z; ((1a-13)*(1a-10))"e d %1' "# 0;'> !* Insert the CRLF and come back! I 2r q0,q1  !* Return region affected ! !& Find Start of Block:! !S Skip to top of next textual block A top of block is a non-null line. Returns -number of characters from end of file. (Thus, 0 = Eof) ! !* Search for a non-null line or move to eof if none found, return -1 ! :s î _î:"l zj' "# r' .-z  !& Find End Of Block:! !S Skip to end of next textual block An end of block for this macro is defined as being either the next sequence of two contiguous carriage returns following text or else end of file after text. Returns -number of chars from end of file. (Thus, 0 = Eof) ! !* Search for double carriage return to signify block break. ! !* Use eof if none found ... ! :s   _ :"l zj' "# 2r' .-z  0 !# AP M:! !S Mail current story to a user! [1 hx1 !* Copy message into q1 ! q1 M(M.M &_AP_M_Aux) !* Run aux routine ! M(M.M &_AP_Display_Current) !* Display current message !  !* Return ! !& AP M Aux:! !S Needed to help out the AP M command! f[bbind !* Get a scrap buffer ! [1 !* Get a scrap q-reg ! u1 !* Fill q1 with text ! g1 !* Re-insert message into buffer ! j iTo: !* Insert a TO: label ! fs xunamef6 !* Insert XUname into buffer ! qNews_Reader_Name[1 i Subject:In_the_1_news,_ !* Subject line ! g1_Date !* Get newswire date ! ]1 i --Text_follows_this_line--  !* Terminate header field ! gAP_..J !* Get base mode line into buffer ! i  !* Keep things from looking messy ! 3j !* Jump to name, in case user wants to ! !* alter it ! 1f !* End of catch frame !  !^R News Mail ^G:! !^R Exit from News Mail command without sending! f;Mail-Exit !# AP >:! !S Move to next screenful! F@M(M.M ^R_Next_Screen) @V  !# AP <:! !S Move to previous screenful! F@M(M.M ^R_Previous_Screen) @V  !# AP ^L:! !S Don't do anything. Just let redisplay happen ! M(M.M &_AP_Display_Current) !# AP Q:! !S Exit AP News! 0U..H F;AP-Catch !# AP N:! !S Move to next story! [0 FF"n u0' "# 1u0' q0"l -q0:M(M.M #_AP_P)' 0fsvbw 0fsvz q0:s:"l l .UAP_Current_Pos M(M.M &_AP_Display_Current) :i* C [Stopped_at_End_of_File] fs echo display out :fi :i* C  fs echo display out' "# l .UAP_Current_Pos M(M.M &_AP_Display_Current)' !# AP P:! !S Move to next story! [0 FF"n u0' "# 1u0' q0"l -q0:M(M.M #_AP_N)' 0fsvbw 0fsvz -q0:s:"l .-b"e l' .uAP_Current_Pos M(M.M &_AP_Display_Current) :i* C [Stopped_at_Head_of_File] fs echo display out :fi :i* C  fs echo display out' "# .-b"e l' .uAP_Current_Pos M(M.M &_AP_Display_Current)' !# AP ?:! !S Help! -1fsreread :FTNews_Digest_Reader  Cmnd:_______Description:  B___________Move_to_and_Briefly_Describe_Current_(or_Nth)_Story J___________Jump_to_First_(or_Nth)_Message M___________Mail_Current_Story_(using_EMACS_^R_mode) N___________Move_to_(Nth)_Next_Story P___________Move_to_(Nth)_Previous_Story Q___________Quit S___________Summarize_All_Stories T___________Display_Story_(for_printing_terminals) <_or_>______Move_to_Previous_or_Next_Page_of_Long_Story __________Return_to_Superior _or_._____Redisplay_current_story _____Move_to_Next_Story_(+_Brief_on_Printing_Terminal) _____Part_of_arg_to_next_command ____Flushes_any_pending_arg ___Runs_a_minibuffer ?_or_[Help]_Types_this_info   fi[1 q1-_"e fsrgetty"eTu1' "# 14.u1'' q1fsreread w  !# AP J:! !S Jump to random story! 0fsvbw0fsvz ff"e :i01' "# :\[0' J :s<0>"l m(m.m &_AP_Display_Current)' "# :i*NSS No_Such_Story fs err'  !# AP ^Q:! !S Ignore this command - VT52s are prone to send these accidentally! :i* C  fs echo display out 0 !# AP ^S:! !S Ignore this command - VT52s are prone to send these accidentally! :i* C  fs echo display out 0 !# AP 0:! !S Argument to next command ! :I5500 !# AP 1:! !S Argument to next command ! :I5500 !# AP 2:! !S Argument to next command ! :I5500 !# AP 3:! !S Argument to next command ! :I5500 !# AP 4:! !S Argument to next command ! :I5500 !# AP 5:! !S Argument to next command ! :I5500 !# AP 6:! !S Argument to next command ! :I5500 !# AP 7:! !S Argument to next command ! :I5500 !# AP 8:! !S Argument to next command ! :I5500 !# AP 9:! !S Argument to next command ! :I5500 !# AP +:! !S Argument to next command ! :I5500 !# AP -:! !S Argument to next command ! :I5500 !# AP /:! !S Argument to next command ! :I5500 !# AP *:! !S Argument to next command ! :I5500 !# AP (:! !S Argument to next command ! :I5500 !# AP ):! !S Argument to next command ! :I5500 !# AP =:! !S Argument to next command ! :I5500 !# AP Z:! !S Argument to next command - number of messages in buffer ! qAP_Z_Arg_Value:\[1 :i5510 !# AP ^[:! !S (Altmode) Run a minibuffer ! @M(M.M ^R_Execute_Minibuffer) M(M.M &_AP_Display_Current)  !# AP ^M:! !S Flush argument to next command! :i5 :i* C fs echo display out 0fs echo active !# AP ^J:! !S Flush argument to next command! :i5 :i* C fs echo display out 0fs echo active !# AP ^?:! !S Flush argument to next command! :i5 :i* C fs echo display out 0fs echo active !# AP T:! !S Print if on a printing tty! FF"e ht ' 0fsvbw 0fsvz j :s .uAP_Current_Pos M(M.M &_AP_Narrow_Bounds) M(M.M &_AP_Set_Global_Topic) ht  !& AP Brief:! !S Brief about the current story! -1,1a-32"e t' "# :l s 0tt' !# AP B:! !S Brief about the Nth stories! FF"e j fsrgetty"e !' M(M.M &_AP_Brief) ' 0fsvb 0fsvz F[0 q0"l ft  -q0u0' j q0:s:"l :i*NSS No_Such_Storyfs err' .uAP_Current_Pos M(M.M &_AP_Narrow_Bounds) M(M.M &_AP_Set_Global_Topic) j M(M.M &_AP_Brief)  !# AP S:! !S Summarize all stories! -1fsreread 0f[vb 0f[vz .f([9)uAP_Current_Pos 0j .[1 :ftSummary_of_Latest_News...   < :s; .u1 ! q1,.t M(M.M &_AP_Brief) q1j > q9j ]1 ]9w f]vzw f]vb M(M.M &_AP_Narrow_Bounds) M(M.M &_AP_Set_Global_Topic) fi[1 q1-_"e fsrgetty"eTu1' "# 14.u1'' q1fsreread w  !# AP .:! !S Display current message! M(M.M &_AP_Display_Current) !# AP ^C:! !S Return to Superior! 100000.fsexit M(M.M &_AP_Display_Current) !# AP ^`:! !S Move to next and brief ! 0fsvbw 0fsvz :s"l .UAP_Current_Pos M(M.M &_AP_Narrow_Bounds) M(M.M &_AP_Set_Global_Topic) J fsrgetty"n m(m.m &_AP_Display_Current)' "# M(M.M &_AP_Brief)'' "# .UAP_Current_Pos M(M.M &_AP_Narrow_Bounds) M(M.M &_AP_Set_Global_Topic) :i* C [End_of_File] fs echo display out :fi :i* C  fs echo display out' !& AP Setup buffer for Reading:! !S Parse the buffer into readable form.! [0 1f[bothcase !* Ignore CASE ! [1[2[3 m(m.m &_AP_Find_AM/PM)u1 !* Put AM/PM in q1 ! m(m.m &_AP_Find_DOW)u2 !* Snarf day of week if possible into q2! m(m.m &_AP_Find_Date)u3 !* Put Date in q3 ! m(m.m &_AP_Find_and_Flush_header) !* Flush mail header ! q3 M.V 0_Date !* Save date in a variable ! :i*[0_News_Digest:_21] M.V 0_..J !& AP Find AM/PM:! !S Return a string like Morning or Evening describing time! j :sAM-NewsAM_NewsA.M._NewsA.M.-NewsDAY_AMs"l :i*_Morning ' j :sPM-NewsPM_NewsP.M._NewsP.M.-NewsDAY_PMs"l :i*_Evening ' :i* ' !& AP Find Date:! !S Find the date if any on the news wire.! [1 j :s Date:_"l !* Search for Date (in mail header) ! <:s Date:_;> !* In case of included messages,repeat! 2fwfx1 q1' !* Return next two words ! j :sJanFebMarAprMayJunJulAugSepOctNovDec"l !* If not found ! r -fwfx1 !* Kill next word (Month) into q1 ! .[2 !* Save point just in case ! -fwl !* Skip back over what is hopeful day! 1a:"d q2j g1 o Date-Unknown' !* If not a digit we lose - leave it be ! i_ r -@fwfx1 !* Append space + day to month ! q1 ' !* Return value accumulated ! !Date-Unknown! :i*Undated !& AP Find DOW:! !S Search for Day of week and return it if found! j :sDAY_s"l fkc -fwl [1 fwx1 q1 ' j :sSummary_for_"l [1 fwx1 f~1Sunday"e q1' f~1Monday"e q1' f~1Tuesday"e q1' f~1Wednesday"e q1' f~1Thursday"e q1' f~1Friday"e q1' f~1Saturday"e q1'' :i*Undated  !& AP Find and Flush Header:! !S Search for intro paragraph and flush it.! j <:s; -d> !* Delete stray ^_s ! [0 j <:s*****XXXXX; !* Search for *** trailer ! -l .u0 :s ___"l 0l q0,.k 15.i 12.i' !* Find more text? Kill in between, loop ! "# q0,z kw 0;' !* Else kill rest of buffer and exit! > ]0 j :sdesk_supervisor(212)__here_arestories"l !* Find paragraph 1 ! oReady' :sDAY_s"l !* Or Search for DAY s ! 3l oReady' :sAP_NEWS_DIGEST"l !* Or Search for AP NEWS DIGEST ! 5l oReady' !* Or Search for the C. 19... copyright notice ! :s c.19 c._19"l 2l 0,.k ' :s: "l .-250"l !* Find a : close to head of buffer ! 0,.k ' "# j'' s _ _   0,.k  !Ready! 1 m(m.m ^R_Forward_Paragraph) l b,.k  !Uppercase?:! !S Return 0 if at begging of an all-caps word! [1 -1,1a"b -1' <-1,1au1 q1"b 0;' q1"d 2' q1-140."g 1' c > 0 !& Previous Terminated:! !S Previous line had a sentence termination! .:\[0 fn 0j  !* Return to point when done ! 0l ."e -2' !* If head of buffer, return no! -l m(m.m^R_Back_to_Indentation) !* Go back and out past indent ! -1,1a-î"e 2' !* Return no if blank line before ! 1:"n -3' !* If no word to skip, return yes ! .u0 !* Save this point ! :l -1,0a-."e 0' !* If ends in period, then return yes ! !"! -1,0a-'"e 0' !* Single quote is ok here too ! :l 1:<-fwl> !* Jump to end of line and skip back ! .-q0"g 1' !* More than one word on line, return no ! 0 !* Return yes ! !& Mail Buffer:! !S Mail message as specified by buffer contents. Buffer should contain header information followed by a line containing "--Text follows this line--", followed by the text. Header info is as described in .MAIL.;MAILRQ INFO except that To: allows several recipients separated by commas, and Cc: is allowed. Also, use From: to say who you are.! Q..O[1 F[B BIND G1 !* Make copy of buffer to do munging in, so "C" after! J 1F[Bothcase:S !* sending finds the message as user set it up.! --Text_follows_this_line--"L @F_ L 1A-15."E O Win'' :I*No_text,_just_header FS ERR !Win! [2 [3 0[4 [5 !* Q4 counts number of recipients.! 0L FSZ-.F[VZ !* Narrow bounds to just the header info.! J < .-Z; !* look at each line of header! 1af_ +1"g l !' !* line ok if it begins with whitespace! :fb:"l r -@f_ k !* remove whitespace before colon if any! 0@fc l !' !* convert item name to upper case! 1A-15."E L !' !* If no colon on line, but not empty, it's garbage.! :I*Garbage_in_message_header FS ERR > !* (Maybe user typed the text above the -----)! !* the mailer won't accept lower.! J I  J < L .-Z; :FB CC:  TO:  BCC:+4"E !' !* Find the next CC, BCC or TO line.! -D :I2 0FF~TO"N 0X2 !* Q2 gets null string for To,! :I2_(R-OPTION_2)' !* or (R-OPTION CC) for CC.! 0K <:FB@_; -D> 0L !* Flush any spaces after @'s.! < @f_ k !* Flush whitespace before name.! S,  FKD FKU3 !* Q3 has -1 for comma, -2 for CRLF.! 0,1af_ +1"g -1u3' !* unless next line is continuation! 0F"E -2-Q3; !' !* If null name, ignore, or exit if ended by CR.! .-ZU5 0L ITO: 1A-("E Q5+ZJ' !* Put TO: before name. If doesn't start with "("! "# I( 1AF"[!'!"L !* Put quotes around things with whitespace inside.! .,Q5+Z:FB_"L 0L4CI" Q5+ZJ .,(0l.(q5+zj)):FB@W I" !''!'' Q5+ZJ I)' !* Then put a pair of parens around it.! %4 !* Indicate that we have seen at least one recipient.! I  FQ2"N -S) G2 L' !* If it's a CC, stick (R-OPTION CC) before final ")".! :0L 0A-)"N I_) -2S) F_' L !* Move any @Site inside the trailing closeparen.! -2-Q3; > :0L > Q4"E :I*No_Recipients FS ERR' !* Message is illegal if not mailed to anybody.! J :S FROM:"E I CLAIMED-FROM: FS XUNAMEF6 I !* If no FROM, stick our UNAME in! ' "#  CLAIMED-FROM:' J :S H:"L  HEADER-FORCE: @ FC' !* Convert line following H: to U.C.! J :S S:"L  SUBJECT:' J :S R:"L  REGISTERED: @FC' j 2f= "e 2d' J IFROM-JOB: FS XJNAMEF6 I SENT-BY: FS UNAMEF6 I  ZJ ITEXT;-1  F] VZ K F[D FILE ET DSK:.MAIL.;MAIL_> FS MACHINE-(F6DM)"E ET AI:' E\ FN E^ EIHPEF