home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume43 / prg / part01 next >
Internet Message Format  |  1994-06-10  |  79KB

  1. From: patsch@ubka.uni-karlsruhe.de (Patrick Dockhorn)
  2. Newsgroups: comp.sources.misc
  3. Subject: v43i032:  prg - PostScript report generator V1.1, Part01/06
  4. Date: 10 Jun 1994 10:22:15 -0500
  5. Organization: University of Karlsruhe, Germany
  6. Sender: kent@sparky.sterling.com
  7. Approved: kent@sparky.sterling.com
  8. Message-ID: <csm-v43i032=prg.102120@sparky.sterling.com>
  9. X-Md4-Signature: 25fd09f064b48b1e6f3f6fce494ac994
  10.  
  11. Submitted-by: patsch@ubka.uni-karlsruhe.de (Patrick Dockhorn)
  12. Posting-number: Volume 43, Issue 32
  13. Archive-name: prg/part01
  14. Environment: postscript, UNIX
  15.  
  16. WHAT IS PRG ?
  17.  
  18. prg is a PostScript report generator based on generic input data.  The
  19. data consists of two parts: A description file and a data file.  The
  20. first file describes the logical structure of the data file.
  21.  
  22. prg can be used to manage all kinds of data, like your personal phone
  23. book, addresses, books, music cassettes and so on. Once you've entered
  24. your data you can create reports that contain an arbitrary combination
  25. of fields from your data and you may sort them by whatever keys you
  26. want.  You may also retrieve only a subset of the records stored in
  27. the data file; prg contains a parser for simple selection expressions
  28. to support this.
  29.  
  30. PRG runs in a UNIX environment; it only requires standard-tools
  31. (awk, shell...), there's no need for any compiler.
  32.  
  33. WHAT'S NEW IN RELEASE 1.1 :
  34.  
  35. 1. MAJOR NEW FEATURES
  36.  
  37. 1.1. SELECTORS ADDED:
  38.  
  39.      It is now possible to print a report of a selection of records only.
  40.      The selection is implemented as an expression that is parsed at
  41.      runtime to determine whether a record qualifies for a report or not.
  42.      See the new SELECTION section in the OnLine-Documentation and the
  43.      manual page for details.
  44.  
  45. 1.2. ONLINE-HELP:
  46.      You may now query prg for the meaning of any of its parameters using
  47.      the '-info yourOption' option, i.e.
  48.      prg -info -select
  49.      shows you information about the '-select' option.
  50.  
  51. 1.3. SUPPORTING LARGE DATA FILES
  52.      The PostScript code has been rewritten in order to support arbitrary
  53.      large data files.
  54.  
  55.  
  56. 2. MINOR NEW FEATURES
  57.  
  58. 2.1. Time-Field allows seconds to be used if field data is preceeded by 's'
  59.  
  60. 2.2. If you want hash characters in your strings replace them by '\hash'
  61.  
  62. 2.3. If a column has the same contents for two succeeding rows i and i+1
  63.      you may want to use the option '-noDuplicates' to avoid the repetitive
  64.      printing of this identical contents.
  65.  
  66. 2.4. If the contents of the first column change, a delimiting horizontal
  67.      line is drawn between these two rows.
  68.  
  69. 2.5. Enhanced handling of time fields (option '-accuracy' added).
  70.  
  71. 2.6. The command line used to produce the program now appears on the
  72.      title page.
  73.  
  74.  
  75. WHERE TO GET IT:
  76.  
  77. The new release 1.1 is currently available from the ftp site
  78.  
  79. ftp.ubka.uni-karlsruhe.de
  80.  
  81. in the directory
  82.  
  83. /pub/prg
  84.  
  85. Get the file prg-1.1.tar.gz using binary transfer mode.
  86.  
  87. If you have any comments, find bugs etc., drop me a line.
  88.  
  89.  -patsch
  90.  
  91.  --
  92. Patrick Dockhorn \ Uni-Bibliothek \ Kaiserstrasse 12 \ 76131 Karlsruhe \
  93. \ e-mail: patsch@ubka.uni-karlsruhe.de,finger=ubkaaix3\ Germany  __o    \
  94.  \  There are two rules for success in life:           \       _`\<,_    \ 
  95.   \   Rule 1: Don't tell people everything you know.    \     (_)/ (_)    \
  96. ------------
  97. #! /bin/sh
  98. # This is a shell archive.  Remove anything before this line, then feed it
  99. # into a shell via "sh file" or similar.  To overwrite existing files,
  100. # type "sh file -c".
  101. # Contents:  prg prg/INDEX prg/data prg/doc prg/lib prg/man prg/prg
  102. # Wrapped by kent@sparky on Thu Jun  9 12:32:32 1994
  103. PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin:$PATH ; export PATH
  104. echo If this archive is complete, you will see the following message:
  105. echo '          "shar: End of archive 1 (of 6)."'
  106. if test ! -d 'prg' ; then
  107.     echo shar: Creating directory \"'prg'\"
  108.     mkdir 'prg'
  109. fi
  110. if test -f 'prg/INDEX' -a "${1}" != "-c" ; then 
  111.   echo shar: Will not clobber existing file \"'prg/INDEX'\"
  112. else
  113.   echo shar: Extracting \"'prg/INDEX'\" \(949 characters\)
  114.   sed "s/^X//" >'prg/INDEX' <<'END_OF_FILE'
  115. XINDEX - List of files contained in the 'prg' distribution:
  116. X----------------------------------------------------------
  117. X
  118. XINDEX        This file
  119. XINSTALL        Notes on how to install prg on your system
  120. XREADME        Introduction to prg
  121. Xprg        patsch's PostScript report generator, shell script
  122. X
  123. Xdata/videos    Example data, movie collection on video tapes
  124. Xdata/videos.des Description file for the movie collection
  125. X
  126. Xdoc/prg.1.ps    Manual page in PostScript format
  127. Xdoc/prg.5.ps    Manual page for the prg file format in PostScript
  128. Xdoc/videos-by-actors.ps        Sample report, see EXAMPLES section
  129. Xdoc/videos-by-length.ps        Sample report, see EXAMPLES section
  130. Xdoc/videos-by-number.ps        Sample report, see EXAMPLES section
  131. X
  132. Xlib/prg.awk    AWK program that does most of the extraction work
  133. Xlib/prg.sed    SED skript that provides for the correct representation
  134. X        of german umlauts
  135. X
  136. Xman/prg.1    Manual page for the PostScript report generator
  137. Xman/prg.5    Manual page for the data files related to prg
  138. X
  139. END_OF_FILE
  140.   if test 949 -ne `wc -c <'prg/INDEX'`; then
  141.     echo shar: \"'prg/INDEX'\" unpacked with wrong size!
  142.   fi
  143.   # end of 'prg/INDEX'
  144. fi
  145. if test ! -d 'prg/data' ; then
  146.     echo shar: Creating directory \"'prg/data'\"
  147.     mkdir 'prg/data'
  148. fi
  149. if test ! -d 'prg/doc' ; then
  150.     echo shar: Creating directory \"'prg/doc'\"
  151.     mkdir 'prg/doc'
  152. fi
  153. if test ! -d 'prg/lib' ; then
  154.     echo shar: Creating directory \"'prg/lib'\"
  155.     mkdir 'prg/lib'
  156. fi
  157. if test ! -d 'prg/man' ; then
  158.     echo shar: Creating directory \"'prg/man'\"
  159.     mkdir 'prg/man'
  160. fi
  161. if test -f 'prg/prg' -a "${1}" != "-c" ; then 
  162.   echo shar: Will not clobber existing file \"'prg/prg'\"
  163. else
  164.   echo shar: Extracting \"'prg/prg'\" \(70190 characters\)
  165.   sed "s/^X//" >'prg/prg' <<'END_OF_FILE'
  166. X#!/bin/sh
  167. X
  168. X############################################################
  169. X#                                                          #
  170. X# prg  - PostScript Report Generator                       #
  171. X#        Creates a PostScript report of my videos or       #
  172. X#        anything else defined by a description and        #
  173. X#        a data file in the prg format.                    #
  174. X#                                                          #
  175. X#        Written in late May 1994 by patsch.               #
  176. X#                                                          #
  177. X#        To get an idea about what prg can do, try the     #
  178. X#        example database provided.                        #
  179. X#                                                          #
  180. X#        Further information about the program can be      #
  181. X#        found in the manual page provided, or by          #
  182. X#        supplying one of the following options:           #
  183. X#        -help                                             #
  184. X#        -info guide                                       #
  185. X#        -info options                                     #
  186. X#        -info usage                                       #
  187. X#        -info files                                       #
  188. X#                                                          #
  189. X#                                                          #
  190. X#        The main part of the shell skript can be found    #
  191. X#        by searching for 'prgmain'.                       #
  192. X#                                                          #
  193. X#   !---------------------------------------------------!  #
  194. X#   !                                                   !  #
  195. X#   !        Copyright (C) 1994, Patrick Dockhorn.      !  #
  196. X#   !                                                   !  #
  197. X#   !   Permission to use and modify this software and  !  #
  198. X#   !   its documentation for any purpose other than    !  #
  199. X#   !   its incorporation into a commercial product is  !  #
  200. X#   !   hereby granted without fee.  Permission to copy !  #
  201. X#   !   and distribute this software and its            !  #
  202. X#   !   documentation only for non-commercial use is    !  #
  203. X#   !   also granted without fee, provided, however,    !  #
  204. X#   !   that the above copyright notice appear in all   !  #
  205. X#   !   copies, that both that copyright notice and     !  #
  206. X#   !   this permission notice appear in supporting     !  #
  207. X#   !   documentation. The author makes no              !  #
  208. X#   !   representations about the suitability of this   !  #
  209. X#   !   software for any purpose. It is provided        !  #
  210. X#   !   ``as is'' without express or implied warranty.  !  #
  211. X#   !                                                   !  #
  212. X#   !---------------------------------------------------!  #
  213. X#                                                          #
  214. X############################################################
  215. X
  216. X
  217. X
  218. X##################################################################
  219. X#
  220. X# CONFIGURATION: PLEASE ADJUST THESE VARIABLES TO YOUR NEEDS
  221. X#
  222. X#
  223. X
  224. X# define your awk program here
  225. XAWK=awk
  226. X
  227. X# Path where the awk and sed programs that prg requires are located
  228. XPRGLIBPATH=./lib
  229. X
  230. X# Path with the data and description files
  231. XPRGDATAPATH=./data
  232. X
  233. X# Path for temporary files, you need write access there !
  234. XTMPDIR=.
  235. X
  236. X#
  237. X# DEFAULT VALUES FOR THE COMMAND LINE OPTIONS
  238. X#
  239. X
  240. X# data and description file
  241. XINFILE=${PRGDATAPATH}/videos
  242. XDESFILE=${PRGDATAPATH}/videos.des
  243. X
  244. XFONTNAME=AvantGarde-Book
  245. XFONTSIZE=12
  246. X
  247. X# Active output columns
  248. XFORMAT=NUM#IDX#TIT#ACT#CAT#LEN#OFF
  249. X
  250. X# Sort keys
  251. XSORTBY=NUM#IDX
  252. X
  253. X# Default: Select all
  254. X# Use
  255. X# -select 'TIT=="Michae*"'
  256. X# to select only those entries where the TIT field
  257. X# starts with Michae
  258. X# See the manual page or the online docu for the
  259. X# exact specification of a selector.
  260. XSELECT=""
  261. X
  262. X# title of the report
  263. XTITLE="Videoliste"
  264. X
  265. X# AWK debugging is off
  266. XDEBUG=0
  267. X
  268. X# AWK expression debugging is off
  269. XDEBUGEXPR=0
  270. X
  271. X# PostScript debugging is off as well
  272. XDEBUG_PS="false"
  273. X
  274. X# Optimization is on by default
  275. XOPTIMIZE="true"
  276. X
  277. X# delimiter string
  278. XDELIMITER=", "
  279. X
  280. X# by default the title is default
  281. XSHOWTITLE="true"
  282. X
  283. X# default unit is cm, 
  284. X# therefore this is the multiplication factor for points
  285. XUNIT=28.346456
  286. X
  287. X# comparison for sorting is not case sensitive by default
  288. XCASECOMP=0
  289. X
  290. X# print in portrait or landscape mode ?
  291. XLANDSCAPE="false"
  292. X
  293. X# Width and Height of the physical page
  294. X# The defaults represent DIN A4.
  295. X
  296. XPAGEWIDTH="21.0 cm"
  297. XPAGEHEIGHT="29.7 cm"
  298. X
  299. X# security offset from left and bottom margin
  300. X# to prevent any objects from being invisible
  301. X# due to the printers lack of displaying them
  302. X# in extreme positions
  303. X
  304. XHOFF="1.2 cm"    # horizontal skip (used with left AND right margins)
  305. XVOFF="1.2 cm"   # vertical skip (used with top AND bottom margins)
  306. X
  307. X# If you attempt to print large amounts of data
  308. X# the input has to be split into smaller chunks
  309. X# in order to avoid a memory overflow in your
  310. X# PostScript printer/interpreter.
  311. X# If you encounter this problem please
  312. X# decrease the value of the following variable.
  313. X# It represents the maximum number of elements
  314. X# an array within prg's PostScript engine may contain
  315. X
  316. XMAXARRAYSIZE=256
  317. X
  318. X# Default value for 'remove duplicate values in succeeding rows'
  319. XNODUPLS="false"
  320. X
  321. X# Specify the accuracy of time fields.
  322. X# Possible values are: seconds, minutes or hours
  323. XACCURACY="seconds"
  324. X
  325. X# Compare By Sorting Criteria
  326. X# If this flag is set, comparison for
  327. X# string equality (during the selection)
  328. X# is based on the entry as it is used for the
  329. X# sorting process, i.e. with CBSC=1
  330. X# (ACT == H*) would find the entry Anthony$Hopkins,
  331. X# whereas with CBSC=0 it would not. It would
  332. X# then for example find Harold$Ramis.
  333. XCBSC=1
  334. X
  335. X# END OF CONFIGURABLE PART
  336. X#
  337. X###################################################################
  338. X
  339. X##################################################################
  340. X#
  341. X# functions
  342. X#
  343. X##################################################################
  344. X
  345. X
  346. XHelp()
  347. X{
  348. X cat << END_OF_INTENTION
  349. X
  350. Xprg is a PostScript report generator based on generic input data.
  351. XThe data consists of two parts: A description file and a data file.
  352. XThe first file describes the logical structure of the data file.
  353. X
  354. Xprg was written originally to manage a collection of video tapes and
  355. Xthis is where some of the 'specials', like the automatic computation
  356. Xof offsets on tapes stems from. If you don't need those features,
  357. Xsimply don't use them.
  358. X
  359. Xprg can be used to manage all kinds of data, like your personal phone
  360. Xbook, addresses, books, music cassettes and so on. Once you've entered
  361. Xyour data you can create reports that contain an arbitrary combination
  362. Xof fields from your data and you may sort them by whatever keys you want.
  363. X
  364. XDetails about prg's command line options are displayed when giving the
  365. X'-info usage' option. General hints about how to use the program are
  366. Xshown with the '-info guide' option, the format of the description and
  367. Xdata file are explained in detail when supplying the '-info files' option.
  368. X
  369. Xhave fun,                               If you have any comments, find bugs
  370. X  patsch                                or would like to add a feature,
  371. X   patsch@ubka.uni-karlsruhe.de         please let me know !
  372. X
  373. XEND_OF_INTENTION
  374. X}
  375. X
  376. XInfoGuide()
  377. X{
  378. Xcat << END_OF_GUIDE
  379. X
  380. X0. GETTING STARTED
  381. X
  382. XTake a look at the example files containing a video tape collection.
  383. XYou may create a number of different reports by slightly varying the
  384. Xparameters to prg. For example you might want to try:
  385. X
  386. Xprg videos -format ACT#TIT#NUM#IDX#DIR -sortby ACT#TIT
  387. X
  388. XThis creates a report sorted by the actors appearing in the videos.
  389. XIf an actor appears in several movies, the entries are sorted using
  390. Xthe movie titles.
  391. X
  392. XThe report contains the fields specified with the -format option.
  393. XIf you take a look at the description file you'll see that they
  394. Xcorrespond to Actors, Titles, the internal number of the video tape,
  395. Xthe index of the movie on the specific tape and the director.
  396. XAs the actor appears as a sort key, only one actor is shown in the
  397. Xactor column.
  398. X
  399. XLet's try something else. We'll create a report of all the movies
  400. Xsorted by number and index, i.e. a 'natural sort'. I'd like to see
  401. Xa maximum of two actors as well as the title and the length of the
  402. Xmovie. This file is created by
  403. X
  404. Xprg videos -format NUM#IDX#ACT-2#TIT#LEN -sortby NUM#IDX
  405. X
  406. XAs the NUM and IDX fields have the 'numeric' attribute, their contents
  407. Xare shown justified to the right. We might as well get a list of all
  408. Xthe movies with the longest movie first:
  409. X
  410. Xprg videos -format NUM#IDX#ACT-2#TIT#LEN -sortby -LEN
  411. X
  412. XNote the dash in front of the sort key, this indicates a reverse sort.
  413. X
  414. XNow that you got an idea of how prg works and what it can do, you might
  415. Xwant to read the additional documentation in the following sections.
  416. X
  417. X------------------------------------------------------------------
  418. X1. FILES
  419. X------------------------------------------------------------------
  420. X
  421. X1.0  PROGRAMS
  422. X
  423. Xprg runs in a UNIX environment. It requires a number of standard
  424. XUNIX tools to be present, otherwise it won't work.
  425. XMost of these tools are available for other operating systems,
  426. Xe.g. OS/2, as well, therefore you will be able to use prg with
  427. Xthis operating systems as well.
  428. XThe tools required are awk (or nawk or gawk), sed, cat, sort,
  429. Xwc, basename, split and the bourne shell.
  430. X
  431. X1.1. INPUT FILES
  432. X
  433. Xprg looks for its input files, i.e. the description file and the data
  434. Xfile, in the directory specified by PRGDATAPATH. This setting is
  435. Xoverwritten if you specify another directory using the '-datapath
  436. Xyour-data-directory' option on the command line.  If the data file is
  437. Xnot found there, prg looks for it in the current working directory. If
  438. Xit still fails to locate the data file, it bails out.  The description
  439. Xfile name is built from the data file name by appending ".des"
  440. XInformation about the format of the data and description file can be
  441. Xobtained by specifying the '-info files' option.
  442. X
  443. X1.2. LIBRARY FILES
  444. X
  445. Xprg requires two library files to work. The first is an awk program
  446. Xthat does the whole job of extracting the requested information and
  447. Xfiddling it into an array that serves as an input to the PostScript
  448. Xprogram. The second is a small sed program used to convert various
  449. XUmlauts into their corresponding PostScript codes. This sed program
  450. Xcan easily be extended to provided support for other languages as
  451. Xwell. At the moment the German umlauts are supported. They may be
  452. Xentered in LaTeX style as well as ISO Latin1 umlauts.  prg searches
  453. Xfor this library files in the path given by the variable PRGLIBPATH.
  454. XYou may override this setting by specifying another directory through
  455. Xthe command line option '-libpath your-directory'.
  456. X
  457. X1.3. OUTPUT FILE
  458. X
  459. Xprg always creates a PostScript file that, if sent to a PostScript
  460. Xprinter, produces a formatted report of your data. This output file
  461. Xis *ALWAYS* written into your current working directory, regardless
  462. Xof the actual location of your data and library files.
  463. X
  464. X1.4 TEMPORARY FILES
  465. X
  466. Xprg creates a number of temporary files. These files are written into
  467. Xthe directory you specify with the TMPDIR variable in the configuration
  468. Xpart of prg. It is important that TMPDIR points to a directory where
  469. Xyou have both read and write permission.
  470. X
  471. X------------------------------------------------------------------
  472. X2. THE FORMAT SPECIFIER
  473. X------------------------------------------------------------------
  474. X
  475. XWith prg you can select arbitrary members of your records to be
  476. Xincluded in the output. You simply concatenate the individual
  477. Xcolumn identifiers with a '#' character.
  478. XLet's suppose you have defined a field ACT in your description file
  479. X(like the actor field in the example movie collection).
  480. X
  481. XIf you specify this field in the format string, the corresponding data
  482. Xis included in the report, usually in a column that is wide enough to
  483. Xtake all the data present. This is something not desired, as you may
  484. Xhave multiple entries within one field - as in the example. You may
  485. Xspecify more than one actor in the ACT field of your records. If ACT
  486. Xis a sort key as well, this doesn't pose a problem, as only the
  487. Xcurrent sort key is displayed in the actor's column then. However, if
  488. Xyou use another field as the sort key, you may want to see all the
  489. Xactors you specified, causing the column to become *really* wide. By
  490. Xdefault, only one element of a field that may contain more than one
  491. Xelement is displayed - with the exception of a field of type
  492. X'weightened selection'. With a weightened selection (like the
  493. X'Category' field in the video collection) shortcuts for all the
  494. Xpossible selections are displayed. If you want to see more than one
  495. Xelement of a field holding several entries, you can specify the number
  496. Xof desired entries by supplying a trailing dash followed by the
  497. Xmaximum number of hits you would like to see.
  498. X
  499. XInstead of
  500. X
  501. Xprg -format ACT
  502. X
  503. Xyou write
  504. X
  505. Xprg -format ACT-3
  506. X
  507. XThen up to three actors would be displayed in the actors column,
  508. Xdelimited by the standard delimiter, which you may want to change
  509. Xeither in the configuration section of prg or by supplying the command
  510. Xline option '-delimiter'.
  511. X
  512. XSometimes it may be necessary to neglect the optimized sizes prg
  513. Xcomputes for you. It is therefore possible to specify for each
  514. Xselected column the size of the column. Such a manual setting of a
  515. Xcolumn's width always overrides the computed width, thus you can set
  516. Xthe size of one column by hand while prg computes all the others in a
  517. Xway that the resulting output still fits onto the paper. If you wanted
  518. Xto restrict the size of the actor's column to 2 centimeter, you would
  519. Xspecify
  520. X
  521. Xprg -format ACT:2#TIT#NUM#IDX 
  522. X
  523. XIn this example the actor's column came out exactly 2 centimeters
  524. Xwide, while all the others would be computed such that they would fit
  525. Xonto the page. You may freely mix the width specifier ':' and the
  526. Xfield multiplicity specifier '-'.
  527. X
  528. XNote that prg never allows two columns to overwrite each other, as the
  529. Xoutput within a column is always clipped to the boundaries of that
  530. Xcolumn.  Therefore a column that's two small to hold all the data you
  531. Xwant it to hold still makes sense and does produce a nice output.
  532. X
  533. X
  534. X------------------------------------------------------------------
  535. X3. THE SORT KEYS
  536. X------------------------------------------------------------------
  537. X
  538. XYou specify the sort keys in the same way you do with the output
  539. Xcolumns, i.e. by concatenating an arbitrary number of column
  540. Xidentifiers with '#' characters, e.g.
  541. X
  542. X-sortby ACT#TIT
  543. X
  544. Xwould produce a report sorted by the contents of the ACT field.
  545. XIf the contents of two ACT fields are identical, then the TIT
  546. Xfields are used to identify the order of the two records.
  547. X
  548. XThe default is to order the entries ascending; if you want them
  549. Xto be sorted descending preceed the corresponding column identifier
  550. Xby a single dash, i.e.
  551. X
  552. X-sortby -ACT
  553. X
  554. Xproduces a report where the actors appear reverted, i.e. from Z to A.
  555. X
  556. XIf you specify a column representing a number or a time object, i.e.
  557. Xwith type 'N' or 'T', the sorting is based on the arithmetic value of
  558. Xthe columns rather than the characters.
  559. X
  560. X------------------------------------------------------------------
  561. X4. SELECTION MECHANISM
  562. X------------------------------------------------------------------
  563. X
  564. XFrom release 1.1 on, prg provides for a selection mechanism that
  565. Xallows you to select only a subset of the records defined in your
  566. Xdata file. The exact format of such a selector is the topic of
  567. Xthis section. Selectors *have* to be present in a separate file,
  568. Xas the simple parser expects spaces which are lost on the command line
  569. X(any idea on how to avoid this ?). You specify the selector with
  570. Xthe '-select filename' option. If you provide the filename 'stdin',
  571. Xyou are prompted for the selector.
  572. X
  573. XA selector is an expression as described by the following 'grammar':
  574. X
  575. XOPERATOR:   [ == | != | >= | <= | > | < | contains ]
  576. X
  577. XEXPRESSION: [ (FIELD-ID OPERATOR VALUE)         |    # simple test
  578. X
  579. X              EXPRESSION || EXPRESSION          |    # OR
  580. X
  581. X              EXPRESSION && EXPRESSION          |    # AND
  582. X
  583. X              (EXPRESSION)                      |    # forcing evaluation
  584. X
  585. X              !EXPRESSION                       ]    # negation
  586. X
  587. Xwhere FIELD-ID is one of the field identifiers you chose in your
  588. Xdescription file, i.e. TIT, ACT, LEN...  for the video data.
  589. X
  590. XVALUE is either a string or a numeric value; a string should be
  591. Xenclosed in double quotes.
  592. X
  593. XThe 'contains' operator is useful for fields that may hold multiple values.
  594. XIt checks whether the given values is at least present once in the field.
  595. X
  596. XHowever, if you specify a field with the Multi-Attribute 'M' as a sort key, 
  597. Xyou have to use the == operator; you may not use the contains operator.
  598. X
  599. X**********************************************************************
  600. XThe usage of this expressions should be intuitive; however take care
  601. Xto stick to the exact syntax. The expression parser isn't robust at
  602. Xall - you might even say that it's worse than lint as far as checking
  603. Xyour input is concerned. Don't put spaces before the first and after
  604. Xthe second operand; always surround the operator by spaces.
  605. X**********************************************************************
  606. X
  607. XYou may use the truncation character '*' to indicate that
  608. Xthe expression yields true if the current field contains a
  609. Xstring that's equal to the given value up to the asterisk;
  610. Xotherwise an exact match is performed. This special feature
  611. Xis available for the ==, != and contains operator.
  612. X
  613. XThe selection mechanism also interacts with the 
  614. X'-compareBySortingCriteria' or '-cbsc' option. It is useful
  615. Xto determine whether a selector should use the actual entry
  616. X(e.g. "Michael$Biehn") or the modified entry as it is printed
  617. Xand used for sorting, i.e. "Biehn, Michael".
  618. X
  619. XExamples for selectors:
  620. X
  621. X(TIT == "Terminator")    # selects all records where the TIT field
  622. X            # is Terminator
  623. X
  624. X(LEN > 120)             # selects all movies longer than 2 hours
  625. X
  626. X(ACT == "Michael*")     # all records with actors starting with Michael
  627. X                        # NOTE: This expression is valid iff ACT is a
  628. X                        #       a sort key. Otherwise you would have to
  629. X                        #       use the contains-operator
  630. X
  631. XAll sequels of the Terminator series with Arnie:
  632. X
  633. X(ACT == "Arnold*") && (TIT=="Terminat*")
  634. X
  635. XAnd finally a rather complex example.
  636. XNOTE: As long as you stick to the syntax, the recursive
  637. X      expression parser will eventually get the value for
  638. X      your expression. However, awk is an interpreter and
  639. X      this program is not optimized for speed, therefore
  640. X      complex operations will result in some delay...
  641. X
  642. X(((ACT == Wil*) && (DIR contains Mc*)) || (NUM == 2))
  643. X
  644. XThis means: Select all entries where
  645. Xa) the actor field (which has to be a sort key, otherwise == is not allowed!)
  646. X   contains a value starting with 'Wil' and the director field contains at least
  647. X   one value starting with 'Mc'
  648. Xor
  649. Xb) the NUM field has the value 2.
  650. X
  651. X------------------------------------------------------------------
  652. X5. SPECIALS
  653. X------------------------------------------------------------------
  654. X
  655. XThere is a column identifier OFF, which stands for Offset, that is
  656. Xuseful for the representation of any media like video tapes, cassette
  657. Xtapes and compact discs. Provided that the records contain a LEN entry
  658. Xof type 'T' (Time), the OFF entry of the record is automatically
  659. Xcomputed by adding up all the LEN entries before the current entry on
  660. Xthe current media. The media is identified by the NUM column whereas
  661. Xthe logical position of the entry is determined by the order it
  662. Xappears in the data file. This implies that, in order for the Offset
  663. Xvalue to be correct, the movies on one tape have to be *in order* in
  664. Xthe data file. I could have computed the correct offset value but this
  665. Xwould imply having another pass through the whole array and as it is a
  666. Xspecial anyway I thought that I might as well impose a rule on the
  667. Xdata order to get the accurate offset value. I summarize: You should
  668. Xnot specify a value for the OFF column in any record as it is computed
  669. Xautomatically. However you are free to use this column of type 'Time'
  670. Xin your reports by specifying it in the format string.
  671. X
  672. X------------------------------------------------------------------
  673. X6. ADDING SUPPORT FOR A NEW LANGUAGE
  674. X------------------------------------------------------------------
  675. X
  676. XIf you'd like to add support for a new language, i.e. special characters
  677. Xthat do not appear in the standard PostScript character encodings, you
  678. Xhave to do the following:
  679. X
  680. X- change the /germanvec vector which holds the modified encoding table
  681. X  for the german umlauts such that the available positions refer to the
  682. X  characters you'd like to see in the output. You need some knowledge
  683. X  of PostScript to do this.
  684. X- extend the sed skript prg.sed such that your national characters are
  685. X  replaced by the corresponding PostScript octal codes.
  686. X
  687. X------------------------------------------------------------------
  688. X7. KNOWN BUGS & NEW FEATURES
  689. X------------------------------------------------------------------
  690. X
  691. XI implemented the whole prg project in a couple of days and therefore
  692. Xthere'll be heaps of bugs and possibilities for improvevements -
  693. Xstarting with the bad english used in this documentation :-)
  694. X
  695. XIf you find a bug or would like to have a feature added or if you
  696. Xadded support for a new language (french umlauts etc.), please drop me
  697. Xa note and I'll incorporate your ideas into the next release of prg.
  698. X
  699. XSend your messages to patsch@ubka.uni-karlsruhe.de
  700. X
  701. XHave fun !
  702. X
  703. X  -patsch
  704. X
  705. XEND_OF_GUIDE
  706. X}
  707. X
  708. XInfoFiles()
  709. X{
  710. Xcat << END_OF_FILEINFO
  711. X
  712. XThere are two types of data files required to run prg -
  713. Xthe description file and the actual data file.
  714. XThe description file, as the name implies, describes
  715. Xthe format of the records in the data file. The data file
  716. Xitself contains an arbitrary number of records. The name of
  717. Xthe description file is always created by appending ".des"
  718. Xto the name of the data file.
  719. X
  720. X------------------------------------------------------------------
  721. X1. DESCRIPTION FILE
  722. X------------------------------------------------------------------
  723. X
  724. XI'll use an excerpt of the example, the video tape collection,
  725. Xto explain on how the description file is organized:
  726. X
  727. XBEGIN_DESCRIPTION
  728. XNUM#Nr.#N#O
  729. XIDX#Index#N#O
  730. XDIR#Director#A#M
  731. XPRO#Producer#A#M
  732. XACT#Actor#A#M
  733. XTIT#Title#A#O
  734. XLEN#Length#T#O
  735. XMOD#Record Mode#A#S#SP#LP
  736. XCAT#Categories#A#W#_C_omedy#_A_ction#_Science_Fiction#_T_hriller
  737. XEND_DESCRIPTION
  738. X
  739. X
  740. XThe generic format of the description file is as follows:
  741. XThe beginning of the description is identified by the keyword
  742. X
  743. XBEGIN_DESCRIPTION
  744. X
  745. XThe following field definition lines each describe one field (I also
  746. Xuse the word 'column' for a field) in the record.  The format for
  747. Xthese lines is:
  748. X
  749. XfieldIdentifier#fieldName#fieldType#fieldMultiplicity#selections...
  750. X
  751. XAt the end we have the keyword
  752. X
  753. XEND_DESCRIPTION
  754. X
  755. XLet's examine the column definition lines. They consists of a number
  756. Xof fields separated by a '#' character.
  757. X
  758. X1.1. fieldIdentifier
  759. X
  760. XThis is a string that you use to refer to the field within the format
  761. Xstring, where you specify which fields should appear in the report.
  762. XYou also use this shortcut within the specification of the sort keys.
  763. XThe length of the field identifier is not restricted to three characters.
  764. XHowever, the identifier should represent some sort of abbreviation for
  765. Xthe field name.
  766. X
  767. X1.2. fieldName
  768. X
  769. XThe field name is the title of the field as it appears on top of each
  770. Xpage when the column is printed. For example the field name of the
  771. Xfield identified by ACT is Actor.
  772. X
  773. X1.3. fieldType
  774. X
  775. XThe data contained in the ACT field is alphanumeric, i.e. a string
  776. Xcontaining characters and maybe numbers. I call this type 'A'.
  777. XHowever, the LEN field indicating the length of the movie in minutes
  778. Xis a numeric field, therefore it's field type is 'N'. This information
  779. Xis used in two ways: First, a numeric column is always justified to
  780. Xthe right when printed and second, the ordering of numeric data is
  781. Xbased on its arithmetic value rather than the characters its build
  782. Xfrom.  For example: Using the standard sorting method, the data 1, 2
  783. Xand 10 would be sorted into 1, 10, 2. If the corresponding column has
  784. Xnumeric type, an arithmetic comparison takes place and the order is 1,
  785. X2, 10.  There is a third possible field type identified by a
  786. X'T'. Objects of this type represent a time given in minutes. The
  787. Xdifference to the standard numeric type is that when printed, these
  788. Xminutes are always converted into hours and minutes. If you preceed
  789. Xa time value with an 's', it is assumed to be in seconds rather than 
  790. Xminutes.
  791. X
  792. XSummary of field types:
  793. X-------------------------------
  794. XA    text
  795. XN    numeric data
  796. XT    time in minutes or seconds
  797. X-------------------------------
  798. X
  799. X1.4. fieldMultiplicity
  800. X
  801. XUsually every field within a record contains exactly one datum,
  802. Xi.e. there is one title for a movie. Therefore the field multiplicity
  803. Xwould be one, represented by 'O'.
  804. X
  805. XIn a movie there appear a number of actors. In order to 'simulate'
  806. Xthis 1-to-N relation one field may contain any number of objects, as
  807. Xlong as the field multiplicity is set to 'M' for multiple.  If you
  808. Xspecify a column with field multiplicity 'M' as the sort key, all the
  809. Xentries in the field are used for sorting and the result is one line
  810. Xin the report for every entry in the field. On the other hand if you
  811. Xdon't use such a field for sorting you may specify how many of the
  812. Xentered objects you want to see within the field. They then appear
  813. Xconcatenated by a standard delimiter string.
  814. X
  815. XSometimes a field contains only a limited number of values.  E.g. the
  816. Xrecord mode in the video collection only takes the values SP for
  817. X'short play' and LP for 'long play'.  In this case the field
  818. Xmultiplicity is 'S' for selection. The only difference to a standard
  819. Xfield with multiple entries allows is that prg does a consistency
  820. Xcheck of your input, i.e. if you supply a datum that's not within the
  821. Xlist of possible selections it complains about it.
  822. X
  823. XFinally there are weightened selections. Suppose you have a number of
  824. Xcategories that a movie more or less matches. You might want to give
  825. Xyour personal marks to the movie with respect to this categories.
  826. XHaving a field multiplicity type 'W' provides support for this.
  827. XLike selections you specify all the categories you would like to
  828. Xsee, but you also include information on how to abbreviate these
  829. Xcategories. The definition for the 'Category' field in the video
  830. Xdescription file looks like this:
  831. X
  832. XCAT#Categories#A#W#_C_omedy#_A_ction#_Science_Fiction#_T_hriller
  833. X
  834. XNote the underscore (_) characters in the category names. The
  835. Xcharacters following the underscores are used to build the
  836. Xabbreviations that appear in the column title later on, i.e.
  837. Xthe title for the 'Categories' column looks like this:
  838. XCo Ac SF Th
  839. X
  840. X
  841. X---------------------------------------------------
  842. XSummary of field multiplicity:
  843. X---------------------------------------------------
  844. XO    only one entry allowed
  845. XM    multiple entries allowed
  846. XS    choice between a number of predefined values
  847. XW    a weight is assigned to a number of attributes
  848. X---------------------------------------------------
  849. X
  850. XNote: Some combinations of field type and field multiplicity are not
  851. Xsupported yet, i.e. a field of type 'T' is always supposed to have
  852. Xmultiplicity one.
  853. X
  854. X------------------------------------------------------------------
  855. X2. DATA FILE
  856. X------------------------------------------------------------------
  857. X
  858. XThe data file contains an arbitrary number of records. Each record
  859. Xmay define all the fields specified earlier in the description file.
  860. XIf a field is not specified, it is considered empty for that record.
  861. X
  862. XThe beginning of a record is identified by an empty line. Each line up
  863. Xto the next empty line is considered a definition line for this
  864. Xrecord. Let's take a look at a record definition from the movie
  865. Xcollection:
  866. X
  867. XNUM#2
  868. XIDX#0
  869. XDIR#John$McTiernan
  870. XACT#Bruce$Willis#Alan$Rickman#Alexander$Godunov
  871. XACT#Bonnie$Bedelia
  872. XTIT#Die Hard
  873. XLEN#125
  874. XMOD#SP
  875. XCAT#Ac3#Th2
  876. X
  877. XEach line starts with the field identifier followed by the field
  878. Xseparator, the '#' character. Then comes the data for the field.
  879. XFor simple fields like NUM, IDX or the title field this is just a
  880. Xnumber or a string. If the field may contain more than one entry,
  881. Xthese entries can be appended using even more '#' characters.
  882. XTake a look at the definition of the actors in the above example,
  883. Xwhere 4 actors are defined within two lines.
  884. X
  885. XOne important thing is the '$' character. It is used to determine
  886. Xthe correct sorting order of the entry. Specifying
  887. X
  888. XACT#Bruce Willis
  889. X
  890. Xcreates an entry that, as far as sorting is concerned, starts with a 'B'.
  891. X
  892. XACT#Bruce$Willis
  893. X
  894. Xhowever results in the internal sort key 'Willis, Bruce', i.e. the
  895. Xlast name comes first. This is very important when you enter names and
  896. Xstuff like that as most often you will prefer the second behaviour to
  897. Xthe first.
  898. X
  899. XThe second important thing is the specification of weightened selections.
  900. XThe values you may assign to the attributes are restricted to the digits
  901. X0 to 9. Thus you simply supply the abbreviation of the attribute followed
  902. Xby the weight, as in
  903. X
  904. XCAT#Act3#Th2
  905. X
  906. Xwhich means that I consider the movie 'Die Hard' to have 3 Action and
  907. X2 Thriller points.
  908. X
  909. XAs far as fields with type 'Time' are concerned: The time is always
  910. Xgiven in minutes there, but the output shows the time in hours and
  911. Xminutes.
  912. X
  913. XEND_OF_FILEINFO
  914. X}
  915. X
  916. XInfoUsage()
  917. X{
  918. X cat << END_OF_USAGE
  919. X
  920. XUsage: prg input-file [ -format ID1#ID2#...#IDn ] [ -sortby ID1#ID2#..#IDn]
  921. X           [ -select [ YourSelectorFile | stdin ] ]
  922. X           [ -fontName YourPostScriptFontName ] [ -fontSize YourFontSize ]
  923. X           [ -unit faktor ]
  924. X           [ -title YourTitle ] [ -showTitle flag ] [ -delimiter delimiter ]
  925. X           [ -debug ] [ -debugExpr ] [ -debugPS ] [ -optimize flag ]
  926. X           [ -help ][ -libpath prglibpath ] [ -datapath prgdatapath ]
  927. X           [ -info anyOptionShownHere ]
  928. X           [ -info options ] [ -info guide ] [ -info files ]
  929. X           [ -info usage ] [ -caseCompare flag ] [ -landscape ]
  930. X           [ -noDuplicates ] [ -compareBySortCriteria flag ]
  931. X           [ -accuracy specifier ]
  932. X
  933. XEND_OF_USAGE
  934. X}
  935. X
  936. XInfoOptions()
  937. X{
  938. X echo "------------------------------------------------------------------"
  939. X echo "SUMMARY OF OPTIONS"
  940. X echo "------------------------------------------------------------------"
  941. X echo "Use '-info your-option' to get information about a specific option,"
  942. X echo "e.g. '-info -format'"
  943. X echo "------------------------------------------------------------------"
  944. X
  945. X InfoUsage
  946. X InfoOption -format
  947. X InfoOption -sortby
  948. X InfoOption -select
  949. X InfoOption -fontName
  950. X InfoOption -unit
  951. X InfoOption -title
  952. X InfoOption -showTitle
  953. X InfoOption -delimiter
  954. X InfoOption -debug
  955. X InfoOption -debugExpr
  956. X InfoOption -debugPS
  957. X InfoOption -optimize
  958. X InfoOption -help
  959. X InfoOption -libpath
  960. X InfoOption -datapath
  961. X InfoOption -info
  962. X InfoOption -info options
  963. X InfoOption -info guide
  964. X InfoOption -info files
  965. X InfoOption -usage
  966. X InfoOption -caseCompare
  967. X InfoOption -landscape
  968. X InfoOption -noDuplicates
  969. X}
  970. X
  971. XInfoOption()
  972. X{
  973. X echo
  974. X echo -n "Information about the Option '"
  975. X echo -n $*
  976. X echo "' :"
  977. X echo
  978. X
  979. X case $1 in
  980. X -format | -f )
  981. X cat << EO_FORMAT
  982. XSelects the columns to be shown (in the given order)
  983. XYou may specify the desired width of a column by
  984. Xappending :WIDTH to the column name, where WIDTH
  985. Xis always in centimeter, i.e. having a column called ACT
  986. X
  987. X-format ACT:5.5
  988. X
  989. Xwill result in the ACT column being exactly 5.5 cm wide.
  990. X(The base unit can be changed using the '-unit' option).
  991. X
  992. XYou may also restrict the number of matches for multiple
  993. Xfields, i.e. fields that may hold more than one entry:
  994. X
  995. X-format ACT-3
  996. X
  997. Xwould restrict the number of ACTs to be displayed to 3.
  998. XBoth possibilities may be mixed.
  999. XThe default is ${FORMAT}
  1000. XEO_FORMAT
  1001. X    ;;
  1002. X   -fontsize | -fs )
  1003. Xcat << EO_FONTSIZE
  1004. XFont size to be used (ignored when optimization is active).
  1005. XDefault is ${FONTSIZE}.
  1006. XEO_FONTSIZE
  1007. X    ;;
  1008. X   -delimiter | -delim )
  1009. Xecho "Defines the delimiter string for fields with multiple entries."
  1010. X    ;;
  1011. X   -sortby | -sort | -s )
  1012. Xcat << EO_SORTBY
  1013. XSelects the key columns to be used for sorting. If you preceed
  1014. Xthe key with a single dash (-), the sort is done in reverse order.
  1015. XDefault is ${SORTBY}
  1016. XEO_SORTBY
  1017. X    ;;
  1018. X   -select | -sel )
  1019. Xcat << EO_SELECT
  1020. XSupplied filename contains the selection string. As this string
  1021. Xcontains spaces it can't be passed on the command line.
  1022. XIf you specify 'stdin' as the filename, you will be prompted for
  1023. Xthe selector.
  1024. X
  1025. XExamples for selectors:
  1026. X
  1027. X(TIT == "Terminator")    # selects all records where the TIT field
  1028. X            # is Terminator
  1029. X
  1030. X(LEN > 120)             # selects all movies longer than 2 hours
  1031. X
  1032. X(ACT == "Michael*")     # all records with actors starting with Michael
  1033. X                        # NOTE: This expression is valid iff ACT is a
  1034. X                        #       a sort key. Otherwise you would have to
  1035. X                        #       use the contains-operator
  1036. X
  1037. XAll sequels of the Terminator series with Arnie:
  1038. X(ACT == "Arnold*") && (TIT=="Terminat*")
  1039. X
  1040. XAnd:
  1041. X
  1042. X(((ACT == Wil*) && (DIR contains Mc*)) || (NUM == 2))
  1043. X
  1044. XThis means: Select all entries where
  1045. Xa) the actor field (which has to be a sort key, otherwise == is not allowed!)
  1046. X   contains a value starting with 'Wil' and the director field contains at least
  1047. X   one value starting with 'Mc'
  1048. Xor
  1049. Xb) the NUM field has the value 2.
  1050. X
  1051. XEO_SELECT
  1052. X    ;;
  1053. X   -unit | -u )
  1054. Xcat << EO_UNIT
  1055. XMultiplier for the width parameter of the format string.
  1056. XDefaults to ${UNIT}, i.e. width is given in centimeter.
  1057. XIf you set the unit parameter to 1, the width is in points,
  1058. Xthe standard PostScript unit.
  1059. XEO_UNIT
  1060. X    ;;
  1061. X   -libpath | -lib )
  1062. Xcat << EO_LIB
  1063. XSpecifies the path where the AWK and SED programs
  1064. X(prg.awk and prg.sed) are located. Default is ${PRGLIBPATH}
  1065. XEO_LIB
  1066. X    ;;
  1067. X   -datapath | -data )
  1068. Xcat << EO_DATA
  1069. XSpecifies the path where the data files for prg are located.
  1070. XDefault is ${PRGDATAPATH}.
  1071. XEO_DATA
  1072. X    ;;
  1073. X   -title | -t )
  1074. X    echo "Specify the title string of the report; default is \"${TITLE}\"."
  1075. X    ;;
  1076. X   -optimize | -opt )
  1077. Xcat << EO_OPTIMIZE
  1078. XBy default prg computes the width of the columns and the font
  1079. Xsize such that the fields you select in the format string fit
  1080. Xexactly into one line ouf the report. However, you might want
  1081. Xto adjust this settings manually. Specifying '-optimize 0' turns
  1082. Xthe optimization off completely. Note that you may also mix
  1083. Xoptimized size computation with your own specifications, as
  1084. Xany width information you supply in the format string always
  1085. Xoverrides the results from prg's own computation.
  1086. Xhave a default of '0' for the optimization, '-optimize 1'
  1087. Xturns optimization on again.
  1088. XEO_OPTIMIZE
  1089. X    ;;
  1090. X   -showTitle | -st )
  1091. X    echo "Should a title page be drawn ?"
  1092. X    echo "'-showTitle 1' enables the title page, '-showTitle 0' disables it."
  1093. X    ;;
  1094. X   -debug )
  1095. X    echo "Print debugging information while processing the data."
  1096. X    ;;
  1097. X   -debugExpr | -de )
  1098. X    echo "Enable debugging of the expression parser."
  1099. X    ;;
  1100. X   -debugPS | -dps )
  1101. X    echo "Activate debugging within the PostScript file created."
  1102. X    ;;
  1103. X   -caseCompare | -case )
  1104. Xcat << EO_CASECOMPARE
  1105. XIf you specify '-caseCompare 1' sorting is done with respect to the
  1106. Xcase of the characters. Given '-caseCompare 0' sorting is case insensitive.
  1107. XEO_CASECOMPARE
  1108. X    ;;
  1109. X   -help | -h )
  1110. X    echo "Displays some general notes about the program."
  1111. X    ;;
  1112. X   -info | -i )
  1113. X    if [ $# -eq 1 ]
  1114. X    then
  1115. X     cat << EO_INFO_INFO
  1116. XThe option '-info' has to be followed by either one of
  1117. Xoptions, guide, files or usage, or any possible option
  1118. Xof prg, i.e.
  1119. X
  1120. Xprg -info -select
  1121. X
  1122. Xshows information about the '-select' parameter.
  1123. X
  1124. XEO_INFO_INFO
  1125. X    else
  1126. X     case $2 in
  1127. X     options | o )
  1128. Xcat << EO_INFO_OPTIONS
  1129. XDisplays a list of prg's options and their meaning.
  1130. XEO_INFO_OPTIONS
  1131. X     ;;
  1132. X     guide | g )
  1133. Xcat << EO_INFO_GUIDE
  1134. XDisplays some notes on how to use the program, what can be
  1135. Xdone and how.
  1136. XEO_INFO_GUIDE
  1137. X     ;;
  1138. X     files | f )
  1139. Xcat << EO_INFO_FILES
  1140. XDisplays information about the structure of both the
  1141. Xdescription and data file.
  1142. XEO_INFO_FILES
  1143. X     ;;
  1144. X     * )
  1145. X     echo "Display information about the option \"$2\", if it exists."
  1146. X     ;;     
  1147. X    esac
  1148. X    fi
  1149. X    ;;
  1150. X   -landscape | -l )
  1151. Xcat << EO_LANDSCAPE
  1152. XProduces pages in landscape format instead of the default
  1153. Xportrait format.
  1154. XEO_LANDSCAPE
  1155. X    ;;
  1156. X   -noDuplicates | -nd )
  1157. Xcat << EO_NODUPLS
  1158. XIf column 0 has the same value for row i and row i+1, the
  1159. Xvalue in the first column is not displayed in row i+1 if this flag
  1160. Xis given. Exception: The first line of a new page.
  1161. XEO_NODUPLS
  1162. X    ;;
  1163. X   -accuracy | -acc )
  1164. Xcat << EO_ACCURACY
  1165. XSpecifies the accuracy used when printing time data.
  1166. XPossible arguments are seconds, minutes or hours.
  1167. X '-accuracy seconds' displays any time field in the
  1168. Xformat HH:MM:SS, or, if the HH field is 'empty', as MM:SS.
  1169. XIf you specify '-accuracy minutes', the format is HH:MM.
  1170. XUsing '-accuracy hours' results in the 'HH' format.
  1171. XEO_ACCURACY
  1172. X    ;;
  1173. X   -compareBySortingCriteria | -cbsc )
  1174. Xcat << EO_CBSC
  1175. XOther name for this option: -compareBySortCriteria
  1176. XIf this flag is set with '-cbsc 1', comparison of strings
  1177. X(during the selection) is based on the entry as it is used
  1178. Xfor the sorting process, rather than the physical characters.
  1179. XI.e. given '-cbsc 1', the selector
  1180. X(ACT == H*)
  1181. Xwould match the entry Anthony$Hopkins, as this entry is modified
  1182. Xto 'Hopkins, Anthony' for sorting, which starts with an 'H'.
  1183. XUsing the option '-cbsc 0' it would be possible to match, for
  1184. Xexample, Harold$Ramis.
  1185. XEO_CBSC
  1186. X    ;;
  1187. X   esac
  1188. X   echo
  1189. X}
  1190. X
  1191. XparseCommandLine()
  1192. X{
  1193. X for i
  1194. X do
  1195. X  ANY=0
  1196. X  if [ $XFORMAT -eq 1 ]; then FORMAT=$i; XFORMAT=0; ANY=1; fi
  1197. X  if [ $XSORTBY -eq 1 ]; then SORTBY=$i; XSORTBY=0; ANY=1; fi
  1198. X  if [ $XSELECT -eq 1 ]
  1199. X  then
  1200. X   if [ "$i" = "stdin" ]
  1201. X   then
  1202. X    echo "Please enter the expression you want me to use"
  1203. X    echo -n "to select records from your data : "
  1204. X    read SELECT
  1205. X    XSELECT=0
  1206. X    ANY=1
  1207. X   else
  1208. X    if [ -f $i ]
  1209. X    then
  1210. X     SELECT="`cat $i`"
  1211. X     XSELECT=0
  1212. X     ANY=1
  1213. X    else
  1214. X     echo
  1215. X     echo The file \"$i\" which is supposed to hold the
  1216. X     echo selector string could not be opened.
  1217. X     echo
  1218. X     exit
  1219. X    fi
  1220. X   fi
  1221. X  fi
  1222. X  if [ $XFONTNAME -eq 1 ]; then FONTNAME=$i; XFONTNAME=0; ANY=1; fi
  1223. X  if [ $XFONTSIZE -eq 1 ]; then FONTSIZE=$i; XFONTSIZE=0; ANY=1; fi
  1224. X  if [ $XDELIMITER -eq 1 ]; then DELIMITER="$i"; XDELIMITER=0; ANY=1; fi
  1225. X  if [ $XTITLE -eq 1 ]; then TITLE="$i"; XTITLE=0; ANY=1; fi
  1226. X  if [ $XACCURACY -eq 1 ]; then ACCURACY="$i"; XACCURACY=0; ANY=1; fi
  1227. X  if [ $XUNIT -eq 1 ]; then UNIT=$i; XUNIT=0; ANY=1; fi
  1228. X  if [ $XCASECOMP -eq 1 ]; then CASECOMP=$i; XCASECOMP=0; ANY=1; fi
  1229. X  if [ $XSHOWTITLE -eq 1 ]
  1230. X  then
  1231. X   if [ $i -eq 1 ]
  1232. X   then
  1233. X    SHOWTITLE="true"
  1234. X   else
  1235. X    SHOWTITLE="false"
  1236. X   fi
  1237. X   XSHOWTITLE=0
  1238. X   ANY=1
  1239. X  fi
  1240. X  if [ $XCBSC -eq 1 ]; then CBSC=$i; XCBSC=0; ANY=1; fi
  1241. X  if [ $XOPTIMIZE -eq 1 ]
  1242. X  then
  1243. X   if [ $i -eq 1 ]
  1244. X   then
  1245. X    OPTIMIZE="true"
  1246. X   else
  1247. X    OPTIMIZE="false"
  1248. X   fi
  1249. X   XOPTIMIZE=0
  1250. X   ANY=1
  1251. X  fi
  1252. X  if [ $XINFO -eq 1 ]
  1253. X  then
  1254. X   XINFO=0
  1255. X   case $i in
  1256. X   guide | g )
  1257. X    InfoGuide
  1258. X    exit
  1259. X    ;;
  1260. X   usage | u )
  1261. X    InfoUsage
  1262. X    exit
  1263. X    ;;
  1264. X   options | o )
  1265. X    InfoOptions
  1266. X    exit
  1267. X    ;;
  1268. X   files | f )
  1269. X    InfoFiles
  1270. X    exit
  1271. X    ;;
  1272. X    * )
  1273. X    InfoOption $i
  1274. X    exit
  1275. X    ;;
  1276. X   esac
  1277. X  fi
  1278. X  if [ $XLIBPATH -eq 1 ]; then PRGLIBPATH=$i; XLIBPATH=0; ANY=1; fi
  1279. X  if [ $XDATAPATH -eq 1 ]
  1280. X  then
  1281. X   PRGDATAPATH=$i
  1282. X   INFILE=${PRGDATAPATH}/`basename ${INFILE}`
  1283. X   DESFILE=${INFILE}.des
  1284. X   XDATAPATH=0
  1285. X   ANY=1
  1286. X  fi
  1287. X  case $i in
  1288. X   -format | -f )
  1289. X    XFORMAT=1;ANY=1
  1290. X    ;;
  1291. X   -fontsize | -fs )
  1292. X    XFONTSIZE=1;ANY=1
  1293. X    ;;
  1294. X   -delimiter | -delim )
  1295. X    XDELIMITER=1;ANY=1
  1296. X    ;;
  1297. X   -sortby | -sort | -s )
  1298. X    XSORTBY=1;ANY=1
  1299. X    ;;
  1300. X   -select | -sel )
  1301. X    XSELECT=1;ANY=1
  1302. X    ;;
  1303. X   -unit | -u )
  1304. X    XUNIT=1;ANY=1
  1305. X    ;;
  1306. X   -libpath | -lib )
  1307. X    XLIBPATH=1;ANY=1
  1308. X    ;;
  1309. X   -datapath | -data )
  1310. X    XDATAPATH=1; ANY=1
  1311. X    ;;
  1312. X   -title | -t )
  1313. X    XTITLE=1;ANY=1
  1314. X    ;;
  1315. X   -optimize | -opt )
  1316. X    XOPTIMIZE=1;ANY=1
  1317. X    ;;
  1318. X   -showTitle | -st )
  1319. X    XSHOWTITLE=1;ANY=1
  1320. X    ;;
  1321. X   -debug )
  1322. X    DEBUG=1;ANY=1
  1323. X    ;;
  1324. X   -debugExpr | -de )
  1325. X    DEBUGEXPR=1;ANY=1
  1326. X    ;;
  1327. X   -debug )
  1328. X    DEBUG=1;ANY=1
  1329. X    ;;
  1330. X   -debugPS | -dps )
  1331. X    DEBUG_PS="true";ANY=1
  1332. X    ;;
  1333. X   -caseCompare | -case )
  1334. X    XCASECOMP=1;ANY=1
  1335. X    ;;
  1336. X   -help | -h )
  1337. X    Help
  1338. X    exit
  1339. X    ;;
  1340. X   -info | -i )
  1341. X    XINFO=1;ANY=1
  1342. X    ;;
  1343. X   -landscape | -l )
  1344. X    LANDSCAPE="true";ANY=1
  1345. X    ;;
  1346. X   -keeptemp | -k )
  1347. X    KEEPTEMP=1;ANY=1
  1348. X    ;;
  1349. X   -noDuplicates | -nd )
  1350. X    NODUPLS="true";ANY=1
  1351. X    ;;
  1352. X   -accuracy | -acc )
  1353. X    XACCURACY=1;ANY=1
  1354. X    ;;
  1355. X   -compareBySortingCriteria | -cbsc )
  1356. X    XCBSC=1;ANY=1
  1357. X    ;;
  1358. X  esac
  1359. X  if [ $ANY -eq 0 ]
  1360. X  then
  1361. X   if [ $INFILESET -eq 1 ]
  1362. X   then
  1363. X    echo Input file has already been set to $INFILE
  1364. X    echo
  1365. X    InfoUsage
  1366. X    exit
  1367. X   fi
  1368. X   INFILESET=1
  1369. X   INFILE=${PRGDATAPATH}/$i
  1370. X   DESFILE=${INFILE}.des
  1371. X   TIFILE=`echo $i | sed 's/^-//g'`
  1372. X   if [ "$i" != "$TIFILE" ]
  1373. X   then
  1374. X    echo I guess you supplied an unknown parameter \"$i\"
  1375. X    echo
  1376. X    InfoUsage
  1377. X    exit
  1378. X   fi
  1379. X  fi
  1380. X done
  1381. X}
  1382. X
  1383. XinitVariables()
  1384. X{
  1385. X COMLINE="$*"
  1386. X # initizialize temporary variables
  1387. X XFORMAT=0
  1388. X XSORTBY=0
  1389. X XSELECT=0
  1390. X XFONTNAME=0
  1391. X XFONTSIZE=0
  1392. X XDELIMITER=0
  1393. X XOPTIMIZE=0
  1394. X XSHOWTITLE=0
  1395. X XCBSC=0
  1396. X XTITLE=0
  1397. X XACCURACY=0
  1398. X XUNIT=0
  1399. X XCASECOMP=0
  1400. X XINFO=0
  1401. X XLIBPATH=0
  1402. X XDATAPATH=0
  1403. X INFILESET=0
  1404. X # keep temporary files ?
  1405. X KEEPTEMP=0 
  1406. X # temporary files
  1407. X SORTFILENAME=${TMPDIR}/sort.sh
  1408. X TMPDATA=${TMPDIR}/data.tmp
  1409. X TMPHEADER=${TMPDIR}/header.tmp
  1410. X}
  1411. X
  1412. XcheckDataFiles()
  1413. X{
  1414. X if [ ! -f $INFILE ]
  1415. X then
  1416. X  doexit=1
  1417. X  echo The input file  \"$INFILE\" does not exist.
  1418. X  if [ $INFILE != `basename ${INFILE}` ]
  1419. X  then
  1420. X   INFILE=`basename $INFILE`
  1421. X   echo Trying the file $INFILE instead.
  1422. X   if [ ! -f $INFILE ]
  1423. X   then
  1424. X    echo The input file  \"$INFILE\" does not exist.
  1425. X   else
  1426. X    echo "Ok, I'll use the file ${INFILE}."
  1427. X    doexit=0
  1428. X    DESFILE=${INFILE}.des
  1429. X   fi
  1430. X  fi
  1431. X  if [ $doexit -eq 1 ]
  1432. X  then
  1433. X   exit
  1434. X  fi
  1435. X fi
  1436. X if [ ! -f $DESFILE ]
  1437. X then
  1438. X  echo Die Beschreibungsdatei \"$DESFILE\" zur Eingabedatei \"$INFILE\" existiert nicht.
  1439. X  exit
  1440. X fi
  1441. X /bin/rm -f $TMPDATA $TMPHEADER
  1442. X
  1443. X echo > $TMPHEADER
  1444. X echo "% HEADER ----------------------------------------------------------------" >> $TMPHEADER
  1445. X echo >> $TMPHEADER
  1446. X}
  1447. X
  1448. XcreatePostScriptFile()
  1449. X{
  1450. Xcat << END_OF_PS_HEADER > $PSFILE
  1451. X%!
  1452. X%%Creator: $USER on `hostname` using prg
  1453. X%%Title: ${TITLE}
  1454. X%%CreationDate: `date`
  1455. X%%DocumentFonts: ${FONTNAME}
  1456. X%%EndComments
  1457. X
  1458. X%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1459. X%                                                            %
  1460. X%   prg - patsch's PostScript report generator Release 1.1   %
  1461. X%                                                            %
  1462. X%         Copyright (C) 1994 Patrick Dockhorn                %
  1463. X% Permission to use and modify this software and its         %
  1464. X% documentation for any purpose other than its incorporation %
  1465. X% into a commercial product is hereby granted without fee.   %
  1466. X% Permission to copy and distribute this software and its    %
  1467. X% documentation only for non-commercial use is also granted  %
  1468. X% without fee, provided, however, that the above copyright   %
  1469. X% notice appear in all copies, that both that copyright      %
  1470. X% notice and this permission notice appear in supporting     %
  1471. X% documentation. The author makes no representations about   %
  1472. X% the suitability of this software for any purpose. It is    %
  1473. X% provided \`\`as is'' without express or implied warranty.    %
  1474. X%                                                            %
  1475. X%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1476. X
  1477. X%%EndProlog
  1478. X
  1479. X% recode font vector to enable foreign special characters
  1480. X% copied from PostScript cookbook
  1481. X
  1482. X/reencsmalldict 12 dict def
  1483. X/ReEncodeSmall
  1484. X{
  1485. X reencsmalldict begin
  1486. X /newcodesandnames exch def
  1487. X /newfontname exch def
  1488. X /basefontname exch def
  1489. X
  1490. X /basefontdict basefontname findfont def
  1491. X /newfont basefontdict maxlength dict def
  1492. X basefontdict
  1493. X {
  1494. X  exch dup /FID ne
  1495. X  {
  1496. X   dup /Encoding eq
  1497. X   { exch dup length array copy
  1498. X     newfont 3 1 roll put }
  1499. X   { exch newfont 3 1 roll put }
  1500. X   ifelse
  1501. X  }
  1502. X  { pop pop }
  1503. X  ifelse
  1504. X } forall
  1505. X
  1506. X newfont /FontName newfontname put
  1507. X newcodesandnames aload pop
  1508. X newcodesandnames length 2 idiv
  1509. X { newfont /Encoding get 3 1 roll put } repeat
  1510. X newfontname newfont definefont pop
  1511. X end
  1512. X} def
  1513. X
  1514. X% ------------------------------------------------------------------
  1515. X%
  1516. X% germanvec is an array that contains positions and character
  1517. X% names. The given characters, - they are usually not included
  1518. X% in the standard font encoding - are activated at the given
  1519. X% positions in the character set.
  1520. X% To use your own characters (i.e. /ccedilla, modify
  1521. X% the font vector accordingly.
  1522. X% The PostScript Language Reference contains the names
  1523. X% of characters available as well as a map of unused
  1524. X% regions in the standard text encoding.
  1525. X% The following octal regions can be used in a standard
  1526. X% text encoding without removing other characters:
  1527. X% \260, \300, \321-\341, \354-\360, \362-\364, \366-\367, \374-\376
  1528. X%
  1529. X% ------------------------------------------------------------------
  1530. X
  1531. X/germanvec [
  1532. X 8#300 /adieresis
  1533. X 8#311 /Adieresis
  1534. X 8#321 /odieresis 
  1535. X 8#322 /Odieresis
  1536. X 8#323 /udieresis
  1537. X 8#324 /Udieresis
  1538. X 8#325 /germandbls
  1539. X 8#326 /eacute
  1540. X 8#327 /egrave
  1541. X 8#330 /ecircumflex
  1542. X 8#331 /ccedilla
  1543. X 8#332 /otilde
  1544. X 8#333 /atilde
  1545. X 8#334 /ntilde
  1546. X 8#335 /copyright
  1547. X 8#336 /registered
  1548. X 8#337 /trademark
  1549. X 8#340 /Ccedilla
  1550. X 8#341 /aacute
  1551. X] def
  1552. X
  1553. X% ------------------------------------------------------------------
  1554. X%
  1555. X% - Umlaute - 
  1556. X%
  1557. X% Activate the new font encoding that includes foreign umlauts
  1558. X% for the font selected by the user by FONTNAME.
  1559. X%
  1560. X% ------------------------------------------------------------------
  1561. X
  1562. X/Umlaute
  1563. X{
  1564. X /${FONTNAME} /GermanFont germanvec ReEncodeSmall
  1565. X} def
  1566. X
  1567. X% ------------------------------------------------------------------
  1568. X%
  1569. X% (text) width clipshow -
  1570. X%
  1571. X% The given text is shown at the current point. Before the text
  1572. X% is displayed, a clip rectangle is placed around it with the
  1573. X% given width. This avoids overlapping text in adjacent columns.
  1574. X%
  1575. X% ------------------------------------------------------------------
  1576. X
  1577. X/clipshow
  1578. X{
  1579. X  gsave
  1580. X    newpath x0 1 add y0 1 add moveto 2 sub dup 0 rlineto 
  1581. X    0 lsize 2 sub rlineto neg 0 rlineto closepath clip
  1582. X    newpath x0 xboff add y0 descent add yboff add moveto show
  1583. X  grestore
  1584. X} def
  1585. X
  1586. X% ------------------------------------------------------------------
  1587. X%
  1588. X% prg-array optimizeColumns -
  1589. X%
  1590. X% optimizeColumns uses the given array of application specific data
  1591. X% to update its internal state as far as the maximum column width
  1592. X% required is concerned.
  1593. X%
  1594. X% ------------------------------------------------------------------
  1595. X
  1596. X/optimizeColumns
  1597. X{
  1598. X  % --------------------------------------------------------------------------
  1599. X  % use all the information given to compute optimal column widths & font size
  1600. X  % --------------------------------------------------------------------------
  1601. X  {
  1602. X    /elem exch def               % define current element
  1603. X    % (elem is) == elem ==
  1604. X    0 1 nColumns 1 sub              % loop through all columns
  1605. X    {
  1606. X      /i exch def
  1607. X      fieldMulti i get (W) eq
  1608. X      {
  1609. X    % Weightened Selection: Column Width is constant, i.e.
  1610. X    % compute only once
  1611. X    maxSizes i get 0 eq % not yet computed -> do it
  1612. X    {
  1613. X      /legend true def
  1614. X      /len 0 def
  1615. X      multiWeightSelTitles i get
  1616. X      {
  1617. X        stringwidth pop multiOff dup add add len add /len exch def
  1618. X      } forall % for all strings in the multi weight info array
  1619. X      % put information about the size of the field into the array
  1620. X      maxSizes i len put        
  1621. X    } if
  1622. X      }     % end if current column is weightened selection
  1623. X      {     % if current column is NOT a weightened selection
  1624. X    % simply compute the width of the given strings using
  1625. X    % their maximum multiplicity as given in /colMultiplicity
  1626. X    % the strings are concatenated using the delimiter string
  1627. X    /cnt 0 def  % counter for maximum multiplicity
  1628. X    /len xboff dup add def
  1629. X    /maxMultiplicity colMultiplicity i get def
  1630. X    elem i get
  1631. X    dup /nMultis exch length def
  1632. X    {
  1633. X      /len exch stringwidth pop len add
  1634. X      % should I append the delimiter ?
  1635. X      /cnt cnt 1 add def
  1636. X      cnt nMultis ne
  1637. X      cnt maxMultiplicity ne and
  1638. X      {
  1639. X        delimiter stringwidth pop add def
  1640. X      }
  1641. X      {
  1642. X        def exit
  1643. X      } ifelse
  1644. X    } forall
  1645. X    % if size exceeds maximum, store it
  1646. X    maxSizes i get len lt
  1647. X    {
  1648. X      maxSizes i len put
  1649. X    } if
  1650. X      } ifelse      % end if current column is *not* a weightened selection
  1651. X    } for           % for all selected columns
  1652. X  } forall  % end optimization loop through the input array
  1653. X} def
  1654. X
  1655. X% ------------------------------------------------------------------
  1656. X%
  1657. X% - postOptimization -
  1658. X%
  1659. X% Uses the information obtained from calling optimizeColumns
  1660. X% (several times, if the input data is too large)
  1661. X% and mixes it with field widths given by the user to compute
  1662. X% the new font size and applies the resulting scaling factor
  1663. X% to a number of internal parameters.
  1664. X%
  1665. X% ------------------------------------------------------------------
  1666. X
  1667. X/postOptimization
  1668. X{
  1669. X  0 1 nColumns 1 sub
  1670. X  {
  1671. X    /i exch def
  1672. X    colSizes i get -1 eq    % no size given -> use the computed size
  1673. X    {
  1674. X      colSizes i maxSizes i get put
  1675. X      debug 
  1676. X      { 
  1677. X    (\012 Computed width for column ') print colNames i get print 
  1678. X    (' to ) print colSizes i get 12 string cvs print
  1679. X      } if
  1680. X    }
  1681. X    {
  1682. X      debug
  1683. X      { 
  1684. X    (\012 Using specified width \() print colSizes i get
  1685. X    12 string cvs print ( points\) for column ') print
  1686. X    colNames i get print
  1687. X      } if
  1688. X    } ifelse
  1689. X  } for
  1690. X  0 colSizes { add } forall
  1691. X  /total exch def
  1692. X  /factor hspace total div def                      % scaling factor
  1693. X  /fsize fsize factor mul def
  1694. X  /GermanFont findfont fsize scalefont setfont
  1695. X  % update column size information
  1696. X  [ colSizes { factor mul } forall ] /colSizes exch def
  1697. X  /multiOff multiOff factor mul def
  1698. X
  1699. X  /sbbox 4 array def                   %% compute scaled bounding box
  1700. X  0 1 3
  1701. X  {
  1702. X    /i exch def
  1703. X    sbbox i bbox i get fsize mul 1000 div put
  1704. X  } for
  1705. X  
  1706. X  % size of one line, taking descent and font size into account
  1707. X  /lsize sbbox 3 get sbbox 1 get
  1708. X  sub yboff dup add add def    
  1709. X  
  1710. X  % current descent value, used to position the characters vertically
  1711. X  % within a line
  1712. X  /descent sbbox 1 get neg def        %% 0 is origin, lly is therefore negative descent
  1713. X  
  1714. X  debug { (\012 Descent set to ) print descent 10 string cvs print (\012) print } if
  1715. X  /nLines vspace lsize div cvi def    %% number of lines on one page according to line size
  1716. X  
  1717. X  % update available vertical space
  1718. X  /vspace nLines lsize mul def
  1719. X  
  1720. X  % compute expected number of pages
  1721. X  totalEntries nLines 1 sub idiv totalEntries nLines 1 sub mod 0 ne { 1 add } if
  1722. X  /nPages exch def
  1723. X  /nPagesStr nPages 10 string cvs def
  1724. X  
  1725. X  debug { (\012 Report will consist of ) print nLines 10 string cvs print ( lines per page.) print } if
  1726. X  debug { (\012 Optimization finished, using font size ) print fsize 10 string cvs print } if
  1727. X
  1728. X  % ------------------------------------------------------------------
  1729. X  % print title page
  1730. X  % ------------------------------------------------------------------
  1731. X  
  1732. X  showtitle
  1733. X  {
  1734. X    16 dict begin
  1735. X      top
  1736. X      newpath
  1737. X      gsave
  1738. X    0 0 moveto title true charpath pathbbox 
  1739. X    /tury exch def
  1740. X    /turx exch def
  1741. X    /tlly exch def
  1742. X    /tllx exch def
  1743. X    % the '18 sub' is to leave some space at the border for
  1744. X    % additional infos
  1745. X    newpath hspace 18 sub turx tllx sub div /sfak exch def
  1746. X    hspace 2 div vspace 2 div translate sfak sfak scale
  1747. X    tllx turx sub 2 div tlly tury sub 2 div moveto title show
  1748. X      grestore
  1749. X      % compute positions required for user name and sorting criteria
  1750. X      % debug { (\012 size of title string is ) print turx tllx sub 10 string cvs print } if
  1751. X      % debug { (\012 scaling factor is ) print sfak 10 string cvs print } if
  1752. X      /topoff vspace tury tlly sub sfak mul add 2 div yboff add lsize add def
  1753. X      /botoff sortFields length lsize mul def
  1754. X      userstr stringwidth pop ( presents) stringwidth pop add neg hspace add 2 div
  1755. X      topoff moveto userstr show ( presents) show
  1756. X      % display the sort keys
  1757. X      (Sorting Criteria:) stringwidth pop neg hspace add 2 div /scx exch def
  1758. X      scx botoff moveto (Sorting Criteria:) show
  1759. X      sortFields
  1760. X      {
  1761. X    /botoff botoff lsize sub def
  1762. X    scx botoff moveto show
  1763. X      } forall
  1764. X      % show date and page info
  1765. X      0 vspace lsize sub moveto datestr show
  1766. X      hspace timestr stringwidth pop sub vspace lsize sub moveto timestr show
  1767. X      0 0 moveto totalEntries 16 string cvs show ( lines) show
  1768. X      % display total number of pages
  1769. X      hspace ( pages) stringwidth pop sub 
  1770. X      nPagesStr stringwidth pop sub 0 moveto
  1771. X      nPagesStr show ( pages) show
  1772. X      gsave
  1773. X    /GermanFont findfont 6 scalefont setfont
  1774. X    gsave
  1775. X      0 vspace 2 div translate 90 rotate
  1776. X      commandLine dup stringwidth pop 2 div neg 0
  1777. X      moveto show
  1778. X    grestore
  1779. X    gsave
  1780. X      hspace vspace 2 div translate -90 rotate
  1781. X      (thanks for using patsch's PostScript Report Generator - (C) 1994 Patrick Dockhorn)
  1782. X      dup stringwidth pop 2 div neg 0
  1783. X      moveto show
  1784. X    grestore
  1785. X      grestore
  1786. X    end
  1787. X    showpage
  1788. X  } if
  1789. X  
  1790. X  % ------------------------------------------------------------------
  1791. X  % print legend if any weightened selection present
  1792. X  % ------------------------------------------------------------------
  1793. X  
  1794. X  legend
  1795. X  {
  1796. X    12 dict begin
  1797. X      top
  1798. X      /y0 vspace lsize sub def
  1799. X      newpath (Additional Information) dup
  1800. X      stringwidth pop neg
  1801. X      dup /tmpsw exch def
  1802. X      hspace add 2 div y0 moveto show
  1803. X      tmpsw 0 rlineto stroke
  1804. X      /y0 y0 lsize dup add sub def
  1805. X      /nhits 0 def
  1806. X      0 1 nColumns 1 sub
  1807. X      {
  1808. X    /i exch def
  1809. X    fieldMulti i get (W) eq
  1810. X    {
  1811. X      /ybuf y0 def
  1812. X      /nhits nhits 1 add def
  1813. X      nhits 2 mod 0 eq
  1814. X      {
  1815. X        /x0 hspace 2 div xboff add def
  1816. X      }
  1817. X      {
  1818. X        /x0 xboff def
  1819. X      } ifelse
  1820. X      newpath x0 y0 moveto (Explanation for column ') show
  1821. X      colNames i get show (' :) show
  1822. X      x0 y0 lineto stroke newpath
  1823. X      /mss 0 def
  1824. X      /scarr multiWeightSelTitles i get def
  1825. X      /ltarr multiWeightSelFullTitles i get def
  1826. X      scarr
  1827. X      {
  1828. X        stringwidth pop dup mss gt { /mss exch def } { pop } ifelse
  1829. X      } forall
  1830. X      
  1831. X      0 1 scarr length 1 sub
  1832. X      {
  1833. X        /j exch def
  1834. X        /y0 y0 lsize sub def
  1835. X        x0 y0 moveto scarr j get show
  1836. X        x0 mss add xboff dup add add y0 moveto ltarr j get show
  1837. X      } for
  1838. X      nhits 2 mod 0 eq
  1839. X      {
  1840. X        /y0 y0 lsize dup add sub def
  1841. X      }
  1842. X      {
  1843. X        /y0 ybuf def
  1844. X      } ifelse
  1845. X    } if
  1846. X      } for
  1847. X      showpage
  1848. X    end
  1849. X  } if
  1850. X} def
  1851. X
  1852. X
  1853. X% ------------------------------------------------------------------
  1854. X%
  1855. X% prg-array createReport -
  1856. X%
  1857. X% Prints the data given in prg-array (which is in a format specified
  1858. X% through the -format option) nicely formatted. Does all the pagebreak,
  1859. X% handling, rotation etc.
  1860. X%
  1861. X% ------------------------------------------------------------------
  1862. X
  1863. X/createReport
  1864. X{
  1865. X  % ------------------------------------------------------------------  
  1866. X  % handle all array elements
  1867. X  % ------------------------------------------------------------------  
  1868. X
  1869. X  {
  1870. X    /elem exch def          % define current element
  1871. X    line 0 eq                   % Top of page ?
  1872. X    {
  1873. X      top
  1874. X      /x0 0 def
  1875. X      /y0 vspace def              % start value for y
  1876. X      0 setlinewidth              % set line width for bounding box
  1877. X      newpath 0 0 moveto hspace 0 rlineto 0 vspace rlineto
  1878. X      hspace neg 0 rlineto closepath
  1879. X      /y0 y0 lsize sub def
  1880. X      0 y0 moveto hspace 0 rlineto stroke
  1881. X
  1882. X      gsave
  1883. X    /GermanFont findfont 6 scalefont setfont
  1884. X    newpath 0 vspace yboff add moveto title show delimiter show datestr show
  1885. X    newpath hspace (Page ) stringwidth pop sub page 1 add 10 string cvs /pagestr exch def
  1886. X    pagestr stringwidth pop sub ( / ) stringwidth pop sub nPagesStr stringwidth pop sub 
  1887. X    vspace yboff add moveto (Page ) show pagestr show ( / ) show nPagesStr show
  1888. X      grestore
  1889. X      
  1890. X      0 1 nColumns 1 sub
  1891. X      {
  1892. X    /i exch def
  1893. X    /cs colSizes i get def
  1894. X    debug
  1895. X    {
  1896. X      (\012 Column size for ') print colNames i get print (' is ) print
  1897. X      cs 10 string cvs print (\012) print
  1898. X    } if
  1899. X    
  1900. X    fieldMulti i get (W) eq       % multi-field -> special title
  1901. X    {
  1902. X      /xbuf x0 def
  1903. X      /j 0 def
  1904. X      /offArr colMultiOffsets i get def
  1905. X      % debug { (\012 offArr for column ) print colNames i get print ( is \012) print offArr == } if
  1906. X      /mwsl multiWeightSelTitles i get length def
  1907. X      multiWeightSelTitles i get
  1908. X      {
  1909. X        dup stringwidth pop /mssize exch def    % save string size
  1910. X        newpath x0 multiOff add y0 yboff add descent add moveto % position
  1911. X        show
  1912. X        offArr j x0 put    % save current x position
  1913. X        j 0 gt j mwsl ne and 
  1914. X        {
  1915. X          x0 y0 lsize add moveto 0 vspace neg 
  1916. X          rlineto stroke 
  1917. X        } if
  1918. X        /j j 1 add def
  1919. X        mssize multiOff dup add add
  1920. X        dup x0 add /x0 exch def
  1921. X        neg cs add /cs exch def
  1922. X      } forall
  1923. X      /x0 xbuf def
  1924. X      
  1925. X%           debug 
  1926. X%           { 
  1927. X%             (\012 Updated colMultiOffsets[) print i 10 string cvs print
  1928. X%               (] to the following offset array:\012) print offArr == 
  1929. X%           } if
  1930. X
  1931. X      colMultiOffsets i offArr put
  1932. X    }
  1933. X    {
  1934. X      colNames i get cs clipshow
  1935. X    } ifelse
  1936. X    i 0 gt { newpath x0 y0 lsize add moveto 0 vspace neg rlineto stroke } if
  1937. X    /x0 x0 colSizes i get add def
  1938. X      } for % end for all columns
  1939. X      debug { (\012 Multi-Column offset array:\012) print colMultiOffsets == } if
  1940. X      
  1941. X      /y0 y0 lsize sub def
  1942. X    } if % end if first line of page  
  1943. X    
  1944. X    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1945. X    %
  1946. X    % Standard Procedure for a single entry
  1947. X    %
  1948. X    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1949. X
  1950. X    newpath
  1951. X    /x0 0 def
  1952. X    0 1 nColumns 1 sub
  1953. X    {
  1954. X      /i exch def
  1955. X      fieldMulti i get (W) eq         % Weightened selection
  1956. X      {
  1957. X    /done false def
  1958. X    % debug { (\012 Handling multi field ') print colNames i get print ('\012) print } if
  1959. X    elem i get
  1960. X    {
  1961. X      % debug { (\012 Checking weightened selection ) print dup == } if
  1962. X      dup 1 get /val exch def
  1963. X      0 get /cat exch def
  1964. X      % search for the position of the category
  1965. X      /idx 0 def
  1966. X      multiWeightSelTitles i get
  1967. X      {
  1968. X        cat eq % category match -> show the corr. value
  1969. X        {
  1970. X          colMultiOffsets i get idx get multiOff add
  1971. X          cat stringwidth pop add val stringwidth pop sub
  1972. X          y0 yboff add descent add moveto val show
  1973. X          /done true def
  1974. X          exit
  1975. X        } if
  1976. X        /idx idx 1 add def
  1977. X      } forall
  1978. X      done { exit } if
  1979. X    } forall
  1980. X      }       % end if current column is weightened selection
  1981. X      {       % if current column is NOT a weightened selection
  1982. X    % simply compute the width of the given strings using
  1983. X    % their maximum multiplicity as given in /colMultiplicity
  1984. X    % the strings are concatenated using the delimiter string
  1985. X    
  1986. X    % first check if the current element is the same
  1987. X    % as the previous one, if so, and duplicate elim.
  1988. X    % is selected, nothing is displayed
  1989. X    % (except if this is the first line of a new page)
  1990. X
  1991. X    /displayThis true def
  1992. X    noDupls line 0 ne and i 0 eq and
  1993. X    {
  1994. X      /tidx 0 def
  1995. X      true
  1996. X      elem i get
  1997. X      {
  1998. X        lastElem i get tidx get eq and
  1999. X        /tidx tidx 1 add def
  2000. X      } forall
  2001. X      not /displayThis exch def
  2002. X    } if
  2003. X
  2004. X    displayThis
  2005. X    {
  2006. X      line 0 ne i 0 eq and
  2007. X      {
  2008. X        0 y0 lsize add yboff add moveto hspace 0 rlineto stroke
  2009. X      } if
  2010. X      /cnt 0 def    % counter for maximum multiplicity
  2011. X      /xwidth colSizes i get def
  2012. X      /maxMultiplicity colMultiplicity i get def
  2013. X      /xbuf x0 def
  2014. X      elem i get
  2015. X      dup /nMultis exch length def
  2016. X      nMultis 1 eq
  2017. X      {
  2018. X        % only one entry -> check for the field type and
  2019. X        % display numeric values right justified
  2020. X        
  2021. X        
  2022. X        0 get
  2023. X        fieldTypes i get dup (N) eq exch (T) eq or
  2024. X        {
  2025. X          dup stringwidth pop neg x0 add xwidth add
  2026. X          xboff dup add sub
  2027. X          /x0 exch def xwidth clipshow
  2028. X        }
  2029. X        {
  2030. X          % no numeric field
  2031. X          xwidth clipshow
  2032. X        } ifelse
  2033. X      }
  2034. X      {
  2035. X        % more than one entry
  2036. X        {
  2037. X          dup
  2038. X          xwidth clipshow
  2039. X          stringwidth pop dup neg xwidth add /xwidth exch def
  2040. X          x0 add /x0 exch def
  2041. X          % should I append the delimiter ?
  2042. X          /cnt cnt 1 add def
  2043. X          cnt nMultis ne
  2044. X          cnt maxMultiplicity ne and
  2045. X          {
  2046. X        delimiter xwidth clipshow
  2047. X        delimiter stringwidth pop dup
  2048. X        x0 add /x0 exch def neg xwidth add
  2049. X        /xwidth exch def
  2050. X          }
  2051. X          {
  2052. X        exit    % leave if maximum multiplicity reached
  2053. X          } ifelse
  2054. X        } forall
  2055. X      } ifelse
  2056. X      /x0 xbuf def
  2057. X    } if          % if entry should be shown at all
  2058. X      } ifelse        % end if not a weightened selection
  2059. X      
  2060. X      /x0 x0 colSizes i get add def
  2061. X      
  2062. X    } for             % end for all columns
  2063. X    
  2064. X    % one line is finished
  2065. X    % debug { (\012 Line ) print line 10 string cvs print ( printed.) print } if
  2066. X
  2067. X    /line line 0 eq
  2068. X    { line 2 add } { line 1 add } ifelse 
  2069. X    dup nLines ge { pop 0 /page page 1 add def showpage } if def
  2070. X    /y0 y0 lsize sub def        % new y starting position
  2071. X    /lastElem elem def        % remember last element for duplicate elimination
  2072. X  } forall            % end for all data
  2073. X} def
  2074. X
  2075. X%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2076. X%%
  2077. X%%           M     M    A      III   N     N
  2078. X%%           MM   MM   A A      I    NN    N
  2079. X%%           M M M M  A   A     I    N N   N
  2080. X%%           M  M  M A     A    I    N  N  N
  2081. X%%           M     M AAAAAAA    I    N   N N
  2082. X%%           M     M A     A    I    N    NN
  2083. X%%           M     M A     A   III   N     N
  2084. X%%
  2085. X%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2086. X
  2087. X128 dict begin    % start a large user dictionary
  2088. X
  2089. XUmlaute         % activate german (or, more generally, foreign Umlauts)
  2090. X
  2091. X/GermanFont findfont $FONTSIZE scalefont setfont        % select font
  2092. X
  2093. X% Dynamic data for output header
  2094. X
  2095. X/cm { 28.346456 mul } def    %% definition of a cm based in points
  2096. X/pageWidth ${PAGEWIDTH} def    %% Width of a page
  2097. X/pageHeight ${PAGEHEIGHT} def    %% Height of a page
  2098. X/hoff ${HOFF} def                 %% horizontal skip value
  2099. X/voff ${VOFF} def                 %% vertical skip value
  2100. X
  2101. X/landscape ${LANDSCAPE} def    %% Print in landscape mode ?
  2102. X/datestr (`date +%d.%m.%y`) def    %% today's date
  2103. X/timestr (`date +%H:%M:%S`) def    %% current time
  2104. X/userstr (${USER}) def        %% user running the program
  2105. X/fsize $FONTSIZE def        %% base font used
  2106. X/title (${TITLE}) def        %% title for the report
  2107. X/delimiter (${DELIMITER}) def    %% delimiter string for multi-fields
  2108. X/noDupls ${NODUPLS} def         %% display values if same for two succeeding rows ?
  2109. X
  2110. X% define size variables depending on landscape parameter
  2111. X
  2112. Xlandscape            
  2113. X{
  2114. X /lph pageWidth def
  2115. X /lpw pageHeight def
  2116. X}
  2117. X{
  2118. X /lpw pageWidth def
  2119. X /lph pageHeight def
  2120. X} ifelse
  2121. X
  2122. X% procedure called when new page is started 
  2123. X
  2124. X/top
  2125. X{
  2126. X  landscape
  2127. X  {
  2128. X    -90 rotate pageHeight neg 0 translate
  2129. X  } if
  2130. X  hoff voff translate
  2131. X} def
  2132. X
  2133. X
  2134. X%% ------------------------------------------------------------------
  2135. X%% the following arrays were created by the prg.awk program
  2136. X%% ------------------------------------------------------------------
  2137. X
  2138. XEND_OF_PS_HEADER
  2139. X
  2140. Xcat $TMPHEADER | sed -f ${PRGLIBPATH}/prg.sed >> $PSFILE
  2141. X
  2142. Xcat << END_OF_PS_HEAD3 >> $PSFILE
  2143. X
  2144. X%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2145. X%% define global variables used for optimization
  2146. X%% and printing
  2147. X%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2148. X
  2149. X/optimize ${OPTIMIZE} def           %% optimize output size ?
  2150. X/debug ${DEBUG_PS} def              %% PostScript debugging
  2151. X/showtitle ${SHOWTITLE} def         %% display title page ?
  2152. X/commandLine (command line used: ${COMLINE}) def        %% how the program was invoked
  2153. X/line 0 def                         %% current line
  2154. X/page 0 def                         %% current page
  2155. X/hspace lpw hoff dup add sub def    %% space available horizontally
  2156. X/vspace lph voff dup add sub def    %% space available vertically
  2157. X/xboff 3 def                        %% box offset horizontally
  2158. X/yboff 2 def                        %% box offset horizontally
  2159. X/multiOff 2 def                     %% Offset for multiple weightened selection
  2160. X/x0 0 def                           %% start value for x
  2161. X  
  2162. X/nColumns colSizes length def       %% number of columns
  2163. X/bbox /GermanFont findfont 
  2164. X/FontBBox get [ exch aload pop ] def %% Bounding-Box (scale-independent)
  2165. X/legend false def             %% draw a legend on the second page ?
  2166. X/maxSizes nColumns array def        %% array to hold the maximum values
  2167. X
  2168. X0 1 nColumns 1 sub            %% NULL the maxSizes array
  2169. X{
  2170. X maxSizes exch 0 put
  2171. X} for
  2172. X
  2173. X%% compute default values for column widths if no optimization requested
  2174. X
  2175. Xoptimize not
  2176. X{
  2177. X  % compute default sizes for the columns (if no explicit data given)
  2178. X  0 1 nColumns 1 sub 
  2179. X  {
  2180. X    /i exch def colSizes i colSizes i get
  2181. X    dup -1 eq { pop hspace nColumns div } if put
  2182. X    fieldMulti i get (W) eq { /legend true def } if
  2183. X  } for
  2184. X} if % no optimization -> compute default values
  2185. X
  2186. X% ------------------------------------------------------------------
  2187. X% ------------------------------ DATA ------------------------------
  2188. X% ------------------------------------------------------------------
  2189. X
  2190. XEND_OF_PS_HEAD3
  2191. X
  2192. X
  2193. X# Determine the split factor for the input data, i.e. how often it has to
  2194. X# be split in order to avoid a memory overflow in the printer
  2195. X
  2196. XTMPPFIX=${TMPDIR}/split`date +%S%M`
  2197. X
  2198. Xif [ $NELEMENTS -gt $MAXARRAYSIZE ]
  2199. Xthen
  2200. X /bin/rm -f ${TMPPFIX}* 1>/dev/null 2>/dev/null
  2201. X cat ${TMPDATA} | split -l $MAXARRAYSIZE -a 4 - ${TMPPFIX}
  2202. X TMPCNT=1
  2203. X CNTMAX=0
  2204. X for fi in `ls ${TMPPFIX}*`
  2205. X do
  2206. X  CNTMAX=`expr $CNTMAX + 1`
  2207. X done
  2208. X echo -n "Creating PostScript report"
  2209. X if [ "$OPTIMIZE" = "true" ]
  2210. X then
  2211. X  cat << END_OF_PSHEAD1 >> $PSFILE
  2212. X
  2213. X
  2214. X%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2215. X%%
  2216. X%% Pass 1 : Computing optimized column widths
  2217. X%%
  2218. X%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2219. X
  2220. XEND_OF_PSHEAD1
  2221. X
  2222. X fi
  2223. X
  2224. X # Pass 1 : Optimization
  2225. X
  2226. X for fi in `ls ${TMPPFIX}*`
  2227. X do
  2228. X  echo -n "."
  2229. X  echo "" >> $PSFILE
  2230. X  if [ "$OPTIMIZE" = "true" ]
  2231. X  then
  2232. X   echo -n "%% Pass 1, " >> $PSFILE
  2233. X  else
  2234. X   echo -n "%% " >> $PSFILE
  2235. X  fi
  2236. X  echo -n "Part ${TMPCNT} / ${CNTMAX} from `basename $INFILE`" >> $PSFILE
  2237. X  echo " (`cat $fi | wc -l | sed 's/[ ]*//g'` elements)" >> $PSFILE
  2238. X  echo "[" >> $PSFILE
  2239. X  cat $fi >> $PSFILE
  2240. X  if [ "$OPTIMIZE" = "true" ]
  2241. X  then
  2242. X   echo "] optimizeColumns %% use data to compute optimal column widths (Pass 1)" >> $PSFILE
  2243. X  else
  2244. X   echo "] postOptimization createReport    %% print the data using the default settings" >> $PSFILE
  2245. X  fi
  2246. X  TMPCNT=`expr $TMPCNT + 1`
  2247. X done
  2248. X
  2249. X # Pass 2 : Printing
  2250. X
  2251. X if [ "$OPTIMIZE" = "true" ]
  2252. X then
  2253. X  cat << END_OF_PSHEAD2 >> $PSFILE
  2254. X
  2255. X% post-process optimization, create title page and legend
  2256. X
  2257. XpostOptimization   
  2258. X
  2259. X%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2260. X%%
  2261. X%% Pass 2 : Create the report and print it out
  2262. X%%
  2263. X%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2264. X
  2265. XEND_OF_PSHEAD2
  2266. X
  2267. X  TMPCNT=1
  2268. X  for fi in `ls ${TMPPFIX}*`
  2269. X  do
  2270. X   echo -n "."
  2271. X   echo "" >> $PSFILE
  2272. X   echo -n "%% Pass 2, Part ${TMPCNT} / ${CNTMAX} from `basename $INFILE`" >> $PSFILE
  2273. X   echo " (`cat $fi | wc -l | sed 's/[ ]*//g'` elements)" >> $PSFILE
  2274. X   echo "[" >> $PSFILE
  2275. X   cat $fi >> $PSFILE
  2276. X   echo "] createReport    %% print the data using the precomputed settings" >> $PSFILE
  2277. X   TMPCNT=`expr $TMPCNT + 1`
  2278. X   /bin/rm -f $fi
  2279. X  done
  2280. X fi   # end if optimization requested
  2281. X
  2282. X echo "done"    # splitting finished
  2283. X
  2284. Xelse
  2285. X echo -n "Creating PostScript report..."
  2286. X # input does not have to be splitted, i.e. small amount of data
  2287. X echo "[" >> $PSFILE
  2288. X cat ${TMPDATA} >> $PSFILE
  2289. X echo -n "] " >> $PSFILE
  2290. X if [ "$OPTIMIZE" = "true" ]
  2291. X then
  2292. X  echo -n "dup optimizeColumns " >> $PSFILE
  2293. X fi
  2294. X echo "postOptimization createReport" >> $PSFILE
  2295. X echo "done."
  2296. Xfi
  2297. Xecho "line 0 eq not { showpage } if" >> $PSFILE
  2298. Xecho "end    % end large user dictionary" >> $PSFILE
  2299. Xecho "%%TRAILER" >> $PSFILE
  2300. Xecho >> $PSFILE
  2301. X
  2302. X}
  2303. X
  2304. X##################################################################
  2305. X##################################################################
  2306. X#
  2307. X# MAIN ('mainprg') - patsch's PostScript report generator
  2308. X# 
  2309. X##################################################################
  2310. X##################################################################
  2311. X
  2312. X
  2313. XinitVariables $0 $*     # initialize temporary variables
  2314. XparseCommandLine $*     # parse the command line
  2315. XcheckDataFiles          # check whether the data files exist
  2316. X
  2317. X
  2318. X#######################################################
  2319. X#
  2320. X# 1. Create an array of data suitable as input to the
  2321. X#    postscript functions.
  2322. X#
  2323. X#######################################################
  2324. X
  2325. X# Selection step may be added later
  2326. X
  2327. Xecho -n "Selecting records from $INFILE "
  2328. X
  2329. Xcat $DESFILE $INFILE | $AWK -v FS='#' -v debug=$DEBUG \
  2330. X                        -v debugExpr=$DEBUGEXPR \
  2331. X                                      -v tmpData=$TMPDATA \
  2332. X                                      -v fn=$FONTNAME \
  2333. X                                      -v fsize=$FONTSIZE \
  2334. X                                      -v format=$FORMAT \
  2335. X                                      -v sortby=$SORTBY \
  2336. X                                      -v select="$SELECT" \
  2337. X                                      -v tmpHeader=$TMPHEADER \
  2338. X                                      -v sortFileName=$SORTFILENAME \
  2339. X                                      -v unit=$UNIT \
  2340. X                      -v casecomp=$CASECOMP \
  2341. X                      -v accuracy=$ACCURACY \
  2342. X                            -v compareLastNames=$CBSC \
  2343. X                                      -f ${PRGLIBPATH}/prg.awk
  2344. X
  2345. X
  2346. Xif [ $? -ne 0 ]
  2347. Xthen
  2348. X echo
  2349. X echo ${PRGLIBPATH}/prg.awk produced an error.
  2350. X echo Please check any previous error output and fix
  2351. X echo the problems mentioned - bailing out.
  2352. X exit
  2353. Xfi
  2354. Xecho done.
  2355. X
  2356. XNELEMENTS=`cat ${TMPDATA} | wc -l`
  2357. Xecho -n Sorting $NELEMENTS records...
  2358. X
  2359. X#######################################################
  2360. X#
  2361. X# 2. Strip off trailing blanks in the postscript
  2362. X#    strings and sort the data according to the keys.
  2363. X#
  2364. X#######################################################
  2365. X
  2366. Xchmod +x $SORTFILENAME 
  2367. X./$SORTFILENAME ${TMPDATA}
  2368. Xecho done
  2369. X
  2370. X# strip off leading sort keys, convert umlauts and strip
  2371. X# away trailing blanks in strings
  2372. X
  2373. XNSORTFIELDS=`cat ${TMPHEADER}.nsf`
  2374. Xcat ${TMPDATA}.srt |  cut -d '#' -f${NSORTFIELDS}- | sed -f ${PRGLIBPATH}/prg.sed > ${TMPDATA}
  2375. X
  2376. X#######################################################
  2377. X#
  2378. X# 3. Create the PostScript file
  2379. X#
  2380. X#######################################################
  2381. X
  2382. XPSFILE=`basename ${INFILE}`.ps
  2383. X
  2384. XcreatePostScriptFile
  2385. X
  2386. Xecho
  2387. Xecho Your report was written into the file ${PSFILE}.
  2388. Xecho You may want to print it out using the standard
  2389. Xecho "printer command (usually lpr on UNIX machines)."
  2390. Xecho
  2391. Xecho "Thanks for using patsch's PostScript report generator."
  2392. X
  2393. Xif [ $KEEPTEMP -eq 0 ]
  2394. Xthen
  2395. X # remove temporary data
  2396. X /bin/rm -f ${TMPHEADER} ${TMPHEADER}.nsf ${TMPDATA} ${TMPDATA}.srt ${SORTFILENAME}
  2397. Xfi
  2398. END_OF_FILE
  2399.   if test 70190 -ne `wc -c <'prg/prg'`; then
  2400.     echo shar: \"'prg/prg'\" unpacked with wrong size!
  2401.   fi
  2402.   chmod +x 'prg/prg'
  2403.   # end of 'prg/prg'
  2404. fi
  2405. echo shar: End of archive 1 \(of 6\).
  2406. cp /dev/null ark1isdone
  2407. MISSING=""
  2408. for I in 1 2 3 4 5 6 ; do
  2409.     if test ! -f ark${I}isdone ; then
  2410.     MISSING="${MISSING} ${I}"
  2411.     fi
  2412. done
  2413. if test "${MISSING}" = "" ; then
  2414.     echo You have unpacked all 6 archives.
  2415.     rm -f ark[1-9]isdone
  2416. else
  2417.     echo You still must unpack the following archives:
  2418.     echo "        " ${MISSING}
  2419. fi
  2420. exit 0
  2421. exit 0 # Just in case...
  2422.