SATSHELL Example
S@
Home SATGUI SATSHELL SATFORM SATFILTER SATREPORT SATMYSQL License Download Examples Contact

A basic help-text display utility.

User Guide

The following example assumes that the directories for both satshell and sathelp are included in the PATH environment variable.

To start the application enter:

satshell sathelp

When the application has started a screen similar to the following is displayed:

Book/Topic Selection Screen:

Each of the "folder" icons indicates a "book". The title of the book is displayed to the right of the icon.

NOTE: The "Close" button on the Book/Topic selection screen will close all SATHELP windows.


To display the topics contained in a book, single-click on the small black arrow to the left of the folder icon.

For example: To display the topics for "SATHELP Overview", single-click on the arrow to the left of the appropriate folder.


To display a selected book/topic, double-click anywhere on the line (except on the small black arrow) in which the required book/topic title is displayed.

Example: To display the "What is SATHELP?" topic from the "SATHELP Overview" book, double-click anywhere on the line containing "What is SATHELP". A new window is displayed containing the "SATHELP Overview" book, with the "What is SATHELP?" topic at the top of the display.

Book/Topic Display Screen:

A single-click on one of the blue "contents" links will move to display the Contents section at the begining of the book.

NOTE: The "Close" button on the Book/Topic display screen will close the associated window only.

A single-click on one of the blue links will move the display to the required topic.

NOTE: It is possible to have several Book/Topic display screens open simultaneously.


To search for books/topics contaning specified words select the "Find" radio-button on the Book/Topic selection screen.

Enter the words to search for into the entry field then press the "Search" button.

For example: To display all topics containing the word "text", type the word "text" into the search words entry field then press the "Search" button.

Book/Topic Find Screen:

A list of topics containing the matching words is displayed.

NOTE: The "Clear" button will delete the contents of the search words entry field.


A double-click on one of the topics will open a Book/Topic display window showing the selected topic.

For example: To display the "Selecting books and topics" topic, double-click anywhere on the line containing "Selecting books and topics". A new window is displayed containing the "Using SATHELP" book, with the "Selecting books and topics" topic at the top of the display.


By default the search will match a topic if it contains any one of the search words.

For example: To display all topics containing either of the words "text" or "book", type the words "text book" into the search words entry field then press the "Search" button.

To find a match only when a topic contains all of the search words activate the "Match all words" check-button then press the "Search" button.

To perform a case sensitive search activate the "Case sensitive" check-button then press the "Search" button.

NOTE: The "Match all words" and "Case sensitive" options may be used in conjunction.


Source Code

#===========================================================#
# SCRIPT  : sathelp                                         #
# PURPOSE : Basic help-text display utility.                #
#-----------------------------------------------------------#
# If using Bourne or Korn shell, the "-e" option for the    #
# "echo" commands is NOT required.                          #
#===========================================================#

#-------------------------------------------------------#
# Display main screen: List of "books" and "topics".    #
#-------------------------------------------------------#
main() {
cat << !
proc notebook {name} {hide "contents find";placeItem "\$name 1,3"}
newScreen {{"SATHELP"} 47x20}
addRadioButtons {select 1,1 {+Contents Find} horizontal outline {:notebook select}}
addBorder {contents 1,3 45x14 sunken}
addTree {contents:list 0,0 40x11 yscroll {displaytopic contents:list}}
addBorder {find hide 45x14 sunken}
addEntry {find:words 0,1 0,21 focus}
addButton {find:Search 24,1 5 {search find:words find:match:match_all_words find:match:case_sensitive}}
addButton {find:Clear  34,1 5 clear}
addCheckButtons {find:match 0,3 {Match_all_words Case_sensitive} horizontal}
addMultiList {find:topics 1,6 5 {Select_Topic,37 topic,0} yscroll outline {displaytopic find:topics(1)}}
addButton {Close 1,17 8 exit} 
!

gawk -F- '
BEGIN {
   print "setItem {contents:list"
}
{
   if ($0 ~ /^@/) {
      Book = $2
      print "{/" Book " folder text(" $3 ")}"
   }
   if ($0 ~ /^:/) {
      print "{/" Book "/" $2 " text(" $3 ")}"
   }
}
END {
   print "}"
}' ${HelpText}

}

#------------------------------------------------------#
# Clear "search" field.                                #
#------------------------------------------------------#
clear() {
echo "setItem {find:words {}};unlock"
}

#------------------------------------------------------#
# Search for topics containing specified word(s).      #
#------------------------------------------------------#
search() {

Words="$1"
All=$2
Case=$3

Check=1
Grep="grep"

[ ${All}  = Y ] && Check=`echo ${Words} | wc -w`
[ ${Case} = N ] && Grep="grep -i"

echo "setItem {find:topics "

for Book in `grep "^@" ${HelpText} | cut -f2 -d-`
do
   for TopicInfo in `gawk '/^@-'${Book}'/,/!-'${Book}'/ {if ($0~/^:/) print}' ${HelpText}`
   do
      Topic=`echo ${TopicInfo} | cut -f2 -d-`
      Title=`echo ${TopicInfo} | cut -f3 -d-`
      Text=`gawk '/^@-'${Book}'/,/!-'${Book}'/ {if ($0~/^[^@!]/) print}' ${HelpText}|
            gawk '/^:-'${Topic}'/,/;-'${Topic}'/ {if ($0~/^[^:;]/) print}'`

      Count=0

      for Word in ${Words}
      do
         echo "${Text}" | $Grep ${Word} > /dev/null && Count=`expr ${Count} + 1`
      done

      [ ${Count} -ge ${Check} ] && echo -e "{${Title}\t/${Book}/${Topic}}"|sed 's/_/ /g'
   done
done

echo "};unlock"

}

#------------------------------------------------------#
# Display selected topic.                              #
#------------------------------------------------------#
displaytopic() {

Book=`echo $1 | cut -f2 -d/`
Topic=`echo $1 | cut -f3 -d/`

[ "X${Topic}" = X ] && Topic=topic1

Text="`gawk '/^@-'${Book}'/,/!-'${Book}'/ {if ($0~/^[^@!:;]|^$/) print}' ${HelpText}`"

cat << !
newWindow {win$WindowID {SATHELP} 52x20}
addText {win$WindowID.text 1,1 45x15 yscroll}
addButton {win$WindowID.Close 1,17 8 {:closeWindow 'win$WindowID'}}
setItem {win$WindowID.text {$Text}}
gotoLabel {win$WindowID.text $Topic}
unlock
!

WindowID=`expr ${WindowID} + 1`

}

#------------#
# Initialise #
#------------#

HelpText=sathelptext
WindowID=1

main

#-----------#
# Main Loop #
#-----------#
while true
do
   read Command
   [ -z "$Command" ] && exit
   eval "$Command"
done

#---------------#
# End of script #
#---------------#

Comments

This aplication consists of six sections:

  1. A function to display the main Book/Topic selection screen. (main).
  2. A function to clear the search words entry field. (clear).
  3. A function to search for matching topics. (search).
  4. A function to display a selected topic. (displaytopic).
  5. Code to initialise variables and display the initial screen (Initialise).
  6. Code to read and run Action commands (Main Loop).


main - Displays the main Book/Topic selection screen.

main() {

Define the main function.

cat << !

A shell script "here" document is used to write SAT/DL commands to Standard Output. This will be read and interpreted by SATSHELL.

proc notebook {name} {hide "contents find";placeItem "\$name 1,3"}
Create a TCL procedure (See Notebook example) to display selected notebook "page".

newScreen {{"SATHELP"} 47x20}

Clear the screen/message line, set the application screen size to 47 characters by 20 rows, and set the window title to "SATHELP".

addRadioButtons {select 1,1 {+Contents Find} horizontal outline {:notebook select}}

Add a group of radio buttons called select with its top left corner at column 1, row 1. The group has two buttons: Contents and Find. The "+" prefix causes the Contents button to be activated. The radiobuttons have an outline and are displayed horizontal (The default is vertical). When a radio button is selected the notebook procedure is invoked with the value of the select radio button (contents -or- find) as the first parameter.

Note: The colon prefix to ":notebook" indicates that a TCL procedure should be invoked rather than a script function.

addBorder {contents 1,3 45x14 sunken}

Add a border called contents with its top left corner at column 1, row 3. The border size is 45 columns by 14 rows and has a sunken relief. This border is used as the container for the notebook "Contents" page.

addTree {contents:list 0,0 40x11 yscroll {displaytopic contents:list}}

Add a tree called contents:list. The "contents:" prefix creates the tree inside the contents border/container. The tree is positioned with its top left corner at column 0, row 0 relative to the contents border/container. The tree size is 40 columns by 11 rows and has a "Y" direction (vertical) scrollbar. Double-click on a tree folder/file item runs the displaytopic function with the value of the selected item as the first parameter.

addBorder {find hide 45x14 sunken}

Add a hidden border called find. Hidden borders and their contents are created but not displayed. The border size is 45 columns by 14 rows and has a sunken relief. This border is used as the container for the notebook "Find" page.

addEntry {find:words 0,1 0,21 focus}

Add and entry called find:words. The "find:" prefix creates the entry inside the find border/container. The entry is positioned with its top left corner at column 0, row 1 relative to the find border/container. The entry has a label text width of 0 (No label text displayed) and an entry width of 21 characters. When displayed and the window active the entry has keyboard focus.

addButton {find:Search 24,1 5 {search find:words find:match:match_all_words find:match:case_sensitive}}

Add a button called find:Search. The "find:" prefix creates the button inside the find border/container. The button is positioned with its top left corner at column 24, row 1 relative to the find border/container. The button is 5 characters wide and runs the search function with the values of find:words, find:match:match_all_words, and find:match:case_sensitive as parameters.

addButton {find:Clear 34,1 5 clear}

Add a buton called find:Clear. The "find:" prefix creates the button inside the find border/container. The button is positioned with its top left corner at column 34, row 1 relative to the find border/container. The button is 5 characters wide and runs the clear function.

addCheckButtons {find:match 0,3 {Match_all_words Case_sensitive} horizontal}

Add a group of check buttons called find:match The "find:" prefix creates the check buttons inside the find border/container. The check button group is positioned with its top left corner at column 0, row 3 relative to the find border/container. The group has two buttons: Match all words and Case sensitive. The radio buttons are displayed horizontal (The default is vertical).

addMultiList {find:topics 1,6 5 {Select_Topic,37 topic,0} yscroll outline {displaytopic find:topics(1)}}

Add a multi-column list called find:topics. The "find:" prefix creates the check buttons inside the find border/container. The multi-column list is positioned with its top left corner at column 1, row 6 relative to the find border/container. The multi-column list has 5 rows and two columns, Select Topic which is 37 characters wide, and topic which is 0 characters wide (hidden). The multi-column list has an outline and has a "Y" direction (vertical) scrollbar. Double-click on a line in the multi-column list item runs the displaytopic function with the value of the topic column of the selected line as the first parameter.

Note: The columns are numbered from zero.

addButton {Close 1,17 8 exit}

Add a buton called Close with its top left corner at column 34, row 1. The button is 8 characters wide and will exit the application.

!

End the "here" document.

gawk -F- '
BEGIN {
   print "setItem {contents:list"
}
{
   if ($0 ~ /^@/) {
      Book = $2
      print "{/" Book " folder text(" $3 ")}"
   }
   if ($0 ~ /^:/) {
      print "{/" Book "/" $2 " text(" $3 ")}"
   }
}
END {
   print "}"
}' ${HelpText}

Run a gawk script to read the help text file specified in the ${HelpText} variable in order to create a setItem command to populate the contents:list tree item (See SATHELP File Format).

}

End the function definition.


clear - Clear the search words entry field.

clear() {

Define the clear function.

echo "setItem {find:words {}};unlock"

Set the value of the find:words entry item to null. An unlock command is appended to the setItems, separated by ";". The unlock is required because SATSHELL "locks" the application window when an Action is triggered to prevent new Actions while the current is being processed.

}

End the function definition.


search - Search for matching topics.

search() {

Define the search function.

Words="$1"
All=$2
Case=$3

Assign variables to the values of the parameters passed to the search function.

Check=1

Set number of words which must match. The default value ("1") indicates that a single matching word is required.

Grep="grep"

Set "Grep" command to be used for matching.

[ ${All} = Y ] && Check=`echo ${Words} | wc -w`

If a match of all search words is required set the value of Check to the number of search words.

[ ${Case} = N ] && Grep="grep -i"

If a case insensitive search is required set the "Grep" command to grep -i.

echo "setItem {find:topics "

for Book in `grep "^@" ${HelpText} | cut -f2 -d-`
do
   for TopicInfo in `gawk '/^@-'${Book}'/,/!-'${Book}'/ {if ($0~/^:/) print}' ${HelpText}`
   do
      Topic=`echo ${TopicInfo} | cut -f2 -d-`
      Title=`echo ${TopicInfo} | cut -f3 -d-`
      Text=`gawk '/^@-'${Book}'/,/!-'${Book}'/ {if ($0~/^[^@!]/) print}' ${HelpText}|
            gawk '/^:-'${Topic}'/,/;-'${Topic}'/ {if ($0~/^[^:;]/) print}'`

      Count=0

      for Word in ${Words}
      do
         echo "${Text}" | $Grep ${Word} > /dev/null && Count=`expr ${Count} + 1`
      done

      [ ${Count} -ge ${Check} ] && echo "{${Title}\t/${Book}/${Topic}}"|sed 's/_/ /g'
   done
done

echo "};unlock"

Run shell and gawk script to search the help text file specified in the ${HelpText} variable in order to create a setItem command to populate the find:topics multi-column list item with a list of topics which match the search criteria. (See SATHELP File Format). The unlock is required because SATSHELL "locks" the application window when an Action is triggered to prevent new Actions while the current is being processed.

}

End the function definition.


displaytopic - Display a selected topic.

displaytopic() {

Define the displaytopic function.

Book=`echo $1 | cut -f2 -d/`
Topic=`echo $1 | cut -f3 -d/`

Assign Book and Topic variables to the appropriate parts of the parameter passed to the displaytopic function.

[ "X${Topic}" = X ] && Topic=topic1

If no topic selected default to topic1.

Text="`gawk '/^@-'${Book}'/,/!-'${Book}'/ {if ($0~/^[^@!:;]|^$/) print}' ${HelpText}`"

Assign Text variable to the contents of the selected topic from the help text file specified in the ${HelpText} variable.

cat << !

A shell script "here" document is used to write SAT/DL commands to Standard Output. This will be read and interpreted by SATSHELL.

newWindow {win$WindowID {SATHELP} 52x20}

Create a new window called win$WindowID in which to display the help text topic. The $WindowID variable is initailised in the initialise section of the script. This variable is incremented each time a new window is created. This ensures that each window has a unique name, which allows many help text topic display windows to be opened simultaneously.

addText {win$WindowID.text 1,1 45x15 yscroll}

Add a text item called win$WindowID.text. The win$WindowID prefix creates the text item inside the new window with this name. The text item is positioned with its top left corner at column 1, row 1. The text item size is 45 columns by 15 rows and has a "Y" direction (vertical) scrollbar.

addButton {win$WindowID.Close 1,17 8 {:closeWindow 'win$WindowID'}}

Add a buton called win$WindowID.Close. The "win$WindowID" prefix creates the button inside the new window with this name. The button is positioned with its top left corner at column 1, row 17 relative to the. The button is 8 characters wide and runs the :closeWindow SAT/DL command with win$WindowID as the parameter.

Note: The semi-colon prefix indicates that a SAT/DL command or a defined proc is run instead of a shell script function/command.

setItem {win$WindowID.text {$Text}}

Set the contents of the win$WindowID.text item to the value of the Text variable.

gotoLabel {win$WindowID.text $Topic}

Move the win$WindowID.text item so that the top of the display is positioned to put the label named in the $Topic variable at the top of the item.

unlock

The unlock is required because SATSHELL "locks" the application window when an Action is triggered to prevent new Actions while the current is being processed.

!

End the "here" document.

WindowID=`expr ${WindowID} + 1`

Increment the WindowID variable. The value of this variable is used as a suffix for window names to ensure that each Topic Display Window has a unique name, which allows many help text topic display windows to be opened simultaneously.

}

End the function definition.


"Initialise" - Initialise variables and display the initial screen.

HelpText=sathelptext
WindowID=1

Initialise the HelpText (name os help text file) and WindowID variables.

main

Run the main function.


"Main Loop" - Read and run Action commands.

while true
do

Start a "Do forever" loop.

   read Command

Read an Action command from standard input.

   [ -z "$Command" ] && exit

If the "Command" is null then the application window has closed, so exit the script. This check is important as the script will not otherwise terminate when the window is closed.

   eval "$Command"

Run the Action command.

Note: The "$Command" must be enclosed in double quotes.

done

End of the "Do forever" loop.

SATHELP File Format

TagDescription
@-bookID-bookTitleMark begining of book with identifier bookID and title bookTitle.
:-topicID-topicTitleMark begining of topic with identifier topicID and title topicTitle.
;-topicIDMark end of topic with identifier topicID.
!-bookIDMark end of book with identifier bookID.

Sample SATHELP File

@-book1-SATHELP_Overview
:-topic1-Contents
<label topic1><font helvetica><size 24><b><u>SATHELP Overview</u></b><size 12>

<size 18><b>Contents</b><size 12>

<link topic2>What is SATHELP?</link>
<link topic3>What is in this demo?</link>

;-topic1

:-topic2-What_is_SATHELP?
<label topic2><size 18><b>What is SATHELP?</b><size 12> (<link topic1>Contents</link>)

SATHELP is an application created for the\
purpose of demonstrating some of the new SATGUI/SATSHELL\
(SATUNI) facilities

;-topic2

:-topic3-What_is_in_this_demo?
<label topic3><size 18><b>What is in this demo?</b><size 12> (<link topic1>Contents</link>)

The following lists some SATUNI facilities which\
are demonstrated in SATHELP:-

o Tree item
o Text item
o Borders as containers
o Using, hide, placeItem and TCL procs



;-topic3
!-book1

===================================================================
@-book2-Using_SATHELP
:-topic1-Contents
<label topic1><font helvetica><size 24><b><u>Using SATHELP</u></b><size 12>

<size 18><b>Contents</b><size 12>

<link topic2>Selecting books and topics</link>
<link topic3>Searching for words</link>

;-topic1

:-topic2-Selecting_books_and_topics
<label topic2><size 18><b>Selecting books and topics</b><size 12> (<link topic1>Contents</link>)

The contents screen, when first displayed, shows\
a list of the books contained in the help text\
file.

Click on the arrow next to the book to display a\
list of the topics contained in the book.

Double-click on a book or topic line to display\
the selected book/topic in a new window.

<b>Note:</b> It is possible to open more than one\
book/topic window.

The <b>Contents</b> and <b>Find</b> buttons are used\
to select the required display.

The <b>Close>/b< button will close the SATHELP application.

;-topic2

:-topic3-Searching_for_words
<label topic3><size 18><b>Searching for words</b><size 12> (<link topic1>Contents</link>)

To perform a word search select the <b>Find</b> button.

Enter the word(s) you wish to search for into the search\
words entry field, then press the <b>Search</b> button. A\
list of the topics containing the word(s) will be\
displayed in the <b>Select Topic</b> box. Double-click on\
on a topic to open a book window positioned at the selected\
topic. The <b>Close</b> button in the book window will\
close the book window only.

By default the search will match if a topic contains\
any one of the search words and is <i>not</i> case sensitive.

The <b>Match all words</b> and <b>Case sensitive</b> check\
boxes can be used to modify the scope of the search.

The <b>Clear</b> button will delete the contents of the\
search words field.


;-topic3
!-book2


Copyright © 2003
Adrian Davis.