@q @program asys-docs 1 99999 d i ( asys-Docs v1.2 Jessy @ FurryMUCK 3/97, 2/99 asys-docs runs the Argo +man command, is a soft-coded, player- extensible documentation system with search capablities and an integral list editor. It is essentially the same program as DocTools.muf, with modifications for inclusion in the Argo system. INTSTALLATION: asys-docs uses the standard Argo installation method. Install lib-Argo. Port asys-Docs and set it W. Type 'install asys-docs'. asys-Docs requires lib-lmgr, lib-edit, lib-editor, lib-strings, lib- reflist and a .tell macro -- all of which should be installed on any established MUCK -- and lib-Argo. USE: +man...................Show contents or introductory text +man #contents.........List titles of available documents +man #search...........Bring up search-string prompt. Program will search main manual and supplement. Search strings can also be entered on the command line, with syntax ' #search ' +man #browse...........Same as #search, but displays full documents rather than titles. ' #browse *' would scroll through all documents +man #edit.............Edit main manual The #edit argument brings up a menu of options for adding, editing, or deleting documents, aliases, keywords, or the default screen. Documents are stored as lists on the Argo library. Aliases are alternate titles by which users may call up documents. Keywords are words that will be matched in searches, but do not have to appear in the text of the document. Typing the command with no arguments will display the default doc- ument if it is present. Otherwise, the titles of all available doc- uments are shown. Full #argument strings are not necessary: simply type enough to distinguish between arguments. You may speak, pose, and page while at a prompt line. asys-Docs may be freely ported. Please comment any changes. ) $include $lib/lmgr $include $lib/edit $include $lib/editor $include $lib/strings $include $lib/reflist $include $lib/argo $def thisVersion "1.2" $define Tell me @ owner swap notify $enddef $define Line me @ " " notify $enddef $define ClearButOne begin depth 1 <= not while pop repeat $enddef lvar ourString (* workspace var *) lvar ourCounter (* misc counter var *) lvar ourDataObj (* dbref: object holding system-wide data *) lvar ourBoolean (* misc control flow var *) lvar ourCom (* string: 'official' name of command *) lvar setSup? (* boolean: true if working with supplements *) : DoInstall ( -- ) (* install program into Argo system *) caller program? not if (* confirm installation method *) ">> Programs must be installed via the " "+install" GetCommandName strcat " command." strcat Tell exit then prog "@a/version" getpropstr if (* confirm re-install *) ">> Reinstalling..." Tell else ">> Installing..." Tell then (* record 'official' name of prog; remove old links *) RecOldActions prog "@a/name" "asys-docs" setprop #0 "+man" newexit dup ourString ! (* create command *) prog setlink prog "@a/version" thisVersion setprop (* set version *) ourString @ "@a/version" thisVersion setprop #0 "@a/comm_list/+man" ourString @ setprop (* register command *) #0 "@a/prog_list/" prog name strcat prog setprop ourString @ "@a/name" "+man" setprop ">> Installed." Tell ; : DoUninstall (* uninstall program from Argo *) prog "@a/name" getpropstr if #0 "@a/prog_list/" prog "@a/name" getpropstr strcat getprop not if ">> " prog name strcat " is not currently installed." strcat Tell pid kill then else ">> " prog name strcat " is not currently installed." strcat Tell pid kill then ">> Please confirm: You wish to uninstall " prog name strcat "?" strcat Tell ReadYesNo not if ">> Aborted." Tell pid kill Then background "@a/comm_list/+man" RemoveCommand #0 "@a/prog_list/" prog "@a/name" getpropstr strcat remove_prop RecOldActions #0 "@a/prog_list/" prog "@a/name" getpropstr strcat remove_prop ">> Uninstalled." Tell ; : DoHelp ( -- ) (* switch all players' souls into different bodies randomly *) Line "asys-Docs \(#" prog intostr strcat "\)" strcat Tell Line " " command @ strcat " ............................" strcat 31 strcut pop "Show contents, or intro text if provided" strcat Tell " " command @ strcat " ....." strcat 31 strcut pop "Show document for " strcat Tell " " command @ strcat " #contents...................." strcat 31 strcut pop "List all documents" strcat Tell " " command @ strcat " #search ............." strcat 31 strcut pop "List documents containing " strcat Tell " " command @ strcat " #browse ............." strcat 31 strcut pop "Display documents containing " strcat Tell " " command @ strcat " #edit........................" strcat 31 strcut pop "Add, edit, or delete documents (staff)" strcat Tell Line "Arguments do not have to be typed completely: '" command @ " #search time' and '" command @ " #s time' are equivalent." strcat strcat strcat strcat Tell ; : InsertControls ( s -- s' ) (* replace chars that would confuse directory system or allow setting wizprops with harmless strings *) dup "/" instr if "=$sl$=" "/" subst then dup ":" instr if "=$co$=" ":" subst then dup "*" instr if "=$a$=" "*" subst then dup "." instr if "=$p$=" "." subst then dup "@" instr if "=$at$=" "@" subst then dup "~" instr if "=$t$=" "~" subst then ; : RemoveControls ( s -- s' ) (* remove control chars from s *) dup "=$sl$=" instr if "/" "=$sl$=" subst then dup "=$co$=" instr if ":" "=$co$=" subst then dup "=$a$=" instr if "*" "=$a$=" subst then dup "=$p$=" instr if "." "=$p$=" subst then dup "=$at$=" instr if "@" "=$at$=" subst then dup "=$t$=" instr if "~" "=$t$=" subst then ; : DoFormatMatch ( s i -- s i ) (* format matched doc title; tell if match fills third column *) over RemoveControls "" "@a/docs/" subst dup strlen 1 - strcut pop " " strcat 24 strcut pop strcat depth pick 1 + depth 1 - put depth pick 3 % not if Tell "" then ; : DoEditList ( s -- s i )(* edit a doc list on library; return list name and 1 if list was successfully written or 0 if user aborted or deleted *) InsertControls dup "@a/docs/default" smatch not if "@a/docs/" swap strcat dup else dup then ourDataObj @ over over (* editing clears /sup prop; check sup & replace if needed *) over over swap "#/sup" strcat getpropstr if 1 setSup? ! over "#/sup" strcat ourString ! then LMGR-GetList EDITOR "abort" smatch if ClearButOne 0 else depth 1 - pick depth 2 - pick LMGR-DeleteList 1 depth 1 - rotate depth 1 - rotate LMGR-PutRange 1 then setSup? @ if ourDataObj @ ourString @ "yes" setprop then ; : DoRemoveDoc ( d s -- ) (* remove dir s and s's subdirs from d *) dup "*/" smatch not if "/" strcat then over over nextprop swap pop begin (* begin sub-dir removing loop *) dup while over over nextprop 3 pick rot remove_prop repeat (* end sub-dir removing loop *) pop pop ; : DoShowDoc ( s -- ) (* print doc s to user's screen *) ourDataObj @ LMGR-GetList EDITdisplay ; : DoFindDoc ( s -- [s'] i ) (* return list name for doc specified by name or number s, and 1 if list was found or 0 if not found *) Begin (* begin doc-finding loop *) dup number? if atoi 1 ourDataObj @ "@a/docs/" nextprop begin (* begin doc-counting loop *) dup not if ">> Document number " rot intostr strcat " not found." strcat Tell NukeStack 0 exit then ourBoolean @ not if ourDataObj @ over "/sup" strcat getprop if ourDataObj @ swap nextprop continue then then dup "/default#" instr if ourDataObj @ swap nextprop continue then 3 pick 3 pick = if swap pop swap pop "" "@a/docs/" subst dup strlen 1 - strcut pop InsertControls break then over 1 + 2 put ourDataObj @ swap nextprop repeat (* end doc-counting loop *) break else InsertControls ourDataObj @ "@a/docs/" 3 pick strcat "#" strcat getprop not if ">> Document '" swap RemoveControls Strcat "' Not found." strcat Tell NukeStack 0 exit then break then repeat (* end doc-finding loop *) 1 ; : DoAddDoc ( -- ) (* get title of new doc; write *) begin (* begin input loop *) ">> What is the title of this document?" Tell ReadLine strip dup number? if ">> Because documents can be specified by number or " "title, using a number as a title results in ambiguities. " "Please choose a different title." strcat strcat Tell pop continue else break then repeat (* end input loop *) ">> Do you want this document to appear on the contents list?" Tell ReadYesNo if DoEditList pop pop else DoEditList if "#/sup" strcat ourDataObj @ swap "yes" setprop else pop then then ; : DoDeleteDoc ( -- ) (* get title|number of existing doc; delete *) ">> Enter title or number of document to delete, or .q to quit." Tell ReadLine strip QCheck DoFindDoc not if exit then "#" strcat "@a/docs/" swap strcat ourDataObj @ swap over over remove_prop DoRemoveDoc ">> Document deleted." Tell ; : DoEditDoc ( -- ) (* get title|number of existing doc; edit *) NukeStack begin (* begin input loop *) ">> Enter title or number of document to edit." Tell ReadLine strip QCheck dup ".n" smatch if break then DoFindDoc not while repeat (* end input loop *) DoEditList pop ; : DoRenameDoc ( -- ) (* rename an existing doc *) (* find doc to rename *) begin (* begin input loop *) ">> Enter title or number of document to be renamed, or .q to quit." Tell ReadLine strip QCheck DoFindDoc not while repeat (* get new title *) ">> Enter new title for '" over RemoveControls strcat "', or .q to quit." strcat Tell ReadLine strip QCheck InsertControls over over smatch if pop pop ">> Document renamed." Tell exit then ourDataObj @ "@a/docs/" 4 rotate strcat "#/" strcat ourDataObj @ "@a/docs/" 5 rotate strcat "#/" strcat MoveDir-r ">> Document renamed." Tell ; : DoAddAlias ( -- ) (* get title|number of existing doc; make an alias for it *) begin (* begin input loop *) ">> Enter title or number of document to be aliased." Tell ReadLine DoFindDoc not while repeat (* end input loop *) begin (* begin input loop *) ">> Enter alias to be used for '" over RemoveControls strcat "'." strcat Tell ReadLine dup number? if ">> Because documents can be specified by number or " "title, using a number as a title results in ambiguities. " "Please choose a different title." strcat strcat Tell pop continue else break then repeat (* end input loop *) InsertControls ourDataObj @ "@a/docs/xrefs/" rot strcat rot setprop ">> Alias added." Tell ; : DoDeleteAlias ( -- ) (* delete an alias *) begin (* begin input loop *) ">> Enter alias to delete." Tell ReadLine ourDataObj @ "@a/docs/xrefs/" 3 pick strcat getpropstr if break else ">> There is no alias '" swap strcat "'." strcat Tell continue then repeat (* end input loop *) InsertControls ourDataObj @ "@a/docs/xrefs/" rot strcat remove_prop ">> Alias deleted." Tell ; : DoAddKeywords ( -- ) (* add keywords for a doc *) begin (* begin input loop *) ">> Enter title or number of document to supply " "keywords for." strcat Tell ReadLine DoFindDoc not while repeat (* end input loop *) "#" strcat "@a/docs/" swap strcat "/kwords" strcat ourDataObj @ swap begin (* begin input loop *) ">> Enter keyword or words, as a space-separated string." Tell ReadLine break repeat (* end input loop *) 3 pick 3 pick getpropstr " " strcat swap strcat setprop ">> Keywords added." Tell ; : DoDeleteKeywords ( -- ) (* remove keywords for a doc *) begin (* begin input loop *) ">> Enter title or number of document to " "delete keywords for." strcat Tell ReadLine DoFindDoc not while repeat (* end input loop *) InsertControls "#" strcat "@a/docs/" swap strcat "/kwords" strcat ourDataObj @ swap over over getprop dup if ">> Current keywords: " over strcat Tell else ">> No keywords have been entered for that document." Tell pop pop pop exit then begin (* begin input loop *) ">> Enter keyword to delete." Tell ReadLine over over instr not if ">> '" swap strcat "' is not a current keyword." strcat Tell pop continue then "" swap subst break repeat (* end input loop *) dup STRblank? if pop ourDataObj @ swap remove_prop else ourDataObj @ rot rot setprop then ">> Keyword deleted." Tell ; : DoEditDefault ( -- ) (* edit default screen *) "default" DoEditList ; : DoContents ( -- ) (* list titles of docs, formatted to 3 cols *) Disabled? Line "0" ourCounter ! "" ourString ! ourDataObj @ "@a/docs/" nextprop dup not if ">> Sorry, no documents have been entered on this MUCK." Tell pop exit then begin (* begin doc-fetching loop *) dup while ourDataObj @ over "/sup" strcat getprop (* ourBoolean is true if supplement docs are to be shown as well *) ourBoolean @ not and if ourDataObj @ swap nextprop continue then dup "@a/docs/default#" smatch if ourDataObj @ swap nextprop continue then dup "@a/docs/xrefs" smatch if ourDataObj @ swap nextprop continue then ourCounter @ atoi 1 + intostr ourCounter ! ourCounter @ ") " strcat ourCounter @ strlen 1 = if " " strcat then over "" "@a/docs/" subst "" "#" subst RemoveControls strcat (* append 'S' to supplement titles *) dup "/sup" strcat ourDataObj @ swap getprop if " (S)" strcat then 24 Pad ourString @ swap strcat ourString ! (* print if we have three items; one line *) ourCounter @ atoi 3 % not if ourString @ Tell "" ourString ! then ourDataObj @ swap nextprop repeat (* end doc-fetching loop *) pop ourString @ Tell (* print remaining items *) ; : DoEditMenu ( -- ) (* display menu of edit options *) Line " A) List all documents F) Add an alias" Tell " B) Add a document G) Remove an alias" Tell " C) Edit a document H) Add keywords" Tell " D) Delete a document I) Remove keywords" Tell " E) Rename a document J) Edit default screen" Tell Line ">> Enter selection A - I, or .q to quit." Tell ; : DoEdit ( -- ) (* read menu input; route to admin/edit functions *) Disabled? StaffCheck not if ">> Permission denied." Tell exit then 1 ourBoolean ! begin (* begin input loop *) NukeStack DoEditMenu ReadLine strip QCheck dup "[A-J]" smatch not if ">> Invalid entry." Tell pop continue then dup "A" smatch if pop DoContents else dup "B" smatch if pop DoAddDoc else dup "C" smatch if pop DoEditDoc else dup "D" smatch if pop DoDeleteDoc else dup "E" smatch if pop DoRenameDoc else dup "F" smatch if pop DoAddAlias else dup "G" smatch if pop DoDeleteAlias else dup "H" smatch if pop DoAddKeywords else dup "I" smatch if pop DoDeleteKeywords else dup "J" smatch if pop DoEditDefault else ">> Invalid entry." Tell pop then then then then then then then then then then repeat (* end input loop *) ; : DoSearch ( -- ) (* search for s stored in ourString; print title or text, depending on #search/#browse *) Disabled? ourString @ not if ">> Syntax: " command @ strcat " #search " strcat Tell exit then ourString @ RemoveControls tolower ourString ! Line ">> Searching for '" ourString @ strcat "'... " strcat Tell Line background ourString @ tolower ourString ! NukeStack 0 ourDataObj @ "@a/docs/" nextprop "" begin (* begin list-fetching loop *) over while over RemoveControls tolower ourString @ tolower smatch 3 pick RemoveControls tolower ourString @ tolower instr or if (* ourBoolean is true if user is browsing: display full text... *) ourBoolean @ if over ourDataObj @ LMGR-GetList EDITdisplay Line (* ... otherwise show titles in 3 cols *) else DoFormatMatch then swap ourDataObj @ swap nextprop swap continue then ourDataObj @ 3 pick "/kwords" strcat getprop dup if tolower ourString @ tolower instr if ourBoolean @ if over ourDataObj @ LMGR-GetList EDITdisplay Line else DoFormatMatch then swap ourDataObj @ swap nextprop swap continue then else pop then (* put list on stack as string range *) over ourDataObj @ LMGR-GetList ourCounter ! begin (* begin text-searching loop *) ourCounter @ while ourCounter @ 1 - ourCounter ! tolower ourString @ instr if (* found one... pop remaining lines from stack *) begin (* begin line-popping loop *) ourCounter @ while pop ourCounter @ 1 - ourCounter ! repeat (* end line-popping loop *) ourBoolean @ if over ourDataObj @ LMGR-GetList EDITdisplay Line else DoFormatMatch then break then repeat (* end text-searching loop *) swap ourDataObj @ swap nextprop swap repeat Tell Line ">> Search complete." Tell pop pop ; : DoBrowse ( -- ) (* store true in ourBoolean to indicate 'display text'; search dbase of docs *) Disabled? ourString @ not if ">> Syntax: " command @ strcat " #browse " strcat Tell exit then 1 ourBoolean ! DoSearch ; : DoReadDoc ( s -- ) (* print doc s to player's screen *) Disabled? ourDataObj @ "@a/docs/xrefs/" 3 pick strcat getprop dup if swap pop else pop then DoFindDoc if "@a/docs/" swap strcat DoShowDoc then ; : main "me" match me ! dup ourString ! GetDataObj ourDataObj ! trig "@a/name" getpropstr ourCom ! Update dup if InsertControls dup "#*" smatch if " " STRsplit ourString ! "#help" over stringpfx if pop DoHelp else "#search" over stringpfx if pop DoSearch else "#find" over stringpfx if pop DoSearch else "#browse" over stringpfx if pop DoBrowse else "#contents" over stringpfx if pop DoContents else "#edit" over stringpfx if pop DoEdit else "#enable" over stringpfx if pop DoEnable else "#disable" over stringpfx if pop DoDisable else "#version" over stringpfx if pop DoVersion else "#install" over stringpfx if pop DoInstall else "#uninstall" over stringpfx if pop DoUninstall else ">> Command not understood." Tell exit then then then then then then then then then then then else DoReadDoc then else "@a/docs/default" ourDataObj @ LMGR-GetList dup if EDITdisplay else pop DoContents then then ; . c q @set asys-docs=W