[Date Prev] [Date Next] [Thread Prev] [Thread Next] Date Index Thread Index Search archive:
Date:Mon Mar 2 22:39:31 1993 
Subject:Finding and browsing Poplog Online Documentation 
From:Aaron Sloman 
Volume-ID:930302.04 

I sent this to pop-forum, but maybe it would be of interest or use to
some news readers who don't get pop-forum mail.

 From Aaron Sloman Mon Mar  1 19:47:14 GMT 1993
 To: pop-forum@hplb.hpl.hp.com
 Subject: ved_browse (A new browsing utility)

I've been finding it difficult to find things in the Poplog system
because of the proliferation of different directory trees (including
local directories, X stuff, and the possibility of additional
libraries, such as objectclass, etc.)

It used to be possible to get by with "index" files (e.g. HELP INDEX,
HELP XVEDINDEX HELP XPOPINDEX) but it is hard to remember these names,
and in some cases (e.g. HELP PLOGINDEX) you have to have the language
subsystem loaded for the index file and the corresponding documentation
files to be accessible. (In V14.2, lib make_indexes  is a heroic attempt
to get round this.)

I now think that in effect the old Poplog indexing mechanisms have
broken down because there are too many categories all with their own
help, teach, ref, lib, etc. files, and remembering about all the
different names imposes an intolerable cognitive requirement on users.

So I've tried to produce a better solution, and ved_browse is a first
attempt.

LIB VED_BROWSE described in HELP VED_BROWSE helps you find out which
files are actually available in various POPLOG library categories, e.g.

    pop11 help files
    prolog teach files
    pop11 autolodable files
    pop11 lib files (including autoloadable files)
    prolog src files
    ml lib files
    lisp ref files

To run the program (after installing it in an autoloadable library) do

    ENTER browse

You first get a menu (on the command line) of languages to choose from
(i.e. all the four poplog languages) and then a menu of types of file
(e.g. teach, help, ref, lib, etc.) In both case select by typing the
appropriate number key (without RETURN).

Then, to look at a particular file listed in the browse index file, put
the cursor on or to the left of its name, and press the REDO key (or
again do ENTER browse).

The HELP file and the LIB file follow, separated by a row of "="
signs.

This version works on Unix Poplog only. I leave it to someone else
to convert it to VMS.

Aaron
Help file follows, then LIB file.
=======================================================================
[help file to go in $poplocal/local/help/ved_browse or in main system]

DRAFT HELP VED_BROWSE  (Unix Poplog only)         Aaron Sloman, Feb 1993

LIB VED_BROWSE

This utility provides an extension to the Poplog Ved-based mechanisms
for browsing online documentation and libraries. The library makes
available the command "ENTER browse", which makes it easy to browse
online documentation and libraries in Poplog.

         CONTENTS - (Use <ENTER> g to access required sections)

 -- Introduction
 -- (a) ENTER browse (Building an index)
 -- (b) ENTER browse (Selecting from a browse index)
 -- How an index is built
 -- The structure of the browse index files
 -- WARNINGS
 -- Changing search lists: the browse_search_lists property
 -- SEE ALSO

-- Introduction -------------------------------------------------------
The procedure ved_browse has two forms of behaviour, depending on whether
the current file is already a browse index file created by a previous
call of ved_browse. In that case the name where the cursor is, is used
to read the relevant file into the editor. If the current file is not a
browse index file, then ved_browse will create one.

In order to do this it first asks you to select the language, and then
it asks you which type of file is required, For both of these it
provides a simple menu on the VED status line. More detailed
explanations follow.


-- (a) ENTER browse (Selecting from a browse index) -------------------

If invoked in an index of files previously created as described below by
"ENTER browse", the command fetches the file whose name the cursor is
above or to the left of.

(See the WARNING below)


-- (b) ENTER browse (Building an index) -------------------------------

If the command is not invoked in a browse-produced index of available
files, it gets you an index of available files in a category, using the
name of the category and the directory searchlist for the category.

When you give the command "ENTER browse" it first asks you which
language subsystem, by presenting the following menu:

    0:current 1:pop11 2:prolog 3:lisp 4:ml

Select the language by typing the appropriate key. Pressing "0" implies
that you want the language that is currently the default. (There's no
need to press RETURN after making your selection.)

It then prompts you on the status line to specify which category of
files to look at. You select from the following menu, by typing a
number:

    1:help 2:teach 3:ref 4:doc 5:lib 6:auto 7:src 8:include

Select the category by pressing the appropriate number key.

When the language is Pop11, the 8 category options correspond to
searching through directories in

    vedhelplist
    vedteachlist
    vedreflist
    veddoclist
    popuseslist
    popautolist
    popsrclist
    popincludelist

except that overlaps between help, teach, ref, and doc lists are
eliminated. (By default they have a lot of overlap, for convenience.)

For other languages only a subset of categories may have corresponding
directories. (It would be possible, but a bit tedious to have the
program automatically modify the second menu depending on which language
you have chosen. I may do that later.)

Ideally documentation and libraries associated with VED should be dealt
with separately from Pop-11 information, but that would require major
reorganisation of the Pop-11 directory structure. So information
about VED is obtained by selecting the Pop-11 option first, and then
teach, help, ref, or lib second.


-- How an index is built ----------------------------------------------

Once you have selected a category and a language, ved_browse traverses
directories in that category and lists their contents in a VED buffer,
grouped by directory. It does this by spawning a sub-shell with a
command of one of the following forms, depending on the operating system

SunOS
    /usr/5bin/ls -xL dir1 dir2 dir3 ....
HP-UX
    /bin/ls -xL dir1 dir2 dir3 ....
Others
    /bin/ls -CL dir1 dir2 dir3 ....

where the directory names come from the appropriate search list.

If you prefer to vary the format of the index you can alter the string
browse_ls_command, defined in LIB VED_BROWSE. E.g. to have single column
output try

    'ls -L' -> browse_ls_command;

You can keep the index and at any time later on move the VED cursor to
the name of the desired file and again give the command

    ENTER browse

in order to read that file. Alternatively, simply press the REDO key if
that command is still on the command line.

NOTE: it should be possible to tailor this program to work on VMS, but
I am not sufficiently familiar with VMS or VMS Poplog.


-- The structure of the browse index files -----------------------------

A different index file is created for each combination of language and
file category.

The top two lines in the file are used by subsequent calls of ved_browse
to recognise that this is a browse index file, and to determine the
language and category, so they should not be edited after creation.

The first line is an instruction to the user and also identifies the
file as a browse index file. The second line gives language name and
index category. The third line is a reminder not to edit the first two.

After that a table of contents is provided listing the directories
found, in the standard format of Poplog online documentation files so
that you can select a group using the normal "ENTER g" command, as
described in HELP * VED_INDEXIFY

Files in a directory are grouped together.


-- WARNINGS -----------------------------------------------------------

1. SUBDIRECTORIES
If there are any sub-directories in the directories included in
search lists they will be listed as ordinary files, and attepts to
access them in mode (b) may produce mysterious failure messages.

Some of those sub-directories will in any case be included in search
lists (e.g. $popvedlib and $popvedlib/term are both in popautolist
and popuseslist), but not all sub-directories are.

If you wish to have sub-directories indicated as directories in the
browse index add the "F" flag to browse_ls_command (See MAN * LS).
However, this will slow down creation of indexes considerably.

2. UNREADABLE FILES
In "src" directories some unreadable binary files will be listed, in
particular files called safepop11 or files with the suffixes
    .o .obj .olb .wlb


3. CATEGORIES NOT INCLUDED
There are some X source files provided with Poplog that are not in
any standard search list. These will not be found by ved_browse, but
can be explored (e.g. using ved_dired -- see HELP * DIRED) in the
following directory
    $usepop/pop/x/Xpw

There are also some useful command files in $popcom, and possibly
$poplocal/local/com $popsys/popenv which are not included. There
should be something like a vedcomlist category.

Also $popcontrib is not included at present (unless you add some
$popcontrib directories to your search lists). That should be remedied,
though ved_dired can easily be used to browse $popcontrib.


4. USER-DEFINED CATEGORIES

HELP * VEDGETSYSFILE and REF * VEDGETSYSFILEPDR describe mechanisms by
which users can define new browseable file categories that can then be
integrated with the standard Poplog cross reference (hypertext)
mechanism. At present ved_browse does not cope with these, but it is
easy to extend, by modifying the values of the following global
variables from LIB VED_BROWSE

    browse_type_menu        browse_types
    browse_subsystem_menu   browse_subsystems

and then adding extra keys to the property described below, where
a key is a word composed of a subsystem (language) name and a type
name.


-- Changing search lists: the browse_search_lists property ------------

The search lists are stored in a pop-11 property (see * newproperty)
called browse_search_lists. The lists are accessed and updated via
keys that are words composed from the language name and the file
category. The following keys are used:

For Lisp:      lisphelp lisplib lispref lispsrc lispteach

For Poplog ML: mlhelp mllib mlsrc mlteach

For Pop11:     pop11auto pop11doc pop11help pop11include pop11lib
               pop11ref pop11src pop11teach
    (This includes all the main X documentation and libraries)

For Prolog:    prologhelp prologlib prologsrc prologteach

The value associated with each key can either be a word whose valof
normally holds the search lists, or a list in the standard form of
Poplog search lists. (See HELP * SEARCH_LISTS). The procedure
flatten_searchlist is used to remove extraneous information before the
list is used by ved_browse.

Examples:

    browse_search_lists("lisplib") =>
    ** [$poplocal/local/lisp/modules/ $usepop/pop/lisp/modules/]

    browse_search_lists("pop11help") =>
    ** vedhelplist

Note however, that the default vedhelplist will include "ref" "doc" and
"teach" directories, whereas ved_browse will ignore those if the
category chosen is "help".

You can modify a search list for a particular category by associating a
new variable name, or a list with the key. e.g.

    "prologliblist" -> browse_search_lists("prologlib");

    [...some list ...] -> browse_search_lists("lisplib");

NOTE: this mechanism should be better integrated with LIB SUBSYSTEM.
However, it was intended that ved_browse should be usable to look
at documentation and programme libraries for a poplog language that
is not included in the current process, and LIB SUBSYSTEM does not
yet provide an appropriate mechanism.


-- SEE ALSO -----------------------------------------------------------

The following additional files may be relevant.

HELP * DOCUMENTATION
HELP * SHOWLIB
HELP * VEDSYSFILE
HELP * VEDGETSYSFILE
HELP * DIRED
DOC  * SYSSPEC
HELP * SUBSYSTEMS
REF  * SUBSYSTEM
    (including entries for
        * ved_lisp * ved_pml * ved_pop11 * ved_prolog)

LIB * VED_BROWSE

--- $poplocal/local/help/ved_browse
--- NO COPYRIGHT. USE AS DESIRED FOR ANY PURPOSE -------

=======================================================================
End of HELP file. LIB file follows.
=======================================================================
/* --- NO COPYRIGHT. COPY AND REUSE AS REQUIRED ----------
 > File:            $poplocal/local/auto/ved_browse.p
 > Purpose:         Get an index to online files, or access a file
 > Author:          Aaron Sloman, Feb 26 1993
 > Documentation:    HELP * VED_BROWSE
 > Related Files:    See cross references in HELP VED_BROWSE
 */


section;

;;; Global constants used below
;;; Standard directories for PML documentation and libraries
lconstant dir_lists =
    [
;;; ML
        [mlhelp [ '$poplocal/local/pml/help/' '$usepop/pop/pml/help/' ]]
        [mlteach [ '$poplocal/local/pml/teach/' '$usepop/pop/pml/teach/']]
        [mllib ['$poplocal/local/pml/lib/' '$usepop/pop/pml/lib/']]
        [mlsrc [ '$usepop/pop/pml/src/' ]]
;;; LISP
        [lisphelp
            ['$poplocal/local/lisp/help/' '$usepop/pop/lisp/help/' ]]
        [lispref ['$usepop/pop/lisp/ref/' ]]
        [lispsrc [ '$usepop/pop/lisp/src/' ]]
        [lispteach ['$poplocal/local/lisp/teach/']]
        [lisplib
            ['$poplocal/local/lisp/modules/' '$usepop/pop/lisp/modules/']]
;;; PROLOG
        [prologhelp
            ['$poplocal/local/plog/help/' '$usepop/pop/plog/help/' ]]
        [prologteach
            ['$poplocal/local/plog/teach/' '$usepop/pop/plog/teach/' ]]
        [prologlib
            [ '$poplocal/local/plog/lib/'
                '$poplocal/local/plog/auto/'
                '$usepop/pop/plog/lib/'
                '$usepop/pop/plog/auto/' ]]
        [prologsrc
            ['$usepop/pop/plog/src/']]
;;; POP11
        [pop11teach vedteachlist]
        [pop11help vedhelplist]
        [pop11ref vedreflist]
        [pop11doc veddoclist]
        [pop11src vedsrclist]
        [pop11teach vedteachlist]
        [pop11auto popautolist]
        [pop11lib popuseslist]
        [pop11include popincludelist]
    ]
    ;

;;; Define a property mapping combination of language and category onto
;;; search list, or its name.

global constant browse_search_lists =
    newproperty(dir_lists, length(dir_lists), [], "perm");


;;; Some useful strings
lconstant
    browse_index_message =
        'BROWSE INDEX: put cursor on desired file name then press REDO',

    name_terminators = '\s\t';


;;; Menu strings, and corresonding vectors of names of languages or
;;; file categories

global vars
    browse_subsystem_menu =
        '0:current 1:pop11 2:prolog 3:lisp 4:ml',

    browse_subsystems =
        {current pop11 prolog lisp ml},

    browse_type_menu =
        '1:help 2:teach 3:ref 4:doc 5:lib 6:auto 7:src 8:include :',

    browse_types =
        {'help' 'teach' 'ref' 'doc' 'lib' 'auto' 'src' 'include'},
;

;;; Nex procedure should be part of poplog

define sys_file_exists() with_nargs 1;
    ;;; check for existence of a file. Faster than -readable-
    sys_file_stat(nullvector)
enddefine;

;;; get default command for running "ls" on library directories
#_IF sys_file_exists('/usr/5bin/ls')
	;;; Probably SunOS !

    global vars browse_ls_command = '/usr/5bin/ls -xL';

#_ELSEIF issubstring('hp', hd(sys_machine_type))
    ;;; Running HP-UX

    global vars browse_ls_command = '/bin/ls -xL';

#_ELSE
    ;;; Default for Unix systems

    global vars browse_ls_command = '/bin/ls -CL';

#_ENDIF




define lconstant getoption(menu_string, vector) -> char;
    ;;; displayse menu options and returns the selection, based on
    ;;; character typed by user.

    lvars char, menu_string, vector, len = datalength(vector);

    ;;; show menu and wait for response
    repeat
        vedsetstatus(menu_string, false, true);
        vedwiggle(0,vedscreenwidth);
        vedscr_read_input() -> char;
        if isnumbercode(char) and (char - `0`) <= len then
            quitloop
        else
            vedscreenbell()
        endif
    endrepeat;
enddefine;


define lconstant thisname() -> name;
    ;;; return file name under or to right of VED cursor
    ;;; also move VED cursor to right of the name
    lvars char, name, startcol,
        col = vedcolumn,
        line = vedthisline();

    min(col, vvedlinesize) -> col;    ;;; in case to right of text
    ;;; find beginning of name by moving left to space or tab
    until col == 1
    or strmember(subscrs(col, line), name_terminators)
    do
        col - 1 -> col;
    enduntil;

    ;;; now get name to right of cursor
    ;;; Move right past spaces and tabs to start of name
    until col > vvedlinesize
    or not(strmember(subscrs(col, line), name_terminators))
    do
        col + 1 -> col;
    enduntil;

    ;;; record beginning of name
    col -> startcol;

    ;;; find next space or tab character, ending file name
    until col > vvedlinesize
    or strmember(subscrs(col, line), name_terminators)
    do
        col + 1 -> col;
    enduntil;

    ;;; now extract the name
    substring(startcol, col - startcol, line) -> name;
    ;;; move cursor to end of name
    col -> vedcolumn;
enddefine;


define lconstant prune_dirs(doc_type, doc_dirs) -> doc_dirs;
    ;;; return doc_dirs, minus those that don't include doc_type
    lvars dir, doc_type, doc_dirs, dirs;

    flatten_searchlist(recursive_valof(doc_dirs)) -> doc_dirs;

    unless member(doc_type, ['lib', 'auto']) then
        ;;; remove dirs of different type, e.g. remove ref dirs
        ;;; from help list
        [%
            for dir in doc_dirs do
                if issubstring(doc_type, dir) then dir endif
            endfor
        %] -> doc_dirs
    endunless;

    ;;; now remove redundancies
    [%
        for dirs on doc_dirs do
            front(dirs) -> dir;
            unless member(dir, back(dirs)) then dir endunless
            endfor
    %] -> doc_dirs
enddefine;

define lconstant browse_get_file();
    ;;; get file name that cursor is on or to left of in browse index file
    lvars filename,  language_and_type;

    vedbuffer(2) -> language_and_type;

    thisname() -> filename;

    ;;; Now build up the help, teach, showlib or whatever command
    veddo(language_and_type sys_>< space sys_>< filename)
enddefine;

define lconstant browse_make_index();
    lvars
        char, dir, command, doc_type, subsystem_name,
        searchlist, doc_dirs,
        oldfile = vedcurrentfile;

    getoption(browse_subsystem_menu, browse_subsystems) -> char;

    subscrv(char - `0` + 1, browse_subsystems) -> subsystem_name;

    ;;; deal with option 0
    if subsystem_name = "current" then subsystem -> subsystem_name endif;
    ;;; in case current subsystem is prolog "top" level.
    if subsystem_name = "top" then "prolog" -> subsystem_name endif;

    ;;; find documentation type
    getoption(browse_type_menu, browse_types) -> char;

    subscrv(char - `0`, browse_types) -> doc_type;

    ;;; create the key for accessing the table - a compound word
    ;;; and use it to access the property
    browse_search_lists(consword(subsystem_name sys_>< doc_type)) -> doc_dirs;

    ;;; flatten the list, get rid of duplicates, and remove extras
    prune_dirs(doc_type, doc_dirs) -> doc_dirs;

    if doc_dirs == [] then
        vederror('NO SEARCH LIST FOR ' >< subsystem_name >< space >< doc_type)
    endif;

    ;;; build up a string to form the argument for veddo, of the form
    ;;; sh <ls command> dir1 dir2 dir3 ... | expand -8
    ;;; where expand is used to remove tabs.

    consstring
        (#| explode('sh '),        ;;; for ENTER sh, to invoke vedgenshell
            explode(browse_ls_command),
            `\s`,
            for dir in doc_dirs do
                if sys_file_exists(dir) then explode(dir), `\s` endif
            endfor,
            explode(' | expand -8')
        |#) -> command;

    veddo(command);

    ;;; That should have created lists of relevant files, in a
    ;;; new VED buffer. Check.
    if oldfile == vedcurrentfile then vederror('NO FILES FOUND') endif;

    ;;; suppress screen output till call of vedrefresh, below

    dlocal vedediting = false;
    vedtopfile();
    vedlineabove();
    0 -> vedlineoffset;

    ;;; Insert instructions at top of file. (Also used to identify this
    ;;;     later as a browse index file)
    vedinsertstring(browse_index_message);

    ;;; now record the language and documentation type
    vedlinebelow();
    vedinsertstring(
        if subsystem_name = "ml" then 'pml' else subsystem_name endif
        sys_>< space sys_><
         if member(doc_type, ['lib' 'auto']) then 'showlib' else doc_type
        endif);
    vedlinebelow();
    vedinsertstring('NB:- Do not alter previous two lines -:NB');

    ;;; Now remove the line produced by vedgenshell, starting "sh"
    vednextline();
    if isstartstring('sh ', vedthisline()) then
        nullstring -> vedthisline()
    else
        vedlineabove();
    endif;

    if length(doc_dirs) > 1 then
        ;;; Now prepare an index to directories, using ved_indexify
        veddo('gs;@a/;-- /;');
        veddo('indexify');
    else
        vedlinebelow();
        vedinsertstring(hd(doc_dirs))
    endif;
    vedtopfile(); vedtextright();
    vedputcommand('browse');
    chain(vedrefresh);
enddefine;

;;; Now the top level procedure

define global ved_browse();
    if vvedbuffersize > 2 and vedbuffer(1) = browse_index_message then
        ;;; inside a "browse" index file. Get the name and find the file.
        browse_get_file();
    else
        ;;; create a new index
        browse_make_index()
    endif
enddefine;

endsection;
-- 
Aaron Sloman,
School of Computer Science, The University of Birmingham, B15 2TT, England
EMAIL   A.Sloman@cs.bham.ac.uk  OR A.Sloman@bham.ac.uk
Phone: +44-(0)21-414-3711       Fax:   +44-(0)21-414-4281