# s c r a p e  --  Screen-scraping demo script for Kermit 95.
#
# Kermit 95 1.1.17 or later required.
#
# Author:  Max Evarts, The Kermit Project, Columbia University, 24 May 1999
#
goto BEGIN ; Jump around comments

Kermit 95 allows scripts to access the terminal screen via the functions:

  \fscrncurx()
    Returns the 0-based X coordinate (column) of the Terminal screen cursor.

  \fscrncury()
    Returns the 0-based Y coordinate (row) of the Terminal screen cursor.

  \fscrstr(ny,nx,n1)
    Returns the string at Terminal-screen coordinates (nx,ny), length n1,
    blanks included.

The script below is a real-life demonstration of these functions that was
written to solve the following problem:

  A program displays scanned optical images.  Each image file is indexed
  (up to 7 indexes) and we can use these indexes to find images.
  Customers have a window with seven fields in which to put information to
  find an image.  The customer presses a special key on the information
  that is displayed on the Kermit 95 terminal screen and this information
  should be forwarded to one of the seven index fields (filters).  We have
  our own API and use program:

  CSAPI32.EXE SYSTEMNAME [SPYLINK NAME] [FILTER1/,] ... [FILTER7/,]
       [INTERACTIVE(YES/NO)] [SHOW DUPLICATES(YES/NO)] [USE FILTER(YES/NO)]

  to run our browser and display images depending on filters 1-7.

Requirements:

  1. An initialization file in which we declare:
      a) SYSTEMNAME (ip address - general parameter)
      b) INTERACTIVE (YES/NO - general parameter)
      c) SHOWDUPLICATES (YES/NO - general parameter)
      d) USEFILTER (YES/NO - general parameter)
      e) Screen name on which definition is active
      f) SPYLINKNAME (type of document which I search: invoices, bills,
	 etc -- the parameter can be different on each screen)
      g) Up to seven position of information (start column, end column,
         row) associated with filters - parameters can be different on
         each screen

  2. A script that, after the user presses the special key, runs CSAPI32
     with parameters based on screen scraping and the initialization-file
     settings.  This script should get the screen name (which appears in a
     certain spot on every screen, e.g.  in line 2 from column 5 to 18
     "Work with invoices").  This is required to forward the info to the
     proper spylink (document type) and because filters which can be
     different on each screen.  If the user presses the special key on a
     non-declared screen, an error message is given.

Operation:

  We define a macro, READSCRN, that uses screen scraping functions to a)
  determine if the current host screen is one of the screens that has been
  defined and b) if it is, read values from the .INI file and the current
  screen to build a command line for the image browsing application.

The script:

:BEGIN

<begin SCRAPEIT.KSC>

; SCRAPEIT.KSC - Script to be called at startup of Kermit 95 to initialize
; screen scraping-functions for control of a local application, CSAPI32.EXE,
; from Kermit 95 using information displayed on the user's screen and
; taken from an initialization file, SCRP.CFG.
;
; Version 1.0 - 5/14/99
;   Change "echo" to "run" to make version live
; Version 0.6 beta - 5/6/99
;   Changes to READSCRN macro to place commas for empty values and separate
;   two or more contiguous filter values by spaces instead of commas - ME
; Version 0.5 beta - 5/5/99
;   First beta release

; HOLDSCREEN function is used to update the user on an error condition,
; require them hit Enter to move on, then resume program flow at a given
; point.

def HOLDSCREEN echo, getc \%9 {Press Enter to continue: }, goto \%1

; MAKEVAR function is used to create a variable from each item in the
; SCRP.CFG file by prefixing each left column item with an underscore and
; then assigning the value from the right column of scrp.cfg to it.

def MAKEVAR asg \%9 _\%1, _assign \%9 \%2

; This variation does not evaluate the value being assigned to the variable
def MAKEKVAR asg \%9 _\%1, asg \%9 \%2

; Tell user what this file does
echo
echo Loading CSAPI imaging extensions...

; Open the configfile (scrp.cfg) in an error-handling way
def _noconfig
asg _configfile \freplace(\v(startup)scripts/scrp.cfg,/,\\)
echo Configuraton file = \m(_configfile)
xif not exist \m(_configfile) { 
  ec {FATAL - Configuration file \m(_configfile) not found}
  holdscreen END
  def _noconfig 1
  end
}
open read \m(_configfile)
xif fail {
  ec {Fatal - Error reading configuration file \m(_configfile)}
  holdscreen END
  def _noconfig 1
  end
}

; OK, file is here and it is good, read each line and feed it to MAKEVAR 
; or MAKEKVAR, handling blank lines and comment lines

echo Loading configuration...
while true {
  read \%a
  if fail break
  if eq "\fsubstring(1,1,\%a)" ";" continue
  if eq "\%a" "" continue
  xif eq "\fsubstring(1,9,\%a)" "keymapped" {
     makekvar \%a
     continue
  }
  makevar \%a
}
close read
echo Configuration loaded successfully.
echo

; The READSCRN macro does the bulk of the real work. 
;
; It first initializes all of its internal variables, then it goes into a
; FOR loop that reads up to _maxscreen number of possible screenname
; locations looking for an exact match to the screen name variable at the
; exact location specified in SCRP.CFG.  If a match is found, _scrno is
; defined to represent the proper prefix for that screen.  Subsequently,
; _scrno is used to select all the appropriate variables for the active
; screen.  If no match is found then, _scrno remains undefined and the
; READSCRN macro exits immediately.
;
; From here the macro simply uses the \fscrnstr() function to read values
; from the screen at the locations defined for the active screen.  It then
; combines these values with the general and screen-specific variables and
; builds and runs the CSAPI32.EXE command line.

def READSCRN {
 def _scrno, def _qscrn, def _fltr1, def _fltr2
 def _fltr3, def _fltr4, def _fltr5, def _fltr6, def _fltr7
 for \%i 1 \m(_maxscreens) 1 {
    _asg _qscrn\%i \ftrim(\fscrnstr(\fdef(_scr\%i_name_r),-
\fdef(_scr\%i_name_c),\fdef(_scr\%i_name_l)))
    if eq {\m(_qscrn\%i)} {\m(_screenname\%i)} _asg _scrno scr\%i
 }
 if not def _scrno goto END
 if = \fdef(_\m(_scrno)_fltr1_l) 0 asg _fltr1 {\44}
 else asg _fltr1 \ftrim(\fscrnstr(\fdef(_\m(_scrno)_fltr1_r)
                             \fdef(_\m(_scrno)_fltr1_c)
                             \fdef(_\m(_scrno)_fltr1_l)))
 if eq "\m(_fltr1)" "" asg _fltr1 {\44}
 if = \fdef(_\m(_scrno)_fltr2_l) 0 asg _fltr2 {\44}
 else asg _fltr2 \ftrim(\fscrnstr(\fdef(_\m(_scrno)_fltr2_r)
                             \fdef(_\m(_scrno)_fltr2_c)
                             \fdef(_\m(_scrno)_fltr2_l)))
 if eq "\m(_fltr2)" "" asg _fltr2 {\44}
 if = \fdef(_\m(_scrno)_fltr3_l) 0 asg _fltr3 {\44}
 else asg _fltr3 \ftrim(\fscrnstr(\fdef(_\m(_scrno)_fltr3_r)
                             \fdef(_\m(_scrno)_fltr3_c)
                             \fdef(_\m(_scrno)_fltr3_l)))
 if eq "\m(_fltr3)" "" asg _fltr3 {\44}
 if = \fdef(_\m(_scrno)_fltr4_l) 0 asg _fltr4 {\44}
 else asg _fltr4 \ftrim(\fscrnstr(\fdef(_\m(_scrno)_fltr4_r)
                             \fdef(_\m(_scrno)_fltr4_c)
                             \fdef(_\m(_scrno)_fltr4_l)))
 if eq "\m(_fltr4)" "" asg _fltr4 {\44}
 if = \fdef(_\m(_scrno)_fltr5_l) 0 asg _fltr5 {\44}
 else asg _fltr5 \ftrim(\fscrnstr(\fdef(_\m(_scrno)_fltr5_r)
                             \fdef(_\m(_scrno)_fltr5_c)
                             \fdef(_\m(_scrno)_fltr5_l)))
 if eq "\m(_fltr5)" "" asg _fltr5 {\44}
 if = \fdef(_\m(_scrno)_fltr6_l) 0 asg _fltr6 {\44}
 else asg _fltr6 \ftrim(\fscrnstr(\fdef(_\m(_scrno)_fltr6_r)
                             \fdef(_\m(_scrno)_fltr6_c)
                             \fdef(_\m(_scrno)_fltr6_l)))
 if eq "\m(_fltr6)" "" asg _fltr6 {\44}
 if = \fdef(_\m(_scrno)_fltr7_l) 0 asg _fltr7 {\44}
 else asg _fltr7 \ftrim(\fscrnstr(\fdef(_\m(_scrno)_fltr7_r)
                             \fdef(_\m(_scrno)_fltr7_c)
                             \fdef(_\m(_scrno)_fltr7_l)))
 if eq "\m(_fltr7)" "" asg _fltr7 {\44}
 run CSAPI32 \m(_systemname)\{32}\fdef(_\m(_scrno)_spylnk)\{32}-
\m(_fltr1)\{32}\m(_fltr2)\{32}\m(_fltr3)\{32}\m(_fltr4)\{32}\m(_fltr5)\{32}-
\m(_fltr6)\{32}\m(_fltr7)\{32}\m(_interactive)\{32}\m(_showduplicates)\{32}-
\m(_usefilter)
 :END
 if terminal-macro connect
}

; Set the key that was chosen in SCRP.CFG to execute the READSCRN macro
; ;
set key \m(_keymapped) \Kreadscrn

:END

<end SCRAPEIT.KSC>

<begin SCRP.CFG>

; Set general parameters

; This is the key that is mapped to invoke the image viewing code.
; Default mapping is F1.

; For a list of scan codes to choose a different key, see the "Table of
; Keyboard Key Codes" in the online manual.  Four backslashes are required
; to have an actual backslash persist through several variable assignments
; as the backslash is the Kermit script language quoting character.

keymapped	\\\\368

; General command line parameters for CSAPI32
systemname 	*DEFAULT
interactive 	NO
showduplicates 	YES
usefilter 	NO

; List of different unique screen text
screenname1	{Sample Screen 1}
screenname2	{Sample Screen 2}

; Maximum of unique screens the READSCRN macro is expected to deal with
; *It is important that this is updated to reflect the actual number of
; screens because READSCRN will not look for more than the number of unique
; screens given here.*
; 
maxscreens	2

; Parameters for screename1
; First the location for the unique text
scr1_name_r	0
scr1_name_c	0
scr1_name_l	0

; Spylink name
scr1_spylnk	INVOICES

; Filter screen coordinates - screename1.
; Replace the 0's with actual numbers for your application.
scr1_fltr1_r	0
scr1_fltr1_c	0
scr1_fltr1_l	0
scr1_fltr2_r	0
scr1_fltr2_c	0
scr1_fltr2_l	0
scr1_fltr3_r	0
scr1_fltr3_c	0
scr1_fltr3_l	0
scr1_fltr4_r	0
scr1_fltr4_c	0
scr1_fltr4_l	0
scr1_fltr5_r	0
scr1_fltr5_c	0
scr1_fltr5_l	0
scr1_fltr6_r	0
scr1_fltr6_c	0
scr1_fltr6_l	0
scr1_fltr7_r	0
scr1_fltr7_c	0
scr1_fltr7_l	0

; Parameters for screename2
; First the location for the unique text
scr2_name_r	0
scr2_name_c	0
scr2_name_l	0

; Spylink name
scr2_spylnk	BILLING

; Filter screen coordinates - screename2
scr2_fltr1_r	0
scr2_fltr1_c	0
scr2_fltr1_l	0
scr2_fltr2_r	0
scr2_fltr2_c	0
scr2_fltr2_l	0
scr2_fltr3_r	0
scr2_fltr3_c	0
scr2_fltr3_l	0
scr2_fltr4_r	0
scr2_fltr4_c	0
scr2_fltr4_l	0
scr2_fltr5_r	0
scr2_fltr5_c	0
scr2_fltr5_l	0
scr2_fltr6_r	0
scr2_fltr6_c	0
scr2_fltr6_l	0
scr2_fltr7_r	0
scr2_fltr7_c	0
scr2_fltr7_l	0

; <end SCRP.CFG>
